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 +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +280 -78
- package/lib/index.mjs +280 -78
- package/package.json +2 -2
- package/readme.md +4 -5
package/lib/index.d.mts
CHANGED
package/lib/index.d.ts
CHANGED
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
|
|
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/
|
|
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
|
-
|
|
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
|
-
["
|
|
803
|
-
["
|
|
804
|
-
["
|
|
805
|
-
["
|
|
806
|
-
["
|
|
807
|
-
["
|
|
808
|
-
["
|
|
809
|
-
["
|
|
810
|
-
["
|
|
811
|
-
["
|
|
812
|
-
["
|
|
813
|
-
["
|
|
814
|
-
["
|
|
815
|
-
["
|
|
816
|
-
["
|
|
817
|
-
["
|
|
818
|
-
["
|
|
819
|
-
["
|
|
820
|
-
["
|
|
821
|
-
["
|
|
822
|
-
["
|
|
823
|
-
["
|
|
824
|
-
["
|
|
825
|
-
["
|
|
826
|
-
["
|
|
827
|
-
["
|
|
828
|
-
["
|
|
829
|
-
["
|
|
830
|
-
["
|
|
831
|
-
["
|
|
832
|
-
["
|
|
833
|
-
["
|
|
834
|
-
["
|
|
835
|
-
["
|
|
836
|
-
["
|
|
837
|
-
["
|
|
838
|
-
["
|
|
839
|
-
["
|
|
840
|
-
["
|
|
841
|
-
["
|
|
842
|
-
["
|
|
843
|
-
["
|
|
844
|
-
["
|
|
845
|
-
["
|
|
846
|
-
["
|
|
847
|
-
["
|
|
848
|
-
["
|
|
849
|
-
["
|
|
850
|
-
["
|
|
851
|
-
["
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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("正在获取前
|
|
1300
|
-
const
|
|
1301
|
-
this.logger.info("弹幕词云前
|
|
1302
|
-
this.logger.info(
|
|
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(
|
|
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
|
|
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/
|
|
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:
|
|
94690
|
+
maxFontSize: 60,
|
|
94490
94691
|
minFontSize: 12,
|
|
94491
94692
|
densityTarget: 0.3,
|
|
94492
|
-
weightExponent: 0.
|
|
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
|
|
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/
|
|
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
|
|
95502
|
+
var bili_api_default = BiliAPI;
|
|
95302
95503
|
|
|
95303
95504
|
//#endregion
|
|
95304
|
-
//#region src/
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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/
|
|
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
|
-
|
|
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
|
-
["
|
|
805
|
-
["
|
|
806
|
-
["
|
|
807
|
-
["
|
|
808
|
-
["
|
|
809
|
-
["
|
|
810
|
-
["
|
|
811
|
-
["
|
|
812
|
-
["
|
|
813
|
-
["
|
|
814
|
-
["
|
|
815
|
-
["
|
|
816
|
-
["
|
|
817
|
-
["
|
|
818
|
-
["
|
|
819
|
-
["
|
|
820
|
-
["
|
|
821
|
-
["
|
|
822
|
-
["
|
|
823
|
-
["
|
|
824
|
-
["
|
|
825
|
-
["
|
|
826
|
-
["
|
|
827
|
-
["
|
|
828
|
-
["
|
|
829
|
-
["
|
|
830
|
-
["
|
|
831
|
-
["
|
|
832
|
-
["
|
|
833
|
-
["
|
|
834
|
-
["
|
|
835
|
-
["
|
|
836
|
-
["
|
|
837
|
-
["
|
|
838
|
-
["
|
|
839
|
-
["
|
|
840
|
-
["
|
|
841
|
-
["
|
|
842
|
-
["
|
|
843
|
-
["
|
|
844
|
-
["
|
|
845
|
-
["
|
|
846
|
-
["
|
|
847
|
-
["
|
|
848
|
-
["
|
|
849
|
-
["
|
|
850
|
-
["
|
|
851
|
-
["
|
|
852
|
-
["
|
|
853
|
-
["
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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("正在获取前
|
|
1302
|
-
const
|
|
1303
|
-
this.logger.info("弹幕词云前
|
|
1304
|
-
this.logger.info(
|
|
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(
|
|
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
|
|
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/
|
|
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:
|
|
94692
|
+
maxFontSize: 60,
|
|
94492
94693
|
minFontSize: 12,
|
|
94493
94694
|
densityTarget: 0.3,
|
|
94494
|
-
weightExponent: 0.
|
|
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
|
|
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/
|
|
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
|
|
95504
|
+
var bili_api_default = BiliAPI;
|
|
95304
95505
|
|
|
95305
95506
|
//#endregion
|
|
95306
|
-
//#region src/
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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 [](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
|
|