### v.1.3版本自动幽境危战(20250628) (#1222)

* ### v.1.3版本自动幽境危战(20250628)

- **新增功能**:
  1. 添加`自动重试`,战斗失败或执行错误会`重试一次`。
- **优化**:
  2. 优化退出点击时序和逻辑。
  3. 优化进入秘境后向前走的逻辑。
  4. 优化LOG输出显示内容。
- **修复**
  1. 修复默认状态下,选择长夜套的BUG。

* ### v.1.3版本自动幽境危战(20250628)

### v.1.3版本自动幽境危战(20250628)
- **新增功能**:
  1. 添加`自动重试`,战斗失败或执行错误会`重试一次`。
- **优化**:
  2. 优化退出点击时序和逻辑。
  3. 优化进入秘境后向前走的逻辑。
  4. 优化LOG输出显示内容。
- **修复**
  1. 修复默认状态下,选择长夜套的BUG。
This commit is contained in:
kaedelcb
2025-06-28 16:00:58 +08:00
committed by GitHub
parent 6cf84a6ced
commit 0a99e73bc6
4 changed files with 89 additions and 78 deletions

View File

@@ -1,4 +1,4 @@
# 幽境危战注意事项 # 自动幽境危战注意事项
## 零、前言 ## 零、前言
@@ -12,9 +12,9 @@
1. **使用前准备** 1. **使用前准备**
- 请在`<<幽境危战>>`中配置好战斗队伍。 - 请在`<<幽境危战>>`中配置好战斗队伍。
2. **黑名单建议** 2. **黑名单建议**
- 根目录下有建议加入自动拾取黑名单的名称,请检查并添加。 - 根目录下有文件内含建议加入`自动拾取黑名单`的名称,请检查并添加。
3. **战斗实力** 3. **战斗实力**
- 请确保队伍具备足够的战斗实力,当前版本在战斗失败时会自动退出秘境 - 请确保队伍具备足够的战斗实力,当前版本在战斗失败或执行错误,只会重试`一次`
4. **自动拾取功能** 4. **自动拾取功能**
- 为避免不必要的干扰,建议关闭自动拾取功能。 - 为避免不必要的干扰,建议关闭自动拾取功能。
@@ -24,10 +24,10 @@
- 默认设置下,脚本不会修改圣遗物奖励。 - 默认设置下,脚本不会修改圣遗物奖励。
2. **Boss挑战关卡选择** 2. **Boss挑战关卡选择**
- 必填项请从上往下选择第几个Boss挑战关卡1至3否则脚本将退出执行。 - 必填项请从上往下选择第几个Boss挑战关卡`1至3`,否则脚本将无法执行。
3. **挑战次数** 3. **挑战次数**
- 默认设置为15次,期间若树脂耗尽,脚本将自动结束。 - 默认设置为`15`次,期间若树脂耗尽,脚本将自动结束。
4. **树脂顺序设定** 4. **树脂顺序设定**
- 使用`/`隔开数字来设定树脂使用顺序,如`1/2`表示先使用浓缩树脂,再使用原粹树脂。 - 使用`/`隔开数字来设定树脂使用顺序,如`1/2`表示先使用浓缩树脂,再使用原粹树脂。
@@ -36,13 +36,13 @@
- 2 = 原粹树脂 - 2 = 原粹树脂
- 3 = 脆弱树脂 - 3 = 脆弱树脂
- 4 = 须臾树脂 - 4 = 须臾树脂
- 默认设置:`1/2` - 默认设置:`1/2`,表示先使用浓缩树脂,再使用原粹树脂,不填的不使用"。
5. **最长战斗超时时间** 5. **最长战斗超时时间**
- 默认设置为240秒一般情况下无需修改。 - 默认设置为`240`秒,一般情况下无需修改。
6. **开始战斗后的移动时间** 6. **开始战斗后的移动时间**
- 默认设置为1秒(注意单位为秒)。由于开始位置离Boss较远请根据实际情况设定一般情况下默认设置即可。 - 默认设置为`1`秒(注意单位为`秒`),由于战斗开始位置离Boss较远请根据实际情况设定一般情况下默认设置即可。
## 三、更新说明 ## 三、更新说明
@@ -57,10 +57,19 @@
### v.1.2版本20250627 ### v.1.2版本20250627
- **新增功能** - **新增功能**
1. 添加圣遗物奖励选择功能。 1. 添加圣遗物`奖励选择`功能。
2. 添加自动选择难度功能。 2. 添加自动选择`难度`功能。
- **优化** - **优化**
1. 优化逻辑处理。 1. 优化逻辑处理。
2. 加大战斗完成识别区域。 2. 加大战斗完成识别区域。
请将以上内容保存为`README.md`文件以便在GitHub或其他支持Markdown的平台上正确显示和使用。 ### v.1.3版本20250628
- **新增功能**
1. 添加`自动重试`,战斗失败或执行错误会`重试一次`
- **优化**
2. 优化退出点击时序和逻辑。
3. 优化进入秘境后向前走的逻辑。
4. 优化LOG输出显示内容。
- **修复**
1. 修复默认状态下选择长夜套的BUG。

View File

@@ -8,8 +8,10 @@
var Fighttimeout = settings.timeout * 1000 ? settings.timeout * 1000 : 240000;//战斗超时时间默认为240秒 var Fighttimeout = settings.timeout * 1000 ? settings.timeout * 1000 : 240000;//战斗超时时间默认为240秒
const ocrRegion1 = { x: 643, y: 58, width: 800, height: 800 }; // 上方挑战成功区域 const ocrRegion1 = { x: 643, y: 58, width: 800, height: 800 }; // 上方挑战成功区域
const ocrRegion2 = { x: 780, y: 406, width: 370, height: 135 }; // 中间挑战失败区域 const ocrRegion2 = { x: 780, y: 406, width: 370, height: 135 }; // 中间挑战失败区域
// const ocrRegion3 = { x: 1782, y: 1023, width: 64, height: 29 }; // 右下角space区域
const ocrRo1 = RecognitionObject.ocr(ocrRegion1.x, ocrRegion1.y, ocrRegion1.width, ocrRegion1.height); const ocrRo1 = RecognitionObject.ocr(ocrRegion1.x, ocrRegion1.y, ocrRegion1.width, ocrRegion1.height);
const ocrRo2 = RecognitionObject.ocr(ocrRegion2.x, ocrRegion2.y, ocrRegion2.width, ocrRegion2.height); const ocrRo2 = RecognitionObject.ocr(ocrRegion2.x, ocrRegion2.y, ocrRegion2.width, ocrRegion2.height);
// const ocrRo3 = RecognitionObject.ocr(ocrRegion3.x, ocrRegion3.y, ocrRegion3.width, ocrRegion3.height);
var Rewardsuse = settings.Rewardsuse ? settings.Rewardsuse : "1/2"; var Rewardsuse = settings.Rewardsuse ? settings.Rewardsuse : "1/2";
var resinTypes = Rewardsuse.split("/"); var resinTypes = Rewardsuse.split("/");
var rewards = []; var rewards = [];
@@ -35,7 +37,7 @@
var advanceNum = 0;//前进次数 var advanceNum = 0;//前进次数
var verticalNum = 0; var verticalNum = 0;
var Artifacts = settings.Artifacts ? settings.Artifacts : "长夜之誓 / 深廊终曲"; var Artifacts = settings.Artifacts ? settings.Artifacts : "保持圣遗物奖励不变";
//建立一个数值映射所有圣遗物对应需要识别的图片 //建立一个数值映射所有圣遗物对应需要识别的图片
var artifactImageMap = { var artifactImageMap = {
@@ -94,11 +96,11 @@
captureRegion = captureGameRegion(); // 获取一张截图 captureRegion = captureGameRegion(); // 获取一张截图
res = captureRegion.DeriveCrop(xa, ya, wa, ha).Find(Imagidentify); res = captureRegion.DeriveCrop(xa, ya, wa, ha).Find(Imagidentify);
if (res.isEmpty()) { if (res.isEmpty()) {
if (debugmodel===1 & xa===0 & ya===0){log.info("识别页面元素")}; if (debugmodel===1 & xa===0 & ya===0){log.info("识别页面元素")};
} else { } else {
if (afterBehavior===1){if (xa===0 & ya===0){log.info("点击模式:开");}await sleep(1000);click(res.x+xa, res.y+ya);}else{if (debugmodel===1 & xa===0 & ya===0){log.info("点击模式:关")}} if (afterBehavior===1){if (xa===0 & ya===0){log.info("点击模式:开");}await sleep(1000);click(res.x+xa, res.y+ya);}else{if (debugmodel===1 & xa===0 & ya===0){log.info("点击模式:关")}}
if (afterBehavior===2){if (xa===0 & ya===0){log.info("F模式:开");}await sleep(1000);keyPress("F");}else{if (debugmodel===1 & xa===0 & ya===0){log.info("F模式:关")}} if (afterBehavior===2){if (xa===0 & ya===0){log.info("F模式:开");}await sleep(1000);keyPress("F");}else{if (debugmodel===1 & xa===0 & ya===0){log.info("F模式:关")}}
if (debugmodel===1 & xa===0 & ya===0){log.info("全图代码位置:({x},{y},{h},{w})", res.x+xa, res.y+ya, res.width+wa, res.Height+ha);}else{ log.info("识别到图片");} if (debugmodel===1 & xa===0 & ya===0){log.info("全图代码位置:({x},{y},{h},{w})", res.x+xa, res.y+ya, res.width+wa, res.Height+ha);}else{ log.info("识别到页面元素");}
return result = { x: res.x+xa, y: res.y+ya, w:res.width+wa,h:res.Height+ha,found: true } return result = { x: res.x+xa, y: res.y+ya, w:res.width+wa,h:res.Height+ha,found: true }
} }
const NowTime = new Date(); const NowTime = new Date();
@@ -233,7 +235,7 @@
try { try {
let startTime = Date.now(); let startTime = Date.now();
const successKeywords = ["挑战完成","战斗完成"]; const successKeywords = ["挑战完成","战斗完成"];
const failureKeywords = ["战斗失败"]; const failureKeywords = ["战斗失败","挑战失败"];
// 循环检测直到超时 // 循环检测直到超时
while (Date.now() - startTime < timeout) { while (Date.now() - startTime < timeout) {
@@ -278,8 +280,6 @@
}); });
} }
// 领取奖励更换 // 领取奖励更换
async function selectionHolyRelics() { async function selectionHolyRelics() {
@@ -373,14 +373,14 @@
await click(SHU.x+550,SHU.y) await click(SHU.x+550,SHU.y)
await sleep(300); await sleep(300);
log.info(` ${resinTypeMap[rewards[i]]} 获取奖励...`); log.info(` ${resinTypeMap[rewards[i]]} 获取奖励...`);
dispatcher.addTimer(new RealtimeTimer("AutoPick", { forceInteraction: true })); // dispatcher.addTimer(new RealtimeTimer("AutoPick", { forceInteraction: true }));
dispatcher.addTimer(new RealtimeTimer("AutoPick", { "forceInteraction": false })); dispatcher.addTimer(new RealtimeTimer("AutoPick", { "forceInteraction": false }));
return true; return true;
} }
} }
await sleep(500); await sleep(500);
} }
log.warn("未找到树脂,结束地脉花..."); log.warn("未找到树脂,结束领取奖励...");
dispatcher.addTimer(new RealtimeTimer("AutoPick", { "forceInteraction": false })); dispatcher.addTimer(new RealtimeTimer("AutoPick", { "forceInteraction": false }));
await sleep(1000); await sleep(1000);
await keyPress("VK_ESCAPE"); //退出待写 await keyPress("VK_ESCAPE"); //退出待写
@@ -420,18 +420,21 @@
var resinAgain = false; var resinAgain = false;
log.warn("根目录下有建议加的黑名单的名称,建议加入自动拾取黑名单..."); log.warn("根目录下有建议加的黑名单的名称,建议加入自动拾取黑名单...");
log.warn("请保证队伍战斗实力,目前战斗失败会自动退出秘境..."); log.warn("请保证队伍战斗实力,战斗失败或执行错误,会重试一次...");
log.warn("使用前请在 <<幽境危战>> 中配置好战斗队伍..."); log.warn("使用前请在 <<幽境危战>> 中配置好战斗队伍...");
log.warn("最好关闭自动拾取功能..."); log.warn("最好关闭自动拾取功能...");
log.info(`圣遗物奖励选择:'${Artifacts}'`); log.info(`圣遗物奖励选择:'${Artifacts}'`);
// for (let j = 0;j < 2;j++) { //重试两次
for (let j = 0;j < 2;j++) {
await genshin.returnMainUi(); resinAgain = false; //重试标志
await pathingScript.runFile(`assets/全自动幽境危战.json`);
await VeinEntrance();
try{ try{
await genshin.returnMainUi();
await pathingScript.runFile(`assets/全自动幽境危战.json`);
await VeinEntrance();
// 进入-选择难道 // 进入-选择难道
let intoAction = await Textocr("单人挑战",10,0,0,1554,970,360, 105); let intoAction = await Textocr("单人挑战",10,0,0,1554,970,360, 105);
if (!intoAction.found) {await genshin.returnMainUi();throw new Error("未进入挑战页面,停止执行...")} if (!intoAction.found) {await genshin.returnMainUi();throw new Error("未进入挑战页面,停止执行...")}
@@ -451,12 +454,11 @@
} }
//圣遗物奖励选择 //圣遗物奖励选择
if (Artifacts != "保持圣遗物奖励不变"){ if (Artifacts != "保持圣遗物奖励不变"){
let artifact = await imageRecognition(artifactImageMap[Artifacts],0.2,0,0,186,972,71,71); let artifact = await imageRecognition(artifactImageMap[Artifacts],0.2,0,0,186,972,71,71);
if (!artifact.found) { if (!artifact.found) {
log.warn("圣遗物奖励和设定不一致,尝试切换...") log.warn("圣遗物奖励和设定不一致,尝试切换...")
if (!await selectionHolyRelics()) {throw new Error("圣遗物奖励设置错误,停止执行...")} if (!await selectionHolyRelics()){throw new Error("圣遗物奖励设置错误,停止执行...")}
} }
else else
{ {
@@ -523,44 +525,43 @@
await sleep(1000); await sleep(1000);
await keyPress("VK_ESCAPE"); await keyPress("VK_ESCAPE");
await sleep(1000); await sleep(1000);
resinAgain = true;//待开发重试
let exitChallenge = await Textocr("退出挑战",2,1,0,866,719,274,86); let exitChallenge = await Textocr("退出挑战",2,1,0,866,719,274,86);
return false; await sleep(1000);
throw new Error("战斗失败,停止执行...");
} }
} catch (error) { } catch (error) {
log.info(`挑战失败,再来一次`); resinAgain = true;
if(!await autoFight(Fighttimeout)){ if (j==0)log.info(`挑战失败,再来一次...`);
log.warn("战斗超时失败,尝试寻找地脉花入口");
}
} }
// if (resinAgain == true) if (resinAgain != true) {
await sleep(1000); await sleep(1000);
await keyPress("VK_ESCAPE");
await sleep(1000);
while((await Textocr("Enter",5,0,0,18,990,156,80).found) == false)
{
await keyPress("VK_ESCAPE"); await keyPress("VK_ESCAPE");
await sleep(1000); await sleep(1000);
}
log.info(`${i+1}次领奖`); while((await Textocr("Enter",5,0,0,18,990,156,80).found) == false)
if(!(await autoNavigateToReward())){verticalNum++;continue;}
await sleep(1000);
if (!(await claimRewards())) {
log.warn("树脂消耗完毕,结束任务");
resinexhaustion = true;
}
else
{
if (challengeNum != i+1)
{ {
let challengeAgian = await Textocr("再次挑战",10,1,0,1094,958,200,70); await keyPress("VK_ESCAPE");
await sleep(1000);
}
log.info(`${i+1}次领奖`);
if(!(await autoNavigateToReward())){verticalNum++;continue;}
await sleep(1000);
if (!(await claimRewards())) {
log.warn("树脂消耗完毕,结束任务");
resinexhaustion = true;
}
else
{
if (challengeNum != i+1)
{
let challengeAgian = await Textocr("再次挑战",10,1,0,1094,958,200,70);
}
} }
} }
@@ -572,36 +573,37 @@
await sleep(1000); await sleep(1000);
var exitTimeout = 0; var exitTimeout = 0;
while(exitTimeout < 20) while(exitTimeout < 20) {
{
let exitChallenge = await Textocr("退出挑战",0.3,0,0,866,719,274,86); let exitChallenge = await Textocr("退出挑战",0.3,0,0,866,719,274,86);
if (exitChallenge.found) { if (exitChallenge.found) {
await sleep(600); await sleep(1500);
await click(exitChallenge.x, exitChallenge.y); await click(exitChallenge.x, exitChallenge.y);
await sleep(500); await sleep(500);
break; break;
} }
let exitChallenge2 = await Textocr("退出挑战",0.3,1,0,866,719,274,86); let exitChallenge2 = await Textocr("退出挑战",0.3,1,0,866,719,274,86);
log.info("尝试退出挑战..."); log.info("尝试退出挑战...");
await sleep(1000); await sleep(1500);
await keyPress("VK_ESCAPE"); await keyPress("VK_ESCAPE");
await sleep(1000); await sleep(1000);
exitTimeout++; exitTimeout++;
} }
await genshin.returnMainUi(); await genshin.returnMainUi();
return false; if (resinAgain == true){throw new Error("执行错误,重试一次...")}
return true;
} }
await sleep(500); await sleep(500);
} }
}
}
catch (error) { catch (error) {
log.error(`执行过程中发生错误:${error.message}`); log.error(`执行过程中发生错误:${error.message}`);
resinAgain = true;
await genshin.returnMainUi();
continue;
}finally{ }finally{
await genshin.returnMainUi(); await genshin.returnMainUi();
log.info(`Auto自动幽境危战结束...`); if (resinAgain == false) log.info(`Auto自动幽境危战结束...`);
} }
// } }
})(); })();

View File

@@ -1,10 +1,10 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"name": "自动幽境危战", "name": "自动幽境危战",
"version": "1.2", "version": "1.3",
"tags": ["幽境危战"], "tags": ["幽境危战"],
"bgi_version": "0.44.8", "bgi_version": "0.44.8",
"description": "请先配置好秘境内的队伍,幽境危战战斗失败会导致卡死,请保证队伍实力,先配置好秘境内的队伍", "description": "请先配置好秘境内的队伍,幽境危战战斗失败或执行错误会重试一次,请保证队伍实力",
"authors": [ "authors": [
{ {
"name": "LCB-茶包" "name": "LCB-茶包"

View File

@@ -28,7 +28,7 @@
{ {
"name": "challengeName", "name": "challengeName",
"type": "select", "type": "select",
"label": "必填:选择第几个Boss挑战关卡", "label": "必填:从上往下1~3选择第几个Boss挑战关卡",
"options": [ "options": [
"1", "1",
"2", "2",
@@ -38,7 +38,7 @@
{ {
"name": "challengeNum", "name": "challengeNum",
"type": "input-text", "type": "input-text",
"label": "挑战次数,默认15次期间树脂耗尽会自动结束" "label": "挑战次数默认15次期间树脂耗尽会自动结束"
}, },
{ {
"name": "Rewardsuse", "name": "Rewardsuse",