koishi-plugin-onebot-verifier 1.1.7 → 1.1.9
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 +2 -0
- package/lib/index.js +37 -12
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -14,10 +14,12 @@ export interface Config {
|
|
|
14
14
|
minMembers?: number;
|
|
15
15
|
maxCapacity?: number;
|
|
16
16
|
memberTimeout: false | number;
|
|
17
|
+
frequencyMode: 'delay' | 'ignore' | 'reject';
|
|
17
18
|
verifyRules?: {
|
|
18
19
|
guildId: string;
|
|
19
20
|
keyword?: string;
|
|
20
21
|
minLevel?: number;
|
|
22
|
+
frequency?: number;
|
|
21
23
|
action?: 'accept' | 'reject';
|
|
22
24
|
}[];
|
|
23
25
|
specialRules?: {
|
package/lib/index.js
CHANGED
|
@@ -51,7 +51,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
51
51
|
import_koishi.Schema.object({
|
|
52
52
|
friendTimeout: import_koishi.Schema.union([
|
|
53
53
|
import_koishi.Schema.const(false).description("手动"),
|
|
54
|
-
import_koishi.Schema.number().description("
|
|
54
|
+
import_koishi.Schema.number().description("自动").default(360)
|
|
55
55
|
]).description("超时处理").default(false),
|
|
56
56
|
friendLevel: import_koishi.Schema.number().description("最低好友等级").default(0).min(0).max(256),
|
|
57
57
|
friendRegex: import_koishi.Schema.string().description("好友验证正则"),
|
|
@@ -61,40 +61,47 @@ var Config = import_koishi.Schema.intersect([
|
|
|
61
61
|
import_koishi.Schema.object({
|
|
62
62
|
memberTimeout: import_koishi.Schema.union([
|
|
63
63
|
import_koishi.Schema.const(false).description("手动"),
|
|
64
|
-
import_koishi.Schema.number().description("
|
|
64
|
+
import_koishi.Schema.number().description("自动").default(360)
|
|
65
65
|
]).description("超时处理").default(false),
|
|
66
|
+
frequencyMode: import_koishi.Schema.union([
|
|
67
|
+
import_koishi.Schema.const("delay").description("延时"),
|
|
68
|
+
import_koishi.Schema.const("ignore").description("忽略"),
|
|
69
|
+
import_koishi.Schema.const("reject").description("拒绝")
|
|
70
|
+
]).description("频率限制").default("delay"),
|
|
66
71
|
verifyRules: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
67
72
|
guildId: import_koishi.Schema.string().description("群号").required(),
|
|
68
73
|
keyword: import_koishi.Schema.string().description("正则"),
|
|
69
74
|
minLevel: import_koishi.Schema.number().description("等级").default(0),
|
|
75
|
+
frequency: import_koishi.Schema.number().description("频率").default(0),
|
|
70
76
|
action: import_koishi.Schema.union([
|
|
71
77
|
import_koishi.Schema.const("accept").description("同意"),
|
|
72
78
|
import_koishi.Schema.const("reject").description("拒绝")
|
|
73
79
|
]).description("操作")
|
|
74
|
-
})).description("
|
|
75
|
-
}).description("加群请求配置"),
|
|
76
|
-
import_koishi.Schema.object({
|
|
80
|
+
})).description("普通验证").role("table"),
|
|
77
81
|
specialRules: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
78
82
|
guildId: import_koishi.Schema.string().description("群号").required(),
|
|
79
83
|
mode: import_koishi.Schema.union([
|
|
80
84
|
import_koishi.Schema.const("vote").description("投票"),
|
|
81
85
|
import_koishi.Schema.const("captcha").description("验证码")
|
|
82
86
|
]).description("模式").default("vote")
|
|
83
|
-
})).description("
|
|
87
|
+
})).description("高级验证").role("table")
|
|
88
|
+
}).description("加群请求配置"),
|
|
89
|
+
import_koishi.Schema.object({
|
|
90
|
+
voteInSitu: import_koishi.Schema.boolean().description("[投票]原群投票模式").default(true),
|
|
84
91
|
voteRatio: import_koishi.Schema.string().description("[投票]支持/反对人数").default("3:2"),
|
|
85
|
-
voteInSitu: import_koishi.Schema.boolean().description("[投票]对应群中发起").default(true),
|
|
86
92
|
captchaDiff: import_koishi.Schema.union([
|
|
87
93
|
import_koishi.Schema.const("simple").description("简单"),
|
|
88
94
|
import_koishi.Schema.const("medium").description("中等"),
|
|
89
95
|
import_koishi.Schema.const("hard").description("困难")
|
|
90
|
-
]).description("[验证]
|
|
91
|
-
}).description("
|
|
96
|
+
]).description("[验证]计算难度").default("simple")
|
|
97
|
+
}).description("模式配置")
|
|
92
98
|
]);
|
|
93
99
|
function apply(ctx, config) {
|
|
94
100
|
const logger = new import_koishi.Logger("onebot-verifier");
|
|
95
101
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
96
102
|
const activeCaptchas = /* @__PURE__ */ new Map();
|
|
97
103
|
const inviterMap = /* @__PURE__ */ new Map();
|
|
104
|
+
const requestMap = /* @__PURE__ */ new Map();
|
|
98
105
|
const getComment = /* @__PURE__ */ __name((comment) => {
|
|
99
106
|
if (!comment) return "";
|
|
100
107
|
const lines = comment.split(/[\r\n]+/).map((s) => s.trim());
|
|
@@ -154,7 +161,7 @@ function apply(ctx, config) {
|
|
|
154
161
|
return [];
|
|
155
162
|
}
|
|
156
163
|
}, "sendNotice");
|
|
157
|
-
const setupManual = /* @__PURE__ */ __name(async (session, kind, specialMode, useInSitu) => {
|
|
164
|
+
const setupManual = /* @__PURE__ */ __name(async (session, kind, specialMode, useInSitu, forceTimeoutResult) => {
|
|
158
165
|
const timeoutCfg = kind === "member" ? config.memberTimeout : config.friendTimeout;
|
|
159
166
|
let targetStr = config.notifyTarget || "";
|
|
160
167
|
if (useInSitu && kind === "member" && session.guildId) targetStr = `guild:${session.guildId}`;
|
|
@@ -169,7 +176,7 @@ function apply(ctx, config) {
|
|
|
169
176
|
msgIds.forEach((id) => activeTasks.set(id, task));
|
|
170
177
|
if (typeof timeoutCfg === "number") {
|
|
171
178
|
const waitMinutes = Math.abs(timeoutCfg);
|
|
172
|
-
const isPass = timeoutCfg > 0;
|
|
179
|
+
const isPass = forceTimeoutResult !== void 0 ? forceTimeoutResult : timeoutCfg > 0;
|
|
173
180
|
task.timer = setTimeout(async () => {
|
|
174
181
|
if (!activeTasks.has(msgIds[0])) return;
|
|
175
182
|
msgIds.forEach((id) => activeTasks.delete(id));
|
|
@@ -204,8 +211,25 @@ function apply(ctx, config) {
|
|
|
204
211
|
if (rule.keyword) logger.info(`[加群请求] ${session.userId} 内容 "${verifyText}" ${keywordMatch ? "=" : "≠"} "${rule.keyword}"`);
|
|
205
212
|
}
|
|
206
213
|
if (levelMatch && keywordMatch) {
|
|
214
|
+
const historyKey = `${session.userId}:${session.guildId}`;
|
|
215
|
+
const lastTime = requestMap.get(historyKey) || 0;
|
|
216
|
+
const now = Date.now();
|
|
217
|
+
const isFrequent = rule.frequency && now - lastTime < rule.frequency * 6e4;
|
|
218
|
+
if (isFrequent) {
|
|
219
|
+
requestMap.set(historyKey, now);
|
|
220
|
+
if (config.frequencyMode === "reject") {
|
|
221
|
+
await executeAction(session, kind, false, "频繁申请,自动拒绝");
|
|
222
|
+
await sendNotice(session, kind, "auto_reject");
|
|
223
|
+
return;
|
|
224
|
+
} else if (config.frequencyMode === "ignore") {
|
|
225
|
+
return await setupManual(session, kind);
|
|
226
|
+
} else if (config.frequencyMode === "delay") {
|
|
227
|
+
return await setupManual(session, kind, void 0, false, rule.action === "accept");
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
requestMap.set(historyKey, now);
|
|
207
231
|
if (rule.action) {
|
|
208
|
-
await executeAction(session, kind, rule.action === "accept", rule.action === "accept" ? "" : "
|
|
232
|
+
await executeAction(session, kind, rule.action === "accept", rule.action === "accept" ? "" : "错误回答,自动拒绝");
|
|
209
233
|
await sendNotice(session, kind, rule.action === "accept" ? "auto_pass" : "auto_reject");
|
|
210
234
|
return;
|
|
211
235
|
}
|
|
@@ -343,6 +367,7 @@ function apply(ctx, config) {
|
|
|
343
367
|
});
|
|
344
368
|
ctx.on("guild-removed", async (session) => {
|
|
345
369
|
if (session.guildId) {
|
|
370
|
+
if (config.debugMode) logger.info(`[事件] 退出: ${session.guildId} 数据: ${JSON.stringify(session.event?._data)}`);
|
|
346
371
|
const eventData = session.event?._data || {};
|
|
347
372
|
if (eventData.sub_type === "kick_me") {
|
|
348
373
|
const inviterId = inviterMap.get(session.guildId);
|