koishi-plugin-bilibili-notify 3.2.9-rc.2 → 3.2.9-rc.4

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
@@ -113,7 +113,8 @@ const BAConfigSchema = koishi.Schema.object({
113
113
  pushImgsInDynamic: koishi.Schema.boolean().default(false).description("是否推送动态中的图片,默认不开启。开启后会单独推送动态中的图片,该功能容易导致QQ风控"),
114
114
  live: koishi.Schema.object({}).description("直播推送设置"),
115
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检测"),
116
- wordcloud: koishi.Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云"),
116
+ wordcloud: koishi.Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云").experimental(),
117
+ liveSummary: koishi.Schema.string().default("🔍【弹幕情报站】本场直播数据如下:\\n🧍‍♂️ 总共 -dmc 位-mdn上线\\n💬 共计 -dca 条弹幕飞驰而过\\n📊 热词云图已生成,快来看看你有没有上榜!\\n\\n👑 本场顶级输出选手:\\n🥇 -un1 - 弹幕输出 -dc1 条\\n🥈 -un2 - 弹幕 -dc2 条,萌力惊人\\n🥉 -un3 - -dc3 条精准狙击\\n\\n🎖️ 特别嘉奖:-un4 & -un5\\n你们的弹幕,我们都记录在案!🕵️‍♀️").description("自定义直播总结语,开启弹幕词云自动发送。变量解释:-dmc代表总弹幕发送人数,-mdn代表主播粉丝牌子名,-dca代表总弹幕数,-un1到-un5代表弹幕发送条数前五名用户的用户名,-dc1到-dc5代表弹幕发送条数前五名的弹幕发送数量"),
117
118
  restartPush: koishi.Schema.boolean().default(true).description("插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启"),
118
119
  pushTime: koishi.Schema.number().min(0).max(12).step(.5).default(1).description("设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时"),
119
120
  customLiveStart: koishi.Schema.string().default("-name开播啦,当前粉丝数:-follower\\n-link").description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name开播啦,会发送为xxxUP开播啦"),
@@ -935,58 +936,107 @@ var ComRegister = class {
935
936
  });
936
937
  biliCom.subcommand(".wc").action(async ({ session }) => {
937
938
  const words = [
938
- ["弹幕护体", 77],
939
- ["笑死", 30],
940
- ["泪目", 45],
941
- ["加油", 70],
942
- ["???", 80],
943
- ["我可以", 66],
944
- ["无语", 55],
945
- ["梦开始的地方", 1],
946
- ["太真实了", 8],
947
- ["我哭死", 1],
948
- ["人呢", 2],
949
- ["有点意思", 4],
950
- ["妙啊", 4],
951
- ["这波啊", 11],
952
- ["懂了", 6],
953
- ["破防了", 65],
954
- ["蚌埠住了", 92],
955
- ["", 100],
956
- ["针不戳", 68],
957
- ["yyds", 50],
958
- ["DNA动了", 58],
959
- ["猝不及防", 40],
960
- ["建议加精", 15],
961
- ["保护", 22],
962
- ["害怕", 18],
963
- ["就这?", 99],
964
- ["2333", 20],
965
- ["公开处刑", 35],
966
- ["血压上来了", 45],
967
- ["整不会了", 32],
968
- ["见证历史", 88],
969
- ["下次一定", 65],
970
- ["奥利给", 56],
971
- ["求更新", 18],
972
- ["真实", 20],
973
- ["好活当赏", 25],
974
- ["泪,冲了出来", 68],
975
- ["刻进DNA", 70],
976
- ["我直接好家伙", 55],
977
- ["夺笋啊", 40],
978
- ["歪歪滴艾斯", 1],
979
- ["典中典", 5],
980
- ["麻中麻", 3],
981
- ["绷不住了", 8],
982
- ["逆天", 95],
983
- ["", 65],
984
- ["", 20],
985
- ["", 101],
986
- ["急急急", 3],
987
- ["", 5]
939
+ ["摆烂", 91],
940
+ ["可以", 82],
941
+ ["可以", 72],
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]
988
1029
  ];
989
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("-mdn", "特工").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);
990
1040
  });
991
1041
  }
992
1042
  async init(config) {
@@ -1394,7 +1444,8 @@ var ComRegister = class {
1394
1444
  roomId: data$1.room_id,
1395
1445
  liveOpenFollowerNum,
1396
1446
  liveEndFollowerNum,
1397
- liveFollowerChange
1447
+ liveFollowerChange,
1448
+ medalName: data$1.medal_name
1398
1449
  };
1399
1450
  }
1400
1451
  async useLiveRoomInfo(roomId) {
@@ -1420,10 +1471,14 @@ var ComRegister = class {
1420
1471
  danmakuWeightRecord[w$3] = (danmakuWeightRecord[w$3] || 0) + 1;
1421
1472
  });
1422
1473
  }
1474
+ addUserToDanmakuMaker(username, danmakuMakerRecord) {
1475
+ danmakuMakerRecord[username] = (danmakuMakerRecord[username] || 0) + 1;
1476
+ }
1423
1477
  async liveDetectWithListener(roomId, uid, cardStyle) {
1424
1478
  let liveTime;
1425
1479
  let pushAtTimeTimer;
1426
1480
  const danmakuWeightRecord = {};
1481
+ const danmakuMakerRecord = {};
1427
1482
  let liveStatus = false;
1428
1483
  let liveRoomInfo;
1429
1484
  let masterInfo;
@@ -1431,14 +1486,23 @@ var ComRegister = class {
1431
1486
  const liveMsgObj = this.liveMsgManager.get(uid);
1432
1487
  const sendDanmakuWordCloud = async () => {
1433
1488
  this.logger.info("开始制作弹幕词云");
1434
- this.logger.info("正在获取前50热词");
1435
- const top50Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 50);
1436
- this.logger.info("弹幕词云前50词及权重:");
1437
- this.logger.info(top50Words);
1489
+ this.logger.info("正在获取前90热词");
1490
+ const top90Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 90);
1491
+ this.logger.info("弹幕词云前90词及权重:");
1492
+ this.logger.info(top90Words);
1438
1493
  this.logger.info("正在准备生成弹幕词云");
1439
- const buffer = await this.ctx.gi.generateWordCloudImg(top50Words, masterInfo.username);
1494
+ const buffer = await this.ctx.gi.generateWordCloudImg(top90Words, masterInfo.username);
1440
1495
  this.logger.info("弹幕词云生成完成,正在准备发送词云图片");
1441
1496
  await this.broadcastToTargets(uid, koishi.h.image(buffer, "image/jpeg"), PushType.Live);
1497
+ this.logger.info("词云图片发送完毕!");
1498
+ this.logger.info("开始构建弹幕发送排行榜消息");
1499
+ const danmakuMakerCount = Object.keys(danmakuMakerRecord).length;
1500
+ const danmakuCount = Object.values(danmakuMakerRecord).reduce((sum, val) => sum + val, 0);
1501
+ const top5DanmakuMaker = Object.entries(danmakuMakerRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 5);
1502
+ const danmakuMakerMsg = this.config.liveSummary.replace("-dmc", `${danmakuMakerCount}`).replace("-mdn", `${masterInfo.medalName}`).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");
1503
+ await this.broadcastToTargets(uid, danmakuMakerMsg, PushType.Live);
1504
+ Object.keys(danmakuWeightRecord).forEach((key) => delete danmakuWeightRecord[key]);
1505
+ Object.keys(danmakuMakerRecord).forEach((key) => delete danmakuMakerRecord[key]);
1442
1506
  };
1443
1507
  const pushAtTimeFunc = async () => {
1444
1508
  if (!await useMasterAndLiveRoomInfo(LiveType.LiveBroadcast)) {
@@ -1486,9 +1550,11 @@ var ComRegister = class {
1486
1550
  },
1487
1551
  onIncomeDanmu: ({ body }) => {
1488
1552
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1553
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1489
1554
  },
1490
1555
  onIncomeSuperChat: ({ body }) => {
1491
1556
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1557
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1492
1558
  },
1493
1559
  onWatchedChange: ({ body }) => {
1494
1560
  watchedNum = body.text_small;
@@ -1964,6 +2030,7 @@ var ComRegister = class {
1964
2030
  }),
1965
2031
  liveDetectType: koishi.Schema.string(),
1966
2032
  wordcloud: koishi.Schema.boolean(),
2033
+ liveSummary: koishi.Schema.string(),
1967
2034
  restartPush: koishi.Schema.boolean().required(),
1968
2035
  pushTime: koishi.Schema.number().required(),
1969
2036
  pushImgsInDynamic: koishi.Schema.boolean().required(),
@@ -94621,10 +94688,10 @@ var GenerateImg = class extends koishi.Service {
94621
94688
  const words = ${JSON.stringify(words)}
94622
94689
 
94623
94690
  renderAutoFitWordCloud(canvas, words, {
94624
- maxFontSize: 40,
94691
+ maxFontSize: 60,
94625
94692
  minFontSize: 12,
94626
94693
  densityTarget: 0.3,
94627
- weightExponent: 0.5
94694
+ weightExponent: 0.4
94628
94695
  });
94629
94696
  </script>
94630
94697
  </body>
@@ -95528,6 +95595,7 @@ var ServerManager = class extends koishi.Service {
95528
95595
  sub: globalConfig.sub,
95529
95596
  master: globalConfig.master,
95530
95597
  wordcloud: globalConfig.wordcloud,
95598
+ liveSummary: globalConfig.liveSummary,
95531
95599
  liveDetectType: globalConfig.liveDetectType,
95532
95600
  restartPush: globalConfig.restartPush,
95533
95601
  pushTime: globalConfig.pushTime,
package/lib/index.mjs CHANGED
@@ -115,7 +115,8 @@ const BAConfigSchema = Schema.object({
115
115
  pushImgsInDynamic: Schema.boolean().default(false).description("是否推送动态中的图片,默认不开启。开启后会单独推送动态中的图片,该功能容易导致QQ风控"),
116
116
  live: Schema.object({}).description("直播推送设置"),
117
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检测"),
118
- wordcloud: Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云"),
118
+ wordcloud: Schema.boolean().default(false).description("直播结束后,是否生成本场直播弹幕词云").experimental(),
119
+ liveSummary: Schema.string().default("🔍【弹幕情报站】本场直播数据如下:\\n🧍‍♂️ 总共 -dmc 位-mdn上线\\n💬 共计 -dca 条弹幕飞驰而过\\n📊 热词云图已生成,快来看看你有没有上榜!\\n\\n👑 本场顶级输出选手:\\n🥇 -un1 - 弹幕输出 -dc1 条\\n🥈 -un2 - 弹幕 -dc2 条,萌力惊人\\n🥉 -un3 - -dc3 条精准狙击\\n\\n🎖️ 特别嘉奖:-un4 & -un5\\n你们的弹幕,我们都记录在案!🕵️‍♀️").description("自定义直播总结语,开启弹幕词云自动发送。变量解释:-dmc代表总弹幕发送人数,-mdn代表主播粉丝牌子名,-dca代表总弹幕数,-un1到-un5代表弹幕发送条数前五名用户的用户名,-dc1到-dc5代表弹幕发送条数前五名的弹幕发送数量"),
119
120
  restartPush: Schema.boolean().default(true).description("插件重启后,如果订阅的主播正在直播,是否进行一次推送,默认开启"),
120
121
  pushTime: Schema.number().min(0).max(12).step(.5).default(1).description("设定间隔多长时间推送一次直播状态,单位为小时,默认为一小时"),
121
122
  customLiveStart: Schema.string().default("-name开播啦,当前粉丝数:-follower\\n-link").description("自定义开播提示语,-name代表UP昵称,-follower代表当前粉丝数,-link代表直播间链接(如果使用的是QQ官方机器人,请不要使用),\\n为换行。例如-name开播啦,会发送为xxxUP开播啦"),
@@ -937,58 +938,107 @@ var ComRegister = class {
937
938
  });
938
939
  biliCom.subcommand(".wc").action(async ({ session }) => {
939
940
  const words = [
940
- ["弹幕护体", 77],
941
- ["笑死", 30],
942
- ["泪目", 45],
943
- ["加油", 70],
944
- ["???", 80],
945
- ["我可以", 66],
946
- ["无语", 55],
947
- ["梦开始的地方", 1],
948
- ["太真实了", 8],
949
- ["我哭死", 1],
950
- ["人呢", 2],
951
- ["有点意思", 4],
952
- ["妙啊", 4],
953
- ["这波啊", 11],
954
- ["懂了", 6],
955
- ["破防了", 65],
956
- ["蚌埠住了", 92],
957
- ["", 100],
958
- ["针不戳", 68],
959
- ["yyds", 50],
960
- ["DNA动了", 58],
961
- ["猝不及防", 40],
962
- ["建议加精", 15],
963
- ["保护", 22],
964
- ["害怕", 18],
965
- ["就这?", 99],
966
- ["2333", 20],
967
- ["公开处刑", 35],
968
- ["血压上来了", 45],
969
- ["整不会了", 32],
970
- ["见证历史", 88],
971
- ["下次一定", 65],
972
- ["奥利给", 56],
973
- ["求更新", 18],
974
- ["真实", 20],
975
- ["好活当赏", 25],
976
- ["泪,冲了出来", 68],
977
- ["刻进DNA", 70],
978
- ["我直接好家伙", 55],
979
- ["夺笋啊", 40],
980
- ["歪歪滴艾斯", 1],
981
- ["典中典", 5],
982
- ["麻中麻", 3],
983
- ["绷不住了", 8],
984
- ["逆天", 95],
985
- ["", 65],
986
- ["", 20],
987
- ["", 101],
988
- ["急急急", 3],
989
- ["", 5]
941
+ ["摆烂", 91],
942
+ ["可以", 82],
943
+ ["可以", 72],
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]
990
1031
  ];
991
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("-mdn", "特工").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);
992
1042
  });
993
1043
  }
994
1044
  async init(config) {
@@ -1396,7 +1446,8 @@ var ComRegister = class {
1396
1446
  roomId: data$1.room_id,
1397
1447
  liveOpenFollowerNum,
1398
1448
  liveEndFollowerNum,
1399
- liveFollowerChange
1449
+ liveFollowerChange,
1450
+ medalName: data$1.medal_name
1400
1451
  };
1401
1452
  }
1402
1453
  async useLiveRoomInfo(roomId) {
@@ -1422,10 +1473,14 @@ var ComRegister = class {
1422
1473
  danmakuWeightRecord[w$3] = (danmakuWeightRecord[w$3] || 0) + 1;
1423
1474
  });
1424
1475
  }
1476
+ addUserToDanmakuMaker(username, danmakuMakerRecord) {
1477
+ danmakuMakerRecord[username] = (danmakuMakerRecord[username] || 0) + 1;
1478
+ }
1425
1479
  async liveDetectWithListener(roomId, uid, cardStyle) {
1426
1480
  let liveTime;
1427
1481
  let pushAtTimeTimer;
1428
1482
  const danmakuWeightRecord = {};
1483
+ const danmakuMakerRecord = {};
1429
1484
  let liveStatus = false;
1430
1485
  let liveRoomInfo;
1431
1486
  let masterInfo;
@@ -1433,14 +1488,23 @@ var ComRegister = class {
1433
1488
  const liveMsgObj = this.liveMsgManager.get(uid);
1434
1489
  const sendDanmakuWordCloud = async () => {
1435
1490
  this.logger.info("开始制作弹幕词云");
1436
- this.logger.info("正在获取前50热词");
1437
- const top50Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 50);
1438
- this.logger.info("弹幕词云前50词及权重:");
1439
- this.logger.info(top50Words);
1491
+ this.logger.info("正在获取前90热词");
1492
+ const top90Words = Object.entries(danmakuWeightRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 90);
1493
+ this.logger.info("弹幕词云前90词及权重:");
1494
+ this.logger.info(top90Words);
1440
1495
  this.logger.info("正在准备生成弹幕词云");
1441
- const buffer = await this.ctx.gi.generateWordCloudImg(top50Words, masterInfo.username);
1496
+ const buffer = await this.ctx.gi.generateWordCloudImg(top90Words, masterInfo.username);
1442
1497
  this.logger.info("弹幕词云生成完成,正在准备发送词云图片");
1443
1498
  await this.broadcastToTargets(uid, h.image(buffer, "image/jpeg"), PushType.Live);
1499
+ this.logger.info("词云图片发送完毕!");
1500
+ this.logger.info("开始构建弹幕发送排行榜消息");
1501
+ const danmakuMakerCount = Object.keys(danmakuMakerRecord).length;
1502
+ const danmakuCount = Object.values(danmakuMakerRecord).reduce((sum, val) => sum + val, 0);
1503
+ const top5DanmakuMaker = Object.entries(danmakuMakerRecord).sort((a$1, b$2) => b$2[1] - a$1[1]).slice(0, 5);
1504
+ const danmakuMakerMsg = this.config.liveSummary.replace("-dmc", `${danmakuMakerCount}`).replace("-mdn", `${masterInfo.medalName}`).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");
1505
+ await this.broadcastToTargets(uid, danmakuMakerMsg, PushType.Live);
1506
+ Object.keys(danmakuWeightRecord).forEach((key) => delete danmakuWeightRecord[key]);
1507
+ Object.keys(danmakuMakerRecord).forEach((key) => delete danmakuMakerRecord[key]);
1444
1508
  };
1445
1509
  const pushAtTimeFunc = async () => {
1446
1510
  if (!await useMasterAndLiveRoomInfo(LiveType.LiveBroadcast)) {
@@ -1488,9 +1552,11 @@ var ComRegister = class {
1488
1552
  },
1489
1553
  onIncomeDanmu: ({ body }) => {
1490
1554
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1555
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1491
1556
  },
1492
1557
  onIncomeSuperChat: ({ body }) => {
1493
1558
  this.segmentDanmaku(body.content, danmakuWeightRecord);
1559
+ this.addUserToDanmakuMaker(body.user.uname, danmakuMakerRecord);
1494
1560
  },
1495
1561
  onWatchedChange: ({ body }) => {
1496
1562
  watchedNum = body.text_small;
@@ -1966,6 +2032,7 @@ var ComRegister = class {
1966
2032
  }),
1967
2033
  liveDetectType: Schema.string(),
1968
2034
  wordcloud: Schema.boolean(),
2035
+ liveSummary: Schema.string(),
1969
2036
  restartPush: Schema.boolean().required(),
1970
2037
  pushTime: Schema.number().required(),
1971
2038
  pushImgsInDynamic: Schema.boolean().required(),
@@ -94623,10 +94690,10 @@ var GenerateImg = class extends Service {
94623
94690
  const words = ${JSON.stringify(words)}
94624
94691
 
94625
94692
  renderAutoFitWordCloud(canvas, words, {
94626
- maxFontSize: 40,
94693
+ maxFontSize: 60,
94627
94694
  minFontSize: 12,
94628
94695
  densityTarget: 0.3,
94629
- weightExponent: 0.5
94696
+ weightExponent: 0.4
94630
94697
  });
94631
94698
  </script>
94632
94699
  </body>
@@ -95530,6 +95597,7 @@ var ServerManager = class extends Service {
95530
95597
  sub: globalConfig.sub,
95531
95598
  master: globalConfig.master,
95532
95599
  wordcloud: globalConfig.wordcloud,
95600
+ liveSummary: globalConfig.liveSummary,
95533
95601
  liveDetectType: globalConfig.liveDetectType,
95534
95602
  restartPush: globalConfig.restartPush,
95535
95603
  pushTime: globalConfig.pushTime,
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.2",
4
+ "version": "3.2.9-rc.4",
5
5
  "contributors": [
6
6
  "Akokko <admin@akokko.com>"
7
7
  ],
@@ -49,7 +49,7 @@
49
49
  "tough-cookie": "^5.1.2"
50
50
  },
51
51
  "devDependencies": {
52
- "@biomejs/biome": "^2.0.0",
52
+ "@biomejs/biome": "^2.0.6",
53
53
  "@koishijs/cache": "^2.1.0",
54
54
  "@koishijs/client": "^5.30.9",
55
55
  "@koishijs/plugin-help": "^2.4.5",
@@ -61,7 +61,7 @@
61
61
  "@types/md5": "^2.3.5",
62
62
  "@types/qrcode": "^1.5.5",
63
63
  "@types/tough-cookie": "^4.0.5",
64
- "globals": "^16.2.0",
64
+ "globals": "^16.3.0",
65
65
  "koishi": "^4.18.8",
66
66
  "koishi-plugin-puppeteer": "^3.9.0",
67
67
  "tsdown": "^0.12.9",
package/readme.md CHANGED
@@ -305,6 +305,8 @@ uid为必填参数,为要推送的UP主的UID,index为可选参数,为要
305
305
  > - ver 3.2.9-rc.0 优化:弹幕词云生成效果、选项 `pushTime` 设置为0时可关闭该功能; 新增:选项 `wordcloud` 可选择在直播结束后是否生成弹幕词云
306
306
  > - ver 3.2.9-rc.1 优化:弹幕词云生成效果;
307
307
  > - ver 3.2.9-rc.2 优化:弹幕词云生成效果;
308
+ > - ver 3.2.9-rc.3 优化:弹幕词云生成效果; 新增:直播总结语,开启弹幕词云后自动发送、选项 `liveSummary` 可自定义直播总结语; 修复:一场直播完成后,如果插件中途没有被关闭过,会影响同一位up主下一次直播词云数据;
309
+ > - ver 3.2.9-rc.4 优化:弹幕词云生成效果; 新增:直播总结 `-mdn` 变量,代表主播粉丝牌子名
308
310
 
309
311
  ## 交流群
310
312