diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-1.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-1.json new file mode 100644 index 000000000..ec2716d4e --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-1.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔11-呼呼丘-1", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754200248662 + }, + "positions": [ + { + "id": 1, + "x": 14248.3935546875, + "y": 581.4296875, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-2.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-2.json new file mode 100644 index 000000000..b7acbbac3 --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-2.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔11-呼呼丘-2", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754200241832 + }, + "positions": [ + { + "id": 1, + "x": 14309.2685546875, + "y": 462.38916015625, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-3.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-3.json new file mode 100644 index 000000000..0f7d94053 --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔11-呼呼丘-3.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔11-呼呼丘-3", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754200188083 + }, + "positions": [ + { + "id": 1, + "x": 14390.443359375, + "y": 470.20263671875, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-1.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-1.json new file mode 100644 index 000000000..e6958502d --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-1.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔12-浪浪湾-1", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754569850355 + }, + "positions": [ + { + "id": 1, + "x": 14799.513671875, + "y": 631.3671875, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-2.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-2.json new file mode 100644 index 000000000..ac5a5f832 --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-2.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔12-浪浪湾-2", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754570057671 + }, + "positions": [ + { + "id": 1, + "x": 14801.615234375, + "y": 740.56103515625, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-3.json b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-3.json new file mode 100644 index 000000000..394410b1a --- /dev/null +++ b/repo/js/AutoLeyLineOutcrop/assets/pathing/target/纳塔12-浪浪湾-3.json @@ -0,0 +1,26 @@ +{ + "info": { + "name": "纳塔12-浪浪湾-3", + "bgi_version": "0.45.0", + "type": "collect", + "order": 0, + "tags": [], + "enable_monster_loot_split": false, + "map_name": "Teyvat", + "map_match_method": "", + "items": [], + "authors": [], + "version": "1.0", + "description": "", + "last_modified_time": 1754570352636 + }, + "positions": [ + { + "id": 1, + "x": 14870.0927734375, + "y": 807.755859375, + "type": "target", + "move_mode": "walk" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/main.js b/repo/js/AutoLeyLineOutcrop/main.js index 45eb2aef9..41e5049a0 100644 --- a/repo/js/AutoLeyLineOutcrop/main.js +++ b/repo/js/AutoLeyLineOutcrop/main.js @@ -118,7 +118,9 @@ async function prepareForLeyLineRun() { await genshin.switchParty(settings.team); } // 3. 关闭自定义标记 - await closeCustomMarks(); + if (!settings.useAdventurerHandbook) { + await closeCustomMarks(); + } // 4. 添加自动拾取实时任务 // TODO: 个性化拾取策略 dispatcher.addTimer(new RealtimeTimer("AutoPick")); diff --git a/repo/js/AutoLeyLineOutcrop/manifest.json b/repo/js/AutoLeyLineOutcrop/manifest.json index c6930cc98..42559d354 100644 --- a/repo/js/AutoLeyLineOutcrop/manifest.json +++ b/repo/js/AutoLeyLineOutcrop/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "全自动地脉花", - "version": "4.1.5", + "version": "4.1.6", "tags": ["地脉花"], "bgi_version": "0.44.7", "description": "基于OCR图像识别的全自动刷取地脉花。\n💡更多信息请查看在线手册:https://hcnsvf0s8d0s.feishu.cn/wiki/Tb1twpThLi7UlykqcYOcuccTnjJ \n\n----------注意事项----------\n●仅支持BetterGI 0.44.7 及以上版本!\n●部分地脉花因特殊原因不支持全自动,具体的点位请在手册中查看。\n●树脂使用的优先级:2倍原粹树脂 > 浓缩树脂 > 原粹树脂。\n●运行时会传送到七天神像设置中设置的七天神像,需要关闭七天神像设置中的“是否就近七天神像恢复血量”,并指定七天神像。\n●战斗策略注意调度器设置中地图追踪行走配置里的“允许在JsSpript中使用”和“覆盖JS中的自动战斗配置”,只有在都打开的情况下脚本才会使用下面的战斗配置,否则会使用独立任务中的战斗策略。战斗超时时间不能大于脚本自定义配置中的时间。\n\n如果遇到问题,请先参照手册中的方法进行解决。", diff --git a/repo/js/AutoLeyLineOutcrop/utils/attemptReward.js b/repo/js/AutoLeyLineOutcrop/utils/attemptReward.js index 859fa4d31..38a243b36 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/attemptReward.js +++ b/repo/js/AutoLeyLineOutcrop/utils/attemptReward.js @@ -1,134 +1,138 @@ -/** - * 带验证的单击函数 - * @param {number} x - X坐标 - * @param {number} y - Y坐标 - * @param {string} targetText - 需要验证消失的目标文字 - * @param {number} maxRetries - 最大重试次数,默认为10 - * @returns {Promise} 是否成功 - */ -this.clickWithVerification = async function(x, y, targetText, maxRetries = 20) { - for (let i = 0; i < maxRetries; i++) { - keyUp("LBUTTON"); - click(x, y); - await sleep(400); - - // 验证目标文字是否消失 - let captureRegion = captureGameRegion(); - let resList = captureRegion.findMulti(ocrRoThis); - captureRegion.dispose(); - let textFound = false; - - if (resList && resList.count > 0) { - for (let j = 0; j < resList.count; j++) { - if (resList[j].text.includes(targetText)) { - textFound = true; - break; - } - } - } - - // 如果文字消失了,说明点击成功 - if (!textFound) { - return true; - } - } - - log.warn(`经过${maxRetries}次点击,文字"${targetText}"仍未消失`); - return false; -} - -/** - * 尝试领取地脉花奖励 - * @returns {Promise} - */ -this.attemptReward = async function (retryCount = 0) { - const MAX_RETRY = 3; - if (retryCount >= MAX_RETRY) { - throw new Error("超过最大重试次数,领取奖励失败"); - } - - log.info("开始领取地脉奖励"); - keyPress("F"); - await sleep(500); - - // 识别是否为地脉之花界面 - let captureRegion = captureGameRegion(); - let resList = captureRegion.findMulti(ocrRoThis); // 使用预定义的ocrRoThis对象 - captureRegion.dispose(); - let isValid = false; - let condensedResin = null; - let originalResin = null; - let fragileResin = null; - let isResinEmpty = false; - let dobuleReward = false; - - if (resList && resList.count > 0) { - // 分析识别到的文本 - for (let i = 0; i < resList.count; i++) { - let res = resList[i]; - if (res.text.includes("浓缩树脂")) { - isValid = true; - condensedResin = res; - } else if (res.text.includes("原粹树脂")) { - isValid = true; - originalResin = res; - } else if (res.text.includes("脆弱树脂") && settings.fragileResin) { - isValid = true; - fragileResin = res; - } else if (res.text.includes("双倍掉落")) { - isValid = true; - dobuleReward = true; - } else { - isValid = true; - isResinEmpty = true; - } - } // 处理不同的树脂情况 - if (originalResin && dobuleReward) { - log.info("选择使用原粹树脂,获得双倍产出"); - await clickWithVerification( - Math.round(originalResin.x + originalResin.width / 2) + 400, - Math.round(originalResin.y + originalResin.height / 2), - "使用" - ); - } else if (condensedResin) { - log.info("选择使用浓缩树脂"); - await clickWithVerification( - Math.round(condensedResin.x + condensedResin.width / 2) + 400, - Math.round(condensedResin.y + condensedResin.height / 2), - "使用" - ); - } else if (originalResin) { - log.info("选择使用原粹树脂"); - await clickWithVerification( - Math.round(originalResin.x + originalResin.width / 2) + 400, - Math.round(originalResin.y + originalResin.height / 2), - "使用" - ); - } else if (fragileResin) { - log.info("选择使用脆弱树脂"); - await clickWithVerification( - Math.round(fragileResin.x + fragileResin.width / 2) + 400, - Math.round(fragileResin.y + fragileResin.height / 2), - "使用" - ); - } else if (isResinEmpty) { - log.error("树脂用完了呢"); - keyPress("VK_ESCAPE"); - throw new Error("树脂已用完"); - } - if (settings.friendshipTeam) { - log.info("切换回战斗队伍"); - await sleep(500); - const switchSuccess = await switchTeam(settings.team); - } - } - - // 界面不正确,尝试重试 - if (!isValid) { - log.info("当前界面不是地脉之花界面,重试"); - await genshin.returnMainUi(); - await sleep(1000); - await autoNavigateToReward(); - await attemptReward(++retryCount); - } +/** + * 带验证的单击函数 + * @param {number} x - X坐标 + * @param {number} y - Y坐标 + * @param {string} targetText - 需要验证消失的目标文字 + * @param {number} maxRetries - 最大重试次数,默认为10 + * @returns {Promise} 是否成功 + */ +this.clickWithVerification = async function(x, y, targetText, maxRetries = 20) { + for (let i = 0; i < maxRetries; i++) { + keyUp("LBUTTON"); + click(x, y); + await sleep(400); + + // 验证目标文字是否消失 + let captureRegion = captureGameRegion(); + let resList = captureRegion.findMulti(ocrRoThis); + captureRegion.dispose(); + let textFound = false; + + if (resList && resList.count > 0) { + for (let j = 0; j < resList.count; j++) { + if (resList[j].text.includes(targetText)) { + textFound = true; + break; + } + } + } + + // 如果文字消失了,说明点击成功 + if (!textFound) { + return true; + } + } + + log.warn(`经过${maxRetries}次点击,文字"${targetText}"仍未消失`); + return false; +} + +/** + * 尝试领取地脉花奖励 + * @returns {Promise} + */ +this.attemptReward = async function (retryCount = 0) { + const MAX_RETRY = 3; + if (retryCount >= MAX_RETRY) { + throw new Error("超过最大重试次数,领取奖励失败"); + } + + log.info("开始领取地脉奖励"); + keyPress("F"); + await sleep(500); + + // 识别是否为地脉之花界面 + let captureRegion = captureGameRegion(); + let resList = captureRegion.findMulti(ocrRoThis); // 使用预定义的ocrRoThis对象 + captureRegion.dispose(); + let isValid = false; + let condensedResin = null; + let originalResin = null; + let fragileResin = null; + let isResinEmpty = false; + let dobuleReward = false; + let isOriginalResinEmpty = false; + + if (resList && resList.count > 0) { + // 分析识别到的文本 + for (let i = 0; i < resList.count; i++) { + let res = resList[i]; + if (res.text.includes("浓缩树脂")) { + isValid = true; + condensedResin = res; + } else if (res.text.includes("原粹树脂")) { + isValid = true; + originalResin = res; + } else if (res.text.includes("脆弱树脂") && settings.fragileResin) { + isValid = true; + fragileResin = res; + } else if (res.text.includes("双倍掉落")) { + isValid = true; + dobuleReward = true; + } else if (res.text.includes("补充")){ + isValid = true; + isOriginalResinEmpty = true; + } else { + isValid = true; + isResinEmpty = true; + } + } // 处理不同的树脂情况 + if (originalResin && dobuleReward && !isOriginalResinEmpty) { + log.info("选择使用原粹树脂,获得双倍产出"); + await clickWithVerification( + Math.round(originalResin.x + originalResin.width / 2) + 400, + Math.round(originalResin.y + originalResin.height / 2), + "使用" + ); + } else if (condensedResin) { + log.info("选择使用浓缩树脂"); + await clickWithVerification( + Math.round(condensedResin.x + condensedResin.width / 2) + 400, + Math.round(condensedResin.y + condensedResin.height / 2), + "使用" + ); + } else if (originalResin && !isOriginalResinEmpty) { + log.info("选择使用原粹树脂"); + await clickWithVerification( + Math.round(originalResin.x + originalResin.width / 2) + 400, + Math.round(originalResin.y + originalResin.height / 2), + "使用" + ); + } else if (fragileResin) { + log.info("选择使用脆弱树脂"); + await clickWithVerification( + Math.round(fragileResin.x + fragileResin.width / 2) + 400, + Math.round(fragileResin.y + fragileResin.height / 2), + "使用" + ); + } else if (isResinEmpty && isOriginalResinEmpty) { + log.error("树脂用完了呢"); + keyPress("VK_ESCAPE"); + throw new Error("原粹树脂不足20,无法领取奖励"); + } + if (settings.friendshipTeam) { + log.info("切换回战斗队伍"); + await sleep(500); + const switchSuccess = await switchTeam(settings.team); + } + } + + // 界面不正确,尝试重试 + if (!isValid) { + log.info("当前界面不是地脉之花界面,重试"); + await genshin.returnMainUi(); + await sleep(1000); + await autoNavigateToReward(); + await attemptReward(++retryCount); + } } \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/utils/breadthFirstPathSearch.js b/repo/js/AutoLeyLineOutcrop/utils/breadthFirstPathSearch.js index a744b69c6..13203503f 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/breadthFirstPathSearch.js +++ b/repo/js/AutoLeyLineOutcrop/utils/breadthFirstPathSearch.js @@ -1,75 +1,75 @@ -/** - * 使用广度优先搜索算法查找从传送点到目标的所有路径 - * @param {Object} nodeData - 节点数据 - * @param {Object} targetNode - 目标节点 - * @param {Object} nodeMap - 节点映射 - * @returns {Array} 找到的所有可行路径 - */ -this.breadthFirstPathSearch = -function (nodeData, targetNode, nodeMap) { - // 存储找到的所有有效路径 - const validPaths = []; - - // 获取所有传送点作为起点 - const teleportNodes = nodeData.node.filter(node => node.type === "teleport"); - log.debug(`找到 ${teleportNodes.length} 个传送点作为可能的起点`); - - // 对每个传送点,尝试查找到目标的路径 - for (const startNode of teleportNodes) { - // 初始化队列,每个元素包含 [当前节点, 路径信息] - const queue = [[startNode, { - startNode: startNode, - routes: [], - visitedNodes: new Set([startNode.id]) - }]]; - - // 广度优先搜索 - while (queue.length > 0) { - const [currentNode, pathInfo] = queue.shift(); - - // 如果已经到达目标节点 - if (currentNode.id === targetNode.id) { - validPaths.push({ - startNode: pathInfo.startNode, - targetNode: targetNode, - routes: [...pathInfo.routes] - }); - continue; // 找到一条路径,继续搜索其他可能路径 - } - - // 检查当前节点的下一个连接 - if (currentNode.next && currentNode.next.length > 0) { - for (const nextRoute of currentNode.next) { - const nextNodeId = nextRoute.target; - - // 避免循环 - if (pathInfo.visitedNodes.has(nextNodeId)) { - continue; - } - - const nextNode = nodeMap[nextNodeId]; - if (!nextNode) { - continue; - } - - // 创建新的路径信息 - const newPathInfo = { - startNode: pathInfo.startNode, - routes: [...pathInfo.routes, nextRoute.route], - visitedNodes: new Set([...pathInfo.visitedNodes, nextNodeId]) - }; - - // 加入队列 - queue.push([nextNode, newPathInfo]); - } - } - } - } - - // 检查是否存在反向路径 - const reversePaths = findReversePathsIfNeeded(nodeData, targetNode, nodeMap, validPaths); - validPaths.push(...reversePaths); - - log.debug(`共找到 ${validPaths.length} 条有效路径`); - return validPaths; +/** + * 使用广度优先搜索算法查找从传送点到目标的所有路径 + * @param {Object} nodeData - 节点数据 + * @param {Object} targetNode - 目标节点 + * @param {Object} nodeMap - 节点映射 + * @returns {Array} 找到的所有可行路径 + */ +this.breadthFirstPathSearch = +function (nodeData, targetNode, nodeMap) { + // 存储找到的所有有效路径 + const validPaths = []; + + // 获取所有传送点作为起点 + const teleportNodes = nodeData.node.filter(node => node.type === "teleport"); + log.debug(`找到 ${teleportNodes.length} 个传送点作为可能的起点`); + + // 对每个传送点,尝试查找到目标的路径 + for (const startNode of teleportNodes) { + // 初始化队列,每个元素包含 [当前节点, 路径信息] + const queue = [[startNode, { + startNode: startNode, + routes: [], + visitedNodes: new Set([startNode.id]) + }]]; + + // 广度优先搜索 + while (queue.length > 0) { + const [currentNode, pathInfo] = queue.shift(); + + // 如果已经到达目标节点 + if (currentNode.id === targetNode.id) { + validPaths.push({ + startNode: pathInfo.startNode, + targetNode: targetNode, + routes: [...pathInfo.routes] + }); + continue; // 找到一条路径,继续搜索其他可能路径 + } + + // 检查当前节点的下一个连接 + if (currentNode.next && currentNode.next.length > 0) { + for (const nextRoute of currentNode.next) { + const nextNodeId = nextRoute.target; + + // 避免循环 + if (pathInfo.visitedNodes.has(nextNodeId)) { + continue; + } + + const nextNode = nodeMap[nextNodeId]; + if (!nextNode) { + continue; + } + + // 创建新的路径信息 + const newPathInfo = { + startNode: pathInfo.startNode, + routes: [...pathInfo.routes, nextRoute.route], + visitedNodes: new Set([...pathInfo.visitedNodes, nextNodeId]) + }; + + // 加入队列 + queue.push([nextNode, newPathInfo]); + } + } + } + } + + // 检查是否存在反向路径 + const reversePaths = findReversePathsIfNeeded(nodeData, targetNode, nodeMap, validPaths); + validPaths.push(...reversePaths); + + log.debug(`共找到 ${validPaths.length} 条有效路径`); + return validPaths; } \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/utils/executePathsUsingNodeData.js b/repo/js/AutoLeyLineOutcrop/utils/executePathsUsingNodeData.js index b5841bee2..96700c8a0 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/executePathsUsingNodeData.js +++ b/repo/js/AutoLeyLineOutcrop/utils/executePathsUsingNodeData.js @@ -1,158 +1,158 @@ -/** - * 使用节点数据执行路径 - * @param {Object} position - 位置对象 - * @returns {Promise} - */ -this.executePathsUsingNodeData = async function (position) { - try { - const nodeData = await loadNodeData(); - let currentNodePosition = position; - const targetNode = findTargetNodeByPosition(nodeData, currentNodePosition.x, currentNodePosition.y); - - if (!targetNode) { - log.error(`未找到与坐标(${currentNodePosition.x}, ${currentNodePosition.y})匹配的目标节点`); - return; - } - log.debug(`找到目标节点: ID ${targetNode.id}, 位置(${targetNode.position.x}, ${targetNode.position.y})`); - const paths = findPathsToTarget(nodeData, targetNode); - - if (paths.length === 0) { - log.error(`未找到通向目标节点(ID: ${targetNode.id})的路径`); - return; - } - - // 选择最短的路径执行 - const optimalPath = selectOptimalPath(paths); - log.debug(`选择了含有 ${optimalPath.routes.length} 个路径点的最优路径`); - - // 执行路径 - await executePath(optimalPath); - currentRunTimes++; - - // 如果达到刷取次数上限,退出循环 - if (currentRunTimes >= settings.timesValue) { - return; - } - let currentNode = targetNode; - log.debug(`开始处理节点链,目标节点ID: ${targetNode.id}, next数量: ${targetNode.next ? targetNode.next.length : 'undefined'}`); - - while (currentNode.next && currentRunTimes < settings.timesValue) { - log.debug(`当前节点ID: ${currentNode.id}, next数量: ${currentNode.next.length}`); - if (currentNode.next.length === 1) { // 获取下一个节点的ID 和 路径,并在节点数据中找到下一个节点 - const nextNodeId = currentNode.next[0].target; - const nextRoute = currentNode.next[0].route; - log.debug(`单一路径: 从节点${currentNode.id}到节点${nextNodeId}, 路径: ${nextRoute}`); - const nextNode = nodeData.node.find(node => node.id === nextNodeId); - - if (!nextNode) { - return; - } - const pathObject = { - startNode: currentNode, - targetNode: nextNode, - routes: [nextRoute] - }; - - log.info(`直接执行下一个节点路径: ${nextRoute}`); - await executePath(pathObject); - - currentRunTimes++; - - log.info(`完成节点 ID ${nextNodeId}, 已执行 ${currentRunTimes}/${settings.timesValue} 次`); // 更新当前节点为下一个节点,继续检查 - currentNode = nextNode; - currentNodePosition = { x: nextNode.position.x, y: nextNode.position.y }; - } - else if (currentNode.next.length > 1) { - // 如果存在分支路线,先打开大地图判断下一个地脉花的位置,然后结合顺序边缘数据选择最优路线 - log.info("检测到多个分支路线,开始查找下一个地脉花位置"); - - // 备份当前地脉花坐标 - const currentLeyLineX = leyLineX; - const currentLeyLineY = leyLineY; - - // 打开大地图 - await genshin.returnMainUi(); - keyPress("M"); - await sleep(1000); - - // 查找下一个地脉花 - const found = await locateLeyLineOutcrop(settings.leyLineOutcropType); - await genshin.returnMainUi(); - - if (!found) { - log.warn("无法在分支点找到下一个地脉花,退出本次循环"); - return; - } - log.info(`找到下一个地脉花,位置: (${leyLineX}, ${leyLineY})`); - - // 直接比较所有分支节点到地脉花的距离,选择最近的路径 - let selectedRoute = null; - let selectedNodeId = null; - let closestDistance = Infinity; - for (const nextRoute of currentNode.next) { - const branchNodeId = nextRoute.target; - const branchNode = nodeData.node.find(node => node.id === branchNodeId); - - if (!branchNode) continue; - - const distance = calculate2DDistance( - leyLineX, leyLineY, - branchNode.position.x, branchNode.position.y - ); - - log.info(`分支节点ID ${branchNodeId} 到地脉花距离: ${distance.toFixed(2)}`); - - if (distance < closestDistance) { - closestDistance = distance; - selectedRoute = nextRoute.route; - selectedNodeId = branchNodeId; - } - } - - if (!selectedRoute) { - log.error("无法找到合适的路线,终止执行"); - // 恢复原始坐标 - leyLineX = currentLeyLineX; - leyLineY = currentLeyLineY; - return; - } - const nextNode = nodeData.node.find(node => node.id === selectedNodeId); - if (!nextNode) { - log.error(`未找到节点ID ${selectedNodeId},终止执行`); - // 恢复原始坐标 - leyLineX = currentLeyLineX; - leyLineY = currentLeyLineY; - return; - } - - log.info(`选择路线: ${selectedRoute}, 目标节点ID: ${selectedNodeId}`); - - // 创建路径对象并执行 - const pathObject = { - startNode: currentNode, - targetNode: nextNode, - routes: [selectedRoute] - }; - await executePath(pathObject); - currentRunTimes++; - log.info(`完成节点 ID ${selectedNodeId}, 已执行 ${currentRunTimes}/${settings.timesValue} 次`); - // 更新当前节点为下一个节点,继续检查 - currentNode = nextNode; - currentNodePosition = { x: nextNode.position.x, y: nextNode.position.y }; - } - else { - log.info("当前路线完成,退出循环"); - break; - } - } - } - catch (error) { - if(error.message.includes("战斗失败")) { - log.error("战斗失败,重新寻找地脉花后重试"); - return; - } - // 其他错误需要向上传播 - log.error(`执行路径时出错: ${error.message}`); - throw error; - } +/** + * 使用节点数据执行路径 + * @param {Object} position - 位置对象 + * @returns {Promise} + */ +this.executePathsUsingNodeData = async function (position) { + try { + const nodeData = await loadNodeData(); + let currentNodePosition = position; + const targetNode = findTargetNodeByPosition(nodeData, currentNodePosition.x, currentNodePosition.y); + + if (!targetNode) { + log.error(`未找到与坐标(${currentNodePosition.x}, ${currentNodePosition.y})匹配的目标节点`); + return; + } + log.debug(`找到目标节点: ID ${targetNode.id}, 位置(${targetNode.position.x}, ${targetNode.position.y})`); + const paths = findPathsToTarget(nodeData, targetNode); + + if (paths.length === 0) { + log.error(`未找到通向目标节点(ID: ${targetNode.id})的路径`); + return; + } + + // 选择最短的路径执行 + const optimalPath = selectOptimalPath(paths); + log.debug(`选择了含有 ${optimalPath.routes.length} 个路径点的最优路径`); + + // 执行路径 + await executePath(optimalPath); + currentRunTimes++; + + // 如果达到刷取次数上限,退出循环 + if (currentRunTimes >= settings.timesValue) { + return; + } + let currentNode = targetNode; + log.debug(`开始处理节点链,目标节点ID: ${targetNode.id}, next数量: ${targetNode.next ? targetNode.next.length : 'undefined'}`); + + while (currentNode.next && currentRunTimes < settings.timesValue) { + log.debug(`当前节点ID: ${currentNode.id}, next数量: ${currentNode.next.length}`); + if (currentNode.next.length === 1) { // 获取下一个节点的ID 和 路径,并在节点数据中找到下一个节点 + const nextNodeId = currentNode.next[0].target; + const nextRoute = currentNode.next[0].route; + log.debug(`单一路径: 从节点${currentNode.id}到节点${nextNodeId}, 路径: ${nextRoute}`); + const nextNode = nodeData.node.find(node => node.id === nextNodeId); + + if (!nextNode) { + return; + } + const pathObject = { + startNode: currentNode, + targetNode: nextNode, + routes: [nextRoute] + }; + + log.info(`直接执行下一个节点路径: ${nextRoute}`); + await executePath(pathObject); + + currentRunTimes++; + + log.info(`完成节点 ID ${nextNodeId}, 已执行 ${currentRunTimes}/${settings.timesValue} 次`); // 更新当前节点为下一个节点,继续检查 + currentNode = nextNode; + currentNodePosition = { x: nextNode.position.x, y: nextNode.position.y }; + } + else if (currentNode.next.length > 1) { + // 如果存在分支路线,先打开大地图判断下一个地脉花的位置,然后结合顺序边缘数据选择最优路线 + log.info("检测到多个分支路线,开始查找下一个地脉花位置"); + + // 备份当前地脉花坐标 + const currentLeyLineX = leyLineX; + const currentLeyLineY = leyLineY; + + // 打开大地图 + await genshin.returnMainUi(); + keyPress("M"); + await sleep(1000); + + // 查找下一个地脉花 + const found = await locateLeyLineOutcrop(settings.leyLineOutcropType); + await genshin.returnMainUi(); + + if (!found) { + log.warn("无法在分支点找到下一个地脉花,退出本次循环"); + return; + } + log.info(`找到下一个地脉花,位置: (${leyLineX}, ${leyLineY})`); + + // 直接比较所有分支节点到地脉花的距离,选择最近的路径 + let selectedRoute = null; + let selectedNodeId = null; + let closestDistance = Infinity; + for (const nextRoute of currentNode.next) { + const branchNodeId = nextRoute.target; + const branchNode = nodeData.node.find(node => node.id === branchNodeId); + + if (!branchNode) continue; + + const distance = calculate2DDistance( + leyLineX, leyLineY, + branchNode.position.x, branchNode.position.y + ); + + log.info(`分支节点ID ${branchNodeId} 到地脉花距离: ${distance.toFixed(2)}`); + + if (distance < closestDistance) { + closestDistance = distance; + selectedRoute = nextRoute.route; + selectedNodeId = branchNodeId; + } + } + + if (!selectedRoute) { + log.error("无法找到合适的路线,终止执行"); + // 恢复原始坐标 + leyLineX = currentLeyLineX; + leyLineY = currentLeyLineY; + return; + } + const nextNode = nodeData.node.find(node => node.id === selectedNodeId); + if (!nextNode) { + log.error(`未找到节点ID ${selectedNodeId},终止执行`); + // 恢复原始坐标 + leyLineX = currentLeyLineX; + leyLineY = currentLeyLineY; + return; + } + + log.info(`选择路线: ${selectedRoute}, 目标节点ID: ${selectedNodeId}`); + + // 创建路径对象并执行 + const pathObject = { + startNode: currentNode, + targetNode: nextNode, + routes: [selectedRoute] + }; + await executePath(pathObject); + currentRunTimes++; + log.info(`完成节点 ID ${selectedNodeId}, 已执行 ${currentRunTimes}/${settings.timesValue} 次`); + // 更新当前节点为下一个节点,继续检查 + currentNode = nextNode; + currentNodePosition = { x: nextNode.position.x, y: nextNode.position.y }; + } + else { + log.info("当前路线完成,退出循环"); + break; + } + } + } + catch (error) { + if(error.message.includes("战斗失败")) { + log.error("战斗失败,重新寻找地脉花后重试"); + return; + } + // 其他错误需要向上传播 + log.error(`执行路径时出错: ${error.message}`); + throw error; + } } \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/utils/findLeyLineOutcrop.js b/repo/js/AutoLeyLineOutcrop/utils/findLeyLineOutcrop.js index 21de2b709..f91149cd7 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/findLeyLineOutcrop.js +++ b/repo/js/AutoLeyLineOutcrop/utils/findLeyLineOutcrop.js @@ -1,69 +1,69 @@ -/** - * 查找地脉花位置 - * @param {string} country - 国家名称 - * @param {string} type - 地脉花类型 - * @returns {Promise} - */ -this.findLeyLineOutcrop = -async function (country, type) { - currentFlower = null; - await sleep(1000); - log.info("开始寻找地脉花"); - if (!config.mapPositions[country] || config.mapPositions[country].length === 0) { - throw new Error(`未找到国家 ${country} 的位置信息`); - } - - const positions = config.mapPositions[country]; - await genshin.moveMapTo(positions[0].x, positions[0].y, country); - const found = await locateLeyLineOutcrop(type); - await sleep(1000); // 移动后等一下 - if (found) return; - for (let retryCount = 1; retryCount < positions.length; retryCount++) { - const position = positions[retryCount]; - log.info(`第 ${retryCount + 1} 次尝试定位地脉花`); - log.info(`移动到位置:(${position.x}, ${position.y}), ${position.name || '未命名位置'}`); - await genshin.moveMapTo(position.x, position.y); - - const found = await locateLeyLineOutcrop(type); - if (found) return; - } - - // 如果到这里还没找到 - throw new Error("寻找地脉花失败,已达最大重试次数"); -} - -/** - * 在地图上定位地脉花 - * @param {string} type - 地脉花类型 - * @returns {Promise} 是否找到地脉花 - */ -this.locateLeyLineOutcrop = -async function (type) { - await sleep(500); // 确保画面稳定 - await genshin.setBigMapZoomLevel(3.0); - - const iconPath = type === "蓝花(经验书)" - ? "assets/icon/Blossom_of_Revelation.png" - : "assets/icon/Blossom_of_Wealth.png"; - - const captureRegion = captureGameRegion(); - const flowerList = captureRegion.findMulti(RecognitionObject.TemplateMatch(file.ReadImageMatSync(iconPath))); - captureRegion.dispose(); - - if (flowerList && flowerList.count > 0) { - currentFlower = flowerList[0]; - - const center = genshin.getPositionFromBigMap(); - const mapZoomLevel = genshin.getBigMapZoomLevel(); - const mapScaleFactor = 2.361; - - leyLineX = (960 - currentFlower.x - 25) * mapZoomLevel / mapScaleFactor + center.x; - leyLineY = (540 - currentFlower.y - 25) * mapZoomLevel / mapScaleFactor + center.y; - - log.info(`找到地脉花的坐标:(${leyLineX}, ${leyLineY})`); - return true; - } else { - log.warn("未找到地脉花"); - return false; - } +/** + * 查找地脉花位置 + * @param {string} country - 国家名称 + * @param {string} type - 地脉花类型 + * @returns {Promise} + */ +this.findLeyLineOutcrop = +async function (country, type) { + currentFlower = null; + await sleep(1000); + log.info("开始寻找地脉花"); + if (!config.mapPositions[country] || config.mapPositions[country].length === 0) { + throw new Error(`未找到国家 ${country} 的位置信息`); + } + + const positions = config.mapPositions[country]; + await genshin.moveMapTo(positions[0].x, positions[0].y, country); + const found = await locateLeyLineOutcrop(type); + await sleep(1000); // 移动后等一下 + if (found) return; + for (let retryCount = 1; retryCount < positions.length; retryCount++) { + const position = positions[retryCount]; + log.info(`第 ${retryCount + 1} 次尝试定位地脉花`); + log.info(`移动到位置:(${position.x}, ${position.y}), ${position.name || '未命名位置'}`); + await genshin.moveMapTo(position.x, position.y); + + const found = await locateLeyLineOutcrop(type); + if (found) return; + } + + // 如果到这里还没找到 + throw new Error("寻找地脉花失败,已达最大重试次数"); +} + +/** + * 在地图上定位地脉花 + * @param {string} type - 地脉花类型 + * @returns {Promise} 是否找到地脉花 + */ +this.locateLeyLineOutcrop = +async function (type) { + await sleep(500); // 确保画面稳定 + await genshin.setBigMapZoomLevel(3.0); + + const iconPath = type === "蓝花(经验书)" + ? "assets/icon/Blossom_of_Revelation.png" + : "assets/icon/Blossom_of_Wealth.png"; + + const captureRegion = captureGameRegion(); + const flowerList = captureRegion.findMulti(RecognitionObject.TemplateMatch(file.ReadImageMatSync(iconPath))); + captureRegion.dispose(); + + if (flowerList && flowerList.count > 0) { + currentFlower = flowerList[0]; + + const center = genshin.getPositionFromBigMap(); + const mapZoomLevel = genshin.getBigMapZoomLevel(); + const mapScaleFactor = 2.361; + + leyLineX = (960 - currentFlower.x - 25) * mapZoomLevel / mapScaleFactor + center.x; + leyLineY = (540 - currentFlower.y - 25) * mapZoomLevel / mapScaleFactor + center.y; + + log.info(`找到地脉花的坐标:(${leyLineX}, ${leyLineY})`); + return true; + } else { + log.warn("未找到地脉花"); + return false; + } } \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/utils/processLeyLineOutcrop.js b/repo/js/AutoLeyLineOutcrop/utils/processLeyLineOutcrop.js index f905fdf19..f351445f0 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/processLeyLineOutcrop.js +++ b/repo/js/AutoLeyLineOutcrop/utils/processLeyLineOutcrop.js @@ -25,14 +25,15 @@ async function (timeout, targetPath, retries = 0) { const result2 = captureRegion.find(ocrRo3); // 检查地脉之花状态 - 已完成状态,准备领取奖励 - if (result2.text.includes("地脉之花")) { + log.debug(`地脉花状态:${result2.text}`); + if (result2.text.includes("之花")) { log.info("识别到地脉之花,准备领取奖励"); await switchToFriendshipTeamIfNeeded(); return; } // 处理地脉溢口 - if (result2.text.includes("地脉溢口")) { + if (result2.text.includes("溢口")) { log.info("识别到地脉溢口"); keyPress("F"); await sleep(300); diff --git a/repo/js/AutoLeyLineOutcrop/utils/recognitionResin.js b/repo/js/AutoLeyLineOutcrop/utils/recognitionResin.js index abe04fdb5..223ff6bd4 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/recognitionResin.js +++ b/repo/js/AutoLeyLineOutcrop/utils/recognitionResin.js @@ -1,159 +1,159 @@ -/* - 代码迁移中,还未完成适配 -*/ - - -const CondensedRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/Condensed Resin.png")); -const FragileRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/Fragile Resin.png")); -const TemporaryRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/5.png")); -CondensedRo.threshold = 0.70; -CondensedRo.Use3Channels = true; -FragileRo.threshold = 0.70; -FragileRo.Use3Channels = true; - -this.recognitionResin = -async function() { - let totalRunNum = 0; - await genshin.returnMainUi(); - await sleep(2000); - keyPress("m"); - await sleep(2000); - - let captureRegion = captureGameRegion(); - let resList = captureRegion.findMulti(RecognitionObject.ocr(1043, 5, 300, 100)); - captureRegion.dispose(); - let IsOver = false - - for (let i = 0; i < resList.count; i++) { - let resStamina = resList[i]; - log.info(`第 ${i + 1} 个结果: ${resStamina.text}`); - await sleep(2000); - - // 提取/前面的数字 - const rawText = resStamina.text; - const splitResult = rawText.split('/'); // 用/分割字符串 - - // 确保分割后得到两部分且第一部分是有效数字 - if (splitResult.length >= 1) { - const staminaValue = parseInt(splitResult[0]); // 只取第一部分 - - if (!isNaN(staminaValue)) { - log.info(`提取的体力值: ${staminaValue}`); - - if (staminaValue >= 40) { - IsOver = true; - } - break; - } else { - log.warn("无效的数字格式"); - } - } else { - log.warn("未找到/分隔符"); - } - - await sleep(2000) - await genshin.returnMainUi(); - keyPress("b"); - await sleep(2000); - click(1245, 50); - await sleep(2000); - - // 浓缩树脂识别 - let Condensed = captureGameRegion().find(CondensedRo); - Condensed.dispose(); - let Isfive = false; - if (Condensed.isExist()) { - log.info("识别到浓缩树脂"); - let CondensedX = Math.round(Condensed.x + Condensed.width / 2 - 20) - let Condensedy = Math.round(Condensed.y + Condensed.height / 2 + 60) - log.info(`点击坐标: (${CondensedX}, ${Condensedy})`); - - let captureRegion = captureGameRegion(); - let Condensedres = captureRegion.findMulti(RecognitionObject.ocr(CondensedX, Condensedy, 50, 50)); - captureRegion.dispose(); - for (let i = 0; i < Condensedres.count; i++) { - let resCondensed = Condensedres[i]; - log.info(`浓缩树脂: ${resCondensed.text}`); - await sleep(2000); - if (resCondensed.text == 5) { - Isfive = true; - log.info("浓缩树脂已满") - await sleep(2000); - - } - } - } - // 脆弱树脂识别 - let FragileCapture = captureGameRegion(); - let Fragile = FragileCapture.find(FragileRo); - FragileCapture.dispose(); - if (Fragile.isExist()) { - log.info("识别到脆弱树脂"); - - let FragileX = Math.round(Fragile.x + Fragile.width / 2 - 20) - let Fragiley = Math.round(Fragile.y + Fragile.height / 2 + 60) - - let captureRegion = captureGameRegion(); - let Fragileres = captureRegion.findMulti(RecognitionObject.ocr(FragileX, Fragiley, 50, 50)); - captureRegion.dispose(); - - if (Fragileres.count === 0) { - log.error("OCR识别失败:未能识别到脆弱树脂数量"); - } else { - for (let i = 0; i < Fragileres.count; i++) { - let resFragile = Fragileres[i]; - if (resFragile.text && resFragile.text.trim() !== "") { - log.info("脆弱树脂数量: " + resFragile.text); - } else { - log.warn("OCR识别结果为空或无效"); - } - } - } - } else { - log.info("未识别到脆弱树脂"); - await sleep(2000); - } - // 须臾树脂识别 - let TemporaryCapture = captureGameRegion(); - let Temporary = TemporaryCapture.find(TemporaryRo); - TemporaryCapture.dispose(); - let Temporaryres = null; - if (Temporary.isExist()) { - log.info("识别到须臾树脂"); - - let TemporaryX = Math.round(Temporary.x + Temporary.width / 2 - 20) - let Temporaryy = Math.round(Temporary.y + Temporary.height / 2 + 40) - log.info(`点击坐标: (${TemporaryX}, ${Temporaryy})`); - - let captureRegion = captureGameRegion(); - Temporaryres = captureRegion.findMulti(RecognitionObject.ocr(TemporaryX, Temporaryy, 50, 50)); - captureRegion.dispose(); - } else { - log.info("未识别到须臾树脂"); - } - - if (Temporaryres && Temporaryres.count === 0) { - log.error("OCR识别失败:未能识别到须臾树脂数量"); - } else { - for (let i = 0; i < Temporaryres.count; i++) { - let resTemporary = Temporaryres[i]; - if (resTemporary.text && resTemporary.text.trim() !== "") { - log.info("须臾树脂数量: " + resTemporary.text); - } else { - log.warn("OCR识别结果为空或无效"); - } - await sleep(2000); - } - } - - - // 尝试调用任务 - - - if (IsOver && Isfive == true) { - log.info("需要前往合成台"); // 输出 true - } else { - log.info("不需要前往合成台"); - } - } +/* + 代码迁移中,还未完成适配 +*/ + + +const CondensedRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/Condensed Resin.png")); +const FragileRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/Fragile Resin.png")); +const TemporaryRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/5.png")); +CondensedRo.threshold = 0.70; +CondensedRo.Use3Channels = true; +FragileRo.threshold = 0.70; +FragileRo.Use3Channels = true; + +this.recognitionResin = +async function() { + let totalRunNum = 0; + await genshin.returnMainUi(); + await sleep(2000); + keyPress("m"); + await sleep(2000); + + let captureRegion = captureGameRegion(); + let resList = captureRegion.findMulti(RecognitionObject.ocr(1043, 5, 300, 100)); + captureRegion.dispose(); + let IsOver = false + + for (let i = 0; i < resList.count; i++) { + let resStamina = resList[i]; + log.info(`第 ${i + 1} 个结果: ${resStamina.text}`); + await sleep(2000); + + // 提取/前面的数字 + const rawText = resStamina.text; + const splitResult = rawText.split('/'); // 用/分割字符串 + + // 确保分割后得到两部分且第一部分是有效数字 + if (splitResult.length >= 1) { + const staminaValue = parseInt(splitResult[0]); // 只取第一部分 + + if (!isNaN(staminaValue)) { + log.info(`提取的体力值: ${staminaValue}`); + + if (staminaValue >= 40) { + IsOver = true; + } + break; + } else { + log.warn("无效的数字格式"); + } + } else { + log.warn("未找到/分隔符"); + } + + await sleep(2000) + await genshin.returnMainUi(); + keyPress("b"); + await sleep(2000); + click(1245, 50); + await sleep(2000); + + // 浓缩树脂识别 + let Condensed = captureGameRegion().find(CondensedRo); + Condensed.dispose(); + let Isfive = false; + if (Condensed.isExist()) { + log.info("识别到浓缩树脂"); + let CondensedX = Math.round(Condensed.x + Condensed.width / 2 - 20) + let Condensedy = Math.round(Condensed.y + Condensed.height / 2 + 60) + log.info(`点击坐标: (${CondensedX}, ${Condensedy})`); + + let captureRegion = captureGameRegion(); + let Condensedres = captureRegion.findMulti(RecognitionObject.ocr(CondensedX, Condensedy, 50, 50)); + captureRegion.dispose(); + for (let i = 0; i < Condensedres.count; i++) { + let resCondensed = Condensedres[i]; + log.info(`浓缩树脂: ${resCondensed.text}`); + await sleep(2000); + if (resCondensed.text == 5) { + Isfive = true; + log.info("浓缩树脂已满") + await sleep(2000); + + } + } + } + // 脆弱树脂识别 + let FragileCapture = captureGameRegion(); + let Fragile = FragileCapture.find(FragileRo); + FragileCapture.dispose(); + if (Fragile.isExist()) { + log.info("识别到脆弱树脂"); + + let FragileX = Math.round(Fragile.x + Fragile.width / 2 - 20) + let Fragiley = Math.round(Fragile.y + Fragile.height / 2 + 60) + + let captureRegion = captureGameRegion(); + let Fragileres = captureRegion.findMulti(RecognitionObject.ocr(FragileX, Fragiley, 50, 50)); + captureRegion.dispose(); + + if (Fragileres.count === 0) { + log.error("OCR识别失败:未能识别到脆弱树脂数量"); + } else { + for (let i = 0; i < Fragileres.count; i++) { + let resFragile = Fragileres[i]; + if (resFragile.text && resFragile.text.trim() !== "") { + log.info("脆弱树脂数量: " + resFragile.text); + } else { + log.warn("OCR识别结果为空或无效"); + } + } + } + } else { + log.info("未识别到脆弱树脂"); + await sleep(2000); + } + // 须臾树脂识别 + let TemporaryCapture = captureGameRegion(); + let Temporary = TemporaryCapture.find(TemporaryRo); + TemporaryCapture.dispose(); + let Temporaryres = null; + if (Temporary.isExist()) { + log.info("识别到须臾树脂"); + + let TemporaryX = Math.round(Temporary.x + Temporary.width / 2 - 20) + let Temporaryy = Math.round(Temporary.y + Temporary.height / 2 + 40) + log.info(`点击坐标: (${TemporaryX}, ${Temporaryy})`); + + let captureRegion = captureGameRegion(); + Temporaryres = captureRegion.findMulti(RecognitionObject.ocr(TemporaryX, Temporaryy, 50, 50)); + captureRegion.dispose(); + } else { + log.info("未识别到须臾树脂"); + } + + if (Temporaryres && Temporaryres.count === 0) { + log.error("OCR识别失败:未能识别到须臾树脂数量"); + } else { + for (let i = 0; i < Temporaryres.count; i++) { + let resTemporary = Temporaryres[i]; + if (resTemporary.text && resTemporary.text.trim() !== "") { + log.info("须臾树脂数量: " + resTemporary.text); + } else { + log.warn("OCR识别结果为空或无效"); + } + await sleep(2000); + } + } + + + // 尝试调用任务 + + + if (IsOver && Isfive == true) { + log.info("需要前往合成台"); // 输出 true + } else { + log.info("不需要前往合成台"); + } + } } \ No newline at end of file diff --git a/repo/js/AutoLeyLineOutcrop/utils/recognizeTextInRegion.js b/repo/js/AutoLeyLineOutcrop/utils/recognizeTextInRegion.js index a65666574..32bb57c04 100644 --- a/repo/js/AutoLeyLineOutcrop/utils/recognizeTextInRegion.js +++ b/repo/js/AutoLeyLineOutcrop/utils/recognizeTextInRegion.js @@ -1,75 +1,75 @@ -/** - * 识别战斗结果 - * @param {number} timeout - 超时时间 - * @returns {Promise} 战斗是否成功 - */ -this.recognizeTextInRegion = -async function (timeout) { - return new Promise((resolve, reject) => { - (async () => { - try { - let startTime = Date.now(); - let noTextCount = 0; - const successKeywords = ["挑战达成", "战斗胜利", "挑战成功"]; - const failureKeywords = ["挑战失败"]; - - // 循环检测直到超时 - while (Date.now() - startTime < timeout) { - let captureRegion = null; - try { - captureRegion = captureGameRegion(); - let result = captureRegion.find(ocrRo1); - let text = result.text; - - // 检查成功关键词 - for (let keyword of successKeywords) { - if (text.includes(keyword)) { - log.debug("检测到战斗成功关键词: {0}", keyword); - resolve(true); - return; - } - } - - // 检查失败关键词 - for (let keyword of failureKeywords) { - if (text.includes(keyword)) { - log.debug("检测到战斗失败关键词: {0}", keyword); - resolve(false); - return; - } - } - - let foundText = recognizeFightText(captureRegion); - if (!foundText) { - noTextCount++; - log.info(`检测到可能离开战斗区域,当前计数: ${noTextCount}`); - - if (noTextCount >= 10) { - log.warn("已离开战斗区域"); - resolve(false); - return; - } - } - else { - noTextCount = 0; // 重置计数 - } - } - catch (error) { - log.error("OCR过程中出错: {0}", error); - } - finally { - if (captureRegion) { - captureRegion.dispose(); - } - } - await sleep(1000); // 检查间隔 - } - - log.warn("在超时时间内未检测到战斗结果"); - resolve(false); - } catch (error) { - reject(error); - } - })(); - }); +/** + * 识别战斗结果 + * @param {number} timeout - 超时时间 + * @returns {Promise} 战斗是否成功 + */ +this.recognizeTextInRegion = +async function (timeout) { + return new Promise((resolve, reject) => { + (async () => { + try { + let startTime = Date.now(); + let noTextCount = 0; + const successKeywords = ["挑战达成", "战斗胜利", "挑战成功"]; + const failureKeywords = ["挑战失败"]; + + // 循环检测直到超时 + while (Date.now() - startTime < timeout) { + let captureRegion = null; + try { + captureRegion = captureGameRegion(); + let result = captureRegion.find(ocrRo1); + let text = result.text; + + // 检查成功关键词 + for (let keyword of successKeywords) { + if (text.includes(keyword)) { + log.debug("检测到战斗成功关键词: {0}", keyword); + resolve(true); + return; + } + } + + // 检查失败关键词 + for (let keyword of failureKeywords) { + if (text.includes(keyword)) { + log.debug("检测到战斗失败关键词: {0}", keyword); + resolve(false); + return; + } + } + + let foundText = recognizeFightText(captureRegion); + if (!foundText) { + noTextCount++; + log.info(`检测到可能离开战斗区域,当前计数: ${noTextCount}`); + + if (noTextCount >= 10) { + log.warn("已离开战斗区域"); + resolve(false); + return; + } + } + else { + noTextCount = 0; // 重置计数 + } + } + catch (error) { + log.error("OCR过程中出错: {0}", error); + } + finally { + if (captureRegion) { + captureRegion.dispose(); + } + } + await sleep(1000); // 检查间隔 + } + + log.warn("在超时时间内未检测到战斗结果"); + resolve(false); + } catch (error) { + reject(error); + } + })(); + }); } \ No newline at end of file