v.3.3版全自动枫丹地脉花 20250716 (#1353)

- **优化**:
1. 优化战斗完成后寻找地脉花逻辑,提高开花领奖正确率。
2. 优化结束战斗异常和领奖异常的处理。
3. 修复无法使用须臾树脂的问题。
This commit is contained in:
kaedelcb
2025-07-16 09:56:59 +08:00
committed by GitHub
parent 15c8792a07
commit f5b7bd9040
2 changed files with 184 additions and 125 deletions

View File

@@ -2,15 +2,11 @@
## 零、前言
测试中注意事项不完善请谅解如有BUGQQ119996800,随时欢迎反馈
后续优化代码和使用说明,先测试看如何!
感谢平面镜和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. 优化领奖速度。
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. 优化模糊模式下的搜索范围,和坐标位置。

View File

@@ -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);}
//开始寻找并执行地脉花自动。