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 CHANGED
@@ -3,7 +3,7 @@ export declare const name = "cat-raising";
3
3
  export interface Config {
4
4
  targetQQ: string;
5
5
  isGroup: boolean;
6
- monitorGroup: string;
6
+ monitorGroups: string[];
7
7
  historySize: number;
8
8
  }
9
9
  export declare const Config: Schema<Config>;
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
- monitorGroup: import_koishi.Schema.string().description("监听的群号(只检测此群的消息)").required(),
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{8,15})\b/g
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 !== config.monitorGroup) return;
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/i;
188
+ const triggerRegex = /神金|发|掉落|猫猫钻|w|\b\d{3,5}\b|一千|一百|十|九|八|七|六|五|四|三|两|二|一/i;
139
189
  if (!triggerRegex.test(messageForChecks)) {
140
190
  return;
141
191
  }
142
- const hasRejectionKeyword = REJECTION_KEYWORDS.some((keyword) => messageForChecks.includes(keyword));
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) => messageForChecks.includes(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 roomIds = extractAllRoomIds(messageForChecks);
151
- if (roomIds.length > 1) {
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(messageForChecks);
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
- session.send(`看到啦看到啦,不要发那么多次嘛~`);
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(`向监听群 ${config.monitorGroup} 发送B站信息时失败:`, e);
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
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-cat-raising",
3
3
  "description": "",
4
- "version": "0.1.7",
4
+ "version": "0.1.8",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [