From 6d50527f17b498263ebb1e69f2ec9c8d791e71da Mon Sep 17 00:00:00 2001 From: milangree Date: Mon, 22 Jun 2026 09:47:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat=EF=BC=9A=E6=B7=BB=E5=8A=A0=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E6=97=B6=E9=97=B4=E7=AD=BE=E5=88=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=8F=92=E4=BB=B6=E4=BC=9A=E5=9C=A8=20runTime=20?= =?UTF-8?q?=E5=88=B0=20runTimeEnd=20=E4=B9=8B=E9=97=B4=E6=AF=8F=E5=A4=A9?= =?UTF-8?q?=E9=9A=8F=E6=9C=BA=E9=80=89=E6=8B=A9=E4=B8=80=E4=B8=AA=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E7=82=B9=E6=89=A7=E8=A1=8C=E7=AD=BE=E5=88=B0=E3=80=82?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9F=AD=E5=91=BD=E4=BB=A4=EF=BC=9At=20(time?= =?UTF-8?q?),=20r=20(range),=20d=20(delay),=20b=20(bot),=20l=20(log)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- checkin/checkin.ts | 382 ++++++++++++++++++++++++++++++--------------- 1 file changed, 256 insertions(+), 126 deletions(-) diff --git a/checkin/checkin.ts b/checkin/checkin.ts index 0e56ff49..1f54ce92 100644 --- a/checkin/checkin.ts +++ b/checkin/checkin.ts @@ -19,24 +19,28 @@ interface SignTarget { interface CheckInConfig { runTime: string; + runTimeEnd?: string; logChat: string; randomDelay: number; lastRunDate: string; botToken: string; pushChatId: string; targets: SignTarget[]; + currentRunTime?: string; } type SignResult = { success: boolean; message?: string; error?: string }; const DEFAULT_CONFIG: CheckInConfig = { runTime: "10:00", + runTimeEnd: "11:30", logChat: "", randomDelay: 0, lastRunDate: "", botToken: "", pushChatId: "", targets: [], + currentRunTime: undefined, }; const SH_TZ = "Asia/Shanghai"; @@ -84,6 +88,7 @@ class CheckInPlugin extends Plugin { private readonly cfg = new ConfigManager(); private timer: NodeJS.Timeout | null = null; private running = false; + private todayRunTime: string | null = null; constructor() { super(); @@ -103,11 +108,7 @@ class CheckInPlugin extends Plugin { const action = (args[0] || "").toLowerCase(); if (!action || action === "help" || action === "h") { - if (!action) { - if (!this.cfg.get().targets.length) { - await this.edit(msg, "❌ 当前没有配置签到目标,请先使用 add"); - return; - } + if (!action && this.cfg.get().targets.length > 0) { await this.edit(msg, "🚀 开始执行所有签到任务..."); void this.runAllSigns("手动触发", msg.chatId, msg); return; @@ -116,134 +117,207 @@ class CheckInPlugin extends Plugin { return; } - if (action === "add") { - const id = args[1]; - const name = args[2]; - const target = args[3]; - const command = args[4]; - if (!id || !name || !target || !command) { - await this.edit(msg, `❌ 格式错误:${PREFIX}qd add [ID] [名称] [目标] [命令] [data:回调数据|text:按钮名]`); - return; - } - - const matcher = this.parseButtonMatcher(args.slice(5)); - const conf = this.cfg.get(); - const next: SignTarget = { id, name, target, command, ...matcher, enabled: true }; - const i = conf.targets.findIndex((t) => t.id === id); - if (i >= 0) conf.targets[i] = next; - else conf.targets.push(next); - this.cfg.save({ targets: conf.targets }); - await this.edit(msg, `✅ 已${i >= 0 ? "更新" : "添加"}签到目标: ${name} (${id})`); + if (["add", "del", "delete", "list", "toggle", "test"].includes(action)) { + await this.handleTargetCommand(action, args, msg); return; } - if (action === "del" || action === "delete") { - const id = args[1]; - if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd del [ID]`)); - const conf = this.cfg.get(); - const n = conf.targets.length; - conf.targets = conf.targets.filter((t) => t.id !== id); - this.cfg.save({ targets: conf.targets }); - await this.edit(msg, conf.targets.length < n ? `✅ 已删除签到目标: ${id}` : `❌ 未找到目标: ${id}`); + if (["set", "config", "settings", "info"].includes(action)) { + await this.handleConfigCommand(action, args, msg); return; } - if (action === "list") { - const conf = this.cfg.get(); - if (!conf.targets.length) return void (await this.edit(msg, "📝 当前没有配置签到目标")); - const enabled = conf.targets.filter((t) => t.enabled).length; - const lines = conf.targets - .map((t, i) => { - const m = t.callbackData ? `\n 回调: ${this.escape(t.callbackData)}` : t.buttonText ? `\n 按钮: ${this.escape(t.buttonText)}` : ""; - return `${t.enabled ? "🟢" : "🔴"} ${i + 1}. ${this.escape(t.name)}\n ID: ${this.escape(t.id)}\n 目标: ${this.escape(t.target)}\n 命令: ${this.escape(t.command)}${m}`; - }) - .join("\n\n"); - await this.edit(msg, `📝 签到目标列表 (${enabled}/${conf.targets.length} 个启用)\n\n${lines}`); + if (action === "reset") { + this.cfg.save({ lastRunDate: "", currentRunTime: undefined }); + this.todayRunTime = null; + await this.edit(msg, "✅ 已重置每日运行状态,定时任务可再次触发。"); return; } - if (action === "toggle") { - const id = args[1]; - if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd toggle [ID]`)); - const conf = this.cfg.get(); - const t = conf.targets.find((x) => x.id === id); - if (!t) return void (await this.edit(msg, `❌ 未找到目标: ${id}`)); - t.enabled = !t.enabled; - this.cfg.save({ targets: conf.targets }); - await this.edit(msg, `✅ 已${t.enabled ? "启用" : "禁用"}签到目标: ${this.escape(t.name)} (${this.escape(id)})`); - return; - } + await this.edit(msg, `❌ 未知命令,请使用 ${PREFIX}qd help 查看帮助`); + } catch (e: any) { + console.error("[CheckIn] Command error:", e); + try { + await this.edit(msg, `❌ 命令执行失败: ${this.escape(e?.message || "未知错误")}`); + } catch {} + } + }, + }; + + private async handleTargetCommand(action: string, args: string[], msg: Api.Message): Promise { + const conf = this.cfg.get(); + + if (action === "add") { + const id = args[1]; + const name = args[2]; + const target = args[3]; + const command = args[4]; + if (!id || !name || !target || !command) { + await this.edit(msg, `❌ 格式错误:${PREFIX}qd add [ID] [名称] [目标] [命令] [data:回调数据|text:按钮名]`); + return; + } + + const matcher = this.parseButtonMatcher(args.slice(5)); + const next: SignTarget = { id, name, target, command, ...matcher, enabled: true }; + const i = conf.targets.findIndex((t) => t.id === id); + if (i >= 0) conf.targets[i] = next; + else conf.targets.push(next); + this.cfg.save({ targets: conf.targets }); + await this.edit(msg, `✅ 已${i >= 0 ? "更新" : "添加"}签到目标: ${name} (${id})`); + return; + } + + if (action === "del" || action === "delete") { + const id = args[1]; + if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd del [ID]`)); + const n = conf.targets.length; + conf.targets = conf.targets.filter((t) => t.id !== id); + this.cfg.save({ targets: conf.targets }); + await this.edit(msg, conf.targets.length < n ? `✅ 已删除签到目标: ${id}` : `❌ 未找到目标: ${id}`); + return; + } + + if (action === "list") { + if (!conf.targets.length) return void (await this.edit(msg, "📝 当前没有配置签到目标")); + const enabled = conf.targets.filter((t) => t.enabled).length; + const lines = conf.targets + .map((t, i) => { + const m = t.callbackData ? `\n 回调: ${this.escape(t.callbackData)}` : t.buttonText ? `\n 按钮: ${this.escape(t.buttonText)}` : ""; + return `${t.enabled ? "🟢" : "🔴"} ${i + 1}. ${this.escape(t.name)}\n ID: ${this.escape(t.id)}\n 目标: ${this.escape(t.target)}\n 命令: ${this.escape(t.command)}${m}`; + }) + .join("\n\n"); + await this.edit(msg, `📝 签到目标列表 (${enabled}/${conf.targets.length} 个启用)\n\n${lines}`); + return; + } + + if (action === "toggle") { + const id = args[1]; + if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd toggle [ID]`)); + const t = conf.targets.find((x) => x.id === id); + if (!t) return void (await this.edit(msg, `❌ 未找到目标: ${id}`)); + t.enabled = !t.enabled; + this.cfg.save({ targets: conf.targets }); + await this.edit(msg, `✅ 已${t.enabled ? "启用" : "禁用"}签到目标: ${this.escape(t.name)} (${this.escape(id)})`); + return; + } + + if (action === "test") { + const id = args[1]; + if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd test [ID]`)); + const t = conf.targets.find((x) => x.id === id); + if (!t) return void (await this.edit(msg, `❌ 未找到目标: ${id}`)); + await this.edit(msg, `🚀 开始测试签到目标: ${this.escape(t.name)}...`); + const r = await this.runSingleSign(t); + await this.edit(msg, r.success ? `✅ ${this.escape(t.name)} 测试成功\n\n结果: ${this.escape(r.message || "无")}` : `❌ ${this.escape(t.name)} 测试失败\n\n错误: ${this.escape(r.error || "未知错误")}`); + return; + } + } + + private async handleConfigCommand(action: string, args: string[], msg: Api.Message): Promise { + const conf = this.cfg.get(); + + if (action === "settings" || action === "config" || action === "info") { + const enabled = conf.targets.filter((t) => t.enabled).length; + const timeRange = conf.runTimeEnd ? `${conf.runTime} ~ ${conf.runTimeEnd}` : conf.runTime; + const timeMode = conf.runTimeEnd ? "🔄 随机时间模式" : "📌 固定时间模式"; + + await this.edit( + msg, + `⚙️ CheckIn 配置信息\n\n` + + `${timeMode}\n` + + `⏰ 运行时间: ${this.escape(timeRange)}\n` + + `🎲 随机延迟: ${conf.randomDelay} 分钟\n` + + `🤖 Bot推送: ${conf.botToken ? "已配置" : "未配置"}\n` + + `📱 推送目标: ${this.escape(conf.pushChatId || "未设置")}\n` + + `📅 上次运行: ${this.escape(conf.lastRunDate || "无")}\n` + + `🎯 签到目标: ${enabled}/${conf.targets.length} 个启用` + ); + return; + } + + if (action === "set" || action === "config") { + const type = (args[1] || "").toLowerCase(); + const value = args[2]; + const extra = args[3]; - if (action === "test") { - const id = args[1]; - if (!id) return void (await this.edit(msg, `❌ 请指定目标ID:${PREFIX}qd test [ID]`)); - const t = this.cfg.get().targets.find((x) => x.id === id); - if (!t) return void (await this.edit(msg, `❌ 未找到目标: ${id}`)); - await this.edit(msg, `🚀 开始测试签到目标: ${this.escape(t.name)}...`); - const r = await this.runSingleSign(t); - await this.edit(msg, r.success ? `✅ ${this.escape(t.name)} 测试成功\n\n结果: ${this.escape(r.message || "无")}` : `❌ ${this.escape(t.name)} 测试失败\n\n错误: ${this.escape(r.error || "未知错误")}`); + if (type === "time" || type === "t") { + if (!value || !/^([01]?\d|2[0-3]):[0-5]\d$/.test(value)) { + await this.edit(msg, "❌ 格式错误,请使用 HH:MM (例如 10:30)"); return; } - - if (action === "set") { - const type = (args[1] || "").toLowerCase(); - const v = args[2]; - if (type === "time") { - if (!v || !/^([01]?\d|2[0-3]):[0-5]\d$/.test(v)) return void (await this.edit(msg, "❌ 格式错误,请使用 HH:MM (例如 10:30)")); - this.cfg.save({ runTime: v }); - await this.edit(msg, `✅ 每日运行时间已设置为: ${v}`); - return; - } - if (type === "bot") { - const token = args[2]; - const chatId = args[3]; - if (!token || !chatId) return void (await this.edit(msg, `❌ 格式错误:${PREFIX}qd set bot [Token] [ChatID]`)); - this.cfg.save({ botToken: token, pushChatId: chatId }); - await this.edit(msg, `✅ Bot配置已更新:\nToken: ${this.mask(token)}\nChatID: ${this.escape(chatId)}`); + + if (conf.runTimeEnd) { + const [startH, startM] = value.split(":").map(Number); + const [endH, endM] = conf.runTimeEnd.split(":").map(Number); + if (startH * 60 + startM > endH * 60 + endM && endH * 60 + endM > 0) { + await this.edit(msg, `⚠️ 开始时间 (${value}) 晚于结束时间 (${conf.runTimeEnd}),请调整时间范围`); return; } - if (type === "delay") { - const n = Number(v); - if (!Number.isInteger(n) || n < 0 || n > 60) return void (await this.edit(msg, "❌ 请输入 0-60 之间的分钟数")); - this.cfg.save({ randomDelay: n }); - await this.edit(msg, `✅ 随机延迟已设置为: ${n} 分钟`); - return; - } - await this.edit(msg, "❌ 未知设置项。支持: time, bot, delay"); + } + + this.cfg.save({ runTime: value }); + await this.edit(msg, `✅ 开始时间已设置为: ${value}`); + return; + } + + if (type === "range" || type === "r") { + if (!value) { + this.cfg.save({ runTimeEnd: undefined }); + await this.edit(msg, "✅ 已清除随机时间窗口,使用固定时间模式"); return; } + + if (!/^([01]?\d|2[0-3]):[0-5]\d$/.test(value)) { + await this.edit(msg, "❌ 格式错误,请使用 HH:MM (例如 11:30)"); + return; + } + + const [startH, startM] = conf.runTime.split(":").map(Number); + const [endH, endM] = value.split(":").map(Number); + if (startH * 60 + startM > endH * 60 + endM && endH * 60 + endM > 0) { + await this.edit(msg, `⚠️ 开始时间 (${conf.runTime}) 晚于结束时间 (${value}),将允许跨天执行`); + } + + this.cfg.save({ runTimeEnd: value }); + await this.edit(msg, `✅ 随机时间窗口已设置为: ${conf.runTime} ~ ${value}`); + return; + } - if (action === "reset") { - this.cfg.save({ lastRunDate: "" }); - await this.edit(msg, "✅ 已重置每日运行状态,定时任务可再次触发。"); + if (type === "delay" || type === "d") { + const n = Number(value); + if (!Number.isInteger(n) || n < 0 || n > 60) { + await this.edit(msg, "❌ 请输入 0-60 之间的分钟数"); return; } + this.cfg.save({ randomDelay: n }); + await this.edit(msg, `✅ 随机延迟已设置为: ${n} 分钟`); + return; + } - if (action === "settings") { - const conf = this.cfg.get(); - const enabled = conf.targets.filter((t) => t.enabled).length; - await this.edit( - msg, - `⚙️ CheckIn 配置信息\n\n` + - `运行时间: ${this.escape(conf.runTime)}\n` + - `Bot Token: ${this.mask(conf.botToken) || "未设置"}\n` + - `推送目标: ${this.escape(conf.pushChatId || "未设置")}\n` + - `随机延迟: ${conf.randomDelay} 分钟\n` + - `上次运行: ${this.escape(conf.lastRunDate || "无")}\n` + - `签到目标: ${enabled}/${conf.targets.length} 个启用` - ); + if (type === "bot" || type === "b") { + if (!value || !extra) { + await this.edit(msg, `❌ 格式错误:${PREFIX}qd set bot [Token] [ChatID]`); return; } + this.cfg.save({ botToken: value, pushChatId: extra }); + await this.edit(msg, `✅ Bot配置已更新:\nToken: ${this.mask(value)}\nChatID: ${this.escape(extra)}`); + return; + } - await this.edit(msg, `❌ 未知命令,请使用 ${PREFIX}qd help 查看帮助`); - } catch (e: any) { - console.error("[CheckIn] Command error:", e); - try { - await this.edit(msg, `❌ 命令执行失败: ${this.escape(e?.message || "未知错误")}`); - } catch {} + if (type === "log" || type === "l") { + if (!value) { + await this.edit(msg, `❌ 请指定日志聊天ID:${PREFIX}qd set log [ChatID]`); + return; + } + this.cfg.save({ logChat: value }); + await this.edit(msg, `✅ 日志聊天已设置为: ${this.escape(value)}`); + return; } - }, - }; + + await this.edit(msg, `❌ 未知设置项。支持: time, range, delay, bot, log`); + return; + } + } private async checkAndRun(): Promise { if (this.running) return; @@ -251,11 +325,32 @@ class CheckInPlugin extends Plugin { const conf = this.cfg.get(); const now = new Date(); const today = this.dateCN(now); - const [h, m] = conf.runTime.split(":").map(Number); const t = new Date(now.toLocaleString("en-US", { timeZone: SH_TZ })); - if (conf.lastRunDate === today || t.getHours() !== h || t.getMinutes() !== m) return; + + if (conf.lastRunDate === today) return; + + const runTimeToday = this.getTodayRunTime(); + if (!runTimeToday) { + this.todayRunTime = conf.runTime; + } else { + this.todayRunTime = runTimeToday; + } + + const [h, m] = this.todayRunTime.split(":").map(Number); + + if (t.getHours() !== h || t.getMinutes() !== m) return; + + if (conf.runTimeEnd) { + const [endH, endM] = conf.runTimeEnd.split(":").map(Number); + const endMinutes = endH * 60 + endM; + const currentMinutes = t.getHours() * 60 + t.getMinutes(); + if (currentMinutes > endMinutes) return; + } + this.running = true; - if (conf.randomDelay > 0) await this.sleep(Math.floor(Math.random() * conf.randomDelay * 60_000)); + if (conf.randomDelay > 0) { + await this.sleep(Math.floor(Math.random() * conf.randomDelay * 60_000)); + } await this.runAllSigns("自动定时任务"); this.cfg.save({ lastRunDate: today }); } catch (e) { @@ -265,6 +360,33 @@ class CheckInPlugin extends Plugin { } } + private getTodayRunTime(): string | null { + const conf = this.cfg.get(); + if (!conf.runTimeEnd) return null; + if (this.todayRunTime) return this.todayRunTime; + + const [startH, startM] = conf.runTime.split(":").map(Number); + const [endH, endM] = conf.runTimeEnd.split(":").map(Number); + + const startMinutes = startH * 60 + startM; + let endMinutes = endH * 60 + endM; + + if (endMinutes < startMinutes) { + endMinutes += 24 * 60; + } + + if (endMinutes <= startMinutes) { + return conf.runTime; + } + + const randomMinute = startMinutes + Math.floor(Math.random() * (endMinutes - startMinutes)); + const finalMinutes = randomMinute >= 24 * 60 ? randomMinute - 24 * 60 : randomMinute; + const hours = Math.floor(finalMinutes / 60); + const minutes = finalMinutes % 60; + + return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`; + } + private async runAllSigns(source: string, fallbackPeer?: any, statusMsg?: Api.Message): Promise { const client = await getGlobalClient(); if (!client) return; @@ -403,29 +525,37 @@ class CheckInPlugin extends Plugin { } private helpText(): string { - return `CheckIn 自动化签到插件 + return `🤖 CheckIn 自动化签到插件 -基础指令: +📌 基础指令: ${PREFIX}qd - 手动触发所有签到 ${PREFIX}qd reset - 重置今日运行状态 -${PREFIX}qd settings - 查看当前配置 +${PREFIX}qd help - 显示此帮助 -目标管理: -${PREFIX}qd add [ID] [名称] [目标] [命令] -${PREFIX}qd add [ID] [名称] [目标] [命令] data:[回调数据](推荐) -${PREFIX}qd add [ID] [名称] [目标] [命令] text:[按钮名] +🎯 目标管理: +${PREFIX}qd add [ID] [名称] [目标] [命令] [data:回调|text:按钮] ${PREFIX}qd del [ID] ${PREFIX}qd list ${PREFIX}qd toggle [ID] ${PREFIX}qd test [ID] -设置: -${PREFIX}qd set time [HH:MM] -${PREFIX}qd set bot [Token] [ChatID] -${PREFIX}qd set delay [分钟] +⚙️ 配置管理: +${PREFIX}qd set time [HH:MM] - 设置开始时间 +${PREFIX}qd set range [HH:MM] - 设置随机窗口结束时间(取消则清除) +${PREFIX}qd set delay [分钟] - 随机延迟 0-60分钟 +${PREFIX}qd set bot [Token] [ChatID] - 设置Bot推送 +${PREFIX}qd set log [ChatID] - 设置日志聊天 +${PREFIX}qd settings - 查看当前配置 + +💡 使用示例: +${PREFIX}qd add storm Storm签到 @storm_bot /start data:checkin +${PREFIX}qd set time 10:00 - 从10点开始 +${PREFIX}qd set range 11:30 - 到11:30结束(随机时间模式) +${PREFIX}qd set range - 清除随机窗口(固定时间模式) -示例: -${PREFIX}qd add storm Storm签到 @stormuser_bot /start data:checkin`; +🔄 随机时间说明: +设置 range 后,每天在 time ~ range 之间随机选择时间执行, +避免固定时间被检测。支持跨天(如 22:00 ~ 02:00)。`; } private async edit(msg: Api.Message, text: string): Promise { @@ -487,4 +617,4 @@ class CheckInPlugin extends Plugin { } } -export default new CheckInPlugin(); +export default new CheckInPlugin(); \ No newline at end of file From a47255b458117ba54d39b6c72cf0c3bd415f4c9a Mon Sep 17 00:00:00 2001 From: milangree <63492019+milangree@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:03:47 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- checkin/checkin.ts | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/checkin/checkin.ts b/checkin/checkin.ts index 1f54ce92..e0000453 100644 --- a/checkin/checkin.ts +++ b/checkin/checkin.ts @@ -219,18 +219,18 @@ class CheckInPlugin extends Plugin { if (action === "settings" || action === "config" || action === "info") { const enabled = conf.targets.filter((t) => t.enabled).length; const timeRange = conf.runTimeEnd ? `${conf.runTime} ~ ${conf.runTimeEnd}` : conf.runTime; - const timeMode = conf.runTimeEnd ? "🔄 随机时间模式" : "📌 固定时间模式"; - + const timeMode = conf.runTimeEnd ? "🔄 在设定时间段内随机执行" : "📌 按固定时间执行"; + await this.edit( msg, `⚙️ CheckIn 配置信息\n\n` + `${timeMode}\n` + - `⏰ 运行时间: ${this.escape(timeRange)}\n` + - `🎲 随机延迟: ${conf.randomDelay} 分钟\n` + - `🤖 Bot推送: ${conf.botToken ? "已配置" : "未配置"}\n` + - `📱 推送目标: ${this.escape(conf.pushChatId || "未设置")}\n` + - `📅 上次运行: ${this.escape(conf.lastRunDate || "无")}\n` + - `🎯 签到目标: ${enabled}/${conf.targets.length} 个启用` + `⏰ 执行时间: ${this.escape(timeRange)}\n` + + `🎲 额外随机延迟: ${conf.randomDelay} 分钟\n` + + `🤖 Bot 通知: ${conf.botToken ? "已配置" : "未配置"}\n` + + `📱 通知目标: ${this.escape(conf.pushChatId || "未设置")}\n` + + `📅 最近执行日期: ${this.escape(conf.lastRunDate || "无")}\n` + + `🎯 已启用目标: ${enabled}/${conf.targets.length}` ); return; } @@ -263,7 +263,7 @@ class CheckInPlugin extends Plugin { if (type === "range" || type === "r") { if (!value) { this.cfg.save({ runTimeEnd: undefined }); - await this.edit(msg, "✅ 已清除随机时间窗口,使用固定时间模式"); + await this.edit(msg, "✅ 已清除执行时间范围,改为固定时间执行"); return; } @@ -279,7 +279,7 @@ class CheckInPlugin extends Plugin { } this.cfg.save({ runTimeEnd: value }); - await this.edit(msg, `✅ 随机时间窗口已设置为: ${conf.runTime} ~ ${value}`); + await this.edit(msg, `✅ 执行时间范围已设置为: ${conf.runTime} ~ ${value}(将在该时间段内随机执行)`); return; } @@ -541,21 +541,21 @@ class CheckInPlugin extends Plugin { ⚙️ 配置管理: ${PREFIX}qd set time [HH:MM] - 设置开始时间 -${PREFIX}qd set range [HH:MM] - 设置随机窗口结束时间(取消则清除) -${PREFIX}qd set delay [分钟] - 随机延迟 0-60分钟 -${PREFIX}qd set bot [Token] [ChatID] - 设置Bot推送 +${PREFIX}qd set range [HH:MM] - 设置执行时间结束点(留空则改为固定时间) +${PREFIX}qd set delay [分钟] - 设置额外随机延迟(0-60 分钟) +${PREFIX}qd set bot [Token] [ChatID] - 设置 Bot 通知 ${PREFIX}qd set log [ChatID] - 设置日志聊天 ${PREFIX}qd settings - 查看当前配置 💡 使用示例: ${PREFIX}qd add storm Storm签到 @storm_bot /start data:checkin -${PREFIX}qd set time 10:00 - 从10点开始 -${PREFIX}qd set range 11:30 - 到11:30结束(随机时间模式) -${PREFIX}qd set range - 清除随机窗口(固定时间模式) +${PREFIX}qd set time 10:00 - 从 10:00 开始 +${PREFIX}qd set range 11:30 - 在 10:00 到 11:30 之间随机执行 +${PREFIX}qd set range - 清除时间范围,改为固定时间执行 -🔄 随机时间说明: -设置 range 后,每天在 time ~ range 之间随机选择时间执行, -避免固定时间被检测。支持跨天(如 22:00 ~ 02:00)。`; +🔄 时间范围说明: +设置 range 后,系统会每天在 time 到 range 之间随机选择一个时刻执行, +这样可以避免每天都在同一时间签到。支持跨天,例如 22:00 到次日 02:00。`; } private async edit(msg: Api.Message, text: string): Promise { @@ -617,4 +617,4 @@ class CheckInPlugin extends Plugin { } } -export default new CheckInPlugin(); \ No newline at end of file +export default new CheckInPlugin(); From 7aaed5861b3389177202ff8b46108e32382b41d0 Mon Sep 17 00:00:00 2001 From: milangree Date: Sun, 28 Jun 2026 18:57:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=AF=8F=E5=A4=A9=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E7=94=9F=E6=88=90=E9=9A=8F=E6=9C=BA=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BB=A5=E9=81=BF=E5=85=8D=E8=BF=9E=E7=BB=AD=E5=A4=9A=E5=A4=A9?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=90=8C=E4=B8=80=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- checkin/checkin.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/checkin/checkin.ts b/checkin/checkin.ts index e0000453..f48c41e2 100644 --- a/checkin/checkin.ts +++ b/checkin/checkin.ts @@ -329,6 +329,9 @@ class CheckInPlugin extends Plugin { if (conf.lastRunDate === today) return; + // 每天重新生成随机时间,避免连续多天使用同一时间 + this.todayRunTime = null; + const runTimeToday = this.getTodayRunTime(); if (!runTimeToday) { this.todayRunTime = conf.runTime;