mirror of
https://github.com/Jerryplusy/crystelf-plugin.git
synced 2025-10-14 05:39:18 +00:00
Compare commits
No commits in common. "34ac5c631e00a8ed6b51ab81f82fb865ddd2149f" and "c764ecc9f99a643a11f1ec96217cdbe52fa95105" have entirely different histories.
34ac5c631e
...
c764ecc9f9
329
apps/auth.js
329
apps/auth.js
@ -4,7 +4,6 @@ import tools from '../components/tool.js';
|
||||
import Group from '../lib/yunzai/group.js';
|
||||
import Message from '../lib/yunzai/message.js';
|
||||
|
||||
let pending = new Map();
|
||||
export class CarbonAuth extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
@ -17,6 +16,167 @@ export class CarbonAuth extends plugin {
|
||||
{ reg: '^#重新验证([\\s\\S]*)?$', fnc: 'cmdRevalidate' },
|
||||
],
|
||||
});
|
||||
this.pending = new Map();
|
||||
|
||||
//答案监听
|
||||
Bot.on?.('message.group', async (e) => {
|
||||
const key = `${e.group_id}_${e.user_id}`;
|
||||
//logger.info(key);
|
||||
const session = this.pending.get(key);
|
||||
if (!session) return;
|
||||
session.tries++;
|
||||
const { type, answer, tries, cfg } = session;
|
||||
|
||||
const pass = async () => {
|
||||
this.pending.delete(key);
|
||||
const redisKey = `Yz:pendingWelcome:${e.group_id}:${e.user_id}`;
|
||||
const cached = await redis.get(redisKey);
|
||||
if (cached) {
|
||||
try {
|
||||
const msgList = JSON.parse(cached);
|
||||
await e.reply(msgList);
|
||||
} finally {
|
||||
await redis.del(redisKey);
|
||||
}
|
||||
} else {
|
||||
return await e.reply('验证通过,欢迎加入本群~', true);
|
||||
}
|
||||
};
|
||||
|
||||
if (type === 'math') {
|
||||
const msgStr = (e.message || [])
|
||||
.filter((m) => m.type === 'text')
|
||||
.map((m) => m.text)
|
||||
.join('')
|
||||
.trim();
|
||||
const num = parseInt(msgStr, 10);
|
||||
if (!isNaN(num) && num === answer) return pass();
|
||||
if (tries >= cfg.frequency) {
|
||||
this.pending.delete(key);
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
e.reply([segment.at(e.user_id), '验证失败,你错太多次辣!'], true);
|
||||
return await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
return e.reply(
|
||||
[segment.at(e.user_id), `回答错了呢,你还有${cfg.frequency - tries}次机会,再试试看?`],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (type === 'carbon') {
|
||||
const msgStr = (e.message || [])
|
||||
.filter((m) => m.type === 'text')
|
||||
.map((m) => m.text)
|
||||
.join('');
|
||||
const msgRegions = msgStr
|
||||
.toUpperCase()
|
||||
.replace(/,/g, ',')
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
const rightRegions = answer.map((r) => r.toUpperCase());
|
||||
|
||||
let correct;
|
||||
if (cfg.carbon['hard-mode']) {
|
||||
correct = rightRegions.every((r) => msgRegions.includes(r));
|
||||
} else {
|
||||
correct = rightRegions.some((r) => msgRegions.includes(r));
|
||||
}
|
||||
|
||||
if (correct) return pass();
|
||||
if (tries >= cfg.frequency) {
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
this.pending.delete(key);
|
||||
e.reply([segment.at(e.user_id), '验证失败,你错太多次辣!'], true);
|
||||
return await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
return e.reply(
|
||||
[segment.at(e.user_id), `回答错了呢,你还有${cfg.frequency - tries}次机会,再试试看?`],
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
//主动退群
|
||||
Bot.on?.('notice.group.decrease', async (e) => {
|
||||
const key = `${e.group_id}_${e.user_id}`;
|
||||
if (this.pending.has(key)) {
|
||||
this.pending.delete(key);
|
||||
logger.mark(`[crystelf-plugin] 用户 ${e.user_id} 主动退群,验证流程结束..`);
|
||||
e.reply('害,怎么跑路了');
|
||||
}
|
||||
});
|
||||
|
||||
//加群事件
|
||||
Bot.on?.('notice.group.increase', async (e) => {
|
||||
if (e.isMaster) return true;
|
||||
await this.auth(e, e.group_id, e.user_id);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证
|
||||
* @param e 事件
|
||||
* @param group_id 群号
|
||||
* @param user_id 带验证用户id
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
async auth(e, group_id, user_id) {
|
||||
const cfg = await configControl.get('auth');
|
||||
if (!cfg) return;
|
||||
const groupCfg = cfg.groups[group_id] || cfg.default;
|
||||
if (!groupCfg.enable) return;
|
||||
const key = `${group_id}_${user_id}`;
|
||||
|
||||
if (groupCfg.carbon.enable) {
|
||||
try {
|
||||
const res = await axios.post(`${cfg.url}/captcha/chiralCarbon/getChiralCarbonCaptcha`, {
|
||||
answer: true,
|
||||
hint: groupCfg.carbon.hint,
|
||||
});
|
||||
if (!res.data?.data?.data) return e.reply('获取验证图失败,请稍后重试..');
|
||||
const { base64, regions } = res.data.data.data;
|
||||
const regionCount = regions.length;
|
||||
this.pending.set(key, { type: 'carbon', answer: regions, tries: 0, cfg: groupCfg });
|
||||
e.reply([
|
||||
segment.at(user_id),
|
||||
segment.image(base64),
|
||||
`上图中有一块或多块区域含有手性碳原子\n为了加入本群,你需要在${groupCfg.timeout}秒内正确找出${groupCfg.carbon['hard-mode'] ? '全部含有手性碳的区域' : '其中任意一块包含手性碳的区域'}\n回答的话,直接回复区域代号即可,多个区域用逗号隔开\n提示一下,本图共有${regionCount}块手性碳区域噢..`,
|
||||
]);
|
||||
} catch (err) {
|
||||
logger.error('[crystelf-plugin] 请求手性碳验证API失败..', err);
|
||||
}
|
||||
} else {
|
||||
await tools.sleep(500);
|
||||
const a = Math.floor(Math.random() * 100);
|
||||
const b = Math.floor(Math.random() * 100);
|
||||
const op = Math.random() > 0.5 ? '+' : '-';
|
||||
const ans = op === '+' ? a + b : a - b;
|
||||
this.pending.set(key, { type: 'math', answer: ans, tries: 0, cfg: groupCfg });
|
||||
e.reply([segment.at(user_id), `请在${groupCfg.timeout}秒内发送${a} ${op} ${b}的计算结果..`]);
|
||||
}
|
||||
|
||||
if (groupCfg.timeout > 60) {
|
||||
setTimeout(
|
||||
async () => {
|
||||
if (this.pending.has(key)) {
|
||||
await e.reply([segment.at(user_id), `小朋友,你还有1分钟的时间完成验证噢~`]);
|
||||
}
|
||||
},
|
||||
(groupCfg.timeout - 60) * 1000
|
||||
);
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
if (this.pending.has(key)) {
|
||||
this.pending.delete(key);
|
||||
await e.reply([segment.at(user_id), `小朋友,验证超时啦!请重新申请入群~`]);
|
||||
await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
}, groupCfg.timeout * 1000);
|
||||
}
|
||||
|
||||
async cmdBypass(e) {
|
||||
@ -28,7 +188,7 @@ export class CarbonAuth extends plugin {
|
||||
const targetId = Number(atElem.qq);
|
||||
const groupId = e.group_id;
|
||||
const key = `${groupId}_${targetId}`;
|
||||
if (pending.has(key)) pending.delete(key);
|
||||
if (this.pending.has(key)) this.pending.delete(key);
|
||||
const redisKey = `Yz:pendingWelcome:${groupId}:${targetId}`;
|
||||
const cached = await redis.get(redisKey);
|
||||
if (cached) {
|
||||
@ -55,168 +215,7 @@ export class CarbonAuth extends plugin {
|
||||
return e.reply('这对吗', true);
|
||||
}
|
||||
const key = `${e.group_id}_${targetId}`;
|
||||
if (pending.get(key)) return e.reply('这孩子已经在验证了..', true);
|
||||
await auth(e, e.group_id, targetId);
|
||||
if (this.pending.get(key)) return e.reply('这孩子已经在验证了..', true);
|
||||
await this.auth(e, e.group_id, targetId);
|
||||
}
|
||||
}
|
||||
//答案监听
|
||||
Bot.on?.('message.group', async (e) => {
|
||||
const key = `${e.group_id}_${e.user_id}`;
|
||||
//logger.info(key);
|
||||
const session = pending.get(key);
|
||||
if (!session) return;
|
||||
session.tries++;
|
||||
const { type, answer, tries, cfg } = session;
|
||||
|
||||
const pass = async () => {
|
||||
pending.delete(key);
|
||||
const redisKey = `Yz:pendingWelcome:${e.group_id}:${e.user_id}`;
|
||||
const cached = await redis.get(redisKey);
|
||||
if (cached) {
|
||||
try {
|
||||
const msgList = JSON.parse(cached);
|
||||
await e.reply(msgList);
|
||||
} finally {
|
||||
await redis.del(redisKey);
|
||||
}
|
||||
} else {
|
||||
return await e.reply('验证通过,欢迎加入本群~', true);
|
||||
}
|
||||
};
|
||||
|
||||
if (type === 'math') {
|
||||
const msgStr = (e.message || [])
|
||||
.filter((m) => m.type === 'text')
|
||||
.map((m) => m.text)
|
||||
.join('')
|
||||
.trim();
|
||||
const num = parseInt(msgStr, 10);
|
||||
if (!isNaN(num) && num === answer) return pass();
|
||||
if (tries >= cfg.frequency) {
|
||||
pending.delete(key);
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
e.reply([segment.at(e.user_id), '验证失败,你错太多次辣!'], true);
|
||||
return await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
return e.reply(
|
||||
[segment.at(e.user_id), `回答错了呢,你还有${cfg.frequency - tries}次机会,再试试看?`],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (type === 'carbon') {
|
||||
const msgStr = (e.message || [])
|
||||
.filter((m) => m.type === 'text')
|
||||
.map((m) => m.text)
|
||||
.join('');
|
||||
const msgRegions = msgStr
|
||||
.toUpperCase()
|
||||
.replace(/,/g, ',')
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
const rightRegions = answer.map((r) => r.toUpperCase());
|
||||
|
||||
let correct;
|
||||
if (cfg.carbon['hard-mode']) {
|
||||
correct = rightRegions.every((r) => msgRegions.includes(r));
|
||||
} else {
|
||||
correct = rightRegions.some((r) => msgRegions.includes(r));
|
||||
}
|
||||
|
||||
if (correct) return pass();
|
||||
if (tries >= cfg.frequency) {
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
pending.delete(key);
|
||||
e.reply([segment.at(e.user_id), '验证失败,你错太多次辣!'], true);
|
||||
return await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
if (cfg.recall) await Message.deleteMsg(e, e.message_id);
|
||||
return e.reply(
|
||||
[segment.at(e.user_id), `回答错了呢,你还有${cfg.frequency - tries}次机会,再试试看?`],
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
//主动退群
|
||||
Bot.on?.('notice.group.decrease', async (e) => {
|
||||
const key = `${e.group_id}_${e.user_id}`;
|
||||
if (pending.has(key)) {
|
||||
pending.delete(key);
|
||||
logger.mark(`[crystelf-plugin] 用户 ${e.user_id} 主动退群,验证流程结束..`);
|
||||
e.reply('害,怎么跑路了');
|
||||
}
|
||||
});
|
||||
|
||||
//加群事件
|
||||
Bot.on?.('notice.group.increase', async (e) => {
|
||||
if (e.isMaster) return true;
|
||||
const key = `${e.group_id}_${e.user_id}`;
|
||||
if (pending.get(key)) return true;
|
||||
logger.info(`[crystelf-plugin] 群[${e.group_id}]开始对用户[${e.user_id}]的加群验证`);
|
||||
await auth(e, e.group_id, e.user_id);
|
||||
});
|
||||
|
||||
/**
|
||||
* 验证
|
||||
* @param e 事件
|
||||
* @param group_id 群号
|
||||
* @param user_id 带验证用户id
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
async function auth(e, group_id, user_id) {
|
||||
const cfg = await configControl.get('auth');
|
||||
if (!cfg) return;
|
||||
const groupCfg = cfg.groups[group_id] || cfg.default;
|
||||
if (!groupCfg.enable) return;
|
||||
const key = `${group_id}_${user_id}`;
|
||||
if (groupCfg.carbon.enable) {
|
||||
try {
|
||||
const res = await axios.post(`${cfg.url}/captcha/chiralCarbon/getChiralCarbonCaptcha`, {
|
||||
answer: true,
|
||||
hint: groupCfg.carbon.hint,
|
||||
});
|
||||
if (!res.data?.data?.data) return e.reply('获取验证图失败,请稍后重试..');
|
||||
const { base64, regions } = res.data.data.data;
|
||||
const regionCount = regions.length;
|
||||
pending.set(key, { type: 'carbon', answer: regions, tries: 0, cfg: groupCfg });
|
||||
e.reply([
|
||||
segment.at(user_id),
|
||||
segment.image(base64),
|
||||
`上图中有一块或多块区域含有手性碳原子\n为了加入本群,你需要在${groupCfg.timeout}秒内正确找出${groupCfg.carbon['hard-mode'] ? '全部含有手性碳的区域' : '其中任意一块包含手性碳的区域'}\n回答的话,直接回复区域代号即可,多个区域用逗号隔开\n提示一下,本图共有${regionCount}块手性碳区域噢..`,
|
||||
]);
|
||||
} catch (err) {
|
||||
logger.error('[crystelf-plugin] 请求手性碳验证API失败..', err);
|
||||
}
|
||||
} else {
|
||||
await tools.sleep(500);
|
||||
const a = Math.floor(Math.random() * 100);
|
||||
const b = Math.floor(Math.random() * 100);
|
||||
const op = Math.random() > 0.5 ? '+' : '-';
|
||||
const ans = op === '+' ? a + b : a - b;
|
||||
pending.set(key, { type: 'math', answer: ans, tries: 0, cfg: groupCfg });
|
||||
e.reply([segment.at(user_id), `请在${groupCfg.timeout}秒内发送${a} ${op} ${b}的计算结果..`]);
|
||||
}
|
||||
|
||||
if (groupCfg.timeout > 60) {
|
||||
setTimeout(
|
||||
async () => {
|
||||
if (pending.has(key)) {
|
||||
await e.reply([segment.at(user_id), `小朋友,你还有1分钟的时间完成验证噢~`]);
|
||||
}
|
||||
},
|
||||
(groupCfg.timeout - 60) * 1000
|
||||
);
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
if (pending.has(key)) {
|
||||
pending.delete(key);
|
||||
await e.reply([segment.at(user_id), `小朋友,验证超时啦!请重新申请入群~`]);
|
||||
await Group.groupKick(e, e.user_id, e.group_id, false);
|
||||
}
|
||||
}, groupCfg.timeout * 1000);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user