koishi-plugin-cat-raising 1.3.6 → 1.3.8
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 +57 -20
- 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*\+/;
|
|
@@ -305,12 +315,14 @@ __name(fetchBilibiliInfo, "fetchBilibiliInfo");
|
|
|
305
315
|
function apply(ctx, config) {
|
|
306
316
|
const forwardedHistory = [];
|
|
307
317
|
const warningMessageMap = /* @__PURE__ */ new Map();
|
|
318
|
+
const pendingDanmakuTimersByMessage = /* @__PURE__ */ new Map();
|
|
319
|
+
const pendingDanmakuTimersByRoom = /* @__PURE__ */ new Map();
|
|
308
320
|
ctx.on("message", async (session) => {
|
|
309
321
|
const groupConfig = config.monitorGroups.find((g) => g.groupId === session.channelId);
|
|
310
322
|
if (!groupConfig) return;
|
|
311
323
|
const strippedContent = session.stripped.content;
|
|
312
324
|
if (!strippedContent.trim()) return;
|
|
313
|
-
if (
|
|
325
|
+
if (config.hardRejectionKeywords.some((keyword) => strippedContent.includes(keyword))) return;
|
|
314
326
|
if (CHECK_IN_REJECTION_REGEX.test(strippedContent)) {
|
|
315
327
|
ctx.logger.info(`[忽略] 消息包含签到模式 (如 110+),判定为非奖励信息。内容: "${strippedContent.replace(/\n/g, " ")}"`);
|
|
316
328
|
return;
|
|
@@ -366,11 +378,26 @@ function apply(ctx, config) {
|
|
|
366
378
|
});
|
|
367
379
|
if (forwardedHistory.length > config.historySize) forwardedHistory.shift();
|
|
368
380
|
if (config.biliAccessKeys && config.biliAccessKeys.length > 0) {
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
);
|
|
373
|
-
|
|
381
|
+
const min = Math.max(0, config.danmakuDelayMinSeconds ?? 8);
|
|
382
|
+
const max = Math.max(min, config.danmakuDelayMaxSeconds ?? 10);
|
|
383
|
+
const delayMs = (Math.floor(Math.random() * (max - min + 1)) + min) * 1e3;
|
|
384
|
+
ctx.logger.info(`[弹幕] ${config.biliAccessKeys.length} 个账号将于 ${Math.round(delayMs / 1e3)} 秒后发送弹幕到直播间 ${roomId}。`);
|
|
385
|
+
const timer = setTimeout(() => {
|
|
386
|
+
const list1 = pendingDanmakuTimersByMessage.get(session.messageId);
|
|
387
|
+
if (list1) pendingDanmakuTimersByMessage.set(session.messageId, list1.filter((t) => t !== timer));
|
|
388
|
+
const list2 = pendingDanmakuTimersByRoom.get(roomId);
|
|
389
|
+
if (list2) pendingDanmakuTimersByRoom.set(roomId, list2.filter((t) => t !== timer));
|
|
390
|
+
const danmakuPromises = config.biliAccessKeys.map(
|
|
391
|
+
(keyConfig) => sendBilibiliDanmaku(ctx, keyConfig, roomId, "喵喵喵")
|
|
392
|
+
);
|
|
393
|
+
Promise.allSettled(danmakuPromises);
|
|
394
|
+
}, delayMs);
|
|
395
|
+
const byMsg = pendingDanmakuTimersByMessage.get(session.messageId) || [];
|
|
396
|
+
byMsg.push(timer);
|
|
397
|
+
pendingDanmakuTimersByMessage.set(session.messageId, byMsg);
|
|
398
|
+
const byRoom = pendingDanmakuTimersByRoom.get(roomId) || [];
|
|
399
|
+
byRoom.push(timer);
|
|
400
|
+
pendingDanmakuTimersByRoom.set(roomId, byRoom);
|
|
374
401
|
}
|
|
375
402
|
} catch (error) {
|
|
376
403
|
session.send("🐱 - 转发失败,请检查目标QQ/群号配置是否正确");
|
|
@@ -384,6 +411,16 @@ function apply(ctx, config) {
|
|
|
384
411
|
const entryIndex = forwardedHistory.findIndex((entry) => entry.originalMessageId === originalMessageId);
|
|
385
412
|
if (entryIndex !== -1) {
|
|
386
413
|
const entry = forwardedHistory[entryIndex];
|
|
414
|
+
const timersByMsg = pendingDanmakuTimersByMessage.get(originalMessageId);
|
|
415
|
+
if (timersByMsg) {
|
|
416
|
+
for (const t of timersByMsg) clearTimeout(t);
|
|
417
|
+
pendingDanmakuTimersByMessage.delete(originalMessageId);
|
|
418
|
+
}
|
|
419
|
+
const timersByRoom = pendingDanmakuTimersByRoom.get(entry.roomId);
|
|
420
|
+
if (timersByRoom) {
|
|
421
|
+
for (const t of timersByRoom) clearTimeout(t);
|
|
422
|
+
pendingDanmakuTimersByRoom.delete(entry.roomId);
|
|
423
|
+
}
|
|
387
424
|
if (entry.helperMessageId) {
|
|
388
425
|
try {
|
|
389
426
|
await session.bot.deleteMessage(session.channelId, entry.helperMessageId);
|