koishi-plugin-bilibili-notify 3.0.0-alpha.0 → 3.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/biliAPI.js +260 -185
- package/lib/comRegister.d.ts +2 -0
- package/lib/comRegister.js +261 -95
- package/lib/generateImg.js +3 -3
- package/lib/index.d.ts +12 -11
- package/lib/index.js +155 -147
- package/lib/utils/retry.d.ts +6 -0
- package/lib/utils/retry.js +24 -0
- package/lib/utils/withLock.d.ts +7 -0
- package/lib/utils/withLock.js +59 -0
- package/package.json +1 -1
- package/readme.md +10 -0
package/lib/comRegister.js
CHANGED
|
@@ -42,8 +42,10 @@ class ComRegister {
|
|
|
42
42
|
loginDBData;
|
|
43
43
|
// 机器人实例
|
|
44
44
|
privateBot;
|
|
45
|
-
//
|
|
45
|
+
// 动态检测销毁函数
|
|
46
46
|
dynamicDispose;
|
|
47
|
+
// 直播检测销毁函数
|
|
48
|
+
liveDispose;
|
|
47
49
|
// 发送消息方式
|
|
48
50
|
sendMsgFunc;
|
|
49
51
|
// 构造函数
|
|
@@ -163,6 +165,8 @@ class ComRegister {
|
|
|
163
165
|
}]);
|
|
164
166
|
// 销毁定时器
|
|
165
167
|
this.loginTimer();
|
|
168
|
+
// 订阅手动订阅中的订阅
|
|
169
|
+
await this.loadSubFromConfig(config.sub);
|
|
166
170
|
// 订阅之前的订阅
|
|
167
171
|
await this.loadSubFromDatabase();
|
|
168
172
|
// 清除控制台通知
|
|
@@ -173,7 +177,6 @@ class ComRegister {
|
|
|
173
177
|
await session.execute('bili show');
|
|
174
178
|
// 开启cookies刷新检测
|
|
175
179
|
ctx.ba.enableRefreshCookiesDetect();
|
|
176
|
-
return;
|
|
177
180
|
}
|
|
178
181
|
}
|
|
179
182
|
finally {
|
|
@@ -437,10 +440,23 @@ class ComRegister {
|
|
|
437
440
|
this.logger.error('bili sub指令 getMasterInfo() 发生了错误,错误为:' + e.message);
|
|
438
441
|
return '订阅出错啦,请重试';
|
|
439
442
|
}
|
|
443
|
+
const liveDetectModeSelector = {
|
|
444
|
+
API: async () => {
|
|
445
|
+
// 判断是否已开启直播检测
|
|
446
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
447
|
+
// 开启直播检测并保存销毁函数
|
|
448
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
WS: async () => {
|
|
452
|
+
// 连接到服务器
|
|
453
|
+
await this.liveDetectWithListener(roomId, target);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
440
456
|
// 订阅直播
|
|
441
457
|
if (liveMsg) {
|
|
442
|
-
//
|
|
443
|
-
this.
|
|
458
|
+
// 判断直播订阅方式
|
|
459
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
444
460
|
// 发送订阅消息通知
|
|
445
461
|
await session.send(`订阅${userData.info.uname}直播通知`);
|
|
446
462
|
}
|
|
@@ -448,6 +464,7 @@ class ComRegister {
|
|
|
448
464
|
if (dynamicMsg) {
|
|
449
465
|
// 判断是否开启动态监测
|
|
450
466
|
if (!this.dynamicDispose) {
|
|
467
|
+
// 开启动态监测
|
|
451
468
|
this.enableDynamicDetect();
|
|
452
469
|
}
|
|
453
470
|
// 发送订阅消息通知
|
|
@@ -583,6 +600,14 @@ class ComRegister {
|
|
|
583
600
|
}
|
|
584
601
|
// 检查登录数据库是否有数据
|
|
585
602
|
this.loginDBData = (await this.ctx.database.get('loginBili', 1, ['dynamic_group_id']))[0];
|
|
603
|
+
// 判断登录信息是否已加载完毕
|
|
604
|
+
await this.checkIfLoginInfoIsLoaded();
|
|
605
|
+
// 如果未登录,则直接返回
|
|
606
|
+
if (!(await this.checkIfIsLogin())) {
|
|
607
|
+
// log
|
|
608
|
+
this.logger.info(`账号未登录,请登录`);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
586
611
|
// 从配置获取订阅
|
|
587
612
|
config.sub && await this.loadSubFromConfig(config.sub);
|
|
588
613
|
// 从数据库获取订阅
|
|
@@ -705,8 +730,12 @@ class ComRegister {
|
|
|
705
730
|
}
|
|
706
731
|
}
|
|
707
732
|
dynamicDetect() {
|
|
733
|
+
// 检测初始化变量
|
|
708
734
|
let detectSetup = true;
|
|
735
|
+
// 更新基线
|
|
709
736
|
let updateBaseline;
|
|
737
|
+
// 第一条动态的动态ID
|
|
738
|
+
let dynamicIdStr;
|
|
710
739
|
// 相当于锁的作用,防止上一个循环没处理完
|
|
711
740
|
let flag = true;
|
|
712
741
|
// 返回一个闭包函数
|
|
@@ -803,14 +832,23 @@ class ComRegister {
|
|
|
803
832
|
// 寻找关注的UP主的动态
|
|
804
833
|
this.subManager.forEach(async (sub) => {
|
|
805
834
|
// 判断是否是订阅的UP主
|
|
806
|
-
if (sub.uid == upUID) {
|
|
807
|
-
//
|
|
835
|
+
if (sub.dynamic && sub.uid == upUID) { // 订阅该UP主,推送该动态
|
|
836
|
+
// 判断更新动态是否为1条
|
|
837
|
+
if (updateNum === 1) {
|
|
838
|
+
// 判断dynamicIdStr是否有值,是否与当前动态ID一致
|
|
839
|
+
if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
|
|
840
|
+
// 重复动态,不再推送,直接返回
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
// 存储该动态ID
|
|
844
|
+
dynamicIdStr = items[num].id_str;
|
|
845
|
+
}
|
|
808
846
|
// 定义变量
|
|
809
847
|
let pic;
|
|
810
848
|
let buffer;
|
|
811
849
|
// 从动态数据中取出UP主名称和动态ID
|
|
812
|
-
const upName =
|
|
813
|
-
const dynamicId =
|
|
850
|
+
const upName = items[num].modules.module_author.name;
|
|
851
|
+
const dynamicId = items[num].id_str;
|
|
814
852
|
// 推送该条动态
|
|
815
853
|
const attempts = 3;
|
|
816
854
|
for (let i = 0; i < attempts; i++) {
|
|
@@ -875,8 +913,12 @@ class ComRegister {
|
|
|
875
913
|
};
|
|
876
914
|
}
|
|
877
915
|
debug_dynamicDetect() {
|
|
916
|
+
// 检测初始化变量
|
|
878
917
|
let detectSetup = true;
|
|
918
|
+
// 更新基线
|
|
879
919
|
let updateBaseline;
|
|
920
|
+
// 第一条动态的动态ID
|
|
921
|
+
let dynamicIdStr;
|
|
880
922
|
// 相当于锁的作用,防止上一个循环没处理完
|
|
881
923
|
let flag = true;
|
|
882
924
|
// 返回一个闭包函数
|
|
@@ -986,14 +1028,23 @@ class ComRegister {
|
|
|
986
1028
|
this.subManager.forEach(async (sub) => {
|
|
987
1029
|
console.log(`当前订阅UP主:${sub.uid}`);
|
|
988
1030
|
// 判断是否是订阅的UP主
|
|
989
|
-
if (sub.uid == upUID) {
|
|
990
|
-
//
|
|
1031
|
+
if (sub.dynamic && sub.uid == upUID) { // 订阅该UP主,推送该动态
|
|
1032
|
+
// 判断更新动态是否为1条
|
|
1033
|
+
if (updateNum === 1) {
|
|
1034
|
+
// 判断dynamicIdStr是否有值,是否与当前动态ID一致
|
|
1035
|
+
if (dynamicIdStr && dynamicIdStr === items[num].id_str) {
|
|
1036
|
+
// 重复动态,不再推送,直接返回
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
// 存储该动态ID
|
|
1040
|
+
dynamicIdStr = items[num].id_str;
|
|
1041
|
+
}
|
|
991
1042
|
// 定义变量
|
|
992
1043
|
let pic;
|
|
993
1044
|
let buffer;
|
|
994
1045
|
// 从动态数据中取出UP主名称和动态ID
|
|
995
|
-
const upName =
|
|
996
|
-
const dynamicId =
|
|
1046
|
+
const upName = items[num].modules.module_author.name;
|
|
1047
|
+
const dynamicId = items[num].id_str;
|
|
997
1048
|
console.log(`UP主名称:${upName},动态ID:${dynamicId}`);
|
|
998
1049
|
// 推送该条动态
|
|
999
1050
|
const attempts = 3;
|
|
@@ -1130,21 +1181,13 @@ class ComRegister {
|
|
|
1130
1181
|
}
|
|
1131
1182
|
async liveDetectWithAPI() {
|
|
1132
1183
|
// 定义变量:第一次订阅
|
|
1133
|
-
let
|
|
1184
|
+
let liveDetectSetup = true;
|
|
1134
1185
|
// 定义变量:timer计时器
|
|
1135
1186
|
let timer = 0;
|
|
1136
1187
|
// 相当于锁的作用,防止上一个循环没处理完
|
|
1137
1188
|
let flag = true;
|
|
1138
1189
|
// 定义订阅对象Record 0未开播 1正在直播 2轮播中
|
|
1139
1190
|
const liveRecord = {};
|
|
1140
|
-
// 初始化subRecord
|
|
1141
|
-
this.subManager.forEach(sub => {
|
|
1142
|
-
// 判断是否订阅直播
|
|
1143
|
-
if (sub.live) {
|
|
1144
|
-
// 将该订阅添加到subRecord中
|
|
1145
|
-
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1146
|
-
}
|
|
1147
|
-
});
|
|
1148
1191
|
// 定义函数: 发送请求获取直播状态
|
|
1149
1192
|
const useLiveStatus = async (roomId) => {
|
|
1150
1193
|
let content;
|
|
@@ -1176,10 +1219,18 @@ class ComRegister {
|
|
|
1176
1219
|
try {
|
|
1177
1220
|
// 获取正在直播对象
|
|
1178
1221
|
const liveUsers = await this.ctx.ba.getTheUserWhoIsLiveStreaming();
|
|
1179
|
-
//
|
|
1180
|
-
if (
|
|
1222
|
+
// 判断是否是初始化直播监测
|
|
1223
|
+
if (liveDetectSetup) {
|
|
1181
1224
|
// 将第一次订阅置为false
|
|
1182
|
-
|
|
1225
|
+
liveDetectSetup = false;
|
|
1226
|
+
// 初始化subRecord
|
|
1227
|
+
this.subManager.forEach(sub => {
|
|
1228
|
+
// 判断是否订阅直播
|
|
1229
|
+
if (sub.live) {
|
|
1230
|
+
// 将该订阅添加到subRecord中
|
|
1231
|
+
liveRecord[sub.uid] = { liveStatus: 0, liveTime: '', target: sub.target };
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1183
1234
|
// 先判断是否有UP主正在直播
|
|
1184
1235
|
if (liveUsers.count > 0) {
|
|
1185
1236
|
// 遍历liveUsers
|
|
@@ -1190,6 +1241,8 @@ class ComRegister {
|
|
|
1190
1241
|
const data = await useLiveStatus(item.room_id.toString());
|
|
1191
1242
|
// 设置开播时间
|
|
1192
1243
|
liveRecord[item.mid].liveTime = data.live_time;
|
|
1244
|
+
// 改变开播状态
|
|
1245
|
+
liveRecord[item.mid].liveStatus = 1;
|
|
1193
1246
|
// 设置直播中消息
|
|
1194
1247
|
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1195
1248
|
.replace('-name', item.uname)
|
|
@@ -1203,8 +1256,6 @@ class ComRegister {
|
|
|
1203
1256
|
target: liveRecord[item.mid].target,
|
|
1204
1257
|
data
|
|
1205
1258
|
}, LiveType.LiveBroadcast, liveMsg);
|
|
1206
|
-
// 改变开播状态
|
|
1207
|
-
liveRecord[item.mid].liveStatus = 1;
|
|
1208
1259
|
}
|
|
1209
1260
|
});
|
|
1210
1261
|
}
|
|
@@ -1312,6 +1363,8 @@ class ComRegister {
|
|
|
1312
1363
|
const masterInfo = await this.useMasterInfo(subUID);
|
|
1313
1364
|
// 获取直播间消息
|
|
1314
1365
|
const liveRoomInfo = await this.useLiveRoomInfo(masterInfo.roomId.toString());
|
|
1366
|
+
// 设置开播时间
|
|
1367
|
+
liveRoomInfo.live_time = liveRecord[subUID].liveTime;
|
|
1315
1368
|
// 定义下播播通知语
|
|
1316
1369
|
const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
|
|
1317
1370
|
.replace('-name', masterInfo.username)
|
|
@@ -1340,10 +1393,21 @@ class ComRegister {
|
|
|
1340
1393
|
// 定义弹幕存放数组
|
|
1341
1394
|
const currentLiveDanmakuArr = [];
|
|
1342
1395
|
const temporaryLiveDanmakuArr = [];
|
|
1396
|
+
// 定义开播状态
|
|
1397
|
+
let liveStatus = false;
|
|
1343
1398
|
// 处理target
|
|
1399
|
+
// 定义channelIdArr总长度
|
|
1400
|
+
let channelIdArrLen = 0;
|
|
1401
|
+
// 定义数据
|
|
1402
|
+
let liveRoomInfo;
|
|
1403
|
+
let masterInfo;
|
|
1344
1404
|
// 找到频道/群组对应的
|
|
1345
|
-
const
|
|
1405
|
+
const danmakuPushTargetArr = target.map(channel => {
|
|
1406
|
+
// 获取符合条件的target
|
|
1346
1407
|
const liveDanmakuArr = channel.channelIdArr.filter(channelId => channelId.liveDanmaku);
|
|
1408
|
+
// 将当前liveDanmakuArr的长度+到channelIdArrLen中
|
|
1409
|
+
channelIdArrLen += liveDanmakuArr.length;
|
|
1410
|
+
// 返回符合的target
|
|
1347
1411
|
return {
|
|
1348
1412
|
channelIdArr: liveDanmakuArr,
|
|
1349
1413
|
platform: channel.platform
|
|
@@ -1351,11 +1415,14 @@ class ComRegister {
|
|
|
1351
1415
|
});
|
|
1352
1416
|
// 定义定时推送函数
|
|
1353
1417
|
const pushAtTimeFunc = async () => {
|
|
1354
|
-
//
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1418
|
+
// 判断是否信息是否获取成功
|
|
1419
|
+
if (!(await useMasterAndLiveRoomInfo())) {
|
|
1420
|
+
// 未获取成功,直接返回
|
|
1421
|
+
return this.sendPrivateMsg('获取直播间信息失败,推送直播卡片失败!');
|
|
1422
|
+
}
|
|
1423
|
+
// 设置开播时间
|
|
1424
|
+
liveTime = liveRoomInfo.live_time;
|
|
1425
|
+
// 设置直播中消息
|
|
1359
1426
|
const liveMsg = this.config.customLive ? this.config.customLive
|
|
1360
1427
|
.replace('-name', masterInfo.username)
|
|
1361
1428
|
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
|
|
@@ -1364,24 +1431,58 @@ class ComRegister {
|
|
|
1364
1431
|
await this.sendLiveNotifyCard({
|
|
1365
1432
|
username: masterInfo.username,
|
|
1366
1433
|
userface: masterInfo.userface,
|
|
1367
|
-
target
|
|
1434
|
+
target,
|
|
1368
1435
|
data: liveRoomInfo
|
|
1369
1436
|
}, LiveType.LiveBroadcast, liveMsg);
|
|
1370
1437
|
};
|
|
1371
1438
|
// 定义弹幕推送函数
|
|
1372
1439
|
const danmakuPushFunc = () => {
|
|
1373
1440
|
// 判断数组是否有内容
|
|
1374
|
-
if (temporaryLiveDanmakuArr.length > 0) {
|
|
1441
|
+
if (channelIdArrLen > 0 && temporaryLiveDanmakuArr.length > 0) {
|
|
1375
1442
|
// 发送消息
|
|
1376
|
-
this.sendMsg(
|
|
1443
|
+
this.sendMsg(danmakuPushTargetArr, temporaryLiveDanmakuArr.join('\n'));
|
|
1377
1444
|
// 将临时消息数组清空
|
|
1378
1445
|
temporaryLiveDanmakuArr.length = 0;
|
|
1379
1446
|
}
|
|
1380
1447
|
};
|
|
1381
|
-
//
|
|
1382
|
-
const
|
|
1383
|
-
|
|
1384
|
-
|
|
1448
|
+
// 定义直播间信息获取函数
|
|
1449
|
+
const useMasterAndLiveRoomInfo = async () => {
|
|
1450
|
+
// 定义flag
|
|
1451
|
+
let flag = true;
|
|
1452
|
+
// 判断是否已存在值
|
|
1453
|
+
if (liveRoomInfo && masterInfo && liveTime) {
|
|
1454
|
+
// 所有值均已存在,不需要再获取信息
|
|
1455
|
+
return flag;
|
|
1456
|
+
}
|
|
1457
|
+
// 获取直播间信息
|
|
1458
|
+
liveRoomInfo = await this.useLiveRoomInfo(roomId).catch(() => {
|
|
1459
|
+
// 设置flag为false
|
|
1460
|
+
flag = false;
|
|
1461
|
+
// 返回空
|
|
1462
|
+
return null;
|
|
1463
|
+
});
|
|
1464
|
+
// 判断是否成功获取信息
|
|
1465
|
+
if (!flag || !liveRoomInfo || !liveRoomInfo.uid) {
|
|
1466
|
+
// 上一步未成功
|
|
1467
|
+
flag = false;
|
|
1468
|
+
// 返回flag
|
|
1469
|
+
return flag;
|
|
1470
|
+
}
|
|
1471
|
+
// 获取主播信息(需要满足flag为true,liveRoomInfo.uid有值)
|
|
1472
|
+
masterInfo = await this.useMasterInfo(liveRoomInfo.uid).catch(() => {
|
|
1473
|
+
// 设置flag为false
|
|
1474
|
+
flag = false;
|
|
1475
|
+
// 返回空
|
|
1476
|
+
return null;
|
|
1477
|
+
});
|
|
1478
|
+
// 返回信息
|
|
1479
|
+
return flag;
|
|
1480
|
+
};
|
|
1481
|
+
// 判断是否信息是否获取成功
|
|
1482
|
+
if (!(await useMasterAndLiveRoomInfo())) {
|
|
1483
|
+
// 未获取成功,直接返回
|
|
1484
|
+
return this.sendPrivateMsg('获取直播间信息失败,启动直播间弹幕检测失败!');
|
|
1485
|
+
}
|
|
1385
1486
|
// 构建消息处理函数
|
|
1386
1487
|
const handler = {
|
|
1387
1488
|
onOpen: () => {
|
|
@@ -1411,49 +1512,67 @@ class ComRegister {
|
|
|
1411
1512
|
temporaryLiveDanmakuArr.push(content);
|
|
1412
1513
|
},
|
|
1413
1514
|
onLiveStart: async () => {
|
|
1414
|
-
//
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1515
|
+
// 判断是否已经开播
|
|
1516
|
+
if (liveStatus)
|
|
1517
|
+
return;
|
|
1518
|
+
// 设置开播状态为true
|
|
1519
|
+
liveStatus = true;
|
|
1520
|
+
// 判断是否信息是否获取成功
|
|
1521
|
+
if (!(await useMasterAndLiveRoomInfo())) {
|
|
1522
|
+
// 设置开播状态为false
|
|
1523
|
+
liveStatus = false;
|
|
1524
|
+
// 未获取成功,直接返回
|
|
1525
|
+
return await this.sendPrivateMsg('获取直播间信息失败,推送直播开播卡片失败!');
|
|
1526
|
+
}
|
|
1527
|
+
// 设置开播时间
|
|
1528
|
+
liveTime = liveRoomInfo.live_time;
|
|
1529
|
+
// 定义开播通知语
|
|
1530
|
+
const liveStartMsg = this.config.customLiveStart ? this.config.customLiveStart
|
|
1420
1531
|
.replace('-name', masterInfo.username)
|
|
1421
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
// 推送下播通知
|
|
1532
|
+
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
|
|
1533
|
+
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1534
|
+
// 推送开播通知
|
|
1425
1535
|
await this.sendLiveNotifyCard({
|
|
1426
1536
|
username: masterInfo.username,
|
|
1427
1537
|
userface: masterInfo.userface,
|
|
1428
|
-
target
|
|
1538
|
+
target,
|
|
1429
1539
|
data: liveRoomInfo
|
|
1430
|
-
}, LiveType.
|
|
1540
|
+
}, LiveType.StartBroadcasting, liveStartMsg);
|
|
1541
|
+
// 判断定时器是否已开启
|
|
1542
|
+
if (!pushAtTimeTimer) {
|
|
1543
|
+
// 开始直播,开启定时器
|
|
1544
|
+
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1545
|
+
}
|
|
1431
1546
|
},
|
|
1432
1547
|
onLiveEnd: async () => {
|
|
1433
|
-
//
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
pushAtTimeTimer = null;
|
|
1548
|
+
// 判断是否信息是否获取成功
|
|
1549
|
+
if (!(await useMasterAndLiveRoomInfo())) {
|
|
1550
|
+
// 未获取成功,直接返回
|
|
1551
|
+
return this.sendPrivateMsg('获取直播间信息失败,推送直播下播卡片失败!');
|
|
1552
|
+
}
|
|
1553
|
+
// 更改直播时长
|
|
1554
|
+
liveRoomInfo.live_time = liveTime;
|
|
1441
1555
|
// 定义下播播通知语
|
|
1442
1556
|
const liveEndMsg = this.config.customLiveEnd ? this.config.customLiveEnd
|
|
1443
1557
|
.replace('-name', masterInfo.username)
|
|
1444
|
-
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime))
|
|
1445
|
-
.replace('-link', `https://live.bilibili.com/${liveRoomInfo.short_id === 0 ? liveRoomInfo.room_id : liveRoomInfo.short_id}`) : null;
|
|
1558
|
+
.replace('-time', await this.ctx.gi.getTimeDifference(liveTime)) : null;
|
|
1446
1559
|
// 推送通知卡片
|
|
1447
1560
|
await this.sendLiveNotifyCard({
|
|
1448
1561
|
username: masterInfo.username,
|
|
1449
1562
|
userface: masterInfo.userface,
|
|
1450
|
-
target
|
|
1563
|
+
target,
|
|
1451
1564
|
data: liveRoomInfo
|
|
1452
|
-
}, LiveType.
|
|
1565
|
+
}, LiveType.StopBroadcast, liveEndMsg);
|
|
1566
|
+
// 关闭定时推送定时器
|
|
1567
|
+
pushAtTimeTimer();
|
|
1568
|
+
// 将推送定时器变量置空
|
|
1569
|
+
pushAtTimeTimer = null;
|
|
1570
|
+
// 将直播状态设置为false
|
|
1571
|
+
liveStatus = false;
|
|
1453
1572
|
}
|
|
1454
1573
|
};
|
|
1455
1574
|
// 启动直播间弹幕监测
|
|
1456
|
-
this.ctx.bl.startLiveRoomListener(roomId, handler, danmakuPushFunc);
|
|
1575
|
+
await this.ctx.bl.startLiveRoomListener(roomId, handler, danmakuPushFunc);
|
|
1457
1576
|
// 判断直播状态
|
|
1458
1577
|
if (liveRoomInfo.live_status === 1) {
|
|
1459
1578
|
// 设置开播时间
|
|
@@ -1468,12 +1587,18 @@ class ComRegister {
|
|
|
1468
1587
|
await this.sendLiveNotifyCard({
|
|
1469
1588
|
username: masterInfo.username,
|
|
1470
1589
|
userface: masterInfo.userface,
|
|
1471
|
-
target
|
|
1590
|
+
target,
|
|
1472
1591
|
data: liveRoomInfo
|
|
1473
1592
|
}, LiveType.LiveBroadcast, liveMsg);
|
|
1474
1593
|
}
|
|
1475
1594
|
// 正在直播,开启定时器
|
|
1476
|
-
|
|
1595
|
+
// 判断定时器是否已开启
|
|
1596
|
+
if (!pushAtTimeTimer) {
|
|
1597
|
+
// 开始直播,开启定时器
|
|
1598
|
+
pushAtTimeTimer = this.ctx.setInterval(pushAtTimeFunc, this.config.pushTime * 1000 * 60 * 60);
|
|
1599
|
+
}
|
|
1600
|
+
// 设置直播状态为true
|
|
1601
|
+
liveStatus = true;
|
|
1477
1602
|
}
|
|
1478
1603
|
}
|
|
1479
1604
|
subShow() {
|
|
@@ -1657,7 +1782,7 @@ class ComRegister {
|
|
|
1657
1782
|
break;
|
|
1658
1783
|
}
|
|
1659
1784
|
catch (e) {
|
|
1660
|
-
this.logger.error('
|
|
1785
|
+
this.logger.error('loadSubFromConfig() getUserInfo() 发生了错误,错误为:' + e.message);
|
|
1661
1786
|
if (i === attempts - 1) { // 已尝试三次
|
|
1662
1787
|
// 发送私聊消息并重启服务
|
|
1663
1788
|
return await this.sendPrivateMsgAndStopService();
|
|
@@ -1673,10 +1798,24 @@ class ComRegister {
|
|
|
1673
1798
|
// 发送提示
|
|
1674
1799
|
this.logger.warn(`UID:${sub.uid} 用户没有开通直播间,无法订阅直播!`);
|
|
1675
1800
|
}
|
|
1801
|
+
//
|
|
1802
|
+
const liveDetectModeSelector = {
|
|
1803
|
+
API: async () => {
|
|
1804
|
+
// 判断是否已开启直播检测
|
|
1805
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
1806
|
+
// 开启直播检测并保存销毁函数
|
|
1807
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
1808
|
+
}
|
|
1809
|
+
},
|
|
1810
|
+
WS: async () => {
|
|
1811
|
+
// 连接到服务器
|
|
1812
|
+
await this.liveDetectWithListener(data.live_room.roomid, sub.target);
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1676
1815
|
// 判断是否订阅直播
|
|
1677
1816
|
if (sub.live) {
|
|
1678
|
-
//
|
|
1679
|
-
this.
|
|
1817
|
+
// 启动直播监测
|
|
1818
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
1680
1819
|
}
|
|
1681
1820
|
}
|
|
1682
1821
|
// 在B站中订阅该对象
|
|
@@ -1697,17 +1836,6 @@ class ComRegister {
|
|
|
1697
1836
|
}
|
|
1698
1837
|
}
|
|
1699
1838
|
async loadSubFromDatabase() {
|
|
1700
|
-
// 判断登录信息是否已加载完毕
|
|
1701
|
-
await this.checkIfLoginInfoIsLoaded();
|
|
1702
|
-
// 如果未登录,则直接返回
|
|
1703
|
-
if (!(await this.checkIfIsLogin())) {
|
|
1704
|
-
// log
|
|
1705
|
-
this.logger.info(`账号未登录,请登录`);
|
|
1706
|
-
return;
|
|
1707
|
-
}
|
|
1708
|
-
// 已存在订阅管理对象,不再进行订阅操作
|
|
1709
|
-
if (this.subManager.length !== 0)
|
|
1710
|
-
return;
|
|
1711
1839
|
// 从数据库中获取数据
|
|
1712
1840
|
const subData = await this.ctx.database.get('bilibili', { id: { $gt: 0 } });
|
|
1713
1841
|
// 定义变量:订阅直播数
|
|
@@ -1808,23 +1936,37 @@ class ComRegister {
|
|
|
1808
1936
|
dynamic: sub.dynamic === 1 ? true : false,
|
|
1809
1937
|
liveDispose: null
|
|
1810
1938
|
};
|
|
1939
|
+
// 定义直播模式监测器
|
|
1940
|
+
const liveDetectModeSelector = {
|
|
1941
|
+
API: async () => {
|
|
1942
|
+
// 判断是否已开启直播检测
|
|
1943
|
+
if (!this.liveDispose) { // 未开启直播检测
|
|
1944
|
+
// 开启直播检测并保存销毁函数
|
|
1945
|
+
this.liveDispose = await this.liveDetectWithAPI();
|
|
1946
|
+
}
|
|
1947
|
+
},
|
|
1948
|
+
WS: async () => {
|
|
1949
|
+
// 判断订阅直播数是否超过限制
|
|
1950
|
+
if (!this.config.unlockSubLimits && liveSubNum >= 3) {
|
|
1951
|
+
// 将live改为false
|
|
1952
|
+
subManagerItem.live = false;
|
|
1953
|
+
// log
|
|
1954
|
+
this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1955
|
+
// 发送错误消息
|
|
1956
|
+
await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1957
|
+
}
|
|
1958
|
+
else {
|
|
1959
|
+
// 直播订阅数+1
|
|
1960
|
+
liveSubNum++;
|
|
1961
|
+
// 订阅直播,开始循环检测
|
|
1962
|
+
await this.liveDetectWithListener(sub.room_id, target);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1811
1966
|
// 判断是否订阅直播
|
|
1812
1967
|
if (sub.live) {
|
|
1813
|
-
//
|
|
1814
|
-
|
|
1815
|
-
// 将live改为false
|
|
1816
|
-
subManagerItem.live = false;
|
|
1817
|
-
// log
|
|
1818
|
-
this.logger.warn(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1819
|
-
// 发送错误消息
|
|
1820
|
-
await this.sendPrivateMsg(`UID:${sub.uid} 订阅直播数超过限制,自动取消订阅`);
|
|
1821
|
-
}
|
|
1822
|
-
else {
|
|
1823
|
-
// 直播订阅数+1
|
|
1824
|
-
liveSubNum++;
|
|
1825
|
-
// 订阅直播,开始循环检测
|
|
1826
|
-
this.liveDetectWithListener(sub.room_id, target);
|
|
1827
|
-
}
|
|
1968
|
+
// 启动直播监测
|
|
1969
|
+
await liveDetectModeSelector[this.config.liveDetectMode]();
|
|
1828
1970
|
}
|
|
1829
1971
|
// 保存新订阅对象
|
|
1830
1972
|
this.subManager.push(subManagerItem);
|
|
@@ -1874,6 +2016,17 @@ class ComRegister {
|
|
|
1874
2016
|
}
|
|
1875
2017
|
// 取消订阅
|
|
1876
2018
|
sub.live = false;
|
|
2019
|
+
// 判断直播检测方式
|
|
2020
|
+
switch (this.config.liveDetectMode) {
|
|
2021
|
+
case 'API': {
|
|
2022
|
+
msg = '请手动删除订阅,并重启插件';
|
|
2023
|
+
break;
|
|
2024
|
+
}
|
|
2025
|
+
case 'WS': {
|
|
2026
|
+
// 取消直播监听
|
|
2027
|
+
this.ctx.bl.closeListener(sub.roomId);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
1877
2030
|
// 如果没有对这个UP的任何订阅,则移除
|
|
1878
2031
|
if (checkIfNoSubExist(sub)) {
|
|
1879
2032
|
// 从管理对象中移除
|
|
@@ -1932,6 +2085,15 @@ class ComRegister {
|
|
|
1932
2085
|
this.subManager.filter(sub => sub.uid === uid).map(async (sub, i) => {
|
|
1933
2086
|
// 判断是否还存在订阅了动态的对象,不存在则停止动态监测
|
|
1934
2087
|
this.checkIfUserIsTheLastOneWhoSubDyn();
|
|
2088
|
+
switch (this.config.liveDetectMode) {
|
|
2089
|
+
case "API": {
|
|
2090
|
+
break;
|
|
2091
|
+
}
|
|
2092
|
+
case "WS": {
|
|
2093
|
+
// 停止直播检测
|
|
2094
|
+
this.ctx.bl.closeListener(sub.roomId);
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
1935
2097
|
// 从数据库中删除订阅
|
|
1936
2098
|
await this.ctx.database.remove('bilibili', { uid: this.subManager[i].uid });
|
|
1937
2099
|
// 将该订阅对象从订阅管理对象中移除
|
|
@@ -1979,6 +2141,10 @@ class ComRegister {
|
|
|
1979
2141
|
}),
|
|
1980
2142
|
unlockSubLimits: koishi_1.Schema.boolean().required(),
|
|
1981
2143
|
automaticResend: koishi_1.Schema.boolean().required(),
|
|
2144
|
+
liveDetectMode: koishi_1.Schema.union([
|
|
2145
|
+
koishi_1.Schema.const('API'),
|
|
2146
|
+
koishi_1.Schema.const('WS')
|
|
2147
|
+
]).required(),
|
|
1982
2148
|
restartPush: koishi_1.Schema.boolean().required(),
|
|
1983
2149
|
pushTime: koishi_1.Schema.number().required(),
|
|
1984
2150
|
liveLoopTime: koishi_1.Schema.number().default(10),
|
package/lib/generateImg.js
CHANGED
|
@@ -176,7 +176,7 @@ class GenerateImg extends koishi_1.Service {
|
|
|
176
176
|
</div>
|
|
177
177
|
${this.giConfig.hideDesc ? '' : `<p class="card-text">${data.description ? data.description : '这个主播很懒,什么都简介都没写'}</p>`}
|
|
178
178
|
<p class="card-link">
|
|
179
|
-
|
|
179
|
+
<span>人气:${data.online > 10000 ? `${(data.online / 10000).toFixed(1)}万` : data.online}</span>
|
|
180
180
|
<span>分区名称:${data.area_name}</span>
|
|
181
181
|
</p>
|
|
182
182
|
<p class="card-link">
|
|
@@ -1432,7 +1432,7 @@ class GenerateImg extends koishi_1.Service {
|
|
|
1432
1432
|
}
|
|
1433
1433
|
case 3: {
|
|
1434
1434
|
titleStatus = '下播啦';
|
|
1435
|
-
liveTime =
|
|
1435
|
+
liveTime = `开播时间:${time}`;
|
|
1436
1436
|
cover = true;
|
|
1437
1437
|
break;
|
|
1438
1438
|
}
|
|
@@ -1455,7 +1455,7 @@ class GenerateImg extends koishi_1.Service {
|
|
|
1455
1455
|
const seconds = differenceInSeconds % 60;
|
|
1456
1456
|
// 返回格式化的字符串
|
|
1457
1457
|
return days ?
|
|
1458
|
-
`${days}
|
|
1458
|
+
`${days}天${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒` :
|
|
1459
1459
|
`${hours}小时${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒`;
|
|
1460
1460
|
}
|
|
1461
1461
|
unixTimestampToString(timestamp) {
|
package/lib/index.d.ts
CHANGED
|
@@ -6,6 +6,17 @@ declare module 'koishi' {
|
|
|
6
6
|
sm: ServerManager;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
declare class ServerManager extends Service {
|
|
10
|
+
servers: ForkScope[];
|
|
11
|
+
renderType: number;
|
|
12
|
+
dynamicLoopTime: number;
|
|
13
|
+
constructor(ctx: Context);
|
|
14
|
+
protected start(): void | Promise<void>;
|
|
15
|
+
registerPlugin: () => boolean;
|
|
16
|
+
disposePlugin: () => Promise<boolean>;
|
|
17
|
+
restartPlugin: () => Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
9
20
|
export interface Config {
|
|
10
21
|
require: {};
|
|
11
22
|
key: string;
|
|
@@ -36,6 +47,7 @@ export interface Config {
|
|
|
36
47
|
dynamicCheckNumber: number;
|
|
37
48
|
dynamicLoopTime: '1分钟' | '2分钟' | '3分钟' | '5分钟' | '10分钟' | '20分钟';
|
|
38
49
|
live: {};
|
|
50
|
+
liveDetectMode: 'API' | 'WS';
|
|
39
51
|
restartPush: boolean;
|
|
40
52
|
pushTime: number;
|
|
41
53
|
danmakuPushTime: number;
|
|
@@ -54,15 +66,4 @@ export interface Config {
|
|
|
54
66
|
dynamicDebugMode: boolean;
|
|
55
67
|
}
|
|
56
68
|
export declare const Config: Schema<Config>;
|
|
57
|
-
declare class ServerManager extends Service {
|
|
58
|
-
servers: ForkScope[];
|
|
59
|
-
renderType: number;
|
|
60
|
-
dynamicLoopTime: number;
|
|
61
|
-
constructor(ctx: Context);
|
|
62
|
-
protected start(): void | Promise<void>;
|
|
63
|
-
registerPlugin: () => boolean;
|
|
64
|
-
disposePlugin: () => Promise<boolean>;
|
|
65
|
-
restartPlugin: () => Promise<boolean>;
|
|
66
|
-
}
|
|
67
|
-
export declare function apply(ctx: Context, config: Config): void;
|
|
68
69
|
export {};
|