Files
yenai-plugin/apps/groupAdmin/groupVerify.js
yeyang aede99227c 🐛 #I9LCDN
2024-05-03 21:12:01 +08:00

290 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Config } from "../../components/index.js"
import { common, GroupAdmin as Ga } from "../../model/index.js"
import _ from "lodash"
import { sleep } from "../../tools/index.js"
// 全局
let temp = {}
const ops = [ "+", "-" ]
export class GroupVerify extends plugin {
constructor() {
super({
name: "椰奶群管-入群验证",
event: "message.group",
priority: 5,
rule: [
{
reg: "^#重新验证(\\d+|从未发言的人)?$",
fnc: "cmdReverify"
},
{
reg: "^#绕过验证(\\d+)?$",
fnc: "cmdPass"
},
{
reg: "^#(开启|关闭)验证$",
fnc: "handelverify"
},
{
reg: "^#切换验证模式$",
fnc: "setmode"
},
{
reg: "^#设置验证超时时间(\\d+)(s|秒)?$",
fnc: "setovertime"
}
]
})
this.verifycfg = Config.groupverify
}
// 重新验证
async cmdReverify(e) {
if (!common.checkPermission(e, "admin", "admin")) return
if (!this.verifycfg.openGroup.includes(e.group_id)) return e.reply("当前群未开启验证哦~", true)
let qq = e.message.find(item => item.type == "at")?.qq
if (!qq) qq = e.msg.replace(/#|重新验证/g, "").trim()
if (qq == "从未发言的人") return this.cmdReverifyNeverSpeak(e)
if (!(/\d{5,}/.test(qq))) return e.reply("❎ 请输入正确的QQ号")
qq = Number(qq)
if (qq == (e.bot ?? Bot).uin) return
if (Config.masterQQ.includes(qq)) return e.reply("❎ 该命令对机器人管理员无效")
if (temp[qq + e.group_id]) return e.reply("❎ 目标群成员处于验证状态")
await verify(qq, e.group_id, e)
}
// 绕过验证
async cmdPass(e) {
if (!common.checkPermission(e, "admin", "admin")) return
if (!this.verifycfg.openGroup.includes(e.group_id)) return e.reply("当前群未开启验证哦~", true)
let qq = e.message.find(item => item.type == "at")?.qq
if (!qq) qq = e.msg.replace(/#|绕过验证/g, "").trim()
if (!(/\d{5,}/.test(qq))) return e.reply("❎ 请输入正确的QQ号")
if (qq == (e.bot ?? Bot).uin) return
qq = Number(qq)
if (!temp[qq + e.group_id]) return e.reply("❎ 目标群成员当前无需验证")
clearTimeout(temp[qq + e.group_id].kickTimer)
clearTimeout(temp[qq + e.group_id].remindTimer)
delete temp[qq + e.group_id]
return await e.reply(this.verifycfg.SuccessMsgs[e.group_id] || this.verifycfg.SuccessMsgs[0] || "✅ 验证成功,欢迎入群")
}
async cmdReverifyNeverSpeak(e) {
let list = null
try {
list = await new Ga(e).getNeverSpeak(e.group_id)
} catch (error) {
return common.handleException(e, error)
}
for (let item of list) {
await verify(item.user_id, e.group_id, e)
await sleep(2000)
}
}
// 开启验证
async handelverify(e) {
if (!common.checkPermission(e, "admin", "admin")) return
let type = /开启/.test(e.msg) ? "add" : "del"
let isopen = this.verifycfg.openGroup.includes(e.group_id)
if (isopen && type == "add") return e.reply("❎ 本群验证已处于开启状态")
if (!isopen && type == "del") return e.reply("❎ 本群暂未开启验证")
Config.modifyarr("groupverify", "openGroup", e.group_id, type)
e.reply(`✅ 已${type == "add" ? "开启" : "关闭"}本群验证`)
}
// 切换验证模式
async setmode(e) {
if (!common.checkPermission(e, "master")) return
let value = this.verifycfg.mode == "模糊" ? "精确" : "模糊"
Config.modify("groupverify", "mode", value)
e.reply(`✅ 已切换验证模式为${value}验证`)
}
// 设置验证超时时间
async setovertime(e) {
if (!common.checkPermission(e, "master")) return
let overtime = e.msg.match(/\d+/g)
Config.modify("groupverify", "time", Number(overtime))
e.reply(`✅ 已将验证超时时间设置为${overtime}`)
if (overtime < 60) {
e.reply("建议至少一分钟(60秒)哦ε(*´・ω・)з")
}
}
}
// 进群监听
Bot.on?.("notice.group.increase", async(e) => {
logger.mark(`[Yenai-Plugin][进群验证]收到${e.user_id}的进群事件`)
let { openGroup, DelayTime } = Config.groupverify
if (!openGroup.includes(e.group_id)) return
if (!e.group.is_admin && !e.group.is_owner) return
if (e.user_id == (e.bot ?? Bot).uin) return
if (Config.masterQQ.includes(e.user_id)) return
if (Config.groupAdmin.whiteQQ.includes(e.user_id)) return
await sleep(DelayTime * 1000)
await verify(e.user_id, e.group_id, e)
})
// 答案监听
Bot.on?.("message.group", async(e) => {
let { openGroup, mode, SuccessMsgs } = Config.groupverify
if (!openGroup.includes(e.group_id)) return
if (!e.group.is_admin && !e.group.is_owner) return
if (!temp[e.user_id + e.group_id]) return
const { verifyCode, kickTimer, remindTimer } = temp[e.user_id + e.group_id]
const { nums, operator } = temp[e.user_id + e.group_id]
const isAccurateModeOK = mode === "精确" && e.raw_message == verifyCode
const isVagueModeOK = mode === "模糊" && e.raw_message?.includes(verifyCode)
const isOK = isAccurateModeOK || isVagueModeOK
if (isOK) {
delete temp[e.user_id + e.group_id]
clearTimeout(kickTimer)
clearTimeout(remindTimer)
return await sendMsg(e, SuccessMsgs[e.group_id] || SuccessMsgs[0] || "✅ 验证成功,欢迎入群")
} else {
temp[e.user_id + e.group_id].remainTimes -= 1
const { remainTimes } = temp[e.user_id + e.group_id]
if (remainTimes > 0) {
await e.group.recallMsg(e)
const msg = `\n❎ 验证失败\n你还有「${remainTimes}」次机会\n请发送「${nums[0]} ${operator} ${nums[1]}」的运算结果`
return await sendMsg(e, [ segment.at(e.user_id), msg ])
}
clearTimeout(kickTimer)
clearTimeout(remindTimer)
await sendMsg(e, [ segment.at(e.user_id), "\n验证失败请重新申请" ])
delete temp[e.user_id + e.group_id]
return await e.group.kickMember(e.user_id)
}
})
// 主动退群
Bot.on?.("notice.group.decrease", async(e) => {
if (!e.group.is_admin && !e.group.is_owner) return
if (!temp[e.user_id + e.group_id]) return
clearTimeout(temp[e.user_id + e.group_id].kickTimer)
clearTimeout(temp[e.user_id + e.group_id].remindTimer)
delete temp[e.user_id + e.group_id]
sendMsg(e, `${e.user_id}」主动退群,验证流程结束`)
})
// 发送验证信息
/**
*
* @param userId
* @param groupId
* @param e
*/
async function verify(userId, groupId, e) {
if (!e.group.is_admin && !e.group.is_owner) return
userId = Number(userId)
groupId = Number(groupId)
logger.mark(`[Yenai-Plugin][进群验证]进行${userId}的验证`)
const { times, range, time, remindAtLastMinute } = Config.groupverify
const operator = ops[_.random(0, 1)]
let [ m, n ] = [ _.random(range.min, range.max), _.random(range.min, range.max) ]
while (m == n) {
n = Math.floor(Math.random() * (range.max - range.min + 1)) + range.min
}
[ m, n ] = [ m >= n ? m : n, m >= n ? n : m ]
const verifyCode = String(operator === "-" ? m - n : m + n)
logger.mark(`[Yenai-Plugin][进群验证]答案:${verifyCode}`)
const kickTimer = setTimeout(async() => {
sendMsg(e, [ segment.at(userId), "\n验证超时移出群聊请重新申请" ])
delete temp[userId + groupId]
clearTimeout(kickTimer)
return await e.group.kickMember(userId)
}, time * 1000)
const shouldRemind = remindAtLastMinute && time >= 120
const remindTimer = setTimeout(async() => {
if (shouldRemind && temp[userId + groupId].remindTimer) {
const msg = ` \n验证仅剩最后一分钟\n请发送「${m} ${operator} ${n}」的运算结果\n否则将会被移出群聊`
await sendMsg(e, [ segment.at(userId), msg ])
}
clearTimeout(remindTimer)
}, Math.abs(time * 1000 - 60000))
const msg = ` 欢迎!\n请在「${time}」秒内发送\n${m} ${operator} ${n}」的运算结果\n否则将会被移出群聊`
// 消息发送成功才写入
if (await sendMsg(e, [ segment.at(userId), msg ])) {
temp[userId + groupId] = {
remainTimes: times,
nums: [ m, n ],
operator,
verifyCode,
kickTimer,
remindTimer
}
} else {
// 删除定时器
clearTimeout(remindTimer)
clearTimeout(kickTimer)
}
}
async function sendMsg(e, msg) {
const sendMsgFunctions = {
reply: async() => e.reply(msg),
group: async() => e.group.sendMsg(msg),
bot: async() => e.bot.pinkGroup(e.group_id).sendMsg(msg),
self_id: async() => Bot[e.self_id].pinkGroup(e.group_id).sendMsg(msg)
}
for (const key in sendMsgFunctions) {
if (e[key]) {
try {
const sendFunction = sendMsgFunctions[key]
let res = await sendFunction()
return res
} catch (error) {
logger.debug(`[Yenai-Plugin][进群验证]发送消息失败: ${error.message}`)
}
}
}
throw Error("[Yenai-Plugin][进群验证]未获取到发送消息函数")
}