From 94be9916a2d5ae3052a7447ff7fd3cbb7881eb0e Mon Sep 17 00:00:00 2001 From: eric2788 Date: Thu, 2 Dec 2021 15:40:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=A6=E8=A7=81=20changelo?= =?UTF-8?q?g.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/node.js.yml | 2 +- Dockerfile | 22 ++++-- README.md | 66 +++++++++++++++++- assets/dd_showcase.png | Bin 0 -> 54839 bytes changelog.md | 5 +- data/storage.json | 35 ---------- package.json | 23 +++--- {bot => src/bot}/http.js | 2 +- {bot => src/bot}/index.js | 0 {bot => src/bot}/ws.js | 6 +- .../command_listener.js | 2 +- {commands => src/commands}/blive.js | 0 {commands => src/commands}/focus.js | 0 {commands => src/commands}/highlights.js | 0 config.js => src/config.js | 0 {data => src/data}/settings.json | 0 {el => src/el}/api/message-source.js | 2 +- {el => src/el}/api/redis_api.js | 2 +- {el => src/el}/api/websocket_api.js | 3 +- {el => src/el}/command-manager.js | 0 {el => src/el}/data-storer.js | 10 ++- {el => src/el}/message-handler.js | 0 {el => src/el}/types.js | 1 + {el => src/el}/utils.js | 0 index.js => src/index.js | 5 +- test.js => src/test.js | 2 +- {ws_handles => src/ws_handles}/dammu_msg.js | 0 .../ws_handles}/live_broadcast.js | 0 {ws_handles => src/ws_handles}/room_enter.js | 0 .../ws_handles}/superchat_msg.js | 0 30 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 assets/dd_showcase.png delete mode 100644 data/storage.json rename {bot => src/bot}/http.js (83%) rename {bot => src/bot}/index.js (100%) rename {bot => src/bot}/ws.js (85%) rename command_listener.js => src/command_listener.js (97%) rename {commands => src/commands}/blive.js (100%) rename {commands => src/commands}/focus.js (100%) rename {commands => src/commands}/highlights.js (100%) rename config.js => src/config.js (100%) rename {data => src/data}/settings.json (100%) rename {el => src/el}/api/message-source.js (87%) rename {el => src/el}/api/redis_api.js (96%) rename {el => src/el}/api/websocket_api.js (96%) rename {el => src/el}/command-manager.js (100%) rename {el => src/el}/data-storer.js (87%) rename {el => src/el}/message-handler.js (100%) rename {el => src/el}/types.js (98%) rename {el => src/el}/utils.js (100%) rename index.js => src/index.js (75%) rename test.js => src/test.js (95%) rename {ws_handles => src/ws_handles}/dammu_msg.js (100%) rename {ws_handles => src/ws_handles}/live_broadcast.js (100%) rename {ws_handles => src/ws_handles}/room_enter.js (100%) rename {ws_handles => src/ws_handles}/superchat_msg.js (100%) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 3eca619..97f2892 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,6 +1,6 @@ name: Build Executable And Publish env: - version: 0.1.2 + version: 0.1.3 artifact_name: vup_monitors GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile index 2cd92f6..8d65b80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,23 @@ -FROM node:17-alpine +FROM node:16 AS builder WORKDIR /app -RUN cd /app +COPY ./src ./src +COPY *.json . -COPY . . +RUN npm install +RUN npm install pkg -g +RUN pkg . -VOLUME [ "/app/data" ] +FROM ubuntu:latest -RUN npm install +WORKDIR / + +ENV NODE_ENV=production + +COPY --from=builder /app/dist/vup_monitors-linux /vup_monitors +RUN chmod +x /vup_monitors + +VOLUME [ "/data" ] -CMD ["npm", "run", "start"] \ No newline at end of file +ENTRYPOINT [ "/vup_monitors" ] \ No newline at end of file diff --git a/README.md b/README.md index cb179ca..9e1ff12 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Vup Monitors -基于 go-cqhttp 和 nodejs 的 Vups 直播間監控機器人 +基于 go-cqhttp 和 nodejs 的 Vups 直播間監控機器人,支援多群使用和私人广播 + +![showcase](/assets/dd_showcase.png) + +#### 目前支援监控的DD行为 + +- 进入直播间 +- 发送SC +- 发送弹幕 ## 前置 @@ -23,7 +31,7 @@ ### 本项目 (Vup_monitors) -- 下载对应平台的可执行文件 +- 到 `releases` 下载对应平台的可执行文件 - 运行程序后关闭 @@ -33,6 +41,8 @@ - 再运行程序 +- 开始透过指令设定监控和高亮 + #### 除了 biligo-live-ws 以外的运行方式 @@ -40,6 +50,58 @@ 运行 blive-redis-server 和 redis,然后在 `data/settings.json` 设定数据源为 `redis` 即可 +## 指令 + +`<>` 为必填参数, `[]` 为选填参数 + +### !B站直播 + +B站直播WS讯息监控指令 + +- `!B站直播 监控 <房间号>` - 监听房间 +- `!B站直播 中止 <房间号>` - 中止监听房间 +- `!B站直播 监听中` - 获取正在监听中的房间号列表 + +### !高亮名单 + +控制高亮名单用户,以进行广播 + +```log +- 如果在群使用指令,则会添加/删除到该群所属的高亮用户名单 +- 如果在私聊使用且附上`[群id]`,则会添加/删除该群id所属的高亮用户名单 +- 如果在私聊使用而不附上`[群id]`,则会添加/删除属于你自己的高亮用户名单 +``` + +- `!高亮 新增 <用户id> [群id]` - 新增用户到高亮名单 +- `!高亮 移除 <用户id> [群id]` - 删除用户到高亮名单 +- `!高亮 列表 [群id]` - 显示高亮用户名单列表 + +**高亮名单会分开群号和QQ号,只有在私聊才会接受 `[群id]` 作为参数以私下设置群高亮名单,如不填则为属于该QQ号的高亮名单** + +### !注视名单 + +透过设置群注视名单,可以在广播时限制仅限在注视用户的直播间内/注视用户本人的所有DD行为。 + +```log +- 由于注视用户不支援私聊,因此在私聊使用此指令时必须添加群id +- 如果在群添加注视用户,则无需填入群id,並以该群作为添加/删除对象 +``` + +- `!注视 新增 <用户id> <群id(如私聊)>` - 新增该群注视用户 +- `!注视 移除 <用户id> <群id(如私聊)>` - 移除该群注视用户 +- `!注视 列表 <用户id> <群id(如私聊)>` - 查看该群所属注视用户名单 + +添加注视用户后,广播规则将如下 + +| 高亮用户 | 直播间 | 广播 | +| ------- | ----- | ----- | +| 在注视名单内 | 不在注视名单内 | ✔ | +| 不在注视名单内 | 不在注视名单内 | ✖ | +| 不在注视名单内 | 在注视名单内 | ✔ | +| 在注视名单内 | 在注视名单内 | ✔ | + +如果没有注视用户,则默认广播所有高亮用户在监控中的直播间的DD行为。 + ## 其他部署方式 ### Docker diff --git a/assets/dd_showcase.png b/assets/dd_showcase.png new file mode 100644 index 0000000000000000000000000000000000000000..9f8d6caa881807eff8b423c2bdfa5adab2febb40 GIT binary patch literal 54839 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 fh3%N#vODoJhXs6Wv { ws.on('error', err => { - console.warn(`连接 WS 时出现错误: ${err?.message ?? err}`) + console.warn(`连接 go-cqhttp 时出现错误: ${err?.message ?? err}`) rej(err) }) ws.on('open', () => { - console.log(`WS 连接成功。`) + console.log(`go-cqhttp 连接成功。`) res(ws) }) }) diff --git a/command_listener.js b/src/command_listener.js similarity index 97% rename from command_listener.js rename to src/command_listener.js index 977d10d..86874f7 100644 --- a/command_listener.js +++ b/src/command_listener.js @@ -1,5 +1,5 @@ const { invoke } = require('./el/command-manager') -const { owners } = require('./data/settings.json') +const { owners } = require('./el/data-storer').settings const { commands } = require('./config') module.exports = async({data, ws, http}) => { diff --git a/commands/blive.js b/src/commands/blive.js similarity index 100% rename from commands/blive.js rename to src/commands/blive.js diff --git a/commands/focus.js b/src/commands/focus.js similarity index 100% rename from commands/focus.js rename to src/commands/focus.js diff --git a/commands/highlights.js b/src/commands/highlights.js similarity index 100% rename from commands/highlights.js rename to src/commands/highlights.js diff --git a/config.js b/src/config.js similarity index 100% rename from config.js rename to src/config.js diff --git a/data/settings.json b/src/data/settings.json similarity index 100% rename from data/settings.json rename to src/data/settings.json diff --git a/el/api/message-source.js b/src/el/api/message-source.js similarity index 87% rename from el/api/message-source.js rename to src/el/api/message-source.js index 03e643b..b96fa46 100644 --- a/el/api/message-source.js +++ b/src/el/api/message-source.js @@ -1,6 +1,6 @@ const redisSource = require('./redis_api') const websocketSource = require('./websocket_api') -const { source } = require('../../data/settings.json') +const { source } = require('../data-storer').settings const sources = { ...redisSource, diff --git a/el/api/redis_api.js b/src/el/api/redis_api.js similarity index 96% rename from el/api/redis_api.js rename to src/el/api/redis_api.js index a5d0dd5..88bbe14 100644 --- a/el/api/redis_api.js +++ b/src/el/api/redis_api.js @@ -1,5 +1,5 @@ const { createClient } = require('redis'); -const settings = require('../../data/settings.json') +const settings = require('../data-storer').settings const utils = require('../utils'); const { handleMessage } = require('../message-handler'); diff --git a/el/api/websocket_api.js b/src/el/api/websocket_api.js similarity index 96% rename from el/api/websocket_api.js rename to src/el/api/websocket_api.js index daa5d39..8ee2787 100644 --- a/el/api/websocket_api.js +++ b/src/el/api/websocket_api.js @@ -1,5 +1,5 @@ const WebSocket = require('ws') -const { websocket } = require('../../data/settings.json') +const { websocket } = require('../data-storer').settings const utils = require('../utils') const { default: axios } = require('axios') const FormData = require('form-data') @@ -68,6 +68,7 @@ class WebSocketSouce extends MessageSource { } async listenAll(rooms){ + if (rooms.length == 0) return const form = new FormData() for (const room of rooms){ form.append('subscribes', room) diff --git a/el/command-manager.js b/src/el/command-manager.js similarity index 100% rename from el/command-manager.js rename to src/el/command-manager.js diff --git a/el/data-storer.js b/src/el/data-storer.js similarity index 87% rename from el/data-storer.js rename to src/el/data-storer.js index 6b508bb..e4bc213 100644 --- a/el/data-storer.js +++ b/src/el/data-storer.js @@ -1,4 +1,4 @@ -const { existsSync, mkdirSync, writeFileSync , promises: fs } = require('fs') +const { existsSync, mkdirSync, writeFileSync, readFileSync , promises: fs } = require('fs') const PATH = './data/storage.json' @@ -47,18 +47,22 @@ if (!existsSync('./data')){ mkdirSync('./data') } +const SETTING_PATH = './data/settings.json' -if (!existsSync('./data/settings.json')) { +if (!existsSync(SETTING_PATH)) { console.log("找不到 data/settings.json 档案") const config = JSON.stringify(DEFAULT_CONFIG, undefined, 4) - writeFileSync('./data/settings.json', config) + writeFileSync(SETTING_PATH, config) console.log("已新增默认的 data/settings.json 设定档。") + } +const settings = JSON.parse(readFileSync(SETTING_PATH)) const write_transactions = [] const actions = { + settings, // this.update(data => { ... }) update: async (update) => { const data = await actions.read() diff --git a/el/message-handler.js b/src/el/message-handler.js similarity index 100% rename from el/message-handler.js rename to src/el/message-handler.js diff --git a/el/types.js b/src/el/types.js similarity index 98% rename from el/types.js rename to src/el/types.js index e48606b..ed7e37e 100644 --- a/el/types.js +++ b/src/el/types.js @@ -34,6 +34,7 @@ class MessageSource { } async listenAll(rooms){ + if (rooms.length == 0) return for (const room of rooms) { await this.listen(room, false) } diff --git a/el/utils.js b/src/el/utils.js similarity index 100% rename from el/utils.js rename to src/el/utils.js diff --git a/index.js b/src/index.js similarity index 75% rename from index.js rename to src/index.js index b26bbc7..8975679 100644 --- a/index.js +++ b/src/index.js @@ -11,9 +11,12 @@ async function executeCommands(data) { } } +const { owners } = require('./el/data-storer').settings +console.log(`已设置管理员QQ号: ${owners}, 群管和管理员都可使用指令。`) + // 同时启动 Redis 和 WS 监控 console.log('正在启动 vup monitors...') -Promise.all([ ws.startWS(), messager.connect()]) +Promise.all([ws.startWS(), messager.connect()]) .then(() => { ws.listen(data => { if (process.env.NODE_ENV === 'development') { diff --git a/test.js b/src/test.js similarity index 95% rename from test.js rename to src/test.js index 796fd77..05619a9 100644 --- a/test.js +++ b/src/test.js @@ -1,6 +1,6 @@ const { invoke } = require('./el/command-manager') const readline = require("readline"); -const { connect } = require('./el/redis_api'); +const { connect } = require('./el/api/message-source'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout diff --git a/ws_handles/dammu_msg.js b/src/ws_handles/dammu_msg.js similarity index 100% rename from ws_handles/dammu_msg.js rename to src/ws_handles/dammu_msg.js diff --git a/ws_handles/live_broadcast.js b/src/ws_handles/live_broadcast.js similarity index 100% rename from ws_handles/live_broadcast.js rename to src/ws_handles/live_broadcast.js diff --git a/ws_handles/room_enter.js b/src/ws_handles/room_enter.js similarity index 100% rename from ws_handles/room_enter.js rename to src/ws_handles/room_enter.js diff --git a/ws_handles/superchat_msg.js b/src/ws_handles/superchat_msg.js similarity index 100% rename from ws_handles/superchat_msg.js rename to src/ws_handles/superchat_msg.js