mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
Compare commits
5 Commits
b8b73ba6f2
...
8fad9982b3
| Author | SHA1 | Date | |
|---|---|---|---|
| 8fad9982b3 | |||
| 2448707633 | |||
| 2818ecf6c4 | |||
| f303ff7be7 | |||
| 4eb69ca8f1 |
41
.github/workflows/bun.yml
vendored
41
.github/workflows/bun.yml
vendored
@@ -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
6
Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FROM caddy:alpine
|
||||||
|
|
||||||
|
COPY dist/ /etc/caddy/html/
|
||||||
|
COPY src/files/Caddyfile /etc/caddy/
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
@@ -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() : '未知错误'
|
||||||
|
|||||||
@@ -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
11
src/files/Caddyfile
Normal 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
|
||||||
|
}
|
||||||
@@ -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: '积分兑换',
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user