koishi-plugin-cat-raising 1.3.5 → 1.3.7
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.ts +6 -0
- package/lib/index.js +64 -117
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export interface Config {
|
|
|
26
26
|
historySize: number;
|
|
27
27
|
/** 用于发送B站弹幕的 access_key 列表 */
|
|
28
28
|
biliAccessKeys: BiliAccessKeyConfig[];
|
|
29
|
+
/** 硬拒绝关键词列表 */
|
|
30
|
+
hardRejectionKeywords: string[];
|
|
31
|
+
/** 发送弹幕的延迟下限(秒) */
|
|
32
|
+
danmakuDelayMinSeconds?: number;
|
|
33
|
+
/** 发送弹幕的延迟上限(秒) */
|
|
34
|
+
danmakuDelayMaxSeconds?: number;
|
|
29
35
|
}
|
|
30
36
|
export declare const Config: Schema<Config>;
|
|
31
37
|
/**
|
package/lib/index.js
CHANGED
|
@@ -39,19 +39,30 @@ var import_koishi = require("koishi");
|
|
|
39
39
|
var crypto = __toESM(require("crypto"));
|
|
40
40
|
var import_url = require("url");
|
|
41
41
|
var name = "cat-raising";
|
|
42
|
-
var Config = import_koishi.Schema.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
})
|
|
54
|
-
|
|
42
|
+
var Config = import_koishi.Schema.intersect([
|
|
43
|
+
import_koishi.Schema.object({
|
|
44
|
+
targetQQ: import_koishi.Schema.string().description("转发目标:填 QQ 或 群号").role("link").required(),
|
|
45
|
+
isGroup: import_koishi.Schema.boolean().description("目标类型:群聊则勾选").default(false)
|
|
46
|
+
}).description("基础设置"),
|
|
47
|
+
import_koishi.Schema.object({
|
|
48
|
+
monitorGroups: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
49
|
+
groupId: import_koishi.Schema.string().description("监听群号").role("link").required(),
|
|
50
|
+
sendHelperMessages: import_koishi.Schema.boolean().description("在群内发送「直播间/主播/投稿数」等提示消息").default(true)
|
|
51
|
+
})).description("监听群组").required(),
|
|
52
|
+
historySize: import_koishi.Schema.number().description("防复读历史条数(避免短期重复转发)").role("slider", { min: 5, max: 100, step: 1 }).default(30)
|
|
53
|
+
}).description("监听设置"),
|
|
54
|
+
import_koishi.Schema.object({
|
|
55
|
+
biliAccessKeys: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
56
|
+
key: import_koishi.Schema.string().description("Bilibili access_key").required(),
|
|
57
|
+
remark: import_koishi.Schema.string().description("备注(例如所属账号)")
|
|
58
|
+
})).description("弹幕账号配置(留空则不发弹幕)").default([]),
|
|
59
|
+
danmakuDelayMinSeconds: import_koishi.Schema.number().description("弹幕延迟下限(秒)").role("slider", { min: 0, max: 60, step: 1 }).default(8),
|
|
60
|
+
danmakuDelayMaxSeconds: import_koishi.Schema.number().description("弹幕延迟上限(秒)").role("slider", { min: 0, max: 60, step: 1 }).default(10)
|
|
61
|
+
}).description("弹幕设置"),
|
|
62
|
+
import_koishi.Schema.object({
|
|
63
|
+
hardRejectionKeywords: import_koishi.Schema.array(import_koishi.Schema.string()).description("命中则忽略的关键词(硬拒绝)").default(["发言榜单", "投稿数:", "预告"])
|
|
64
|
+
}).description("过滤规则")
|
|
65
|
+
]);
|
|
55
66
|
function preprocessChineseNumerals(text) {
|
|
56
67
|
const numMap = { "零": 0, "一": 1, "二": 2, "两": 2, "三": 3, "四": 4, "五": 5, "六": 6, "七": 7, "八": 8, "九": 9 };
|
|
57
68
|
const unitMap = {
|
|
@@ -151,7 +162,6 @@ function parseEventFromText(text) {
|
|
|
151
162
|
return allRewards.length > 0 ? { dateTime: globalDateTime || "时间未知", rewards: allRewards } : null;
|
|
152
163
|
}
|
|
153
164
|
__name(parseEventFromText, "parseEventFromText");
|
|
154
|
-
var HARD_REJECTION_KEYWORDS = ["发言榜单", "投稿数:"];
|
|
155
165
|
var REJECTION_KEYWORDS = ["签到", "打卡"];
|
|
156
166
|
var OVERRIDE_KEYWORDS = ["神金", "发"];
|
|
157
167
|
var CHECK_IN_REJECTION_REGEX = /\b\d{2,3}\s*\+/;
|
|
@@ -237,28 +247,47 @@ async function fetchBilibiliInfo(ctx, roomId) {
|
|
|
237
247
|
let uid;
|
|
238
248
|
let anchorName = "未知";
|
|
239
249
|
try {
|
|
240
|
-
const
|
|
241
|
-
`https://api.live.bilibili.com/
|
|
250
|
+
const anchorInRoom = await ctx.http.get(
|
|
251
|
+
`https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room?roomid=${roomId}`,
|
|
242
252
|
{ headers: commonHeaders }
|
|
243
253
|
);
|
|
244
|
-
uid =
|
|
245
|
-
anchorName =
|
|
254
|
+
uid = anchorInRoom?.data?.info?.uid || uid;
|
|
255
|
+
anchorName = anchorInRoom?.data?.info?.uname || anchorName;
|
|
246
256
|
} catch {
|
|
247
257
|
}
|
|
248
258
|
if (!uid || anchorName === "未知") {
|
|
249
259
|
try {
|
|
250
|
-
const
|
|
251
|
-
`https://api.live.bilibili.com/room/v1/Room/
|
|
260
|
+
const roomInfo = await ctx.http.get(
|
|
261
|
+
`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${roomId}`,
|
|
252
262
|
{ headers: commonHeaders }
|
|
253
263
|
);
|
|
254
|
-
uid =
|
|
255
|
-
|
|
256
|
-
|
|
264
|
+
uid = roomInfo?.data?.uid || uid;
|
|
265
|
+
anchorName = roomInfo?.data?.uname || anchorName;
|
|
266
|
+
} catch {
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (anchorName === "未知" || !uid) {
|
|
270
|
+
await sleep(300);
|
|
271
|
+
try {
|
|
272
|
+
const anchorInRoom2 = await ctx.http.get(
|
|
273
|
+
`https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room?roomid=${roomId}`,
|
|
257
274
|
{ headers: commonHeaders }
|
|
258
275
|
);
|
|
259
|
-
|
|
276
|
+
uid = uid || anchorInRoom2?.data?.info?.uid;
|
|
277
|
+
anchorName = anchorInRoom2?.data?.info?.uname || anchorName;
|
|
260
278
|
} catch {
|
|
261
279
|
}
|
|
280
|
+
if (!uid || anchorName === "未知") {
|
|
281
|
+
try {
|
|
282
|
+
const roomInfo2 = await ctx.http.get(
|
|
283
|
+
`https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${roomId}`,
|
|
284
|
+
{ headers: commonHeaders }
|
|
285
|
+
);
|
|
286
|
+
uid = uid || roomInfo2?.data?.uid;
|
|
287
|
+
anchorName = roomInfo2?.data?.uname || anchorName;
|
|
288
|
+
} catch {
|
|
289
|
+
}
|
|
290
|
+
}
|
|
262
291
|
}
|
|
263
292
|
if (!uid) throw new Error("无法从房间信息中获取UID");
|
|
264
293
|
const statsInfo = await ctx.http.get(
|
|
@@ -273,93 +302,6 @@ async function fetchBilibiliInfo(ctx, roomId) {
|
|
|
273
302
|
);
|
|
274
303
|
const videoCount = statsInfo?.data?.video;
|
|
275
304
|
if (videoCount === void 0) throw new Error("无法从空间信息中获取投稿数");
|
|
276
|
-
try {
|
|
277
|
-
const anchorInfo = await ctx.http.get(
|
|
278
|
-
`https://api.bilibili.com/x/space/acc/info?mid=${uid}`,
|
|
279
|
-
{
|
|
280
|
-
headers: {
|
|
281
|
-
...commonHeaders,
|
|
282
|
-
Origin: "https://space.bilibili.com",
|
|
283
|
-
Referer: `https://space.bilibili.com/${uid}`
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
);
|
|
287
|
-
anchorName = anchorInfo?.data?.name || anchorName;
|
|
288
|
-
} catch {
|
|
289
|
-
}
|
|
290
|
-
if (anchorName === "未知") {
|
|
291
|
-
try {
|
|
292
|
-
const liveUser = await ctx.http.get(
|
|
293
|
-
`https://api.live.bilibili.com/live_user/v3/UserInfo/get_info?uid=${uid}`,
|
|
294
|
-
{
|
|
295
|
-
headers: {
|
|
296
|
-
...commonHeaders,
|
|
297
|
-
Origin: "https://live.bilibili.com",
|
|
298
|
-
Referer: `https://live.bilibili.com/${roomId}`
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
);
|
|
302
|
-
anchorName = liveUser?.data?.info?.uname || anchorName;
|
|
303
|
-
} catch {
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
if (anchorName === "未知") {
|
|
307
|
-
try {
|
|
308
|
-
const baseInfo = await ctx.http.get(
|
|
309
|
-
`https://api.live.bilibili.com/xlive/web-room/v1/index/getRoomBaseInfo?room_id=${roomId}`,
|
|
310
|
-
{ headers: commonHeaders }
|
|
311
|
-
);
|
|
312
|
-
anchorName = baseInfo?.data?.anchor_info?.base_info?.uname || baseInfo?.data?.anchor_info?.uname || baseInfo?.data?.room_info?.uname || baseInfo?.data?.uname || anchorName;
|
|
313
|
-
} catch {
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (anchorName === "未知") {
|
|
317
|
-
await sleep(300);
|
|
318
|
-
try {
|
|
319
|
-
const infoByRoom2 = await ctx.http.get(
|
|
320
|
-
`https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=${roomId}`,
|
|
321
|
-
{ headers: commonHeaders }
|
|
322
|
-
);
|
|
323
|
-
anchorName = infoByRoom2?.data?.anchor_info?.base_info?.uname || infoByRoom2?.data?.anchor_info?.uname || anchorName;
|
|
324
|
-
} catch {
|
|
325
|
-
}
|
|
326
|
-
try {
|
|
327
|
-
const anchorInRoom = await ctx.http.get(
|
|
328
|
-
`https://api.live.bilibili.com/live_user/v1/guard/get_anchor_in_room?roomid=${roomId}`,
|
|
329
|
-
{ headers: commonHeaders }
|
|
330
|
-
);
|
|
331
|
-
anchorName = anchorInRoom?.data?.info?.uname || anchorName;
|
|
332
|
-
} catch {
|
|
333
|
-
}
|
|
334
|
-
try {
|
|
335
|
-
const anchorInfo2 = await ctx.http.get(
|
|
336
|
-
`https://api.bilibili.com/x/space/acc/info?mid=${uid}`,
|
|
337
|
-
{
|
|
338
|
-
headers: {
|
|
339
|
-
...commonHeaders,
|
|
340
|
-
Origin: "https://space.bilibili.com",
|
|
341
|
-
Referer: `https://space.bilibili.com/${uid}`
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
);
|
|
345
|
-
anchorName = anchorInfo2?.data?.name || anchorName;
|
|
346
|
-
} catch {
|
|
347
|
-
}
|
|
348
|
-
try {
|
|
349
|
-
const liveUser2 = await ctx.http.get(
|
|
350
|
-
`https://api.live.bilibili.com/live_user/v3/UserInfo/get_info?uid=${uid}`,
|
|
351
|
-
{
|
|
352
|
-
headers: {
|
|
353
|
-
...commonHeaders,
|
|
354
|
-
Origin: "https://live.bilibili.com",
|
|
355
|
-
Referer: `https://live.bilibili.com/${roomId}`
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
);
|
|
359
|
-
anchorName = liveUser2?.data?.info?.uname || anchorName;
|
|
360
|
-
} catch {
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
305
|
return { videoCount, anchorName };
|
|
364
306
|
} catch (error) {
|
|
365
307
|
const status = error?.response?.status;
|
|
@@ -378,7 +320,7 @@ function apply(ctx, config) {
|
|
|
378
320
|
if (!groupConfig) return;
|
|
379
321
|
const strippedContent = session.stripped.content;
|
|
380
322
|
if (!strippedContent.trim()) return;
|
|
381
|
-
if (
|
|
323
|
+
if (config.hardRejectionKeywords.some((keyword) => strippedContent.includes(keyword))) return;
|
|
382
324
|
if (CHECK_IN_REJECTION_REGEX.test(strippedContent)) {
|
|
383
325
|
ctx.logger.info(`[忽略] 消息包含签到模式 (如 110+),判定为非奖励信息。内容: "${strippedContent.replace(/\n/g, " ")}"`);
|
|
384
326
|
return;
|
|
@@ -434,11 +376,16 @@ function apply(ctx, config) {
|
|
|
434
376
|
});
|
|
435
377
|
if (forwardedHistory.length > config.historySize) forwardedHistory.shift();
|
|
436
378
|
if (config.biliAccessKeys && config.biliAccessKeys.length > 0) {
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
);
|
|
441
|
-
|
|
379
|
+
const min = Math.max(0, config.danmakuDelayMinSeconds ?? 8);
|
|
380
|
+
const max = Math.max(min, config.danmakuDelayMaxSeconds ?? 10);
|
|
381
|
+
const delayMs = (Math.floor(Math.random() * (max - min + 1)) + min) * 1e3;
|
|
382
|
+
ctx.logger.info(`[弹幕] ${config.biliAccessKeys.length} 个账号将于 ${Math.round(delayMs / 1e3)} 秒后发送弹幕到直播间 ${roomId}。`);
|
|
383
|
+
setTimeout(() => {
|
|
384
|
+
const danmakuPromises = config.biliAccessKeys.map(
|
|
385
|
+
(keyConfig) => sendBilibiliDanmaku(ctx, keyConfig, roomId, "喵喵喵")
|
|
386
|
+
);
|
|
387
|
+
Promise.allSettled(danmakuPromises);
|
|
388
|
+
}, delayMs);
|
|
442
389
|
}
|
|
443
390
|
} catch (error) {
|
|
444
391
|
session.send("🐱 - 转发失败,请检查目标QQ/群号配置是否正确");
|