koishi-plugin-cat-raising 0.1.7 → 0.1.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 +1 -1
- package/lib/index.js +90 -17
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -30,13 +30,62 @@ var name = "cat-raising";
|
|
|
30
30
|
var Config = import_koishi.Schema.object({
|
|
31
31
|
targetQQ: import_koishi.Schema.string().description("目标QQ号或QQ群号").required(),
|
|
32
32
|
isGroup: import_koishi.Schema.boolean().description("是否为QQ群").default(false),
|
|
33
|
-
|
|
33
|
+
monitorGroups: import_koishi.Schema.array(import_koishi.Schema.string()).description("监听的群号列表 (可以添加多个群,插件只会处理这些群里的消息)").required(),
|
|
34
34
|
historySize: import_koishi.Schema.number().description("防复读历史记录大小 (记录最近N条转发信息,防止短期内对同一直播间的同一活动重复转发)").default(30).min(5).max(100)
|
|
35
35
|
});
|
|
36
|
+
function preprocessChineseNumerals(text) {
|
|
37
|
+
const replacements = {
|
|
38
|
+
"三十六": "36",
|
|
39
|
+
"三十五": "35",
|
|
40
|
+
"三十四": "34",
|
|
41
|
+
"三十三": "33",
|
|
42
|
+
"三十二": "32",
|
|
43
|
+
"三十一": "31",
|
|
44
|
+
"三十": "30",
|
|
45
|
+
"二十九": "29",
|
|
46
|
+
"二十八": "28",
|
|
47
|
+
"二十七": "27",
|
|
48
|
+
"二十六": "26",
|
|
49
|
+
"二十五": "25",
|
|
50
|
+
"二十四": "24",
|
|
51
|
+
"二十三": "23",
|
|
52
|
+
"二十二": "22",
|
|
53
|
+
"二十一": "21",
|
|
54
|
+
"二十": "20",
|
|
55
|
+
"十九": "19",
|
|
56
|
+
"十八": "18",
|
|
57
|
+
"十七": "17",
|
|
58
|
+
"十六": "16",
|
|
59
|
+
"十五": "15",
|
|
60
|
+
"十四": "14",
|
|
61
|
+
"十三": "13",
|
|
62
|
+
"十二": "12",
|
|
63
|
+
"十一": "11",
|
|
64
|
+
"十": "10",
|
|
65
|
+
"一千": "1000",
|
|
66
|
+
"一百": "100",
|
|
67
|
+
"九": "9",
|
|
68
|
+
"八": "8",
|
|
69
|
+
"七": "7",
|
|
70
|
+
"六": "6",
|
|
71
|
+
"五": "5",
|
|
72
|
+
"四": "4",
|
|
73
|
+
"三": "3",
|
|
74
|
+
"两": "2",
|
|
75
|
+
"二": "2",
|
|
76
|
+
"一": "1"
|
|
77
|
+
};
|
|
78
|
+
let processedText = text;
|
|
79
|
+
for (const [cn, ar] of Object.entries(replacements)) {
|
|
80
|
+
processedText = processedText.replace(new RegExp(cn, "g"), ar);
|
|
81
|
+
}
|
|
82
|
+
return processedText;
|
|
83
|
+
}
|
|
84
|
+
__name(preprocessChineseNumerals, "preprocessChineseNumerals");
|
|
36
85
|
function extractAllRoomIds(text) {
|
|
37
86
|
const patterns = [
|
|
38
87
|
/(?:播间号|房间号|直播间)[::\s]*(\d{6,15})/g,
|
|
39
|
-
/\b(\d{
|
|
88
|
+
/\b(\d{6,15})\b/g
|
|
40
89
|
];
|
|
41
90
|
const foundIds = /* @__PURE__ */ new Set();
|
|
42
91
|
for (const pattern of patterns) {
|
|
@@ -128,36 +177,38 @@ function parseEvents(text) {
|
|
|
128
177
|
__name(parseEvents, "parseEvents");
|
|
129
178
|
function apply(ctx, config) {
|
|
130
179
|
const forwardedHistory = [];
|
|
180
|
+
const warningMessageMap = /* @__PURE__ */ new Map();
|
|
131
181
|
const REJECTION_KEYWORDS = ["签到", "打卡"];
|
|
132
182
|
const OVERRIDE_KEYWORDS = ["神金", "发"];
|
|
133
183
|
ctx.on("message", async (session) => {
|
|
134
|
-
if (session.channelId
|
|
184
|
+
if (!config.monitorGroups.includes(session.channelId)) return;
|
|
135
185
|
const originalMessageContent = session.content;
|
|
136
186
|
const messageForChecks = session.stripped.content;
|
|
137
187
|
const messageId = session.messageId;
|
|
138
|
-
const triggerRegex = /神金|发|掉落|猫猫钻|w|\b\d{3,5}\b
|
|
188
|
+
const triggerRegex = /神金|发|掉落|猫猫钻|w|\b\d{3,5}\b|一千|一百|十|九|八|七|六|五|四|三|两|二|一/i;
|
|
139
189
|
if (!triggerRegex.test(messageForChecks)) {
|
|
140
190
|
return;
|
|
141
191
|
}
|
|
142
|
-
const
|
|
192
|
+
const roomIds = extractAllRoomIds(messageForChecks);
|
|
193
|
+
if (roomIds.length !== 1) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const roomId = roomIds[0];
|
|
197
|
+
const preprocessedMessage = preprocessChineseNumerals(messageForChecks);
|
|
198
|
+
const hasRejectionKeyword = REJECTION_KEYWORDS.some((keyword) => preprocessedMessage.includes(keyword));
|
|
143
199
|
if (hasRejectionKeyword) {
|
|
144
|
-
const hasOverrideKeyword = OVERRIDE_KEYWORDS.some((keyword) =>
|
|
200
|
+
const hasOverrideKeyword = OVERRIDE_KEYWORDS.some((keyword) => preprocessedMessage.includes(keyword));
|
|
145
201
|
if (!hasOverrideKeyword) {
|
|
146
202
|
ctx.logger.info(`消息包含拒绝关键词且无覆盖词,已忽略: ${messageForChecks.substring(0, 50)}...`);
|
|
147
203
|
return;
|
|
148
204
|
}
|
|
149
205
|
}
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const roomId = roomIds.length === 1 ? roomIds[0] : null;
|
|
155
|
-
const parsedEvents = parseEvents(messageForChecks);
|
|
156
|
-
if (!parsedEvents || !roomId) {
|
|
206
|
+
const parsedEvents = parseEvents(preprocessedMessage);
|
|
207
|
+
if (!parsedEvents) {
|
|
157
208
|
return;
|
|
158
209
|
}
|
|
159
210
|
const strongContextRegex = /神金|发|掉落|猫猫钻|w/i;
|
|
160
|
-
const hasStrongContext = strongContextRegex.test(
|
|
211
|
+
const hasStrongContext = strongContextRegex.test(preprocessedMessage);
|
|
161
212
|
const hasTime = parsedEvents.some((event) => event.dateTime !== "时间未知");
|
|
162
213
|
if (!hasStrongContext && !hasTime) {
|
|
163
214
|
ctx.logger.info(`纯数字信息缺少时间,已忽略: ${messageForChecks.replace(/\s+/g, " ").substring(0, 50)}...`);
|
|
@@ -165,7 +216,19 @@ function apply(ctx, config) {
|
|
|
165
216
|
}
|
|
166
217
|
const currentDateTime = parsedEvents[0].dateTime;
|
|
167
218
|
if (forwardedHistory.some((entry) => entry.roomId === roomId && entry.dateTime === currentDateTime)) {
|
|
168
|
-
|
|
219
|
+
try {
|
|
220
|
+
const sentMessageIds = await session.send(`看到啦看到啦,不要发那么多次嘛~`);
|
|
221
|
+
if (sentMessageIds && sentMessageIds.length > 0) {
|
|
222
|
+
const warningMessageId = sentMessageIds[0];
|
|
223
|
+
warningMessageMap.set(messageId, warningMessageId);
|
|
224
|
+
if (warningMessageMap.size > config.historySize) {
|
|
225
|
+
const oldestKey = warningMessageMap.keys().next().value;
|
|
226
|
+
warningMessageMap.delete(oldestKey);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} catch (e) {
|
|
230
|
+
ctx.logger.warn("发送重复警告消息时失败:", e);
|
|
231
|
+
}
|
|
169
232
|
return;
|
|
170
233
|
}
|
|
171
234
|
let biliInfo = "";
|
|
@@ -190,7 +253,7 @@ function apply(ctx, config) {
|
|
|
190
253
|
helperMessageId = sentMessageIds[0];
|
|
191
254
|
}
|
|
192
255
|
} catch (e) {
|
|
193
|
-
ctx.logger.warn(`向监听群 ${
|
|
256
|
+
ctx.logger.warn(`向监听群 ${session.channelId} 发送B站信息时失败:`, e);
|
|
194
257
|
}
|
|
195
258
|
} catch (error) {
|
|
196
259
|
ctx.logger.warn(`获取直播间 ${roomId} 的B站信息失败: ${error.message}`);
|
|
@@ -210,7 +273,6 @@ function apply(ctx, config) {
|
|
|
210
273
|
originalMessageId: messageId,
|
|
211
274
|
forwardedMessageId,
|
|
212
275
|
helperMessageId,
|
|
213
|
-
// [核心改动 4] 存入历史记录
|
|
214
276
|
originalContent: originalMessageContent,
|
|
215
277
|
roomId,
|
|
216
278
|
dateTime: currentDateTime
|
|
@@ -225,6 +287,7 @@ function apply(ctx, config) {
|
|
|
225
287
|
}
|
|
226
288
|
});
|
|
227
289
|
ctx.on("message-deleted", async (session) => {
|
|
290
|
+
if (!config.monitorGroups.includes(session.channelId)) return;
|
|
228
291
|
const originalMessageId = session.messageId;
|
|
229
292
|
const entryIndex = forwardedHistory.findIndex((entry) => entry.originalMessageId === originalMessageId);
|
|
230
293
|
if (entryIndex !== -1) {
|
|
@@ -245,6 +308,16 @@ function apply(ctx, config) {
|
|
|
245
308
|
} finally {
|
|
246
309
|
forwardedHistory.splice(entryIndex, 1);
|
|
247
310
|
}
|
|
311
|
+
} else if (warningMessageMap.has(originalMessageId)) {
|
|
312
|
+
const warningMessageId = warningMessageMap.get(originalMessageId);
|
|
313
|
+
try {
|
|
314
|
+
await session.bot.deleteMessage(session.channelId, warningMessageId);
|
|
315
|
+
ctx.logger.info(`成功撤回重复提示消息: ${warningMessageId}`);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
ctx.logger.error(`撤回重复提示消息 (ID: ${warningMessageId}) 失败:`, error);
|
|
318
|
+
} finally {
|
|
319
|
+
warningMessageMap.delete(originalMessageId);
|
|
320
|
+
}
|
|
248
321
|
}
|
|
249
322
|
});
|
|
250
323
|
}
|