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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/blive.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Awaitable, Context, Schema, Service } from "koishi";
1
+ import { Awaitable, Context, Service } from "koishi";
2
2
  import { type MsgHandler } from 'blive-message-listener';
3
3
  declare module 'koishi' {
4
4
  interface Context {
@@ -7,18 +7,10 @@ declare module 'koishi' {
7
7
  }
8
8
  declare class BLive extends Service {
9
9
  static inject: string[];
10
- private blConfig;
11
10
  private listenerRecord;
12
- private timerRecord;
13
- constructor(ctx: Context, config: BLive.Config);
11
+ constructor(ctx: Context);
14
12
  protected stop(): Awaitable<void>;
15
- startLiveRoomListener(roomId: string, handler: MsgHandler, danmakuPushTime: () => void): Promise<void>;
13
+ startLiveRoomListener(roomId: string, handler: MsgHandler): Promise<void>;
16
14
  closeListener(roomId: string): void;
17
15
  }
18
- declare namespace BLive {
19
- interface Config {
20
- danmakuPushTime: number;
21
- }
22
- const Config: Schema<Config>;
23
- }
24
16
  export default BLive;
package/lib/blive.js CHANGED
@@ -5,16 +5,11 @@ const blive_message_listener_1 = require("blive-message-listener");
5
5
  class BLive extends koishi_1.Service {
6
6
  // 必要服务
7
7
  static inject = ['ba'];
8
- // 配置
9
- blConfig;
10
8
  // 定义类属性
11
9
  listenerRecord = {};
12
- timerRecord = {};
13
- constructor(ctx, config) {
10
+ constructor(ctx) {
14
11
  // Extends super
15
12
  super(ctx, 'bl');
16
- // 将config赋值给类属性
17
- this.blConfig = config;
18
13
  }
19
14
  // 注册插件dispose逻辑
20
15
  stop() {
@@ -23,7 +18,7 @@ class BLive extends koishi_1.Service {
23
18
  this.closeListener(key);
24
19
  }
25
20
  }
26
- async startLiveRoomListener(roomId, handler, danmakuPushTime) {
21
+ async startLiveRoomListener(roomId, handler) {
27
22
  // 获取cookieStr
28
23
  const cookiesStr = await this.ctx.ba.getCookiesForHeader();
29
24
  // 获取自身信息
@@ -37,8 +32,6 @@ class BLive extends koishi_1.Service {
37
32
  uid: mySelfInfo.data.mid
38
33
  }
39
34
  });
40
- // 默认30s推送一次弹幕消息到群组并将dispose函数保存到Record中
41
- this.timerRecord[roomId] = this.ctx.setInterval(danmakuPushTime, this.blConfig.danmakuPushTime * 1000 * 60);
42
35
  // logger
43
36
  this.logger.info(`${roomId}直播间弹幕监听已开启`);
44
37
  }
@@ -48,21 +41,12 @@ class BLive extends koishi_1.Service {
48
41
  // 输出logger
49
42
  this.logger.info(`${roomId}直播间弹幕监听器无需关闭`);
50
43
  }
51
- // 判断消息发送定时器是否关闭
52
- if (!this.timerRecord || !this.timerRecord[roomId]) {
53
- // 输出logger
54
- this.logger.info(`${roomId}直播间消息发送定时器无需关闭`);
55
- }
56
44
  // 关闭直播间监听器
57
45
  this.listenerRecord[roomId].close();
58
- // 关闭消息发送定时器
59
- this.timerRecord[roomId]();
60
46
  // 判断是否关闭成功
61
47
  if (this.listenerRecord[roomId].closed) {
62
48
  // 删除直播间监听器
63
49
  delete this.listenerRecord[roomId];
64
- // 删除消息发送定时器
65
- delete this.timerRecord[roomId];
66
50
  // 输出logger
67
51
  this.logger.info(`${roomId}直播间弹幕监听已关闭`);
68
52
  // 直接返回
@@ -72,10 +56,4 @@ class BLive extends koishi_1.Service {
72
56
  this.logger.warn(`${roomId}直播间弹幕监听未成功关闭`);
73
57
  }
74
58
  }
75
- // eslint-disable-next-line @typescript-eslint/no-namespace
76
- (function (BLive) {
77
- BLive.Config = koishi_1.Schema.object({
78
- danmakuPushTime: koishi_1.Schema.number().required()
79
- });
80
- })(BLive || (BLive = {}));
81
59
  exports.default = BLive;
@@ -11,7 +11,7 @@ type ChannelIdArr = Array<{
11
11
  channelId: string;
12
12
  dynamic: boolean;
13
13
  live: boolean;
14
- liveDanmaku: boolean;
14
+ liveGuardBuy: boolean;
15
15
  atAll: boolean;
16
16
  }>;
17
17
  type TargetItem = {
@@ -97,7 +97,7 @@ declare namespace ComRegister {
97
97
  channelId: string;
98
98
  dynamic: boolean;
99
99
  live: boolean;
100
- liveDanmaku: boolean;
100
+ liveGuardBuy: boolean;
101
101
  atAll: boolean;
102
102
  }>;
103
103
  platform: string;
@@ -120,7 +120,6 @@ declare namespace ComRegister {
120
120
  customLiveEnd: string;
121
121
  dynamicUrl: boolean;
122
122
  dynamicLoopTime: number;
123
- dynamicCheckNumber: number;
124
123
  filter: {
125
124
  enable: boolean;
126
125
  notify: boolean;
@@ -10,6 +10,10 @@ 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
+ // 弹幕词云
14
+ const segmentit_1 = require("segmentit");
15
+ const canvas_1 = require("canvas");
16
+ const d3_cloud_1 = __importDefault(require("d3-cloud"));
13
17
  var LiveType;
14
18
  (function (LiveType) {
15
19
  LiveType[LiveType["NotLiveBroadcast"] = 0] = "NotLiveBroadcast";
@@ -291,7 +295,7 @@ class ComRegister {
291
295
  channelId: group,
292
296
  dynamic: true,
293
297
  live: true,
294
- liveDanmaku: false,
298
+ liveGuardBuy: false,
295
299
  atAll: options.atAll
296
300
  });
297
301
  });
@@ -351,7 +355,7 @@ class ComRegister {
351
355
  // 判断targetArr是否为空
352
356
  if (target.length === 0) {
353
357
  // 为空则默认为当前环境
354
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
358
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveGuardBuy: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
355
359
  // 没有满足条件的群组或频道
356
360
  await session.send('没有满足条件的群组或频道,默认订阅到当前聊天环境');
357
361
  }
@@ -362,7 +366,7 @@ class ComRegister {
362
366
  }
363
367
  else {
364
368
  // 未填写群号或频道号,默认为当前环境
365
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
369
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveGuardBuy: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
366
370
  // 发送提示消息
367
371
  await session.send('没有填写群号或频道号,默认订阅到当前聊天环境');
368
372
  }
@@ -370,7 +374,7 @@ class ComRegister {
370
374
  }
371
375
  else {
372
376
  // 用户直接订阅,将当前环境赋值给target
373
- target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveDanmaku: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
377
+ target = [{ channelIdArr: [{ channelId: session.event.channel.id, dynamic: true, live: true, liveGuardBuy: false, atAll: options.atAll ? options.atAll : false }], platform: session.event.platform }];
374
378
  }
375
379
  }
376
380
  // 定义外围变量
@@ -622,7 +626,7 @@ class ComRegister {
622
626
  const channelIdArr = idStr.split(',').map(id => {
623
627
  const atAll = /@$/.test(id); // 使用正则表达式检查 id 是否以 @ 结尾
624
628
  const channelId = atAll ? id.slice(0, -1) : id; // 去除末尾的 @
625
- return { channelId, dynamic: true, live: true, liveDanmaku: false, atAll };
629
+ return { channelId, dynamic: true, live: true, liveGuardBuy: false, atAll };
626
630
  });
627
631
  return { channelIdArr, platform };
628
632
  });
@@ -697,7 +701,7 @@ class ComRegister {
697
701
  channelId: guild.id,
698
702
  dynamic: target.channelIdArr[0].dynamic,
699
703
  live: target.channelIdArr[0].live,
700
- liveDanmaku: target.channelIdArr[0].liveDanmaku,
704
+ liveGuardBuy: target.channelIdArr[0].liveGuardBuy,
701
705
  atAll: target.channelIdArr[0].atAll
702
706
  });
703
707
  }
@@ -1392,7 +1396,6 @@ class ComRegister {
1392
1396
  let pushAtTimeTimer;
1393
1397
  // 定义弹幕存放数组
1394
1398
  const currentLiveDanmakuArr = [];
1395
- const temporaryLiveDanmakuArr = [];
1396
1399
  // 定义开播状态
1397
1400
  let liveStatus = false;
1398
1401
  // 处理target
@@ -1402,14 +1405,14 @@ class ComRegister {
1402
1405
  let liveRoomInfo;
1403
1406
  let masterInfo;
1404
1407
  // 找到频道/群组对应的
1405
- const danmakuPushTargetArr = target.map(channel => {
1408
+ const liveGuardBuyPushTargetArr = target.map(channel => {
1406
1409
  // 获取符合条件的target
1407
- const liveDanmakuArr = channel.channelIdArr.filter(channelId => channelId.liveDanmaku);
1410
+ const liveGuardBuyArr = channel.channelIdArr.filter(channelId => channelId.liveGuardBuy);
1408
1411
  // 将当前liveDanmakuArr的长度+到channelIdArrLen中
1409
- channelIdArrLen += liveDanmakuArr.length;
1412
+ channelIdArrLen += liveGuardBuyArr.length;
1410
1413
  // 返回符合的target
1411
1414
  return {
1412
- channelIdArr: liveDanmakuArr,
1415
+ channelIdArr: liveGuardBuyArr,
1413
1416
  platform: channel.platform
1414
1417
  };
1415
1418
  });
@@ -1435,25 +1438,62 @@ class ComRegister {
1435
1438
  data: liveRoomInfo
1436
1439
  }, LiveType.LiveBroadcast, liveMsg);
1437
1440
  };
1438
- // 定义弹幕推送函数
1439
- const danmakuPushFunc = () => {
1440
- // 判断数组是否有内容
1441
- if (channelIdArrLen > 0 && temporaryLiveDanmakuArr.length > 0) {
1442
- // 发送消息
1443
- this.sendMsg(danmakuPushTargetArr, temporaryLiveDanmakuArr.join('\n'));
1444
- // 将临时消息数组清空
1445
- temporaryLiveDanmakuArr.length = 0;
1441
+ // 定义获取弹幕权重Record函数
1442
+ const getDanmakuWeightRecord = () => {
1443
+ // 创建segmentit
1444
+ const segmentit = (0, segmentit_1.useDefault)(new segmentit_1.Segment());
1445
+ // 创建Record
1446
+ const danmakuWeightRecord = {};
1447
+ // 循环遍历currentLiveDanmakuArr
1448
+ for (const danmaku of currentLiveDanmakuArr) {
1449
+ // 遍历结果
1450
+ segmentit.doSegment(danmaku).map((word) => {
1451
+ // 定义权重
1452
+ danmakuWeightRecord[word.w] = (danmakuWeightRecord[word.w] || 0) + 1;
1453
+ });
1446
1454
  }
1455
+ // 返回Record
1456
+ return danmakuWeightRecord;
1457
+ };
1458
+ // 定义获取弹幕词云函数
1459
+ const sendDanmakuWordCloud = (danmakuWeightRecord) => {
1460
+ // 准备词云数据
1461
+ const wordList = Object.keys(danmakuWeightRecord).map(word => ({ text: word, value: danmakuWeightRecord[word] }));
1462
+ // 创建画布
1463
+ const width = 800;
1464
+ const height = 600;
1465
+ const canvas = (0, canvas_1.createCanvas)(width, height);
1466
+ const context = canvas.getContext('2d');
1467
+ // 定义绘制函数
1468
+ const draw = (words) => {
1469
+ context.clearRect(0, 0, width, height);
1470
+ context.fillStyle = '#fff';
1471
+ context.fillRect(0, 0, width, height);
1472
+ words.forEach(function (d) {
1473
+ context.font = `${d.size}px Arial`;
1474
+ context.fillStyle = '#000';
1475
+ context.fillText(d.text, d.x, d.y);
1476
+ });
1477
+ // 保存画布为buffer
1478
+ const buffer = canvas.toBuffer('image/png');
1479
+ // 发送消息
1480
+ this.sendMsg(target, koishi_1.h.image(buffer, 'image/png'));
1481
+ };
1482
+ // 配置词云
1483
+ const layout = (0, d3_cloud_1.default)()
1484
+ .size([width, height])
1485
+ .words(wordList.map(d => ({ text: d.text, size: d.value })))
1486
+ .padding(5)
1487
+ .font('Arial')
1488
+ .fontSize(d => d.size)
1489
+ .on('end', draw);
1490
+ // 生成词云
1491
+ layout.start();
1447
1492
  };
1448
1493
  // 定义直播间信息获取函数
1449
1494
  const useMasterAndLiveRoomInfo = async () => {
1450
- // 定义flag
1495
+ // 定义函数是否执行成功flag
1451
1496
  let flag = true;
1452
- // 判断是否已存在值
1453
- if (liveRoomInfo && masterInfo && liveTime) {
1454
- // 所有值均已存在,不需要再获取信息
1455
- return flag;
1456
- }
1457
1497
  // 获取直播间信息
1458
1498
  liveRoomInfo = await this.useLiveRoomInfo(roomId).catch(() => {
1459
1499
  // 设置flag为false
@@ -1492,24 +1532,18 @@ class ComRegister {
1492
1532
  this.logger.info('直播间连接已断开');
1493
1533
  },
1494
1534
  onIncomeDanmu: ({ body }) => {
1495
- // 处理消息,只需要UP主名字和消息内容
1496
- const content = `【${masterInfo.username}的直播间】${body.user.uname}:${body.content}`;
1497
1535
  // 保存消息到数组
1498
1536
  currentLiveDanmakuArr.push(body.content);
1499
- temporaryLiveDanmakuArr.push(content);
1500
1537
  },
1501
1538
  onIncomeSuperChat: ({ body }) => {
1502
- // 处理SC消息
1503
- const content = `【${masterInfo.username}的直播间】${body.user.uname}发送了一条SC:${body.content}`;
1504
1539
  // 保存消息到数组
1505
1540
  currentLiveDanmakuArr.push(body.content);
1506
- temporaryLiveDanmakuArr.push(content);
1507
1541
  },
1508
1542
  onGuardBuy: ({ body }) => {
1509
- const content = `【${masterInfo.username}的直播间】${body.user.uname}加入了大航海(${body.gift_name})`;
1510
- // 保存消息到数组
1511
- currentLiveDanmakuArr.push(content);
1512
- temporaryLiveDanmakuArr.push(content);
1543
+ // 定义消息
1544
+ const content = `${body.user.uname}加入了大航海(${body.gift_name})`;
1545
+ // 直接发送消息
1546
+ channelIdArrLen > 0 && this.sendMsg(liveGuardBuyPushTargetArr, content);
1513
1547
  },
1514
1548
  onLiveStart: async () => {
1515
1549
  // 判断是否已经开播
@@ -1567,12 +1601,14 @@ class ComRegister {
1567
1601
  pushAtTimeTimer();
1568
1602
  // 将推送定时器变量置空
1569
1603
  pushAtTimeTimer = null;
1604
+ // 发送弹幕词云
1605
+ sendDanmakuWordCloud(getDanmakuWeightRecord());
1570
1606
  // 将直播状态设置为false
1571
1607
  liveStatus = false;
1572
1608
  }
1573
1609
  };
1574
1610
  // 启动直播间弹幕监测
1575
- await this.ctx.bl.startLiveRoomListener(roomId, handler, danmakuPushFunc);
1611
+ await this.ctx.bl.startLiveRoomListener(roomId, handler);
1576
1612
  // 判断直播状态
1577
1613
  if (liveRoomInfo.live_status === 1) {
1578
1614
  // 设置开播时间
@@ -2127,7 +2163,7 @@ class ComRegister {
2127
2163
  channelId: koishi_1.Schema.string().description('频道/群组号'),
2128
2164
  dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
2129
2165
  live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
2130
- liveDanmaku: koishi_1.Schema.boolean().description('该频道/群组是否推送弹幕消息'),
2166
+ liveGuardBuy: koishi_1.Schema.boolean().description('该频道/群组是否推送弹幕消息'),
2131
2167
  atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
2132
2168
  })).description('频道/群组信息'),
2133
2169
  platform: koishi_1.Schema.string().description('推送平台')
@@ -2153,7 +2189,6 @@ class ComRegister {
2153
2189
  customLiveEnd: koishi_1.Schema.string().required(),
2154
2190
  dynamicUrl: koishi_1.Schema.boolean().required(),
2155
2191
  dynamicLoopTime: koishi_1.Schema.number().default(60),
2156
- dynamicCheckNumber: koishi_1.Schema.number().required(),
2157
2192
  filter: koishi_1.Schema.object({
2158
2193
  enable: koishi_1.Schema.boolean(),
2159
2194
  notify: koishi_1.Schema.boolean(),
package/lib/index.d.ts CHANGED
@@ -36,7 +36,7 @@ export interface Config {
36
36
  channelId: string;
37
37
  dynamic: boolean;
38
38
  live: boolean;
39
- liveDanmaku: boolean;
39
+ liveGuardBuy: boolean;
40
40
  atAll: boolean;
41
41
  }>;
42
42
  platform: string;
@@ -44,13 +44,11 @@ export interface Config {
44
44
  }>;
45
45
  dynamic: {};
46
46
  dynamicUrl: boolean;
47
- dynamicCheckNumber: number;
48
47
  dynamicLoopTime: '1分钟' | '2分钟' | '3分钟' | '5分钟' | '10分钟' | '20分钟';
49
48
  live: {};
50
49
  liveDetectMode: 'API' | 'WS';
51
50
  restartPush: boolean;
52
51
  pushTime: number;
53
- danmakuPushTime: number;
54
52
  customLiveStart: string;
55
53
  customLive: string;
56
54
  customLiveEnd: string;
package/lib/index.js CHANGED
@@ -170,16 +170,13 @@ class ServerManager extends koishi_1.Service {
170
170
  customLiveStart: globalConfig.customLiveStart,
171
171
  customLive: globalConfig.customLive,
172
172
  customLiveEnd: globalConfig.customLiveEnd,
173
- dynamicCheckNumber: globalConfig.dynamicCheckNumber,
174
173
  dynamicLoopTime: this.dynamicLoopTime,
175
174
  dynamicUrl: globalConfig.dynamicUrl,
176
175
  filter: globalConfig.filter,
177
176
  dynamicDebugMode: globalConfig.dynamicDebugMode
178
177
  });
179
178
  // BL = BLive
180
- const bl = this.ctx.plugin(blive_1.default, {
181
- danmakuPushTime: globalConfig.danmakuPushTime
182
- });
179
+ const bl = this.ctx.plugin(blive_1.default);
183
180
  // 添加服务
184
181
  this.servers.push(ba);
185
182
  this.servers.push(bl);
@@ -235,7 +232,7 @@ function apply(ctx, config) {
235
232
  globalConfig = config;
236
233
  // 设置提示
237
234
  ctx.notifier.create({
238
- content: '从2.0.0-alpha.9以前版本更新需重新订阅'
235
+ content: '从3.0.0-alpha.10以前版本更新需重新订阅'
239
236
  });
240
237
  ctx.notifier.create({
241
238
  content: '请使用Auth插件创建超级管理员账号,没有权限将无法使用该插件提供的指令。'
@@ -314,7 +311,7 @@ exports.Config = koishi_1.Schema.object({
314
311
  channelId: koishi_1.Schema.string().description('频道/群组号'),
315
312
  dynamic: koishi_1.Schema.boolean().description('该频道/群组是否推送动态信息'),
316
313
  live: koishi_1.Schema.boolean().description('该频道/群组是否推送直播通知'),
317
- liveDanmaku: koishi_1.Schema.boolean().description('该频道/群组是否推送弹幕消息'),
314
+ liveGuardBuy: koishi_1.Schema.boolean().description('该频道/群组是否推送上舰消息'),
318
315
  atAll: koishi_1.Schema.boolean().description('推送开播通知时是否艾特全体成员')
319
316
  })).description('频道/群组信息'),
320
317
  platform: koishi_1.Schema.string().description('推送平台')
@@ -324,13 +321,6 @@ exports.Config = koishi_1.Schema.object({
324
321
  dynamicUrl: koishi_1.Schema.boolean()
325
322
  .default(false)
326
323
  .description('发送动态时是否同时发送链接。注意:如果使用的是QQ官方机器人不能开启此项!'),
327
- dynamicCheckNumber: koishi_1.Schema.number()
328
- .min(2)
329
- .max(10)
330
- .role('slider')
331
- .step(1)
332
- .default(5)
333
- .description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应+1。默认值为5条'),
334
324
  dynamicLoopTime: koishi_1.Schema.union(['1分钟', '2分钟', '3分钟', '5分钟', '10分钟', '20分钟'])
335
325
  .role('')
336
326
  .default('2分钟')
@@ -352,12 +342,6 @@ exports.Config = koishi_1.Schema.object({
352
342
  .step(0.5)
353
343
  .default(1)
354
344
  .description('设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时'),
355
- danmakuPushTime: koishi_1.Schema.number()
356
- .min(0)
357
- .max(10)
358
- .step(0.5)
359
- .default(0.5)
360
- .description('设定间隔多长时间推送一次弹幕消息,单位为分钟,默认为半分钟'),
361
345
  customLiveStart: koishi_1.Schema.string()
362
346
  .default('-name开播啦 -link')
363
347
  .description('自定义开播提示语,-name代表UP昵称,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用)。例如-name开播啦,会发送为xxxUP开播啦'),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-bilibili-notify",
3
3
  "description": "Koishi bilibili notify plugin",
4
- "version": "3.0.0-alpha.10",
4
+ "version": "3.0.0-alpha.11",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
@@ -30,14 +30,18 @@
30
30
  "axios": "^1.7.9",
31
31
  "axios-cookiejar-support": "^5.0.5",
32
32
  "blive-message-listener": "^0.5.0",
33
+ "canvas": "^3.1.0",
34
+ "d3-cloud": "^1.2.7",
33
35
  "jsdom": "^24.1.3",
34
36
  "luxon": "^3.5.0",
35
37
  "md5": "^2.3.0",
36
38
  "qrcode": "^1.5.4",
39
+ "segmentit": "^2.0.3",
37
40
  "tough-cookie": "^4.1.4"
38
41
  },
39
42
  "devDependencies": {
40
43
  "@eslint/js": "^9.20.0",
44
+ "@types/d3-cloud": "^1",
41
45
  "@types/luxon": "^3.4.2",
42
46
  "@types/md5": "^2.3.5",
43
47
  "@types/qrcode": "^1.5.5",
package/readme.md CHANGED
@@ -222,6 +222,7 @@
222
222
  - ver 3.0.0-alpha.8 修复:开播通知连续发送两次,登录后不会加载手动订阅中的订阅; 优化:网络请求报错
223
223
  - ver 3.0.0-alpha.9 优化:加强直播推送对获取直播信息的错误处理
224
224
  - ver 3.0.0-alpha.10 修复:连续推送两次开播通知
225
+ - ver 3.0.0-alpha.11 新增:直播结束后推送弹幕词云,直播推送上舰消息; 修复:直播推送都是同一张画面; 移除:直播推送弹幕消息
225
226
 
226
227
  ## 交流群
227
228