F1找花优化,修复部分bug (#1711)

This commit is contained in:
ddaodan
2025-08-26 10:59:01 +08:00
committed by GitHub
parent 43eaa0b409
commit 50042c7574
6 changed files with 184 additions and 158 deletions

View File

@@ -2,6 +2,7 @@
**仅支持BetterGI 0.44.7 及以上版本!**
**仅支持Bitblt截图方式**
目前脚本仍在更新开发阶段会有很多bug详见下方已知问题如果遇到没有提到的bug请反馈给我们非常感谢
[TOC]
## 配置
使用前需要对脚本以及战斗策略进行配置
在调度器新建一个配置组,将脚本添加进来,脚本只能在配置组内使用
@@ -47,13 +48,9 @@ wgc的bug请使用bitblt截图方式脚本只支持这个
打开大地图,点击左下角设置,开启自定义标记。
脚本非正常结束运行时会出现该问题。
## 更新日志
### 4.1.4
修复取消自动任务报错
### 4.1.3
修复v8报错
### 4.1
通过冒险之证找花 - 测试
- 新增通过冒险之证寻找地脉花
- 修复部分报错
### 4.0
- 适配原神5.7版本更新
- 修复打开自定义标记的bug

View File

@@ -38,7 +38,7 @@ const ocrRoThis = RecognitionObject.ocrThis;
// 全局错误捕获,记录并发送错误日志
log.error("出错了: {error}", error.message);
if (isNotification) {
notification.error("出错了: ${error.message}");
notification.error(`出错了: ${error.message}`);
}
}
finally {

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 1,
"name": "全自动地脉花",
"version": "4.1.4",
"version": "4.1.5",
"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如果遇到问题请先参照手册中的方法进行解决。",

View File

@@ -25,8 +25,7 @@ this.findLeyLineOutcropByBook = async function (country, type) {
await sleep(1000);
click(1300, 800); //点击推荐
await sleep(1000);
let captureRegion = captureGameRegion();
let resList = captureRegion.findMulti(RecognitionObject.ocrThis);
let resList = captureGameRegion().findMulti(ocrRoThis);
for (let i = 0; i < resList.count; i++) {
let res = resList[i];
if (res.text.includes(country)) {
@@ -34,6 +33,14 @@ this.findLeyLineOutcropByBook = async function (country, type) {
}
}
await sleep(1000);
let resList2 = captureGameRegion().findMulti(ocrRoThis);
for (let i = 0; i < resList2.count; i++) {
let res = resList2[i];
if (res.text.includes("停止追踪")) {
res.click();
await sleep(1000);
}
}
click(1500, 850);
click(1500, 850); //点击追踪,连点两次防止点不到
await sleep(1000);
@@ -41,6 +48,27 @@ this.findLeyLineOutcropByBook = async function (country, type) {
const center = genshin.getPositionFromBigMap();
leyLineX = center.x;
leyLineY = center.y;
log.info(`找到地脉花的坐标:(${center.x}, ${center.y})`);
log.info(`找到地脉花的坐标:(${leyLineX}, ${leyLineY})`);
// 取消追踪
click(960, 540);
await sleep(1000);
let zhuizong = captureGameRegion().findMulti(ocrRoThis);
if (zhuizong && zhuizong.count > 0) {
for (let i = 0; i < zhuizong.count; i++) {
if (zhuizong[i].text.includes("停止追踪")) {
zhuizong[i].click();
log.debug("点击取消追踪");
await sleep(1000);
return;
} else if (zhuizong[i].text.includes("地脉") || zhuizong[i].text.includes("衍出")) {
zhuizong[i].click();
await sleep(1000);
click(1700, 1010);
log.debug("点击取消追踪");
await sleep(1000);
}
}
}
return center;
}

View File

@@ -1,74 +1,74 @@
/**
* 加载、验证、输出用户设置
* @returns {Object} 处理过的设置对象
*/
this.loadSettings =
function () {
try {
// 直接使用全局settings对象而不是重新创建
// 这样能保留原始设置内容
// 验证必要的设置
if (!settings.start) {
throw new Error("请仔细阅读脚本介绍和手册,并在调度器内进行配置,如果你是直接运行的脚本,请将脚本加入调度器内运行!");
}
if (!settings.leyLineOutcropType) {
throw new Error("请选择你要刷取的地脉花类型(经验书/摩拉)");
}
if (!settings.country) {
throw new Error("请在游戏中确认地脉花的第一个点的位置然后在js设置中选择地脉花所在的国家。");
}
if (settings.friendshipTeam && !settings.team) {
throw new Error("未配置战斗队伍!当配置了好感队时必须配置战斗队伍!");
}
// 为了向后兼容,确保某些设置有默认值
settings.timeout = settings.timeout * 1000 || 120000;
// 处理刷取次数
if (!settings.count || !/^-?\d+\.?\d*$/.test(settings.count)) {
log.warn(`刷取次数 ${settings.count} 不是数字使用默认次数6次`);
settings.timesValue = 6;
} else {
// 转换为数字
const num = parseFloat(settings.count);
// 范围检查
if (num < 1) {
settings.timesValue = 1;
log.info(`⚠️ 次数 ${num} 小于1已调整为1`);
} else {
// 处理小数
if (!Number.isInteger(num)) {
settings.timesValue = Math.floor(num);
log.info(`⚠️ 次数 ${num} 不是整数,已向下取整为 ${settings.timesValue}`);
} else {
settings.timesValue = num;
}
}
}
// 记录使用的设置
log.info(`地脉花类型:${settings.leyLineOutcropType}`);
log.info(`国家:${settings.country}`);
if (settings.friendshipTeam) {
log.info(`好感队:${settings.friendshipTeam}`);
}
log.info(`刷取次数:${settings.timesValue}`);
// 设置通知状态
isNotification = settings.isNotification;
if (isNotification) {
notification.send(`全自动地脉花开始运行,以下是本次运行的配置:\n\n地脉花类型:${settings.leyLineOutcropType}\n国家:${settings.country}\n刷取次数:${settings.timesValue}`);
}
} catch (error) {
log.error(`加载设置失败: ${error.message}`);
throw error;
}
/**
* 加载、验证、输出用户设置
* @returns {Object} 处理过的设置对象
*/
this.loadSettings =
function () {
try {
// 直接使用全局settings对象而不是重新创建
// 这样能保留原始设置内容
// 验证必要的设置
if (!settings.start) {
throw new Error("请仔细阅读脚本介绍和手册,并在调度器内进行配置,如果你是直接运行的脚本,请将脚本加入调度器内运行!");
}
if (!settings.leyLineOutcropType) {
throw new Error("请选择你要刷取的地脉花类型(经验书/摩拉)");
}
if (!settings.country) {
throw new Error("请在游戏中确认地脉花的第一个点的位置然后在js设置中选择地脉花所在的国家。");
}
if (settings.friendshipTeam && !settings.team) {
throw new Error("未配置战斗队伍!当配置了好感队时必须配置战斗队伍!");
}
// 为了向后兼容,确保某些设置有默认值
//settings.timeout = settings.timeout * 1000 || 120000;
// 处理刷取次数
if (!settings.count || !/^-?\d+\.?\d*$/.test(settings.count)) {
log.warn(`刷取次数 ${settings.count} 不是数字使用默认次数6次`);
settings.timesValue = 6;
} else {
// 转换为数字
const num = parseFloat(settings.count);
// 范围检查
if (num < 1) {
settings.timesValue = 1;
log.info(`⚠️ 次数 ${num} 小于1已调整为1`);
} else {
// 处理小数
if (!Number.isInteger(num)) {
settings.timesValue = Math.floor(num);
log.info(`⚠️ 次数 ${num} 不是整数,已向下取整为 ${settings.timesValue}`);
} else {
settings.timesValue = num;
}
}
}
// 记录使用的设置
log.info(`地脉花类型:${settings.leyLineOutcropType}`);
log.info(`国家:${settings.country}`);
if (settings.friendshipTeam) {
log.info(`好感队:${settings.friendshipTeam}`);
}
log.info(`刷取次数:${settings.timesValue}`);
// 设置通知状态
isNotification = settings.isNotification;
if (isNotification) {
notification.send(`全自动地脉花开始运行,以下是本次运行的配置:\n\n地脉花类型:${settings.leyLineOutcropType}\n国家:${settings.country}\n刷取次数:${settings.timesValue}`);
}
} catch (error) {
log.error(`加载设置失败: ${error.message}`);
throw error;
}
}

View File

@@ -1,74 +1,75 @@
/**
* 判断是否为地脉花并处理
* @param {number} timeout - 超时时间
* @param {string} targetPath - 目标路径
* @param {number} [retries=0] - 当前函数内重试次数
* @returns {Promise<void>}
*/
this.processLeyLineOutcrop =
async function (timeout, targetPath, retries = 0) {
const MAX_RETRIES = 3;
let captureRegion = null;
try {
// 检查重试次数,避免死循环
if (retries >= MAX_RETRIES) {
const errorMsg = `开启地脉花失败,已重试${MAX_RETRIES}次,终止处理`;
log.error("我辣么大一个地脉花哪去了?");
throw new Error(errorMsg);
}
// 截图并识别
captureRegion = captureGameRegion();
const result = captureRegion.find(ocrRo2);
const result2 = captureRegion.find(ocrRo3);
// 检查地脉之花状态 - 已完成状态,准备领取奖励
if (result2.text.includes("地脉之花")) {
log.info("识别到地脉之花,准备领取奖励");
await switchToFriendshipTeamIfNeeded();
return;
}
// 处理地脉溢口
if (result2.text.includes("地脉溢口")) {
log.info("识别到地脉溢口");
keyPress("F");
await sleep(300);
keyPress("F");
await sleep(500);
} else if (result.text.includes("打倒所有敌人")) {
log.info("地脉花已经打开,直接战斗");
} else {
// 未识别到目标,需要重新导航
log.warn("未识别到地脉花文本,尝试重新导航");
await pathingScript.runFile(targetPath);
return await this.processLeyLineOutcrop(timeout, targetPath, retries + 1);
}
// 执行战斗
const fightResult = await autoFight(timeout);
if (!fightResult) {
throw new Error("战斗失败");
}
// 完成后续操作
await switchToFriendshipTeamIfNeeded();
await autoNavigateToReward();
} catch (error) {
// 保留原始错误信息
const errorMsg = `地脉花处理失败 (重试${retries}/${MAX_RETRIES}): ${error.message}`;
log.error(errorMsg);
throw error;
} finally {
// 确保资源释放
if (captureRegion) {
try {
captureRegion.dispose();
} catch (disposeError) {
log.warn(`截图资源释放失败: ${disposeError.message}`);
}
}
}
}
/**
* 判断是否为地脉花并处理
* @param {number} timeout - 超时时间
* @param {string} targetPath - 目标路径
* @param {number} [retries=0] - 当前函数内重试次数
* @returns {Promise<void>}
*/
this.processLeyLineOutcrop =
async function (timeout, targetPath, retries = 0) {
const MAX_RETRIES = 3;
let captureRegion = null;
timeout = timeout * 1000;
try {
// 检查重试次数,避免死循环
if (retries >= MAX_RETRIES) {
const errorMsg = `开启地脉花失败,已重试${MAX_RETRIES}次,终止处理`;
log.error("我辣么大一个地脉花哪去了?");
throw new Error(errorMsg);
}
// 截图并识别
captureRegion = captureGameRegion();
const result = captureRegion.find(ocrRo2);
const result2 = captureRegion.find(ocrRo3);
// 检查地脉之花状态 - 已完成状态,准备领取奖励
if (result2.text.includes("地脉之花")) {
log.info("识别到地脉之花,准备领取奖励");
await switchToFriendshipTeamIfNeeded();
return;
}
// 处理地脉溢口
if (result2.text.includes("地脉溢口")) {
log.info("识别到地脉溢口");
keyPress("F");
await sleep(300);
keyPress("F");
await sleep(500);
} else if (result.text.includes("打倒所有敌人")) {
log.info("地脉花已经打开,直接战斗");
} else {
// 未识别到目标,需要重新导航
log.warn("未识别到地脉花文本,尝试重新导航");
await pathingScript.runFile(targetPath);
return await this.processLeyLineOutcrop(timeout, targetPath, retries + 1);
}
// 执行战斗
const fightResult = await autoFight(timeout);
if (!fightResult) {
throw new Error("战斗失败");
}
// 完成后续操作
await switchToFriendshipTeamIfNeeded();
await autoNavigateToReward();
} catch (error) {
// 保留原始错误信息
const errorMsg = `地脉花处理失败 (重试${retries}/${MAX_RETRIES}): ${error.message}`;
log.error(errorMsg);
throw error;
} finally {
// 确保资源释放
if (captureRegion) {
try {
captureRegion.dispose();
} catch (disposeError) {
log.warn(`截图资源释放失败: ${disposeError.message}`);
}
}
}
}