Compare commits

..

5 Commits

Author SHA1 Message Date
8fad9982b3 fix layout effect 2025-03-19 12:06:07 +08:00
2448707633 fix open live danmaku client init 2025-03-19 11:56:07 +08:00
2818ecf6c4 try fix open live 2025-03-19 11:41:09 +08:00
f303ff7be7 add publish permissions 2025-03-19 10:22:17 +08:00
4eb69ca8f1 add docker container 2025-03-19 10:19:19 +08:00
11 changed files with 75 additions and 73 deletions

View File

@@ -7,11 +7,19 @@ on:
push:
branches: [ "master" ]
env:
DOCKERHUB_SLUG: megghy/vtsuru_live
GHCR_SLUG: ghcr.io/megghy/vtsuru_live
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
@@ -20,7 +28,40 @@ jobs:
- name: 📥 Install dependencies
run: bun install
- name: 📦 Build
run: bun run build
- name: 📦 Upload SourceMap
run: bunx @hyperdx/cli upload-sourcemaps --serviceKey ${{ secrets.HYPERDX_SERVICE_KEY }} --path dist/assets
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.GHCR_SLUG }}
- name: Get current time
uses: josStorer/get-current-time@v2
id: time
with:
format: YYYYMMDD_HHmmss
utcOffset: "+08:00"
- name: Build Docker image and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
${{ env.GHCR_SLUG }}:latest
${{ env.GHCR_SLUG }}:${{ steps.time.outputs.formattedTime }}

6
Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
FROM caddy:alpine
COPY dist/ /etc/caddy/html/
COPY src/files/Caddyfile /etc/caddy/
EXPOSE 80

View File

@@ -59,6 +59,7 @@ export default abstract class BaseDanmakuClient {
}
} catch (err) {
console.error(err)
this.state = 'disconnected'
return {
success: false,
message: err ? err.toString() : '未知错误'

View File

@@ -18,7 +18,7 @@ export default class OpenLiveClient extends BaseDanmakuClient {
private timer: any | undefined
public authInfo: AuthInfo | undefined
public roomAuthInfo: RoomAuthInfo | undefined
public roomAuthInfo: OpenLiveInfo | undefined
public authCode: string | undefined
public events: {
@@ -71,6 +71,8 @@ export default class OpenLiveClient extends BaseDanmakuClient {
)
})
this.roomAuthInfo = auth.data
return await super.initClientInner(chatClient)
} else {
console.log(`[${this.type}] 无法开启场次: ` + auth.message)
@@ -369,66 +371,6 @@ export interface AuthInfo {
Caller: string
CodeSign: string
}
/**
* 场次信息
*/
interface GameInfo {
/**
* 场次id,心跳key(心跳保持20s-60s)调用一次,超过60s无心跳自动关闭,长连停止推送消息
*/
game_id: string
}
/**
* 长连信息
*/
interface WebsocketInfo {
/**
* 长连使用的请求json体 第三方无需关注内容,建立长连时使用即可
*/
auth_body: string
/**
* wss 长连地址
*/
wss_link: string[]
}
/**
* 主播信息
*/
interface AnchorInfo {
/**
* 主播房间号
*/
room_id: number
/**
* 主播昵称
*/
uname: string
/**
* 主播头像
*/
uface: string
/**
* 主播uid
*/
uid: number
open_id: string
}
export interface RoomAuthInfo {
/**
* 场次信息
*/
game_info: GameInfo
/**
* 长连信息
*/
websocket_info: WebsocketInfo
/**
* 主播信息
*/
anchor_info: AnchorInfo
}
export interface DanmakuEventsMap {
danmaku: (arg1: DanmakuInfo, arg2?: any) => void
gift: (arg1: GiftInfo, arg2?: any) => void

11
src/files/Caddyfile Normal file
View File

@@ -0,0 +1,11 @@
:80 {
# Compress responses according to Accept-Encoding headers
encode gzip zstd
root * /etc/caddy/html/
try_files {path} /index.html
# Serve everything else from the file system
file_server
}

View File

@@ -49,6 +49,7 @@ export default [
{
path: 'goods',
name: 'user-goods',
alias: 'point',
component: () => import('@/views/pointViews/PointGoodsView.vue'),
meta: {
title: '积分兑换',

View File

@@ -1,8 +1,6 @@
import { useAccount } from '@/api/account'
import OpenLiveClient, {
AuthInfo,
RoomAuthInfo
} from '@/data/DanmakuClients/OpenLiveClient'
import { OpenLiveInfo } from '@/api/api-models'
import OpenLiveClient, { AuthInfo } from '@/data/DanmakuClients/OpenLiveClient'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
@@ -21,7 +19,7 @@ export const useDanmakuClient = defineStore('DanmakuClient', () => {
const connected = computed(
() => status.value === 'running' || status.value === 'listening'
)
const authInfo = ref<RoomAuthInfo>()
const authInfo = ref<OpenLiveInfo>()
const accountInfo = useAccount()
let existOtherClient = false

View File

@@ -39,7 +39,7 @@ const sider = ref()
const { width } = useElementSize(sider)
const authInfo = ref<AuthInfo>()
const danmakuClient = await useDanmakuClient().initClient()
const danmakuClient = await useDanmakuClient()
const menuOptions = [
{
@@ -200,6 +200,8 @@ onUnmounted(() => {
</KeepAlive>
</RouterView>
<template v-else>
{{ }}
<NAlert type="info" title="正在请求弹幕客户端认证信息...">
<NSpin show />
</NAlert>

View File

@@ -386,8 +386,8 @@ onMounted(() => { })
</NDivider>
<NFlex align="center">
<NInputGroup style="max-width: 400px;">
<NInput :value="`${useCNUrl ? CN_HOST : CURRENT_HOST}@${accountInfo.name}/point`" readonly />
<NButton secondary @click="copyToClipboard(`${useCNUrl ? CN_HOST : CURRENT_HOST}@${accountInfo.name}/point`)">
<NInput :value="`${useCNUrl ? CN_HOST : CURRENT_HOST}@${accountInfo.name}/goods`" readonly />
<NButton secondary @click="copyToClipboard(`${useCNUrl ? CN_HOST : CURRENT_HOST}@${accountInfo.name}/goods`)">
复制 </NButton>
</NInputGroup>
<NCheckbox v-model:checked="useCNUrl"> 使用国内镜像(访问更快) </NCheckbox>

View File

@@ -158,7 +158,7 @@ onMounted(async () => {
关于
</NFlex>
</template>
<NDescriptions label-placement="left" bordered size="small">
<NDescriptions label-placement="left" bordered size="small" :column="2">
<NDescriptionsItem label="用户名">
{{ user.info.name }}
</NDescriptionsItem>

View File

@@ -129,7 +129,7 @@ onMounted(async () => {
</script>
<template>
<NLayout>
<NLayout style="height: 100vh">
<NSpin v-if="useAuth.isLoading && useAuth.currentToken" :show="useAuth.isLoading" />
<NLayoutContent
v-else-if="(!useAuth.currentToken && useAuth.biliTokens.length > 0) || useAuth.isInvalid"
@@ -167,8 +167,8 @@ onMounted(async () => {
<NFlex align="center" justify="center">
<div style="max-width: 95vw; width: 1200px">
<NCard title="我的信息">
<NDescriptions label-placement="left" bordered size="small">
<NDescriptionsItem label="用户名">
<NDescriptions label-placement="left" bordered size="small" :column="2">
<NDescriptionsItem label="用户名" style="min-width: 100px;">
{{ biliAuth.name ?? '未知' }}
</NDescriptionsItem>
<NDescriptionsItem label="UserId">