koishi-plugin-bilibili-notify 2.0.0-alpha.1 → 2.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.
@@ -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>', '订阅用户动态和直播通知')
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) => {
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,55 +313,80 @@ 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;
316
+ // 订阅对象
317
+ const subUserData = await this.subUserInBili(ctx, mid);
318
+ // 判断是否订阅对象存在
319
+ if (!subUserData.flag)
320
+ return '订阅对象失败,请稍后重试!';
321
+ // 定义目标变量
322
+ let target = [];
323
+ // 判断是否使用多平台功能
324
+ if (options.multiplatform) {
325
+ // 分割字符串,赋值给target
326
+ target = this.splitMultiPlatformStr(options.multiplatform);
327
+ }
328
+ // 判断是否使用了多平台
329
+ if (target) {
330
+ target.forEach(async ({ channelIdArr, platform }, index) => {
331
+ if (channelIdArr.length > 0) { // 输入了推送群号或频道号
332
+ // 拿到对应的bot
333
+ const bot = this.getBot(ctx, platform);
334
+ // 判断是否配置了对应平台的机器人
335
+ if (!ctx.bots.some(bot => bot.platform === platform)) {
336
+ await session.send('您未配置对应平台的机器人,不能在该平台进行订阅操作');
337
+ }
338
+ // 判断是否需要加入的群全部推送
339
+ if (channelIdArr[0].channelId !== 'all') {
340
+ // 定义满足条件的群组数组
341
+ const targetArr = [];
342
+ // 获取机器人加入的群组
343
+ const guildList = await bot.getGuildList();
344
+ // 遍历target数组
345
+ for (const channelId of channelIdArr) {
346
+ // 定义是否加入群组标志
347
+ let flag = false;
348
+ // 遍历群组
349
+ for (const guild of guildList.data) {
350
+ // 获取频道列表
351
+ const channelList = await bot.getChannelList(guild.id);
352
+ // 判断机器人是否加入群聊或频道
353
+ if (channelList.data.some(channel => channel.id === channelId.channelId)) {
354
+ // 加入群聊或频道
355
+ targetArr.push(channelId);
356
+ // 设置标志位为true
357
+ flag = true;
358
+ // 结束循环
359
+ break;
360
+ }
361
+ }
362
+ if (!flag) {
363
+ // 不满足条件发送错误提示
364
+ await session.send(`您的机器未加入${channelId.channelId},无法对该群或频道进行推送`);
365
+ }
366
+ }
367
+ // 判断targetArr是否为空
368
+ if (target.length === 0) {
369
+ // 为空则默认为当前环境
370
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
371
+ // 没有满足条件的群组或频道
372
+ await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
373
+ }
374
+ // 将符合条件的群组添加到target中
375
+ target[index].channelIdArr = targetArr;
315
376
  }
377
+ // 如果为all则全部推送,不需要进行处理
316
378
  }
317
- }
318
- else if (createGroupData.code !== 0) {
319
- // 创建分组失败
320
- return '创建关注分组出错';
321
- }
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 '添加订阅对象到分组失败,请稍后重试';
379
+ else {
380
+ // 未填写群号或频道号,默认为当前环境
381
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
382
+ // 发送提示消息
383
+ await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
344
384
  }
345
- }
385
+ });
386
+ }
387
+ else {
388
+ // 用户直接订阅,将当前环境赋值给target
389
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, atAll: options.atAll }], platform: session.event.platform }];
346
390
  }
347
391
  // 定义外围变量
348
392
  let content;
@@ -379,88 +423,14 @@ class ComRegister {
379
423
  // 返回错误信息
380
424
  return msg;
381
425
  }
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
426
  // 获取data
457
427
  const { data } = content;
458
428
  // 判断是否需要订阅直播和动态
459
- const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data);
429
+ const [liveMsg, dynamicMsg] = await this.checkIfNeedSub(options.live, options.dynamic, session, data.live_room);
460
430
  // 判断是否未订阅任何消息
461
- if (!liveMsg && !dynamicMsg) {
431
+ if (!liveMsg && !dynamicMsg)
462
432
  return '您未订阅该UP的任何消息';
463
- }
433
+ // 获取到对应的订阅对象
464
434
  const subUser = this.subManager.find(sub => sub.uid === mid);
465
435
  // 判断要订阅的用户是否已经存在于订阅管理对象中
466
436
  if (subUser) {
@@ -475,44 +445,22 @@ class ComRegister {
475
445
  }
476
446
  // 获取直播房间号
477
447
  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
448
  // 获取用户信息
503
449
  let userData;
504
450
  try {
505
- const { data } = await ctx.ba.getMasterInfo(sub.uid);
451
+ const { data } = await ctx.ba.getMasterInfo(mid);
506
452
  userData = data;
507
453
  }
508
454
  catch (e) {
509
455
  this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
510
456
  return '订阅出错啦,请重试';
511
457
  }
512
- console.log(liveMsg, dynamicMsg);
458
+ // 定义live销毁函数
459
+ let liveDispose;
513
460
  // 订阅直播
514
461
  if (liveMsg) {
515
- await session.execute(`bili live ${roomId} ${targetId.split(',').join(' ')}`);
462
+ // 开始循环检测
463
+ liveDispose = ctx.setInterval(this.liveDetect(ctx, roomId, target), config.liveLoopTime * 1000);
516
464
  // 发送订阅消息通知
517
465
  await session.send(`订阅${userData.info.uname}直播通知`);
518
466
  }
@@ -531,29 +479,32 @@ class ComRegister {
531
479
  // 发送订阅消息通知
532
480
  await session.send(`订阅${userData.info.uname}动态通知`);
533
481
  }
482
+ // 保存到数据库中
483
+ const sub = await ctx.database.create('bilibili', {
484
+ uid: mid,
485
+ room_id: roomId,
486
+ dynamic: dynamicMsg ? 1 : 0,
487
+ live: liveMsg ? 1 : 0,
488
+ target: JSON.stringify(target),
489
+ platform: session.event.platform,
490
+ time: new Date()
491
+ });
492
+ // 订阅数+1
493
+ this.num++;
494
+ // 保存新订阅对象
495
+ this.subManager.push({
496
+ id: sub.id,
497
+ uid: mid,
498
+ roomId,
499
+ target,
500
+ platform: session.event.platform,
501
+ live: liveMsg,
502
+ dynamic: dynamicMsg,
503
+ liveDispose
504
+ });
534
505
  // 新增订阅展示到控制台
535
506
  this.updateSubNotifier(ctx);
536
507
  });
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
508
  biliCom
558
509
  .subcommand('.status <roomId:string>', '查询主播当前直播状态', { hidden: true })
559
510
  .usage('查询主播当前直播状态')
@@ -597,19 +548,6 @@ class ComRegister {
597
548
  // pic不存在,说明使用的是page模式
598
549
  await session.send(koishi_1.h.image(buffer, 'image/png'));
599
550
  });
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
551
  biliCom
614
552
  .subcommand('.private', '向主人账号发送一条测试消息', { hidden: true })
615
553
  .usage('向主人账号发送一条测试消息')
@@ -621,15 +559,28 @@ class ComRegister {
621
559
  await session.send('已发送消息,如未收到则说明您的机器人不支持发送私聊消息或您的信息填写有误');
622
560
  });
623
561
  }
562
+ splitMultiPlatformStr(str) {
563
+ return str.split(';').map(cv => cv.split('.')).map(([idStr, platform]) => {
564
+ const channelIdArr = idStr.split(',').map(id => {
565
+ const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
566
+ const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
567
+ return { channelId, atAll };
568
+ });
569
+ return { channelIdArr, platform };
570
+ });
571
+ }
572
+ getBot(ctx, pf) {
573
+ return ctx.bots.find(bot => bot.platform === pf);
574
+ }
624
575
  async sendPrivateMsg(content) {
625
576
  if (this.config.master.enable) {
626
577
  if (this.config.master.masterAccountGuildId) {
627
578
  // 向机器人主人发送消息
628
- await this.bot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
579
+ await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content, this.config.master.masterAccountGuildId);
629
580
  }
630
581
  else {
631
582
  // 向机器人主人发送消息
632
- await this.bot.sendPrivateMessage(this.config.master.masterAccount, content);
583
+ await this.privateBot.sendPrivateMessage(this.config.master.masterAccount, content);
633
584
  }
634
585
  }
635
586
  }
@@ -674,22 +625,34 @@ class ComRegister {
674
625
  // 结束
675
626
  return;
676
627
  }
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);
628
+ async sendMsg(ctx, targets, content, live) {
629
+ for (const target of targets) {
630
+ // 获取机器人实例
631
+ const bot = this.getBot(ctx, target.platform);
632
+ // 定义需要发送的数组
633
+ let sendArr = [];
634
+ // 判断是否需要推送所有机器人加入的群
635
+ if (target.channelIdArr[0].channelId === 'all') {
636
+ // 获取所有guild
637
+ for (const guild of (await bot.getGuildList()).data) {
638
+ sendArr.push({ channelId: guild.id, atAll: target.channelIdArr[0].atAll });
639
+ }
640
+ }
641
+ else {
642
+ sendArr = target.channelIdArr;
643
+ }
644
+ // 循环给每个群组发送
645
+ if (live) {
646
+ // 直播推送,需要判断是否为
647
+ for (const channel of sendArr) {
648
+ await this.sendMsgFunc(bot, channel.channelId, (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [channel.atAll && (0, jsx_runtime_1.jsx)("at", { type: "all" }), content] }));
649
+ }
650
+ }
651
+ else {
652
+ for (const channel of sendArr) {
653
+ await this.sendMsgFunc(bot, channel.channelId, content);
654
+ }
685
655
  }
686
- }
687
- else {
688
- sendArr = targets;
689
- }
690
- // 循环给每个群组发送
691
- for (const guild of sendArr) {
692
- await this.sendMsgFunc(guild, content);
693
656
  }
694
657
  }
695
658
  dynamicDetect(ctx) {
@@ -819,13 +782,13 @@ class ComRegister {
819
782
  if (e.message === '出现关键词,屏蔽该动态') {
820
783
  // 如果需要发送才发送
821
784
  if (this.config.filter.notify) {
822
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条含有屏蔽关键字的动态`);
785
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
823
786
  }
824
787
  return;
825
788
  }
826
789
  if (e.message === '已屏蔽转发动态') {
827
790
  if (this.config.filter.notify) {
828
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条转发动态,已屏蔽`);
791
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
829
792
  }
830
793
  return;
831
794
  }
@@ -843,12 +806,12 @@ class ComRegister {
843
806
  if (pic) {
844
807
  this.logger.info('推送动态中,使用render模式');
845
808
  // pic存在,使用的是render模式
846
- await this.sendMsg(sub.targetIdArr, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
809
+ await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
847
810
  }
848
811
  else if (buffer) {
849
812
  this.logger.info('推送动态中,使用page模式');
850
813
  // 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] }));
814
+ 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
815
  }
853
816
  else {
854
817
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -1003,13 +966,13 @@ class ComRegister {
1003
966
  if (e.message === '出现关键词,屏蔽该动态') {
1004
967
  // 如果需要发送才发送
1005
968
  if (this.config.filter.notify) {
1006
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条含有屏蔽关键字的动态`);
969
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条含有屏蔽关键字的动态`);
1007
970
  }
1008
971
  return;
1009
972
  }
1010
973
  if (e.message === '已屏蔽转发动态') {
1011
974
  if (this.config.filter.notify) {
1012
- await this.sendMsg(sub.targetIdArr, `${upName}发布了一条转发动态,已屏蔽`);
975
+ await this.sendMsg(ctx, sub.target, `${upName}发布了一条转发动态,已屏蔽`);
1013
976
  }
1014
977
  return;
1015
978
  }
@@ -1027,12 +990,12 @@ class ComRegister {
1027
990
  if (pic) {
1028
991
  this.logger.info('推送动态中,使用render模式');
1029
992
  // pic存在,使用的是render模式
1030
- await this.sendMsg(sub.targetIdArr, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
993
+ await this.sendMsg(ctx, sub.target, pic + (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: dUrl }));
1031
994
  }
1032
995
  else if (buffer) {
1033
996
  this.logger.info('推送动态中,使用page模式');
1034
997
  // 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] }));
998
+ 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
999
  }
1037
1000
  else {
1038
1001
  this.logger.info(items[num].modules.module_author.name + '发布了一条动态,但是推送失败');
@@ -1046,7 +1009,7 @@ class ComRegister {
1046
1009
  }
1047
1010
  };
1048
1011
  }
1049
- liveDetect(ctx, roomId, guildId) {
1012
+ liveDetect(ctx, roomId, target) {
1050
1013
  let firstSubscription = true;
1051
1014
  let timer = 0;
1052
1015
  let open = false;
@@ -1056,80 +1019,40 @@ class ComRegister {
1056
1019
  // 相当于锁的作用,防止上一个循环没处理完
1057
1020
  let flag = true;
1058
1021
  // 定义发送直播通知卡片方法
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);
1022
+ const sendLiveNotifyCard = async (data, liveType, liveNotifyMsg) => {
1023
+ // 定义变量
1024
+ let pic;
1025
+ let buffer;
1026
+ // 多次尝试生成图片
1027
+ const attempts = 3;
1028
+ for (let i = 0; i < attempts; i++) {
1029
+ try {
1030
+ // 获取直播通知卡片
1031
+ const { pic: picv, buffer: bufferv } = await ctx.gi.generateLiveImg(data, username, userface, liveType);
1032
+ // 赋值
1033
+ pic = picv;
1034
+ buffer = bufferv;
1035
+ // 成功则跳出循环
1036
+ break;
1091
1037
  }
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
- }
1038
+ catch (e) {
1039
+ if (i === attempts - 1) { // 已尝试三次
1040
+ this.logger.error('liveDetect generateLiveImg() 推送卡片生成失败,原因:' + e.message);
1041
+ // 发送私聊消息并重启服务
1042
+ return await this.sendPrivateMsgAndStopService(ctx);
1120
1043
  }
1121
1044
  }
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
- }
1045
+ }
1046
+ // 推送直播信息
1047
+ // pic 存在,使用的是render模式
1048
+ if (pic) {
1049
+ const msg = (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: liveNotifyMsg && liveNotifyMsg });
1050
+ return await this.sendMsg(ctx, target, pic + msg, true);
1051
+ }
1052
+ // pic不存在,说明使用的是page模式
1053
+ const msg = (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [koishi_1.h.image(buffer, 'image/png'), liveNotifyMsg && liveNotifyMsg] });
1054
+ await this.sendMsg(ctx, target, msg, true);
1055
+ };
1133
1056
  // 定义获取主播信息方法
1134
1057
  let useMasterInfo;
1135
1058
  if (this.config.changeMasterInfoApi) {
@@ -1217,22 +1140,10 @@ class ComRegister {
1217
1140
  const liveEndMsg = this.config.customLiveEnd
1218
1141
  .replace('-name', username)
1219
1142
  .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] }));
1143
+ // 更改直播时长
1144
+ data.live_time = liveTime;
1145
+ // 发送@全体成员通知
1146
+ await sendLiveNotifyCard(data, LiveType.StopBroadcast, liveEndMsg);
1236
1147
  }
1237
1148
  // 未进循环,还未开播,继续循环
1238
1149
  break;
@@ -1266,15 +1177,8 @@ class ComRegister {
1266
1177
  .replace('-name', username)
1267
1178
  .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1268
1179
  .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
- }
1180
+ // 发送消息
1181
+ await sendLiveNotifyCard(data, LiveType.StartBroadcasting, liveStartMsg);
1278
1182
  }
1279
1183
  else { // 还在直播
1280
1184
  if (this.config.pushTime > 0) {
@@ -1283,8 +1187,13 @@ class ComRegister {
1283
1187
  if (timer >= (6 * 60 * this.config.pushTime)) { // 到时间推送直播消息
1284
1188
  // 到时间重新计时
1285
1189
  timer = 0;
1190
+ // 定义直播中通知消息
1191
+ const liveMsg = this.config.customLive ? this.config.customLive
1192
+ .replace('-name', username)
1193
+ .replace('-time', await ctx.gi.getTimeDifference(liveTime))
1194
+ .replace('-link', `https://live.bilibili.com/${data.short_id === 0 ? data.room_id : data.short_id}`) : '';
1286
1195
  // 发送直播通知卡片
1287
- sendLiveNotifyCard(data, LiveType.LiveBroadcast);
1196
+ sendLiveNotifyCard(data, LiveType.LiveBroadcast, liveMsg);
1288
1197
  }
1289
1198
  }
1290
1199
  // 否则继续循环
@@ -1306,10 +1215,10 @@ class ComRegister {
1306
1215
  });
1307
1216
  return table ? table : '没有订阅任何UP';
1308
1217
  }
1309
- async checkIfNeedSub(liveSub, dynamicSub, session, data) {
1218
+ async checkIfNeedSub(liveSub, dynamicSub, session, liveRoomData) {
1310
1219
  // 定义方法:用户直播间是否存在
1311
1220
  const liveRoom = async () => {
1312
- if (!data.live_room) {
1221
+ if (!liveRoomData) {
1313
1222
  // 未开通直播间
1314
1223
  await session.send('该用户未开通直播间,无法订阅直播');
1315
1224
  // 返回false
@@ -1370,6 +1279,97 @@ class ComRegister {
1370
1279
  check();
1371
1280
  });
1372
1281
  }
1282
+ async subUserInBili(ctx, mid) {
1283
+ // 获取关注分组信息
1284
+ const checkGroupIsReady = async () => {
1285
+ // 判断是否有数据
1286
+ if (this.loginDBData.dynamic_group_id === '' || this.loginDBData.dynamic_group_id === null) {
1287
+ // 没有数据,没有创建分组,尝试创建分组
1288
+ const createGroupData = await ctx.ba.createGroup("订阅");
1289
+ // 如果分组已创建,则获取分组id
1290
+ if (createGroupData.code === 22106) {
1291
+ // 分组已存在,拿到之前的分组id
1292
+ const allGroupData = await ctx.ba.getAllGroup();
1293
+ // 遍历所有分组
1294
+ for (const group of allGroupData.data) {
1295
+ // 找到订阅分组
1296
+ if (group.name === '订阅') {
1297
+ // 拿到分组id
1298
+ this.loginDBData.dynamic_group_id = group.tagid;
1299
+ // 结束循环
1300
+ break;
1301
+ }
1302
+ }
1303
+ }
1304
+ else if (createGroupData.code !== 0) {
1305
+ console.log(createGroupData);
1306
+ // 创建分组失败
1307
+ return false;
1308
+ }
1309
+ // 创建成功,保存到数据库
1310
+ ctx.database.set('loginBili', 1, { dynamic_group_id: this.loginDBData.dynamic_group_id });
1311
+ // 创建成功
1312
+ return true;
1313
+ }
1314
+ return true;
1315
+ };
1316
+ // 判断分组是否准备好
1317
+ const flag = await checkGroupIsReady();
1318
+ // 判断是否创建成功
1319
+ if (!flag) {
1320
+ // 创建分组失败
1321
+ return { flag: false, msg: '创建分组失败,请尝试重启插件' };
1322
+ }
1323
+ // 获取分组明细
1324
+ const relationGroupDetailData = await ctx.ba.getRelationGroupDetail(this.loginDBData.dynamic_group_id);
1325
+ // 判断分组信息是否获取成功
1326
+ if (relationGroupDetailData.code !== 0) {
1327
+ if (relationGroupDetailData.code === 22104) {
1328
+ // 将原先的分组id置空
1329
+ this.loginDBData.dynamic_group_id = null;
1330
+ // 分组不存在
1331
+ const flag = await checkGroupIsReady();
1332
+ // 判断是否创建成功
1333
+ if (!flag) {
1334
+ // 创建分组失败
1335
+ return { flag: false, msg: '创建分组失败,请尝试重启插件' };
1336
+ }
1337
+ return { flag: true, msg: '分组不存在,已重新创建分组' };
1338
+ }
1339
+ // 获取分组明细失败
1340
+ return { flag: false, msg: '获取分组明细失败' };
1341
+ }
1342
+ relationGroupDetailData.data.forEach(user => {
1343
+ if (user.mid === mid) {
1344
+ // 已关注订阅对象
1345
+ return { flag: true, msg: '订阅对象已存在于分组中' };
1346
+ }
1347
+ });
1348
+ // 订阅对象
1349
+ const subUserData = await ctx.ba.follow(mid);
1350
+ // 判断是否订阅成功
1351
+ switch (subUserData.code) {
1352
+ case -101: return { flag: false, msg: '账号未登录,请使用指令bili login登录后再进行订阅操作' };
1353
+ case -102: return { flag: false, msg: '账号被封停,无法进行订阅操作' };
1354
+ case 22002: return { flag: false, msg: '因对方隐私设置,无法进行订阅操作' };
1355
+ case 22003: return { flag: false, msg: '你已将对方拉黑,无法进行订阅操作' };
1356
+ case 22013: return { flag: false, msg: '账号已注销,无法进行订阅操作' };
1357
+ case 40061: return { flag: false, msg: '账号不存在,请检查uid输入是否正确或用户是否存在' };
1358
+ case 22001: break; // 订阅对象为自己 无需添加到分组
1359
+ case 22014: // 已关注订阅对象 无需再次关注
1360
+ case 0: { // 执行订阅成功
1361
+ // 把订阅对象添加到分组中
1362
+ const copyUserToGroupData = await ctx.ba.copyUserToGroup(mid, this.loginDBData.dynamic_group_id);
1363
+ // 判断是否添加成功
1364
+ if (copyUserToGroupData.code !== 0) {
1365
+ // 添加失败
1366
+ return { flag: false, msg: '添加订阅对象到分组失败,请稍后重试' };
1367
+ }
1368
+ }
1369
+ }
1370
+ // 订阅成功
1371
+ return { flag: true, msg: '用户订阅成功' };
1372
+ }
1373
1373
  async getSubFromDatabase(ctx) {
1374
1374
  // 判断登录信息是否已加载完毕
1375
1375
  await this.checkIfLoginInfoIsLoaded(ctx);
@@ -1397,8 +1397,21 @@ class ComRegister {
1397
1397
  // 跳过下面的步骤
1398
1398
  continue;
1399
1399
  }
1400
+ // 判断用户是否在B站中订阅了
1401
+ const subUserData = await this.subUserInBili(ctx, sub.uid);
1402
+ // 判断是否订阅
1403
+ if (!subUserData.flag) {
1404
+ // log
1405
+ this.logger.warn(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
1406
+ // 发送私聊消息
1407
+ await this.sendPrivateMsg(`UID:${sub.uid} ${subUserData.msg},自动取消订阅`);
1408
+ // 删除该条数据
1409
+ await ctx.database.remove('bilibili', { id: sub.id });
1410
+ // 跳过下面的步骤
1411
+ continue;
1412
+ }
1400
1413
  // 获取推送目标数组
1401
- const targetIdArr = sub.targetId.split(' ');
1414
+ const target = JSON.parse(sub.target);
1402
1415
  /* 判断数据库是否被篡改 */
1403
1416
  // 获取用户信息
1404
1417
  let content;
@@ -1448,7 +1461,7 @@ class ComRegister {
1448
1461
  }
1449
1462
  }
1450
1463
  // 检测房间号是否被篡改
1451
- if (sub.live && (!data.live_room || data.live_room.roomid.toString() !== sub.room_id)) {
1464
+ if (sub.live && (!data.live_room || data.live_room.roomid != sub.room_id)) {
1452
1465
  // 房间号被篡改,删除该订阅
1453
1466
  await deleteSub();
1454
1467
  // log
@@ -1462,10 +1475,10 @@ class ComRegister {
1462
1475
  id: sub.id,
1463
1476
  uid: sub.uid,
1464
1477
  roomId: sub.room_id,
1465
- targetIdArr,
1478
+ target,
1466
1479
  platform: sub.platform,
1467
- live: +sub.live === 1 ? true : false,
1468
- dynamic: +sub.dynamic === 1 ? true : false,
1480
+ live: sub.live === 1 ? true : false,
1481
+ dynamic: sub.dynamic === 1 ? true : false,
1469
1482
  liveDispose: null
1470
1483
  };
1471
1484
  // 判断是否订阅直播
@@ -1482,7 +1495,7 @@ class ComRegister {
1482
1495
  // 直播订阅数+1
1483
1496
  liveSubNum++;
1484
1497
  // 订阅直播,开始循环检测
1485
- const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, targetIdArr), this.config.liveLoopTime * 1000);
1498
+ const dispose = ctx.setInterval(this.liveDetect(ctx, sub.room_id, target), this.config.liveLoopTime * 1000);
1486
1499
  // 保存销毁函数
1487
1500
  subManagerItem.liveDispose = dispose;
1488
1501
  }
@@ -1517,7 +1530,7 @@ class ComRegister {
1517
1530
  // num--
1518
1531
  this.num--;
1519
1532
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1520
- this.checkIfUserThatIsSubDynAndUnsub();
1533
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1521
1534
  };
1522
1535
  try {
1523
1536
  switch (type) {
@@ -1562,7 +1575,7 @@ class ComRegister {
1562
1575
  // 取消订阅
1563
1576
  this.subManager[index].dynamic = false;
1564
1577
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1565
- this.checkIfUserThatIsSubDynAndUnsub();
1578
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1566
1579
  // 如果没有对这个UP的任何订阅,则移除
1567
1580
  if (checkIfNoSubExist(sub)) {
1568
1581
  // 从管理对象中移除
@@ -1583,7 +1596,7 @@ class ComRegister {
1583
1596
  this.updateSubNotifier(ctx);
1584
1597
  }
1585
1598
  }
1586
- checkIfUserThatIsSubDynAndUnsub() {
1599
+ checkIfUserIsTheLastOneWhoSubDyn() {
1587
1600
  if (this.subManager.some(sub => sub.dynamic)) {
1588
1601
  // 停止动态监测
1589
1602
  this.dynamicDispose();
@@ -1596,7 +1609,7 @@ class ComRegister {
1596
1609
  if (sub.live)
1597
1610
  await this.subManager[i].liveDispose();
1598
1611
  // 判断是否还存在订阅了动态的对象,不存在则停止动态监测
1599
- this.checkIfUserThatIsSubDynAndUnsub();
1612
+ this.checkIfUserIsTheLastOneWhoSubDyn();
1600
1613
  // 从数据库中删除订阅
1601
1614
  await ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
1602
1615
  // 将该订阅对象从订阅管理对象中移除
@@ -1621,21 +1634,20 @@ class ComRegister {
1621
1634
  }
1622
1635
  (function (ComRegister) {
1623
1636
  ComRegister.Config = koishi_1.Schema.object({
1624
- platform: koishi_1.Schema.string(),
1625
1637
  master: koishi_1.Schema.object({
1626
1638
  enable: koishi_1.Schema.boolean(),
1639
+ platform: koishi_1.Schema.string(),
1627
1640
  masterAccount: koishi_1.Schema.string(),
1628
1641
  masterAccountGuildId: koishi_1.Schema.string()
1629
1642
  }),
1630
1643
  unlockSubLimits: koishi_1.Schema.boolean().required(),
1631
1644
  automaticResend: koishi_1.Schema.boolean().required(),
1632
1645
  changeMasterInfoApi: koishi_1.Schema.boolean().required(),
1633
- liveStartAtAll: koishi_1.Schema.boolean().required(),
1634
1646
  restartPush: koishi_1.Schema.boolean().required(),
1635
- pushUrl: koishi_1.Schema.boolean().required(),
1636
1647
  pushTime: koishi_1.Schema.number().required(),
1637
1648
  liveLoopTime: koishi_1.Schema.number().default(10),
1638
1649
  customLiveStart: koishi_1.Schema.string().required(),
1650
+ customLive: koishi_1.Schema.string(),
1639
1651
  customLiveEnd: koishi_1.Schema.string().required(),
1640
1652
  dynamicUrl: koishi_1.Schema.boolean().required(),
1641
1653
  dynamicLoopTime: koishi_1.Schema.number().default(60),