From a754bd8d7fa192f21cdb8f2a8b4a819a762b00e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E7=AB=AF=E5=AE=A2?= <107686912+Kirito520Asuna@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:20:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E6=9C=9F=E9=99=90/=E5=91=A8?= =?UTF-8?q?=E6=9C=AC=E9=80=9A=E7=9F=A5=E5=99=A8=200.1.1=20(#3002)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(utils): 重构工具模块导入导出结构并优化功能实现 - 将各个工具模块改为ES6模块化导入导出方式 - 新增通用文本识别点击工具函数findTextAndClick - 优化campaignArea模块中的征讨领域识别逻辑 - 统一uid识别和通知发送的调用方式 - 移除eval动态加载改用静态导入 - 更新版本号至0.1.1 * config(ActivitySwitchNotice): 更新默认显示天数设置 - 移除周一到周五的默认显示配置 - 保留周日和周六作为默认显示选项 * feat(ActivitySwitchNotice): 更新版本历史记录 - 周本提醒日升为多选功能实现 - 适配新秘境征讨UI界面调整 --- repo/js/ActivitySwitchNotice/README.md | 3 + repo/js/ActivitySwitchNotice/main.js | 34 ++++---- repo/js/ActivitySwitchNotice/manifest.json | 2 +- repo/js/ActivitySwitchNotice/settings.json | 25 +++--- .../js/ActivitySwitchNotice/utils/activity.js | 21 +++-- .../utils/campaignArea.js | 84 ++++++++++++------- .../ActivitySwitchNotice/utils/mapMission.js | 14 +++- repo/js/ActivitySwitchNotice/utils/notice.js | 12 ++- repo/js/ActivitySwitchNotice/utils/tool.js | 82 ++++++++++++++++++ repo/js/ActivitySwitchNotice/utils/uid.js | 10 ++- repo/js/ActivitySwitchNotice/utils/ws.js | 6 +- 11 files changed, 217 insertions(+), 76 deletions(-) create mode 100644 repo/js/ActivitySwitchNotice/utils/tool.js diff --git a/repo/js/ActivitySwitchNotice/README.md b/repo/js/ActivitySwitchNotice/README.md index 368d99083..4e2b7b17a 100644 --- a/repo/js/ActivitySwitchNotice/README.md +++ b/repo/js/ActivitySwitchNotice/README.md @@ -511,6 +511,9 @@ ActivitySwitchNotice/ ## 版本历史 +### 0.1.1 (2026-03-16) +- 周本提醒日 升为多选 +- 适配新秘境征讨UI ### 0.1.0 (2026-02-01) - 新增 新活动通知(存储活动名称列表-历史对比) ### 0.0.8 (2026-01-22) diff --git a/repo/js/ActivitySwitchNotice/main.js b/repo/js/ActivitySwitchNotice/main.js index 4539e11eb..dfe75f469 100644 --- a/repo/js/ActivitySwitchNotice/main.js +++ b/repo/js/ActivitySwitchNotice/main.js @@ -1,7 +1,9 @@ let manifest = {}; let manifest_json = "manifest.json"; let configSettings = undefined - +import {mapMission} from "./utils/mapMission" +import {dailyCommissionMain,campaignAreaMain} from "./utils/campaignArea" +import {activityMain} from "./utils/activity" /** * 初始化设置函数 * 从配置文件中读取设置信息并返回 @@ -87,17 +89,17 @@ async function getValueByMultiCheckboxName(name) { return values } async function init() { - let utils = [ - "uid", - "ws", - "notice", - "campaignArea", - "activity", - "mapMission", - ] - for (let util of utils) { - eval(file.readTextSync(`utils/${util}.js`)); - } + // let utils = [ + // "uid", + // "ws", + // "notice", + // "campaignArea", + // "activity", + // "mapMission", + // ] + // for (let util of utils) { + // eval(file.readTextSync(`utils/${util}.js`)); + // } // manifest = JSON.parse(file.readTextSync("manifest.json")); await initSettings(); log.debug("main 初始化完成"); @@ -151,7 +153,7 @@ async function main() { if (mapList.length > 0) { try { log.info(`开始识别地图任务`) - await mapUtil.mapMission(mapList) + await mapMission(mapList) } finally { await toMainUi() } @@ -160,15 +162,15 @@ async function main() { let openKey = true try { - await campaignAreaUtil.dailyCommissionMain(openKey) + await dailyCommissionMain(openKey) await sleep(ms * 2); openKey = false } catch (e) { await toMainUi() throw e } - await campaignAreaUtil.campaignAreaMain(openKey) + await campaignAreaMain(openKey) await sleep(ms * 2); await toMainUi() - await activityUtil.activityMain(settings.newActivityNotice) + await activityMain(settings.newActivityNotice) } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/manifest.json b/repo/js/ActivitySwitchNotice/manifest.json index d5c8183c0..4dbf94a59 100644 --- a/repo/js/ActivitySwitchNotice/manifest.json +++ b/repo/js/ActivitySwitchNotice/manifest.json @@ -1,6 +1,6 @@ { "name": "活动期限/周本通知器", - "version": "0.1.0", + "version": "0.1.1", "description": "", "settings_ui": "settings.json", "main": "main.js", diff --git a/repo/js/ActivitySwitchNotice/settings.json b/repo/js/ActivitySwitchNotice/settings.json index c24c0f58b..7afa83c30 100644 --- a/repo/js/ActivitySwitchNotice/settings.json +++ b/repo/js/ActivitySwitchNotice/settings.json @@ -75,19 +75,22 @@ "type": "separator" }, { - "name": "campaignAreaReminderDay", - "type": "select", - "label": "周本提醒日(0-6,0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六)", + "label": "周本提醒日", + "name": "campaignAreaReminderDays", + "type": "multi-checkbox", "options": [ - "0", - "1", - "2", - "3", - "4", - "5", - "6" + "周一", + "周二", + "周三", + "周四", + "周五", + "周六", + "周日" ], - "default": "0" + "default": [ + "周六", + "周日"] + }, { "name": "campaignAreaKey", diff --git a/repo/js/ActivitySwitchNotice/utils/activity.js b/repo/js/ActivitySwitchNotice/utils/activity.js index 2b3a8aa75..d598a3c81 100644 --- a/repo/js/ActivitySwitchNotice/utils/activity.js +++ b/repo/js/ActivitySwitchNotice/utils/activity.js @@ -1,3 +1,5 @@ +import {sendNotice,sendText} from "./notice"; +import {ocrUID} from "./uid"; const config_name = "config" const json_path = { activity: `${config_name}/activity.json` @@ -445,11 +447,11 @@ async function init() { /** * 活动主函数:扫描所有活动页面,识别剩余时间,最后统一发送通知 */ -async function activityMain(newActivityNotice = true) { + async function activityMain(newActivityNotice = true) { await init(); const ms = 1000; await sleep(ms); - let uid = await uidUtil.ocrUID() + let uid = await ocrUID() let activityData=[] let activitySetLast = new Set() try { @@ -724,7 +726,7 @@ async function activityMain(newActivityNotice = true) { blackText += `==>{已开启黑名单: ${blackAllText.join("|")}}<==` } - await noticeUtil.sendNotice(activityMapFilter, `UID:${uid}\n原神活动剩余时间提醒(仅显示 ${titleKey} 的活动)${blackText}`); + await sendNotice(activityMapFilter, `UID:${uid}\n原神活动剩余时间提醒(仅显示 ${titleKey} 的活动)${blackText}`); } else { log.warn("不存在符合条件的活动,未发送通知"); } @@ -737,7 +739,7 @@ async function activityMain(newActivityNotice = true) { try { if(activitySetLast.size > 0){ log.info("新增活动: {newActivities}", newActivities); - await noticeUtil.sendText(newActivities.join("\n"), `UID:${uid}\n新增活动`); + await sendText(newActivities.join("\n"), `UID:${uid}\n新增活动`); } activityData=activityData.filter(item => item.uid !== uid) activityData.push(currentActivityJson) @@ -762,8 +764,9 @@ async function activityMain(newActivityNotice = true) { } } -this.activityUtil = { - // config, - activityMain, - // OcrRemainingTime, -} +// this.activityUtil = { +// // config, +// activityMain, +// // OcrRemainingTime, +// } +export {activityMain} diff --git a/repo/js/ActivitySwitchNotice/utils/campaignArea.js b/repo/js/ActivitySwitchNotice/utils/campaignArea.js index 606c1c2d9..05cbd5cd8 100644 --- a/repo/js/ActivitySwitchNotice/utils/campaignArea.js +++ b/repo/js/ActivitySwitchNotice/utils/campaignArea.js @@ -1,3 +1,6 @@ +import {findTextAndClick,getDayOfWeek} from "./tool"; +import {sendText} from "./notice"; +import {ocrUID} from "./uid"; function settingsParseInt(str, defaultValue) { try { return str ? parseInt('' + str) : defaultValue; @@ -13,10 +16,12 @@ function settingsParseStr(str, defaultValue) { const config = { campaignAreaKey: settingsParseStr(settings.campaignAreaKey, 'F1'), - campaignAreaReminderDay: settingsParseInt(settings.campaignAreaReminderDay, 0),//征讨领域提醒日 + // campaignAreaReminderDay: settingsParseInt(settings.campaignAreaReminderDay, 0),//征讨领域提醒日 + campaignAreaReminderDays: Array.from(settings.campaignAreaReminderDays) } const ocrRegionConfig = { weeklyCount: {x: 809, y: 258, width: 277, height: 37},//征讨领域减半次数识别区域坐标和尺寸 + campaignArea:{x:433, y:215, width:306, height:697},//征讨领域识别区域 dailyCommission: {x: 630, y: 312, width: 105, height: 118},//每日委托识别区域坐标和尺寸 } const xyConfig = { @@ -99,27 +104,31 @@ async function ocrWeeklyCount(ocrRegion = ocrRegionConfig.weeklyCount) { } } -/** - * 获取当前日期的星期信息 - * @returns {Object} 返回包含星期数字和星期名称的对象 - */ -async function getDayOfWeek() { - // 获取当前日期对象 - const today = new Date(); - // 获取当前日期是星期几(0代表星期日,1代表星期一,以此类推) - const day = today.getDay(); - // 创建包含星期名称的数组 - const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; - let weekDay = `${weekDays[day]}`; - - log.debug(`今天是[{day}]`, day) - log.debug(`今天是[{weekDays}]`, weekDay) - // 返回包含星期数字和对应星期名称的对象 - return { - day: day, - dayOfWeek: weekDay - } -} +// /** +// * 获取当前日期的星期信息 +// * @param {boolean} [calibrationGameRefreshTime=true] 是否进行游戏刷新时间校准 +// * @returns {Object} 返回包含星期数字和星期名称的对象 +// */ +// async function getDayOfWeek(calibrationGameRefreshTime = true) { +// // 获取当前日期对象 +// let today = new Date();//4点刷新 所以要减去4小时 +// if (calibrationGameRefreshTime) { +// today.setHours(today.getHours() - 4); // 减去 4 小 +// } +// // 获取当前日期是星期几(0代表星期日,1代表星期一,以此类推) +// const day = today.getDay(); +// // 创建包含星期名称的数组 +// const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; +// let weekDay = `${weekDays[day]}`; +// +// log.debug(`今天是[{day}]`, day) +// log.debug(`今天是[{weekDays}]`, weekDay) +// // 返回包含星期数字和对应星期名称的对象 +// return { +// day: day, +// dayOfWeek: weekDay +// } +// } /** * 执行秘境征讨剩余次数提醒的主函数 @@ -129,7 +138,10 @@ async function campaignAreaMain(openKey = true) { // 获取当前星期信息 let dayOfWeek = await getDayOfWeek(); // 如果不是周日(0代表周日),则直接返回 - const bool = dayOfWeek.day != config.campaignAreaReminderDay; + // const bool = dayOfWeek.day != config.campaignAreaReminderDay; + log.info(`秘境征讨提醒日:{0}`,JSON.stringify(config.campaignAreaReminderDays)) + const bool =!config.campaignAreaReminderDays.includes(dayOfWeek.dayOfWeek) + // log.info(`bool={0}`,bool) // 记录开始执行秘境征讨提醒的日志 log.info(`[{dayOfWeek.dayOfWeek}],${bool ? "跳过" : "开始"}执行秘境征讨剩余次数提醒`, dayOfWeek.dayOfWeek) if (bool) { @@ -148,16 +160,21 @@ async function campaignAreaMain(openKey = true) { await click(xyConfig.secretRealm.x, xyConfig.secretRealm.y) await sleep(ms * 2) // 点击秘境征讨坐标 - await click(xyConfig.campaignArea.x, xyConfig.campaignArea.y) + // await click(xyConfig.campaignArea.x, xyConfig.campaignArea.y) + const find = await findTextAndClick("征讨领域"); + if (find===null){ + log.warn("未找到征讨领域") + return + } await sleep(ms * 2) // 使用OCR识别本周秘境征讨剩余次数 let weekJson = await ocrWeeklyCount(); // 如果有剩余次数,则记录日志并发送通知 if (weekJson.count > 0) { - let uid = await uidUtil.ocrUID() + let uid = await ocrUID() log.info(`本周剩余消耗减半次数:${weekJson.count}`) - await noticeUtil.sendText(`>|本周剩余消耗减半次数:${weekJson.count}`, `UID:${uid}\n秘境征讨`) + await sendText(`>|本周剩余消耗减半次数:${weekJson.count}`, `UID:${uid}\n秘境征讨`) } } @@ -171,8 +188,8 @@ async function dailyCommissionMain(openKey = true) { // 获取当前星期信息 let dayOfWeek = await getDayOfWeek(); // 如果不是周日(0代表周日), - const bool = dayOfWeek.day != config.campaignAreaReminderDay; - + // const bool = dayOfWeek.day != config.campaignAreaReminderDay; + const bool =config.campaignAreaReminderDays.includes(dayOfWeek.dayOfWeek) // 设置操作间隔时间(毫秒) let ms = 600 // 等待一段时间 @@ -191,12 +208,17 @@ async function dailyCommissionMain(openKey = true) { if (re.daily.total > re.daily.use || re.physical.total > re.physical.use ) { - let uid = await uidUtil.ocrUID() - await noticeUtil.sendText(`>|每日委托奖励:${re.daily.use}/${re.daily.total}\n>|原粹树脂消耗:${re.physical.use}/${re.physical.total}`, `UID:${uid}\n每日委托`) + let uid = await ocrUID() + await sendText(`>|每日委托奖励:${re.daily.use}/${re.daily.total}\n>|原粹树脂消耗:${re.physical.use}/${re.physical.total}`, `UID:${uid}\n每日委托`) } } -this.campaignAreaUtil = { +// this.campaignAreaUtil = { +// campaignAreaMain, +// dailyCommissionMain, +// } + +export { campaignAreaMain, dailyCommissionMain, } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/utils/mapMission.js b/repo/js/ActivitySwitchNotice/utils/mapMission.js index 32385807f..5764904fa 100644 --- a/repo/js/ActivitySwitchNotice/utils/mapMission.js +++ b/repo/js/ActivitySwitchNotice/utils/mapMission.js @@ -1,3 +1,5 @@ +import {sendText} from "./notice"; +import {ocrUID} from "./uid"; const ocrRegionConfig = { mapMission: {x: 6, y: 8, width: 395, height: 977},//地图任务识别区域坐标和尺寸 } @@ -87,13 +89,19 @@ async function mapMission(list = [], toOpenMap = true) { log.warn(`未识别到地图任务`) return } - const uid = await uidUtil.ocrUID() + const uid = await ocrUID() let text = "" keyJsonList.forEach(item => text += "|< " + item.text + " >\n") - await noticeUtil.sendText(text, `UID:${uid}\n地图任务`) + await sendText(text, `UID:${uid}\n地图任务`) } -this.mapUtil = { +// this.mapUtil = { +// mapMission, +// ocrMapMission, +// openMap, +// } + +export { mapMission, ocrMapMission, openMap, diff --git a/repo/js/ActivitySwitchNotice/utils/notice.js b/repo/js/ActivitySwitchNotice/utils/notice.js index b985e3e54..a5eef3440 100644 --- a/repo/js/ActivitySwitchNotice/utils/notice.js +++ b/repo/js/ActivitySwitchNotice/utils/notice.js @@ -1,3 +1,4 @@ +import {sendText as wsSendText} from "./ws" const NoticeType = Object.freeze({ bgi: 'bgi',//BGI通知 independence: 'independence',//独立通知 @@ -44,7 +45,7 @@ async function sendNotice(map = new Map(), title, noNotice = false) { for (let noticeElement of configNotice.noticeList) { switch (noticeElement.type) { case NoticeType.independence: - await wsUtil.sendText(noticeText) + await wsSendText(noticeText) break case NoticeType.bgi: notification.send(noticeText) @@ -74,7 +75,7 @@ async function sendText(noticeText, title, noNotice = false) { for (let noticeElement of configNotice.noticeList) { switch (noticeElement.type) { case NoticeType.independence: - await wsUtil.sendText(text) + await wsSendText(text) break case NoticeType.bgi: notification.send(text) @@ -84,7 +85,12 @@ async function sendText(noticeText, title, noNotice = false) { return } -this.noticeUtil = { +// this.noticeUtil = { +// sendNotice, +// sendText, +// } + +export { sendNotice, sendText, } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/utils/tool.js b/repo/js/ActivitySwitchNotice/utils/tool.js new file mode 100644 index 000000000..56cf203af --- /dev/null +++ b/repo/js/ActivitySwitchNotice/utils/tool.js @@ -0,0 +1,82 @@ +/** + * 通用找文本并点击(OCR) + * @param {string} text 目标文本(单个文本) + * @param {number} [x=0] OCR 区域左上角 X + * @param {number} [y=0] OCR 区域左上角 Y + * @param {number} [w=1920] OCR 区域宽度 + * @param {number} [h=1080] OCR 区域高度 + * @param {number} [attempts=5] OCR 尝试次数 + * @param {number} [interval=50] 每次 OCR 之间的等待间隔(毫秒) + * @param {number} [preClickDelay=50] 点击前等待时间(毫秒) + * @param {number} [postClickDelay=50] 点击后等待时间(毫秒) + * + * @returns + * - RecognitionResult | null + */ +async function findTextAndClick( + text, + x = 0, + y = 0, + w = 1920, + h = 1080, + attempts = 5, + interval = 50, + preClickDelay = 50, + postClickDelay = 50 +) { + const keyword = text.toLowerCase(); + + for (let i = 0; i < attempts; i++) { + const gameRegion = captureGameRegion(); + try { + const ro = RecognitionObject.Ocr(x, y, w, h); + const results = gameRegion.findMulti(ro); + + for (let j = 0; j < results.count; j++) { + const res = results[j]; + if ( + res.isExist() && + res.text && + res.text.toLowerCase().includes(keyword) + ) { + await sleep(preClickDelay); + res.click(); + await sleep(postClickDelay); + return res; + } + } + } finally { + gameRegion.dispose(); + } + + await sleep(interval); + } + + return null; +} +/** + * 获取当前日期的星期信息 + * @param {boolean} [calibrationGameRefreshTime=true] 是否进行游戏刷新时间校准 + * @returns {Object} 返回包含星期数字和星期名称的对象 + */ +async function getDayOfWeek(calibrationGameRefreshTime = true) { + // 获取当前日期对象 + let today = new Date();//4点刷新 所以要减去4小时 + if (calibrationGameRefreshTime) { + today.setHours(today.getHours() - 4); // 减去 4 小 + } + // 获取当前日期是星期几(0代表星期日,1代表星期一,以此类推) + const day = today.getDay(); + // 创建包含星期名称的数组 + const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; + let weekDay = `${weekDays[day]}`; + + log.debug(`今天是[{day}]`, day) + log.debug(`今天是[{weekDays}]`, weekDay) + // 返回包含星期数字和对应星期名称的对象 + return { + day: day, + dayOfWeek: weekDay + } +} +export { findTextAndClick,getDayOfWeek} \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/utils/uid.js b/repo/js/ActivitySwitchNotice/utils/uid.js index 955931f9c..5104edb4f 100644 --- a/repo/js/ActivitySwitchNotice/utils/uid.js +++ b/repo/js/ActivitySwitchNotice/utils/uid.js @@ -135,7 +135,15 @@ async function check() { return check } -this.uidUtil = { +// this.uidUtil = { +// toMainUi, +// isInMainUI, +// checkUid, +// ocrUID, +// check, +// compareUid, +// } +export { toMainUi, isInMainUI, checkUid, diff --git a/repo/js/ActivitySwitchNotice/utils/ws.js b/repo/js/ActivitySwitchNotice/utils/ws.js index 455ba4c31..3f8191553 100644 --- a/repo/js/ActivitySwitchNotice/utils/ws.js +++ b/repo/js/ActivitySwitchNotice/utils/ws.js @@ -159,7 +159,11 @@ async function sendText(text) { await send(wsProxyUrl, wsUrl, ws_token, action, group_id, user_id, textList, atList) } -this.wsUtil = { +// this.wsUtil = { +// send, +// sendText +// } +export { send, sendText } \ No newline at end of file