koishi-plugin-bilibili-notify 2.0.0-alpha.1 → 2.0.0-alpha.11

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.
@@ -10,15 +10,16 @@ const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
10
10
  const koishi_1 = require("koishi");
11
11
  // 导入qrcode
12
12
  const qrcode_1 = __importDefault(require("qrcode"));
13
- const jimp_1 = require("jimp");
14
13
  var LiveType;
15
14
  (function (LiveType) {
16
15
  LiveType[LiveType["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
17
16
  LiveType[LiveType["StartBroadcasting"] = 1] = "StartBroadcasting";
18
17
  LiveType[LiveType["LiveBroadcast"] = 2] = "LiveBroadcast";
18
+ LiveType[LiveType["StopBroadcast"] = 3] = "StopBroadcast";
19
19
  })(LiveType || (LiveType = {}));
20
20
  class ComRegister {
21
21
  static inject = ['ba', 'gi', 'database', 'sm'];
22
+ qqRelatedBotList = ['qq', 'onebot', 'red', 'satori', 'chronocat'];
22
23
  logger;
23
24
  config;
24
25
  loginTimer;
@@ -26,8 +27,10 @@ class ComRegister {
26
27
  rebootCount = 0;
27
28
  subNotifier;
28
29
  subManager = [];
30
+ // 检查登录数据库是否有数据
31
+ loginDBData;
29
32
  // 机器人实例
30
- bot;
33
+ privateBot;
31
34
  // 动态销毁函数
32
35
  dynamicDispose;
33
36
  // 发送消息方式
@@ -36,26 +39,27 @@ class ComRegister {
36
39
  constructor(ctx, config) {
37
40
  this.logger = ctx.logger('cr');
38
41
  this.config = config;
39
- // 拿到机器人实例
40
- this.bot = ctx.bots.find(bot => bot.platform === config.platform);
41
- if (!this.bot) {
42
+ // 拿到私人机器人实例
43
+ this.privateBot = ctx.bots.find(bot => bot.platform === config.master.platform);
44
+ if (!this.privateBot) {
42
45
  ctx.notifier.create({
43
- type: 'danger',
44
- content: '未找到对应机器人实例,请检查配置是否正确或重新配置适配器!'
46
+ content: '您未配置私人机器人,将无法向您推送机器人状态!'
45
47
  });
46
- this.logger.error('未找到对应机器人实例,请检查配置是否正确或重新配置适配器!');
48
+ this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
47
49
  }
50
+ // 检查登录数据库是否有数据
51
+ ctx.database.get('loginBili', 1, ['dynamic_group_id']).then(data => this.loginDBData = data[0]);
48
52
  // 从数据库获取订阅
49
53
  this.getSubFromDatabase(ctx);
50
54
  // 判断消息发送方式
51
55
  if (config.automaticResend) {
52
- this.sendMsgFunc = async (guild, content) => {
56
+ this.sendMsgFunc = async (bot, channelId, content) => {
53
57
  // 多次尝试发送消息
54
58
  const attempts = 3;
55
59
  for (let i = 0; i < attempts; i++) {
56
60
  try {
57
61
  // 发送消息
58
- await this.bot.sendMessage(guild, content);
62
+ await bot.sendMessage(channelId, content);
59
63
  // 防止消息发送速度过快被忽略
60
64
  await ctx.sleep(500);
61
65
  // 成功发送消息,跳出循环
@@ -63,19 +67,19 @@ class ComRegister {
63
67
  }
64
68
  catch (e) {
65
69
  if (i === attempts - 1) { // 已尝试三次
66
- this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
70
+ this.logger.error(`发送群组ID:${channelId}消息失败!原因: ` + e.message);
67
71
  console.log(e);
68
- this.sendPrivateMsg(`发送群组ID:${guild}消息失败,请查看日志`);
72
+ this.sendPrivateMsg(`发送群组ID:${channelId}消息失败,请查看日志`);
69
73
  }
70
74
  }
71
75
  }
72
76
  };
73
77
  }
74
78
  else {
75
- this.sendMsgFunc = async (guild, content) => {
79
+ this.sendMsgFunc = async (bot, guild, content) => {
76
80
  try {
77
81
  // 发送消息
78
- await this.bot.sendMessage(guild, content);
82
+ await bot.sendMessage(guild, content);
79
83
  }
80
84
  catch (e) {
81
85
  this.logger.error(`发送群组ID:${guild}消息失败!原因: ` + e.message);
@@ -99,9 +103,30 @@ class ComRegister {
99
103
  .usage('查看订阅管理对象')
100
104
  .example('status sm')
101
105
  .action(async () => {
102
- console.log(this.subManager);
106
+ this.logger.info(this.subManager);
103
107
  return '查看控制台';
104
108
  });
109
+ statusCom
110
+ .subcommand('.bot', '查询当前拥有的机器人信息', { hidden: true })
111
+ .usage('查询当前拥有的机器人信息')
112
+ .example('status bot 查询当前拥有的机器人信息')
113
+ .action(() => {
114
+ this.logger.info('开始输出BOT信息');
115
+ ctx.bots.forEach(bot => {
116
+ this.logger.info('--------------------------------');
117
+ this.logger.info('平台:' + bot.platform);
118
+ this.logger.info('名称:' + bot.user.name);
119
+ this.logger.info('--------------------------------');
120
+ });
121
+ });
122
+ statusCom
123
+ .subcommand('.env', '查询当前环境的信息', { hidden: true })
124
+ .usage('查询当前环境的信息')
125
+ .example('status env 查询当前环境的信息')
126
+ .action(async ({ session }) => {
127
+ await session.send(`Guild ID:${session.event.guild.id}`);
128
+ await session.send(`Channel ID: ${session.event.channel.id}`);
129
+ });
105
130
  const biliCom = ctx.command('bili', 'bili-notify插件相关指令', { permissions: ['authority:3'] });
106
131
  biliCom.subcommand('.login', '登录B站之后才可以进行之后的操作')
107
132
  .usage('使用二维码登录,登录B站之后才可以进行之后的操作')
@@ -216,6 +241,7 @@ class ComRegister {
216
241
  await session.send(this.unsubSingle(ctx, sub.uid, 1)); /* 1为取消订阅Dynamic */
217
242
  // 将存在flag设置为true
218
243
  exist = true;
244
+ // 结束循环
219
245
  return;
220
246
  }
221
247
  // 取消全部订阅 执行dispose方法,销毁定时器
@@ -228,9 +254,12 @@ class ComRegister {
228
254
  // 将订阅对象移出订阅关注组
229
255
  const removeUserFromGroupData = await ctx.ba.removeUserFromGroup(sub.uid);
230
256
  // 判断是否移出成功 22105关注对象为自己
231
- if (removeUserFromGroupData.code !== 0 || removeUserFromGroupData.data !== 22105) {
257
+ if (removeUserFromGroupData.code !== 0 && removeUserFromGroupData.code !== 22105) {
232
258
  // 移出失败
233
259
  await session.send('取消订阅对象失败,请稍后重试');
260
+ // 将存在flag设置为true
261
+ exist = true;
262
+ // 结束循环
234
263
  return;
235
264
  }
236
265
  // id--
@@ -263,29 +292,19 @@ class ComRegister {
263
292
  return subTable;
264
293
  });
265
294
  biliCom
266
- .subcommand('.sub <mid:string> [...guildId:string]', '订阅用户动态和直播通知')
295
+ .subcommand('.sub <mid:string> [...groupId:string]', '订阅用户动态和直播通知')
296
+ .option('multiplatform', '-m <value:string>', { type: /^[A-Za-z0-9]+@?(?:,[A-Za-z0-9]+@?)*\.[A-Za-z0-9]+(?:;[A-Za-z0-9]+@?(?:,[A-Za-z0-9]+@?)*\.[A-Za-z0-9]+)*$/ })
267
297
  .option('live', '-l')
268
298
  .option('dynamic', '-d')
269
- .usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d。若没有加任何参数,之后会向你单独询问,尖括号中为必选参数,中括号为可选参数,目标群号若不填,则默认为当前群聊')
270
- .example('bili sub 1194210119 目标QQ群号(实验性) -l -d 订阅UID为1194210119的UP主的动态和直播')
271
- .action(async ({ session, options }, mid, ...guildId) => {
299
+ .option('atAll', '-a')
300
+ .usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d')
301
+ .example('bili sub 1194210119 目标群号或频道号 -l -d 订阅UID为1194210119的UP主的动态和直播')
302
+ .action(async ({ session, options }, mid, ...groupId) => {
272
303
  this.logger.info('调用bili.sub指令');
273
304
  // 先判断是否订阅直播,再判断是否解锁订阅限制,最后判断直播订阅是否已超三个
274
305
  if (options.live && !this.config.unlockSubLimits && (this.subManager.reduce((acc, cur) => acc + (cur.live ? 1 : 0), 0) >= 3)) {
275
306
  return '直播订阅已达上限,请取消部分直播订阅后再进行订阅';
276
307
  }
277
- // 检查是否是不支持的平台
278
- switch (session.event.platform) {
279
- case 'lark':
280
- case 'red':
281
- case 'onebot':
282
- case 'telegram':
283
- case 'satori':
284
- case 'chronocat':
285
- case 'qq':
286
- case 'qqguild': break;
287
- default: return '暂不支持该平台';
288
- }
289
308
  // 检查是否登录
290
309
  if (!(await this.checkIfIsLogin(ctx))) {
291
310
  // 未登录直接返回
@@ -294,54 +313,97 @@ class ComRegister {
294
313
  // 检查必选参数是否已填
295
314
  if (!mid)
296
315
  return '请输入用户uid';
297
- // 检查数据库是否有数据
298
- const loginDBData = (await ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
299
- // 判断是否有数据
300
- if (loginDBData.dynamic_group_id === '' || loginDBData.dynamic_group_id === null) {
301
- // 没有数据,没有创建分组,尝试创建分组
302
- const createGroupData = await ctx.ba.createGroup("订阅");
303
- // 如果分组已创建,则获取分组id
304
- if (createGroupData.code === 22106) {
305
- // 分组已存在,拿到之前的分组id
306
- const allGroupData = await ctx.ba.getAllGroup();
307
- // 遍历所有分组
308
- for (const group of allGroupData.data) {
309
- // 找到订阅分组
310
- if (group.name === '订阅') {
311
- // 拿到分组id
312
- loginDBData.dynamic_group_id = group.tagid;
313
- // 结束循环
314
- break;
315
- }
316
- }
316
+ // 订阅对象
317
+ const subUserData = await this.subUserInBili(ctx, mid);
318
+ // 判断是否订阅对象存在
319
+ if (!subUserData.flag)
320
+ return '订阅对象失败,请稍后重试!';
321
+ // 定义目标变量
322
+ let target = [];
323
+ // 判断是否使用了多群组推送
324
+ if (groupId.length > 0) {
325
+ // 定义channelIdArr
326
+ const channelIdArr = [];
327
+ // 遍历输入的群组
328
+ groupId.forEach(group => {
329
+ channelIdArr.push({
330
+ channelId: group,
331
+ atAll: options.atAll
332
+ });
333
+ });
334
+ target.push({
335
+ channelIdArr,
336
+ platform: session.event.platform
337
+ });
338
+ }
339
+ else {
340
+ // 判断是否使用多平台功能
341
+ if (options.multiplatform) {
342
+ // 分割字符串,赋值给target
343
+ target = this.splitMultiPlatformStr(options.multiplatform);
317
344
  }
318
- else if (createGroupData.code !== 0) {
319
- // 创建分组失败
320
- return '创建关注分组出错';
345
+ // 判断是否使用了多平台
346
+ if (target) {
347
+ target.forEach(async ({ channelIdArr, platform }, index) => {
348
+ if (channelIdArr.length > 0) { // 输入了推送群号或频道号
349
+ // 拿到对应的bot
350
+ const bot = this.getBot(ctx, platform);
351
+ // 判断是否配置了对应平台的机器人
352
+ if (!ctx.bots.some(bot => bot.platform === platform)) {
353
+ await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
354
+ }
355
+ // 判断是否需要加入的群全部推送
356
+ if (channelIdArr[0].channelId !== 'all') {
357
+ // 定义满足条件的群组数组
358
+ const targetArr = [];
359
+ // 获取机器人加入的群组
360
+ const guildList = await bot.getGuildList();
361
+ // 遍历target数组
362
+ for (const channelId of channelIdArr) {
363
+ // 定义是否加入群组标志
364
+ let flag = false;
365
+ // 遍历群组
366
+ for (const guild of guildList.data) {
367
+ // 获取频道列表
368
+ const channelList = await bot.getChannelList(guild.id);
369
+ // 判断机器人是否加入群聊或频道
370
+ if (channelList.data.some(channel => channel.id === channelId.channelId)) {
371
+ // 加入群聊或频道
372
+ targetArr.push(channelId);
373
+ // 设置标志位为true
374
+ flag = true;
375
+ // 结束循环
376
+ break;
377
+ }
378
+ }
379
+ if (!flag) {
380
+ // 不满足条件发送错误提示
381
+ await session.send(`您的机器未加入${channelId.channelId},无法对该群或频道进行推送`);
382
+ }
383
+ }
384
+ // 判断targetArr是否为空
385
+ if (target.length === 0) {
386
+ // 为空则默认为当前环境
387
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
388
+ // 没有满足条件的群组或频道
389
+ await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
390
+ }
391
+ // 将符合条件的群组添加到target中
392
+ target[index].channelIdArr = targetArr;
393
+ }
394
+ // 如果为all则全部推送,不需要进行处理
395
+ }
396
+ else {
397
+ // 未填写群号或频道号,默认为当前环境
398
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
399
+ // 发送提示消息
400
+ await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
401
+ }
402
+ });
321
403
  }
322
- // 创建成功,保存到数据库
323
- ctx.database.set('loginBili', 1, { dynamic_group_id: loginDBData.dynamic_group_id });
324
- }
325
- // 订阅对象
326
- const subUserData = await ctx.ba.follow(mid);
327
- // 判断是否订阅成功
328
- switch (subUserData.code) {
329
- case -101: return '账号未登录,请使用指令bili login登录后再进行订阅操作';
330
- case -102: return '账号被封停,无法进行订阅操作';
331
- case 22002: return '因对方隐私设置,无法进行订阅操作';
332
- case 22003: return '你已将对方拉黑,无法进行订阅操作';
333
- case 22013: return '账号已注销,无法进行订阅操作';
334
- case 40061: return '账号不存在,请检查uid输入是否正确或用户是否存在';
335
- case 22001: break; // 订阅对象为自己 无需添加到分组
336
- case 22014: // 已关注订阅对象 无需再次关注
337
- case 0: { // 执行订阅成功
338
- // 把订阅对象添加到分组中
339
- const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, loginDBData.dynamic_group_id);
340
- // 判断是否添加成功
341
- if (copyUserToGroupData.code !== 0) {
342
- // 添加失败
343
- return '添加订阅对象到分组失败,请稍后重试';
344
- }
404
+ else {
405
+ // 用户直接订阅,将当前环境赋值给target
406
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
345
407
  }
346
408
  }
347
409
  // 定义外围变量
@@ -379,88 +441,14 @@ class ComRegister {
379
441
  // 返回错误信息
380
442
  return msg;
381
443
  }
382
- // 定义目标群组id
383
- let targetId;
384
- // 定义目标群组id数组
385
- let targetIdArr;
386
- // 判断是否输入了QQ群号
387
- if (guildId.length > 0) { // 输入了QQ群号
388
- // 定义方法
389
- const checkIfGuildHasJoined = async (bot) => {
390
- // 获取机器人加入的群组
391
- const guildList = await bot.getGuildList();
392
- // 定义满足条件的群组数组
393
- const targetArr = [];
394
- // 判断群号是否符合条件
395
- for (const guild of guildId) {
396
- // 判断是否机器人加入了该群
397
- if (guildList.data.some(cv => cv.id === guild)) { // 机器人加入了该群
398
- // 保存到数组
399
- targetArr.push(guild);
400
- // 继续下一个循环
401
- continue;
402
- }
403
- // 不满足条件发送错误提示
404
- session.send(`您的机器未加入${guild},无法对该群进行推送`);
405
- }
406
- // 返回数组
407
- return targetArr;
408
- };
409
- // 定义可用的群组数组
410
- let okGuild = [];
411
- // 判断是否需要加入的群全部推送
412
- if (guildId[0] === 'all') {
413
- // 判断是否有群机器人相关Bot
414
- if (['qq', 'onebot', 'red', 'satori', 'chronocat'].includes(session.event.platform)) {
415
- // 推送所有群组
416
- okGuild.push('all');
417
- }
418
- else {
419
- // 发送错误提示并返回
420
- session.send('您尚未配置任何QQ群相关机器人,不能对QQ群进行操作');
421
- // 直接返回
422
- return;
423
- }
424
- }
425
- else {
426
- // 判断是否有群机器人相关Bot
427
- switch (session.event.platform) {
428
- case 'qq':
429
- case 'onebot':
430
- case 'red':
431
- case 'satori':
432
- case 'chronocat': {
433
- // 检查机器人是否加入该群
434
- okGuild = await checkIfGuildHasJoined(this.bot);
435
- break;
436
- }
437
- default: {
438
- // 发送错误提示并返回
439
- session.send('您尚未配置任何QQ群相关机器人,不能对QQ群进行操作');
440
- // 直接返回
441
- return;
442
- }
443
- }
444
- }
445
- // 将可用的目标赋值给数组
446
- targetIdArr = okGuild;
447
- // 将群号用空格进行分割
448
- targetId = okGuild.join(' ');
449
- }
450
- else { // 没有输入QQ群号
451
- // 为当前群聊环境进行推送
452
- targetId = session.event.channel.id;
453
- // 将目标id转换为数组进行赋值
454
- targetIdArr = [session.event.channel.id];
455
- }
456
444
  // 获取data
457
445
  const { data } = content;
458
446
  // 判断是否需要订阅直播和动态
459
- const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data);
447
+ const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data.live_room);
460
448
  // 判断是否未订阅任何消息
461
- if (!liveMsg && !dynamicMsg) {
449
+ if (!liveMsg && !dynamicMsg)
462
450
  return '您未订阅该UP的任何消息';
463
- }
451
+ // 获取到对应的订阅对象
464
452
  const subUser = this.subManager.find(sub => sub.uid === mid);
465
453
  // 判断要订阅的用户是否已经存在于订阅管理对象中
466
454
  if (subUser) {
@@ -475,44 +463,22 @@ class ComRegister {
475
463
  }
476
464
  // 获取直播房间号
477
465
  const roomId = data.live_room?.roomid.toString();
478
- // 保存到数据库中
479
- const sub = await ctx.database.create('bilibili', {
480
- uid: mid,
481
- room_id: roomId,
482
- dynamic: dynamicMsg ? 1 : 0,
483
- video: 1,
484
- live: liveMsg ? 1 : 0,
485
- targetId,
486
- platform: session.event.platform,
487
- time: new Date()
488
- });
489
- // 订阅数+1
490
- this.num++;
491
- // 保存新订阅对象
492
- this.subManager.push({
493
- id: sub.id,
494
- uid: mid,
495
- targetIdArr,
496
- roomId,
497
- platform: session.event.platform,
498
- live: liveMsg,
499
- dynamic: dynamicMsg,
500
- liveDispose: null
501
- });
502
466
  // 获取用户信息
503
467
  let userData;
504
468
  try {
505
- const { data } = await ctx.ba.getMasterInfo(sub.uid);
469
+ const { data } = await ctx.ba.getMasterInfo(mid);
506
470
  userData = data;
507
471
  }
508
472
  catch (e) {
509
473
  this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
510
474
  return '订阅出错啦,请重试';
511
475
  }
512
- console.log(liveMsg, dynamicMsg);
476
+ // 定义live销毁函数
477
+ let liveDispose;
513
478
  // 订阅直播
514
479
  if (liveMsg) {
515
- await session.execute(`bili live ${roomId} ${targetId.split(',').join(' ')}`);
480
+ // 开始循环检测
481
+ liveDispose = ctx.setInterval(this.liveDetect(ctx, roomId, target), config.liveLoopTime * 1000);
516
482
  // 发送订阅消息通知
517
483
  await session.send(`订阅${userData.info.uname}直播通知`);
518
484
  }
@@ -531,29 +497,32 @@ class ComRegister {
531
497
  // 发送订阅消息通知
532
498
  await session.send(`订阅${userData.info.uname}动态通知`);
533
499
  }
500
+ // 保存到数据库中
501
+ const sub = await ctx.database.create('bilibili', {
502
+ uid: mid,
503
+ room_id: roomId,
504
+ dynamic: dynamicMsg ? 1 : 0,
505
+ live: liveMsg ? 1 : 0,
506
+ target: JSON.stringify(target),
507
+ platform: session.event.platform,
508
+ time: new Date()
509
+ });
510
+ // 订阅数+1
511
+ this.num++;
512
+ // 保存新订阅对象
513
+ this.subManager.push({
514
+ id: sub.id,
515
+ uid: mid,
516
+ roomId,
517
+ target,
518
+ platform: session.event.platform,
519
+ live: liveMsg,
520
+ dynamic: dynamicMsg,
521
+ liveDispose
522
+ });
534
523
  // 新增订阅展示到控制台
535
524
  this.updateSubNotifier(ctx);
536
525
  });
537
- biliCom
538
- .subcommand('.live <roomId:string> <...guildId:string>', '订阅主播开播通知', { hidden: true })
539
- .usage('订阅主播开播通知')
540
- .example('bili live 26316137 订阅房间号为26316137的直播间')
541
- .action(async (_, roomId, ...guildId) => {
542
- this.logger.info('调用bili.live指令');
543
- // 如果room_id为空则返回
544
- if (!roomId)
545
- return `${roomId}非法调用 dynamic 指令`; // 订阅主播房间号不能为空
546
- if (!guildId)
547
- return `${roomId}非法调用 dynamic 指令`; // 目标群组或频道不能为空
548
- // 要订阅的对象不在订阅管理对象中,直接返回
549
- const index = this.subManager.findIndex(sub => sub.roomId === roomId);
550
- if (index === -1)
551
- return '请勿直接调用该指令';
552
- // 开始循环检测
553
- const dispose = ctx.setInterval(this.liveDetect(ctx, roomId, guildId), config.liveLoopTime * 1000);
554
- // 保存销毁函数
555
- this.subManager[index].liveDispose = dispose;
556
- });
557
526
  biliCom
558
527
  .subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
559
528
  .usage('查询主播当前直播状态')
@@ -597,19 +566,6 @@ class ComRegister {
597
566
  // pic不存在,说明使用的是page模式
598
567
  await session.send(koishi_1.h.image(buffer, 'image/png'));
599
568
  });
600
- biliCom
601
- .subcommand('.bot', '查询当前拥有的机器人信息', { hidden: true })
602
- .usage('查询当前拥有的机器人信息')
603
- .example('bili bot 查询当前拥有的机器人信息')
604
- .action(() => {
605
- this.logger.info('开始输出BOT信息');
606
- ctx.bots.forEach(bot => {
607
- this.logger.info('--------------------------------');
608
- this.logger.info('平台:' + bot.platform);
609
- this.logger.info('名称:' + bot.user.name);
610
- this.logger.info('--------------------------------');
611
- });
612
- });
613
569
  biliCom
614
570
  .subcommand('.private', '向主人账号发送一条测试消息', { hidden: true })
615
571
  .usage('向主人账号发送一条测试消息')
@@ -621,15 +577,28 @@ class ComRegister {
621
577
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
622
578
  });
623
579
  }
580
+ splitMultiPlatformStr(str) {
581
+ return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
582
+ const channelIdArr = idStr.split(',').map(id => {
583
+ const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
584
+ const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
585
+ return { channelId, atAll };
586
+ });
587
+ return { channelIdArr, platform };
588
+ });
589
+ }
590
+ getBot(ctx, pf) {
591
+ return ctx.bots.find(bot => bot.platform === pf);
592
+ }
624
593
  async sendPrivateMsg(content) {
625
594
  if (this.config.master.enable) {
626
595
  if (this.config.master.masterAccountGuildId) {
627
596
  // 向机器人主人发送消息
628
- await this.bot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
597
+ await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
629
598
  }
630
599
  else {
631
600
  // 向机器人主人发送消息
632
- await this.bot.sendPrivateMessage(this.config.master.masterAccount, content);
601
+ await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content);
633
602
  }
634
603
  }
635
604
  }
@@ -674,22 +643,34 @@ class ComRegister {
674
643
  // 结束
675
644
  return;
676
645
  }
677
- async sendMsg(targets, content) {
678
- // 定义需要发送的数组
679
- let sendArr = [];
680
- // 判断是否需要推送所有机器人加入的群
681
- if (targets[0] === 'all') {
682
- // 获取所有guild
683
- for (const guild of (await this.bot.getGuildList()).data) {
684
- sendArr.push(guild.id);
646
+ async sendMsg(ctx, targets, content, live) {
647
+ for (const target of targets) {
648
+ // 获取机器人实例
649
+ const bot = this.getBot(ctx, target.platform);
650
+ // 定义需要发送的数组
651
+ let sendArr = [];
652
+ // 判断是否需要推送所有机器人加入的群
653
+ if (target.channelIdArr[0].channelId === 'all') {
654
+ // 获取所有guild
655
+ for (const guild of (await bot.getGuildList()).data) {
656
+ sendArr.push({ channelId: guild.id, atAll: target.channelIdArr[0].atAll });
657
+ }
658
+ }
659
+ else {
660
+ sendArr = target.channelIdArr;
661
+ }
662
+ // 循环给每个群组发送
663
+ if (live) {
664
+ // 直播推送,需要判断是否为
665
+ for (const channel of sendArr) {
666
+ await this.sendMsgFunc(bot, channel.channelId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [content, channel.atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" })] }));
667
+ }
668
+ }
669
+ else {
670
+ for (const channel of sendArr) {
671
+ await this.sendMsgFunc(bot, channel.channelId, content);
672
+ }
685
673
  }
686
- }
687
- else {
688
- sendArr = targets;
689
- }
690
- // 循环给每个群组发送
691
- for (const guild of sendArr) {
692
- await this.sendMsgFunc(guild, content);
693
674
  }
694
675
  }
695
676
  dynamicDetect(ctx) {
@@ -819,13 +800,13 @@ class ComRegister {
819
800
  if (e.message === '出现关键词,屏蔽该动态') {
820
801
  // 如果需要发送才发送
821
802
  if (this.config.filter.notify) {
822
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条含有屏蔽关键字的动态`);
803
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
823
804
  }
824
805
  return;
825
806
  }
826
807
  if (e.message === '已屏蔽转发动态') {
827
808
  if (this.config.filter.notify) {
828
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条转发动态,已屏蔽`);
809
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
829
810
  }
830
811
  return;
831
812
  }
@@ -843,12 +824,12 @@ class ComRegister {
843
824
  if (pic) {
844
825
  this.logger.info('推送动态中,使用render模式');
845
826
  // pic存在,使用的是render模式
846
- await this.sendMsg(sub.targetIdArr, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
827
+ await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
847
828
  }
848
829
  else if (buffer) {
849
830
  this.logger.info('推送动态中,使用page模式');
850
831
  // pic不存在,说明使用的是page模式
851
- await this.sendMsg(sub.targetIdArr, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
832
+ await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
852
833
  }
853
834
  else {
854
835
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -1003,13 +984,13 @@ class ComRegister {
1003
984
  if (e.message === '出现关键词,屏蔽该动态') {
1004
985
  // 如果需要发送才发送
1005
986
  if (this.config.filter.notify) {
1006
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条含有屏蔽关键字的动态`);
987
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
1007
988
  }
1008
989
  return;
1009
990
  }
1010
991
  if (e.message === '已屏蔽转发动态') {
1011
992
  if (this.config.filter.notify) {
1012
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条转发动态,已屏蔽`);
993
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
1013
994
  }
1014
995
  return;
1015
996
  }
@@ -1027,12 +1008,12 @@ class ComRegister {
1027
1008
  if (pic) {
1028
1009
  this.logger.info('推送动态中,使用render模式');
1029
1010
  // pic存在,使用的是render模式
1030
- await this.sendMsg(sub.targetIdArr, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1011
+ await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1031
1012
  }
1032
1013
  else if (buffer) {
1033
1014
  this.logger.info('推送动态中,使用page模式');
1034
1015
  // pic不存在,说明使用的是page模式
1035
- await this.sendMsg(sub.targetIdArr, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1016
+ await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1036
1017
  }
1037
1018
  else {
1038
1019
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -1046,7 +1027,7 @@ class ComRegister {
1046
1027
  }
1047
1028
  };
1048
1029
  }
1049
- liveDetect(ctx, roomId, guildId) {
1030
+ liveDetect(ctx, roomId, target) {
1050
1031
  let firstSubscription = true;
1051
1032
  let timer = 0;
1052
1033
  let open = false;
@@ -1056,80 +1037,40 @@ class ComRegister {
1056
1037
  // 相当于锁的作用,防止上一个循环没处理完
1057
1038
  let flag = true;
1058
1039
  // 定义发送直播通知卡片方法
1059
- let sendLiveNotifyCard;
1060
- // 判断直播是否需要@全体成员
1061
- if (this.config.pushUrl) {
1062
- sendLiveNotifyCard = async (data, liveType, liveStartMsg, atAll) => {
1063
- // 定义变量
1064
- let pic;
1065
- let buffer;
1066
- // 多次尝试生成图片
1067
- const attempts = 3;
1068
- for (let i = 0; i < attempts; i++) {
1069
- try {
1070
- // 获取直播通知卡片
1071
- const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
1072
- // 赋值
1073
- pic = picv;
1074
- buffer = bufferv;
1075
- // 成功则跳出循环
1076
- break;
1077
- }
1078
- catch (e) {
1079
- if (i === attempts - 1) { // 已尝试三次
1080
- this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1081
- // 发送私聊消息并重启服务
1082
- return await this.sendPrivateMsgAndStopService(ctx);
1083
- }
1084
- }
1085
- }
1086
- // 推送直播信息
1087
- // pic 存在,使用的是render模式
1088
- if (pic) {
1089
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg, liveType !== LiveType.StartBroadcasting ? `https://live.bilibili.com/${roomId}` : ''] });
1090
- return await this.sendMsg(guildId, pic + msg);
1040
+ const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg) => {
1041
+ // 定义变量
1042
+ let pic;
1043
+ let buffer;
1044
+ // 多次尝试生成图片
1045
+ const attempts = 3;
1046
+ for (let i = 0; i < attempts; i++) {
1047
+ try {
1048
+ // 获取直播通知卡片
1049
+ const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
1050
+ // 赋值
1051
+ pic = picv;
1052
+ buffer = bufferv;
1053
+ // 成功则跳出循环
1054
+ break;
1091
1055
  }
1092
- // pic不存在,说明使用的是page模式
1093
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg, liveType !== LiveType.StartBroadcasting ? `https://live.bilibili.com/${roomId}` : ''] });
1094
- await this.sendMsg(guildId, msg);
1095
- };
1096
- }
1097
- else {
1098
- sendLiveNotifyCard = async (data, liveType, liveStartMsg, atAll) => {
1099
- // 定义变量
1100
- let pic;
1101
- let buffer;
1102
- // 多次尝试生成图片
1103
- const attempts = 3;
1104
- for (let i = 0; i < attempts; i++) {
1105
- try {
1106
- // 获取直播通知卡片
1107
- const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
1108
- // 赋值
1109
- pic = picv;
1110
- buffer = bufferv;
1111
- // 成功则跳出循环
1112
- break;
1113
- }
1114
- catch (e) {
1115
- if (i === attempts - 1) { // 已尝试三次
1116
- this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1117
- // 发送私聊消息并重启服务
1118
- return await this.sendPrivateMsgAndStopService(ctx);
1119
- }
1056
+ catch (e) {
1057
+ if (i === attempts - 1) { // 已尝试三次
1058
+ this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1059
+ // 发送私聊消息并重启服务
1060
+ return await this.sendPrivateMsgAndStopService(ctx);
1120
1061
  }
1121
1062
  }
1122
- // 推送直播信息
1123
- // pic 存在,使用的是render模式
1124
- if (pic) {
1125
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg] });
1126
- return await this.sendMsg(guildId, pic + msg);
1127
- }
1128
- // pic不存在,说明使用的是page模式
1129
- const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), liveStartMsg && liveStartMsg] });
1130
- await this.sendMsg(guildId, msg);
1131
- };
1132
- }
1063
+ }
1064
+ // 推送直播信息
1065
+ // pic 存在,使用的是render模式
1066
+ if (pic) {
1067
+ const msg = liveNotifyMsg ? liveNotifyMsg : '';
1068
+ return await this.sendMsg(ctx, target, pic + msg, true);
1069
+ }
1070
+ // pic不存在,说明使用的是page模式
1071
+ const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg && liveNotifyMsg] });
1072
+ await this.sendMsg(ctx, target, msg, true);
1073
+ };
1133
1074
  // 定义获取主播信息方法
1134
1075
  let useMasterInfo;
1135
1076
  if (this.config.changeMasterInfoApi) {
@@ -1217,22 +1158,10 @@ class ComRegister {
1217
1158
  const liveEndMsg = this.config.customLiveEnd
1218
1159
  .replace('-name', username)
1219
1160
  .replace('-time', await ctx.gi.getTimeDifference(liveTime));
1220
- // 获取头像并缩放
1221
- let resizedImage;
1222
- // Jimp无法处理Webp格式,直接跳过
1223
- try {
1224
- resizedImage = await jimp_1.Jimp.read(userface).then(async (image) => {
1225
- return await image.resize({ w: 100, h: 100 }).getBuffer(jimp_1.JimpMime.png);
1226
- });
1227
- }
1228
- catch (e) {
1229
- if (e.message === 'Unsupported MIME type: image/webp')
1230
- console.log('主播使用的是webp格式头像,无法进行渲染');
1231
- else
1232
- console.log(e);
1233
- }
1234
- // 发送下播通知
1235
- await this.sendMsg(guildId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [resizedImage && koishi_1.h.image(resizedImage, 'image/png'), " ", liveEndMsg] }));
1161
+ // 更改直播时长
1162
+ data.live_time = liveTime;
1163
+ // 发送@全体成员通知
1164
+ await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg);
1236
1165
  }
1237
1166
  // 未进循环,还未开播,继续循环
1238
1167
  break;
@@ -1266,15 +1195,8 @@ class ComRegister {
1266
1195
  .replace('-name', username)
1267
1196
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1268
1197
  .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`);
1269
- // 判断是否需要@全体成员
1270
- if (this.config.liveStartAtAll) {
1271
- // 发送@全体成员通知
1272
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg, true);
1273
- }
1274
- else {
1275
- // 发送直播通知卡片
1276
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1277
- }
1198
+ // 发送消息
1199
+ await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1278
1200
  }
1279
1201
  else { // 还在直播
1280
1202
  if (this.config.pushTime > 0) {
@@ -1283,8 +1205,13 @@ class ComRegister {
1283
1205
  if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
1284
1206
  // 到时间重新计时
1285
1207
  timer = 0;
1208
+ // 定义直播中通知消息
1209
+ const liveMsg = this.config.customLive ? this.config.customLive
1210
+ .replace('-name', username)
1211
+ .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1212
+ .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : '';
1286
1213
  // 发送直播通知卡片
1287
- sendLiveNotifyCard(data, LiveType.LiveBroadcast);
1214
+ sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1288
1215
  }
1289
1216
  }
1290
1217
  // 否则继续循环
@@ -1306,10 +1233,10 @@ class ComRegister {
1306
1233
  });
1307
1234
  return table ? table : '没有订阅任何UP';
1308
1235
  }
1309
- async checkIfNeedSub(liveSub, dynamicSub, session, data) {
1236
+ async checkIfNeedSub(liveSub, dynamicSub, session, liveRoomData) {
1310
1237
  // 定义方法:用户直播间是否存在
1311
1238
  const liveRoom = async () => {
1312
- if (!data.live_room) {
1239
+ if (!liveRoomData) {
1313
1240
  // 未开通直播间
1314
1241
  await session.send('该用户未开通直播间,无法订阅直播');
1315
1242
  // 返回false
@@ -1370,6 +1297,97 @@ class ComRegister {
1370
1297
  check();
1371
1298
  });
1372
1299
  }
1300
+ async subUserInBili(ctx, mid) {
1301
+ // 获取关注分组信息
1302
+ const checkGroupIsReady = async () => {
1303
+ // 判断是否有数据
1304
+ if (this.loginDBData.dynamic_group_id === '' || this.loginDBData.dynamic_group_id === null) {
1305
+ // 没有数据,没有创建分组,尝试创建分组
1306
+ const createGroupData = await ctx.ba.createGroup("订阅");
1307
+ // 如果分组已创建,则获取分组id
1308
+ if (createGroupData.code === 22106) {
1309
+ // 分组已存在,拿到之前的分组id
1310
+ const allGroupData = await ctx.ba.getAllGroup();
1311
+ // 遍历所有分组
1312
+ for (const group of allGroupData.data) {
1313
+ // 找到订阅分组
1314
+ if (group.name === '订阅') {
1315
+ // 拿到分组id
1316
+ this.loginDBData.dynamic_group_id = group.tagid;
1317
+ // 结束循环
1318
+ break;
1319
+ }
1320
+ }
1321
+ }
1322
+ else if (createGroupData.code !== 0) {
1323
+ console.log(createGroupData);
1324
+ // 创建分组失败
1325
+ return false;
1326
+ }
1327
+ // 创建成功,保存到数据库
1328
+ ctx.database.set('loginBili', 1, { dynamic_group_id: this.loginDBData.dynamic_group_id });
1329
+ // 创建成功
1330
+ return true;
1331
+ }
1332
+ return true;
1333
+ };
1334
+ // 判断分组是否准备好
1335
+ const flag = await checkGroupIsReady();
1336
+ // 判断是否创建成功
1337
+ if (!flag) {
1338
+ // 创建分组失败
1339
+ return { flag: false, msg: '创建分组失败,请尝试重启插件' };
1340
+ }
1341
+ // 获取分组明细
1342
+ const relationGroupDetailData = await ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
1343
+ // 判断分组信息是否获取成功
1344
+ if (relationGroupDetailData.code !== 0) {
1345
+ if (relationGroupDetailData.code === 22104) {
1346
+ // 将原先的分组id置空
1347
+ this.loginDBData.dynamic_group_id = null;
1348
+ // 分组不存在
1349
+ const flag = await checkGroupIsReady();
1350
+ // 判断是否创建成功
1351
+ if (!flag) {
1352
+ // 创建分组失败
1353
+ return { flag: false, msg: '创建分组失败,请尝试重启插件' };
1354
+ }
1355
+ return { flag: true, msg: '分组不存在,已重新创建分组' };
1356
+ }
1357
+ // 获取分组明细失败
1358
+ return { flag: false, msg: '获取分组明细失败' };
1359
+ }
1360
+ relationGroupDetailData.data.forEach(user => {
1361
+ if (user.mid === mid) {
1362
+ // 已关注订阅对象
1363
+ return { flag: true, msg: '订阅对象已存在于分组中' };
1364
+ }
1365
+ });
1366
+ // 订阅对象
1367
+ const subUserData = await ctx.ba.follow(mid);
1368
+ // 判断是否订阅成功
1369
+ switch (subUserData.code) {
1370
+ case -101: return { flag: false, msg: '账号未登录,请使用指令bili login登录后再进行订阅操作' };
1371
+ case -102: return { flag: false, msg: '账号被封停,无法进行订阅操作' };
1372
+ case 22002: return { flag: false, msg: '因对方隐私设置,无法进行订阅操作' };
1373
+ case 22003: return { flag: false, msg: '你已将对方拉黑,无法进行订阅操作' };
1374
+ case 22013: return { flag: false, msg: '账号已注销,无法进行订阅操作' };
1375
+ case 40061: return { flag: false, msg: '账号不存在,请检查uid输入是否正确或用户是否存在' };
1376
+ case 22001: break; // 订阅对象为自己 无需添加到分组
1377
+ case 22014: // 已关注订阅对象 无需再次关注
1378
+ case 0: { // 执行订阅成功
1379
+ // 把订阅对象添加到分组中
1380
+ const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
1381
+ // 判断是否添加成功
1382
+ if (copyUserToGroupData.code !== 0) {
1383
+ // 添加失败
1384
+ return { flag: false, msg: '添加订阅对象到分组失败,请稍后重试' };
1385
+ }
1386
+ }
1387
+ }
1388
+ // 订阅成功
1389
+ return { flag: true, msg: '用户订阅成功' };
1390
+ }
1373
1391
  async getSubFromDatabase(ctx) {
1374
1392
  // 判断登录信息是否已加载完毕
1375
1393
  await this.checkIfLoginInfoIsLoaded(ctx);
@@ -1397,8 +1415,21 @@ class ComRegister {
1397
1415
  // 跳过下面的步骤
1398
1416
  continue;
1399
1417
  }
1418
+ // 判断用户是否在B站中订阅了
1419
+ const subUserData = await this.subUserInBili(ctx, sub.uid);
1420
+ // 判断是否订阅
1421
+ if (!subUserData.flag) {
1422
+ // log
1423
+ this.logger.warn(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
1424
+ // 发送私聊消息
1425
+ await this.sendPrivateMsg(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
1426
+ // 删除该条数据
1427
+ await ctx.database.remove('bilibili', { id: sub.id });
1428
+ // 跳过下面的步骤
1429
+ continue;
1430
+ }
1400
1431
  // 获取推送目标数组
1401
- const targetIdArr = sub.targetId.split(' ');
1432
+ const target = JSON.parse(sub.target);
1402
1433
  /* 判断数据库是否被篡改 */
1403
1434
  // 获取用户信息
1404
1435
  let content;
@@ -1448,7 +1479,7 @@ class ComRegister {
1448
1479
  }
1449
1480
  }
1450
1481
  // 检测房间号是否被篡改
1451
- if (sub.live && (!data.live_room || data.live_room.roomid.toString() !== sub.room_id)) {
1482
+ if (sub.live && (!data.live_room || data.live_room.roomid != sub.room_id)) {
1452
1483
  // 房间号被篡改,删除该订阅
1453
1484
  await deleteSub();
1454
1485
  // log
@@ -1462,10 +1493,10 @@ class ComRegister {
1462
1493
  id: sub.id,
1463
1494
  uid: sub.uid,
1464
1495
  roomId: sub.room_id,
1465
- targetIdArr,
1496
+ target,
1466
1497
  platform: sub.platform,
1467
- live: +sub.live === 1 ? true : false,
1468
- dynamic: +sub.dynamic === 1 ? true : false,
1498
+ live: sub.live === 1 ? true : false,
1499
+ dynamic: sub.dynamic === 1 ? true : false,
1469
1500
  liveDispose: null
1470
1501
  };
1471
1502
  // 判断是否订阅直播
@@ -1482,7 +1513,7 @@ class ComRegister {
1482
1513
  // 直播订阅数+1
1483
1514
  liveSubNum++;
1484
1515
  // 订阅直播,开始循环检测
1485
- const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, targetIdArr), this.config.liveLoopTime * 1000);
1516
+ const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, target), this.config.liveLoopTime * 1000);
1486
1517
  // 保存销毁函数
1487
1518
  subManagerItem.liveDispose = dispose;
1488
1519
  }
@@ -1517,7 +1548,7 @@ class ComRegister {
1517
1548
  // num--
1518
1549
  this.num--;
1519
1550
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1520
- this.checkIfUserThatIsSubDynAndUnsub();
1551
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1521
1552
  };
1522
1553
  try {
1523
1554
  switch (type) {
@@ -1562,7 +1593,7 @@ class ComRegister {
1562
1593
  // 取消订阅
1563
1594
  this.subManager[index].dynamic = false;
1564
1595
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1565
- this.checkIfUserThatIsSubDynAndUnsub();
1596
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1566
1597
  // 如果没有对这个UP的任何订阅,则移除
1567
1598
  if (checkIfNoSubExist(sub)) {
1568
1599
  // 从管理对象中移除
@@ -1583,7 +1614,7 @@ class ComRegister {
1583
1614
  this.updateSubNotifier(ctx);
1584
1615
  }
1585
1616
  }
1586
- checkIfUserThatIsSubDynAndUnsub() {
1617
+ checkIfUserIsTheLastOneWhoSubDyn() {
1587
1618
  if (this.subManager.some(sub => sub.dynamic)) {
1588
1619
  // 停止动态监测
1589
1620
  this.dynamicDispose();
@@ -1596,7 +1627,7 @@ class ComRegister {
1596
1627
  if (sub.live)
1597
1628
  await this.subManager[i].liveDispose();
1598
1629
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1599
- this.checkIfUserThatIsSubDynAndUnsub();
1630
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1600
1631
  // 从数据库中删除订阅
1601
1632
  await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
1602
1633
  // 将该订阅对象从订阅管理对象中移除
@@ -1621,21 +1652,20 @@ class ComRegister {
1621
1652
  }
1622
1653
  (function (ComRegister) {
1623
1654
  ComRegister.Config = koishi_1.Schema.object({
1624
- platform: koishi_1.Schema.string(),
1625
1655
  master: koishi_1.Schema.object({
1626
1656
  enable: koishi_1.Schema.boolean(),
1657
+ platform: koishi_1.Schema.string(),
1627
1658
  masterAccount: koishi_1.Schema.string(),
1628
1659
  masterAccountGuildId: koishi_1.Schema.string()
1629
1660
  }),
1630
1661
  unlockSubLimits: koishi_1.Schema.boolean().required(),
1631
1662
  automaticResend: koishi_1.Schema.boolean().required(),
1632
1663
  changeMasterInfoApi: koishi_1.Schema.boolean().required(),
1633
- liveStartAtAll: koishi_1.Schema.boolean().required(),
1634
1664
  restartPush: koishi_1.Schema.boolean().required(),
1635
- pushUrl: koishi_1.Schema.boolean().required(),
1636
1665
  pushTime: koishi_1.Schema.number().required(),
1637
1666
  liveLoopTime: koishi_1.Schema.number().default(10),
1638
1667
  customLiveStart: koishi_1.Schema.string().required(),
1668
+ customLive: koishi_1.Schema.string(),
1639
1669
  customLiveEnd: koishi_1.Schema.string().required(),
1640
1670
  dynamicUrl: koishi_1.Schema.boolean().required(),
1641
1671
  dynamicLoopTime: koishi_1.Schema.number().default(60),