koishi-plugin-bilibili-notify 3.2.9-rc.1 → 3.2.9-rc.3

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/index.d.mts CHANGED
@@ -35,6 +35,7 @@ interface BAConfig {
35
35
  live: {};
36
36
  liveDetectType: "WS" | "API";
37
37
  wordcloud: boolean;
38
+ liveSummary: string;
38
39
  restartPush: boolean;
39
40
  pushTime: number;
40
41
  customLiveStart: string;
package/lib/index.d.ts CHANGED
@@ -35,6 +35,7 @@ interface BAConfig {
35
35
  live: {};
36
36
  liveDetectType: "WS" | "API";
37
37
  wordcloud: boolean;
38
+ liveSummary: string;
38
39
  restartPush: boolean;
39
40
  pushTime: number;
40
41
  customLiveStart: string;
package/lib/index.js CHANGED
@@ -39,7 +39,8 @@ const path = __toESM$1(require("path"));
39
39
  const qrcode = __toESM$1(require("qrcode"));
40
40
  const cron = __toESM$1(require("cron"));
41
41
  const luxon = __toESM$1(require("luxon"));
42
- const segmentit = __toESM$1(require("segmentit"));
42
+ const __node_rs_jieba = __toESM$1(require("@node-rs/jieba"));
43
+ const __node_rs_jieba_dict = __toESM$1(require("@node-rs/jieba/dict"));
43
44
  const __satorijs_element_jsx_runtime = __toESM$1(require("@satorijs/element/jsx-runtime"));
44
45
  const node_path = __toESM$1(require("node:path"));
45
46
  const node_url = __toESM$1(require("node:url"));
@@ -113,6 +114,7 @@ const BAConfigSchema = koishi.Schema.object({
113
114
  live: koishi.Schema.object({}).description("直播推送设置"),
114
115
  liveDetectType: koishi.Schema.union([koishi.Schema.const("WS").description("使用WebSocket连接到B站消息服务器进行直播检测,推荐使用"), koishi.Schema.const("API").description("通过轮询API发送请求监测直播状态,此模式理论可无限订阅,但容易产生其他问题,功能没有WS模式全面").experimental()]).role("radio").default("WS").description("直播检测方式,WS为连接到B站消息服务器,API为通过轮询发送请求监测,默认使用WS检测"),
115
116
  wordcloud: koishi.Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云"),
117
+ liveSummary: koishi.Schema.string().default("🔍【弹幕情报站】本场直播数据如下:\\n🧍‍♂️ 总共 -dmc 位特工上线\\n💬 共计 -dca 条弹幕飞驰而过\\n📊 热词云图已生成,快来看看你有没有上榜!\\n\\n👑 本场顶级输出选手:\\n🥇 -un1 - 弹幕输出 -dc1 条\\n🥈 -un2 - 弹幕 -dc2 条,萌力惊人\\n🥉 -un3 - -dc3 条精准狙击\\n\\n🎖️ 特别嘉奖:-un4 & -un5\\n你们的弹幕,我们都记录在案!🕵️‍♀️").description("自定义直播总结语,开启弹幕词云自动发送。变量解释:-dmc代表总弹幕发送人数,-dca代表总弹幕数,-un1到-un5代表弹幕发送条数前五名用户的用户名,-dc1到-dc5代表弹幕发送条数前五名的弹幕发送数量"),
116
118
  restartPush: koishi.Schema.boolean().default(true).description("插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启"),
117
119
  pushTime: koishi.Schema.number().min(0).max(12).step(.5).default(1).description("设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时"),
118
120
  customLiveStart: koishi.Schema.string().default("-name开播啦,当前粉丝数:-follower\\n-link").description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name开播啦,会发送为xxxUP开播啦"),
@@ -615,7 +617,142 @@ const PushTypeMsg = {
615
617
  };
616
618
 
617
619
  //#endregion
618
- //#region src/comRegister.tsx
620
+ //#region src/stop_words.ts
621
+ const stopwords = new Set([
622
+ ",",
623
+ "。",
624
+ "!",
625
+ "?",
626
+ ":",
627
+ ";",
628
+ "“",
629
+ "”",
630
+ "‘",
631
+ "’",
632
+ "(",
633
+ ")",
634
+ "、",
635
+ "……",
636
+ "——",
637
+ "-",
638
+ "_",
639
+ ".",
640
+ ",",
641
+ "(",
642
+ ")",
643
+ "【",
644
+ "】",
645
+ "而且",
646
+ "但是",
647
+ "如果",
648
+ "虽然",
649
+ "因为",
650
+ "所以",
651
+ "但是",
652
+ "那么",
653
+ "那么就",
654
+ "今天",
655
+ "昨天",
656
+ "后天",
657
+ "明天",
658
+ "现在",
659
+ "刚刚",
660
+ "刚才",
661
+ "一直",
662
+ "一直在",
663
+ "目前",
664
+ "以前",
665
+ "以后",
666
+ "以前的",
667
+ "the",
668
+ "and",
669
+ "to",
670
+ "of",
671
+ "a",
672
+ "is",
673
+ "in",
674
+ "on",
675
+ "for",
676
+ "with",
677
+ "this",
678
+ "that",
679
+ "you",
680
+ "觉得",
681
+ "表示",
682
+ "发现",
683
+ "认为",
684
+ "看到",
685
+ "听说",
686
+ "了解",
687
+ "知道",
688
+ "说明",
689
+ "指出",
690
+ "讨论",
691
+ "讨论一下",
692
+ "看看",
693
+ "想想",
694
+ "说说",
695
+ "讲讲",
696
+ "一个",
697
+ "一些",
698
+ "这个",
699
+ "那个",
700
+ "每个",
701
+ "什么",
702
+ "东西",
703
+ "事情",
704
+ "这些",
705
+ "那些",
706
+ "这种",
707
+ "那种",
708
+ "怎么说",
709
+ "怎么会",
710
+ "怎么可能",
711
+ "不可能",
712
+ "有点像",
713
+ "真的很",
714
+ "特别是",
715
+ "有时候",
716
+ "每次都",
717
+ "一点点",
718
+ "哪里有",
719
+ "太离谱",
720
+ "太搞笑",
721
+ "太真实",
722
+ "为了",
723
+ "因为",
724
+ "所以",
725
+ "但是",
726
+ "而且",
727
+ "然后",
728
+ "如果",
729
+ "虽然",
730
+ "然而",
731
+ "不过",
732
+ "并且",
733
+ "即使",
734
+ "由于",
735
+ "那么",
736
+ "除非",
737
+ "比如",
738
+ "比如说",
739
+ "现在",
740
+ "刚刚",
741
+ "刚才",
742
+ "以前",
743
+ "以后",
744
+ "一直",
745
+ "从来",
746
+ "目前",
747
+ "最近",
748
+ "已经",
749
+ "后来",
750
+ "之前",
751
+ "某天"
752
+ ]);
753
+
754
+ //#endregion
755
+ //#region src/command_register.tsx
619
756
  var import_lib$1 = __toESM$1(require_lib$3());
620
757
  var ComRegister = class {
621
758
  static inject = [
@@ -648,7 +785,7 @@ var ComRegister = class {
648
785
  privateBot;
649
786
  dynamicJob;
650
787
  liveJob;
651
- _segmentit = (0, segmentit.useDefault)(new segmentit.Segment());
788
+ _jieba = __node_rs_jieba.Jieba.withDict(__node_rs_jieba_dict.dict);
652
789
  constructor(ctx, config) {
653
790
  this.ctx = ctx;
654
791
  this.init(config);
@@ -799,58 +936,107 @@ var ComRegister = class {
799
936
  });
800
937
  biliCom.subcommand(".wc").action(async ({ session }) => {
801
938
  const words = [
802
- ["弹幕护体", 77],
803
- ["笑死", 30],
804
- ["泪目", 45],
805
- ["加油", 70],
806
- ["???", 80],
807
- ["我可以", 66],
808
- ["无语", 55],
809
- ["梦开始的地方", 1],
810
- ["太真实了", 8],
811
- ["我哭死", 1],
812
- ["人呢", 2],
813
- ["有点意思", 4],
814
- ["妙啊", 4],
815
- ["这波啊", 11],
816
- ["懂了", 6],
817
- ["破防了", 65],
818
- ["蚌埠住了", 92],
819
- ["", 100],
820
- ["针不戳", 68],
821
- ["yyds", 50],
822
- ["DNA动了", 58],
823
- ["猝不及防", 40],
824
- ["建议加精", 15],
825
- ["保护", 22],
826
- ["害怕", 18],
827
- ["就这?", 99],
828
- ["2333", 20],
829
- ["公开处刑", 35],
830
- ["血压上来了", 45],
831
- ["整不会了", 32],
832
- ["见证历史", 88],
833
- ["下次一定", 65],
834
- ["奥利给", 56],
835
- ["求更新", 18],
836
- ["真实", 20],
837
- ["好活当赏", 25],
838
- ["泪,冲了出来", 68],
839
- ["刻进DNA", 70],
840
- ["我直接好家伙", 55],
841
- ["夺笋啊", 40],
842
- ["歪歪滴艾斯", 1],
843
- ["典中典", 5],
844
- ["麻中麻", 3],
845
- ["绷不住了", 8],
846
- ["逆天", 95],
847
- ["", 65],
848
- ["", 20],
849
- ["", 101],
850
- ["急急急", 3],
851
- ["", 5]
939
+ ["摆烂", 60],
940
+ ["可以", 42],
941
+ ["可以", 42],
942
+ ["可以", 42],
943
+ ["dog", 40],
944
+ ["dog", 40],
945
+ ["不是", 37],
946
+ ["不是", 37],
947
+ ["就是", 27],
948
+ ["就是", 27],
949
+ ["吃瓜", 16],
950
+ ["吃瓜", 16],
951
+ ["吃瓜", 16],
952
+ ["cj", 8],
953
+ ["cj", 8],
954
+ ["cj", 8],
955
+ ["没有", 8],
956
+ ["没有", 8],
957
+ ["没有", 8],
958
+ ["有点", 8],
959
+ ["有点", 8],
960
+ ["喜欢", 7],
961
+ ["喜欢", 7],
962
+ ["空调", 7],
963
+ ["空调", 7],
964
+ ["空调", 7],
965
+ ["感觉", 7],
966
+ ["感觉", 7],
967
+ ["感觉", 7],
968
+ ["时候", 6],
969
+ ["时候", 6],
970
+ ["怎么", 6],
971
+ ["怎么", 6],
972
+ ["痛车", 6],
973
+ ["痛车", 6],
974
+ ["一下", 6],
975
+ ["一下", 6],
976
+ ["还是", 6],
977
+ ["还是", 6],
978
+ ["麻麻", 6],
979
+ ["麻麻", 6],
980
+ ["下午", 5],
981
+ ["下午", 5],
982
+ ["开始", 5],
983
+ ["开始", 5],
984
+ ["一部", 5],
985
+ ["一部", 5],
986
+ ["这样", 5],
987
+ ["这样", 5],
988
+ ["上次", 5],
989
+ ["上次", 5],
990
+ ["游戏", 5],
991
+ ["游戏", 5],
992
+ ["这边", 5],
993
+ ["这边", 5],
994
+ ["问号", 5],
995
+ ["问号", 5],
996
+ ["好看", 5],
997
+ ["好看", 5],
998
+ ["哈哈哈", 5],
999
+ ["哈哈哈", 5],
1000
+ ["角色", 5],
1001
+ ["角色", 5],
1002
+ ["味道", 5],
1003
+ ["味道", 5],
1004
+ ["233333", 4],
1005
+ ["233333", 4],
1006
+ ["老规矩", 4],
1007
+ ["老规矩", 4],
1008
+ ["鸣潮", 4],
1009
+ ["鸣潮", 4],
1010
+ ["养生", 4],
1011
+ ["养生", 4],
1012
+ ["划掉", 4],
1013
+ ["划掉", 4],
1014
+ ["排队", 4],
1015
+ ["排队", 4],
1016
+ ["cos", 4],
1017
+ ["cos", 4],
1018
+ ["的话", 4],
1019
+ ["的话", 4],
1020
+ ["我们", 4],
1021
+ ["主要", 4],
1022
+ ["www", 4],
1023
+ ["直接", 4],
1024
+ ["不好", 4],
1025
+ ["学校", 4],
1026
+ ["一样", 4],
1027
+ ["初中", 4],
1028
+ ["毕业", 4]
852
1029
  ];
853
1030
  await session.send(/* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("message", { children: koishi.h.image(await this.ctx.gi.generateWordCloudImg(words, "词云测试"), "image/jpg") }));
1031
+ const top5DanmakuMaker = [
1032
+ ["张三", 60],
1033
+ ["李四", 48],
1034
+ ["王五", 45],
1035
+ ["赵六", 27],
1036
+ ["田七", 25]
1037
+ ];
1038
+ const danmakerRankMsg = this.config.liveSummary.replace("-dmc", "114").replace("-dca", "514").replace("-un1", `${top5DanmakuMaker[0][0]}`).replace("-dc1", `${top5DanmakuMaker[0][1]}`).replace("-un2", `${top5DanmakuMaker[1][0]}`).replace("-dc2", `${top5DanmakuMaker[1][1]}`).replace("-un3", `${top5DanmakuMaker[2][0]}`).replace("-dc3", `${top5DanmakuMaker[2][1]}`).replace("-un4", `${top5DanmakuMaker[3][0]}`).replace("-dc4", `${top5DanmakuMaker[3][1]}`).replace("-un5", `${top5DanmakuMaker[4][0]}`).replace("-dc5", `${top5DanmakuMaker[4][1]}`).replaceAll("\\n", "\n");
1039
+ await session.send(danmakerRankMsg);
854
1040
  });
855
1041
  }
856
1042
  async init(config) {
@@ -981,7 +1167,7 @@ var ComRegister = class {
981
1167
  }
982
1168
  async broadcastToTargets(uid, content, type, retry = 3e3) {
983
1169
  if (!this.checkAllBotsAreReady()) {
984
- this.logger.error(`有机器人未准备好,无法进行推送,${retry / 1e3}秒后重试`);
1170
+ this.logger.error(`存在机器人未初始化完毕,无法进行推送,${retry / 1e3}秒后重试`);
985
1171
  this.ctx.setTimeout(() => {
986
1172
  this.broadcastToTargets(uid, content, type, retry * 2);
987
1173
  }, retry);
@@ -996,7 +1182,7 @@ var ComRegister = class {
996
1182
  const success = await withRetry(async () => {
997
1183
  return await this.ctx.broadcast(atAllArr, /* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("message", { children: /* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("at", { type: "all" }) }));
998
1184
  }, 1);
999
- this.logger.info(`成功推送全体成员消息群组/频道:${success}`);
1185
+ this.logger.info(`成功推送全体成员消息:${success.length}条`);
1000
1186
  }
1001
1187
  if (type === PushType.Dynamic && record.dynamicArr?.length >= 1) {
1002
1188
  this.logger.info(record.dynamicArr);
@@ -1004,7 +1190,7 @@ var ComRegister = class {
1004
1190
  const success = await withRetry(async () => {
1005
1191
  return await this.ctx.broadcast(dynamicArr, /* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("message", { children: content }));
1006
1192
  }, 1);
1007
- this.logger.info(`成功推送动态消息群组/频道:${success}`);
1193
+ this.logger.info(`成功推送动态消息:${success.length}条`);
1008
1194
  }
1009
1195
  if ((type === PushType.Live || type === PushType.StartBroadcasting) && record.liveArr?.length >= 1) {
1010
1196
  this.logger.info(record.liveArr);
@@ -1012,7 +1198,7 @@ var ComRegister = class {
1012
1198
  const success = await withRetry(async () => {
1013
1199
  return await this.ctx.broadcast(liveArr, /* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("message", { children: content }));
1014
1200
  }, 1);
1015
- this.logger.info(`成功推送直播消息群组/频道:${success}`);
1201
+ this.logger.info(`成功推送直播消息:${success.length}条`);
1016
1202
  }
1017
1203
  if (type === PushType.LiveGuardBuy && record.liveGuardBuyArr?.length >= 1) {
1018
1204
  this.logger.info(record.liveGuardBuyArr);
@@ -1020,7 +1206,7 @@ var ComRegister = class {
1020
1206
  const success = await withRetry(async () => {
1021
1207
  return await this.ctx.broadcast(liveGuardBuyArr, /* @__PURE__ */ (0, __satorijs_element_jsx_runtime.jsx)("message", { children: content }));
1022
1208
  }, 1);
1023
- this.logger.info(`成功推送上舰消息群组/频道:${success}`);
1209
+ this.logger.info(`成功推送上舰消息:${success.length}条`);
1024
1210
  }
1025
1211
  return;
1026
1212
  }
@@ -1280,15 +1466,18 @@ var ComRegister = class {
1280
1466
  return await this.broadcastToTargets(uid, msg, liveType === LiveType.StartBroadcasting ? PushType.StartBroadcasting : PushType.Live);
1281
1467
  }
1282
1468
  async segmentDanmaku(danmaku, danmakuWeightRecord) {
1283
- this._segmentit.doSegment(danmaku).map(({ w: w$3, p: p$1 }) => {
1284
- if (p$1 && p$1 === 2048) return;
1469
+ this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !stopwords.has(word)).map((w$3) => {
1285
1470
  danmakuWeightRecord[w$3] = (danmakuWeightRecord[w$3] || 0) + 1;
1286
1471
  });
1287
1472
  }
1473
+ addUserToDanmakuMaker(username, danmakuMakerRecord) {
1474
+ danmakuMakerRecord[username] = (danmakuMakerRecord[username] || 0) + 1;
1475
+ }
1288
1476
  async liveDetectWithListener(roomId, uid, cardStyle) {
1289
1477
  let liveTime;
1290
1478
  let pushAtTimeTimer;
1291
1479
  const danmakuWeightRecord = {};
1480
+ const danmakuMakerRecord = {};
1292
1481
  let liveStatus = false;
1293
1482
  let liveRoomInfo;
1294
1483
  let masterInfo;
@@ -1296,14 +1485,23 @@ var ComRegister = class {
1296
1485
  const liveMsgObj = this.liveMsgManager.get(uid);
1297
1486
  const sendDanmakuWordCloud = async () => {
1298
1487
  this.logger.info("开始制作弹幕词云");
1299
- this.logger.info("正在获取前50热词");
1300
- const top50Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 50);
1301
- this.logger.info("弹幕词云前50词及权重:");
1302
- this.logger.info(top50Words);
1488
+ this.logger.info("正在获取前90热词");
1489
+ const top90Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 90).map(([word, weight]) => [word, weight > 60 ? 60 : weight]);
1490
+ this.logger.info("弹幕词云前90词及权重:");
1491
+ this.logger.info(top90Words);
1303
1492
  this.logger.info("正在准备生成弹幕词云");
1304
- const buffer = await this.ctx.gi.generateWordCloudImg(top50Words, masterInfo.username);
1493
+ const buffer = await this.ctx.gi.generateWordCloudImg(top90Words, masterInfo.username);
1305
1494
  this.logger.info("弹幕词云生成完成,正在准备发送词云图片");
1306
1495
  await this.broadcastToTargets(uid, koishi.h.image(buffer, "image/jpeg"), PushType.Live);
1496
+ this.logger.info("词云图片发送完毕!");
1497
+ this.logger.info("开始构建弹幕发送排行榜消息");
1498
+ const danmakuMakerCount = Object.keys(danmakuMakerRecord).length;
1499
+ const danmakuCount = Object.values(danmakuMakerRecord).reduce((sum, val) => sum + val, 0);
1500
+ const top5DanmakuMaker = Object.entries(danmakuMakerRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 5);
1501
+ const danmakuMakerMsg = this.config.liveSummary.replace("-dmc", `${danmakuMakerCount}`).replace("-dca", `${danmakuCount}`).replace("-un1", `${top5DanmakuMaker[0][0]}`).replace("-dc1", `${top5DanmakuMaker[0][1]}`).replace("-un2", `${top5DanmakuMaker[1][0]}`).replace("-dc2", `${top5DanmakuMaker[1][1]}`).replace("-un3", `${top5DanmakuMaker[2][0]}`).replace("-dc3", `${top5DanmakuMaker[2][1]}`).replace("-un4", `${top5DanmakuMaker[3][0]}`).replace("-dc4", `${top5DanmakuMaker[3][1]}`).replace("-un5", `${top5DanmakuMaker[4][0]}`).replace("-dc5", `${top5DanmakuMaker[4][1]}`).replaceAll("\\n", "\n");
1502
+ await this.broadcastToTargets(uid, danmakuMakerMsg, PushType.Live);
1503
+ Object.keys(danmakuWeightRecord).forEach((key) => delete danmakuWeightRecord[key]);
1504
+ Object.keys(danmakuMakerRecord).forEach((key) => delete danmakuMakerRecord[key]);
1307
1505
  };
1308
1506
  const pushAtTimeFunc = async () => {
1309
1507
  if (!await useMasterAndLiveRoomInfo(LiveType.LiveBroadcast)) {
@@ -1351,9 +1549,11 @@ var ComRegister = class {
1351
1549
  },
1352
1550
  onIncomeDanmu: ({ body }) => {
1353
1551
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1552
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1354
1553
  },
1355
1554
  onIncomeSuperChat: ({ body }) => {
1356
1555
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1556
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1357
1557
  },
1358
1558
  onWatchedChange: ({ body }) => {
1359
1559
  watchedNum = body.text_small;
@@ -1829,6 +2029,7 @@ var ComRegister = class {
1829
2029
  }),
1830
2030
  liveDetectType: koishi.Schema.string(),
1831
2031
  wordcloud: koishi.Schema.boolean(),
2032
+ liveSummary: koishi.Schema.string(),
1832
2033
  restartPush: koishi.Schema.boolean().required(),
1833
2034
  pushTime: koishi.Schema.number().required(),
1834
2035
  pushImgsInDynamic: koishi.Schema.boolean().required(),
@@ -1848,7 +2049,7 @@ var ComRegister = class {
1848
2049
  dynamicDebugMode: koishi.Schema.boolean().required()
1849
2050
  });
1850
2051
  })(ComRegister || (ComRegister = {}));
1851
- var comRegister_default = ComRegister;
2052
+ var command_register_default = ComRegister;
1852
2053
 
1853
2054
  //#endregion
1854
2055
  //#region src/database.ts
@@ -93102,7 +93303,7 @@ var require_lib = __commonJS$1({ "node_modules/koishi-plugin-puppeteer/lib/index
93102
93303
  } });
93103
93304
 
93104
93305
  //#endregion
93105
- //#region src/generateImg.ts
93306
+ //#region src/generate_img.ts
93106
93307
  var import_lib = __toESM$1(require_lib());
93107
93308
  const DYNAMIC_TYPE_NONE = "DYNAMIC_TYPE_NONE";
93108
93309
  const DYNAMIC_TYPE_FORWARD = "DYNAMIC_TYPE_FORWARD";
@@ -94486,10 +94687,10 @@ var GenerateImg = class extends koishi.Service {
94486
94687
  const words = ${JSON.stringify(words)}
94487
94688
 
94488
94689
  renderAutoFitWordCloud(canvas, words, {
94489
- maxFontSize: 40,
94690
+ maxFontSize: 60,
94490
94691
  minFontSize: 12,
94491
94692
  densityTarget: 0.3,
94492
- weightExponent: 0.5
94693
+ weightExponent: 0.4
94493
94694
  });
94494
94695
  </script>
94495
94696
  </body>
@@ -94590,7 +94791,7 @@ var GenerateImg = class extends koishi.Service {
94590
94791
  followerDisplay: koishi.Schema.boolean()
94591
94792
  });
94592
94793
  })(GenerateImg || (GenerateImg = {}));
94593
- var generateImg_default = GenerateImg;
94794
+ var generate_img_default = GenerateImg;
94594
94795
 
94595
94796
  //#endregion
94596
94797
  //#region node_modules/@oxc-project/runtime/src/helpers/decorate.js
@@ -94605,7 +94806,7 @@ var require_decorate = __commonJS$1({ "node_modules/@oxc-project/runtime/src/hel
94605
94806
  } });
94606
94807
 
94607
94808
  //#endregion
94608
- //#region src/biliAPI.ts
94809
+ //#region src/bili_api.ts
94609
94810
  var import_decorate = __toESM$1(require_decorate());
94610
94811
  const mixinKeyEncTab = [
94611
94812
  46,
@@ -95298,10 +95499,10 @@ var BiliAPI = class extends koishi.Service {
95298
95499
  key: koishi.Schema.string().pattern(/^[0-9a-f]{32}$/).required()
95299
95500
  });
95300
95501
  })(BiliAPI || (BiliAPI = {}));
95301
- var biliAPI_default = BiliAPI;
95502
+ var bili_api_default = BiliAPI;
95302
95503
 
95303
95504
  //#endregion
95304
- //#region src/blive.ts
95505
+ //#region src/bili_live.ts
95305
95506
  var BLive = class extends koishi.Service {
95306
95507
  static inject = ["ba"];
95307
95508
  listenerRecord = {};
@@ -95331,7 +95532,7 @@ var BLive = class extends koishi.Service {
95331
95532
  this.logger.warn(`${roomId}直播间连接未成功关闭`);
95332
95533
  }
95333
95534
  };
95334
- var blive_default = BLive;
95535
+ var bili_live_default = BLive;
95335
95536
 
95336
95537
  //#endregion
95337
95538
  //#region src/index.ts
@@ -95373,11 +95574,11 @@ var ServerManager = class extends koishi.Service {
95373
95574
  registerPlugin = () => {
95374
95575
  if (this.servers.length !== 0) return false;
95375
95576
  try {
95376
- const ba = this.ctx.plugin(biliAPI_default, {
95577
+ const ba = this.ctx.plugin(bili_api_default, {
95377
95578
  userAgent: globalConfig.userAgent,
95378
95579
  key: globalConfig.key
95379
95580
  });
95380
- const gi = this.ctx.plugin(generateImg_default, {
95581
+ const gi = this.ctx.plugin(generate_img_default, {
95381
95582
  filter: globalConfig.filter,
95382
95583
  removeBorder: globalConfig.removeBorder,
95383
95584
  cardColorStart: globalConfig.cardColorStart,
@@ -95389,10 +95590,11 @@ var ServerManager = class extends koishi.Service {
95389
95590
  font: globalConfig.font,
95390
95591
  followerDisplay: globalConfig.followerDisplay
95391
95592
  });
95392
- const cr = this.ctx.plugin(comRegister_default, {
95593
+ const cr = this.ctx.plugin(command_register_default, {
95393
95594
  sub: globalConfig.sub,
95394
95595
  master: globalConfig.master,
95395
95596
  wordcloud: globalConfig.wordcloud,
95597
+ liveSummary: globalConfig.liveSummary,
95396
95598
  liveDetectType: globalConfig.liveDetectType,
95397
95599
  restartPush: globalConfig.restartPush,
95398
95600
  pushTime: globalConfig.pushTime,
@@ -95406,7 +95608,7 @@ var ServerManager = class extends koishi.Service {
95406
95608
  filter: globalConfig.filter,
95407
95609
  dynamicDebugMode: globalConfig.dynamicDebugMode
95408
95610
  });
95409
- const bl = this.ctx.plugin(blive_default);
95611
+ const bl = this.ctx.plugin(bili_live_default);
95410
95612
  this.servers.push(ba);
95411
95613
  this.servers.push(bl);
95412
95614
  this.servers.push(gi);
package/lib/index.mjs CHANGED
@@ -4,7 +4,8 @@ import { resolve } from "path";
4
4
  import QRCode from "qrcode";
5
5
  import { CronJob } from "cron";
6
6
  import { DateTime } from "luxon";
7
- import { Segment, useDefault } from "segmentit";
7
+ import { Jieba } from "@node-rs/jieba";
8
+ import { dict } from "@node-rs/jieba/dict";
8
9
  import { Fragment, jsx, jsxs } from "@satorijs/element/jsx-runtime";
9
10
  import { resolve as resolve$1 } from "node:path";
10
11
  import { pathToFileURL } from "node:url";
@@ -115,6 +116,7 @@ const BAConfigSchema = Schema.object({
115
116
  live: Schema.object({}).description("直播推送设置"),
116
117
  liveDetectType: Schema.union([Schema.const("WS").description("使用WebSocket连接到B站消息服务器进行直播检测,推荐使用"), Schema.const("API").description("通过轮询API发送请求监测直播状态,此模式理论可无限订阅,但容易产生其他问题,功能没有WS模式全面").experimental()]).role("radio").default("WS").description("直播检测方式,WS为连接到B站消息服务器,API为通过轮询发送请求监测,默认使用WS检测"),
117
118
  wordcloud: Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云"),
119
+ liveSummary: Schema.string().default("🔍【弹幕情报站】本场直播数据如下:\\n🧍‍♂️ 总共 -dmc 位特工上线\\n💬 共计 -dca 条弹幕飞驰而过\\n📊 热词云图已生成,快来看看你有没有上榜!\\n\\n👑 本场顶级输出选手:\\n🥇 -un1 - 弹幕输出 -dc1 条\\n🥈 -un2 - 弹幕 -dc2 条,萌力惊人\\n🥉 -un3 - -dc3 条精准狙击\\n\\n🎖️ 特别嘉奖:-un4 & -un5\\n你们的弹幕,我们都记录在案!🕵️‍♀️").description("自定义直播总结语,开启弹幕词云自动发送。变量解释:-dmc代表总弹幕发送人数,-dca代表总弹幕数,-un1到-un5代表弹幕发送条数前五名用户的用户名,-dc1到-dc5代表弹幕发送条数前五名的弹幕发送数量"),
118
120
  restartPush: Schema.boolean().default(true).description("插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启"),
119
121
  pushTime: Schema.number().min(0).max(12).step(.5).default(1).description("设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时"),
120
122
  customLiveStart: Schema.string().default("-name开播啦,当前粉丝数:-follower\\n-link").description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name开播啦,会发送为xxxUP开播啦"),
@@ -617,7 +619,142 @@ const PushTypeMsg = {
617
619
  };
618
620
 
619
621
  //#endregion
620
- //#region src/comRegister.tsx
622
+ //#region src/stop_words.ts
623
+ const stopwords = new Set([
624
+ ",",
625
+ "。",
626
+ "!",
627
+ "?",
628
+ ":",
629
+ ";",
630
+ "“",
631
+ "”",
632
+ "‘",
633
+ "’",
634
+ "(",
635
+ ")",
636
+ "、",
637
+ "……",
638
+ "——",
639
+ "-",
640
+ "_",
641
+ ".",
642
+ ",",
643
+ "(",
644
+ ")",
645
+ "【",
646
+ "】",
647
+ "而且",
648
+ "但是",
649
+ "如果",
650
+ "虽然",
651
+ "因为",
652
+ "所以",
653
+ "但是",
654
+ "那么",
655
+ "那么就",
656
+ "今天",
657
+ "昨天",
658
+ "后天",
659
+ "明天",
660
+ "现在",
661
+ "刚刚",
662
+ "刚才",
663
+ "一直",
664
+ "一直在",
665
+ "目前",
666
+ "以前",
667
+ "以后",
668
+ "以前的",
669
+ "the",
670
+ "and",
671
+ "to",
672
+ "of",
673
+ "a",
674
+ "is",
675
+ "in",
676
+ "on",
677
+ "for",
678
+ "with",
679
+ "this",
680
+ "that",
681
+ "you",
682
+ "觉得",
683
+ "表示",
684
+ "发现",
685
+ "认为",
686
+ "看到",
687
+ "听说",
688
+ "了解",
689
+ "知道",
690
+ "说明",
691
+ "指出",
692
+ "讨论",
693
+ "讨论一下",
694
+ "看看",
695
+ "想想",
696
+ "说说",
697
+ "讲讲",
698
+ "一个",
699
+ "一些",
700
+ "这个",
701
+ "那个",
702
+ "每个",
703
+ "什么",
704
+ "东西",
705
+ "事情",
706
+ "这些",
707
+ "那些",
708
+ "这种",
709
+ "那种",
710
+ "怎么说",
711
+ "怎么会",
712
+ "怎么可能",
713
+ "不可能",
714
+ "有点像",
715
+ "真的很",
716
+ "特别是",
717
+ "有时候",
718
+ "每次都",
719
+ "一点点",
720
+ "哪里有",
721
+ "太离谱",
722
+ "太搞笑",
723
+ "太真实",
724
+ "为了",
725
+ "因为",
726
+ "所以",
727
+ "但是",
728
+ "而且",
729
+ "然后",
730
+ "如果",
731
+ "虽然",
732
+ "然而",
733
+ "不过",
734
+ "并且",
735
+ "即使",
736
+ "由于",
737
+ "那么",
738
+ "除非",
739
+ "比如",
740
+ "比如说",
741
+ "现在",
742
+ "刚刚",
743
+ "刚才",
744
+ "以前",
745
+ "以后",
746
+ "一直",
747
+ "从来",
748
+ "目前",
749
+ "最近",
750
+ "已经",
751
+ "后来",
752
+ "之前",
753
+ "某天"
754
+ ]);
755
+
756
+ //#endregion
757
+ //#region src/command_register.tsx
621
758
  var import_lib$1 = __toESM$1(require_lib$3());
622
759
  var ComRegister = class {
623
760
  static inject = [
@@ -650,7 +787,7 @@ var ComRegister = class {
650
787
  privateBot;
651
788
  dynamicJob;
652
789
  liveJob;
653
- _segmentit = useDefault(new Segment());
790
+ _jieba = Jieba.withDict(dict);
654
791
  constructor(ctx, config) {
655
792
  this.ctx = ctx;
656
793
  this.init(config);
@@ -801,58 +938,107 @@ var ComRegister = class {
801
938
  });
802
939
  biliCom.subcommand(".wc").action(async ({ session }) => {
803
940
  const words = [
804
- ["弹幕护体", 77],
805
- ["笑死", 30],
806
- ["泪目", 45],
807
- ["加油", 70],
808
- ["???", 80],
809
- ["我可以", 66],
810
- ["无语", 55],
811
- ["梦开始的地方", 1],
812
- ["太真实了", 8],
813
- ["我哭死", 1],
814
- ["人呢", 2],
815
- ["有点意思", 4],
816
- ["妙啊", 4],
817
- ["这波啊", 11],
818
- ["懂了", 6],
819
- ["破防了", 65],
820
- ["蚌埠住了", 92],
821
- ["", 100],
822
- ["针不戳", 68],
823
- ["yyds", 50],
824
- ["DNA动了", 58],
825
- ["猝不及防", 40],
826
- ["建议加精", 15],
827
- ["保护", 22],
828
- ["害怕", 18],
829
- ["就这?", 99],
830
- ["2333", 20],
831
- ["公开处刑", 35],
832
- ["血压上来了", 45],
833
- ["整不会了", 32],
834
- ["见证历史", 88],
835
- ["下次一定", 65],
836
- ["奥利给", 56],
837
- ["求更新", 18],
838
- ["真实", 20],
839
- ["好活当赏", 25],
840
- ["泪,冲了出来", 68],
841
- ["刻进DNA", 70],
842
- ["我直接好家伙", 55],
843
- ["夺笋啊", 40],
844
- ["歪歪滴艾斯", 1],
845
- ["典中典", 5],
846
- ["麻中麻", 3],
847
- ["绷不住了", 8],
848
- ["逆天", 95],
849
- ["", 65],
850
- ["", 20],
851
- ["", 101],
852
- ["急急急", 3],
853
- ["", 5]
941
+ ["摆烂", 60],
942
+ ["可以", 42],
943
+ ["可以", 42],
944
+ ["可以", 42],
945
+ ["dog", 40],
946
+ ["dog", 40],
947
+ ["不是", 37],
948
+ ["不是", 37],
949
+ ["就是", 27],
950
+ ["就是", 27],
951
+ ["吃瓜", 16],
952
+ ["吃瓜", 16],
953
+ ["吃瓜", 16],
954
+ ["cj", 8],
955
+ ["cj", 8],
956
+ ["cj", 8],
957
+ ["没有", 8],
958
+ ["没有", 8],
959
+ ["没有", 8],
960
+ ["有点", 8],
961
+ ["有点", 8],
962
+ ["喜欢", 7],
963
+ ["喜欢", 7],
964
+ ["空调", 7],
965
+ ["空调", 7],
966
+ ["空调", 7],
967
+ ["感觉", 7],
968
+ ["感觉", 7],
969
+ ["感觉", 7],
970
+ ["时候", 6],
971
+ ["时候", 6],
972
+ ["怎么", 6],
973
+ ["怎么", 6],
974
+ ["痛车", 6],
975
+ ["痛车", 6],
976
+ ["一下", 6],
977
+ ["一下", 6],
978
+ ["还是", 6],
979
+ ["还是", 6],
980
+ ["麻麻", 6],
981
+ ["麻麻", 6],
982
+ ["下午", 5],
983
+ ["下午", 5],
984
+ ["开始", 5],
985
+ ["开始", 5],
986
+ ["一部", 5],
987
+ ["一部", 5],
988
+ ["这样", 5],
989
+ ["这样", 5],
990
+ ["上次", 5],
991
+ ["上次", 5],
992
+ ["游戏", 5],
993
+ ["游戏", 5],
994
+ ["这边", 5],
995
+ ["这边", 5],
996
+ ["问号", 5],
997
+ ["问号", 5],
998
+ ["好看", 5],
999
+ ["好看", 5],
1000
+ ["哈哈哈", 5],
1001
+ ["哈哈哈", 5],
1002
+ ["角色", 5],
1003
+ ["角色", 5],
1004
+ ["味道", 5],
1005
+ ["味道", 5],
1006
+ ["233333", 4],
1007
+ ["233333", 4],
1008
+ ["老规矩", 4],
1009
+ ["老规矩", 4],
1010
+ ["鸣潮", 4],
1011
+ ["鸣潮", 4],
1012
+ ["养生", 4],
1013
+ ["养生", 4],
1014
+ ["划掉", 4],
1015
+ ["划掉", 4],
1016
+ ["排队", 4],
1017
+ ["排队", 4],
1018
+ ["cos", 4],
1019
+ ["cos", 4],
1020
+ ["的话", 4],
1021
+ ["的话", 4],
1022
+ ["我们", 4],
1023
+ ["主要", 4],
1024
+ ["www", 4],
1025
+ ["直接", 4],
1026
+ ["不好", 4],
1027
+ ["学校", 4],
1028
+ ["一样", 4],
1029
+ ["初中", 4],
1030
+ ["毕业", 4]
854
1031
  ];
855
1032
  await session.send(/* @__PURE__ */ jsx("message", { children: h.image(await this.ctx.gi.generateWordCloudImg(words, "词云测试"), "image/jpg") }));
1033
+ const top5DanmakuMaker = [
1034
+ ["张三", 60],
1035
+ ["李四", 48],
1036
+ ["王五", 45],
1037
+ ["赵六", 27],
1038
+ ["田七", 25]
1039
+ ];
1040
+ const danmakerRankMsg = this.config.liveSummary.replace("-dmc", "114").replace("-dca", "514").replace("-un1", `${top5DanmakuMaker[0][0]}`).replace("-dc1", `${top5DanmakuMaker[0][1]}`).replace("-un2", `${top5DanmakuMaker[1][0]}`).replace("-dc2", `${top5DanmakuMaker[1][1]}`).replace("-un3", `${top5DanmakuMaker[2][0]}`).replace("-dc3", `${top5DanmakuMaker[2][1]}`).replace("-un4", `${top5DanmakuMaker[3][0]}`).replace("-dc4", `${top5DanmakuMaker[3][1]}`).replace("-un5", `${top5DanmakuMaker[4][0]}`).replace("-dc5", `${top5DanmakuMaker[4][1]}`).replaceAll("\\n", "\n");
1041
+ await session.send(danmakerRankMsg);
856
1042
  });
857
1043
  }
858
1044
  async init(config) {
@@ -983,7 +1169,7 @@ var ComRegister = class {
983
1169
  }
984
1170
  async broadcastToTargets(uid, content, type, retry = 3e3) {
985
1171
  if (!this.checkAllBotsAreReady()) {
986
- this.logger.error(`有机器人未准备好,无法进行推送,${retry / 1e3}秒后重试`);
1172
+ this.logger.error(`存在机器人未初始化完毕,无法进行推送,${retry / 1e3}秒后重试`);
987
1173
  this.ctx.setTimeout(() => {
988
1174
  this.broadcastToTargets(uid, content, type, retry * 2);
989
1175
  }, retry);
@@ -998,7 +1184,7 @@ var ComRegister = class {
998
1184
  const success = await withRetry(async () => {
999
1185
  return await this.ctx.broadcast(atAllArr, /* @__PURE__ */ jsx("message", { children: /* @__PURE__ */ jsx("at", { type: "all" }) }));
1000
1186
  }, 1);
1001
- this.logger.info(`成功推送全体成员消息群组/频道:${success}`);
1187
+ this.logger.info(`成功推送全体成员消息:${success.length}条`);
1002
1188
  }
1003
1189
  if (type === PushType.Dynamic && record.dynamicArr?.length >= 1) {
1004
1190
  this.logger.info(record.dynamicArr);
@@ -1006,7 +1192,7 @@ var ComRegister = class {
1006
1192
  const success = await withRetry(async () => {
1007
1193
  return await this.ctx.broadcast(dynamicArr, /* @__PURE__ */ jsx("message", { children: content }));
1008
1194
  }, 1);
1009
- this.logger.info(`成功推送动态消息群组/频道:${success}`);
1195
+ this.logger.info(`成功推送动态消息:${success.length}条`);
1010
1196
  }
1011
1197
  if ((type === PushType.Live || type === PushType.StartBroadcasting) && record.liveArr?.length >= 1) {
1012
1198
  this.logger.info(record.liveArr);
@@ -1014,7 +1200,7 @@ var ComRegister = class {
1014
1200
  const success = await withRetry(async () => {
1015
1201
  return await this.ctx.broadcast(liveArr, /* @__PURE__ */ jsx("message", { children: content }));
1016
1202
  }, 1);
1017
- this.logger.info(`成功推送直播消息群组/频道:${success}`);
1203
+ this.logger.info(`成功推送直播消息:${success.length}条`);
1018
1204
  }
1019
1205
  if (type === PushType.LiveGuardBuy && record.liveGuardBuyArr?.length >= 1) {
1020
1206
  this.logger.info(record.liveGuardBuyArr);
@@ -1022,7 +1208,7 @@ var ComRegister = class {
1022
1208
  const success = await withRetry(async () => {
1023
1209
  return await this.ctx.broadcast(liveGuardBuyArr, /* @__PURE__ */ jsx("message", { children: content }));
1024
1210
  }, 1);
1025
- this.logger.info(`成功推送上舰消息群组/频道:${success}`);
1211
+ this.logger.info(`成功推送上舰消息:${success.length}条`);
1026
1212
  }
1027
1213
  return;
1028
1214
  }
@@ -1282,15 +1468,18 @@ var ComRegister = class {
1282
1468
  return await this.broadcastToTargets(uid, msg, liveType === LiveType.StartBroadcasting ? PushType.StartBroadcasting : PushType.Live);
1283
1469
  }
1284
1470
  async segmentDanmaku(danmaku, danmakuWeightRecord) {
1285
- this._segmentit.doSegment(danmaku).map(({ w: w$3, p: p$1 }) => {
1286
- if (p$1 && p$1 === 2048) return;
1471
+ this._jieba.cut(danmaku, true).filter((word) => word.length >= 2 && !stopwords.has(word)).map((w$3) => {
1287
1472
  danmakuWeightRecord[w$3] = (danmakuWeightRecord[w$3] || 0) + 1;
1288
1473
  });
1289
1474
  }
1475
+ addUserToDanmakuMaker(username, danmakuMakerRecord) {
1476
+ danmakuMakerRecord[username] = (danmakuMakerRecord[username] || 0) + 1;
1477
+ }
1290
1478
  async liveDetectWithListener(roomId, uid, cardStyle) {
1291
1479
  let liveTime;
1292
1480
  let pushAtTimeTimer;
1293
1481
  const danmakuWeightRecord = {};
1482
+ const danmakuMakerRecord = {};
1294
1483
  let liveStatus = false;
1295
1484
  let liveRoomInfo;
1296
1485
  let masterInfo;
@@ -1298,14 +1487,23 @@ var ComRegister = class {
1298
1487
  const liveMsgObj = this.liveMsgManager.get(uid);
1299
1488
  const sendDanmakuWordCloud = async () => {
1300
1489
  this.logger.info("开始制作弹幕词云");
1301
- this.logger.info("正在获取前50热词");
1302
- const top50Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 50);
1303
- this.logger.info("弹幕词云前50词及权重:");
1304
- this.logger.info(top50Words);
1490
+ this.logger.info("正在获取前90热词");
1491
+ const top90Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 90).map(([word, weight]) => [word, weight > 60 ? 60 : weight]);
1492
+ this.logger.info("弹幕词云前90词及权重:");
1493
+ this.logger.info(top90Words);
1305
1494
  this.logger.info("正在准备生成弹幕词云");
1306
- const buffer = await this.ctx.gi.generateWordCloudImg(top50Words, masterInfo.username);
1495
+ const buffer = await this.ctx.gi.generateWordCloudImg(top90Words, masterInfo.username);
1307
1496
  this.logger.info("弹幕词云生成完成,正在准备发送词云图片");
1308
1497
  await this.broadcastToTargets(uid, h.image(buffer, "image/jpeg"), PushType.Live);
1498
+ this.logger.info("词云图片发送完毕!");
1499
+ this.logger.info("开始构建弹幕发送排行榜消息");
1500
+ const danmakuMakerCount = Object.keys(danmakuMakerRecord).length;
1501
+ const danmakuCount = Object.values(danmakuMakerRecord).reduce((sum, val) => sum + val, 0);
1502
+ const top5DanmakuMaker = Object.entries(danmakuMakerRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 5);
1503
+ const danmakuMakerMsg = this.config.liveSummary.replace("-dmc", `${danmakuMakerCount}`).replace("-dca", `${danmakuCount}`).replace("-un1", `${top5DanmakuMaker[0][0]}`).replace("-dc1", `${top5DanmakuMaker[0][1]}`).replace("-un2", `${top5DanmakuMaker[1][0]}`).replace("-dc2", `${top5DanmakuMaker[1][1]}`).replace("-un3", `${top5DanmakuMaker[2][0]}`).replace("-dc3", `${top5DanmakuMaker[2][1]}`).replace("-un4", `${top5DanmakuMaker[3][0]}`).replace("-dc4", `${top5DanmakuMaker[3][1]}`).replace("-un5", `${top5DanmakuMaker[4][0]}`).replace("-dc5", `${top5DanmakuMaker[4][1]}`).replaceAll("\\n", "\n");
1504
+ await this.broadcastToTargets(uid, danmakuMakerMsg, PushType.Live);
1505
+ Object.keys(danmakuWeightRecord).forEach((key) => delete danmakuWeightRecord[key]);
1506
+ Object.keys(danmakuMakerRecord).forEach((key) => delete danmakuMakerRecord[key]);
1309
1507
  };
1310
1508
  const pushAtTimeFunc = async () => {
1311
1509
  if (!await useMasterAndLiveRoomInfo(LiveType.LiveBroadcast)) {
@@ -1353,9 +1551,11 @@ var ComRegister = class {
1353
1551
  },
1354
1552
  onIncomeDanmu: ({ body }) => {
1355
1553
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1554
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1356
1555
  },
1357
1556
  onIncomeSuperChat: ({ body }) => {
1358
1557
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1558
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1359
1559
  },
1360
1560
  onWatchedChange: ({ body }) => {
1361
1561
  watchedNum = body.text_small;
@@ -1831,6 +2031,7 @@ var ComRegister = class {
1831
2031
  }),
1832
2032
  liveDetectType: Schema.string(),
1833
2033
  wordcloud: Schema.boolean(),
2034
+ liveSummary: Schema.string(),
1834
2035
  restartPush: Schema.boolean().required(),
1835
2036
  pushTime: Schema.number().required(),
1836
2037
  pushImgsInDynamic: Schema.boolean().required(),
@@ -1850,7 +2051,7 @@ var ComRegister = class {
1850
2051
  dynamicDebugMode: Schema.boolean().required()
1851
2052
  });
1852
2053
  })(ComRegister || (ComRegister = {}));
1853
- var comRegister_default = ComRegister;
2054
+ var command_register_default = ComRegister;
1854
2055
 
1855
2056
  //#endregion
1856
2057
  //#region src/database.ts
@@ -93104,7 +93305,7 @@ var require_lib = __commonJS$1({ "node_modules/koishi-plugin-puppeteer/lib/index
93104
93305
  } });
93105
93306
 
93106
93307
  //#endregion
93107
- //#region src/generateImg.ts
93308
+ //#region src/generate_img.ts
93108
93309
  var import_lib = __toESM$1(require_lib());
93109
93310
  const DYNAMIC_TYPE_NONE = "DYNAMIC_TYPE_NONE";
93110
93311
  const DYNAMIC_TYPE_FORWARD = "DYNAMIC_TYPE_FORWARD";
@@ -94488,10 +94689,10 @@ var GenerateImg = class extends Service {
94488
94689
  const words = ${JSON.stringify(words)}
94489
94690
 
94490
94691
  renderAutoFitWordCloud(canvas, words, {
94491
- maxFontSize: 40,
94692
+ maxFontSize: 60,
94492
94693
  minFontSize: 12,
94493
94694
  densityTarget: 0.3,
94494
- weightExponent: 0.5
94695
+ weightExponent: 0.4
94495
94696
  });
94496
94697
  </script>
94497
94698
  </body>
@@ -94592,7 +94793,7 @@ var GenerateImg = class extends Service {
94592
94793
  followerDisplay: Schema.boolean()
94593
94794
  });
94594
94795
  })(GenerateImg || (GenerateImg = {}));
94595
- var generateImg_default = GenerateImg;
94796
+ var generate_img_default = GenerateImg;
94596
94797
 
94597
94798
  //#endregion
94598
94799
  //#region node_modules/@oxc-project/runtime/src/helpers/decorate.js
@@ -94607,7 +94808,7 @@ var require_decorate = __commonJS$1({ "node_modules/@oxc-project/runtime/src/hel
94607
94808
  } });
94608
94809
 
94609
94810
  //#endregion
94610
- //#region src/biliAPI.ts
94811
+ //#region src/bili_api.ts
94611
94812
  var import_decorate = __toESM$1(require_decorate());
94612
94813
  const mixinKeyEncTab = [
94613
94814
  46,
@@ -95300,10 +95501,10 @@ var BiliAPI = class extends Service {
95300
95501
  key: Schema.string().pattern(/^[0-9a-f]{32}$/).required()
95301
95502
  });
95302
95503
  })(BiliAPI || (BiliAPI = {}));
95303
- var biliAPI_default = BiliAPI;
95504
+ var bili_api_default = BiliAPI;
95304
95505
 
95305
95506
  //#endregion
95306
- //#region src/blive.ts
95507
+ //#region src/bili_live.ts
95307
95508
  var BLive = class extends Service {
95308
95509
  static inject = ["ba"];
95309
95510
  listenerRecord = {};
@@ -95333,7 +95534,7 @@ var BLive = class extends Service {
95333
95534
  this.logger.warn(`${roomId}直播间连接未成功关闭`);
95334
95535
  }
95335
95536
  };
95336
- var blive_default = BLive;
95537
+ var bili_live_default = BLive;
95337
95538
 
95338
95539
  //#endregion
95339
95540
  //#region src/index.ts
@@ -95375,11 +95576,11 @@ var ServerManager = class extends Service {
95375
95576
  registerPlugin = () => {
95376
95577
  if (this.servers.length !== 0) return false;
95377
95578
  try {
95378
- const ba = this.ctx.plugin(biliAPI_default, {
95579
+ const ba = this.ctx.plugin(bili_api_default, {
95379
95580
  userAgent: globalConfig.userAgent,
95380
95581
  key: globalConfig.key
95381
95582
  });
95382
- const gi = this.ctx.plugin(generateImg_default, {
95583
+ const gi = this.ctx.plugin(generate_img_default, {
95383
95584
  filter: globalConfig.filter,
95384
95585
  removeBorder: globalConfig.removeBorder,
95385
95586
  cardColorStart: globalConfig.cardColorStart,
@@ -95391,10 +95592,11 @@ var ServerManager = class extends Service {
95391
95592
  font: globalConfig.font,
95392
95593
  followerDisplay: globalConfig.followerDisplay
95393
95594
  });
95394
- const cr = this.ctx.plugin(comRegister_default, {
95595
+ const cr = this.ctx.plugin(command_register_default, {
95395
95596
  sub: globalConfig.sub,
95396
95597
  master: globalConfig.master,
95397
95598
  wordcloud: globalConfig.wordcloud,
95599
+ liveSummary: globalConfig.liveSummary,
95398
95600
  liveDetectType: globalConfig.liveDetectType,
95399
95601
  restartPush: globalConfig.restartPush,
95400
95602
  pushTime: globalConfig.pushTime,
@@ -95408,7 +95610,7 @@ var ServerManager = class extends Service {
95408
95610
  filter: globalConfig.filter,
95409
95611
  dynamicDebugMode: globalConfig.dynamicDebugMode
95410
95612
  });
95411
- const bl = this.ctx.plugin(blive_default);
95613
+ const bl = this.ctx.plugin(bili_live_default);
95412
95614
  this.servers.push(ba);
95413
95615
  this.servers.push(bl);
95414
95616
  this.servers.push(gi);
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.2.9-rc.1",
4
+ "version": "3.2.9-rc.3",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@akokko/blive-message-listener": "^0.5.1",
39
+ "@node-rs/jieba": "^2.0.1",
39
40
  "@satorijs/element": "^3.1.8",
40
41
  "axios": "^1.10.0",
41
42
  "axios-cookiejar-support": "^6.0.2",
@@ -45,7 +46,6 @@
45
46
  "luxon": "^3.6.1",
46
47
  "md5": "^2.3.0",
47
48
  "qrcode": "^1.5.4",
48
- "segmentit": "^2.0.3",
49
49
  "tough-cookie": "^5.1.2"
50
50
  },
51
51
  "devDependencies": {
package/readme.md CHANGED
@@ -5,7 +5,6 @@
5
5
  ---
6
6
 
7
7
  - koishi-plugin-bilibili-notify [![npm](https://img.shields.io/npm/v/koishi-plugin-bilibili-notify?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-bilibili-notify)
8
- - [重要通知](#重要通知)
9
8
  - [重新订阅](#重新订阅)
10
9
  - [功能](#功能)
11
10
  - [注意事项](#注意事项)
@@ -16,10 +15,6 @@
16
15
  - [感谢](#感谢)
17
16
  - [License](#License)
18
17
 
19
- ## 重要通知
20
- > [!WARNING]
21
- > `3.2.5-alpha.x` 目前均为测试版本,请不要更新🙅
22
-
23
18
  ## 重新订阅
24
19
  > [!NOTE]
25
20
  >由于版本 `2.0.0-alpha.7` 重构了订阅功能,从 `2.0.0-alpha.7` 以前版本升级到以后版本的需重新订阅
@@ -305,8 +300,12 @@ uid为必填参数,为要推送的UP主的UID,index为可选参数,为要
305
300
  > - ver 3.2.9-alpha.2 修复:`AxiosError: Request failed with status code 404 xxx at async BiliAPI.checkIfTokenNeedRefresh`、潜在cookie相关bug、弹幕词云bug `Error: 生成图片失败!错误: TimeoutError: Navigation timeout of 30000 ms exceeded`
306
301
  > - ver 3.2.9-alpha.3 修复:词云生成空白
307
302
  > - ver 3.2.9-alpha.4 修复:弹幕词云bug `Error: 生成图片失败!错误: TimeoutError: Navigation timeout of 30000 ms exceeded`
303
+
304
+ > [!NOTE]
308
305
  > - ver 3.2.9-rc.0 优化:弹幕词云生成效果、选项 `pushTime` 设置为0时可关闭该功能; 新增:选项 `wordcloud` 可选择在直播结束后是否生成弹幕词云
309
306
  > - ver 3.2.9-rc.1 优化:弹幕词云生成效果;
307
+ > - ver 3.2.9-rc.2 优化:弹幕词云生成效果;
308
+ > - ver 3.2.9-rc.3 优化:弹幕词云生成效果; 新增:直播总结语,开启弹幕词云后自动发送、选项 `liveSummary` 可自定义直播总结语; 修复:一场直播完成后,如果插件中途没有被关闭过,会影响同一位up主下一次直播词云数据;
310
309
 
311
310
  ## 交流群
312
311