koishi-plugin-bilibili-notify 3.0.0-alpha.2 → 3.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/biliAPI.d.ts +5 -6
- package/lib/biliAPI.js +394 -300
- package/lib/blive.d.ts +5 -13
- package/lib/blive.js +12 -32
- package/lib/comRegister.d.ts +12 -49
- package/lib/comRegister.js +566 -1136
- package/lib/database.d.ts +2 -13
- package/lib/database.js +6 -17
- package/lib/generateImg.d.ts +4 -3
- package/lib/generateImg.js +198 -159
- package/lib/index.d.ts +18 -19
- package/lib/index.js +212 -214
- package/lib/type/index.d.ts +37 -0
- package/lib/type/index.js +11 -0
- package/lib/utils/index.d.ts +13 -0
- package/lib/utils/index.js +102 -0
- package/lib/utils/retry.d.ts +6 -0
- package/lib/utils/retry.js +24 -0
- package/lib/utils/withLock.d.ts +7 -0
- package/lib/utils/withLock.js +59 -0
- package/package.json +4 -5
- package/readme.md +24 -35
package/lib/comRegister.js
CHANGED
|
@@ -4,24 +4,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
|
|
7
|
-
|
|
8
|
-
/* eslint-disable @typescript-eslint/no-namespace */
|
|
9
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
// Koishi核心依赖
|
|
10
8
|
const koishi_1 = require("koishi");
|
|
11
|
-
//
|
|
9
|
+
// 外部依赖:qrcode
|
|
12
10
|
const qrcode_1 = __importDefault(require("qrcode"));
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})(LiveType || (LiveType = {}));
|
|
11
|
+
// Utils
|
|
12
|
+
const utils_1 = require("./utils");
|
|
13
|
+
// Types
|
|
14
|
+
const type_1 = require("./type");
|
|
15
|
+
// TODO:WorlCloud
|
|
16
|
+
// import { Segment, useDefault } from "segmentit";
|
|
20
17
|
class ComRegister {
|
|
21
18
|
// 必须服务
|
|
22
|
-
static inject = [
|
|
19
|
+
static inject = ["ba", "gi", "database", "bl", "sm"];
|
|
23
20
|
// 定义数组:QQ相关bot
|
|
24
|
-
qqRelatedBotList = [
|
|
21
|
+
qqRelatedBotList = [
|
|
22
|
+
"qq",
|
|
23
|
+
"onebot",
|
|
24
|
+
"red",
|
|
25
|
+
"satori",
|
|
26
|
+
"chronocat",
|
|
27
|
+
];
|
|
25
28
|
// logger
|
|
26
29
|
logger;
|
|
27
30
|
// config
|
|
@@ -42,8 +45,10 @@ class ComRegister {
|
|
|
42
45
|
loginDBData;
|
|
43
46
|
// 机器人实例
|
|
44
47
|
privateBot;
|
|
45
|
-
//
|
|
48
|
+
// 动态检测销毁函数
|
|
46
49
|
dynamicDispose;
|
|
50
|
+
// 直播检测销毁函数
|
|
51
|
+
liveDispose;
|
|
47
52
|
// 发送消息方式
|
|
48
53
|
sendMsgFunc;
|
|
49
54
|
// 构造函数
|
|
@@ -53,76 +58,82 @@ class ComRegister {
|
|
|
53
58
|
// 初始化
|
|
54
59
|
this.init(config);
|
|
55
60
|
// 注册指令
|
|
56
|
-
const statusCom = ctx.command(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
const statusCom = ctx.command("status", "插件状态相关指令", {
|
|
62
|
+
permissions: ["authority:5"],
|
|
63
|
+
});
|
|
64
|
+
statusCom
|
|
65
|
+
.subcommand(".dyn", "查看动态监测运行状态")
|
|
66
|
+
.usage("查看动态监测运行状态")
|
|
67
|
+
.example("status dyn")
|
|
60
68
|
.action(() => {
|
|
61
69
|
if (this.dynamicDispose) {
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
return '动态监测未运行';
|
|
70
|
+
return "动态监测正在运行";
|
|
66
71
|
}
|
|
72
|
+
return "动态监测未运行";
|
|
67
73
|
});
|
|
68
|
-
statusCom
|
|
69
|
-
.
|
|
70
|
-
.
|
|
74
|
+
statusCom
|
|
75
|
+
.subcommand(".sm", "查看订阅管理对象")
|
|
76
|
+
.usage("查看订阅管理对象")
|
|
77
|
+
.example("status sm")
|
|
71
78
|
.action(async () => {
|
|
72
79
|
this.logger.info(this.subManager);
|
|
73
|
-
return
|
|
80
|
+
return "查看控制台";
|
|
74
81
|
});
|
|
75
82
|
statusCom
|
|
76
|
-
.subcommand(
|
|
77
|
-
.usage(
|
|
78
|
-
.example(
|
|
83
|
+
.subcommand(".bot", "查询当前拥有的机器人信息", { hidden: true })
|
|
84
|
+
.usage("查询当前拥有的机器人信息")
|
|
85
|
+
.example("status bot 查询当前拥有的机器人信息")
|
|
79
86
|
.action(() => {
|
|
80
|
-
this.logger.info(
|
|
81
|
-
ctx.bots
|
|
82
|
-
this.logger.info(
|
|
83
|
-
this.logger.info(
|
|
84
|
-
this.logger.info(
|
|
85
|
-
this.logger.info(
|
|
86
|
-
}
|
|
87
|
+
this.logger.info("开始输出BOT信息");
|
|
88
|
+
for (const bot of ctx.bots) {
|
|
89
|
+
this.logger.info("--------------------------------");
|
|
90
|
+
this.logger.info(`平台:${bot.platform}`);
|
|
91
|
+
this.logger.info(`名称:${bot.user.name}`);
|
|
92
|
+
this.logger.info("--------------------------------");
|
|
93
|
+
}
|
|
87
94
|
});
|
|
88
95
|
statusCom
|
|
89
|
-
.subcommand(
|
|
90
|
-
.usage(
|
|
91
|
-
.example(
|
|
96
|
+
.subcommand(".env", "查询当前环境的信息", { hidden: true })
|
|
97
|
+
.usage("查询当前环境的信息")
|
|
98
|
+
.example("status env 查询当前环境的信息")
|
|
92
99
|
.action(async ({ session }) => {
|
|
93
100
|
await session.send(`Guild ID:${session.event.guild.id}`);
|
|
94
101
|
await session.send(`Channel ID: ${session.event.channel.id}`);
|
|
95
102
|
});
|
|
96
|
-
const biliCom = ctx.command(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
const biliCom = ctx.command("bili", "bili-notify插件相关指令", {
|
|
104
|
+
permissions: ["authority:3"],
|
|
105
|
+
});
|
|
106
|
+
biliCom
|
|
107
|
+
.subcommand(".login", "登录B站之后才可以进行之后的操作")
|
|
108
|
+
.usage("使用二维码登录,登录B站之后才可以进行之后的操作")
|
|
109
|
+
.example("bili login")
|
|
100
110
|
.action(async ({ session }) => {
|
|
101
|
-
this.logger.info(
|
|
111
|
+
this.logger.info("调用bili login指令");
|
|
102
112
|
// 获取二维码
|
|
113
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
103
114
|
let content;
|
|
104
115
|
try {
|
|
105
116
|
content = await ctx.ba.getLoginQRCode();
|
|
106
117
|
}
|
|
107
118
|
catch (e) {
|
|
108
|
-
return
|
|
119
|
+
return "bili login getLoginQRCode() 本次网络请求失败";
|
|
109
120
|
}
|
|
110
121
|
// 判断是否出问题
|
|
111
122
|
if (content.code !== 0)
|
|
112
|
-
return await session.send(
|
|
123
|
+
return await session.send("出问题咯,请联系管理员解决");
|
|
113
124
|
// 生成二维码
|
|
114
125
|
qrcode_1.default.toBuffer(content.data.url, {
|
|
115
|
-
errorCorrectionLevel:
|
|
116
|
-
type:
|
|
126
|
+
errorCorrectionLevel: "H", // 错误更正水平
|
|
127
|
+
type: "png", // 输出类型
|
|
117
128
|
margin: 1, // 边距大小
|
|
118
129
|
color: {
|
|
119
|
-
dark:
|
|
120
|
-
light:
|
|
121
|
-
}
|
|
130
|
+
dark: "#000000", // 二维码颜色
|
|
131
|
+
light: "#FFFFFF", // 背景颜色
|
|
132
|
+
},
|
|
122
133
|
}, async (err, buffer) => {
|
|
123
134
|
if (err)
|
|
124
|
-
return await session.send(
|
|
125
|
-
await session.send(koishi_1.h.image(buffer,
|
|
135
|
+
return await session.send("二维码生成出错,请重新尝试");
|
|
136
|
+
await session.send(koishi_1.h.image(buffer, "image/png"));
|
|
126
137
|
});
|
|
127
138
|
// 检查之前是否存在登录定时器
|
|
128
139
|
if (this.loginTimer)
|
|
@@ -137,6 +148,7 @@ class ComRegister {
|
|
|
137
148
|
return;
|
|
138
149
|
flag = false;
|
|
139
150
|
// 获取登录信息
|
|
151
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
140
152
|
let loginContent;
|
|
141
153
|
try {
|
|
142
154
|
loginContent = await ctx.ba.getLoginStatus(content.data.qrcode_key);
|
|
@@ -147,33 +159,35 @@ class ComRegister {
|
|
|
147
159
|
}
|
|
148
160
|
if (loginContent.code !== 0) {
|
|
149
161
|
this.loginTimer();
|
|
150
|
-
return await session.send(
|
|
162
|
+
return await session.send("登录失败请重试");
|
|
151
163
|
}
|
|
152
164
|
if (loginContent.data.code === 86038) {
|
|
153
165
|
this.loginTimer();
|
|
154
|
-
return await session.send(
|
|
166
|
+
return await session.send("二维码已失效,请重新登录");
|
|
155
167
|
}
|
|
156
|
-
if (loginContent.data.code === 0) {
|
|
168
|
+
if (loginContent.data.code === 0) {
|
|
169
|
+
// 登录成功
|
|
157
170
|
const encryptedCookies = ctx.ba.encrypt(ctx.ba.getCookies());
|
|
158
171
|
const encryptedRefreshToken = ctx.ba.encrypt(loginContent.data.refresh_token);
|
|
159
|
-
await ctx.database.upsert(
|
|
172
|
+
await ctx.database.upsert("loginBili", [
|
|
173
|
+
{
|
|
160
174
|
id: 1,
|
|
161
175
|
bili_cookies: encryptedCookies,
|
|
162
|
-
bili_refresh_token: encryptedRefreshToken
|
|
163
|
-
}
|
|
176
|
+
bili_refresh_token: encryptedRefreshToken,
|
|
177
|
+
},
|
|
178
|
+
]);
|
|
164
179
|
// 销毁定时器
|
|
165
180
|
this.loginTimer();
|
|
166
|
-
//
|
|
167
|
-
await this.
|
|
181
|
+
// 订阅手动订阅中的订阅
|
|
182
|
+
await this.loadSubFromConfig(config.sub);
|
|
168
183
|
// 清除控制台通知
|
|
169
184
|
ctx.ba.disposeNotifier();
|
|
170
185
|
// 发送成功登录推送
|
|
171
|
-
await session.send(
|
|
186
|
+
await session.send("登录成功");
|
|
172
187
|
// bili show
|
|
173
|
-
await session.execute(
|
|
188
|
+
await session.execute("bili show");
|
|
174
189
|
// 开启cookies刷新检测
|
|
175
190
|
ctx.ba.enableRefreshCookiesDetect();
|
|
176
|
-
return;
|
|
177
191
|
}
|
|
178
192
|
}
|
|
179
193
|
finally {
|
|
@@ -182,428 +196,143 @@ class ComRegister {
|
|
|
182
196
|
}, 1000);
|
|
183
197
|
});
|
|
184
198
|
biliCom
|
|
185
|
-
.subcommand(
|
|
186
|
-
.usage(
|
|
187
|
-
.
|
|
188
|
-
.option('dynamic', '-d')
|
|
189
|
-
.example('bili unsub 用户UID -ld')
|
|
190
|
-
.action(async ({ session, options }, uid) => {
|
|
191
|
-
this.logger.info('调用bili.unsub指令');
|
|
192
|
-
// 若用户UID为空则直接返回
|
|
193
|
-
if (!uid)
|
|
194
|
-
return '用户UID不能为空';
|
|
195
|
-
// -d -l两个选项不能同时存在
|
|
196
|
-
if (options.dynamic && options.live)
|
|
197
|
-
return '需要取消订阅该UP主请直接使用指令bili unsub 用户UID';
|
|
198
|
-
// 定义是否存在
|
|
199
|
-
let exist;
|
|
200
|
-
await Promise.all(this.subManager.map(async (sub, i) => {
|
|
201
|
-
if (sub.uid === uid) {
|
|
202
|
-
// 取消单个订阅
|
|
203
|
-
if (options.live || options.dynamic) {
|
|
204
|
-
if (options.live)
|
|
205
|
-
await session.send(this.unsubSingle(sub.roomId, 0)); /* 0为取消订阅Live */
|
|
206
|
-
if (options.dynamic)
|
|
207
|
-
await session.send(this.unsubSingle(sub.uid, 1)); /* 1为取消订阅Dynamic */
|
|
208
|
-
// 将存在flag设置为true
|
|
209
|
-
exist = true;
|
|
210
|
-
// 结束循环
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
// 从数据库中删除订阅
|
|
214
|
-
await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
|
|
215
|
-
// 将该订阅对象从订阅管理对象中移除
|
|
216
|
-
this.subManager.splice(i, 1);
|
|
217
|
-
// 将订阅对象移出订阅关注组
|
|
218
|
-
const removeUserFromGroupData = await ctx.ba.removeUserFromGroup(sub.uid);
|
|
219
|
-
// 判断是否移出成功 22105关注对象为自己
|
|
220
|
-
if (removeUserFromGroupData.code !== 0 && removeUserFromGroupData.code !== 22105) {
|
|
221
|
-
// 移出失败
|
|
222
|
-
await session.send('取消订阅对象失败,请稍后重试');
|
|
223
|
-
// 将存在flag设置为true
|
|
224
|
-
exist = true;
|
|
225
|
-
// 结束循环
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
// id--
|
|
229
|
-
this.num--;
|
|
230
|
-
// 判断是否还有动态订阅
|
|
231
|
-
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
232
|
-
// 发送成功通知
|
|
233
|
-
await session.send('已取消订阅该用户');
|
|
234
|
-
// 更新控制台提示
|
|
235
|
-
this.updateSubNotifier();
|
|
236
|
-
// 将存在flag设置为true
|
|
237
|
-
exist = true;
|
|
238
|
-
}
|
|
239
|
-
}));
|
|
240
|
-
// 未订阅该用户,无需取消订阅
|
|
241
|
-
if (!exist)
|
|
242
|
-
await session.send('未订阅该用户,无需取消订阅');
|
|
243
|
-
});
|
|
244
|
-
biliCom
|
|
245
|
-
.subcommand('.show', '展示订阅对象')
|
|
246
|
-
.usage('展示订阅对象')
|
|
247
|
-
.example('bili show')
|
|
199
|
+
.subcommand(".list", "展示订阅对象")
|
|
200
|
+
.usage("展示订阅对象")
|
|
201
|
+
.example("bili list")
|
|
248
202
|
.action(() => {
|
|
249
203
|
const subTable = this.subShow();
|
|
250
204
|
return subTable;
|
|
251
205
|
});
|
|
252
206
|
biliCom
|
|
253
|
-
.subcommand(
|
|
254
|
-
.
|
|
255
|
-
.
|
|
256
|
-
.option('dynamic', '-d')
|
|
257
|
-
.option('atAll', '-a')
|
|
258
|
-
.usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d')
|
|
259
|
-
.example('bili sub 1194210119 目标群号或频道号 -l -d 订阅UID为1194210119的UP主的动态和直播')
|
|
260
|
-
.action(async ({ session, options }, mid, ...groupId) => {
|
|
261
|
-
this.logger.info('调用bili.sub指令');
|
|
262
|
-
// 先判断是否订阅直播,再判断是否解锁订阅限制,最后判断直播订阅是否已超三个
|
|
263
|
-
if (options.live && !this.config.unlockSubLimits && (this.subManager.reduce((acc, cur) => acc + (cur.live ? 1 : 0), 0) >= 3)) {
|
|
264
|
-
return '直播订阅已达上限,请取消部分直播订阅后再进行订阅';
|
|
265
|
-
}
|
|
266
|
-
// 检查是否登录
|
|
267
|
-
if (!(await this.checkIfIsLogin())) {
|
|
268
|
-
// 未登录直接返回
|
|
269
|
-
return '请使用指令bili login登录后再进行订阅操作';
|
|
270
|
-
}
|
|
271
|
-
// 检查必选参数是否已填
|
|
272
|
-
if (!mid)
|
|
273
|
-
return '请输入用户uid';
|
|
274
|
-
// 订阅对象
|
|
275
|
-
const subUserData = await this.subUserInBili(mid);
|
|
276
|
-
// 判断是否订阅对象存在
|
|
277
|
-
if (!subUserData.flag)
|
|
278
|
-
return '订阅对象失败,请稍后重试!';
|
|
279
|
-
// 定义目标变量
|
|
280
|
-
let target = [];
|
|
281
|
-
// 判断是否使用了多群组推送
|
|
282
|
-
if (groupId.length > 0) {
|
|
283
|
-
// 定义channelIdArr
|
|
284
|
-
const channelIdArr = [];
|
|
285
|
-
// 遍历输入的群组
|
|
286
|
-
groupId.forEach(group => {
|
|
287
|
-
channelIdArr.push({
|
|
288
|
-
channelId: group,
|
|
289
|
-
dynamic: true,
|
|
290
|
-
live: true,
|
|
291
|
-
liveDanmaku: false,
|
|
292
|
-
atAll: options.atAll
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
target.push({
|
|
296
|
-
channelIdArr,
|
|
297
|
-
platform: session.event.platform
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
// 判断是否使用多平台功能
|
|
302
|
-
if (options.multiplatform) {
|
|
303
|
-
// 分割字符串,赋值给target
|
|
304
|
-
target = this.splitMultiPlatformStr(options.multiplatform);
|
|
305
|
-
}
|
|
306
|
-
// 判断是否使用了多平台
|
|
307
|
-
if (target.length > 0) {
|
|
308
|
-
for (const [index, { channelIdArr, platform }] of target.entries()) {
|
|
309
|
-
if (channelIdArr.length > 0) { // 输入了推送群号或频道号
|
|
310
|
-
// 拿到对应的bot
|
|
311
|
-
const bot = this.getBot(platform);
|
|
312
|
-
// 判断是否配置了对应平台的机器人
|
|
313
|
-
if (!ctx.bots.some(bot => bot.platform === platform)) {
|
|
314
|
-
// 发送提示消息
|
|
315
|
-
await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
|
|
316
|
-
// 直接返回
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
// 判断是否需要加入的群全部推送
|
|
320
|
-
if (channelIdArr[0].channelId !== 'all') {
|
|
321
|
-
// 定义满足条件的群组数组
|
|
322
|
-
const targetArr = [];
|
|
323
|
-
// 获取机器人加入的群组
|
|
324
|
-
const guildList = await bot.getGuildList();
|
|
325
|
-
// 遍历target数组
|
|
326
|
-
for (const channelId of channelIdArr) {
|
|
327
|
-
// 定义是否加入群组标志
|
|
328
|
-
let flag = false;
|
|
329
|
-
// 遍历群组
|
|
330
|
-
for (const guild of guildList.data) {
|
|
331
|
-
// 获取频道列表
|
|
332
|
-
const channelList = await bot.getChannelList(guild.id);
|
|
333
|
-
// 判断机器人是否加入群聊或频道
|
|
334
|
-
if (channelList.data.some(channel => channel.id === channelId.channelId)) {
|
|
335
|
-
// 加入群聊或频道
|
|
336
|
-
targetArr.push(channelId);
|
|
337
|
-
// 设置标志位为true
|
|
338
|
-
flag = true;
|
|
339
|
-
// 结束循环
|
|
340
|
-
break;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
if (!flag) {
|
|
344
|
-
// 不满足条件发送错误提示
|
|
345
|
-
await session.send(`您的机器未加入${channelId.channelId},无法对该群或频道进行推送`);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
// 判断targetArr是否为空
|
|
349
|
-
if (target.length === 0) {
|
|
350
|
-
// 为空则默认为当前环境
|
|
351
|
-
target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
|
|
352
|
-
// 没有满足条件的群组或频道
|
|
353
|
-
await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
|
|
354
|
-
}
|
|
355
|
-
// 将符合条件的群组添加到target中
|
|
356
|
-
target[index].channelIdArr = targetArr;
|
|
357
|
-
}
|
|
358
|
-
// 如果为all则全部推送,不需要进行处理
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
// 未填写群号或频道号,默认为当前环境
|
|
362
|
-
target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
|
|
363
|
-
// 发送提示消息
|
|
364
|
-
await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
// 用户直接订阅,将当前环境赋值给target
|
|
370
|
-
target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
// 定义外围变量
|
|
374
|
-
let content;
|
|
375
|
-
try {
|
|
376
|
-
// 获取用户信息
|
|
377
|
-
content = await ctx.ba.getUserInfo(mid);
|
|
378
|
-
}
|
|
379
|
-
catch (e) {
|
|
380
|
-
// 返回错误信息
|
|
381
|
-
return 'bili sub getUserInfo() 发生了错误,错误为:' + e.message;
|
|
382
|
-
}
|
|
383
|
-
// 判断是否成功获取用户信息
|
|
384
|
-
if (content.code !== 0) {
|
|
385
|
-
// 定义错误消息
|
|
386
|
-
let msg;
|
|
387
|
-
// 判断错误代码
|
|
388
|
-
switch (content.code) {
|
|
389
|
-
case -400:
|
|
390
|
-
msg = '请求错误';
|
|
391
|
-
break;
|
|
392
|
-
case -403:
|
|
393
|
-
msg = '访问权限不足,请尝试重新登录';
|
|
394
|
-
break;
|
|
395
|
-
case -404:
|
|
396
|
-
msg = '用户不存在';
|
|
397
|
-
break;
|
|
398
|
-
case -352:
|
|
399
|
-
msg = '风控校验失败,请尝试更换UA';
|
|
400
|
-
break;
|
|
401
|
-
default:
|
|
402
|
-
msg = '未知错误,错误信息:' + content.message;
|
|
403
|
-
break;
|
|
404
|
-
}
|
|
405
|
-
// 返回错误信息
|
|
406
|
-
return msg;
|
|
407
|
-
}
|
|
408
|
-
// 获取data
|
|
409
|
-
const { data } = content;
|
|
410
|
-
// 判断是否需要订阅直播和动态
|
|
411
|
-
const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data.live_room);
|
|
412
|
-
// 判断是否未订阅任何消息
|
|
413
|
-
if (!liveMsg && !dynamicMsg)
|
|
414
|
-
return '您未订阅该UP的任何消息';
|
|
415
|
-
// 获取到对应的订阅对象
|
|
416
|
-
const subUser = this.subManager.find(sub => sub.uid === mid);
|
|
417
|
-
// 判断要订阅的用户是否已经存在于订阅管理对象中
|
|
418
|
-
if (subUser) {
|
|
419
|
-
// 已存在,判断是否重复订阅直播通知
|
|
420
|
-
if (liveMsg && subUser.live) {
|
|
421
|
-
return '已订阅该用户直播通知,请勿重复订阅';
|
|
422
|
-
}
|
|
423
|
-
// 已存在,判断是否重复订阅动态通知
|
|
424
|
-
if (dynamicMsg && subUser.dynamic) {
|
|
425
|
-
return '已订阅该用户动态通知,请勿重复订阅';
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
// 获取直播房间号
|
|
429
|
-
const roomId = data.live_room?.roomid.toString();
|
|
430
|
-
// 获取用户信息
|
|
431
|
-
let userData;
|
|
432
|
-
try {
|
|
433
|
-
const { data } = await ctx.ba.getMasterInfo(mid);
|
|
434
|
-
userData = data;
|
|
435
|
-
}
|
|
436
|
-
catch (e) {
|
|
437
|
-
this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
438
|
-
return '订阅出错啦,请重试';
|
|
439
|
-
}
|
|
440
|
-
// 订阅直播
|
|
441
|
-
if (liveMsg) {
|
|
442
|
-
// 连接到服务器
|
|
443
|
-
this.liveDetectWithListener(roomId, target);
|
|
444
|
-
// 发送订阅消息通知
|
|
445
|
-
await session.send(`订阅${userData.info.uname}直播通知`);
|
|
446
|
-
}
|
|
447
|
-
// 订阅动态
|
|
448
|
-
if (dynamicMsg) {
|
|
449
|
-
// 判断是否开启动态监测
|
|
450
|
-
if (!this.dynamicDispose) {
|
|
451
|
-
this.enableDynamicDetect();
|
|
452
|
-
}
|
|
453
|
-
// 发送订阅消息通知
|
|
454
|
-
await session.send(`订阅${userData.info.uname}动态通知`);
|
|
455
|
-
}
|
|
456
|
-
// 保存到数据库中
|
|
457
|
-
const sub = await ctx.database.create('bilibili', {
|
|
458
|
-
uid: mid,
|
|
459
|
-
room_id: roomId,
|
|
460
|
-
dynamic: dynamicMsg ? 1 : 0,
|
|
461
|
-
live: liveMsg ? 1 : 0,
|
|
462
|
-
target: JSON.stringify(target),
|
|
463
|
-
platform: session.event.platform,
|
|
464
|
-
time: new Date()
|
|
465
|
-
});
|
|
466
|
-
// 订阅数+1
|
|
467
|
-
this.num++;
|
|
468
|
-
// 保存新订阅对象
|
|
469
|
-
this.subManager.push({
|
|
470
|
-
id: sub.id,
|
|
471
|
-
uid: mid,
|
|
472
|
-
roomId,
|
|
473
|
-
target,
|
|
474
|
-
platform: session.event.platform,
|
|
475
|
-
live: liveMsg,
|
|
476
|
-
dynamic: dynamicMsg,
|
|
477
|
-
});
|
|
478
|
-
// 新增订阅展示到控制台
|
|
479
|
-
this.updateSubNotifier();
|
|
480
|
-
});
|
|
481
|
-
biliCom
|
|
482
|
-
.subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
|
|
483
|
-
.usage('查询主播当前直播状态')
|
|
484
|
-
.example('bili status 732')
|
|
485
|
-
.action(async ({ session }, roomId) => {
|
|
486
|
-
this.logger.info('调用bili.status指令');
|
|
487
|
-
if (!roomId)
|
|
488
|
-
return session.send('请输入房间号!');
|
|
489
|
-
let content;
|
|
490
|
-
try {
|
|
491
|
-
content = await ctx.ba.getLiveRoomInfo(roomId);
|
|
492
|
-
}
|
|
493
|
-
catch (e) {
|
|
494
|
-
return 'bili status指令 getLiveRoomInfo() 发生了错误,错误为:' + e.message;
|
|
495
|
-
}
|
|
496
|
-
const { data } = content;
|
|
497
|
-
let userData;
|
|
498
|
-
try {
|
|
499
|
-
const { data: userInfo } = await ctx.ba.getMasterInfo(data.uid);
|
|
500
|
-
userData = userInfo;
|
|
501
|
-
}
|
|
502
|
-
catch (e) {
|
|
503
|
-
return 'bili status指令 getMasterInfo() 发生了错误,错误为:' + e.message;
|
|
504
|
-
}
|
|
505
|
-
// B站出问题了
|
|
506
|
-
if (content.code !== 0) {
|
|
507
|
-
if (content.msg === '未找到该房间') {
|
|
508
|
-
session.send('未找到该房间');
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
session.send('未知错误,错误信息为:' + content.message);
|
|
512
|
-
}
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
const { pic, buffer } = await ctx.gi.generateLiveImg(data, userData.info.uname, userData.info.face, data.live_status !== 1 ?
|
|
516
|
-
LiveType.NotLiveBroadcast :
|
|
517
|
-
LiveType.LiveBroadcast);
|
|
518
|
-
// pic 存在,使用的是render模式
|
|
519
|
-
if (pic)
|
|
520
|
-
return pic;
|
|
521
|
-
// pic不存在,说明使用的是page模式
|
|
522
|
-
await session.send(koishi_1.h.image(buffer, 'image/png'));
|
|
523
|
-
});
|
|
524
|
-
biliCom
|
|
525
|
-
.subcommand('.private', '向主人账号发送一条测试消息', { hidden: true })
|
|
526
|
-
.usage('向主人账号发送一条测试消息')
|
|
527
|
-
.example('bili private 向主人账号发送一条测试消息')
|
|
207
|
+
.subcommand(".private", "向主人账号发送一条测试消息", { hidden: true })
|
|
208
|
+
.usage("向主人账号发送一条测试消息")
|
|
209
|
+
.example("bili private 向主人账号发送一条测试消息")
|
|
528
210
|
.action(async ({ session }) => {
|
|
529
211
|
// 发送消息
|
|
530
|
-
await this.sendPrivateMsg(
|
|
212
|
+
await this.sendPrivateMsg("Hello World");
|
|
531
213
|
// 发送提示
|
|
532
|
-
await session.send(
|
|
214
|
+
await session.send("已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误");
|
|
533
215
|
});
|
|
534
216
|
}
|
|
535
217
|
async init(config) {
|
|
536
218
|
// 设置logger
|
|
537
|
-
this.logger = this.ctx.logger(
|
|
219
|
+
this.logger = this.ctx.logger("cr");
|
|
220
|
+
// logger
|
|
221
|
+
this.logger.info("加载订阅中...");
|
|
538
222
|
// 将config设置给类属性
|
|
539
223
|
this.config = config;
|
|
540
224
|
// 拿到私人机器人实例
|
|
541
|
-
this.privateBot = this.ctx.bots.find(bot => bot.platform === config.master.platform);
|
|
225
|
+
this.privateBot = this.ctx.bots.find((bot) => bot.platform === config.master.platform);
|
|
542
226
|
if (!this.privateBot) {
|
|
543
227
|
this.ctx.notifier.create({
|
|
544
|
-
content:
|
|
228
|
+
content: "您未配置私人机器人,将无法向您推送机器人状态!",
|
|
545
229
|
});
|
|
546
|
-
this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
|
|
547
230
|
}
|
|
548
231
|
// 判断消息发送方式
|
|
549
232
|
if (config.automaticResend) {
|
|
550
|
-
this.sendMsgFunc = async (
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
//
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
564
|
-
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ` + e.message);
|
|
565
|
-
console.log(e);
|
|
566
|
-
this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
567
|
-
}
|
|
233
|
+
this.sendMsgFunc = async (
|
|
234
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
235
|
+
bot, channelId,
|
|
236
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
237
|
+
content) => {
|
|
238
|
+
(0, utils_1.withRetry)(async () => await bot.sendMessage(channelId, content)).catch(async (e) => {
|
|
239
|
+
if (e.message === "this._request is not a function") {
|
|
240
|
+
// 2S之后重新发送消息
|
|
241
|
+
this.ctx.setTimeout(async () => {
|
|
242
|
+
await this.sendMsgFunc(bot, channelId, content);
|
|
243
|
+
}, 2000);
|
|
244
|
+
// 返回
|
|
245
|
+
return;
|
|
568
246
|
}
|
|
569
|
-
|
|
247
|
+
// 打印错误信息
|
|
248
|
+
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
|
|
249
|
+
await this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
250
|
+
});
|
|
570
251
|
};
|
|
571
252
|
}
|
|
572
253
|
else {
|
|
573
|
-
this.sendMsgFunc = async (
|
|
254
|
+
this.sendMsgFunc = async (
|
|
255
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
256
|
+
bot, channelId,
|
|
257
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
258
|
+
content) => {
|
|
574
259
|
try {
|
|
575
260
|
// 发送消息
|
|
576
|
-
await bot.sendMessage(
|
|
261
|
+
await bot.sendMessage(channelId, content);
|
|
577
262
|
}
|
|
578
263
|
catch (e) {
|
|
579
|
-
this.
|
|
580
|
-
|
|
264
|
+
if (e.message === "this._request is not a function") {
|
|
265
|
+
// 2S之后重新发送消息
|
|
266
|
+
this.ctx.setTimeout(async () => {
|
|
267
|
+
await this.sendMsgFunc(bot, channelId, content);
|
|
268
|
+
}, 2000);
|
|
269
|
+
// 返回
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// 打印错误信息
|
|
273
|
+
this.logger.error(`发送群组ID:${channelId}消息失败!原因: ${e.message}`);
|
|
274
|
+
await this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
|
|
581
275
|
}
|
|
582
276
|
};
|
|
583
277
|
}
|
|
584
278
|
// 检查登录数据库是否有数据
|
|
585
|
-
this.loginDBData = (await this.ctx.database.get(
|
|
279
|
+
this.loginDBData = (await this.ctx.database.get("loginBili", 1, ["dynamic_group_id"]))[0];
|
|
280
|
+
// 判断登录信息是否已加载完毕
|
|
281
|
+
await this.checkIfLoginInfoIsLoaded();
|
|
282
|
+
// 如果未登录,则直接返回
|
|
283
|
+
if (!(await this.checkIfIsLogin())) {
|
|
284
|
+
// log
|
|
285
|
+
this.logger.info("账号未登录,请登录");
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
586
288
|
// 从配置获取订阅
|
|
587
|
-
config.sub && await this.loadSubFromConfig(config.sub);
|
|
588
|
-
// 从数据库获取订阅
|
|
589
|
-
await this.loadSubFromDatabase();
|
|
289
|
+
config.sub && (await this.loadSubFromConfig(config.sub));
|
|
590
290
|
// 检查是否需要动态监测
|
|
591
291
|
this.checkIfDynamicDetectIsNeeded();
|
|
592
292
|
// 在控制台中显示订阅对象
|
|
593
293
|
this.updateSubNotifier();
|
|
294
|
+
// logger
|
|
295
|
+
this.logger.info("订阅加载完毕!");
|
|
594
296
|
}
|
|
595
|
-
|
|
596
|
-
return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
|
|
597
|
-
const channelIdArr = idStr.split(',').map(id => {
|
|
598
|
-
const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
|
|
599
|
-
const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
|
|
600
|
-
return { channelId, dynamic: true, live: true, liveDanmaku: false, atAll };
|
|
601
|
-
});
|
|
602
|
-
return { channelIdArr, platform };
|
|
603
|
-
});
|
|
604
|
-
}
|
|
297
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
605
298
|
getBot(pf) {
|
|
606
|
-
return this.ctx.bots.find(bot => bot.platform === pf);
|
|
299
|
+
return this.ctx.bots.find((bot) => bot.platform === pf);
|
|
300
|
+
}
|
|
301
|
+
// TODO:WordCloud
|
|
302
|
+
async test_wordCloud() {
|
|
303
|
+
/* const currentLiveDanmakuArr = []
|
|
304
|
+
// 定义获取弹幕权重Record函数
|
|
305
|
+
const getDanmakuWeightRecord = (): Record<string, number> => {
|
|
306
|
+
// 创建segmentit
|
|
307
|
+
const segmentit = useDefault(new Segment());
|
|
308
|
+
// 创建Record
|
|
309
|
+
const danmakuWeightRecord: Record<string, number> = {};
|
|
310
|
+
// 循环遍历currentLiveDanmakuArr
|
|
311
|
+
for (const danmaku of currentLiveDanmakuArr) {
|
|
312
|
+
// 遍历结果
|
|
313
|
+
segmentit.doSegment(danmaku).map((word: { w: string; p: number }) => {
|
|
314
|
+
// 定义权重
|
|
315
|
+
danmakuWeightRecord[word.w] = (danmakuWeightRecord[word.w] || 0) + 1;
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
// 返回Record
|
|
319
|
+
return danmakuWeightRecord;
|
|
320
|
+
}; */
|
|
321
|
+
// Test
|
|
322
|
+
const testTarget = [
|
|
323
|
+
{
|
|
324
|
+
channelIdArr: [
|
|
325
|
+
{
|
|
326
|
+
channelId: "635762054",
|
|
327
|
+
dynamic: true,
|
|
328
|
+
live: false,
|
|
329
|
+
liveGuardBuy: false,
|
|
330
|
+
atAll: false,
|
|
331
|
+
},
|
|
332
|
+
],
|
|
333
|
+
platform: "qqguild",
|
|
334
|
+
},
|
|
335
|
+
];
|
|
607
336
|
}
|
|
608
337
|
async sendPrivateMsg(content) {
|
|
609
338
|
if (this.config.master.enable) {
|
|
@@ -621,9 +350,9 @@ class ComRegister {
|
|
|
621
350
|
// 判断重启次数是否超过三次
|
|
622
351
|
if (this.rebootCount >= 3) {
|
|
623
352
|
// logger
|
|
624
|
-
this.logger.error(
|
|
353
|
+
this.logger.error("已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件");
|
|
625
354
|
// 重启失败,发送消息
|
|
626
|
-
await this.sendPrivateMsg(
|
|
355
|
+
await this.sendPrivateMsg("已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件");
|
|
627
356
|
// 关闭插件
|
|
628
357
|
await this.ctx.sm.disposePlugin();
|
|
629
358
|
// 结束
|
|
@@ -632,32 +361,33 @@ class ComRegister {
|
|
|
632
361
|
// 重启次数+1
|
|
633
362
|
this.rebootCount++;
|
|
634
363
|
// logger
|
|
635
|
-
this.logger.info(
|
|
364
|
+
this.logger.info("插件出现未知错误,正在重启插件");
|
|
636
365
|
// 重启插件
|
|
637
366
|
const flag = await this.ctx.sm.restartPlugin();
|
|
638
367
|
// 判断是否重启成功
|
|
639
368
|
if (flag) {
|
|
640
|
-
this.logger.info(
|
|
369
|
+
this.logger.info("重启插件成功");
|
|
641
370
|
}
|
|
642
371
|
else {
|
|
643
372
|
// logger
|
|
644
|
-
this.logger.error(
|
|
373
|
+
this.logger.error("重启插件失败,请检查机器人状态后使用指令 sys start 启动插件");
|
|
645
374
|
// 重启失败,发送消息
|
|
646
|
-
await this.sendPrivateMsg(
|
|
375
|
+
await this.sendPrivateMsg("重启插件失败,请检查机器人状态后使用指令 sys start 启动插件");
|
|
647
376
|
// 关闭插件
|
|
648
377
|
await this.ctx.sm.disposePlugin();
|
|
649
378
|
}
|
|
650
379
|
}
|
|
651
380
|
async sendPrivateMsgAndStopService() {
|
|
652
381
|
// 发送消息
|
|
653
|
-
await this.sendPrivateMsg(
|
|
382
|
+
await this.sendPrivateMsg("插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件");
|
|
654
383
|
// logger
|
|
655
|
-
this.logger.error(
|
|
384
|
+
this.logger.error("插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件");
|
|
656
385
|
// 关闭插件
|
|
657
386
|
await this.ctx.sm.disposePlugin();
|
|
658
387
|
// 结束
|
|
659
388
|
return;
|
|
660
389
|
}
|
|
390
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
661
391
|
async sendMsg(targets, content, live) {
|
|
662
392
|
for (const target of targets) {
|
|
663
393
|
// 获取机器人实例
|
|
@@ -665,15 +395,15 @@ class ComRegister {
|
|
|
665
395
|
// 定义需要发送的数组
|
|
666
396
|
let sendArr = [];
|
|
667
397
|
// 判断是否需要推送所有机器人加入的群
|
|
668
|
-
if (target.channelIdArr[0].channelId ===
|
|
398
|
+
if (target.channelIdArr[0].channelId === "all") {
|
|
669
399
|
// 获取所有guild
|
|
670
400
|
for (const guild of (await bot.getGuildList()).data) {
|
|
671
401
|
sendArr.push({
|
|
672
402
|
channelId: guild.id,
|
|
673
403
|
dynamic: target.channelIdArr[0].dynamic,
|
|
674
404
|
live: target.channelIdArr[0].live,
|
|
675
|
-
|
|
676
|
-
atAll: target.channelIdArr[0].atAll
|
|
405
|
+
liveGuardBuy: target.channelIdArr[0].liveGuardBuy,
|
|
406
|
+
atAll: target.channelIdArr[0].atAll,
|
|
677
407
|
});
|
|
678
408
|
}
|
|
679
409
|
}
|
|
@@ -696,7 +426,7 @@ class ComRegister {
|
|
|
696
426
|
}
|
|
697
427
|
else {
|
|
698
428
|
for (const channel of sendArr) {
|
|
699
|
-
//
|
|
429
|
+
// 判断是否需要推送动态消息
|
|
700
430
|
if (channel.dynamic || channel.live) {
|
|
701
431
|
await this.sendMsgFunc(bot, channel.channelId, content);
|
|
702
432
|
}
|
|
@@ -724,7 +454,7 @@ class ComRegister {
|
|
|
724
454
|
// 检测启动初始化
|
|
725
455
|
if (detectSetup) {
|
|
726
456
|
// 获取动态信息
|
|
727
|
-
const data = await this.ctx.ba.getAllDynamic();
|
|
457
|
+
const data = (await this.ctx.ba.getAllDynamic());
|
|
728
458
|
// 判断获取动态信息是否成功
|
|
729
459
|
if (data.code !== 0)
|
|
730
460
|
return;
|
|
@@ -737,6 +467,7 @@ class ComRegister {
|
|
|
737
467
|
}
|
|
738
468
|
// 获取用户所有动态数据
|
|
739
469
|
let updateNum;
|
|
470
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
740
471
|
let content;
|
|
741
472
|
try {
|
|
742
473
|
// 查询是否有新动态
|
|
@@ -746,46 +477,50 @@ class ComRegister {
|
|
|
746
477
|
if (updateNum <= 0 || data.code !== 0)
|
|
747
478
|
return;
|
|
748
479
|
// 获取动态内容
|
|
749
|
-
content = await this.ctx.ba.getAllDynamic(updateBaseline);
|
|
480
|
+
content = (await this.ctx.ba.getAllDynamic(updateBaseline));
|
|
750
481
|
}
|
|
751
482
|
catch (e) {
|
|
752
|
-
return this.logger.error(
|
|
483
|
+
return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
|
|
753
484
|
}
|
|
754
485
|
// 判断获取动态内容是否成功
|
|
755
486
|
if (content.code !== 0) {
|
|
756
487
|
switch (content.code) {
|
|
757
|
-
case -101: {
|
|
488
|
+
case -101: {
|
|
489
|
+
// 账号未登录
|
|
758
490
|
// 输出日志
|
|
759
|
-
this.logger.error(
|
|
491
|
+
this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
|
|
760
492
|
// 发送私聊消息
|
|
761
|
-
await this.sendPrivateMsg(
|
|
493
|
+
await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
|
|
762
494
|
// 停止服务
|
|
763
495
|
await this.ctx.sm.disposePlugin();
|
|
764
496
|
// 结束循环
|
|
765
497
|
break;
|
|
766
498
|
}
|
|
767
|
-
case -352: {
|
|
499
|
+
case -352: {
|
|
500
|
+
// 风控
|
|
768
501
|
// 输出日志
|
|
769
|
-
this.logger.error(
|
|
502
|
+
this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
|
|
770
503
|
// 发送私聊消息
|
|
771
|
-
await this.sendPrivateMsg(
|
|
504
|
+
await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
|
|
772
505
|
// 停止服务
|
|
773
506
|
await this.ctx.sm.disposePlugin();
|
|
774
507
|
// 结束循环
|
|
775
508
|
break;
|
|
776
509
|
}
|
|
777
510
|
case 4101128:
|
|
778
|
-
case 4101129: {
|
|
511
|
+
case 4101129: {
|
|
512
|
+
// 获取动态信息错误
|
|
779
513
|
// 输出日志
|
|
780
|
-
this.logger.error(
|
|
514
|
+
this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
|
|
781
515
|
// 发送私聊消息
|
|
782
|
-
await this.sendPrivateMsg(
|
|
516
|
+
await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
|
|
783
517
|
// 结束循环
|
|
784
518
|
break;
|
|
785
519
|
}
|
|
786
|
-
default: {
|
|
520
|
+
default: {
|
|
521
|
+
// 未知错误
|
|
787
522
|
// 发送私聊消息
|
|
788
|
-
await this.sendPrivateMsg(
|
|
523
|
+
await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
|
|
789
524
|
// 结束循环
|
|
790
525
|
break;
|
|
791
526
|
}
|
|
@@ -805,9 +540,11 @@ class ComRegister {
|
|
|
805
540
|
// 从动态数据中取出UP主名称、UID和动态ID
|
|
806
541
|
const upUID = items[num].modules.module_author.mid;
|
|
807
542
|
// 寻找关注的UP主的动态
|
|
808
|
-
this.subManager
|
|
543
|
+
for (const sub of this.subManager) {
|
|
809
544
|
// 判断是否是订阅的UP主
|
|
810
|
-
|
|
545
|
+
// biome-ignore lint/suspicious/noDoubleEquals: <explanation>
|
|
546
|
+
if (sub.dynamic && sub.uid == upUID) {
|
|
547
|
+
// 订阅该UP主,推送该动态
|
|
811
548
|
// 判断更新动态是否为1条
|
|
812
549
|
if (updateNum === 1) {
|
|
813
550
|
// 判断dynamicIdStr是否有值,是否与当前动态ID一致
|
|
@@ -839,16 +576,16 @@ class ComRegister {
|
|
|
839
576
|
}
|
|
840
577
|
catch (e) {
|
|
841
578
|
// 直播开播动态,不做处理
|
|
842
|
-
if (e.message ===
|
|
579
|
+
if (e.message === "直播开播动态,不做处理")
|
|
843
580
|
return;
|
|
844
|
-
if (e.message ===
|
|
581
|
+
if (e.message === "出现关键词,屏蔽该动态") {
|
|
845
582
|
// 如果需要发送才发送
|
|
846
583
|
if (this.config.filter.notify) {
|
|
847
584
|
await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
|
|
848
585
|
}
|
|
849
586
|
return;
|
|
850
587
|
}
|
|
851
|
-
if (e.message ===
|
|
588
|
+
if (e.message === "已屏蔽转发动态") {
|
|
852
589
|
if (this.config.filter.notify) {
|
|
853
590
|
await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
|
|
854
591
|
}
|
|
@@ -856,30 +593,32 @@ class ComRegister {
|
|
|
856
593
|
}
|
|
857
594
|
// 未知错误
|
|
858
595
|
if (i === attempts - 1) {
|
|
859
|
-
this.logger.error(
|
|
596
|
+
this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
|
|
860
597
|
// 发送私聊消息并重启服务
|
|
861
598
|
return await this.sendPrivateMsgAndStopService();
|
|
862
599
|
}
|
|
863
600
|
}
|
|
864
601
|
}
|
|
865
602
|
// 判断是否需要发送URL
|
|
866
|
-
const dUrl = this.config.dynamicUrl
|
|
603
|
+
const dUrl = this.config.dynamicUrl
|
|
604
|
+
? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
|
|
605
|
+
: "";
|
|
867
606
|
// 如果pic存在,则直接返回pic
|
|
868
607
|
if (pic) {
|
|
869
|
-
this.logger.info(
|
|
608
|
+
this.logger.info("推送动态中,使用render模式");
|
|
870
609
|
// pic存在,使用的是render模式
|
|
871
|
-
await this.sendMsg(sub.target, pic +
|
|
610
|
+
await this.sendMsg(sub.target, pic + dUrl);
|
|
872
611
|
}
|
|
873
612
|
else if (buffer) {
|
|
874
|
-
this.logger.info(
|
|
613
|
+
this.logger.info("推送动态中,使用page模式");
|
|
875
614
|
// pic不存在,说明使用的是page模式
|
|
876
|
-
await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer,
|
|
615
|
+
await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
|
|
877
616
|
}
|
|
878
617
|
else {
|
|
879
|
-
this.logger.info(items[num].modules.module_author.name
|
|
618
|
+
this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
|
|
880
619
|
}
|
|
881
620
|
}
|
|
882
|
-
}
|
|
621
|
+
}
|
|
883
622
|
}
|
|
884
623
|
}
|
|
885
624
|
finally {
|
|
@@ -908,7 +647,7 @@ class ComRegister {
|
|
|
908
647
|
// 检测启动初始化
|
|
909
648
|
if (detectSetup) {
|
|
910
649
|
// 获取动态信息
|
|
911
|
-
const data = await this.ctx.ba.getAllDynamic();
|
|
650
|
+
const data = (await this.ctx.ba.getAllDynamic());
|
|
912
651
|
// 判断获取动态信息是否成功
|
|
913
652
|
if (data.code !== 0)
|
|
914
653
|
return;
|
|
@@ -922,59 +661,65 @@ class ComRegister {
|
|
|
922
661
|
}
|
|
923
662
|
// 获取用户所有动态数据
|
|
924
663
|
let updateNum;
|
|
664
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
925
665
|
let content;
|
|
926
666
|
try {
|
|
927
667
|
// 查询是否有新动态
|
|
928
668
|
const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
|
|
929
669
|
updateNum = data.data.update_num;
|
|
670
|
+
// biome-ignore lint/style/noUnusedTemplateLiteral: <explanation>
|
|
930
671
|
console.log(`获取是否有新动态:`);
|
|
931
672
|
console.log(data);
|
|
932
673
|
// 没有新动态或获取动态信息失败直接返回
|
|
933
674
|
if (updateNum <= 0 || data.code !== 0)
|
|
934
675
|
return;
|
|
935
676
|
// 获取动态内容
|
|
936
|
-
content = await this.ctx.ba.getAllDynamic(updateBaseline);
|
|
937
|
-
console.log(
|
|
677
|
+
content = (await this.ctx.ba.getAllDynamic(updateBaseline));
|
|
678
|
+
console.log("获取动态内容:");
|
|
938
679
|
console.log(content.data.items[0]);
|
|
939
680
|
}
|
|
940
681
|
catch (e) {
|
|
941
|
-
return this.logger.error(
|
|
682
|
+
return this.logger.error(`dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:${e.message}`);
|
|
942
683
|
}
|
|
943
684
|
// 判断获取动态内容是否成功
|
|
944
685
|
if (content.code !== 0) {
|
|
945
686
|
switch (content.code) {
|
|
946
|
-
case -101: {
|
|
687
|
+
case -101: {
|
|
688
|
+
// 账号未登录
|
|
947
689
|
// 输出日志
|
|
948
|
-
this.logger.error(
|
|
690
|
+
this.logger.error("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
|
|
949
691
|
// 发送私聊消息
|
|
950
|
-
await this.sendPrivateMsg(
|
|
692
|
+
await this.sendPrivateMsg("账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件");
|
|
951
693
|
// 停止服务
|
|
952
694
|
await this.ctx.sm.disposePlugin();
|
|
953
695
|
// 结束循环
|
|
954
696
|
break;
|
|
955
697
|
}
|
|
956
|
-
case -352: {
|
|
698
|
+
case -352: {
|
|
699
|
+
// 风控
|
|
957
700
|
// 输出日志
|
|
958
|
-
this.logger.error(
|
|
701
|
+
this.logger.error("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
|
|
959
702
|
// 发送私聊消息
|
|
960
|
-
await this.sendPrivateMsg(
|
|
703
|
+
await this.sendPrivateMsg("账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件");
|
|
961
704
|
// 停止服务
|
|
962
705
|
await this.ctx.sm.disposePlugin();
|
|
963
706
|
// 结束循环
|
|
964
707
|
break;
|
|
965
708
|
}
|
|
966
709
|
case 4101128:
|
|
967
|
-
case 4101129: {
|
|
710
|
+
case 4101129: {
|
|
711
|
+
// 获取动态信息错误
|
|
968
712
|
// 输出日志
|
|
969
|
-
this.logger.error(
|
|
713
|
+
this.logger.error(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`);
|
|
970
714
|
// 发送私聊消息
|
|
971
|
-
await this.sendPrivateMsg(
|
|
715
|
+
await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
|
|
972
716
|
// 结束循环
|
|
973
717
|
break;
|
|
974
718
|
}
|
|
975
|
-
default: {
|
|
719
|
+
default: {
|
|
720
|
+
// 未知错误
|
|
976
721
|
// 发送私聊消息
|
|
977
|
-
await this.sendPrivateMsg(
|
|
722
|
+
await this.sendPrivateMsg(`获取动态信息错误,错误码为:${content.code},错误为:${content.message}`); // 未知错误
|
|
978
723
|
// 结束循环
|
|
979
724
|
break;
|
|
980
725
|
}
|
|
@@ -990,7 +735,7 @@ class ComRegister {
|
|
|
990
735
|
// 检查更新的动态
|
|
991
736
|
for (let num = updateNum - 1; num >= 0; num--) {
|
|
992
737
|
// 有更新动态
|
|
993
|
-
console.log(
|
|
738
|
+
console.log("有更新动态");
|
|
994
739
|
// 没有动态内容则直接跳过
|
|
995
740
|
if (!items[num])
|
|
996
741
|
continue;
|
|
@@ -1000,10 +745,12 @@ class ComRegister {
|
|
|
1000
745
|
const dynamicId = content.data.items[num].id_str;
|
|
1001
746
|
console.log(`寻找关注的UP主,当前动态UP主:${upName},UID:${upUID},动态ID:${dynamicId}`);
|
|
1002
747
|
// 寻找关注的UP主的动态
|
|
1003
|
-
this.subManager
|
|
748
|
+
for (const sub of this.subManager) {
|
|
1004
749
|
console.log(`当前订阅UP主:${sub.uid}`);
|
|
1005
750
|
// 判断是否是订阅的UP主
|
|
1006
|
-
|
|
751
|
+
// biome-ignore lint/suspicious/noDoubleEquals: <explanation>
|
|
752
|
+
if (sub.dynamic && sub.uid == upUID) {
|
|
753
|
+
// 订阅该UP主,推送该动态
|
|
1007
754
|
// 判断更新动态是否为1条
|
|
1008
755
|
if (updateNum === 1) {
|
|
1009
756
|
// 判断dynamicIdStr是否有值,是否与当前动态ID一致
|
|
@@ -1036,16 +783,16 @@ class ComRegister {
|
|
|
1036
783
|
}
|
|
1037
784
|
catch (e) {
|
|
1038
785
|
// 直播开播动态,不做处理
|
|
1039
|
-
if (e.message ===
|
|
786
|
+
if (e.message === "直播开播动态,不做处理")
|
|
1040
787
|
return;
|
|
1041
|
-
if (e.message ===
|
|
788
|
+
if (e.message === "出现关键词,屏蔽该动态") {
|
|
1042
789
|
// 如果需要发送才发送
|
|
1043
790
|
if (this.config.filter.notify) {
|
|
1044
791
|
await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
|
|
1045
792
|
}
|
|
1046
793
|
return;
|
|
1047
794
|
}
|
|
1048
|
-
if (e.message ===
|
|
795
|
+
if (e.message === "已屏蔽转发动态") {
|
|
1049
796
|
if (this.config.filter.notify) {
|
|
1050
797
|
await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
|
|
1051
798
|
}
|
|
@@ -1053,30 +800,32 @@ class ComRegister {
|
|
|
1053
800
|
}
|
|
1054
801
|
// 未知错误
|
|
1055
802
|
if (i === attempts - 1) {
|
|
1056
|
-
this.logger.error(
|
|
803
|
+
this.logger.error(`dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:${e.message}`);
|
|
1057
804
|
// 发送私聊消息并重启服务
|
|
1058
805
|
return await this.sendPrivateMsgAndStopService();
|
|
1059
806
|
}
|
|
1060
807
|
}
|
|
1061
808
|
}
|
|
1062
809
|
// 判断是否需要发送URL
|
|
1063
|
-
const dUrl = this.config.dynamicUrl
|
|
810
|
+
const dUrl = this.config.dynamicUrl
|
|
811
|
+
? `${upName}发布了一条动态:https://t.bilibili.com/${dynamicId}`
|
|
812
|
+
: "";
|
|
1064
813
|
// 如果pic存在,则直接返回pic
|
|
1065
814
|
if (pic) {
|
|
1066
|
-
this.logger.info(
|
|
815
|
+
this.logger.info("推送动态中,使用render模式");
|
|
1067
816
|
// pic存在,使用的是render模式
|
|
1068
|
-
await this.sendMsg(sub.target, pic +
|
|
817
|
+
await this.sendMsg(sub.target, pic + dUrl);
|
|
1069
818
|
}
|
|
1070
819
|
else if (buffer) {
|
|
1071
|
-
this.logger.info(
|
|
820
|
+
this.logger.info("推送动态中,使用page模式");
|
|
1072
821
|
// pic不存在,说明使用的是page模式
|
|
1073
|
-
await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer,
|
|
822
|
+
await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), dUrl] }));
|
|
1074
823
|
}
|
|
1075
824
|
else {
|
|
1076
|
-
this.logger.info(items[num].modules.module_author.name
|
|
825
|
+
this.logger.info(`${items[num].modules.module_author.name}发布了一条动态,但是推送失败`);
|
|
1077
826
|
}
|
|
1078
827
|
}
|
|
1079
|
-
}
|
|
828
|
+
}
|
|
1080
829
|
}
|
|
1081
830
|
}
|
|
1082
831
|
finally {
|
|
@@ -1085,7 +834,7 @@ class ComRegister {
|
|
|
1085
834
|
};
|
|
1086
835
|
}
|
|
1087
836
|
// 定义发送直播通知卡片方法
|
|
1088
|
-
async sendLiveNotifyCard(info, liveType, liveNotifyMsg) {
|
|
837
|
+
async sendLiveNotifyCard(info, liveType, followerDisplay, liveNotifyMsg) {
|
|
1089
838
|
// 定义变量
|
|
1090
839
|
let pic;
|
|
1091
840
|
let buffer;
|
|
@@ -1094,7 +843,7 @@ class ComRegister {
|
|
|
1094
843
|
for (let i = 0; i < attempts; i++) {
|
|
1095
844
|
try {
|
|
1096
845
|
// 获取直播通知卡片
|
|
1097
|
-
const { pic: picv, buffer: bufferv } = await this.ctx.gi.generateLiveImg(info.data, info.username, info.userface, liveType);
|
|
846
|
+
const { pic: picv, buffer: bufferv } = await this.ctx.gi.generateLiveImg(info.data, info.username, info.userface, followerDisplay, liveType);
|
|
1098
847
|
// 赋值
|
|
1099
848
|
pic = picv;
|
|
1100
849
|
buffer = bufferv;
|
|
@@ -1102,8 +851,9 @@ class ComRegister {
|
|
|
1102
851
|
break;
|
|
1103
852
|
}
|
|
1104
853
|
catch (e) {
|
|
1105
|
-
if (i === attempts - 1) {
|
|
1106
|
-
|
|
854
|
+
if (i === attempts - 1) {
|
|
855
|
+
// 已尝试三次
|
|
856
|
+
this.logger.error(`liveDetect generateLiveImg() 推送卡片生成失败,原因:${e.message}`);
|
|
1107
857
|
// 发送私聊消息并重启服务
|
|
1108
858
|
return await this.sendPrivateMsgAndStopService();
|
|
1109
859
|
}
|
|
@@ -1113,28 +863,61 @@ class ComRegister {
|
|
|
1113
863
|
// pic 存在,使用的是render模式
|
|
1114
864
|
if (pic) {
|
|
1115
865
|
// 只有在开播时才艾特全体成员
|
|
1116
|
-
if (liveType === LiveType.StartBroadcasting) {
|
|
1117
|
-
return await this.sendMsg(info.target, pic + (liveNotifyMsg ??
|
|
866
|
+
if (liveType === type_1.LiveType.StartBroadcasting) {
|
|
867
|
+
return await this.sendMsg(info.target, pic + (liveNotifyMsg ?? ""), true);
|
|
1118
868
|
}
|
|
1119
869
|
// 正常不需要艾特全体成员
|
|
1120
|
-
return await this.sendMsg(info.target, pic + (liveNotifyMsg ??
|
|
870
|
+
return await this.sendMsg(info.target, pic + (liveNotifyMsg ?? ""));
|
|
1121
871
|
}
|
|
1122
872
|
// pic不存在,说明使用的是page模式
|
|
1123
|
-
const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer,
|
|
873
|
+
const msg = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, "image/png"), liveNotifyMsg || ""] }));
|
|
1124
874
|
// 只有在开播时才艾特全体成员
|
|
1125
|
-
if (liveType === LiveType.StartBroadcasting) {
|
|
875
|
+
if (liveType === type_1.LiveType.StartBroadcasting) {
|
|
1126
876
|
return await this.sendMsg(info.target, msg, true);
|
|
1127
877
|
}
|
|
1128
878
|
// 正常不需要艾特全体成员
|
|
1129
879
|
return await this.sendMsg(info.target, msg);
|
|
1130
880
|
}
|
|
1131
881
|
// 定义获取主播信息方法
|
|
1132
|
-
async useMasterInfo(uid) {
|
|
882
|
+
async useMasterInfo(uid, masterInfo, liveType) {
|
|
883
|
+
// 获取主播信息
|
|
1133
884
|
const { data } = await this.ctx.ba.getMasterInfo(uid);
|
|
1134
|
-
|
|
885
|
+
// 定义粉丝数变量
|
|
886
|
+
let liveOpenFollowerNum;
|
|
887
|
+
let liveEndFollowerNum;
|
|
888
|
+
let liveFollowerChange;
|
|
889
|
+
// 判断直播状态
|
|
890
|
+
if (liveType === type_1.LiveType.StartBroadcasting ||
|
|
891
|
+
liveType === type_1.LiveType.FirstLiveBroadcast) {
|
|
892
|
+
// 第一次启动或刚开播
|
|
893
|
+
// 将当前粉丝数赋值给liveOpenFollowerNum、liveEndFollowerNum
|
|
894
|
+
liveOpenFollowerNum = data.follower_num;
|
|
895
|
+
liveEndFollowerNum = data.follower_num;
|
|
896
|
+
// 将粉丝数变化赋值为0
|
|
897
|
+
liveFollowerChange = 0;
|
|
898
|
+
}
|
|
899
|
+
if (liveType === type_1.LiveType.StopBroadcast ||
|
|
900
|
+
liveType === type_1.LiveType.LiveBroadcast) {
|
|
901
|
+
// 将上一次的liveOpenFollowerNum赋值给本次的liveOpenFollowerNum
|
|
902
|
+
liveOpenFollowerNum = masterInfo.liveOpenFollowerNum;
|
|
903
|
+
// 将当前粉丝数赋值给liveEndFollowerNum
|
|
904
|
+
liveEndFollowerNum = data.follower_num;
|
|
905
|
+
// 计算粉丝数变化量
|
|
906
|
+
liveFollowerChange = liveEndFollowerNum - masterInfo.liveOpenFollowerNum;
|
|
907
|
+
}
|
|
908
|
+
// 返回值
|
|
909
|
+
return {
|
|
910
|
+
username: data.info.uname,
|
|
911
|
+
userface: data.info.face,
|
|
912
|
+
roomId: data.room_id,
|
|
913
|
+
liveOpenFollowerNum,
|
|
914
|
+
liveEndFollowerNum,
|
|
915
|
+
liveFollowerChange,
|
|
916
|
+
};
|
|
1135
917
|
}
|
|
1136
918
|
async useLiveRoomInfo(roomId) {
|
|
1137
919
|
// 发送请求获取直播间信息
|
|
920
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1138
921
|
let content;
|
|
1139
922
|
const attempts = 3;
|
|
1140
923
|
for (let i = 0; i < attempts; i++) {
|
|
@@ -1145,8 +928,9 @@ class ComRegister {
|
|
|
1145
928
|
break;
|
|
1146
929
|
}
|
|
1147
930
|
catch (e) {
|
|
1148
|
-
this.logger.error(
|
|
1149
|
-
if (i === attempts - 1) {
|
|
931
|
+
this.logger.error(`liveDetect getLiveRoomInfo 发生了错误,错误为:${e.message}`);
|
|
932
|
+
if (i === attempts - 1) {
|
|
933
|
+
// 已尝试三次
|
|
1150
934
|
// 发送私聊消息并重启服务
|
|
1151
935
|
return await this.sendPrivateMsgAndStopService();
|
|
1152
936
|
}
|
|
@@ -1154,210 +938,6 @@ class ComRegister {
|
|
|
1154
938
|
}
|
|
1155
939
|
return content.data;
|
|
1156
940
|
}
|
|
1157
|
-
async liveDetectWithAPI() {
|
|
1158
|
-
// 定义变量:第一次订阅
|
|
1159
|
-
let firstSubscription = true;
|
|
1160
|
-
// 定义变量:timer计时器
|
|
1161
|
-
let timer = 0;
|
|
1162
|
-
// 相当于锁的作用,防止上一个循环没处理完
|
|
1163
|
-
let flag = true;
|
|
1164
|
-
// 定义订阅对象Record 0未开播 1正在直播 2轮播中
|
|
1165
|
-
const liveRecord = {};
|
|
1166
|
-
// 初始化subRecord
|
|
1167
|
-
this.subManager.forEach(sub => {
|
|
1168
|
-
// 判断是否订阅直播
|
|
1169
|
-
if (sub.live) {
|
|
1170
|
-
// 将该订阅添加到subRecord中
|
|
1171
|
-
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
// 定义函数: 发送请求获取直播状态
|
|
1175
|
-
const useLiveStatus = async (roomId) => {
|
|
1176
|
-
let content;
|
|
1177
|
-
const attempts = 3;
|
|
1178
|
-
for (let i = 0; i < attempts; i++) {
|
|
1179
|
-
try {
|
|
1180
|
-
// 发送请求获取room信息
|
|
1181
|
-
content = await this.ctx.ba.getLiveRoomInfo(roomId);
|
|
1182
|
-
// 成功则跳出循环
|
|
1183
|
-
break;
|
|
1184
|
-
}
|
|
1185
|
-
catch (e) {
|
|
1186
|
-
this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
|
|
1187
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
1188
|
-
// 发送私聊消息并重启服务
|
|
1189
|
-
return await this.sendPrivateMsgAndStopService();
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
// 返回data
|
|
1194
|
-
return content.data;
|
|
1195
|
-
};
|
|
1196
|
-
return async () => {
|
|
1197
|
-
// 如果flag为false则说明前面的代码还未执行完,则直接返回
|
|
1198
|
-
if (!flag)
|
|
1199
|
-
return;
|
|
1200
|
-
// 将标志位置为false
|
|
1201
|
-
flag = false;
|
|
1202
|
-
try {
|
|
1203
|
-
// 获取正在直播对象
|
|
1204
|
-
const liveUsers = await this.ctx.ba.getTheUserWhoIsLiveStreaming();
|
|
1205
|
-
// 判断是否是第一次订阅
|
|
1206
|
-
if (firstSubscription) {
|
|
1207
|
-
// 将第一次订阅置为false
|
|
1208
|
-
firstSubscription = false;
|
|
1209
|
-
// 先判断是否有UP主正在直播
|
|
1210
|
-
if (liveUsers.count > 0) {
|
|
1211
|
-
// 遍历liveUsers
|
|
1212
|
-
liveUsers.items.forEach(async (item) => {
|
|
1213
|
-
// 判断是否有订阅对象正在直播
|
|
1214
|
-
if (liveRecord[item.mid]) {
|
|
1215
|
-
// 获取当前用户直播间信息
|
|
1216
|
-
const data = await useLiveStatus(item.room_id.toString());
|
|
1217
|
-
// 设置开播时间
|
|
1218
|
-
liveRecord[item.mid].liveTime = data.live_time;
|
|
1219
|
-
// 设置直播中消息
|
|
1220
|
-
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1221
|
-
.replace('-name', item.uname)
|
|
1222
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1223
|
-
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1224
|
-
// 发送直播通知卡片
|
|
1225
|
-
if (this.config.restartPush)
|
|
1226
|
-
this.sendLiveNotifyCard({
|
|
1227
|
-
username: item.uname,
|
|
1228
|
-
userface: item.face,
|
|
1229
|
-
target: liveRecord[item.mid].target,
|
|
1230
|
-
data
|
|
1231
|
-
}, LiveType.LiveBroadcast, liveMsg);
|
|
1232
|
-
// 改变开播状态
|
|
1233
|
-
liveRecord[item.mid].liveStatus = 1;
|
|
1234
|
-
}
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
// 没有正在直播的订阅对象,直接返回
|
|
1238
|
-
return;
|
|
1239
|
-
}
|
|
1240
|
-
// 获取当前订阅直播的数量
|
|
1241
|
-
const currentLiveSubs = this.subManager.filter(sub => sub.live);
|
|
1242
|
-
// 获取当前liveRecord里的订阅数量
|
|
1243
|
-
const currentLiveRecordKeys = Object.keys(liveRecord);
|
|
1244
|
-
// 判断是否能匹配双方数量
|
|
1245
|
-
if (currentLiveRecordKeys.length < currentLiveSubs.length) {
|
|
1246
|
-
// 遍历currentLiveSubs
|
|
1247
|
-
for (const sub of currentLiveSubs) {
|
|
1248
|
-
// 判断liveRecord中缺少了哪些订阅
|
|
1249
|
-
if (!liveRecord[sub.uid]) {
|
|
1250
|
-
// 获取当前用户直播间信息
|
|
1251
|
-
const data = await useLiveStatus(sub.roomId.toString());
|
|
1252
|
-
switch (data.live_status) {
|
|
1253
|
-
case 0:
|
|
1254
|
-
case 2: { // 未开播
|
|
1255
|
-
// 添加到liveRecord中
|
|
1256
|
-
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1257
|
-
// break
|
|
1258
|
-
break;
|
|
1259
|
-
}
|
|
1260
|
-
case 1: { //正在直播
|
|
1261
|
-
// 添加到liveRecord中
|
|
1262
|
-
liveRecord[sub.uid] = { liveStatus: 1, liveTime: data.live_time, target: sub.target };
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
if (currentLiveRecordKeys.length > currentLiveSubs.length) {
|
|
1269
|
-
// 创建Set
|
|
1270
|
-
const setCurrentLiveSubs = new Set(currentLiveSubs.map(sub => sub.uid));
|
|
1271
|
-
// 找出 currentLiveRecordKeys中比currentLiveSubs 多的元素
|
|
1272
|
-
const extraInCurrentLiveSubs = currentLiveRecordKeys.filter(key => !setCurrentLiveSubs.has(key));
|
|
1273
|
-
// 遍历 extraInCurrentLiveSubs
|
|
1274
|
-
for (const subUID of extraInCurrentLiveSubs) {
|
|
1275
|
-
// 删除记录
|
|
1276
|
-
delete liveRecord[subUID];
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
// 数量没有差异,则不进行其他操作
|
|
1280
|
-
// 遍历liveUsers
|
|
1281
|
-
liveUsers.items.forEach(async (item) => {
|
|
1282
|
-
// 判断是否有正在直播的订阅对象
|
|
1283
|
-
if (liveRecord[item.mid]) { // 有正在直播的订阅对象
|
|
1284
|
-
// 获取当前用户直播间信息
|
|
1285
|
-
const data = await useLiveStatus(item.room_id.toString());
|
|
1286
|
-
// 判断开播状态
|
|
1287
|
-
switch (liveRecord[item.mid].liveStatus) {
|
|
1288
|
-
case 0: { // 之前未开播,现在开播了
|
|
1289
|
-
// 设置开播时间
|
|
1290
|
-
liveRecord[item.mid].liveTime = data.live_time;
|
|
1291
|
-
// 定义开播通知语
|
|
1292
|
-
const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
|
|
1293
|
-
.replace('-name', item.uname)
|
|
1294
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1295
|
-
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1296
|
-
// 发送直播通知卡片
|
|
1297
|
-
await this.sendLiveNotifyCard({
|
|
1298
|
-
username: item.uname,
|
|
1299
|
-
userface: item.face,
|
|
1300
|
-
target: liveRecord[item.mid].target,
|
|
1301
|
-
data
|
|
1302
|
-
}, LiveType.LiveBroadcast, liveStartMsg);
|
|
1303
|
-
// 改变开播状态
|
|
1304
|
-
liveRecord[item.mid].liveStatus = 1;
|
|
1305
|
-
// 结束
|
|
1306
|
-
break;
|
|
1307
|
-
}
|
|
1308
|
-
case 1: { // 仍在直播
|
|
1309
|
-
if (this.config.pushTime > 0) {
|
|
1310
|
-
timer++;
|
|
1311
|
-
// 开始记录时间
|
|
1312
|
-
if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
|
|
1313
|
-
// 到时间重新计时
|
|
1314
|
-
timer = 0;
|
|
1315
|
-
// 定义直播中通知消息
|
|
1316
|
-
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1317
|
-
.replace('-name', item.uname)
|
|
1318
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
|
|
1319
|
-
.replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
|
|
1320
|
-
// 发送直播通知卡片
|
|
1321
|
-
this.sendLiveNotifyCard({
|
|
1322
|
-
username: item.uname,
|
|
1323
|
-
userface: item.face,
|
|
1324
|
-
target: liveRecord[item.mid].target,
|
|
1325
|
-
data
|
|
1326
|
-
}, LiveType.LiveBroadcast, liveMsg);
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
});
|
|
1333
|
-
// 找出liveRecord中liveStatus为1但liveUsers中没有的元素
|
|
1334
|
-
const extraInLiveRecord = currentLiveRecordKeys.filter(key => !liveUsers.items.some(item => item.mid === Number(key)));
|
|
1335
|
-
// 遍历 extraInLiveRecord
|
|
1336
|
-
for (const subUID of extraInLiveRecord) { // 下播的主播
|
|
1337
|
-
// 获取主播信息
|
|
1338
|
-
const masterInfo = await this.useMasterInfo(subUID);
|
|
1339
|
-
// 获取直播间消息
|
|
1340
|
-
const liveRoomInfo = await this.useLiveRoomInfo(masterInfo.roomId.toString());
|
|
1341
|
-
// 定义下播播通知语
|
|
1342
|
-
const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
|
|
1343
|
-
.replace('-name', masterInfo.username)
|
|
1344
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[subUID].liveTime))
|
|
1345
|
-
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1346
|
-
// 发送下播通知
|
|
1347
|
-
this.sendLiveNotifyCard({
|
|
1348
|
-
username: masterInfo.username,
|
|
1349
|
-
userface: masterInfo.userface,
|
|
1350
|
-
target: liveRecord[subUID].target,
|
|
1351
|
-
data: liveRoomInfo
|
|
1352
|
-
}, LiveType.StopBroadcast, liveEndMsg);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
finally {
|
|
1356
|
-
// 执行完方法体不论如何都把flag设置为true
|
|
1357
|
-
flag = true;
|
|
1358
|
-
}
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
941
|
async liveDetectWithListener(roomId, target) {
|
|
1362
942
|
// 定义开播时间
|
|
1363
943
|
let liveTime;
|
|
@@ -1365,180 +945,236 @@ class ComRegister {
|
|
|
1365
945
|
let pushAtTimeTimer;
|
|
1366
946
|
// 定义弹幕存放数组
|
|
1367
947
|
const currentLiveDanmakuArr = [];
|
|
1368
|
-
|
|
948
|
+
// 定义开播状态
|
|
949
|
+
let liveStatus = false;
|
|
1369
950
|
// 处理target
|
|
951
|
+
// 定义channelIdArr总长度
|
|
952
|
+
let channelIdArrLen = 0;
|
|
953
|
+
// 定义数据
|
|
954
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
955
|
+
let liveRoomInfo;
|
|
956
|
+
let masterInfo;
|
|
957
|
+
let watchedNum;
|
|
1370
958
|
// 找到频道/群组对应的
|
|
1371
|
-
const
|
|
1372
|
-
|
|
959
|
+
const liveGuardBuyPushTargetArr = target.map((channel) => {
|
|
960
|
+
// 获取符合条件的target
|
|
961
|
+
const liveGuardBuyArr = channel.channelIdArr.filter((channelId) => channelId.liveGuardBuy);
|
|
962
|
+
// 将当前liveDanmakuArr的长度+到channelIdArrLen中
|
|
963
|
+
channelIdArrLen += liveGuardBuyArr.length;
|
|
964
|
+
// 返回符合的target
|
|
1373
965
|
return {
|
|
1374
|
-
channelIdArr:
|
|
1375
|
-
platform: channel.platform
|
|
966
|
+
channelIdArr: liveGuardBuyArr,
|
|
967
|
+
platform: channel.platform,
|
|
1376
968
|
};
|
|
1377
969
|
});
|
|
1378
970
|
// 定义定时推送函数
|
|
1379
971
|
const pushAtTimeFunc = async () => {
|
|
1380
|
-
//
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
972
|
+
// 判断是否信息是否获取成功
|
|
973
|
+
if (!(await useMasterAndLiveRoomInfo(type_1.LiveType.LiveBroadcast))) {
|
|
974
|
+
// 未获取成功,直接返回
|
|
975
|
+
return this.sendPrivateMsg("获取直播间信息失败,推送直播卡片失败!");
|
|
976
|
+
}
|
|
977
|
+
// 设置开播时间
|
|
978
|
+
liveTime = liveRoomInfo.live_time;
|
|
979
|
+
// 获取watched
|
|
980
|
+
const watched = watchedNum || "暂未获取到";
|
|
981
|
+
// 设置直播中消息
|
|
982
|
+
const liveMsg = this.config.customLive
|
|
983
|
+
? this.config.customLive
|
|
984
|
+
.replace("-name", masterInfo.username)
|
|
985
|
+
.replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
|
|
986
|
+
.replace("-watched", watched)
|
|
987
|
+
.replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
|
|
988
|
+
: null;
|
|
1389
989
|
// 发送直播通知卡片
|
|
1390
990
|
await this.sendLiveNotifyCard({
|
|
1391
991
|
username: masterInfo.username,
|
|
1392
992
|
userface: masterInfo.userface,
|
|
1393
|
-
target
|
|
1394
|
-
data: liveRoomInfo
|
|
1395
|
-
}, LiveType.LiveBroadcast, liveMsg);
|
|
993
|
+
target,
|
|
994
|
+
data: liveRoomInfo,
|
|
995
|
+
}, type_1.LiveType.LiveBroadcast, watched, liveMsg);
|
|
1396
996
|
};
|
|
1397
|
-
//
|
|
1398
|
-
const
|
|
1399
|
-
//
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
//
|
|
1404
|
-
|
|
997
|
+
// 定义直播间信息获取函数
|
|
998
|
+
const useMasterAndLiveRoomInfo = async (liveType) => {
|
|
999
|
+
// 定义函数是否执行成功flag
|
|
1000
|
+
let flag = true;
|
|
1001
|
+
// 获取直播间信息
|
|
1002
|
+
liveRoomInfo = await this.useLiveRoomInfo(roomId).catch(() => {
|
|
1003
|
+
// 设置flag为false
|
|
1004
|
+
flag = false;
|
|
1005
|
+
// 返回空
|
|
1006
|
+
return null;
|
|
1007
|
+
});
|
|
1008
|
+
// 判断是否成功获取信息
|
|
1009
|
+
if (!flag || !liveRoomInfo || !liveRoomInfo.uid) {
|
|
1010
|
+
// 上一步未成功
|
|
1011
|
+
flag = false;
|
|
1012
|
+
// 返回flag
|
|
1013
|
+
return flag;
|
|
1405
1014
|
}
|
|
1015
|
+
// 获取主播信息(需要满足flag为true,liveRoomInfo.uid有值)
|
|
1016
|
+
masterInfo = await this.useMasterInfo(liveRoomInfo.uid, masterInfo, liveType).catch(() => {
|
|
1017
|
+
// 设置flag为false
|
|
1018
|
+
flag = false;
|
|
1019
|
+
// 返回空
|
|
1020
|
+
return null;
|
|
1021
|
+
});
|
|
1022
|
+
// 返回信息
|
|
1023
|
+
return flag;
|
|
1406
1024
|
};
|
|
1407
|
-
// 获取直播间信息
|
|
1408
|
-
const liveRoomInfo = await this.useLiveRoomInfo(roomId);
|
|
1409
|
-
// 获取主播信息
|
|
1410
|
-
const masterInfo = await this.useMasterInfo(liveRoomInfo.uid);
|
|
1411
1025
|
// 构建消息处理函数
|
|
1412
1026
|
const handler = {
|
|
1413
|
-
onOpen: () => {
|
|
1414
|
-
this.logger.info('直播间连接成功');
|
|
1415
|
-
},
|
|
1416
|
-
onClose: () => {
|
|
1417
|
-
this.logger.info('直播间连接已断开');
|
|
1418
|
-
},
|
|
1419
1027
|
onIncomeDanmu: ({ body }) => {
|
|
1420
|
-
// 处理消息,只需要UP主名字和消息内容
|
|
1421
|
-
const content = `【${masterInfo.username}的直播间】${body.user.uname}:${body.content}`;
|
|
1422
1028
|
// 保存消息到数组
|
|
1423
1029
|
currentLiveDanmakuArr.push(body.content);
|
|
1424
|
-
temporaryLiveDanmakuArr.push(content);
|
|
1425
1030
|
},
|
|
1426
1031
|
onIncomeSuperChat: ({ body }) => {
|
|
1427
|
-
// 处理SC消息
|
|
1428
|
-
const content = `【${masterInfo.username}的直播间】${body.user.uname}发送了一条SC:${body.content}`;
|
|
1429
1032
|
// 保存消息到数组
|
|
1430
1033
|
currentLiveDanmakuArr.push(body.content);
|
|
1431
|
-
|
|
1034
|
+
},
|
|
1035
|
+
onWatchedChange: ({ body }) => {
|
|
1036
|
+
// 保存观看人数到变量
|
|
1037
|
+
watchedNum = body.text_small;
|
|
1432
1038
|
},
|
|
1433
1039
|
onGuardBuy: ({ body }) => {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1040
|
+
// 定义消息
|
|
1041
|
+
const content = `${body.user.uname}加入了大航海(${body.gift_name})`;
|
|
1042
|
+
// 直接发送消息
|
|
1043
|
+
channelIdArrLen > 0 && this.sendMsg(liveGuardBuyPushTargetArr, content);
|
|
1438
1044
|
},
|
|
1439
1045
|
onLiveStart: async () => {
|
|
1440
|
-
//
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1046
|
+
// 判断是否已经开播
|
|
1047
|
+
if (liveStatus)
|
|
1048
|
+
return;
|
|
1049
|
+
// 设置开播状态为true
|
|
1050
|
+
liveStatus = true;
|
|
1051
|
+
// 判断是否信息是否获取成功
|
|
1052
|
+
if (!(await useMasterAndLiveRoomInfo(type_1.LiveType.StartBroadcasting))) {
|
|
1053
|
+
// 设置开播状态为false
|
|
1054
|
+
liveStatus = false;
|
|
1055
|
+
// 未获取成功,直接返回
|
|
1056
|
+
return await this.sendPrivateMsg("获取直播间信息失败,推送直播开播卡片失败!");
|
|
1057
|
+
}
|
|
1058
|
+
// 设置开播时间
|
|
1059
|
+
liveTime = liveRoomInfo.live_time;
|
|
1060
|
+
// 获取当前粉丝数
|
|
1061
|
+
const follower = masterInfo.liveOpenFollowerNum >= 10_000
|
|
1062
|
+
? `${(masterInfo.liveOpenFollowerNum / 10000).toFixed(1)}万`
|
|
1063
|
+
: masterInfo.liveOpenFollowerNum.toString();
|
|
1064
|
+
// 定义开播通知语
|
|
1065
|
+
const liveStartMsg = this.config.customLiveStart
|
|
1066
|
+
? this.config.customLiveStart
|
|
1067
|
+
.replace("-name", masterInfo.username)
|
|
1068
|
+
.replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
|
|
1069
|
+
.replace("-follower", follower)
|
|
1070
|
+
.replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
|
|
1071
|
+
: null;
|
|
1072
|
+
// 推送开播通知
|
|
1451
1073
|
await this.sendLiveNotifyCard({
|
|
1452
1074
|
username: masterInfo.username,
|
|
1453
1075
|
userface: masterInfo.userface,
|
|
1454
|
-
target
|
|
1455
|
-
data: liveRoomInfo
|
|
1456
|
-
}, LiveType.
|
|
1076
|
+
target,
|
|
1077
|
+
data: liveRoomInfo,
|
|
1078
|
+
}, type_1.LiveType.StartBroadcasting, follower, liveStartMsg);
|
|
1079
|
+
// 判断定时器是否已开启
|
|
1080
|
+
if (!pushAtTimeTimer) {
|
|
1081
|
+
// 开始直播,开启定时器
|
|
1082
|
+
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1083
|
+
}
|
|
1457
1084
|
},
|
|
1458
1085
|
onLiveEnd: async () => {
|
|
1459
|
-
//
|
|
1460
|
-
|
|
1461
|
-
//
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1086
|
+
// 将直播状态设置为false
|
|
1087
|
+
liveStatus = false;
|
|
1088
|
+
// 判断是否信息是否获取成功
|
|
1089
|
+
if (!(await useMasterAndLiveRoomInfo(type_1.LiveType.StopBroadcast))) {
|
|
1090
|
+
// 未获取成功,直接返回
|
|
1091
|
+
return this.sendPrivateMsg("获取直播间信息失败,推送直播下播卡片失败!");
|
|
1092
|
+
}
|
|
1093
|
+
// 更改直播时长
|
|
1094
|
+
liveRoomInfo.live_time = liveTime;
|
|
1095
|
+
// 获取粉丝数变化
|
|
1096
|
+
const followerChange = (() => {
|
|
1097
|
+
// 获取直播关注变化值
|
|
1098
|
+
const liveFollowerChangeNum = masterInfo.liveFollowerChange;
|
|
1099
|
+
// 判断是否大于0
|
|
1100
|
+
if (liveFollowerChangeNum > 0) {
|
|
1101
|
+
// 大于0则加+
|
|
1102
|
+
return liveFollowerChangeNum >= 10_000
|
|
1103
|
+
? `+${liveFollowerChangeNum.toFixed(1)}万`
|
|
1104
|
+
: `+${liveFollowerChangeNum}`;
|
|
1105
|
+
}
|
|
1106
|
+
// 小于0
|
|
1107
|
+
return liveFollowerChangeNum <= -10_000
|
|
1108
|
+
? `${liveFollowerChangeNum.toFixed(1)}万`
|
|
1109
|
+
: liveFollowerChangeNum.toString();
|
|
1110
|
+
})();
|
|
1111
|
+
// 定义下播播通知语
|
|
1112
|
+
const liveEndMsg = this.config.customLiveEnd
|
|
1113
|
+
? this.config.customLiveEnd
|
|
1114
|
+
.replace("-name", masterInfo.username)
|
|
1115
|
+
.replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
|
|
1116
|
+
.replace("-follower_change", followerChange)
|
|
1117
|
+
: null;
|
|
1472
1118
|
// 推送通知卡片
|
|
1473
1119
|
await this.sendLiveNotifyCard({
|
|
1474
1120
|
username: masterInfo.username,
|
|
1475
1121
|
userface: masterInfo.userface,
|
|
1476
|
-
target
|
|
1477
|
-
data: liveRoomInfo
|
|
1478
|
-
}, LiveType.
|
|
1479
|
-
|
|
1122
|
+
target,
|
|
1123
|
+
data: liveRoomInfo,
|
|
1124
|
+
}, type_1.LiveType.StopBroadcast, followerChange, liveEndMsg);
|
|
1125
|
+
// 关闭定时推送定时器
|
|
1126
|
+
pushAtTimeTimer();
|
|
1127
|
+
// 将推送定时器变量置空
|
|
1128
|
+
pushAtTimeTimer = null;
|
|
1129
|
+
},
|
|
1480
1130
|
};
|
|
1481
1131
|
// 启动直播间弹幕监测
|
|
1482
|
-
this.ctx.bl.startLiveRoomListener(roomId, handler
|
|
1132
|
+
await this.ctx.bl.startLiveRoomListener(roomId, handler);
|
|
1133
|
+
// 第一次启动获取信息并判信息是否获取成功
|
|
1134
|
+
if (!(await useMasterAndLiveRoomInfo(type_1.LiveType.FirstLiveBroadcast))) {
|
|
1135
|
+
// 未获取成功,直接返回
|
|
1136
|
+
return this.sendPrivateMsg("获取直播间信息失败,启动直播间弹幕检测失败!");
|
|
1137
|
+
}
|
|
1483
1138
|
// 判断直播状态
|
|
1484
1139
|
if (liveRoomInfo.live_status === 1) {
|
|
1485
1140
|
// 设置开播时间
|
|
1486
1141
|
liveTime = liveRoomInfo.live_time;
|
|
1142
|
+
// 获取当前累计观看人数
|
|
1143
|
+
const watched = watchedNum || "暂未获取到";
|
|
1487
1144
|
// 定义直播中通知消息
|
|
1488
|
-
const liveMsg = this.config.customLive
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1145
|
+
const liveMsg = this.config.customLive
|
|
1146
|
+
? this.config.customLive
|
|
1147
|
+
.replace("-name", masterInfo.username)
|
|
1148
|
+
.replace("-time", await this.ctx.gi.getTimeDifference(liveTime))
|
|
1149
|
+
.replace("-watched", watched)
|
|
1150
|
+
.replace("-link", `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`)
|
|
1151
|
+
: null;
|
|
1492
1152
|
// 发送直播通知卡片
|
|
1493
1153
|
if (this.config.restartPush) {
|
|
1494
1154
|
await this.sendLiveNotifyCard({
|
|
1495
1155
|
username: masterInfo.username,
|
|
1496
1156
|
userface: masterInfo.userface,
|
|
1497
|
-
target
|
|
1498
|
-
data: liveRoomInfo
|
|
1499
|
-
}, LiveType.LiveBroadcast, liveMsg);
|
|
1157
|
+
target,
|
|
1158
|
+
data: liveRoomInfo,
|
|
1159
|
+
}, type_1.LiveType.LiveBroadcast, watched, liveMsg);
|
|
1500
1160
|
}
|
|
1501
1161
|
// 正在直播,开启定时器
|
|
1502
|
-
|
|
1162
|
+
// 判断定时器是否已开启
|
|
1163
|
+
if (!pushAtTimeTimer) {
|
|
1164
|
+
// 开始直播,开启定时器
|
|
1165
|
+
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1166
|
+
}
|
|
1167
|
+
// 设置直播状态为true
|
|
1168
|
+
liveStatus = true;
|
|
1503
1169
|
}
|
|
1504
1170
|
}
|
|
1505
1171
|
subShow() {
|
|
1506
1172
|
// 在控制台中显示订阅对象
|
|
1507
|
-
let table =
|
|
1508
|
-
this.subManager
|
|
1509
|
-
table += `UID:${sub.uid} ${sub.dynamic ?
|
|
1510
|
-
});
|
|
1511
|
-
return table ? table : '没有订阅任何UP';
|
|
1512
|
-
}
|
|
1513
|
-
async checkIfNeedSub(liveSub, dynamicSub, session, liveRoomData) {
|
|
1514
|
-
// 定义方法:用户直播间是否存在
|
|
1515
|
-
const liveRoom = async () => {
|
|
1516
|
-
if (!liveRoomData) {
|
|
1517
|
-
// 未开通直播间
|
|
1518
|
-
await session.send('该用户未开通直播间,无法订阅直播');
|
|
1519
|
-
// 返回false
|
|
1520
|
-
return true;
|
|
1521
|
-
}
|
|
1522
|
-
return false;
|
|
1523
|
-
};
|
|
1524
|
-
// 如果两者都为true或者都为false则直接返回
|
|
1525
|
-
if ((liveSub && dynamicSub) || (!liveSub && !dynamicSub)) {
|
|
1526
|
-
// 判断是否存在直播间
|
|
1527
|
-
if (await liveRoom())
|
|
1528
|
-
return [false, true];
|
|
1529
|
-
// 返回
|
|
1530
|
-
return [true, true];
|
|
1531
|
-
}
|
|
1532
|
-
// 如果只订阅直播
|
|
1533
|
-
if (liveSub) {
|
|
1534
|
-
// 判断是否存在直播间
|
|
1535
|
-
if (await liveRoom())
|
|
1536
|
-
return [false, false];
|
|
1537
|
-
// 返回
|
|
1538
|
-
return [true, false];
|
|
1173
|
+
let table = "";
|
|
1174
|
+
for (const sub of this.subManager) {
|
|
1175
|
+
table += `UID:${sub.uid} ${sub.dynamic ? "已订阅动态" : ""} ${sub.live ? "已订阅直播" : ""}\n`;
|
|
1539
1176
|
}
|
|
1540
|
-
|
|
1541
|
-
return [false, true];
|
|
1177
|
+
return table ? table : "没有订阅任何UP";
|
|
1542
1178
|
}
|
|
1543
1179
|
updateSubNotifier() {
|
|
1544
1180
|
// 更新控制台提示
|
|
@@ -1547,28 +1183,30 @@ class ComRegister {
|
|
|
1547
1183
|
// 获取订阅信息
|
|
1548
1184
|
const subInfo = this.subShow();
|
|
1549
1185
|
// 定义table
|
|
1550
|
-
let table =
|
|
1551
|
-
if (subInfo ===
|
|
1186
|
+
let table = "";
|
|
1187
|
+
if (subInfo === "没有订阅任何UP") {
|
|
1552
1188
|
table = subInfo;
|
|
1553
1189
|
}
|
|
1554
1190
|
else {
|
|
1555
1191
|
// 获取subTable
|
|
1556
|
-
const subTableArray = subInfo.split(
|
|
1192
|
+
const subTableArray = subInfo.split("\n");
|
|
1557
1193
|
subTableArray.splice(subTableArray.length - 1, 1);
|
|
1558
1194
|
// 定义Table
|
|
1559
|
-
table = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { children: "\u5F53\u524D\u8BA2\u9605\u5BF9\u8C61\uFF1A" }), (0, jsx_runtime_1.jsx)("ul", { children: subTableArray.map(str => (
|
|
1195
|
+
table = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { children: "\u5F53\u524D\u8BA2\u9605\u5BF9\u8C61\uFF1A" }), (0, jsx_runtime_1.jsx)("ul", { children: subTableArray.map((str) => (
|
|
1196
|
+
// biome-ignore lint/correctness/useJsxKeyInIterable: <explanation>
|
|
1197
|
+
(0, jsx_runtime_1.jsx)("li", { children: str }))) })] }));
|
|
1560
1198
|
}
|
|
1561
1199
|
// 设置更新后的提示
|
|
1562
1200
|
this.subNotifier = this.ctx.notifier.create(table);
|
|
1563
1201
|
}
|
|
1564
1202
|
async checkIfLoginInfoIsLoaded() {
|
|
1565
|
-
return new Promise(resolve => {
|
|
1203
|
+
return new Promise((resolve) => {
|
|
1566
1204
|
const check = () => {
|
|
1567
1205
|
if (!this.ctx.ba.getLoginInfoIsLoaded()) {
|
|
1568
1206
|
this.ctx.setTimeout(check, 500);
|
|
1569
1207
|
}
|
|
1570
1208
|
else {
|
|
1571
|
-
resolve(
|
|
1209
|
+
resolve("success");
|
|
1572
1210
|
}
|
|
1573
1211
|
};
|
|
1574
1212
|
check();
|
|
@@ -1578,7 +1216,8 @@ class ComRegister {
|
|
|
1578
1216
|
// 获取关注分组信息
|
|
1579
1217
|
const checkGroupIsReady = async () => {
|
|
1580
1218
|
// 判断是否有数据
|
|
1581
|
-
if (this.loginDBData.dynamic_group_id ===
|
|
1219
|
+
if (this.loginDBData.dynamic_group_id === "" ||
|
|
1220
|
+
this.loginDBData.dynamic_group_id === null) {
|
|
1582
1221
|
// 没有数据,没有创建分组,尝试创建分组
|
|
1583
1222
|
const createGroupData = await this.ctx.ba.createGroup("订阅");
|
|
1584
1223
|
// 如果分组已创建,则获取分组id
|
|
@@ -1588,7 +1227,7 @@ class ComRegister {
|
|
|
1588
1227
|
// 遍历所有分组
|
|
1589
1228
|
for (const group of allGroupData.data) {
|
|
1590
1229
|
// 找到订阅分组
|
|
1591
|
-
if (group.name ===
|
|
1230
|
+
if (group.name === "订阅") {
|
|
1592
1231
|
// 拿到分组id
|
|
1593
1232
|
this.loginDBData.dynamic_group_id = group.tagid;
|
|
1594
1233
|
// 结束循环
|
|
@@ -1602,7 +1241,9 @@ class ComRegister {
|
|
|
1602
1241
|
return false;
|
|
1603
1242
|
}
|
|
1604
1243
|
// 创建成功,保存到数据库
|
|
1605
|
-
this.ctx.database.set(
|
|
1244
|
+
this.ctx.database.set("loginBili", 1, {
|
|
1245
|
+
dynamic_group_id: this.loginDBData.dynamic_group_id,
|
|
1246
|
+
});
|
|
1606
1247
|
// 创建成功
|
|
1607
1248
|
return true;
|
|
1608
1249
|
}
|
|
@@ -1613,7 +1254,7 @@ class ComRegister {
|
|
|
1613
1254
|
// 判断是否创建成功
|
|
1614
1255
|
if (!flag) {
|
|
1615
1256
|
// 创建分组失败
|
|
1616
|
-
return { flag: false, msg:
|
|
1257
|
+
return { flag: false, msg: "创建分组失败,请尝试重启插件" };
|
|
1617
1258
|
}
|
|
1618
1259
|
// 获取分组明细
|
|
1619
1260
|
const relationGroupDetailData = await this.ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
|
|
@@ -1627,51 +1268,67 @@ class ComRegister {
|
|
|
1627
1268
|
// 判断是否创建成功
|
|
1628
1269
|
if (!flag) {
|
|
1629
1270
|
// 创建分组失败
|
|
1630
|
-
return { flag: false, msg:
|
|
1271
|
+
return { flag: false, msg: "创建分组失败,请尝试重启插件" };
|
|
1631
1272
|
}
|
|
1632
|
-
return { flag: true, msg:
|
|
1273
|
+
return { flag: true, msg: "分组不存在,已重新创建分组" };
|
|
1633
1274
|
}
|
|
1634
1275
|
// 获取分组明细失败
|
|
1635
|
-
return { flag: false, msg:
|
|
1276
|
+
return { flag: false, msg: "获取分组明细失败" };
|
|
1636
1277
|
}
|
|
1637
|
-
relationGroupDetailData.data
|
|
1278
|
+
for (const user of relationGroupDetailData.data) {
|
|
1638
1279
|
if (user.mid === mid) {
|
|
1639
1280
|
// 已关注订阅对象
|
|
1640
|
-
return { flag: true, msg:
|
|
1281
|
+
return { flag: true, msg: "订阅对象已存在于分组中" };
|
|
1641
1282
|
}
|
|
1642
|
-
}
|
|
1283
|
+
}
|
|
1643
1284
|
// 订阅对象
|
|
1644
1285
|
const subUserData = await this.ctx.ba.follow(mid);
|
|
1645
1286
|
// 判断是否订阅成功
|
|
1646
1287
|
switch (subUserData.code) {
|
|
1647
|
-
case -101:
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
case
|
|
1653
|
-
|
|
1288
|
+
case -101:
|
|
1289
|
+
return {
|
|
1290
|
+
flag: false,
|
|
1291
|
+
msg: "账号未登录,请使用指令bili login登录后再进行订阅操作",
|
|
1292
|
+
};
|
|
1293
|
+
case -102:
|
|
1294
|
+
return { flag: false, msg: "账号被封停,无法进行订阅操作" };
|
|
1295
|
+
case 22002:
|
|
1296
|
+
return { flag: false, msg: "因对方隐私设置,无法进行订阅操作" };
|
|
1297
|
+
case 22003:
|
|
1298
|
+
return { flag: false, msg: "你已将对方拉黑,无法进行订阅操作" };
|
|
1299
|
+
case 22013:
|
|
1300
|
+
return { flag: false, msg: "账号已注销,无法进行订阅操作" };
|
|
1301
|
+
case 40061:
|
|
1302
|
+
return {
|
|
1303
|
+
flag: false,
|
|
1304
|
+
msg: "账号不存在,请检查uid输入是否正确或用户是否存在",
|
|
1305
|
+
};
|
|
1306
|
+
case 22001:
|
|
1307
|
+
break; // 订阅对象为自己 无需添加到分组
|
|
1654
1308
|
case 22014: // 已关注订阅对象 无需再次关注
|
|
1655
|
-
case 0: {
|
|
1309
|
+
case 0: {
|
|
1310
|
+
// 执行订阅成功
|
|
1656
1311
|
// 把订阅对象添加到分组中
|
|
1657
1312
|
const copyUserToGroupData = await this.ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
|
|
1658
1313
|
// 判断是否添加成功
|
|
1659
1314
|
if (copyUserToGroupData.code !== 0) {
|
|
1660
1315
|
// 添加失败
|
|
1661
|
-
return { flag: false, msg:
|
|
1316
|
+
return { flag: false, msg: "添加订阅对象到分组失败,请稍后重试" };
|
|
1662
1317
|
}
|
|
1663
1318
|
}
|
|
1664
1319
|
}
|
|
1665
1320
|
// 订阅成功
|
|
1666
|
-
return { flag: true, msg:
|
|
1321
|
+
return { flag: true, msg: "用户订阅成功" };
|
|
1667
1322
|
}
|
|
1668
1323
|
async loadSubFromConfig(subs) {
|
|
1669
1324
|
for (const sub of subs) {
|
|
1670
1325
|
// 定义Data
|
|
1326
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1671
1327
|
let data;
|
|
1672
1328
|
// 判断是否需要订阅直播
|
|
1673
1329
|
if (sub.live) {
|
|
1674
1330
|
// 获取用户信息
|
|
1331
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1675
1332
|
let content;
|
|
1676
1333
|
// 设置重试次数
|
|
1677
1334
|
const attempts = 3;
|
|
@@ -1683,8 +1340,9 @@ class ComRegister {
|
|
|
1683
1340
|
break;
|
|
1684
1341
|
}
|
|
1685
1342
|
catch (e) {
|
|
1686
|
-
this.logger.error(
|
|
1687
|
-
if (i === attempts - 1) {
|
|
1343
|
+
this.logger.error(`loadSubFromConfig() getUserInfo() 发生了错误,错误为:${e.message}`);
|
|
1344
|
+
if (i === attempts - 1) {
|
|
1345
|
+
// 已尝试三次
|
|
1688
1346
|
// 发送私聊消息并重启服务
|
|
1689
1347
|
return await this.sendPrivateMsgAndStopService();
|
|
1690
1348
|
}
|
|
@@ -1701,8 +1359,8 @@ class ComRegister {
|
|
|
1701
1359
|
}
|
|
1702
1360
|
// 判断是否订阅直播
|
|
1703
1361
|
if (sub.live) {
|
|
1704
|
-
//
|
|
1705
|
-
this.liveDetectWithListener(data.live_room.roomid, sub.target);
|
|
1362
|
+
// 启动直播监测
|
|
1363
|
+
await this.liveDetectWithListener(data.live_room.roomid, sub.target);
|
|
1706
1364
|
}
|
|
1707
1365
|
}
|
|
1708
1366
|
// 在B站中订阅该对象
|
|
@@ -1714,151 +1372,17 @@ class ComRegister {
|
|
|
1714
1372
|
this.subManager.push({
|
|
1715
1373
|
id: +sub.uid,
|
|
1716
1374
|
uid: sub.uid,
|
|
1717
|
-
roomId: sub.live ? data.live_room.roomid :
|
|
1375
|
+
roomId: sub.live ? data.live_room.roomid : "",
|
|
1718
1376
|
target: sub.target,
|
|
1719
|
-
platform:
|
|
1377
|
+
platform: "",
|
|
1720
1378
|
live: sub.live,
|
|
1721
|
-
dynamic: sub.dynamic
|
|
1379
|
+
dynamic: sub.dynamic,
|
|
1722
1380
|
});
|
|
1723
1381
|
}
|
|
1724
1382
|
}
|
|
1725
|
-
async loadSubFromDatabase() {
|
|
1726
|
-
// 判断登录信息是否已加载完毕
|
|
1727
|
-
await this.checkIfLoginInfoIsLoaded();
|
|
1728
|
-
// 如果未登录,则直接返回
|
|
1729
|
-
if (!(await this.checkIfIsLogin())) {
|
|
1730
|
-
// log
|
|
1731
|
-
this.logger.info(`账号未登录,请登录`);
|
|
1732
|
-
return;
|
|
1733
|
-
}
|
|
1734
|
-
// 已存在订阅管理对象,不再进行订阅操作
|
|
1735
|
-
if (this.subManager.length !== 0)
|
|
1736
|
-
return;
|
|
1737
|
-
// 从数据库中获取数据
|
|
1738
|
-
const subData = await this.ctx.database.get('bilibili', { id: { $gt: 0 } });
|
|
1739
|
-
// 定义变量:订阅直播数
|
|
1740
|
-
let liveSubNum = 0;
|
|
1741
|
-
// 循环遍历
|
|
1742
|
-
for (const sub of subData) {
|
|
1743
|
-
// 判断是否存在没有任何订阅的数据
|
|
1744
|
-
if (!sub.dynamic && !sub.live) { // 存在未订阅任何项目的数据
|
|
1745
|
-
// 删除该条数据
|
|
1746
|
-
this.ctx.database.remove('bilibili', { id: sub.id });
|
|
1747
|
-
// log
|
|
1748
|
-
this.logger.warn(`UID:${sub.uid} 该条数据没有任何订阅数据,自动取消订阅`);
|
|
1749
|
-
// 跳过下面的步骤
|
|
1750
|
-
continue;
|
|
1751
|
-
}
|
|
1752
|
-
// 判断用户是否在B站中订阅了
|
|
1753
|
-
const subUserData = await this.subUserInBili(sub.uid);
|
|
1754
|
-
// 判断是否订阅
|
|
1755
|
-
if (!subUserData.flag) {
|
|
1756
|
-
// log
|
|
1757
|
-
this.logger.warn(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
|
|
1758
|
-
// 发送私聊消息
|
|
1759
|
-
await this.sendPrivateMsg(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
|
|
1760
|
-
// 删除该条数据
|
|
1761
|
-
await this.ctx.database.remove('bilibili', { id: sub.id });
|
|
1762
|
-
// 跳过下面的步骤
|
|
1763
|
-
continue;
|
|
1764
|
-
}
|
|
1765
|
-
// 获取推送目标数组
|
|
1766
|
-
const target = JSON.parse(sub.target);
|
|
1767
|
-
/* 判断数据库是否被篡改 */
|
|
1768
|
-
// 获取用户信息
|
|
1769
|
-
let content;
|
|
1770
|
-
const attempts = 3;
|
|
1771
|
-
for (let i = 0; i < attempts; i++) {
|
|
1772
|
-
try {
|
|
1773
|
-
// 获取用户信息
|
|
1774
|
-
content = await this.ctx.ba.getUserInfo(sub.uid);
|
|
1775
|
-
// 成功则跳出循环
|
|
1776
|
-
break;
|
|
1777
|
-
}
|
|
1778
|
-
catch (e) {
|
|
1779
|
-
this.logger.error('getSubFromDatabase() getUserInfo() 发生了错误,错误为:' + e.message);
|
|
1780
|
-
if (i === attempts - 1) { // 已尝试三次
|
|
1781
|
-
// 发送私聊消息并重启服务
|
|
1782
|
-
return await this.sendPrivateMsgAndStopService();
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
// 获取data
|
|
1787
|
-
const { data } = content;
|
|
1788
|
-
// 定义函数删除数据和发送提示
|
|
1789
|
-
const deleteSub = async () => {
|
|
1790
|
-
// 从数据库删除该条数据
|
|
1791
|
-
await this.ctx.database.remove('bilibili', { id: sub.id });
|
|
1792
|
-
// 给用户发送提示
|
|
1793
|
-
await this.sendPrivateMsg(`UID:${sub.uid} 数据库内容被篡改,已取消对该UP主的订阅`);
|
|
1794
|
-
};
|
|
1795
|
-
// 判断是否有其他问题
|
|
1796
|
-
if (content.code !== 0) {
|
|
1797
|
-
switch (content.code) {
|
|
1798
|
-
case -352:
|
|
1799
|
-
case -403: {
|
|
1800
|
-
await this.sendPrivateMsg('你的登录信息已过期,请重新登录Bilibili');
|
|
1801
|
-
return;
|
|
1802
|
-
}
|
|
1803
|
-
case -400:
|
|
1804
|
-
case -404:
|
|
1805
|
-
default: {
|
|
1806
|
-
await deleteSub();
|
|
1807
|
-
// PrivateMsg
|
|
1808
|
-
await this.sendPrivateMsg(`UID:${sub.uid} 数据出现问题,自动取消订阅`);
|
|
1809
|
-
// log
|
|
1810
|
-
this.logger.info(`UID:${sub.uid} 数据出现问题,自动取消订阅`);
|
|
1811
|
-
return;
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
// 检测房间号是否被篡改
|
|
1816
|
-
if (sub.live && (!data.live_room || data.live_room.roomid != sub.room_id)) {
|
|
1817
|
-
// 房间号被篡改,删除该订阅
|
|
1818
|
-
await deleteSub();
|
|
1819
|
-
// log
|
|
1820
|
-
this.logger.info(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
|
|
1821
|
-
// Send msg
|
|
1822
|
-
await this.sendPrivateMsg(`UID:${sub.uid} 房间号被篡改,自动取消订阅`);
|
|
1823
|
-
// 直接返回
|
|
1824
|
-
return;
|
|
1825
|
-
}
|
|
1826
|
-
// 构建订阅对象
|
|
1827
|
-
const subManagerItem = {
|
|
1828
|
-
id: sub.id,
|
|
1829
|
-
uid: sub.uid,
|
|
1830
|
-
roomId: sub.room_id,
|
|
1831
|
-
target,
|
|
1832
|
-
platform: sub.platform,
|
|
1833
|
-
live: sub.live === 1 ? true : false,
|
|
1834
|
-
dynamic: sub.dynamic === 1 ? true : false,
|
|
1835
|
-
liveDispose: null
|
|
1836
|
-
};
|
|
1837
|
-
// 判断是否订阅直播
|
|
1838
|
-
if (sub.live) {
|
|
1839
|
-
// 判断订阅直播数是否超过限制
|
|
1840
|
-
if (!this.config.unlockSubLimits && liveSubNum >= 3) {
|
|
1841
|
-
// 将live改为false
|
|
1842
|
-
subManagerItem.live = false;
|
|
1843
|
-
// log
|
|
1844
|
-
this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1845
|
-
// 发送错误消息
|
|
1846
|
-
await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1847
|
-
}
|
|
1848
|
-
else {
|
|
1849
|
-
// 直播订阅数+1
|
|
1850
|
-
liveSubNum++;
|
|
1851
|
-
// 订阅直播,开始循环检测
|
|
1852
|
-
this.liveDetectWithListener(sub.room_id, target);
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
|
-
// 保存新订阅对象
|
|
1856
|
-
this.subManager.push(subManagerItem);
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
1383
|
checkIfDynamicDetectIsNeeded() {
|
|
1860
1384
|
// 检查是否有订阅对象需要动态监测
|
|
1861
|
-
if (this.subManager.some(sub => sub.dynamic))
|
|
1385
|
+
if (this.subManager.some((sub) => sub.dynamic))
|
|
1862
1386
|
this.enableDynamicDetect();
|
|
1863
1387
|
}
|
|
1864
1388
|
enableDynamicDetect() {
|
|
@@ -1870,110 +1394,12 @@ class ComRegister {
|
|
|
1870
1394
|
this.dynamicDispose = this.ctx.setInterval(this.dynamicDetect(), this.config.dynamicLoopTime * 1000);
|
|
1871
1395
|
}
|
|
1872
1396
|
}
|
|
1873
|
-
unsubSingle(id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
|
|
1874
|
-
// 定义返回消息
|
|
1875
|
-
let msg;
|
|
1876
|
-
// 定义方法:检查是否没有任何订阅
|
|
1877
|
-
const checkIfNoSubExist = (sub) => !sub.dynamic && !sub.live;
|
|
1878
|
-
// 定义方法:将订阅对象从订阅管理对象中移除
|
|
1879
|
-
const removeSub = (index) => {
|
|
1880
|
-
// 从管理对象中移除
|
|
1881
|
-
this.subManager.splice(index, 1);
|
|
1882
|
-
// 从数据库中删除
|
|
1883
|
-
this.ctx.database.remove('bilibili', [this.subManager[index].id]);
|
|
1884
|
-
// num--
|
|
1885
|
-
this.num--;
|
|
1886
|
-
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1887
|
-
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1888
|
-
};
|
|
1889
|
-
try {
|
|
1890
|
-
switch (type) {
|
|
1891
|
-
case 0: { // 取消Live订阅
|
|
1892
|
-
// 获取订阅对象所在的索引
|
|
1893
|
-
const index = this.subManager.findIndex(sub => sub.roomId === id);
|
|
1894
|
-
// 获取订阅对象
|
|
1895
|
-
const sub = this.subManager.find(sub => sub.roomId === id);
|
|
1896
|
-
// 判断是否存在订阅对象
|
|
1897
|
-
if (!sub) {
|
|
1898
|
-
msg = '未订阅该用户,无需取消订阅';
|
|
1899
|
-
return msg;
|
|
1900
|
-
}
|
|
1901
|
-
// 取消订阅
|
|
1902
|
-
sub.live = false;
|
|
1903
|
-
// 如果没有对这个UP的任何订阅,则移除
|
|
1904
|
-
if (checkIfNoSubExist(sub)) {
|
|
1905
|
-
// 从管理对象中移除
|
|
1906
|
-
removeSub(index);
|
|
1907
|
-
return '已取消订阅该用户';
|
|
1908
|
-
}
|
|
1909
|
-
// 更新数据库
|
|
1910
|
-
this.ctx.database.upsert('bilibili', [{
|
|
1911
|
-
id: +`${sub.id}`,
|
|
1912
|
-
live: 0
|
|
1913
|
-
}]);
|
|
1914
|
-
return '已取消订阅Live';
|
|
1915
|
-
}
|
|
1916
|
-
case 1: { // 取消Dynamic订阅
|
|
1917
|
-
// 获取订阅对象所在的索引
|
|
1918
|
-
const index = this.subManager.findIndex(sub => sub.uid === id);
|
|
1919
|
-
// 获取订阅对象
|
|
1920
|
-
const sub = this.subManager.find(sub => sub.uid === id);
|
|
1921
|
-
// 判断是否存在订阅对象
|
|
1922
|
-
if (!sub) {
|
|
1923
|
-
msg = '未订阅该用户,无需取消订阅';
|
|
1924
|
-
return msg;
|
|
1925
|
-
}
|
|
1926
|
-
// 取消订阅
|
|
1927
|
-
this.subManager[index].dynamic = false;
|
|
1928
|
-
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1929
|
-
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1930
|
-
// 如果没有对这个UP的任何订阅,则移除
|
|
1931
|
-
if (checkIfNoSubExist(sub)) {
|
|
1932
|
-
// 从管理对象中移除
|
|
1933
|
-
removeSub(index);
|
|
1934
|
-
return '已取消订阅该用户';
|
|
1935
|
-
}
|
|
1936
|
-
// 更新数据库
|
|
1937
|
-
this.ctx.database.upsert('bilibili', [{
|
|
1938
|
-
id: sub.id,
|
|
1939
|
-
dynamic: 0
|
|
1940
|
-
}]);
|
|
1941
|
-
return '已取消订阅Dynamic';
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
finally {
|
|
1946
|
-
// 执行完该方法后,保证执行一次updateSubNotifier()
|
|
1947
|
-
this.updateSubNotifier();
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
checkIfUserIsTheLastOneWhoSubDyn() {
|
|
1951
|
-
if (this.dynamicDispose && !this.subManager.some(sub => sub.dynamic)) {
|
|
1952
|
-
// 停止动态监测
|
|
1953
|
-
this.dynamicDispose();
|
|
1954
|
-
this.dynamicDispose = null;
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
|
-
unsubAll(uid) {
|
|
1958
|
-
this.subManager.filter(sub => sub.uid === uid).map(async (sub, i) => {
|
|
1959
|
-
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1960
|
-
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
1961
|
-
// 从数据库中删除订阅
|
|
1962
|
-
await this.ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
|
|
1963
|
-
// 将该订阅对象从订阅管理对象中移除
|
|
1964
|
-
this.subManager.splice(i, 1);
|
|
1965
|
-
// id--
|
|
1966
|
-
this.num--;
|
|
1967
|
-
// 发送成功通知
|
|
1968
|
-
this.sendPrivateMsg(`UID:${uid},已取消订阅该用户`);
|
|
1969
|
-
// 更新控制台提示
|
|
1970
|
-
this.updateSubNotifier();
|
|
1971
|
-
});
|
|
1972
|
-
}
|
|
1973
1397
|
async checkIfIsLogin() {
|
|
1974
|
-
if ((await this.ctx.database.get(
|
|
1398
|
+
if ((await this.ctx.database.get("loginBili", 1)).length !== 0) {
|
|
1399
|
+
// 数据库中有数据
|
|
1975
1400
|
// 检查cookie中是否有值
|
|
1976
|
-
if (this.ctx.ba.getCookies() !==
|
|
1401
|
+
if (this.ctx.ba.getCookies() !== "[]") {
|
|
1402
|
+
// 有值说明已登录
|
|
1977
1403
|
return true;
|
|
1978
1404
|
}
|
|
1979
1405
|
}
|
|
@@ -1983,28 +1409,33 @@ class ComRegister {
|
|
|
1983
1409
|
(function (ComRegister) {
|
|
1984
1410
|
ComRegister.Config = koishi_1.Schema.object({
|
|
1985
1411
|
sub: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
1986
|
-
uid: koishi_1.Schema.string().description(
|
|
1987
|
-
dynamic: koishi_1.Schema.boolean().description(
|
|
1988
|
-
live: koishi_1.Schema.boolean().description(
|
|
1412
|
+
uid: koishi_1.Schema.string().description("订阅用户UID"),
|
|
1413
|
+
dynamic: koishi_1.Schema.boolean().description("是否订阅用户动态"),
|
|
1414
|
+
live: koishi_1.Schema.boolean().description("是否订阅用户直播"),
|
|
1989
1415
|
target: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
1990
1416
|
channelIdArr: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
1991
|
-
channelId: koishi_1.Schema.string().description(
|
|
1992
|
-
dynamic: koishi_1.Schema.boolean().description(
|
|
1993
|
-
live: koishi_1.Schema.boolean().description(
|
|
1994
|
-
|
|
1995
|
-
atAll: koishi_1.Schema.boolean().description(
|
|
1996
|
-
})).description(
|
|
1997
|
-
platform: koishi_1.Schema.string().description(
|
|
1998
|
-
})).description(
|
|
1999
|
-
}))
|
|
1417
|
+
channelId: koishi_1.Schema.string().description("频道/群组号"),
|
|
1418
|
+
dynamic: koishi_1.Schema.boolean().description("该频道/群组是否推送动态信息"),
|
|
1419
|
+
live: koishi_1.Schema.boolean().description("该频道/群组是否推送直播通知"),
|
|
1420
|
+
liveGuardBuy: koishi_1.Schema.boolean().description("该频道/群组是否推送弹幕消息"),
|
|
1421
|
+
atAll: koishi_1.Schema.boolean().description("推送开播通知时是否艾特全体成员"),
|
|
1422
|
+
})).description("频道/群组信息"),
|
|
1423
|
+
platform: koishi_1.Schema.string().description("推送平台"),
|
|
1424
|
+
})).description("订阅用户需要发送的频道/群组信息"),
|
|
1425
|
+
}))
|
|
1426
|
+
.role("table")
|
|
1427
|
+
.description("手动输入订阅信息,方便自定义订阅内容,这里的订阅内容不会存入数据库。uid: 订阅用户UID,dynamic: 是否需要订阅动态,live: 是否需要订阅直播"),
|
|
2000
1428
|
master: koishi_1.Schema.object({
|
|
2001
1429
|
enable: koishi_1.Schema.boolean(),
|
|
2002
1430
|
platform: koishi_1.Schema.string(),
|
|
2003
1431
|
masterAccount: koishi_1.Schema.string(),
|
|
2004
|
-
masterAccountGuildId: koishi_1.Schema.string()
|
|
1432
|
+
masterAccountGuildId: koishi_1.Schema.string(),
|
|
2005
1433
|
}),
|
|
2006
|
-
unlockSubLimits: koishi_1.Schema.boolean().required(),
|
|
2007
1434
|
automaticResend: koishi_1.Schema.boolean().required(),
|
|
1435
|
+
liveDetectMode: koishi_1.Schema.union([
|
|
1436
|
+
koishi_1.Schema.const("API"),
|
|
1437
|
+
koishi_1.Schema.const("WS"),
|
|
1438
|
+
]).required(),
|
|
2008
1439
|
restartPush: koishi_1.Schema.boolean().required(),
|
|
2009
1440
|
pushTime: koishi_1.Schema.number().required(),
|
|
2010
1441
|
liveLoopTime: koishi_1.Schema.number().default(10),
|
|
@@ -2013,14 +1444,13 @@ class ComRegister {
|
|
|
2013
1444
|
customLiveEnd: koishi_1.Schema.string().required(),
|
|
2014
1445
|
dynamicUrl: koishi_1.Schema.boolean().required(),
|
|
2015
1446
|
dynamicLoopTime: koishi_1.Schema.number().default(60),
|
|
2016
|
-
dynamicCheckNumber: koishi_1.Schema.number().required(),
|
|
2017
1447
|
filter: koishi_1.Schema.object({
|
|
2018
1448
|
enable: koishi_1.Schema.boolean(),
|
|
2019
1449
|
notify: koishi_1.Schema.boolean(),
|
|
2020
1450
|
regex: koishi_1.Schema.string(),
|
|
2021
1451
|
keywords: koishi_1.Schema.array(String),
|
|
2022
1452
|
}),
|
|
2023
|
-
dynamicDebugMode: koishi_1.Schema.boolean().required()
|
|
1453
|
+
dynamicDebugMode: koishi_1.Schema.boolean().required(),
|
|
2024
1454
|
});
|
|
2025
1455
|
})(ComRegister || (ComRegister = {}));
|
|
2026
1456
|
exports.default = ComRegister;
|