koishi-plugin-onebot-verifier 1.0.10 → 1.1.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.d.ts +4 -2
- package/lib/index.js +88 -26
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -21,12 +21,14 @@ export interface Config {
|
|
|
21
21
|
minLevel?: number;
|
|
22
22
|
action?: 'accept' | 'reject';
|
|
23
23
|
}[];
|
|
24
|
-
voteRatio?: string;
|
|
25
24
|
syncNotify?: boolean;
|
|
26
25
|
specialRules?: {
|
|
27
26
|
guildId: string;
|
|
28
|
-
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
mode: 'vote' | 'captcha';
|
|
29
29
|
}[];
|
|
30
|
+
captchaDiff?: 'simple' | 'medium' | 'hard';
|
|
31
|
+
voteRatio?: string;
|
|
30
32
|
}
|
|
31
33
|
export declare const Config: Schema<Config>;
|
|
32
34
|
export declare function apply(ctx: Context, config?: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -73,22 +73,30 @@ var Config = import_koishi.Schema.intersect([
|
|
|
73
73
|
import_koishi.Schema.const("accept").description("同意"),
|
|
74
74
|
import_koishi.Schema.const("reject").description("拒绝")
|
|
75
75
|
]).description("操作")
|
|
76
|
-
})).description("
|
|
76
|
+
})).description("普通验证配置").role("table")
|
|
77
77
|
}).description("加群请求配置"),
|
|
78
78
|
import_koishi.Schema.object({
|
|
79
79
|
syncNotify: import_koishi.Schema.boolean().description("同步通知目标").default(true),
|
|
80
80
|
specialRules: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
81
81
|
guildId: import_koishi.Schema.string().description("群号").required(),
|
|
82
82
|
mode: import_koishi.Schema.union([
|
|
83
|
-
import_koishi.Schema.const("vote").description("投票")
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
import_koishi.Schema.const("vote").description("投票"),
|
|
84
|
+
import_koishi.Schema.const("captcha").description("验证码")
|
|
85
|
+
]).description("模式").default("vote"),
|
|
86
|
+
enabled: import_koishi.Schema.boolean().description("前置规则").default(true)
|
|
87
|
+
})).description("配置列表").role("table"),
|
|
88
|
+
voteRatio: import_koishi.Schema.string().description("[投票]人数").default("3:2"),
|
|
89
|
+
captchaDiff: import_koishi.Schema.union([
|
|
90
|
+
import_koishi.Schema.const("simple").description("简单"),
|
|
91
|
+
import_koishi.Schema.const("medium").description("中等"),
|
|
92
|
+
import_koishi.Schema.const("hard").description("困难")
|
|
93
|
+
]).description("[验证码]难度").default("simple")
|
|
87
94
|
}).description("特殊验证配置")
|
|
88
95
|
]);
|
|
89
96
|
function apply(ctx, config = {}) {
|
|
90
97
|
const logger = new import_koishi.Logger("onebot-verifier");
|
|
91
98
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
99
|
+
const activeCaptchas = /* @__PURE__ */ new Map();
|
|
92
100
|
const inviterMap = /* @__PURE__ */ new Map();
|
|
93
101
|
const getComment = /* @__PURE__ */ __name((comment) => {
|
|
94
102
|
if (!comment) return "";
|
|
@@ -149,24 +157,6 @@ function apply(ctx, config = {}) {
|
|
|
149
157
|
return [];
|
|
150
158
|
}
|
|
151
159
|
}, "sendNotice");
|
|
152
|
-
const handleSpecialRule = /* @__PURE__ */ __name(async (session, kind) => {
|
|
153
|
-
if (kind !== "member" || !config.specialRules || config.specialRules.length === 0) return false;
|
|
154
|
-
const rule = config.specialRules.find((r) => String(r.guildId) === String(session.guildId));
|
|
155
|
-
if (!rule) return false;
|
|
156
|
-
if (rule.mode === "vote") {
|
|
157
|
-
const [yesStr, noStr] = config.voteRatio.split(":");
|
|
158
|
-
const targetYes = parseInt(yesStr) || 0;
|
|
159
|
-
const targetNo = parseInt(noStr) || 0;
|
|
160
|
-
let msgIds = [];
|
|
161
|
-
if (config.syncNotify !== false) msgIds = await sendNotice(session, kind, "waiting");
|
|
162
|
-
if (msgIds.length > 0) {
|
|
163
|
-
const task = { session, kind, messages: msgIds, specialMode: "vote", voteTarget: { yes: targetYes, no: targetNo }, votes: { yes: /* @__PURE__ */ new Set(), no: /* @__PURE__ */ new Set() } };
|
|
164
|
-
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
165
|
-
}
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
return false;
|
|
169
|
-
}, "handleSpecialRule");
|
|
170
160
|
const setupManual = /* @__PURE__ */ __name(async (session, kind) => {
|
|
171
161
|
const waitMinutes = config.timeout ?? 0;
|
|
172
162
|
const action = kind === "member" ? config.verifyMode : config.timeoutAction;
|
|
@@ -206,7 +196,6 @@ function apply(ctx, config = {}) {
|
|
|
206
196
|
if (config.debugMode) logger.info(`[收到请求] 类型: ${kind} 数据: ${JSON.stringify(session.event?._data || {})}`);
|
|
207
197
|
const verifyText = getComment(session.event?._data?.comment);
|
|
208
198
|
if (kind === "member") {
|
|
209
|
-
if (await handleSpecialRule(session, kind)) return;
|
|
210
199
|
const rules = config.verifyRules?.filter((r) => String(r.guildId) === String(session.guildId)) || [];
|
|
211
200
|
for (const rule of rules) {
|
|
212
201
|
const minL = rule.minLevel ?? 0;
|
|
@@ -224,9 +213,29 @@ function apply(ctx, config = {}) {
|
|
|
224
213
|
return;
|
|
225
214
|
}
|
|
226
215
|
}
|
|
216
|
+
const specialRule = config.specialRules?.find((r) => String(r.guildId) === String(session.guildId) && r.enabled);
|
|
217
|
+
if (specialRule) {
|
|
218
|
+
if (specialRule.mode === "vote") {
|
|
219
|
+
const [yesStr, noStr] = config.voteRatio.split(":");
|
|
220
|
+
const targetYes = parseInt(yesStr) || 0;
|
|
221
|
+
const targetNo = parseInt(noStr) || 0;
|
|
222
|
+
let msgIds = [];
|
|
223
|
+
if (config.syncNotify !== false) msgIds = await sendNotice(session, kind, "waiting");
|
|
224
|
+
if (msgIds.length > 0) {
|
|
225
|
+
const task = { session, kind, messages: msgIds, specialMode: "vote", voteTarget: { yes: targetYes, no: targetNo }, votes: { yes: /* @__PURE__ */ new Set(), no: /* @__PURE__ */ new Set() } };
|
|
226
|
+
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (specialRule.mode === "captcha") {
|
|
231
|
+
await executeAction(session, kind, true, "验证码验证,自动通过");
|
|
232
|
+
if (config.syncNotify !== false) await sendNotice(session, kind, "auto_pass");
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
227
236
|
if (config.verifyMode && config.verifyMode !== "manual") {
|
|
228
237
|
const isApprove = config.verifyMode === "accept";
|
|
229
|
-
await executeAction(session, kind, isApprove, "
|
|
238
|
+
await executeAction(session, kind, isApprove, "默认规则,自动处理");
|
|
230
239
|
await sendNotice(session, kind, isApprove ? "auto_pass" : "auto_reject");
|
|
231
240
|
return;
|
|
232
241
|
}
|
|
@@ -317,6 +326,45 @@ function apply(ctx, config = {}) {
|
|
|
317
326
|
ctx.on("guild-request", hookEvent("guild"));
|
|
318
327
|
ctx.on("guild-member-request", hookEvent("member"));
|
|
319
328
|
ctx.on("guild-added", hookEvent("guild"));
|
|
329
|
+
ctx.on("guild-member-added", async (session) => {
|
|
330
|
+
if (!config.specialRules || !session.guildId || !session.userId) return;
|
|
331
|
+
const rule = config.specialRules.find((r) => String(r.guildId) === String(session.guildId) && r.enabled);
|
|
332
|
+
if (rule?.mode === "captcha") {
|
|
333
|
+
let a, b, op = "+", answer;
|
|
334
|
+
if (config.captchaDiff === "simple") {
|
|
335
|
+
a = Math.floor(Math.random() * 80) + 10;
|
|
336
|
+
b = Math.floor(Math.random() * 80) + 10;
|
|
337
|
+
if (Math.random() > 0.5) {
|
|
338
|
+
op = "+";
|
|
339
|
+
answer = (a + b).toString();
|
|
340
|
+
} else {
|
|
341
|
+
op = "-";
|
|
342
|
+
if (a < b) [a, b] = [b, a];
|
|
343
|
+
answer = (a - b).toString();
|
|
344
|
+
}
|
|
345
|
+
} else if (config.captchaDiff === "medium") {
|
|
346
|
+
a = Math.floor(Math.random() * 89) + 11;
|
|
347
|
+
b = Math.floor(Math.random() * 8) + 2;
|
|
348
|
+
op = "×";
|
|
349
|
+
answer = (a * b).toString();
|
|
350
|
+
} else {
|
|
351
|
+
a = Math.floor(Math.random() * 40) + 11;
|
|
352
|
+
b = Math.floor(Math.random() * 10) + 11;
|
|
353
|
+
op = "×";
|
|
354
|
+
answer = (a * b).toString();
|
|
355
|
+
}
|
|
356
|
+
const captchaKey = `${session.guildId}:${session.userId}`;
|
|
357
|
+
await session.send(`<at id="${session.userId}"/> 请在 60 秒内回复计算结果,以进行验证:${a} ${op} ${b} =`);
|
|
358
|
+
const timer = setTimeout(async () => {
|
|
359
|
+
if (activeCaptchas.has(captchaKey)) {
|
|
360
|
+
activeCaptchas.delete(captchaKey);
|
|
361
|
+
await session.send(`<at id="${session.userId}"/> 验证失败,将被移出本群。`);
|
|
362
|
+
await session.onebot?.setGroupKick(session.guildId, session.userId, false);
|
|
363
|
+
}
|
|
364
|
+
}, 6e4);
|
|
365
|
+
activeCaptchas.set(captchaKey, { guildId: session.guildId, userId: session.userId, answer, timer });
|
|
366
|
+
}
|
|
367
|
+
});
|
|
320
368
|
ctx.on("guild-removed", async (session) => {
|
|
321
369
|
if (session.event?._data?.sub_type === "kick_me") {
|
|
322
370
|
const gid = session.guildId;
|
|
@@ -335,7 +383,21 @@ function apply(ctx, config = {}) {
|
|
|
335
383
|
await sendNotice(session, "removed");
|
|
336
384
|
});
|
|
337
385
|
ctx.middleware(async (session, next) => {
|
|
338
|
-
if (typeof session.content !== "string"
|
|
386
|
+
if (typeof session.content !== "string") return next();
|
|
387
|
+
if (session.guildId && session.userId) {
|
|
388
|
+
const captchaKey = `${session.guildId}:${session.userId}`;
|
|
389
|
+
const captcha = activeCaptchas.get(captchaKey);
|
|
390
|
+
if (captcha) {
|
|
391
|
+
const input2 = session.content.trim();
|
|
392
|
+
if (input2 === captcha.answer) {
|
|
393
|
+
clearTimeout(captcha.timer);
|
|
394
|
+
activeCaptchas.delete(captchaKey);
|
|
395
|
+
await session.send(`<at id="${session.userId}"/> 验证成功,欢迎加入本群!`);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (!session.quote?.id) return next();
|
|
339
401
|
const task = activeTasks.get(session.quote.id);
|
|
340
402
|
if (!task) return next();
|
|
341
403
|
const [targetType, targetId] = (config.notifyTarget || "").split(":");
|