From a98d4d67dcbcb672d69109a4e50b9f639afb3f18 Mon Sep 17 00:00:00 2001 From: mno <718135749@qq.com> Date: Thu, 7 Aug 2025 09:41:32 +0800 Subject: [PATCH] =?UTF-8?q?js=EF=BC=9A=E9=94=84=E5=9C=B0=E4=B8=80=E6=9D=A1?= =?UTF-8?q?=E9=BE=991.3.4=20(#1495)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * js:锄地一条龙1.3.4 ### 1.3.3(2025.08.07) 1.修复拾取失效(再出问题就踹秋秋云屁股) 2.修复泥头车模式卡复活界面 * Update README.md --- repo/js/AutoHoeingOneDragon/README.md | 3 + .../AutoHoeingOneDragon/assets/RevivalUI.png | Bin 0 -> 1430 bytes repo/js/AutoHoeingOneDragon/main.js | 360 ++++++++++-------- repo/js/AutoHoeingOneDragon/manifest.json | 2 +- 4 files changed, 195 insertions(+), 170 deletions(-) create mode 100644 repo/js/AutoHoeingOneDragon/assets/RevivalUI.png diff --git a/repo/js/AutoHoeingOneDragon/README.md b/repo/js/AutoHoeingOneDragon/README.md index 3299cf0b..926a6c46 100644 --- a/repo/js/AutoHoeingOneDragon/README.md +++ b/repo/js/AutoHoeingOneDragon/README.md @@ -74,6 +74,9 @@ --- ### 更新日志 +### 1.3.4(2025.08.07) +1.修复拾取失效 +2.修复泥头车模式卡复活界面 ### 1.3.3(2025.08.05) 1.修复拾取失效 ### 1.3.2(2025.08.05) diff --git a/repo/js/AutoHoeingOneDragon/assets/RevivalUI.png b/repo/js/AutoHoeingOneDragon/assets/RevivalUI.png new file mode 100644 index 0000000000000000000000000000000000000000..e5a5ae76bd9d0bfe154a6e0de91841fec4d76165 GIT binary patch literal 1430 zcmV;H1!?+;P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1uIEJK~y+TCCo`| zoOc00@%LZ8bvDm9UT19A&N5Eo5=a}!CPNWY0a+EGmIGWtia7SbiG$BvIdJ6;LOE4I z0tH1Xv{9TmajOnqVtXdzW$YP`XP{MS6m`4QW5eIK-99C<% zhQKx9u;Md0dX3TCG;a>q7)BkOv_fbDp*5E4Fqxkw6)%ux9^v=m*q3d#_FwVr)qh#r z_<|rfp^$fp<2J-C{LTcw`sDYFBo}!2=#LzozQ#_*^!k1JgFb^G%T)d*?-lRz{^DK4 zajhJWk4@q;pw(+ru2$GDzu@J@zp0FGCE>bQ z<|w=6S9FJa%ue0nN6WvVc=3BgUIGz96b_NK`YC(mJ-#V@O}BkU+LhFf-cTv;V5vO! z?|ejIW||lUm|UE{!j0?8B+W&7-6m&e2l#_7rqrCDHQCMBwCwJB%9{Ebw;VQiIf(FnR&Ds z;Dt?8@pgK(aoXqPXn^N6c)hzucUa~ZD-W2NT0|QT0Fej~LLw2wfaBQMc7n6!5%qc# z%W|mI_gLTf9P#O&mSaa`u|*CG7gIQV>)mTC-~J^^Cm;sITLL@`Ox`x2({EBe*yW37 zk2pLnfryA@gnEA^y((l2(V(0{Aj=c?Pt$!j#gwz5pvKWR% zGBHM{+o5_`<*dDrnQ9CXPxmK3ZTjnARD z{h&>E&?k&yw9?E>7MY(bVk#GZ7$Gg&!t;D$53-4Ql(Y~kCN@IK?T1u*PdFdG#*ci$ zSW@rr&=@|Y?tMlt+y)>i%c+qa6TzUtq`#NhgOA7SeKEFibq4QY#V15Fr7Z>GU$=$vl}v8pjnV z>5?NG0jBFQh}w9j<>;NEvfv&0CCFDyYZIjm0FG*VZ0*0m7hRle0-4C9DJ;y8o^UyAZ1ec@ztd_T zpd=_I(b~pg8tD}kIy-yoc%p}!OQKdD+*(D%2pw_WJm&Z8Q3&L%UNL;QLDcd^s~ zO8YbqS~L$@4C@9{>C4=>bdMXC?xCCrWk(3lLiiTlu*ugu>wLNK4~{#V1jc~E@22OaK4? literal 0 HcmV?d00001 diff --git a/repo/js/AutoHoeingOneDragon/main.js b/repo/js/AutoHoeingOneDragon/main.js index 4ceaa4f1..b6c0c47f 100644 --- a/repo/js/AutoHoeingOneDragon/main.js +++ b/repo/js/AutoHoeingOneDragon/main.js @@ -1,15 +1,15 @@ -//当前js版本1.3.3 +//当前js版本 1.3.4 + //拾取时上下滑动的时间 -const timeMoveUp = 1000; -const timeMoveDown = 1500; +const timeMoveUp = 500; +const timeMoveDown = 1000; const pickupMode = settings.pickupMode || "js拾取,默认只拾取狗粮和晶蝶"; if (settings.activeDumperMode) { //处理泥头车信息 dumpers = settings.activeDumperMode.split(',').map(Number).filter(num => num === 1 || num === 2 || num === 3 || num === 4); } else { dumpers = []; } -const trigger = Number(settings.trigger) || 50; -let state; +trigger = (+settings.trigger || 50); (async function () { //自定义配置处理 @@ -475,37 +475,89 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo let lastMoveDown = 0; let lastPickupTime = new Date(); let lastPickupItem = ""; - // 初始化状态变量 - state = { completed: false, cancelRequested: false, atMainUi: false, lastCheckMainUi: new Date() }; + // 定义状态变量 + let state = { completed: false, cancelRequested: false, atMainUi: false, lastCheckMainUi: new Date() }; // 定义图像路径和目标文本列表 const imagePath = `assets/F_Dialogue.png`; const textxRange = { min: 1210, max: 1412 }; const texttolerance = 30; // Y 坐标容错范围 - // 启动路径文件执行任务 - const pathTask = executePathFile(pathFilePath); + //检查是否在主界面 + async function isMainUI() { + // 修改后的图像路径 + const imagePath = "assets/MainUI.png"; - // 根据条件决定是否启动 OCR 检测和交互任务 - let ocrTask = null; - if (pickupMode === "js拾取,默认只拾取狗粮和晶蝶") { - ocrTask = performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance); + // 修改后的识别区域(左上角区域) + const xMin = 0; + const yMin = 0; + const width = 150; // 识别区域宽度 + const height = 150; // 识别区域高度 + + // 尝试次数设置为 3 次 + const maxAttempts = 3; + + let attempts = 0; + while (attempts < maxAttempts && !state.cancelRequested) { + try { + let template = file.ReadImageMatSync(imagePath); + let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); + let result = captureGameRegion().find(recognitionObject); + if (result.isExist()) { + return true; // 如果找到图标,返回 true + } + } catch (error) { + log.error(`识别图像时发生异常: ${error.message}`); + if (state.cancelRequested) { + break; // 如果请求了取消,则退出循环 + } + return false; // 发生异常时返回 false + } + attempts++; // 增加尝试次数 + await sleep(trigger); // 每次检测间隔 trigger 毫秒 + } + if (state.cancelRequested) { + log.info("图像识别任务已取消"); + } + return false; // 如果尝试次数达到上限或取消,返回 false } - // 根据条件决定是否启动泥头车任务 - let dumperTask = null; - if (dumpers.length > 0) { // 检查 dumpers 是否不为空 - dumperTask = dumper(pathFilePath, map_name); // 调用 dumper 函数 - } + //检查是否在复活界面 + async function isRevivalUI() { + // 修改后的图像路径 + const imagePath = "assets/RevivalUI.png"; - // 等待所有任务完成 - try { - await Promise.allSettled([pathTask, ocrTask, dumperTask]); - } catch (error) { - console.error(`执行任务时发生错误:${error.message}`); - state.cancelRequested = true; // 设置取消标志 - } finally { - state.completed = true; // 确保任务标记为完成 - state.cancelRequested = true; // 设置取消标志 + // 修改后的识别区域(左上角区域) + const xMin = 450; + const yMin = 200; + const width = 1000; // 识别区域宽度 + const height = 250; // 识别区域高度 + + // 尝试次数设置为 10 次 + const maxAttempts = 10; + + let attempts = 0; + while (attempts < maxAttempts && !state.cancelRequested) { + try { + let template = file.ReadImageMatSync(imagePath); + let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); + let result = captureGameRegion().find(recognitionObject); + if (result.isExist()) { + return true; // 如果找到图标,返回 true + } + } catch (error) { + log.error(`识别图像时发生异常: ${error.message}`); + if (state.cancelRequested) { + break; // 如果请求了取消,则退出循环 + } + return false; // 发生异常时返回 false + } + attempts++; // 增加尝试次数 + await sleep(trigger); // 每次检测间隔 trigger 毫秒 + } + if (state.cancelRequested) { + log.info("图像识别任务已取消"); + } + return false; // 如果尝试次数达到上限或取消,返回 false } // 定义一个函数用于执行路径文件 @@ -522,21 +574,80 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo // 定义一个函数用于执行OCR识别和交互 async function performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance) { - await sleep(5000);//启动地图追踪前五秒不执行ocr - let lastOcrTime = Date.now() - trigger; - while (!state.completed && !state.cancelRequested) { - const ocrTime = Date.now(); - if (ocrTime - lastOcrTime < trigger) { - //限制识别频率 - await sleep(trigger - (ocrTime - lastOcrTime)); + async function performOcr(whitelistKeywords, xRange, yRange, timeout = 200) { + let startTime = Date.now(); + while (Date.now() - startTime < timeout) { + try { + // 在捕获的区域内进行OCR识别 + let ra = captureGameRegion(); + let resList = ra.findMulti(RecognitionObject.ocr( + xRange.min, yRange.min, + xRange.max - xRange.min, yRange.max - yRange.min + )); + + // 遍历识别结果,检查是否找到目标文本 + let results = []; + for (let i = 0; i < resList.count; i++) { + let res = resList[i]; + let correctedText = res.text; + + // 如果 whitelistKeywords 为空,则直接将所有文本视为匹配 + if (whitelistKeywords.length === 0) { + results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height }); + } else { + // 否则,检查是否包含目标文本 + for (let targetText of whitelistKeywords) { + if (correctedText.includes(targetText)) { + results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height }); + break; // 匹配到一个目标文本后即可跳出循环 + } + } + } + } + return results; + } catch (error) { + log.error(`识别文字时发生异常: ${error.message}`); + return []; + } } - lastOcrTime = ocrTime; + log.warn("OCR识别超时"); + return []; + } + + while (!state.completed && !state.cancelRequested) { + // 尝试找到 F 图标并返回其坐标 + async function findFIcon(imagePath, xMin, yMin, width, height, timeout = 500) { + let startTime = Date.now(); + while (Date.now() - startTime < timeout && !state.cancelRequested) { + try { + let template = file.ReadImageMatSync(imagePath); + let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); + let result = captureGameRegion().find(recognitionObject); + if (result.isExist()) { + return { success: true, x: result.x, y: result.y, width: result.width, height: result.height }; + } + } catch (error) { + log.error(`识别图像时发生异常: ${error.message}`); + if (state.cancelRequested) { + break; // 如果请求了取消,则退出循环 + } + return null; + } + await sleep(trigger * 2); // 找不到f时等待 trigger*2 毫秒 + } + if (state.cancelRequested) { + log.info("图像识别任务已取消"); + } + return null; + } + // 尝试找到 F 图标 - let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 500); + let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 200); if (!fRes) { state.atMainUi = await isMainUI(); state.lastCheckMainUi = new Date(); if (state.atMainUi) { + //log.info("在主界面,尝试下滑"); await keyMouseScript.runFile(`assets/滚轮下翻.json`); } continue; @@ -557,18 +668,19 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo continue; } - if ((new Date() - lastPickupTime) > 1000 || ocrResult.text != lastPickupItem) { - log.info(`交互或拾取:"${ocrResult.text}"`); - lastPickupTime = new Date(); - lastPickupItem = ocrResult.text; - } - // 计算目标文本的中心Y坐标 let centerYTargetText = ocrResult.y + ocrResult.height / 2; if (Math.abs(centerYTargetText - centerYF) <= texttolerance) { keyPress("F"); // 执行交互操作 - await sleep(trigger); + await sleep(trigger); // 操作后暂停 50 毫秒 foundTarget = true; + + if ((new Date() - lastPickupTime) > 1000 || ocrResult.text != lastPickupItem) { + log.info(`交互或拾取:"${ocrResult.text}"`); + lastPickupTime = new Date(); + lastPickupItem = ocrResult.text; + } + break; } } @@ -580,6 +692,7 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo // 如果距离上次下翻超过timeMoveUp秒,则执行下翻 if (currentTime - lastMoveDown > timeMoveUp) { await keyMouseScript.runFile(`assets/滚轮下翻.json`); + // 如果这是第一次下翻,记录这次下翻的时间 if (thisMoveUpTime === 0) { thisMoveUpTime = currentTime; // 记录第一次上翻的时间 @@ -602,7 +715,7 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo } } - //泥头车模式 + //处理泥头车模式 async function dumper(pathFilePath, map_name) { let lastDumperTimer = 0; const dumperCD = 10000; @@ -684,6 +797,17 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo keyPress('e'); await sleep(400); } + + for (let i = 0; i < 10; i++) { + if (await isRevivalUI()) { + //检测到复苏界面时,退出复苏界面 + keyPress("VK_ESCAPE"); + await sleep(500); + await genshin.returnMainUi(); + } else { + break; + } + } } } catch (error) { } @@ -700,135 +824,30 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo } } - // 尝试找到 F 图标并返回其坐标 - async function findFIcon(imagePath, xMin, yMin, width, height, timeout = 500) { - //log.info('判断是否存在f图标'); - let lastOcrTime = Date.now() - trigger; - let startTime = Date.now(); - while (Date.now() - startTime < timeout && !state.cancelRequested) { - const ocrTime = Date.now(); - if (ocrTime - lastOcrTime < trigger) { - //限制识别频率 - await sleep(trigger - (ocrTime - lastOcrTime)); - } - lastOcrTime = ocrTime; - try { - let template = file.ReadImageMatSync(imagePath); - let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); - let resultFIcon = captureGameRegion().find(recognitionObject); - //captureGameRegion().dispose; - if (resultFIcon.isExist()) { - return { success: true, x: resultFIcon.x, y: resultFIcon.y, width: resultFIcon.width, height: resultFIcon.height }; - } - } catch (error) { - log.error(`识别图像时发生异常: ${error.message}`); - if (state.cancelRequested) { - break; // 如果请求了取消,则退出循环 - } - return null; - } - } - if (state.cancelRequested) { - log.info("图像识别任务已取消"); - } - return null; + // 启动路径文件执行任务 + const pathTask = executePathFile(pathFilePath); + + // 根据条件决定是否启动 OCR 检测和交互任务 + let ocrTask = null; + if (pickupMode === "js拾取,默认只拾取狗粮和晶蝶") { + ocrTask = performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance); } - async function performOcr(whitelistKeywords, xRange, yRange, timeout = 200) { - //log.info('判断目标文本'); - let lastOcrTime = Date.now() - trigger; - let startTime = Date.now(); - while (Date.now() - startTime < timeout && !state.cancelRequested) { - const ocrTime = Date.now(); - if (ocrTime - lastOcrTime < trigger) { - //限制识别频率 - await sleep(trigger - (ocrTime - lastOcrTime)); - } - lastOcrTime = ocrTime; - try { - // 在捕获的区域内进行OCR识别 - let ra = captureGameRegion(); - //captureGameRegion().dispose; - let resList = ra.findMulti(RecognitionObject.ocr( - xRange.min, yRange.min, - xRange.max - xRange.min, yRange.max - yRange.min - )); - - // 遍历识别结果,检查是否找到目标文本 - let results = []; - for (let i = 0; i < resList.count; i++) { - let res = resList[i]; - let correctedText = res.text; - - // 如果 whitelistKeywords 为空,则直接将所有文本视为匹配 - if (whitelistKeywords.length === 0) { - results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height }); - } else { - // 否则,检查是否包含目标文本 - for (let targetText of whitelistKeywords) { - if (correctedText.includes(targetText)) { - results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height }); - break; // 匹配到一个目标文本后即可跳出循环 - } - } - } - } - return results; - } catch (error) { - log.error(`识别文字时发生异常: ${error.message}`); - return []; - } - } - log.warn("OCR识别超时"); - return []; + // 启动泥头车 + let dumperTask = null; + if (dumpers.length > 0) { // 检查 dumpers 是否不为空 + dumperTask = dumper(pathFilePath, map_name); // 调用 dumper 函数 } - //检查是否在主界面 - async function isMainUI() { - //log.info('判断是否处于主界面'); - // 修改后的图像路径 - const imagePath = "assets/MainUI.png"; - - // 修改后的识别区域(左上角区域) - const xMin = 0; - const yMin = 0; - const width = 150; // 识别区域宽度 - const height = 150; // 识别区域高度 - - // 尝试次数设置为 2 次 - const maxAttempts = 2; - - let attempts = 0; - let lastOcrTime = Date.now() - trigger; - while (attempts < maxAttempts && !state.cancelRequested) { - const ocrTime = Date.now(); - if (ocrTime - lastOcrTime < trigger) { - //限制识别频率 - await sleep(trigger - (ocrTime - lastOcrTime)); - } - lastOcrTime = ocrTime; - try { - let template = file.ReadImageMatSync(imagePath); - let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); - let resultMainUi = captureGameRegion().find(recognitionObject); - //captureGameRegion().dispose; - if (resultMainUi.isExist()) { - return true; // 如果找到图标,返回 true - } - } catch (error) { - log.error(`识别图像时发生异常: ${error.message}`); - if (state.cancelRequested) { - break; // 如果请求了取消,则退出循环 - } - return false; // 发生异常时返回 false - } - attempts++; // 增加尝试次数 - await sleep(2); // 每次检测间隔 2 毫秒 - } - if (state.cancelRequested) { - log.info("图像识别任务已取消"); - } - return false; // 如果尝试次数达到上限或取消,返回 false + // 等待所有任务完成 + try { + await Promise.allSettled([pathTask, ocrTask, dumperTask]); + } catch (error) { + console.error(`执行任务时发生错误:${error.message}`); + state.cancelRequested = true; // 设置取消标志 + } finally { + state.completed = true; // 确保任务标记为完成 + state.cancelRequested = true; // 设置取消标志 } } @@ -1326,3 +1345,6 @@ async function isTimeRestricted(timeRule, threshold = 5) { log.info("不处于限制时间"); return false; // 当前时间不在限制时间内 } + + + diff --git a/repo/js/AutoHoeingOneDragon/manifest.json b/repo/js/AutoHoeingOneDragon/manifest.json index 793fb0ce..4bec1272 100644 --- a/repo/js/AutoHoeingOneDragon/manifest.json +++ b/repo/js/AutoHoeingOneDragon/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "锄地一条龙", - "version": "1.3.3", + "version": "1.3.4", "description": "一站式解决自动化锄地,支持只拾取狗粮,请仔细阅读README.md后使用", "authors": [ {