From 9f1d436bc126b7f83713a00e8c982b5b1fbc6d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=AB=E5=B1=B1?= <939048569@qq.com> Date: Wed, 15 Oct 2025 23:40:10 +0800 Subject: [PATCH] =?UTF-8?q?JS=E8=84=9A=E6=9C=AC=EF=BC=9A=E7=AD=89=E5=BE=85?= =?UTF-8?q?=E5=88=B0=E5=85=B7=E4=BD=93=E6=97=B6=E9=97=B4waitUntilSpecified?= =?UTF-8?q?Time=20v1.3=20(#2150)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加对当天日期的判断,防止之前的配置组超时导致之后的配置组执行拖延至第二天 --- repo/js/waitUntilSpecifiedTime/README.md | 18 +- repo/js/waitUntilSpecifiedTime/main.js | 169 ++++++++++++------- repo/js/waitUntilSpecifiedTime/manifest.json | 14 +- repo/js/waitUntilSpecifiedTime/settings.json | 126 +++----------- 4 files changed, 154 insertions(+), 173 deletions(-) diff --git a/repo/js/waitUntilSpecifiedTime/README.md b/repo/js/waitUntilSpecifiedTime/README.md index 407149e70..6fece8ce9 100644 --- a/repo/js/waitUntilSpecifiedTime/README.md +++ b/repo/js/waitUntilSpecifiedTime/README.md @@ -25,10 +25,11 @@ ### 示例说明 -| 当前时间 | 设置目标时间 | 等待结果 | -|----------|--------------|----------| -| 3:00 | 4:00 | 等待1小时 | -| 4:30 | 4:00 | 等待23.5小时(次日4:00)| +| 当前时间 | 目标时间 | allowNextDay | 结果 | +|----------|----------|--------------|------| +| 03:00 | 04:00 | false | 等待 1 小时,当天 04:00 完成 | +| 04:30 | 04:00 | false | 目标已过,立即结束(skipped) | +| 04:30 | 04:00 | true | 等待至次日 04:00(约 23.5 小时) | --- @@ -40,4 +41,11 @@ - 目标时间:3:55 - 等待:23小时55分钟(次日3:55) -**请务必设置目标时间点,否则脚本不会执行!** \ No newline at end of file +**请务必设置目标时间点,否则脚本不会执行!** + +### 更新日志 +### 1.6.3(2025.10.15) +添加 allowNextDay 配置(settings 中为复选框 allowNextDay),用于控制当目标时间“今天已过”时是否等待到“明天”的同一时间。 +- 若希望在目标时间今天已过时也继续等待到明天,请在设置中勾选“如果目标时间今天已过,是否等待到明天同一时间”。 +- 不勾选则脚本会立即跳过,这是为防止意外长时间占用任务造成的问题。 +- 若当天已过,可选择等待到次日同一时间(可选)或立即结束(默认) \ No newline at end of file diff --git a/repo/js/waitUntilSpecifiedTime/main.js b/repo/js/waitUntilSpecifiedTime/main.js index da89596c7..e980fac26 100644 --- a/repo/js/waitUntilSpecifiedTime/main.js +++ b/repo/js/waitUntilSpecifiedTime/main.js @@ -1,79 +1,118 @@ (async function () { - /** - * 计算从「现在」到下一次指定时分的毫秒差 - * - * @param {number} validatedHours 小时(0–23) - * @param {number} validatedMinutes 分钟(0–59) - * @returns {number} 下一次指定时分与目前时间的毫秒差 - */ - function getTimeUntilNextTime(validatedHours, validatedMinutes) { - const now = new Date(); - const nextTime = new Date( - now.getFullYear(), - now.getMonth(), - now.getDate(), - validatedHours, validatedMinutes, 0, 0 - ); - // 如果当前时间已经到达或超过今天指定的时刻,就把 nextTime 设为明天的同一时间 - if (now >= nextTime) { - nextTime.setDate(nextTime.getDate() + 1); + // 默认值 + const DEFAULT_HOURS = 4; + const DEFAULT_MINUTES = 0; + const BUFFER_MS = 10 * 1000; // 10秒缓冲 + + // 解析布尔(支持 true / 'true' / false / 'false') + function parseBoolean(val) { + return val === true || val === 'true' || val === '1' || val === 1; + } + + // 解析数字并做范围限制,若输入为空或无法解析则返回 defaultValue + function parseAndClampNumber(val, defaultValue, min, max) { + const n = Number(val); + if (val === '' || !Number.isFinite(n)) { + return { value: defaultValue, warned: true, reason: 'empty_or_invalid' }; + } + const rounded = Math.floor(n); + if (rounded < min || rounded > max) { + return { value: Math.min(max, Math.max(min, rounded)), warned: true, reason: 'out_of_range' }; + } + return { value: rounded, warned: false, reason: '' }; + } + + // 计算下一个目标时间(返回 Date 或 null,当 allowNextDay=false 且今天已过时) + function computeNextTargetDate(hours, minutes, allowNextDay) { + const now = new Date(); + let target = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes, 0, 0); + if (target.getTime() > now.getTime()) { + return { target, isTomorrow: false }; + } else { + if (allowNextDay) { + const tomorrow = new Date(target.getTime() + 24 * 60 * 60 * 1000); + return { target: tomorrow, isTomorrow: true }; + } else { + return { target: null, isTomorrow: false }; + } + } + } + + // 主等待函数(封装校验、计算、等待) + async function waitUntilSpecifiedTime(rawHours, rawMinutes, rawAllowNextDay) { + // 解析与校验 + const ph = parseAndClampNumber(rawHours, DEFAULT_HOURS, 0, 23); + const pm = parseAndClampNumber(rawMinutes, DEFAULT_MINUTES, 0, 59); + const allowNextDay = parseBoolean(rawAllowNextDay); + + if (ph.warned) { + if (ph.reason === 'out_of_range') { + log.warn(`设置指定小时错误(${rawHours}),已修正为 ${ph.value}(范围 0~23)`); + } else { + log.warn(`未设置有效的指定小时,将使用默认:${ph.value} 时`); + } + } + if (pm.warned) { + if (pm.reason === 'out_of_range') { + log.warn(`设置指定分钟错误(${rawMinutes}),已修正为 ${pm.value}(范围 0~59)`); + } else { + log.warn(`未设置有效的指定分钟,将使用默认:${pm.value} 分`); + } } - return nextTime - now; + const validatedHours = ph.value; + const validatedMinutes = pm.value; + + log.info(`--------------- 将等待至 ${validatedHours}:${validatedMinutes} ---------------`); + + // 计算下一次目标时间 + const { target, isTomorrow } = computeNextTargetDate(validatedHours, validatedMinutes, allowNextDay); + + if (!target) { + // 今天已过且不允许等到明天 + log.info(`[等待到指定时间] 目标时间 ${validatedHours}:${validatedMinutes} 已经过了今天(当前时间 ${new Date().toLocaleString()}),allowNextDay 未开启,脚本将直接结束当前等待分组。`); + return { status: 'skipped', reason: 'target time already passed today', when: null }; + } + + const now = Date.now(); + let msToWait = target.getTime() - now; + + if (msToWait < 0) { + // 非常规保护:若计算误差导致负值(极短时间差),设为 0 + msToWait = 0; + } + + // 日志 → 用更友好的时间描述 + const minutesRemaining = Math.floor(msToWait / 60000); + const hoursRemaining = Math.floor(minutesRemaining / 60); + const minutesPart = minutesRemaining % 60; + log.info(`现在时间 ${new Date().toLocaleString()},将等待约 ${hoursRemaining} 小时 ${minutesPart} 分钟(${Math.floor(msToWait / 1000)} 秒),直到 ${target.toLocaleString()}(isTomorrow=${isTomorrow})`); + + // 真正等待(加缓冲) + await sleep(msToWait + BUFFER_MS); + + log.info(`时间到了!现在是 ${new Date().toLocaleString()},目标 ${validatedHours}:${validatedMinutes}(isTomorrow=${isTomorrow})`); + return { status: 'done', when: target.toISOString(), isTomorrow }; } + // --- 入口逻辑 --- + // setGameMetrics / dispatcher / log / settings / sleep 为宿主提供的全局 API + setGameMetrics(1920, 1080, 2); - // 启用自动拾取的实时任务 dispatcher.addTimer(new RealtimeTimer("AutoPick")); - // 启用自动剧情的实时任务 dispatcher.addTimer(new RealtimeTimer("AutoSkip")); - // 读取参数 - let specifyHours = Number(settings.specifyHours); - let specifyMinutes = Number(settings.specifyMinutes); - - if (isNaN(specifyHours) || isNaN(specifyMinutes)) { - log.warn(`⚠️请先设置目标时间点⚠️\n - ⚠️⚠️请先设置目标时间点⚠️⚠️\n - ⚠️⚠️⚠️请先设置目标时间点⚠️⚠️⚠️\n`); - } else { + // 读取参数(可能为字符串) + const rawHours = settings && settings.specifyHours !== undefined ? settings.specifyHours : ''; + const rawMinutes = settings && settings.specifyMinutes !== undefined ? settings.specifyMinutes : ''; + // settings.allowNextDay 由 settings.json 中的 switch 提供,可能为 boolean 或字符串 'true' + const rawAllowNextDay = settings && settings.allowNextDay !== undefined ? settings.allowNextDay : false; - log.info(`--------------- 将等待至 ${specifyHours}:${specifyMinutes} ---------------`) + // 调用统一等待函数 + const result = await waitUntilSpecifiedTime(rawHours, rawMinutes, rawAllowNextDay); - // 计算相差时间(毫秒) - const timeUntilNextTime = getTimeUntilNextTime(specifyHours, specifyMinutes); - const hours = Math.floor(timeUntilNextTime / 3600000); - const minutes = Math.floor((timeUntilNextTime % 3600000) / 60000); - log.info(`距离目标时间 ${specifyHours}:${specifyMinutes},还有 ${hours} 小时 ${minutes} 分钟`); + // 返回结果,方便宿主或调用者判断 + return result; - // 每5分钟报告一次剩余时间 - const reportInterval = 5 * 60 * 1000; // 5分钟(毫秒) - let remainingTime = timeUntilNextTime; - - while (remainingTime > reportInterval) { - // 等待5分钟或剩余时间(取较小值) - const waitTime = Math.min(reportInterval, remainingTime); - await sleep(waitTime); - - // 更新剩余时间 - remainingTime -= waitTime; - - // 计算剩余小时和分钟 - const remainHours = Math.floor(remainingTime / 3600000); - const remainMinutes = Math.floor((remainingTime % 3600000) / 60000); - - // 报告剩余时间 - log.info(`距离目标时间 ${specifyHours}:${specifyMinutes},还有 ${remainHours} 小时 ${remainMinutes} 分钟`); - } - - // 等待最后剩余的时间(不足5分钟) - if (remainingTime > 0) { - await sleep(remainingTime); - } - - // 多等待5秒 - // await sleep(5000); - log.info(`时间已到!当前时间为 ${specifyHours}:${specifyMinutes}`); - } })(); \ No newline at end of file diff --git a/repo/js/waitUntilSpecifiedTime/manifest.json b/repo/js/waitUntilSpecifiedTime/manifest.json index 63d99aab8..5f6b8db53 100644 --- a/repo/js/waitUntilSpecifiedTime/manifest.json +++ b/repo/js/waitUntilSpecifiedTime/manifest.json @@ -1,13 +1,17 @@ { "manifest_version": 1, - "name": "等待到指定时间点", - "version": "1.2", - "bgi_version": "0.42.0", - "description": "等待到指定时间:\n脚本将暂停所有操作,直至到达您设置的特定时间(24小时制)后結束等待,让后面的任务在您设置的特定时间后才开始运行。\n例如:设置04:00会让脚本等到凌晨4点再继续执行\n使用时务必先设置目标时间,否则脚本不会正常运行\n详见README.md", + "name": "等待到指定时间", + "version": "1.3", + "bgi_version": "0.51.0", + "description": "等待到指定时间(默认凌晨4点),适用于等到第二天4点执行其他任务。", "authors": [ { "name": "蜜柑魚", - "links": "https://github.com/this-Fish" + "link": "https://github.com/this-Fish" + }, + { + "name": "火山", + "link": "https://github.com/RRRR623" } ], "settings_ui": "settings.json", diff --git a/repo/js/waitUntilSpecifiedTime/settings.json b/repo/js/waitUntilSpecifiedTime/settings.json index 1405f97d6..b42130789 100644 --- a/repo/js/waitUntilSpecifiedTime/settings.json +++ b/repo/js/waitUntilSpecifiedTime/settings.json @@ -1,100 +1,30 @@ [ - { - "name": "specifyHours", - "type": "select", - "label": "设置目标时间点(24小时制)\n请设置脚本继续执行的具体时间\n示例:\n小时:4\n分钟:30\n脚本会等待至凌晨4点30分\n\n小时", - "options": [ - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23" - ] - }, - { - "name": "specifyMinutes", - "type": "select", - "label": "分钟", - "options": [ - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31", - "32", - "33", - "34", - "35", - "36", - "37", - "38", - "39", - "40", - "41", - "42", - "43", - "44", - "45", - "46", - "47", - "48", - "49", - "50", - "51", - "52", - "53", - "54", - "55", - "56", - "57", - "58", - "59" - ] - } + { + "name": "specifyHours", + "type": "select", + "label": "指定等待直到下一个 HH:MM 的时(0~23,默认:4)", + "default": "4", + "options": [ + "0","1","2","3","4","5","6","7","8","9","10","11","12", + "13","14","15","16","17","18","19","20","21","22","23" + ] + }, + { + "name": "specifyMinutes", + "type": "select", + "label": "指定等待直到下一个 HH:MM 的分钟(0~59,默认:0)", + "default": "0", + "options": [ + "0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19", + "20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37", + "38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55", + "56","57","58","59" + ] + }, + { + "name": "allowNextDay", + "type": "checkbox", + "label": "如果目标时间今天已过,是否等待到明天同一时间(默认:否)", + "default": false + } ] \ No newline at end of file