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: push:
branches: [ "master" ] branches: [ "master" ]
env:
DOCKERHUB_SLUG: megghy/vtsuru_live
GHCR_SLUG: ghcr.io/megghy/vtsuru_live
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -20,7 +28,40 @@ jobs:
- name: 📥 Install dependencies - name: 📥 Install dependencies
run: bun install run: bun install
- name: 📦 Build - name: 📦 Build
run: bun run build run: bun run build
- name: 📦 Upload SourceMap - name: 📦 Upload SourceMap
run: bunx @hyperdx/cli upload-sourcemaps --serviceKey ${{ secrets.HYPERDX_SERVICE_KEY }} --path dist/assets 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) { } catch (err) {
console.error(err) console.error(err)
this.state = 'disconnected'
return { return {
success: false, success: false,
message: err ? err.toString() : '未知错误' message: err ? err.toString() : '未知错误'

View File

@@ -18,7 +18,7 @@ export default class OpenLiveClient extends BaseDanmakuClient {
private timer: any | undefined private timer: any | undefined
public authInfo: AuthInfo | undefined public authInfo: AuthInfo | undefined
public roomAuthInfo: RoomAuthInfo | undefined public roomAuthInfo: OpenLiveInfo | undefined
public authCode: string | undefined public authCode: string | undefined
public events: { public events: {
@@ -71,6 +71,8 @@ export default class OpenLiveClient extends BaseDanmakuClient {
) )
}) })
this.roomAuthInfo = auth.data
return await super.initClientInner(chatClient) return await super.initClientInner(chatClient)
} else { } else {
console.log(`[${this.type}] 无法开启场次: ` + auth.message) console.log(`[${this.type}] 无法开启场次: ` + auth.message)
@@ -369,66 +371,6 @@ export interface AuthInfo {
Caller: string Caller: string
CodeSign: 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 { export interface DanmakuEventsMap {
danmaku: (arg1: DanmakuInfo, arg2?: any) => void danmaku: (arg1: DanmakuInfo, arg2?: any) => void
gift: (arg1: GiftInfo, 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', path: 'goods',
name: 'user-goods', name: 'user-goods',
alias: 'point',
component: () => import('@/views/pointViews/PointGoodsView.vue'), component: () => import('@/views/pointViews/PointGoodsView.vue'),
meta: { meta: {
title: '积分兑换', title: '积分兑换',

View File

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

View File

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

View File

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

View File

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

View File

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