koishi-plugin-onebot-verifier 1.2.0 → 1.2.1
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.js +24 -36
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -101,8 +101,7 @@ function apply(ctx, config) {
|
|
|
101
101
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
102
102
|
const activeCaptchas = /* @__PURE__ */ new Map();
|
|
103
103
|
const inviterMap = /* @__PURE__ */ new Map();
|
|
104
|
-
const
|
|
105
|
-
const recentRemovals = /* @__PURE__ */ new Map();
|
|
104
|
+
const historyMap = /* @__PURE__ */ new Map();
|
|
106
105
|
const getComment = /* @__PURE__ */ __name((comment) => {
|
|
107
106
|
if (!comment) return "";
|
|
108
107
|
const lines = comment.split(/[\r\n]+/).map((s) => s.trim());
|
|
@@ -212,7 +211,7 @@ function apply(ctx, config) {
|
|
|
212
211
|
}
|
|
213
212
|
const verifyText = getComment(eventData.comment);
|
|
214
213
|
if (kind === "member") {
|
|
215
|
-
const rules = config.verifyRules?.filter((r) =>
|
|
214
|
+
const rules = config.verifyRules?.filter((r) => r.guildId === session.guildId) || [];
|
|
216
215
|
for (const rule of rules) {
|
|
217
216
|
const stats = (rule.minLevel ?? 0) > 0 && session.onebot && session.userId ? await session.onebot.getStrangerInfo(session.userId, true).catch(() => ({})) : null;
|
|
218
217
|
const levelMatch = (stats?.qqLevel ?? 0) >= (rule.minLevel ?? 0);
|
|
@@ -222,12 +221,9 @@ function apply(ctx, config) {
|
|
|
222
221
|
if (rule.keyword) logger.info(`[加群请求] ${session.userId} 内容 "${verifyText}" ${keywordMatch ? "=" : "≠"} "${rule.keyword}"`);
|
|
223
222
|
}
|
|
224
223
|
if (levelMatch && keywordMatch) {
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
const now = Date.now();
|
|
228
|
-
const isFrequent = rule.frequency && now - lastTime < rule.frequency * 6e4;
|
|
224
|
+
const lastLeaveTime = historyMap.get(`${session.userId}:${session.guildId}`) || 0;
|
|
225
|
+
const isFrequent = rule.frequency && Date.now() - lastLeaveTime < rule.frequency * 6e4;
|
|
229
226
|
if (isFrequent) {
|
|
230
|
-
requestMap.set(historyKey, now);
|
|
231
227
|
if (config.frequencyMode === "reject") {
|
|
232
228
|
await executeAction(session, kind, false, "频繁申请,自动拒绝");
|
|
233
229
|
await sendNotice(session, kind, "auto_reject");
|
|
@@ -238,7 +234,6 @@ function apply(ctx, config) {
|
|
|
238
234
|
return await setupManual(session, kind, void 0, false, rule.action === "accept");
|
|
239
235
|
}
|
|
240
236
|
}
|
|
241
|
-
requestMap.set(historyKey, now);
|
|
242
237
|
if (rule.action) {
|
|
243
238
|
await executeAction(session, kind, rule.action === "accept", rule.action === "accept" ? "" : "错误回答,自动拒绝");
|
|
244
239
|
await sendNotice(session, kind, rule.action === "accept" ? "auto_pass" : "auto_reject");
|
|
@@ -246,7 +241,7 @@ function apply(ctx, config) {
|
|
|
246
241
|
}
|
|
247
242
|
}
|
|
248
243
|
}
|
|
249
|
-
const specialRule = config.specialRules?.find((r) =>
|
|
244
|
+
const specialRule = config.specialRules?.find((r) => r.guildId === session.guildId);
|
|
250
245
|
if (specialRule) {
|
|
251
246
|
if (specialRule.mode === "vote") return await setupManual(session, kind, "vote", config.voteInSitu);
|
|
252
247
|
if (specialRule.mode === "captcha") {
|
|
@@ -337,9 +332,13 @@ function apply(ctx, config) {
|
|
|
337
332
|
ctx.on("guild-request", hookEvent("guild"));
|
|
338
333
|
ctx.on("guild-member-request", hookEvent("member"));
|
|
339
334
|
ctx.on("guild-added", hookEvent("guild"));
|
|
335
|
+
ctx.on("guild-member-removed", async (session) => {
|
|
336
|
+
if (!session.guildId || !session.userId) return;
|
|
337
|
+
if (config.verifyRules?.some((r) => r.guildId === session.guildId)) historyMap.set(`${session.userId}:${session.guildId}`, Date.now());
|
|
338
|
+
});
|
|
340
339
|
ctx.on("guild-member-added", async (session) => {
|
|
341
340
|
if (!config.specialRules || !session.guildId || !session.userId) return;
|
|
342
|
-
const rule = config.specialRules.find((r) =>
|
|
341
|
+
const rule = config.specialRules.find((r) => r.guildId === session.guildId);
|
|
343
342
|
if (rule?.mode === "captcha") {
|
|
344
343
|
let a, b, op = "+", answer;
|
|
345
344
|
if (config.captchaDiff === "simple") {
|
|
@@ -364,24 +363,23 @@ function apply(ctx, config) {
|
|
|
364
363
|
op = "×";
|
|
365
364
|
answer = (a * b).toString();
|
|
366
365
|
}
|
|
367
|
-
const captchaKey = `${session.guildId}:${session.userId}`;
|
|
368
366
|
await session.send(`<at id="${session.userId}"/> 请在 60 秒内回复计算结果,以进行验证:${a} ${op} ${b} =`);
|
|
369
367
|
const timer = setTimeout(async () => {
|
|
370
|
-
if (activeCaptchas.has(
|
|
371
|
-
activeCaptchas.delete(
|
|
368
|
+
if (activeCaptchas.has(`${session.userId}:${session.guildId}`)) {
|
|
369
|
+
activeCaptchas.delete(`${session.userId}:${session.guildId}`);
|
|
372
370
|
await session.send(`<at id="${session.userId}"/> 验证失败,将被移出本群。`);
|
|
373
371
|
await session.onebot?.setGroupKick(session.guildId, session.userId, false);
|
|
374
372
|
}
|
|
375
373
|
}, 6e4);
|
|
376
|
-
activeCaptchas.set(
|
|
374
|
+
activeCaptchas.set(`${session.userId}:${session.guildId}`, { guildId: session.guildId, userId: session.userId, answer, timer });
|
|
377
375
|
}
|
|
378
376
|
});
|
|
379
377
|
ctx.on("guild-removed", async (session) => {
|
|
380
378
|
if (session.guildId) {
|
|
381
379
|
const eventData = session.event?._data || {};
|
|
382
380
|
const curTime = eventData.time || 0;
|
|
383
|
-
if (Math.abs(curTime - (
|
|
384
|
-
|
|
381
|
+
if (Math.abs(curTime - (historyMap.get(session.guildId) || 0)) < 300) return;
|
|
382
|
+
historyMap.set(session.guildId, curTime);
|
|
385
383
|
if (config.debugMode) logger.info(`[事件] 退出: ${session.guildId} 数据: ${JSON.stringify(eventData)}`);
|
|
386
384
|
if (eventData.sub_type === "kick_me") {
|
|
387
385
|
const inviterId = inviterMap.get(session.guildId);
|
|
@@ -407,40 +405,30 @@ function apply(ctx, config) {
|
|
|
407
405
|
ctx.middleware(async (session, next) => {
|
|
408
406
|
if (typeof session.content !== "string") return next();
|
|
409
407
|
if (session.guildId && session.userId) {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
activeCaptchas.delete(captchaKey);
|
|
417
|
-
await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
408
|
+
const captcha = activeCaptchas.get(`${session.userId}:${session.guildId}`);
|
|
409
|
+
if (captcha && session.content.trim() === captcha.answer) {
|
|
410
|
+
clearTimeout(captcha.timer);
|
|
411
|
+
activeCaptchas.delete(`${session.userId}:${session.guildId}`);
|
|
412
|
+
await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
|
|
413
|
+
return;
|
|
420
414
|
}
|
|
421
415
|
}
|
|
422
416
|
if (!session.quote?.id) return next();
|
|
423
417
|
const task = activeTasks.get(session.quote.id);
|
|
424
418
|
if (!task) return next();
|
|
425
419
|
const [ntType, ntId] = (config.notifyTarget || "").split(":");
|
|
426
|
-
|
|
427
|
-
const isInSituGuild = task.inSitu && session.guildId && session.guildId === task.session.guildId;
|
|
428
|
-
if (!isGlobalNotifyTarget && !isInSituGuild) return next();
|
|
420
|
+
if ((ntType === "private" ? session.userId !== ntId : session.guildId !== ntId) && !(task.inSitu && session.guildId === task.session.guildId)) return next();
|
|
429
421
|
const input = session.content.replace(/<(quote|at)\s+[^>]*\/>/gi, "").trim();
|
|
430
422
|
const cmdMatch = input.match(/^(y|n|通过|拒绝)(?:\s+(.*))?$/i);
|
|
431
423
|
if (!cmdMatch) return next();
|
|
432
424
|
const isApprove = ["y", "通过"].includes(cmdMatch[1].toLowerCase());
|
|
433
425
|
const extraInfo = cmdMatch[2]?.trim() || "";
|
|
434
426
|
if (config.debugMode) logger.info(`[操作] 收到指令: ${isApprove ? "同意" : "拒绝"}`);
|
|
435
|
-
if (task.specialMode === "vote")
|
|
436
|
-
await handleSpecialVote(session, task, isApprove, extraInfo);
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
427
|
+
if (task.specialMode === "vote") return await handleSpecialVote(session, task, isApprove, extraInfo);
|
|
439
428
|
if (task.timer) clearTimeout(task.timer);
|
|
440
429
|
task.messages.forEach((msg) => activeTasks.delete(msg));
|
|
441
430
|
const isSuccess = await executeAction(task.session, task.kind, isApprove, isApprove ? "" : extraInfo, isApprove && task.kind === "friend" ? extraInfo : "");
|
|
442
|
-
|
|
443
|
-
await session.send(replyText).catch(() => {
|
|
431
|
+
await session.send(isSuccess ? `已${isApprove ? "通过" : "拒绝"}该请求` : `处理请求失败`).catch(() => {
|
|
444
432
|
});
|
|
445
433
|
});
|
|
446
434
|
}
|
package/package.json
CHANGED