diff --git a/repo/js/AutoFontaineLeyLine/README.md b/repo/js/AutoFontaineLeyLine/README.md index b8875106..fcf65354 100644 --- a/repo/js/AutoFontaineLeyLine/README.md +++ b/repo/js/AutoFontaineLeyLine/README.md @@ -2,15 +2,11 @@ ## 零、前言 -测试中,注意事项不完善请谅解,如有BUG,QQ:119996800,随时欢迎反馈。 -后续优化代码和使用说明,先测试看如何! -感谢平面镜和D捣蛋两位大佬的基础线路和逻辑。 +- 本代码仅供娱乐学习,下载请24小时内删除,禁止用于商业行为,如有BUG,非常欢迎请到测试群反馈或Q119996800。 +- 感谢平面镜和D捣蛋两位大佬的基础线路和逻辑。 ## 一、省流注意事项 -1. 目前设置两次自动战斗,加入了错误打开奖励页面的检测,解决误触领奖的错误,建议把超时时间设定为60秒以上,并勾选更快检测战斗结束,根据练度不同调整。 -2. 建议手动把自动拾取关闭,公版没有API接口可以关闭,开始前设置不自动拾取怪物的掉落物,能让线路运行更流畅。 -3. 禁用UID刷取地脉花有概率识别不成功,如更换纯色或没花纹的名片能大大提高识别率(99.99999%)。 ## 二、配置简介 @@ -27,90 +23,17 @@ 6. **直跑模式**:当打完一个地脉花后,如下一个地脉花比较近,直接跑过去而不是重新传送。 + ## 三、更新说明 -### v.1.1版本:20250410 +### v.3.3版本:20250716 -1. 修复自动战斗不停向前走的问题。 -2. 修复第一次战斗部不切换战斗队伍问题。 -3. 修复线路1第三朵花文件命错误。 -4. 修复队伍未填写判断为已定义问题,改为在设置过又删除队伍后判断未未定义。 -5. 修复树脂耗尽模式下,不打完整体线路问题,改为强制打完整体线路。 -6. 新增,如地脉花线路不在初始位置,快速模式是找不到的,在模糊位置可能被找到,即线路在被打过后,尝试通过无视树脂是否用完,遍历此线路查找线路剩余的地脉花,如再次找到地脉花,恢复正常判断树脂是否用完。 -7. 优化快速查找模式下的准确性。 -8. 优化模糊模式下的搜索范围,和坐标位置。 - -### v.1.2版本:20250414 - -1. 优化切换队伍时间,避免可能得切换队伍失败导致退出的情况。 -2. 修复线路2在快速寻找模式下识别不准确问题。 -3. 优化提前出地脉花的检测时间。 -4. 特殊处理:1、枫丹路线2秋分山西侧锚点左下第五朵花特殊处理,避免错误传送到地下螃蟹,直接跑过去。 - -### v.1.3版本:202500422 - -1. 优化最后领奖时检测是否误触地脉之花导致任务失败的问题。 -2. 修复模糊模式下找到地脉花但没有的情况下会继续寻找地脉花的问题。 -3. 优化模糊查找下的开始线路。 -4. 修复由于检测地脉之花页面导致的软件报错。 - -### v.2.0版本:20250503 - -1. 重写寻找地脉花线路方法,删除模糊寻找模式。 -2. 添加直跑模式,当打完一个地脉花后,如下一个地脉花比较近,直接跑过去而不是重新传送。(要求BGI的44.8版本) - -### v.2.1版本:20250512 - -1. 更改UID识别方法。(适配原神UI改变) - -### v.2.2版本:20250524 - -1. 参考D捣蛋和秋云佬的代码,加入异步检测战斗结束。 - -### v.2.3版本:20250528 - -1. 优化寻找地脉花逻辑。 - -### v.2.4版本:20250613 - -1. 特殊处理第二线路第5朵花,避免传送到螃蟹。 -2. 调整领取OCR范围,添加选择优先使用的树脂类型(适配3次地脉双倍)。 -3. 调整按次数执行逻辑,解决次数大于单线路打不够次数的问题。 - -### v.2.5版本:20250619 - -1. 适配5.7版本树脂的选择使用。 - - 说明:设定树脂顺序,1=浓缩树脂/2=原粹树脂/3=脆弱树脂/4=须臾树脂,用`/`隔开,填写对应的树脂数字即可,默认:1/2 ,表示先使用浓缩树脂,再使用原粹树脂,不填的不使用" - -### v.2.6版本:20250620 - -1. 修复参数错误 -2. 前往地脉花和领取奖励坐标优化,减少不必要的位置判断点,加速到达和领取。 - -### v.2.7版本:20250621 - -1. 优化超时时间的设定。 - -### v.2.8版本:20250626 - -1. 减少直跑模式下的途经点数量,防止卡死。 - -### v.2.9版本:20250629 - -1. 添加树脂数量识别,防止树脂耗尽的时候多跑一次。 - -### v.3.0版本:20250701 - -1. 优化战斗失败自动重试2次。 -2. 优化当有须臾树脂,脆弱树脂不显示的处理。 -3. 优化在地脉已经打过时,直接领取奖励。 - -### v.3.1版本:20250702 +- **新功能**: - **优化**: -1. 优化树脂识别OCR区域。 -2. log显示优化。 -3. 修复图像识别构造函数错误。 +1. 优化战斗完成后寻找地脉花逻辑,提高开花领奖正确率。 +2. 优化结束战斗异常和领奖异常的处理。 +3. 修复无法使用须臾树脂的问题。 ### v.3.2版本:20250705 @@ -123,4 +46,87 @@ 4. 优化JS配置显示。 5. 优化线路2第五朵花的特殊处理,解决开花和战斗区域太远的问题。 6. 优化设定默认使用异步战斗。 -7. 优化领奖速度。 \ No newline at end of file +7. 优化领奖速度。 + +### v.3.1版本:20250702 + +- **优化**: +1. 优化树脂识别OCR区域。 +2. log显示优化。 +3. 修复图像识别构造函数错误。 + +### v.3.0版本:20250701 + +1. 优化战斗失败自动重试2次。 +2. 优化当有须臾树脂,脆弱树脂不显示的处理。 +3. 优化在地脉已经打过时,直接领取奖励。 + +### v.2.9版本:20250629 + +1. 添加树脂数量识别,防止树脂耗尽的时候多跑一次。 + +### v.2.8版本:20250626 + +1. 减少直跑模式下的途经点数量,防止卡死。 + +### v.2.7版本:20250621 + +1. 优化超时时间的设定。 + +### v.2.6版本:20250620 + +1. 修复参数错误 +2. 前往地脉花和领取奖励坐标优化,减少不必要的位置判断点,加速到达和领取。 + +### v.2.5版本:20250619 + +1. 适配5.7版本树脂的选择使用。 + - 说明:设定树脂顺序,1=浓缩树脂/2=原粹树脂/3=脆弱树脂/4=须臾树脂,用`/`隔开,填写对应的树脂数字即可,默认:1/2 ,表示先使用浓缩树脂,再使用原粹树脂,不填的不使用" + +### v.2.4版本:20250613 + +1. 特殊处理第二线路第5朵花,避免传送到螃蟹。 +2. 调整领取OCR范围,添加选择优先使用的树脂类型(适配3次地脉双倍)。 +3. 调整按次数执行逻辑,解决次数大于单线路打不够次数的问题。 + +### v.2.3版本:20250528 + +1. 优化寻找地脉花逻辑。 + +### v.2.2版本:20250524 + +1. 参考D捣蛋和秋云佬的代码,加入异步检测战斗结束。 + +### v.2.1版本:20250512 + +1. 更改UID识别方法。(适配原神UI改变) + +### v.2.0版本:20250503 + +1. 重写寻找地脉花线路方法,删除模糊寻找模式。 +2. 添加直跑模式,当打完一个地脉花后,如下一个地脉花比较近,直接跑过去而不是重新传送。(要求BGI的44.8版本) + +### v.1.3版本:202500422 + +1. 优化最后领奖时检测是否误触地脉之花导致任务失败的问题。 +2. 修复模糊模式下找到地脉花但没有的情况下会继续寻找地脉花的问题。 +3. 优化模糊查找下的开始线路。 +4. 修复由于检测地脉之花页面导致的软件报错。 + +### v.1.2版本:20250414 + +1. 优化切换队伍时间,避免可能得切换队伍失败导致退出的情况。 +2. 修复线路2在快速寻找模式下识别不准确问题。 +3. 优化提前出地脉花的检测时间。 +4. 特殊处理:1、枫丹路线2秋分山西侧锚点左下第五朵花特殊处理,避免错误传送到地下螃蟹,直接跑过去。 + +### v.1.1版本:20250410 + +1. 修复自动战斗不停向前走的问题。 +2. 修复第一次战斗部不切换战斗队伍问题。 +3. 修复线路1第三朵花文件命错误。 +4. 修复队伍未填写判断为已定义问题,改为在设置过又删除队伍后判断未未定义。 +5. 修复树脂耗尽模式下,不打完整体线路问题,改为强制打完整体线路。 +6. 新增,如地脉花线路不在初始位置,快速模式是找不到的,在模糊位置可能被找到,即线路在被打过后,尝试通过无视树脂是否用完,遍历此线路查找线路剩余的地脉花,如再次找到地脉花,恢复正常判断树脂是否用完。 +7. 优化快速查找模式下的准确性。 +8. 优化模糊模式下的搜索范围,和坐标位置。 \ No newline at end of file diff --git a/repo/js/AutoFontaineLeyLine/main.js b/repo/js/AutoFontaineLeyLine/main.js index 6f7a43bc..f42a23ba 100644 --- a/repo/js/AutoFontaineLeyLine/main.js +++ b/repo/js/AutoFontaineLeyLine/main.js @@ -146,7 +146,7 @@ } var timesConfig = { value: timesValue }; - log.warn(`全自动枫丹地脉花: v3.2 - ${SHUV}.${color}.${rawTimes}`);//调试LOG + log.warn(`全自动枫丹地脉花: v3.3 - ${SHUV}.${color}.${rawTimes}`);//调试LOG log.warn(`使用树脂类型数量:${rewards.length}`); log.warn(`使用树脂顺序:${golbalRewardText.join(" ->")}`); @@ -162,8 +162,8 @@ var oneResin = "assets/model/one.png"; if (Rewards){log.warn("结束后领励练点和提交每日...");if(settings.nh === undefined || settings.nh === "") {log.warn("好感队未配置,领奖励时不切换队伍..")}} - if (SHUV == 1) {log.warn(`线路模式 : <<按次数刷取>> ${timesConfig.value/2} 次 `);}else{log.warn("线路模式 : 设定使用的树脂类型<<耗尽模式>>(最多99次)... '");timesConfig.value = 198;} - if (color == 1) {log.warn("地脉类型 : <<蓝色-经验花>>...");}else{log.warn("地脉类型 : '<<黄色-摩拉花>>...")} + if (SHUV == 1) {log.warn(`线路模式 : <<按次数刷取>> ${timesConfig.value/2} 次 `);}else{log.warn("线路模式 : 设定使用的树脂类型<<耗尽模式>>(最多99次)");timesConfig.value = 198;} + if (color == 1) {log.warn("地脉类型 : <<蓝色-经验花>>...");}else{log.warn("地脉类型 : <<黄色-摩拉花>>...")} if (settings.n === undefined || settings.n === "") { log.warn("队伍名称未配置,不更换队伍...");SHUOVER=1;} if (settings.nh === undefined || settings.nh === "") { log.warn("好感队禁用...");haoganq=0}else{var haogandui = settings.nh;haoganq=1;if(settings.n === undefined ) {throw new Error("好感队已经设置,请填战斗队伍...")}} let nowuidString = settings.nowuid ? settings.nowuid : ""; @@ -326,7 +326,7 @@ await genshin.returnMainUi(); log.info("重置地图中,打开冒险之证寻找地脉花..."); await genshin.tp(2297.60, -824.45); - await genshin.returnMainUi(); + await genshin.returnMainUi(); for(let i = 0;i<5;i++){ await sleep(700); @@ -654,8 +654,8 @@ } else{ if(i == 1){ - let SHUN01 = await Textocr("接触地脉之花",0.5,0,0,1188,358,200,400); - let SHUN02 = await Textocr("地脉之花", 0.5, 0, 0, 840,225, 230, 125); + let SHUN01 = await Textocr("接触地脉之花",0.2,0,0,1188,358,200,400); + let SHUN02 = await Textocr("地脉之花", 0.2, 0, 0, 840,225, 230, 125); if (SHUN01.found || SHUN02.found) { await keyPress("VK_ESCAPE"); await sleep(1000); @@ -676,9 +676,9 @@ await dispatcher.addTimer(new RealtimeTimer("AutoPick", { "forceInteraction": false })); await sleep(1000); await keyPress("VK_ESCAPE"); - await sleep(1000); + await sleep(500); await genshin.returnMainUi(); - await sleep(1000); + await sleep(500); return true; } } @@ -721,34 +721,49 @@ if (BUC.found) {continue;} } - let { condensedResinCount, originalResinCount, fragileResinCount } = await getRemainResinStatus(); + let { condensedResinCount, originalResinCount, fragileResinCount, momentResinCount } = await getRemainResinStatus(); + + switch (rewards[i]) { + case 1: + condensedResinCount--; + break; + case 2: + originalResinCount -= 20; + break; + case 3: + fragileResinCount--; + break; + case 4: + momentResinCount--; + break; + } let shouldExit = true; if (resinTypes.includes("1")) { - shouldExit &= (parseInt(condensedResinCount, 10) <= 1); + shouldExit &= (parseInt(condensedResinCount, 10) <= 0); } if (resinTypes.includes("2")) { - shouldExit &= (parseInt(originalResinCount, 10) < 40); + shouldExit &= (parseInt(originalResinCount, 10) < 20); } if (resinTypes.includes("3")) { - shouldExit &= (parseInt(fragileResinCount, 10) <= 1); + shouldExit &= (parseInt(fragileResinCount, 10) <= 0); } if (resinTypes.includes("4")) { - shouldExit &= (parseInt(momentResinCount, 10) <= 1); - } + shouldExit &= (parseInt(momentResinCount, 10) <= 0); + } - await click(SHU.x+550,SHU.y) - log.info(`${resinTypeMap[rewards[i]]} ...`); + log.info(`${resinTypeMap[rewards[i]]} ...`); + await click(SHU.x+550,SHU.y) if (shouldExit) { log.warn("树脂耗尽,停止执行..."); - await sleep(1000); + await sleep(1000); SHUOVER=2; return false; } @@ -773,22 +788,21 @@ var momentResinCount = 0; //须臾树脂 // 浓缩树脂 - var condensedResinCountRa = await imageRecognition(condensedResin,0.1, 0, 0,1190,0,400,80); + var condensedResinCountRa = await imageRecognition(condensedResin,0.1, 0, 0,800,20,700,55); if (condensedResinCountRa.found) { - // await moveMouseTo(condensedResinCountRa.x,condensedResinCountRa.y); - let countArea = await Textocr("",0.5, 0, 2,condensedResinCountRa.x+condensedResinCountRa.w,condensedResinCountRa.y,condensedResinCountRa.w*2-5,condensedResinCountRa.h-5);// + let countArea = await Textocr("",2, 0, 2,condensedResinCountRa.x,condensedResinCountRa.y-20,100,80);// if (countArea.found){ // log.info("浓缩树脂识别数量结果: "+ countArea.text); condensedResinCount = countArea.text } else - { - log.info("浓缩树脂识别数量结果:无"); + { + condensedResinCount = "1"; + log.info("浓缩树脂识别数量结果:1");//不知道为什么,1无法识别,0是不显示图标的,所以就当时1了,反正也没啥影响 } - - } else { + }else{ log.info("未检测到浓缩树脂图标"); - } + } var originalResinCountRa = await imageRecognition(originalResin,0.1, 0, 0,1555,0,90,80); if (originalResinCountRa.found) { @@ -796,7 +810,7 @@ let countArea = await Textocr("",0.5, 0, 2,originalResinCountRa.x+originalResinCountRa.w,originalResinCountRa.y,originalResinCountRa.w*3,originalResinCountRa.h);// if (countArea.found){ log.info("原粹树脂识别数量结果:"+ countArea.text); - let match = countArea.text.match(/(\d+)\s*[/1]\s*(2|20|200)/); + let match = countArea.text.match(/(\d+)\s*[/17]\s*(2|20|200)/); if (match) { originalResinCount = match[1]; // log.info("脆弱树脂识别数量提取:"+ originalResinCount); @@ -838,7 +852,7 @@ { var fragileResinCountRa = await imageRecognition(fragileResin,0.1, 0, 1,1170,0,300,100); if (fragileResinCountRa.found) { - // await moveMouseTo(fragileResinCountRa.x+fragileResinCountRa.w+20,fragileResinCountRa.y-15); + // await moveMouseTo(fragileResinCountRa.x+fragileResinCountRa.w+20,fragileResinCountRa.y-15); let countArea = await Textocr("",0.5, 0, 2,fragileResinCountRa.x+fragileResinCountRa.w+20,fragileResinCountRa.y-15,60,40);// if (countArea.found){ // log.info("脆弱树脂识别数量结果:"+ countArea.text); @@ -861,7 +875,12 @@ log.info("树脂状态:浓缩{0} 原粹{1} 脆弱{2} 须臾{3}", condensedResinCount, originalResinCount, fragileResinCount,momentResinCount) return {condensedResinCount,originalResinCount,fragileResinCount,momentResinCount} - } + } + + async function isOnRewardPage() { + const rewardText = await Textocr("地脉之花", 0.2, 0, 0, 840,225, 230, 125); + return rewardText.found; + } async function isOnRewardPage() { const rewardText = await Textocr("地脉之花", 0.2, 0, 0, 840,225, 230, 125); @@ -875,7 +894,7 @@ * @param timeout 超时时间,单位为毫秒,默认值为1000毫秒 * @returns 无返回值 */ - async function checkRewardPage(timeout = 2000) { + async function checkRewardPage(timeout = 1000) { if (!shouldContinueChecking) { return; // 如果不应该继续检测,则直接返回 @@ -1137,16 +1156,30 @@ } shouldContinueChecking = true; - //执行到地脉花地点的寻路脚本 - log.info(`开始执行寻找地脉花奖励:${jsonFile2}`); await dispatcher.addTimer(new RealtimeTimer("AutoPick", { forceInteraction: false})); - await pathingScript.runFile(`${selectedFolder}${jsonFile2}`); - await sleep(2000); + + //执行到地脉花地点的寻路脚本 + let pathDic = JSON.parse(file.readTextSync(`${selectedFolder}${jsonFile2}`)); + log.info(`开始执行寻找地脉花奖励:${jsonFile2}`); + + await genshin.returnMainUi(); + if(!await updatePositionWithTolerance(pathDic, 40)){ + log.info(`离领奖区域过远,通过重新传送寻路到地脉花地点:${jsonFile2}`); + await pathingScript.runFile(`${selectedFolder}${jsonFile1}`); + }else{ + //到达领奖地点 + pathDic["positions"][0]["type"] = "path";// + await pathingScript.run(JSON.stringify(pathDic)); + let SHUN01 = await Textocr("接触地脉之花",1,0,0,1188,358,200,400); + if (!SHUN01.found) await pathingScript.runFile(`${selectedFolder}${jsonFile2}`); + } + + await sleep(1000); // 领取奖励,开始找地脉口 log.info(`开始本线路第 ${executedCount/2+1} 朵花的奖励领取`); if (haoganq==1){log.info(`切换好感队伍:'${haogandui}'`);await genshin.returnMainUi(); await sleep(1000);await genshin.SwitchParty(haogandui);} shouldContinueChecking = false; - await sleep(2000); + await sleep(500); if (!(await claimRewards())) { log.warn("树脂消耗完毕,结束任务"); dispatcher.addTimer(new RealtimeTimer("AutoPick", { forceInteraction: false })); @@ -1164,6 +1197,27 @@ return true;// 线路完成 } + async function updatePositionWithTolerance(pathDic,tolerance = 40) { + await genshin.returnMainUi(); + let smallXY = await genshin.getPositionFromMap(); + const currentX = pathDic["positions"][0]["x"]; + const currentY = pathDic["positions"][0]["y"]; + let isUpdated = false; + log.info(`当前小地图坐标: X=${currentX}, Y=${currentY}`); + + if (Math.abs(currentX - smallXY.x) < tolerance) { + // pathDic["positions"][0]["x"] = smallXY.x; + isUpdated = true; + } + + if (Math.abs(currentY - smallXY.y) < tolerance) { + // pathDic["positions"][0]["y"] = smallXY.y; + isUpdated = true; + } + + return isUpdated; + } + // UID获取存在概率不成功,慎用!请更换背景纯色的名片提高OCR成功率 let uidNumbers = nowuidString.match(/\d+/g); if (nowuidString) { @@ -1184,12 +1238,11 @@ } } } - } + } try { //根据SHUOVER决定模式 - while (SHUOVER<=1){ - Fligtin = true ; //领取冒险点奖励标志。 + while (SHUOVER<=1){ if (!(await PathCheak(0))){ await leftButtonUp(); log.info("未找到地脉花,更换寻找方式,重试...") @@ -1198,8 +1251,8 @@ await leftButtonUp();await genshin.returnMainUi(); throw new Error("未找到地脉花,退出!") } - } - + } + Fligtin = true ; //领取冒险点奖励标志。 //第一次执行选择队伍 if (SHUOVER == 0){await genshin.returnMainUi(); await sleep(1000);await genshin.SwitchParty(settings.n);await sleep(500);} //开始寻找并执行地脉花自动。