koishi-plugin-bilibili-notify 3.0.0-alpha.1 → 3.0.0-alpha.10

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.
@@ -18,27 +18,42 @@ var LiveType;
18
18
  LiveType[LiveType["StopBroadcast"] = 3] = "StopBroadcast";
19
19
  })(LiveType || (LiveType = {}));
20
20
  class ComRegister {
21
+ // 必须服务
21
22
  static inject = ['ba', 'gi', 'database', 'bl', 'sm'];
23
+ // 定义数组:QQ相关bot
22
24
  qqRelatedBotList = ['qq', 'onebot', 'red', 'satori', 'chronocat'];
25
+ // logger
23
26
  logger;
27
+ // config
24
28
  config;
29
+ // 登录定时器
25
30
  loginTimer;
31
+ // 订阅数量
26
32
  num = 0;
33
+ // 重启次数
27
34
  rebootCount = 0;
35
+ // 订阅通知
28
36
  subNotifier;
37
+ // Context
38
+ ctx;
39
+ // 订阅管理器
29
40
  subManager = [];
30
41
  // 检查登录数据库是否有数据
31
42
  loginDBData;
32
43
  // 机器人实例
33
44
  privateBot;
34
- // 动态销毁函数
45
+ // 动态检测销毁函数
35
46
  dynamicDispose;
47
+ // 直播检测销毁函数
48
+ liveDispose;
36
49
  // 发送消息方式
37
50
  sendMsgFunc;
38
51
  // 构造函数
39
52
  constructor(ctx, config) {
53
+ // 将ctx赋值给类属性
54
+ this.ctx = ctx;
40
55
  // 初始化
41
- this.init(ctx, config);
56
+ this.init(config);
42
57
  // 注册指令
43
58
  const statusCom = ctx.command('status', '插件状态相关指令', { permissions: ['authority:5'] });
44
59
  statusCom.subcommand('.dyn', '查看动态监测运行状态')
@@ -150,8 +165,10 @@ class ComRegister {
150
165
  }]);
151
166
  // 销毁定时器
152
167
  this.loginTimer();
168
+ // 订阅手动订阅中的订阅
169
+ await this.loadSubFromConfig(config.sub);
153
170
  // 订阅之前的订阅
154
- await this.loadSubFromDatabase(ctx);
171
+ await this.loadSubFromDatabase();
155
172
  // 清除控制台通知
156
173
  ctx.ba.disposeNotifier();
157
174
  // 发送成功登录推送
@@ -160,7 +177,6 @@ class ComRegister {
160
177
  await session.execute('bili show');
161
178
  // 开启cookies刷新检测
162
179
  ctx.ba.enableRefreshCookiesDetect();
163
- return;
164
180
  }
165
181
  }
166
182
  finally {
@@ -189,17 +205,14 @@ class ComRegister {
189
205
  // 取消单个订阅
190
206
  if (options.live || options.dynamic) {
191
207
  if (options.live)
192
- await session.send(this.unsubSingle(ctx, sub.roomId, 0)); /* 0为取消订阅Live */
208
+ await session.send(this.unsubSingle(sub.roomId, 0)); /* 0为取消订阅Live */
193
209
  if (options.dynamic)
194
- await session.send(this.unsubSingle(ctx, sub.uid, 1)); /* 1为取消订阅Dynamic */
210
+ await session.send(this.unsubSingle(sub.uid, 1)); /* 1为取消订阅Dynamic */
195
211
  // 将存在flag设置为true
196
212
  exist = true;
197
213
  // 结束循环
198
214
  return;
199
215
  }
200
- // 取消全部订阅 执行dispose方法,销毁定时器
201
- if (sub.live)
202
- this.subManager[i].liveDispose();
203
216
  // 从数据库中删除订阅
204
217
  await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
205
218
  // 将该订阅对象从订阅管理对象中移除
@@ -222,7 +235,7 @@ class ComRegister {
222
235
  // 发送成功通知
223
236
  await session.send('已取消订阅该用户');
224
237
  // 更新控制台提示
225
- this.updateSubNotifier(ctx);
238
+ this.updateSubNotifier();
226
239
  // 将存在flag设置为true
227
240
  exist = true;
228
241
  }
@@ -254,7 +267,7 @@ class ComRegister {
254
267
  return '直播订阅已达上限,请取消部分直播订阅后再进行订阅';
255
268
  }
256
269
  // 检查是否登录
257
- if (!(await this.checkIfIsLogin(ctx))) {
270
+ if (!(await this.checkIfIsLogin())) {
258
271
  // 未登录直接返回
259
272
  return '请使用指令bili login登录后再进行订阅操作';
260
273
  }
@@ -262,7 +275,7 @@ class ComRegister {
262
275
  if (!mid)
263
276
  return '请输入用户uid';
264
277
  // 订阅对象
265
- const subUserData = await this.subUserInBili(ctx, mid);
278
+ const subUserData = await this.subUserInBili(mid);
266
279
  // 判断是否订阅对象存在
267
280
  if (!subUserData.flag)
268
281
  return '订阅对象失败,请稍后重试!';
@@ -278,6 +291,7 @@ class ComRegister {
278
291
  channelId: group,
279
292
  dynamic: true,
280
293
  live: true,
294
+ liveDanmaku: false,
281
295
  atAll: options.atAll
282
296
  });
283
297
  });
@@ -297,7 +311,7 @@ class ComRegister {
297
311
  for (const [index, { channelIdArr, platform }] of target.entries()) {
298
312
  if (channelIdArr.length > 0) { // 输入了推送群号或频道号
299
313
  // 拿到对应的bot
300
- const bot = this.getBot(ctx, platform);
314
+ const bot = this.getBot(platform);
301
315
  // 判断是否配置了对应平台的机器人
302
316
  if (!ctx.bots.some(bot => bot.platform === platform)) {
303
317
  // 发送提示消息
@@ -337,7 +351,7 @@ class ComRegister {
337
351
  // 判断targetArr是否为空
338
352
  if (target.length === 0) {
339
353
  // 为空则默认为当前环境
340
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
354
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
341
355
  // 没有满足条件的群组或频道
342
356
  await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
343
357
  }
@@ -348,7 +362,7 @@ class ComRegister {
348
362
  }
349
363
  else {
350
364
  // 未填写群号或频道号,默认为当前环境
351
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
365
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
352
366
  // 发送提示消息
353
367
  await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
354
368
  }
@@ -356,7 +370,7 @@ class ComRegister {
356
370
  }
357
371
  else {
358
372
  // 用户直接订阅,将当前环境赋值给target
359
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
373
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
360
374
  }
361
375
  }
362
376
  // 定义外围变量
@@ -426,12 +440,23 @@ class ComRegister {
426
440
  this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
427
441
  return '订阅出错啦,请重试';
428
442
  }
429
- // 定义live销毁函数
430
- let liveDispose;
443
+ const liveDetectModeSelector = {
444
+ API: async () => {
445
+ // 判断是否已开启直播检测
446
+ if (!this.liveDispose) { // 未开启直播检测
447
+ // 开启直播检测并保存销毁函数
448
+ this.liveDispose = await this.liveDetectWithAPI();
449
+ }
450
+ },
451
+ WS: async () => {
452
+ // 连接到服务器
453
+ await this.liveDetectWithListener(roomId, target);
454
+ }
455
+ };
431
456
  // 订阅直播
432
457
  if (liveMsg) {
433
- // 连接到服务器
434
- this.liveDetectWithListener(ctx, roomId, target);
458
+ // 判断直播订阅方式
459
+ await liveDetectModeSelector[this.config.liveDetectMode]();
435
460
  // 发送订阅消息通知
436
461
  await session.send(`订阅${userData.info.uname}直播通知`);
437
462
  }
@@ -439,7 +464,8 @@ class ComRegister {
439
464
  if (dynamicMsg) {
440
465
  // 判断是否开启动态监测
441
466
  if (!this.dynamicDispose) {
442
- this.enableDynamicDetect(ctx);
467
+ // 开启动态监测
468
+ this.enableDynamicDetect();
443
469
  }
444
470
  // 发送订阅消息通知
445
471
  await session.send(`订阅${userData.info.uname}动态通知`);
@@ -465,10 +491,9 @@ class ComRegister {
465
491
  platform: session.event.platform,
466
492
  live: liveMsg,
467
493
  dynamic: dynamicMsg,
468
- liveDispose
469
494
  });
470
495
  // 新增订阅展示到控制台
471
- this.updateSubNotifier(ctx);
496
+ this.updateSubNotifier();
472
497
  });
473
498
  biliCom
474
499
  .subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
@@ -524,25 +549,19 @@ class ComRegister {
524
549
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
525
550
  });
526
551
  }
527
- async init(ctx, config) {
552
+ async init(config) {
528
553
  // 设置logger
529
- this.logger = ctx.logger('cr');
554
+ this.logger = this.ctx.logger('cr');
530
555
  // 将config设置给类属性
531
556
  this.config = config;
532
557
  // 拿到私人机器人实例
533
- this.privateBot = ctx.bots.find(bot => bot.platform === config.master.platform);
558
+ this.privateBot = this.ctx.bots.find(bot => bot.platform === config.master.platform);
534
559
  if (!this.privateBot) {
535
- ctx.notifier.create({
560
+ this.ctx.notifier.create({
536
561
  content: '您未配置私人机器人,将无法向您推送机器人状态!'
537
562
  });
538
563
  this.logger.error('您未配置私人机器人,将无法向您推送机器人状态!');
539
564
  }
540
- // 检查登录数据库是否有数据
541
- this.loginDBData = (await ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
542
- // 从配置获取订阅
543
- config.sub && await this.loadSubFromConfig(ctx, config.sub);
544
- // 从数据库获取订阅
545
- await this.loadSubFromDatabase(ctx);
546
565
  // 判断消息发送方式
547
566
  if (config.automaticResend) {
548
567
  this.sendMsgFunc = async (bot, channelId, content) => {
@@ -553,7 +572,7 @@ class ComRegister {
553
572
  // 发送消息
554
573
  await bot.sendMessage(channelId, content);
555
574
  // 防止消息发送速度过快被忽略
556
- await ctx.sleep(500);
575
+ await this.ctx.sleep(500);
557
576
  // 成功发送消息,跳出循环
558
577
  break;
559
578
  }
@@ -579,23 +598,37 @@ class ComRegister {
579
598
  }
580
599
  };
581
600
  }
601
+ // 检查登录数据库是否有数据
602
+ this.loginDBData = (await this.ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
603
+ // 判断登录信息是否已加载完毕
604
+ await this.checkIfLoginInfoIsLoaded();
605
+ // 如果未登录,则直接返回
606
+ if (!(await this.checkIfIsLogin())) {
607
+ // log
608
+ this.logger.info(`账号未登录,请登录`);
609
+ return;
610
+ }
611
+ // 从配置获取订阅
612
+ config.sub && await this.loadSubFromConfig(config.sub);
613
+ // 从数据库获取订阅
614
+ await this.loadSubFromDatabase();
582
615
  // 检查是否需要动态监测
583
- this.checkIfDynamicDetectIsNeeded(ctx);
616
+ this.checkIfDynamicDetectIsNeeded();
584
617
  // 在控制台中显示订阅对象
585
- this.updateSubNotifier(ctx);
618
+ this.updateSubNotifier();
586
619
  }
587
620
  splitMultiPlatformStr(str) {
588
621
  return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
589
622
  const channelIdArr = idStr.split(',').map(id => {
590
623
  const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
591
624
  const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
592
- return { channelId, dynamic: true, live: true, atAll };
625
+ return { channelId, dynamic: true, live: true, liveDanmaku: false, atAll };
593
626
  });
594
627
  return { channelIdArr, platform };
595
628
  });
596
629
  }
597
- getBot(ctx, pf) {
598
- return ctx.bots.find(bot => bot.platform === pf);
630
+ getBot(pf) {
631
+ return this.ctx.bots.find(bot => bot.platform === pf);
599
632
  }
600
633
  async sendPrivateMsg(content) {
601
634
  if (this.config.master.enable) {
@@ -609,7 +642,7 @@ class ComRegister {
609
642
  }
610
643
  }
611
644
  }
612
- async sendPrivateMsgAndRebootService(ctx) {
645
+ async sendPrivateMsgAndRebootService() {
613
646
  // 判断重启次数是否超过三次
614
647
  if (this.rebootCount >= 3) {
615
648
  // logger
@@ -617,7 +650,7 @@ class ComRegister {
617
650
  // 重启失败,发送消息
618
651
  await this.sendPrivateMsg('已重启插件三次,请检查机器人状态后使用指令 sys start 启动插件');
619
652
  // 关闭插件
620
- await ctx.sm.disposePlugin();
653
+ await this.ctx.sm.disposePlugin();
621
654
  // 结束
622
655
  return;
623
656
  }
@@ -626,7 +659,7 @@ class ComRegister {
626
659
  // logger
627
660
  this.logger.info('插件出现未知错误,正在重启插件');
628
661
  // 重启插件
629
- const flag = await ctx.sm.restartPlugin();
662
+ const flag = await this.ctx.sm.restartPlugin();
630
663
  // 判断是否重启成功
631
664
  if (flag) {
632
665
  this.logger.info('重启插件成功');
@@ -637,23 +670,23 @@ class ComRegister {
637
670
  // 重启失败,发送消息
638
671
  await this.sendPrivateMsg('重启插件失败,请检查机器人状态后使用指令 sys start 启动插件');
639
672
  // 关闭插件
640
- await ctx.sm.disposePlugin();
673
+ await this.ctx.sm.disposePlugin();
641
674
  }
642
675
  }
643
- async sendPrivateMsgAndStopService(ctx) {
676
+ async sendPrivateMsgAndStopService() {
644
677
  // 发送消息
645
678
  await this.sendPrivateMsg('插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件');
646
679
  // logger
647
680
  this.logger.error('插件发生未知错误,请检查机器人状态后使用指令 sys start 启动插件');
648
681
  // 关闭插件
649
- await ctx.sm.disposePlugin();
682
+ await this.ctx.sm.disposePlugin();
650
683
  // 结束
651
684
  return;
652
685
  }
653
- async sendMsg(ctx, targets, content, live) {
686
+ async sendMsg(targets, content, live) {
654
687
  for (const target of targets) {
655
688
  // 获取机器人实例
656
- const bot = this.getBot(ctx, target.platform);
689
+ const bot = this.getBot(target.platform);
657
690
  // 定义需要发送的数组
658
691
  let sendArr = [];
659
692
  // 判断是否需要推送所有机器人加入的群
@@ -664,6 +697,7 @@ class ComRegister {
664
697
  channelId: guild.id,
665
698
  dynamic: target.channelIdArr[0].dynamic,
666
699
  live: target.channelIdArr[0].live,
700
+ liveDanmaku: target.channelIdArr[0].liveDanmaku,
667
701
  atAll: target.channelIdArr[0].atAll
668
702
  });
669
703
  }
@@ -695,7 +729,7 @@ class ComRegister {
695
729
  }
696
730
  }
697
731
  }
698
- dynamicDetect(ctx) {
732
+ dynamicDetect() {
699
733
  // 检测初始化变量
700
734
  let detectSetup = true;
701
735
  // 更新基线
@@ -715,7 +749,7 @@ class ComRegister {
715
749
  // 检测启动初始化
716
750
  if (detectSetup) {
717
751
  // 获取动态信息
718
- const data = await ctx.ba.getAllDynamic();
752
+ const data = await this.ctx.ba.getAllDynamic();
719
753
  // 判断获取动态信息是否成功
720
754
  if (data.code !== 0)
721
755
  return;
@@ -731,13 +765,13 @@ class ComRegister {
731
765
  let content;
732
766
  try {
733
767
  // 查询是否有新动态
734
- const data = await ctx.ba.hasNewDynamic(updateBaseline);
768
+ const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
735
769
  updateNum = data.data.update_num;
736
770
  // 没有新动态或获取动态信息失败直接返回
737
771
  if (updateNum <= 0 || data.code !== 0)
738
772
  return;
739
773
  // 获取动态内容
740
- content = await ctx.ba.getAllDynamic(updateBaseline);
774
+ content = await this.ctx.ba.getAllDynamic(updateBaseline);
741
775
  }
742
776
  catch (e) {
743
777
  return this.logger.error('dynamicDetect getUserSpaceDynamic() 发生了错误,错误为:' + e.message);
@@ -751,7 +785,7 @@ class ComRegister {
751
785
  // 发送私聊消息
752
786
  await this.sendPrivateMsg('账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
753
787
  // 停止服务
754
- await ctx.sm.disposePlugin();
788
+ await this.ctx.sm.disposePlugin();
755
789
  // 结束循环
756
790
  break;
757
791
  }
@@ -761,7 +795,7 @@ class ComRegister {
761
795
  // 发送私聊消息
762
796
  await this.sendPrivateMsg('账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
763
797
  // 停止服务
764
- await ctx.sm.disposePlugin();
798
+ await this.ctx.sm.disposePlugin();
765
799
  // 结束循环
766
800
  break;
767
801
  }
@@ -821,7 +855,7 @@ class ComRegister {
821
855
  // 获取动态推送图片
822
856
  try {
823
857
  // 渲染图片
824
- const { pic: gimgPic, buffer: gimgBuffer } = await ctx.gi.generateDynamicImg(items[num]);
858
+ const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
825
859
  // 赋值
826
860
  pic = gimgPic;
827
861
  buffer = gimgBuffer;
@@ -835,13 +869,13 @@ class ComRegister {
835
869
  if (e.message === '出现关键词,屏蔽该动态') {
836
870
  // 如果需要发送才发送
837
871
  if (this.config.filter.notify) {
838
- await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
872
+ await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
839
873
  }
840
874
  return;
841
875
  }
842
876
  if (e.message === '已屏蔽转发动态') {
843
877
  if (this.config.filter.notify) {
844
- await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
878
+ await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
845
879
  }
846
880
  return;
847
881
  }
@@ -849,7 +883,7 @@ class ComRegister {
849
883
  if (i === attempts - 1) {
850
884
  this.logger.error('dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:' + e.message);
851
885
  // 发送私聊消息并重启服务
852
- return await this.sendPrivateMsgAndStopService(ctx);
886
+ return await this.sendPrivateMsgAndStopService();
853
887
  }
854
888
  }
855
889
  }
@@ -859,12 +893,12 @@ class ComRegister {
859
893
  if (pic) {
860
894
  this.logger.info('推送动态中,使用render模式');
861
895
  // pic存在,使用的是render模式
862
- await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
896
+ await this.sendMsg(sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
863
897
  }
864
898
  else if (buffer) {
865
899
  this.logger.info('推送动态中,使用page模式');
866
900
  // pic不存在,说明使用的是page模式
867
- await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
901
+ await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
868
902
  }
869
903
  else {
870
904
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -878,7 +912,7 @@ class ComRegister {
878
912
  }
879
913
  };
880
914
  }
881
- debug_dynamicDetect(ctx) {
915
+ debug_dynamicDetect() {
882
916
  // 检测初始化变量
883
917
  let detectSetup = true;
884
918
  // 更新基线
@@ -899,7 +933,7 @@ class ComRegister {
899
933
  // 检测启动初始化
900
934
  if (detectSetup) {
901
935
  // 获取动态信息
902
- const data = await ctx.ba.getAllDynamic();
936
+ const data = await this.ctx.ba.getAllDynamic();
903
937
  // 判断获取动态信息是否成功
904
938
  if (data.code !== 0)
905
939
  return;
@@ -916,7 +950,7 @@ class ComRegister {
916
950
  let content;
917
951
  try {
918
952
  // 查询是否有新动态
919
- const data = await ctx.ba.hasNewDynamic(updateBaseline);
953
+ const data = await this.ctx.ba.hasNewDynamic(updateBaseline);
920
954
  updateNum = data.data.update_num;
921
955
  console.log(`获取是否有新动态:`);
922
956
  console.log(data);
@@ -924,7 +958,7 @@ class ComRegister {
924
958
  if (updateNum <= 0 || data.code !== 0)
925
959
  return;
926
960
  // 获取动态内容
927
- content = await ctx.ba.getAllDynamic(updateBaseline);
961
+ content = await this.ctx.ba.getAllDynamic(updateBaseline);
928
962
  console.log('获取动态内容:');
929
963
  console.log(content.data.items[0]);
930
964
  }
@@ -940,7 +974,7 @@ class ComRegister {
940
974
  // 发送私聊消息
941
975
  await this.sendPrivateMsg('账号未登录,插件已停止工作,请登录后,输入指令 sys start 启动插件');
942
976
  // 停止服务
943
- await ctx.sm.disposePlugin();
977
+ await this.ctx.sm.disposePlugin();
944
978
  // 结束循环
945
979
  break;
946
980
  }
@@ -950,7 +984,7 @@ class ComRegister {
950
984
  // 发送私聊消息
951
985
  await this.sendPrivateMsg('账号被风控,插件已停止工作,请确认风控解除后,输入指令 sys start 启动插件');
952
986
  // 停止服务
953
- await ctx.sm.disposePlugin();
987
+ await this.ctx.sm.disposePlugin();
954
988
  // 结束循环
955
989
  break;
956
990
  }
@@ -1018,7 +1052,7 @@ class ComRegister {
1018
1052
  // 获取动态推送图片
1019
1053
  try {
1020
1054
  // 渲染图片
1021
- const { pic: gimgPic, buffer: gimgBuffer } = await ctx.gi.generateDynamicImg(items[num]);
1055
+ const { pic: gimgPic, buffer: gimgBuffer } = await this.ctx.gi.generateDynamicImg(items[num]);
1022
1056
  // 赋值
1023
1057
  pic = gimgPic;
1024
1058
  buffer = gimgBuffer;
@@ -1032,13 +1066,13 @@ class ComRegister {
1032
1066
  if (e.message === '出现关键词,屏蔽该动态') {
1033
1067
  // 如果需要发送才发送
1034
1068
  if (this.config.filter.notify) {
1035
- await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
1069
+ await this.sendMsg(sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
1036
1070
  }
1037
1071
  return;
1038
1072
  }
1039
1073
  if (e.message === '已屏蔽转发动态') {
1040
1074
  if (this.config.filter.notify) {
1041
- await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
1075
+ await this.sendMsg(sub.target, `${upName}发布了一条转发动态,已屏蔽`);
1042
1076
  }
1043
1077
  return;
1044
1078
  }
@@ -1046,7 +1080,7 @@ class ComRegister {
1046
1080
  if (i === attempts - 1) {
1047
1081
  this.logger.error('dynamicDetect generateDynamicImg() 推送卡片发送失败,原因:' + e.message);
1048
1082
  // 发送私聊消息并重启服务
1049
- return await this.sendPrivateMsgAndStopService(ctx);
1083
+ return await this.sendPrivateMsgAndStopService();
1050
1084
  }
1051
1085
  }
1052
1086
  }
@@ -1056,12 +1090,12 @@ class ComRegister {
1056
1090
  if (pic) {
1057
1091
  this.logger.info('推送动态中,使用render模式');
1058
1092
  // pic存在,使用的是render模式
1059
- await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1093
+ await this.sendMsg(sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1060
1094
  }
1061
1095
  else if (buffer) {
1062
1096
  this.logger.info('推送动态中,使用page模式');
1063
1097
  // pic不存在,说明使用的是page模式
1064
- await this.sendMsg(ctx, sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1098
+ await this.sendMsg(sub.target, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), dUrl] }));
1065
1099
  }
1066
1100
  else {
1067
1101
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -1076,7 +1110,7 @@ class ComRegister {
1076
1110
  };
1077
1111
  }
1078
1112
  // 定义发送直播通知卡片方法
1079
- async sendLiveNotifyCard(ctx, info, liveType, liveNotifyMsg) {
1113
+ async sendLiveNotifyCard(info, liveType, liveNotifyMsg) {
1080
1114
  // 定义变量
1081
1115
  let pic;
1082
1116
  let buffer;
@@ -1085,7 +1119,7 @@ class ComRegister {
1085
1119
  for (let i = 0; i < attempts; i++) {
1086
1120
  try {
1087
1121
  // 获取直播通知卡片
1088
- const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(info.data, info.username, info.userface, liveType);
1122
+ const { pic: picv, buffer: bufferv } = await this.ctx.gi.generateLiveImg(info.data, info.username, info.userface, liveType);
1089
1123
  // 赋值
1090
1124
  pic = picv;
1091
1125
  buffer = bufferv;
@@ -1096,7 +1130,7 @@ class ComRegister {
1096
1130
  if (i === attempts - 1) { // 已尝试三次
1097
1131
  this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1098
1132
  // 发送私聊消息并重启服务
1099
- return await this.sendPrivateMsgAndStopService(ctx);
1133
+ return await this.sendPrivateMsgAndStopService();
1100
1134
  }
1101
1135
  }
1102
1136
  }
@@ -1105,33 +1139,33 @@ class ComRegister {
1105
1139
  if (pic) {
1106
1140
  // 只有在开播时才艾特全体成员
1107
1141
  if (liveType === LiveType.StartBroadcasting) {
1108
- return await this.sendMsg(ctx, info.target, pic + (liveNotifyMsg ?? ''), true);
1142
+ return await this.sendMsg(info.target, pic + (liveNotifyMsg ?? ''), true);
1109
1143
  }
1110
1144
  // 正常不需要艾特全体成员
1111
- return await this.sendMsg(ctx, info.target, pic + (liveNotifyMsg ?? ''));
1145
+ return await this.sendMsg(info.target, pic + (liveNotifyMsg ?? ''));
1112
1146
  }
1113
1147
  // pic不存在,说明使用的是page模式
1114
1148
  const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg || ''] });
1115
1149
  // 只有在开播时才艾特全体成员
1116
1150
  if (liveType === LiveType.StartBroadcasting) {
1117
- return await this.sendMsg(ctx, info.target, msg, true);
1151
+ return await this.sendMsg(info.target, msg, true);
1118
1152
  }
1119
1153
  // 正常不需要艾特全体成员
1120
- return await this.sendMsg(ctx, info.target, msg);
1154
+ return await this.sendMsg(info.target, msg);
1121
1155
  }
1122
1156
  // 定义获取主播信息方法
1123
- async useMasterInfo(ctx, uid) {
1124
- const { data: { info } } = await ctx.ba.getMasterInfo(uid);
1125
- return { username: info.name, userface: info.face };
1157
+ async useMasterInfo(uid) {
1158
+ const { data } = await this.ctx.ba.getMasterInfo(uid);
1159
+ return { username: data.info.uname, userface: data.info.face, roomId: data.room_id };
1126
1160
  }
1127
- async useLiveRoomInfo(ctx, roomId) {
1161
+ async useLiveRoomInfo(roomId) {
1128
1162
  // 发送请求获取直播间信息
1129
1163
  let content;
1130
1164
  const attempts = 3;
1131
1165
  for (let i = 0; i < attempts; i++) {
1132
1166
  try {
1133
1167
  // 发送请求获取room信息
1134
- content = await ctx.ba.getLiveRoomInfo(roomId);
1168
+ content = await this.ctx.ba.getLiveRoomInfo(roomId);
1135
1169
  // 成功则跳出循环
1136
1170
  break;
1137
1171
  }
@@ -1139,180 +1173,21 @@ class ComRegister {
1139
1173
  this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
1140
1174
  if (i === attempts - 1) { // 已尝试三次
1141
1175
  // 发送私聊消息并重启服务
1142
- return await this.sendPrivateMsgAndStopService(ctx);
1176
+ return await this.sendPrivateMsgAndStopService();
1143
1177
  }
1144
1178
  }
1145
1179
  }
1146
1180
  return content.data;
1147
1181
  }
1148
- /* liveDetect(
1149
- ctx: Context,
1150
- roomId: string,
1151
- target: Target
1152
- ) {
1153
- let firstSubscription: boolean = true;
1154
- let timer: number = 0;
1155
- let open: boolean = false;
1156
- let liveTime: string;
1157
- let username: string
1158
- let userface: string
1159
- // 相当于锁的作用,防止上一个循环没处理完
1160
- let flag: boolean = true
1161
-
1162
- return async () => {
1163
- // 如果flag为false则说明前面的代码还未执行完,则直接返回
1164
- if (!flag) return
1165
- flag = false
1166
- // 无论是否执行成功都要释放锁
1167
- try {
1168
- // 发送请求检测直播状态
1169
- let content: any
1170
- const attempts = 3
1171
- for (let i = 0; i < attempts; i++) {
1172
- try {
1173
- // 发送请求获取room信息
1174
- content = await ctx.ba.getLiveRoomInfo(roomId)
1175
- // 成功则跳出循环
1176
- break
1177
- } catch (e) {
1178
- this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message)
1179
- if (i === attempts - 1) { // 已尝试三次
1180
- // 发送私聊消息并重启服务
1181
- return await this.sendPrivateMsgAndStopService(ctx)
1182
- }
1183
- }
1184
- }
1185
- const { data } = content
1186
- // 判断是否是第一次订阅
1187
- if (firstSubscription) {
1188
- firstSubscription = false
1189
- // 获取主播信息
1190
- const attempts = 3
1191
- for (let i = 0; i < attempts; i++) {
1192
- try {
1193
- // 发送请求获取主播信息
1194
- await useMasterInfo(data.uid)
1195
- // 成功则跳出循环
1196
- break
1197
- } catch (e) {
1198
- this.logger.error('liveDetect getMasterInfo() 发生了错误,错误为:' + e.message)
1199
- if (i === attempts - 1) { // 已尝试三次
1200
- // 发送私聊消息并重启服务
1201
- return await this.sendPrivateMsgAndStopService(ctx)
1202
- }
1203
- }
1204
- }
1205
- // 判断直播状态
1206
- if (data.live_status === 1) { // 当前正在直播
1207
- // 设置开播时间
1208
- liveTime = data.live_time
1209
- // 设置直播中消息
1210
- const liveMsg = this.config.customLive ? this.config.customLive
1211
- .replace('-name', username)
1212
- .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1213
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
1214
- // 发送直播通知卡片
1215
- if (this.config.restartPush) sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg)
1216
- // 改变开播状态
1217
- open = true
1218
- } // 未开播,直接返回
1219
- return
1220
- }
1221
- // 检查直播状态
1222
- switch (data.live_status) {
1223
- case 0:
1224
- case 2: { // 状态 0 和 2 说明未开播
1225
- if (open) { // 之前开播,现在下播了
1226
- // 更改直播状态
1227
- open = false
1228
- // 下播了将定时器清零
1229
- timer = 0
1230
- // 定义下播通知消息
1231
- const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1232
- .replace('-name', username)
1233
- .replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null
1234
- // 更改直播时长
1235
- data.live_time = liveTime
1236
- // 推送下播通知
1237
- await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg)
1238
- }
1239
- // 未进循环,还未开播,继续循环
1240
- break
1241
- }
1242
- case 1: {
1243
- if (!open) { // 之前未开播,现在开播了
1244
- // 更改直播状态
1245
- open = true
1246
- // 设置开播时间
1247
- liveTime = data.live_time
1248
- // 获取主播信息
1249
- const attempts = 3
1250
- for (let i = 0; i < attempts; i++) {
1251
- try {
1252
- // 主播信息不会变,开播时刷新一次即可
1253
- // 发送请求获取主播信息
1254
- await useMasterInfo(data.uid)
1255
- // 成功则跳出循环
1256
- break
1257
- } catch (e) {
1258
- this.logger.error('liveDetect open getMasterInfo() 发生了错误,错误为:' + e.message)
1259
- if (i === attempts - 1) { // 已尝试三次
1260
- // 发送私聊消息并重启服务
1261
- return await this.sendPrivateMsgAndStopService(ctx)
1262
- }
1263
- }
1264
- }
1265
- // 定义开播通知语
1266
- const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1267
- .replace('-name', username)
1268
- .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1269
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
1270
- // 发送消息
1271
- await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg)
1272
- } else { // 还在直播
1273
- if (this.config.pushTime > 0) {
1274
- timer++
1275
- // 开始记录时间
1276
- if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
1277
- // 到时间重新计时
1278
- timer = 0
1279
- // 定义直播中通知消息
1280
- const liveMsg = this.config.customLive ? this.config.customLive
1281
- .replace('-name', username)
1282
- .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1283
- .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null
1284
- // 发送直播通知卡片
1285
- sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg)
1286
- }
1287
- }
1288
- // 否则继续循环
1289
- }
1290
- }
1291
- }
1292
- }
1293
- finally {
1294
- // 执行完方法体不论如何都把flag设置为true
1295
- flag = true
1296
- }
1297
- }
1298
- } */
1299
- async liveDetectWithAPI(ctx) {
1182
+ async liveDetectWithAPI() {
1300
1183
  // 定义变量:第一次订阅
1301
- let firstSubscription = true;
1184
+ let liveDetectSetup = true;
1302
1185
  // 定义变量:timer计时器
1303
1186
  let timer = 0;
1304
1187
  // 相当于锁的作用,防止上一个循环没处理完
1305
1188
  let flag = true;
1306
1189
  // 定义订阅对象Record 0未开播 1正在直播 2轮播中
1307
1190
  const liveRecord = {};
1308
- // 初始化subRecord
1309
- this.subManager.forEach(sub => {
1310
- // 判断是否订阅直播
1311
- if (sub.live) {
1312
- // 将该订阅添加到subRecord中
1313
- liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
1314
- }
1315
- });
1316
1191
  // 定义函数: 发送请求获取直播状态
1317
1192
  const useLiveStatus = async (roomId) => {
1318
1193
  let content;
@@ -1320,7 +1195,7 @@ class ComRegister {
1320
1195
  for (let i = 0; i < attempts; i++) {
1321
1196
  try {
1322
1197
  // 发送请求获取room信息
1323
- content = await ctx.ba.getLiveRoomInfo(roomId);
1198
+ content = await this.ctx.ba.getLiveRoomInfo(roomId);
1324
1199
  // 成功则跳出循环
1325
1200
  break;
1326
1201
  }
@@ -1328,7 +1203,7 @@ class ComRegister {
1328
1203
  this.logger.error('liveDetect getLiveRoomInfo 发生了错误,错误为:' + e.message);
1329
1204
  if (i === attempts - 1) { // 已尝试三次
1330
1205
  // 发送私聊消息并重启服务
1331
- return await this.sendPrivateMsgAndStopService(ctx);
1206
+ return await this.sendPrivateMsgAndStopService();
1332
1207
  }
1333
1208
  }
1334
1209
  }
@@ -1343,11 +1218,19 @@ class ComRegister {
1343
1218
  flag = false;
1344
1219
  try {
1345
1220
  // 获取正在直播对象
1346
- const liveUsers = await ctx.ba.getTheUserWhoIsLiveStreaming();
1347
- // 判断是否是第一次订阅
1348
- if (firstSubscription) {
1221
+ const liveUsers = await this.ctx.ba.getTheUserWhoIsLiveStreaming();
1222
+ // 判断是否是初始化直播监测
1223
+ if (liveDetectSetup) {
1349
1224
  // 将第一次订阅置为false
1350
- firstSubscription = false;
1225
+ liveDetectSetup = false;
1226
+ // 初始化subRecord
1227
+ this.subManager.forEach(sub => {
1228
+ // 判断是否订阅直播
1229
+ if (sub.live) {
1230
+ // 将该订阅添加到subRecord中
1231
+ liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
1232
+ }
1233
+ });
1351
1234
  // 先判断是否有UP主正在直播
1352
1235
  if (liveUsers.count > 0) {
1353
1236
  // 遍历liveUsers
@@ -1358,21 +1241,21 @@ class ComRegister {
1358
1241
  const data = await useLiveStatus(item.room_id.toString());
1359
1242
  // 设置开播时间
1360
1243
  liveRecord[item.mid].liveTime = data.live_time;
1244
+ // 改变开播状态
1245
+ liveRecord[item.mid].liveStatus = 1;
1361
1246
  // 设置直播中消息
1362
1247
  const liveMsg = this.config.customLive ? this.config.customLive
1363
1248
  .replace('-name', item.uname)
1364
- .replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1249
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1365
1250
  .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1366
1251
  // 发送直播通知卡片
1367
1252
  if (this.config.restartPush)
1368
- this.sendLiveNotifyCard(ctx, {
1253
+ this.sendLiveNotifyCard({
1369
1254
  username: item.uname,
1370
1255
  userface: item.face,
1371
1256
  target: liveRecord[item.mid].target,
1372
1257
  data
1373
1258
  }, LiveType.LiveBroadcast, liveMsg);
1374
- // 改变开播状态
1375
- liveRecord[item.mid].liveStatus = 1;
1376
1259
  }
1377
1260
  });
1378
1261
  }
@@ -1418,6 +1301,7 @@ class ComRegister {
1418
1301
  delete liveRecord[subUID];
1419
1302
  }
1420
1303
  }
1304
+ // 数量没有差异,则不进行其他操作
1421
1305
  // 遍历liveUsers
1422
1306
  liveUsers.items.forEach(async (item) => {
1423
1307
  // 判断是否有正在直播的订阅对象
@@ -1432,16 +1316,15 @@ class ComRegister {
1432
1316
  // 定义开播通知语
1433
1317
  const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1434
1318
  .replace('-name', item.uname)
1435
- .replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1319
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1436
1320
  .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1437
1321
  // 发送直播通知卡片
1438
- if (this.config.restartPush)
1439
- this.sendLiveNotifyCard(ctx, {
1440
- username: item.uname,
1441
- userface: item.face,
1442
- target: liveRecord[item.mid].target,
1443
- data
1444
- }, LiveType.LiveBroadcast, liveStartMsg);
1322
+ await this.sendLiveNotifyCard({
1323
+ username: item.uname,
1324
+ userface: item.face,
1325
+ target: liveRecord[item.mid].target,
1326
+ data
1327
+ }, LiveType.LiveBroadcast, liveStartMsg);
1445
1328
  // 改变开播状态
1446
1329
  liveRecord[item.mid].liveStatus = 1;
1447
1330
  // 结束
@@ -1457,10 +1340,10 @@ class ComRegister {
1457
1340
  // 定义直播中通知消息
1458
1341
  const liveMsg = this.config.customLive ? this.config.customLive
1459
1342
  .replace('-name', item.uname)
1460
- .replace('-time', await ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1343
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[item.mid].liveTime))
1461
1344
  .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : null;
1462
1345
  // 发送直播通知卡片
1463
- this.sendLiveNotifyCard(ctx, {
1346
+ this.sendLiveNotifyCard({
1464
1347
  username: item.uname,
1465
1348
  userface: item.face,
1466
1349
  target: liveRecord[item.mid].target,
@@ -1472,6 +1355,29 @@ class ComRegister {
1472
1355
  }
1473
1356
  }
1474
1357
  });
1358
+ // 找出liveRecord中liveStatus为1但liveUsers中没有的元素
1359
+ const extraInLiveRecord = currentLiveRecordKeys.filter(key => !liveUsers.items.some(item => item.mid === Number(key)));
1360
+ // 遍历 extraInLiveRecord
1361
+ for (const subUID of extraInLiveRecord) { // 下播的主播
1362
+ // 获取主播信息
1363
+ const masterInfo = await this.useMasterInfo(subUID);
1364
+ // 获取直播间消息
1365
+ const liveRoomInfo = await this.useLiveRoomInfo(masterInfo.roomId.toString());
1366
+ // 设置开播时间
1367
+ liveRoomInfo.live_time = liveRecord[subUID].liveTime;
1368
+ // 定义下播播通知语
1369
+ const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1370
+ .replace('-name', masterInfo.username)
1371
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveRecord[subUID].liveTime))
1372
+ .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1373
+ // 发送下播通知
1374
+ this.sendLiveNotifyCard({
1375
+ username: masterInfo.username,
1376
+ userface: masterInfo.userface,
1377
+ target: liveRecord[subUID].target,
1378
+ data: liveRoomInfo
1379
+ }, LiveType.StopBroadcast, liveEndMsg);
1380
+ }
1475
1381
  }
1476
1382
  finally {
1477
1383
  // 执行完方法体不论如何都把flag设置为true
@@ -1479,7 +1385,7 @@ class ComRegister {
1479
1385
  }
1480
1386
  };
1481
1387
  }
1482
- liveDetectWithListener(ctx, roomId, target) {
1388
+ async liveDetectWithListener(roomId, target) {
1483
1389
  // 定义开播时间
1484
1390
  let liveTime;
1485
1391
  // 定义定时推送定时器
@@ -1487,35 +1393,96 @@ class ComRegister {
1487
1393
  // 定义弹幕存放数组
1488
1394
  const currentLiveDanmakuArr = [];
1489
1395
  const temporaryLiveDanmakuArr = [];
1396
+ // 定义开播状态
1397
+ let liveStatus = false;
1398
+ // 处理target
1399
+ // 定义channelIdArr总长度
1400
+ let channelIdArrLen = 0;
1401
+ // 定义数据
1402
+ let liveRoomInfo;
1403
+ let masterInfo;
1404
+ // 找到频道/群组对应的
1405
+ const danmakuPushTargetArr = target.map(channel => {
1406
+ // 获取符合条件的target
1407
+ const liveDanmakuArr = channel.channelIdArr.filter(channelId => channelId.liveDanmaku);
1408
+ // 将当前liveDanmakuArr的长度+到channelIdArrLen中
1409
+ channelIdArrLen += liveDanmakuArr.length;
1410
+ // 返回符合的target
1411
+ return {
1412
+ channelIdArr: liveDanmakuArr,
1413
+ platform: channel.platform
1414
+ };
1415
+ });
1490
1416
  // 定义定时推送函数
1491
- const pushAtTime = async () => {
1492
- // 获取直播间信息
1493
- const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
1494
- // 获取主播信息
1495
- const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
1496
- // 定义直播中通知消息
1417
+ const pushAtTimeFunc = async () => {
1418
+ // 判断是否信息是否获取成功
1419
+ if (!(await useMasterAndLiveRoomInfo())) {
1420
+ // 未获取成功,直接返回
1421
+ return this.sendPrivateMsg('获取直播间信息失败,推送直播卡片失败!');
1422
+ }
1423
+ // 设置开播时间
1424
+ liveTime = liveRoomInfo.live_time;
1425
+ // 设置直播中消息
1497
1426
  const liveMsg = this.config.customLive ? this.config.customLive
1498
1427
  .replace('-name', masterInfo.username)
1499
- .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1428
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
1500
1429
  .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1501
1430
  // 发送直播通知卡片
1502
- await this.sendLiveNotifyCard(liveRoomInfo, {
1431
+ await this.sendLiveNotifyCard({
1503
1432
  username: masterInfo.username,
1504
1433
  userface: masterInfo.userface,
1505
1434
  target,
1506
1435
  data: liveRoomInfo
1507
1436
  }, LiveType.LiveBroadcast, liveMsg);
1508
1437
  };
1509
- // 定义10秒推送函数
1510
- const pushOnceEveryTenS = () => {
1438
+ // 定义弹幕推送函数
1439
+ const danmakuPushFunc = () => {
1511
1440
  // 判断数组是否有内容
1512
- if (temporaryLiveDanmakuArr.length > 0) {
1441
+ if (channelIdArrLen > 0 && temporaryLiveDanmakuArr.length > 0) {
1513
1442
  // 发送消息
1514
- this.sendMsg(ctx, target, temporaryLiveDanmakuArr.join('\n'));
1443
+ this.sendMsg(danmakuPushTargetArr, temporaryLiveDanmakuArr.join('\n'));
1515
1444
  // 将临时消息数组清空
1516
1445
  temporaryLiveDanmakuArr.length = 0;
1517
1446
  }
1518
1447
  };
1448
+ // 定义直播间信息获取函数
1449
+ const useMasterAndLiveRoomInfo = async () => {
1450
+ // 定义flag
1451
+ let flag = true;
1452
+ // 判断是否已存在值
1453
+ if (liveRoomInfo && masterInfo && liveTime) {
1454
+ // 所有值均已存在,不需要再获取信息
1455
+ return flag;
1456
+ }
1457
+ // 获取直播间信息
1458
+ liveRoomInfo = await this.useLiveRoomInfo(roomId).catch(() => {
1459
+ // 设置flag为false
1460
+ flag = false;
1461
+ // 返回空
1462
+ return null;
1463
+ });
1464
+ // 判断是否成功获取信息
1465
+ if (!flag || !liveRoomInfo || !liveRoomInfo.uid) {
1466
+ // 上一步未成功
1467
+ flag = false;
1468
+ // 返回flag
1469
+ return flag;
1470
+ }
1471
+ // 获取主播信息(需要满足flag为true,liveRoomInfo.uid有值)
1472
+ masterInfo = await this.useMasterInfo(liveRoomInfo.uid).catch(() => {
1473
+ // 设置flag为false
1474
+ flag = false;
1475
+ // 返回空
1476
+ return null;
1477
+ });
1478
+ // 返回信息
1479
+ return flag;
1480
+ };
1481
+ // 判断是否信息是否获取成功
1482
+ if (!(await useMasterAndLiveRoomInfo())) {
1483
+ // 未获取成功,直接返回
1484
+ return this.sendPrivateMsg('获取直播间信息失败,启动直播间弹幕检测失败!');
1485
+ }
1519
1486
  // 构建消息处理函数
1520
1487
  const handler = {
1521
1488
  onOpen: () => {
@@ -1526,62 +1493,113 @@ class ComRegister {
1526
1493
  },
1527
1494
  onIncomeDanmu: ({ body }) => {
1528
1495
  // 处理消息,只需要UP主名字和消息内容
1529
- const content = `${body.user.uname}:${body.content}`;
1496
+ const content = `【${masterInfo.username}的直播间】${body.user.uname}:${body.content}`;
1530
1497
  // 保存消息到数组
1531
- currentLiveDanmakuArr.push(content);
1498
+ currentLiveDanmakuArr.push(body.content);
1499
+ temporaryLiveDanmakuArr.push(content);
1500
+ },
1501
+ onIncomeSuperChat: ({ body }) => {
1502
+ // 处理SC消息
1503
+ const content = `【${masterInfo.username}的直播间】${body.user.uname}发送了一条SC:${body.content}`;
1504
+ // 保存消息到数组
1505
+ currentLiveDanmakuArr.push(body.content);
1532
1506
  temporaryLiveDanmakuArr.push(content);
1533
1507
  },
1534
- onIncomeSuperChat: (msg) => {
1535
- console.log(msg.id, msg.body);
1508
+ onGuardBuy: ({ body }) => {
1509
+ const content = `【${masterInfo.username}的直播间】${body.user.uname}加入了大航海(${body.gift_name})`;
1510
+ // 保存消息到数组
1511
+ currentLiveDanmakuArr.push(content);
1512
+ temporaryLiveDanmakuArr.push(content);
1536
1513
  },
1537
1514
  onLiveStart: async () => {
1538
- // 获取直播间信息
1539
- const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
1540
- // 获取主播信息
1541
- const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
1542
- // 定义下播通知消息
1543
- const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1515
+ // 判断是否已经开播
1516
+ if (liveStatus)
1517
+ return;
1518
+ // 设置开播状态为true
1519
+ liveStatus = true;
1520
+ // 判断是否信息是否获取成功
1521
+ if (!(await useMasterAndLiveRoomInfo())) {
1522
+ // 设置开播状态为false
1523
+ liveStatus = false;
1524
+ // 未获取成功,直接返回
1525
+ return await this.sendPrivateMsg('获取直播间信息失败,推送直播开播卡片失败!');
1526
+ }
1527
+ // 设置开播时间
1528
+ liveTime = liveRoomInfo.live_time;
1529
+ // 定义开播通知语
1530
+ const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1544
1531
  .replace('-name', masterInfo.username)
1545
- .replace('-time', await ctx.gi.getTimeDifference(liveTime)) : null;
1546
- // 更改直播时长
1547
- liveRoomInfo.live_time = liveTime;
1548
- // 推送下播通知
1549
- await this.sendLiveNotifyCard(liveRoomInfo, {
1532
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
1533
+ .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1534
+ // 推送开播通知
1535
+ await this.sendLiveNotifyCard({
1550
1536
  username: masterInfo.username,
1551
1537
  userface: masterInfo.userface,
1552
1538
  target,
1553
1539
  data: liveRoomInfo
1554
- }, LiveType.StopBroadcast, liveEndMsg);
1555
- // 关闭定时器
1556
- pushAtTimeTimer();
1557
- // 定时器变量置空
1558
- pushAtTimeTimer = null;
1540
+ }, LiveType.StartBroadcasting, liveStartMsg);
1541
+ // 判断定时器是否已开启
1542
+ if (!pushAtTimeTimer) {
1543
+ // 开始直播,开启定时器
1544
+ pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
1545
+ }
1559
1546
  },
1560
1547
  onLiveEnd: async () => {
1561
- // 获取直播间消息
1562
- const liveRoomInfo = await this.useLiveRoomInfo(ctx, roomId);
1563
- // 获取主播信息
1564
- const masterInfo = await this.useMasterInfo(ctx, liveRoomInfo.uid);
1565
- // 设置开播时间
1566
- liveTime = liveRoomInfo.live_time;
1567
- // 开启推送定时器
1568
- pushAtTimeTimer = ctx.setInterval(pushAtTime, 3600 * 1000);
1569
- // 定义开播通知语
1570
- const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
1548
+ // 判断是否信息是否获取成功
1549
+ if (!(await useMasterAndLiveRoomInfo())) {
1550
+ // 未获取成功,直接返回
1551
+ return this.sendPrivateMsg('获取直播间信息失败,推送直播下播卡片失败!');
1552
+ }
1553
+ // 更改直播时长
1554
+ liveRoomInfo.live_time = liveTime;
1555
+ // 定义下播播通知语
1556
+ const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
1571
1557
  .replace('-name', masterInfo.username)
1572
- .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1573
- .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1558
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveTime)) : null;
1574
1559
  // 推送通知卡片
1575
- await this.sendLiveNotifyCard(ctx, {
1560
+ await this.sendLiveNotifyCard({
1576
1561
  username: masterInfo.username,
1577
1562
  userface: masterInfo.userface,
1578
1563
  target,
1579
1564
  data: liveRoomInfo
1580
- }, LiveType.StartBroadcasting, liveStartMsg);
1565
+ }, LiveType.StopBroadcast, liveEndMsg);
1566
+ // 关闭定时推送定时器
1567
+ pushAtTimeTimer();
1568
+ // 将推送定时器变量置空
1569
+ pushAtTimeTimer = null;
1570
+ // 将直播状态设置为false
1571
+ liveStatus = false;
1581
1572
  }
1582
1573
  };
1583
1574
  // 启动直播间弹幕监测
1584
- ctx.bl.startLiveRoomListener(roomId, handler, pushOnceEveryTenS);
1575
+ await this.ctx.bl.startLiveRoomListener(roomId, handler, danmakuPushFunc);
1576
+ // 判断直播状态
1577
+ if (liveRoomInfo.live_status === 1) {
1578
+ // 设置开播时间
1579
+ liveTime = liveRoomInfo.live_time;
1580
+ // 定义直播中通知消息
1581
+ const liveMsg = this.config.customLive ? this.config.customLive
1582
+ .replace('-name', masterInfo.username)
1583
+ .replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
1584
+ .replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
1585
+ // 发送直播通知卡片
1586
+ if (this.config.restartPush) {
1587
+ await this.sendLiveNotifyCard({
1588
+ username: masterInfo.username,
1589
+ userface: masterInfo.userface,
1590
+ target,
1591
+ data: liveRoomInfo
1592
+ }, LiveType.LiveBroadcast, liveMsg);
1593
+ }
1594
+ // 正在直播,开启定时器
1595
+ // 判断定时器是否已开启
1596
+ if (!pushAtTimeTimer) {
1597
+ // 开始直播,开启定时器
1598
+ pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
1599
+ }
1600
+ // 设置直播状态为true
1601
+ liveStatus = true;
1602
+ }
1585
1603
  }
1586
1604
  subShow() {
1587
1605
  // 在控制台中显示订阅对象
@@ -1621,7 +1639,7 @@ class ComRegister {
1621
1639
  // 只订阅动态
1622
1640
  return [false, true];
1623
1641
  }
1624
- updateSubNotifier(ctx) {
1642
+ updateSubNotifier() {
1625
1643
  // 更新控制台提示
1626
1644
  if (this.subNotifier)
1627
1645
  this.subNotifier.dispose();
@@ -1640,13 +1658,13 @@ class ComRegister {
1640
1658
  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 => ((0, jsx_runtime_1.jsx)("li", { children: str }))) })] });
1641
1659
  }
1642
1660
  // 设置更新后的提示
1643
- this.subNotifier = ctx.notifier.create(table);
1661
+ this.subNotifier = this.ctx.notifier.create(table);
1644
1662
  }
1645
- async checkIfLoginInfoIsLoaded(ctx) {
1663
+ async checkIfLoginInfoIsLoaded() {
1646
1664
  return new Promise(resolve => {
1647
1665
  const check = () => {
1648
- if (!ctx.ba.getLoginInfoIsLoaded()) {
1649
- ctx.setTimeout(check, 500);
1666
+ if (!this.ctx.ba.getLoginInfoIsLoaded()) {
1667
+ this.ctx.setTimeout(check, 500);
1650
1668
  }
1651
1669
  else {
1652
1670
  resolve('success');
@@ -1655,17 +1673,17 @@ class ComRegister {
1655
1673
  check();
1656
1674
  });
1657
1675
  }
1658
- async subUserInBili(ctx, mid) {
1676
+ async subUserInBili(mid) {
1659
1677
  // 获取关注分组信息
1660
1678
  const checkGroupIsReady = async () => {
1661
1679
  // 判断是否有数据
1662
1680
  if (this.loginDBData.dynamic_group_id === '' || this.loginDBData.dynamic_group_id === null) {
1663
1681
  // 没有数据,没有创建分组,尝试创建分组
1664
- const createGroupData = await ctx.ba.createGroup("订阅");
1682
+ const createGroupData = await this.ctx.ba.createGroup("订阅");
1665
1683
  // 如果分组已创建,则获取分组id
1666
1684
  if (createGroupData.code === 22106) {
1667
1685
  // 分组已存在,拿到之前的分组id
1668
- const allGroupData = await ctx.ba.getAllGroup();
1686
+ const allGroupData = await this.ctx.ba.getAllGroup();
1669
1687
  // 遍历所有分组
1670
1688
  for (const group of allGroupData.data) {
1671
1689
  // 找到订阅分组
@@ -1683,7 +1701,7 @@ class ComRegister {
1683
1701
  return false;
1684
1702
  }
1685
1703
  // 创建成功,保存到数据库
1686
- ctx.database.set('loginBili', 1, { dynamic_group_id: this.loginDBData.dynamic_group_id });
1704
+ this.ctx.database.set('loginBili', 1, { dynamic_group_id: this.loginDBData.dynamic_group_id });
1687
1705
  // 创建成功
1688
1706
  return true;
1689
1707
  }
@@ -1697,7 +1715,7 @@ class ComRegister {
1697
1715
  return { flag: false, msg: '创建分组失败,请尝试重启插件' };
1698
1716
  }
1699
1717
  // 获取分组明细
1700
- const relationGroupDetailData = await ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
1718
+ const relationGroupDetailData = await this.ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
1701
1719
  // 判断分组信息是否获取成功
1702
1720
  if (relationGroupDetailData.code !== 0) {
1703
1721
  if (relationGroupDetailData.code === 22104) {
@@ -1722,7 +1740,7 @@ class ComRegister {
1722
1740
  }
1723
1741
  });
1724
1742
  // 订阅对象
1725
- const subUserData = await ctx.ba.follow(mid);
1743
+ const subUserData = await this.ctx.ba.follow(mid);
1726
1744
  // 判断是否订阅成功
1727
1745
  switch (subUserData.code) {
1728
1746
  case -101: return { flag: false, msg: '账号未登录,请使用指令bili login登录后再进行订阅操作' };
@@ -1735,7 +1753,7 @@ class ComRegister {
1735
1753
  case 22014: // 已关注订阅对象 无需再次关注
1736
1754
  case 0: { // 执行订阅成功
1737
1755
  // 把订阅对象添加到分组中
1738
- const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
1756
+ const copyUserToGroupData = await this.ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
1739
1757
  // 判断是否添加成功
1740
1758
  if (copyUserToGroupData.code !== 0) {
1741
1759
  // 添加失败
@@ -1746,12 +1764,10 @@ class ComRegister {
1746
1764
  // 订阅成功
1747
1765
  return { flag: true, msg: '用户订阅成功' };
1748
1766
  }
1749
- async loadSubFromConfig(ctx, subs) {
1767
+ async loadSubFromConfig(subs) {
1750
1768
  for (const sub of subs) {
1751
1769
  // 定义Data
1752
1770
  let data;
1753
- // 定义直播销毁函数
1754
- let liveDispose;
1755
1771
  // 判断是否需要订阅直播
1756
1772
  if (sub.live) {
1757
1773
  // 获取用户信息
@@ -1761,15 +1777,15 @@ class ComRegister {
1761
1777
  for (let i = 0; i < attempts; i++) {
1762
1778
  try {
1763
1779
  // 获取用户信息
1764
- content = await ctx.ba.getUserInfo(sub.uid);
1780
+ content = await this.ctx.ba.getUserInfo(sub.uid);
1765
1781
  // 成功则跳出循环
1766
1782
  break;
1767
1783
  }
1768
1784
  catch (e) {
1769
- this.logger.error('getSubFromDatabase() getUserInfo() 发生了错误,错误为:' + e.message);
1785
+ this.logger.error('loadSubFromConfig() getUserInfo() 发生了错误,错误为:' + e.message);
1770
1786
  if (i === attempts - 1) { // 已尝试三次
1771
1787
  // 发送私聊消息并重启服务
1772
- return await this.sendPrivateMsgAndStopService(ctx);
1788
+ return await this.sendPrivateMsgAndStopService();
1773
1789
  }
1774
1790
  }
1775
1791
  }
@@ -1782,14 +1798,28 @@ class ComRegister {
1782
1798
  // 发送提示
1783
1799
  this.logger.warn(`UID:${sub.uid} 用户没有开通直播间,无法订阅直播!`);
1784
1800
  }
1801
+ //
1802
+ const liveDetectModeSelector = {
1803
+ API: async () => {
1804
+ // 判断是否已开启直播检测
1805
+ if (!this.liveDispose) { // 未开启直播检测
1806
+ // 开启直播检测并保存销毁函数
1807
+ this.liveDispose = await this.liveDetectWithAPI();
1808
+ }
1809
+ },
1810
+ WS: async () => {
1811
+ // 连接到服务器
1812
+ await this.liveDetectWithListener(data.live_room.roomid, sub.target);
1813
+ }
1814
+ };
1785
1815
  // 判断是否订阅直播
1786
1816
  if (sub.live) {
1787
- // 订阅直播
1788
- this.liveDetectWithListener(ctx, data.live_room.roomid, sub.target);
1817
+ // 启动直播监测
1818
+ await liveDetectModeSelector[this.config.liveDetectMode]();
1789
1819
  }
1790
1820
  }
1791
1821
  // 在B站中订阅该对象
1792
- const subInfo = await this.subUserInBili(ctx, sub.uid);
1822
+ const subInfo = await this.subUserInBili(sub.uid);
1793
1823
  // 判断订阅是否成功
1794
1824
  if (!subInfo.flag)
1795
1825
  this.logger.warn(subInfo.msg);
@@ -1801,25 +1831,13 @@ class ComRegister {
1801
1831
  target: sub.target,
1802
1832
  platform: '',
1803
1833
  live: sub.live,
1804
- dynamic: sub.dynamic,
1805
- liveDispose
1834
+ dynamic: sub.dynamic
1806
1835
  });
1807
1836
  }
1808
1837
  }
1809
- async loadSubFromDatabase(ctx) {
1810
- // 判断登录信息是否已加载完毕
1811
- await this.checkIfLoginInfoIsLoaded(ctx);
1812
- // 如果未登录,则直接返回
1813
- if (!(await this.checkIfIsLogin(ctx))) {
1814
- // log
1815
- this.logger.info(`账号未登录,请登录`);
1816
- return;
1817
- }
1818
- // 已存在订阅管理对象,不再进行订阅操作
1819
- if (this.subManager.length !== 0)
1820
- return;
1838
+ async loadSubFromDatabase() {
1821
1839
  // 从数据库中获取数据
1822
- const subData = await ctx.database.get('bilibili', { id: { $gt: 0 } });
1840
+ const subData = await this.ctx.database.get('bilibili', { id: { $gt: 0 } });
1823
1841
  // 定义变量:订阅直播数
1824
1842
  let liveSubNum = 0;
1825
1843
  // 循环遍历
@@ -1827,14 +1845,14 @@ class ComRegister {
1827
1845
  // 判断是否存在没有任何订阅的数据
1828
1846
  if (!sub.dynamic && !sub.live) { // 存在未订阅任何项目的数据
1829
1847
  // 删除该条数据
1830
- ctx.database.remove('bilibili', { id: sub.id });
1848
+ this.ctx.database.remove('bilibili', { id: sub.id });
1831
1849
  // log
1832
1850
  this.logger.warn(`UID:${sub.uid} 该条数据没有任何订阅数据,自动取消订阅`);
1833
1851
  // 跳过下面的步骤
1834
1852
  continue;
1835
1853
  }
1836
1854
  // 判断用户是否在B站中订阅了
1837
- const subUserData = await this.subUserInBili(ctx, sub.uid);
1855
+ const subUserData = await this.subUserInBili(sub.uid);
1838
1856
  // 判断是否订阅
1839
1857
  if (!subUserData.flag) {
1840
1858
  // log
@@ -1842,7 +1860,7 @@ class ComRegister {
1842
1860
  // 发送私聊消息
1843
1861
  await this.sendPrivateMsg(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
1844
1862
  // 删除该条数据
1845
- await ctx.database.remove('bilibili', { id: sub.id });
1863
+ await this.ctx.database.remove('bilibili', { id: sub.id });
1846
1864
  // 跳过下面的步骤
1847
1865
  continue;
1848
1866
  }
@@ -1855,7 +1873,7 @@ class ComRegister {
1855
1873
  for (let i = 0; i < attempts; i++) {
1856
1874
  try {
1857
1875
  // 获取用户信息
1858
- content = await ctx.ba.getUserInfo(sub.uid);
1876
+ content = await this.ctx.ba.getUserInfo(sub.uid);
1859
1877
  // 成功则跳出循环
1860
1878
  break;
1861
1879
  }
@@ -1863,7 +1881,7 @@ class ComRegister {
1863
1881
  this.logger.error('getSubFromDatabase() getUserInfo() 发生了错误,错误为:' + e.message);
1864
1882
  if (i === attempts - 1) { // 已尝试三次
1865
1883
  // 发送私聊消息并重启服务
1866
- return await this.sendPrivateMsgAndStopService(ctx);
1884
+ return await this.sendPrivateMsgAndStopService();
1867
1885
  }
1868
1886
  }
1869
1887
  }
@@ -1872,7 +1890,7 @@ class ComRegister {
1872
1890
  // 定义函数删除数据和发送提示
1873
1891
  const deleteSub = async () => {
1874
1892
  // 从数据库删除该条数据
1875
- await ctx.database.remove('bilibili', { id: sub.id });
1893
+ await this.ctx.database.remove('bilibili', { id: sub.id });
1876
1894
  // 给用户发送提示
1877
1895
  await this.sendPrivateMsg(`UID:${sub.uid} 数据库内容被篡改,已取消对该UP主的订阅`);
1878
1896
  };
@@ -1918,43 +1936,57 @@ class ComRegister {
1918
1936
  dynamic: sub.dynamic === 1 ? true : false,
1919
1937
  liveDispose: null
1920
1938
  };
1939
+ // 定义直播模式监测器
1940
+ const liveDetectModeSelector = {
1941
+ API: async () => {
1942
+ // 判断是否已开启直播检测
1943
+ if (!this.liveDispose) { // 未开启直播检测
1944
+ // 开启直播检测并保存销毁函数
1945
+ this.liveDispose = await this.liveDetectWithAPI();
1946
+ }
1947
+ },
1948
+ WS: async () => {
1949
+ // 判断订阅直播数是否超过限制
1950
+ if (!this.config.unlockSubLimits && liveSubNum >= 3) {
1951
+ // 将live改为false
1952
+ subManagerItem.live = false;
1953
+ // log
1954
+ this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1955
+ // 发送错误消息
1956
+ await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1957
+ }
1958
+ else {
1959
+ // 直播订阅数+1
1960
+ liveSubNum++;
1961
+ // 订阅直播,开始循环检测
1962
+ await this.liveDetectWithListener(sub.room_id, target);
1963
+ }
1964
+ }
1965
+ };
1921
1966
  // 判断是否订阅直播
1922
1967
  if (sub.live) {
1923
- // 判断订阅直播数是否超过限制
1924
- if (!this.config.unlockSubLimits && liveSubNum >= 3) {
1925
- // 将live改为false
1926
- subManagerItem.live = false;
1927
- // log
1928
- this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1929
- // 发送错误消息
1930
- await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
1931
- }
1932
- else {
1933
- // 直播订阅数+1
1934
- liveSubNum++;
1935
- // 订阅直播,开始循环检测
1936
- this.liveDetectWithListener(ctx, sub.room_id, target);
1937
- }
1968
+ // 启动直播监测
1969
+ await liveDetectModeSelector[this.config.liveDetectMode]();
1938
1970
  }
1939
1971
  // 保存新订阅对象
1940
1972
  this.subManager.push(subManagerItem);
1941
1973
  }
1942
1974
  }
1943
- checkIfDynamicDetectIsNeeded(ctx) {
1975
+ checkIfDynamicDetectIsNeeded() {
1944
1976
  // 检查是否有订阅对象需要动态监测
1945
1977
  if (this.subManager.some(sub => sub.dynamic))
1946
- this.enableDynamicDetect(ctx);
1978
+ this.enableDynamicDetect();
1947
1979
  }
1948
- enableDynamicDetect(ctx) {
1980
+ enableDynamicDetect() {
1949
1981
  // 开始动态监测
1950
1982
  if (this.config.dynamicDebugMode) {
1951
- this.dynamicDispose = ctx.setInterval(this.debug_dynamicDetect(ctx), this.config.dynamicLoopTime * 1000);
1983
+ this.dynamicDispose = this.ctx.setInterval(this.debug_dynamicDetect(), this.config.dynamicLoopTime * 1000);
1952
1984
  }
1953
1985
  else {
1954
- this.dynamicDispose = ctx.setInterval(this.dynamicDetect(ctx), this.config.dynamicLoopTime * 1000);
1986
+ this.dynamicDispose = this.ctx.setInterval(this.dynamicDetect(), this.config.dynamicLoopTime * 1000);
1955
1987
  }
1956
1988
  }
1957
- unsubSingle(ctx, id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
1989
+ unsubSingle(id /* UID或RoomId */, type /* 0取消Live订阅,1取消Dynamic订阅 */) {
1958
1990
  // 定义返回消息
1959
1991
  let msg;
1960
1992
  // 定义方法:检查是否没有任何订阅
@@ -1964,7 +1996,7 @@ class ComRegister {
1964
1996
  // 从管理对象中移除
1965
1997
  this.subManager.splice(index, 1);
1966
1998
  // 从数据库中删除
1967
- ctx.database.remove('bilibili', [this.subManager[index].id]);
1999
+ this.ctx.database.remove('bilibili', [this.subManager[index].id]);
1968
2000
  // num--
1969
2001
  this.num--;
1970
2002
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
@@ -1983,10 +2015,18 @@ class ComRegister {
1983
2015
  return msg;
1984
2016
  }
1985
2017
  // 取消订阅
1986
- if (sub.live)
1987
- sub.liveDispose();
1988
- sub.liveDispose = null;
1989
2018
  sub.live = false;
2019
+ // 判断直播检测方式
2020
+ switch (this.config.liveDetectMode) {
2021
+ case 'API': {
2022
+ msg = '请手动删除订阅,并重启插件';
2023
+ break;
2024
+ }
2025
+ case 'WS': {
2026
+ // 取消直播监听
2027
+ this.ctx.bl.closeListener(sub.roomId);
2028
+ }
2029
+ }
1990
2030
  // 如果没有对这个UP的任何订阅,则移除
1991
2031
  if (checkIfNoSubExist(sub)) {
1992
2032
  // 从管理对象中移除
@@ -1994,7 +2034,7 @@ class ComRegister {
1994
2034
  return '已取消订阅该用户';
1995
2035
  }
1996
2036
  // 更新数据库
1997
- ctx.database.upsert('bilibili', [{
2037
+ this.ctx.database.upsert('bilibili', [{
1998
2038
  id: +`${sub.id}`,
1999
2039
  live: 0
2000
2040
  }]);
@@ -2021,7 +2061,7 @@ class ComRegister {
2021
2061
  return '已取消订阅该用户';
2022
2062
  }
2023
2063
  // 更新数据库
2024
- ctx.database.upsert('bilibili', [{
2064
+ this.ctx.database.upsert('bilibili', [{
2025
2065
  id: sub.id,
2026
2066
  dynamic: 0
2027
2067
  }]);
@@ -2031,7 +2071,7 @@ class ComRegister {
2031
2071
  }
2032
2072
  finally {
2033
2073
  // 执行完该方法后,保证执行一次updateSubNotifier()
2034
- this.updateSubNotifier(ctx);
2074
+ this.updateSubNotifier();
2035
2075
  }
2036
2076
  }
2037
2077
  checkIfUserIsTheLastOneWhoSubDyn() {
@@ -2041,15 +2081,21 @@ class ComRegister {
2041
2081
  this.dynamicDispose = null;
2042
2082
  }
2043
2083
  }
2044
- unsubAll(ctx, uid) {
2084
+ unsubAll(uid) {
2045
2085
  this.subManager.filter(sub => sub.uid === uid).map(async (sub, i) => {
2046
- // 取消全部订阅 执行dispose方法,销毁定时器
2047
- if (sub.live)
2048
- await this.subManager[i].liveDispose();
2049
2086
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
2050
2087
  this.checkIfUserIsTheLastOneWhoSubDyn();
2088
+ switch (this.config.liveDetectMode) {
2089
+ case "API": {
2090
+ break;
2091
+ }
2092
+ case "WS": {
2093
+ // 停止直播检测
2094
+ this.ctx.bl.closeListener(sub.roomId);
2095
+ }
2096
+ }
2051
2097
  // 从数据库中删除订阅
2052
- await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
2098
+ await this.ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
2053
2099
  // 将该订阅对象从订阅管理对象中移除
2054
2100
  this.subManager.splice(i, 1);
2055
2101
  // id--
@@ -2057,13 +2103,13 @@ class ComRegister {
2057
2103
  // 发送成功通知
2058
2104
  this.sendPrivateMsg(`UID:${uid},已取消订阅该用户`);
2059
2105
  // 更新控制台提示
2060
- this.updateSubNotifier(ctx);
2106
+ this.updateSubNotifier();
2061
2107
  });
2062
2108
  }
2063
- async checkIfIsLogin(ctx) {
2064
- if ((await ctx.database.get('loginBili', 1)).length !== 0) { // 数据库中有数据
2109
+ async checkIfIsLogin() {
2110
+ if ((await this.ctx.database.get('loginBili', 1)).length !== 0) { // 数据库中有数据
2065
2111
  // 检查cookie中是否有值
2066
- if (ctx.ba.getCookies() !== '[]') { // 有值说明已登录
2112
+ if (this.ctx.ba.getCookies() !== '[]') { // 有值说明已登录
2067
2113
  return true;
2068
2114
  }
2069
2115
  }
@@ -2081,6 +2127,7 @@ class ComRegister {
2081
2127
  channelId: koishi_1.Schema.string().description('频道/群组号'),
2082
2128
  dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
2083
2129
  live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
2130
+ liveDanmaku: koishi_1.Schema.boolean().description('该频道/群组是否推送弹幕消息'),
2084
2131
  atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
2085
2132
  })).description('频道/群组信息'),
2086
2133
  platform: koishi_1.Schema.string().description('推送平台')
@@ -2094,7 +2141,10 @@ class ComRegister {
2094
2141
  }),
2095
2142
  unlockSubLimits: koishi_1.Schema.boolean().required(),
2096
2143
  automaticResend: koishi_1.Schema.boolean().required(),
2097
- changeMasterInfoApi: koishi_1.Schema.boolean().required(),
2144
+ liveDetectMode: koishi_1.Schema.union([
2145
+ koishi_1.Schema.const('API'),
2146
+ koishi_1.Schema.const('WS')
2147
+ ]).required(),
2098
2148
  restartPush: koishi_1.Schema.boolean().required(),
2099
2149
  pushTime: koishi_1.Schema.number().required(),
2100
2150
  liveLoopTime: koishi_1.Schema.number().default(10),