mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-16 03:33:25 +08:00
全自动地脉花4.4.8 (#2640)
* fix(physical): 修复原粹树脂识别逻辑 - 注释掉定位200的调试日志 - 移除按钮2存在性检查的代码块 - 调整OCR识别区域的坐标计算逻辑 - 修改OCR识别区域的宽度和高度参数 - 优化原粹树脂数值提取,只取分数前半部分 * refactor(physical): 优化图像识别和OCR处理的资源管理 - 将region.Dispose()操作移至try-finally块中确保资源正确释放 - 修改图像匹配异常提示信息为更简洁的格式 - 调整OCR识别代码中region3的创建位置并确保在finally块中释放资源 - 通过try-catch-finally结构增强代码的健壮性,防止内存泄漏 * refactor(physical): 调整模板匹配逻辑结构 - 将 try 语句块移至模板匹配操作之后 - 确保匹配结果在异常处理前已获取 - 优化代码执行流程和错误处理机制 * feat(AutoLeyLineOutcrop): 添加manifest.json读取和日志记录功能 - 添加读取manifest.json文件并记录脚本名称和版本信息 - 添加异常处理机制记录manifest.json读取错误 * chore(release): 更新版本号到 4.4.8 - 更新 manifest.json 中的版本号从 4.4.7 到 4.4.8 * fix(physical): 修复按钮宽度计算逻辑 - 将硬编码的屏幕宽度值1920替换为动态的genshinJson.width变量 - 确保按钮宽度计算适配不同分辨率的屏幕尺寸 * fix(resin): 修复树脂数量统计功能异常处理 - 添加OCR识别失败时的ESC键退出机制 - 修复函数参数传递中的格式问题 - 优化代码格式和空行处理 - 增强异常情况下的原始模式回退逻辑
This commit is contained in:
@@ -109,6 +109,12 @@ async function initialize() {
|
||||
} catch (error) {
|
||||
throw new Error(`JS文件缺失: ${error.message}`);
|
||||
}
|
||||
try {
|
||||
let manifest = JSON.parse(file.readTextSync("manifest.json"));
|
||||
log.info(`脚本名称: {name},版本:{version}`, manifest.name, manifest.version);
|
||||
} catch (e) {
|
||||
log.warn(`error:{e}`, e.message);
|
||||
}
|
||||
// 2. 加载配置文件
|
||||
try {
|
||||
config = JSON.parse(file.readTextSync("config.json"));
|
||||
@@ -237,8 +243,8 @@ async function recheckResinAndContinue() {
|
||||
recheckCount++;
|
||||
if (physical.OpenModeCountMin) {
|
||||
physical.AlreadyRunsCount++;
|
||||
if (physical.NeedRunsCount<=physical.AlreadyRunsCount){
|
||||
log.info(`[已开启取小值]树脂耗尽模式:任务已完成,已经运行{count}次`,physical.AlreadyRunsCount);
|
||||
if (physical.NeedRunsCount <= physical.AlreadyRunsCount) {
|
||||
log.info(`[已开启取小值]树脂耗尽模式:任务已完成,已经运行{count}次`, physical.AlreadyRunsCount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "全自动地脉花",
|
||||
"version": "4.4.7",
|
||||
"version": "4.4.8",
|
||||
"tags": ["地脉花"],
|
||||
"bgi_version": "0.52.0",
|
||||
"description": "基于OCR图像识别的全自动刷取地脉花。\n💡更多信息请查看README! \n\n----------注意事项----------\n●仅支持BetterGI 0.52.0 及以上版本!\n●部分地脉花因特殊原因不支持全自动,具体的点位请在手册中查看。\n●树脂使用的优先级:2倍原粹树脂 > 浓缩树脂 > 原粹树脂。\n●运行时会传送到七天神像设置中设置的七天神像,需要关闭七天神像设置中的“是否就近七天神像恢复血量”,并指定七天神像。\n●战斗策略注意调度器设置中地图追踪行走配置里的“允许在JsSpript中使用”和“覆盖JS中的自动战斗配置”,只有在都打开的情况下脚本才会使用下面的战斗配置,否则会使用独立任务中的战斗策略。战斗超时时间不能大于脚本自定义配置中的时间。\n\n如果遇到问题,请先参照README中的方法进行解决。",
|
||||
|
||||
@@ -205,17 +205,20 @@ async function recognizeNumberByOCR(ocrRegion, pattern) {
|
||||
* 统计原粹树脂数量
|
||||
* @returns {number} 原粹树脂数量
|
||||
*/
|
||||
async function countOriginalResin(tryOriginalMode,opToMainUi,openMap) {
|
||||
async function countOriginalResin(tryOriginalMode, opToMainUi, openMap) {
|
||||
if (tryOriginalMode) {
|
||||
log.info("尝试使用原始模式");
|
||||
return await countOriginalResinBackup()
|
||||
} else {
|
||||
log.info('尝试使用优化模式');
|
||||
let ocrPhysical = await physical.ocrPhysical(opToMainUi,openMap);
|
||||
let ocrPhysical = await physical.ocrPhysical(opToMainUi, openMap);
|
||||
await sleep(600)
|
||||
// ocrPhysical = false//模拟异常
|
||||
if (ocrPhysical && ocrPhysical.ok) {
|
||||
return ocrPhysical.remainder;
|
||||
} else {
|
||||
//异常 退出至地图 尝试使用原始模式
|
||||
await keyPress("VK_ESCAPE")
|
||||
log.error(`ocrPhysical error`);
|
||||
throw new Error("ocrPhysical error");
|
||||
}
|
||||
@@ -468,7 +471,7 @@ this.countAllResin = async function () {
|
||||
let tryPass = true;
|
||||
try {
|
||||
log.info("[开始]统计补充树脂界面中的树脂");
|
||||
resinCounts.original = await countOriginalResin(false,false);
|
||||
resinCounts.original = await countOriginalResin(false, false);
|
||||
moveMouseTo(CONFIG.COORDINATES.AVOID_SELECTION.x, CONFIG.COORDINATES.AVOID_SELECTION.y)
|
||||
await sleep(500);
|
||||
resinCounts.transient = await countTransientResin();
|
||||
@@ -481,7 +484,7 @@ this.countAllResin = async function () {
|
||||
}
|
||||
await sleep(CONFIG.UI_DELAY);
|
||||
log.info("开始统计地图界面中的树脂");
|
||||
if (!tryPass){
|
||||
if (!tryPass) {
|
||||
// 如果第一次尝试失败,则切换到蒙德
|
||||
await switchtoCountrySelection(CONFIG.COORDINATES.MONDSTADT.x, CONFIG.COORDINATES.MONDSTADT.y)
|
||||
resinCounts.original = await countOriginalResin(!tryPass);
|
||||
@@ -539,23 +542,23 @@ this.calCountByResin = async function () {
|
||||
// 1. 原粹树脂:优先消耗40/次,不满40消耗20/次,不满20不消耗
|
||||
let originalResinTimes = 0;
|
||||
let remainingOriginalResin = countResult.originalResinCount;
|
||||
|
||||
|
||||
// 先计算40树脂的次数
|
||||
if (remainingOriginalResin >= 40) {
|
||||
const times40 = Math.floor(remainingOriginalResin / 40);
|
||||
originalResinTimes += times40;
|
||||
remainingOriginalResin = remainingOriginalResin - (times40 * 40);
|
||||
}
|
||||
|
||||
|
||||
// 再计算20树脂的次数
|
||||
if (remainingOriginalResin >= 20) {
|
||||
const times20 = Math.floor(remainingOriginalResin / 20);
|
||||
originalResinTimes += times20;
|
||||
remainingOriginalResin = remainingOriginalResin - (times20 * 20);
|
||||
}
|
||||
|
||||
|
||||
log.info(`原粹树脂可刷取次数: ${originalResinTimes}`);
|
||||
|
||||
|
||||
// 2. 浓缩树脂:每个计算为1次
|
||||
let condensedResinTimes = countResult.condensedResinCount;
|
||||
log.info(`浓缩树脂可刷取次数: ${condensedResinTimes}`);
|
||||
|
||||
@@ -96,16 +96,19 @@ async function ocrPhysical(opToMainUi = false,openMap=false) {
|
||||
}
|
||||
let templateMatchAddButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`${add_objJson.path}`), add_objJson.x, add_objJson.y, add_objJson.width, add_objJson.height);
|
||||
let regionA = captureGameRegion()
|
||||
// let buttonA = captureGameRegion().find(templateMatchAddButtonRo);
|
||||
let buttonA = regionA.find(templateMatchAddButtonRo);
|
||||
regionA.Dispose()
|
||||
try {
|
||||
let buttonA = regionA.find(templateMatchAddButtonRo);
|
||||
|
||||
await sleep(ms)
|
||||
if (!buttonA.isExist()) {
|
||||
log.error(`未找到${add_objJson.path}请检查路径是否正确`)
|
||||
throwError(`未找到${add_objJson.path}请检查路径是否正确`)
|
||||
await sleep(ms)
|
||||
if (!buttonA.isExist()) {
|
||||
log.error(`${add_objJson.path}匹配异常`)
|
||||
throwError(`${add_objJson.path}匹配异常`)
|
||||
}
|
||||
await buttonA.click()
|
||||
}finally {
|
||||
regionA.Dispose()
|
||||
}
|
||||
await buttonA.click()
|
||||
|
||||
// let add_obj = {
|
||||
// x: 1264,
|
||||
// y: 39,
|
||||
@@ -125,16 +128,18 @@ async function ocrPhysical(opToMainUi = false,openMap=false) {
|
||||
}
|
||||
let templateMatchButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`${tmJson.path}`), tmJson.x, tmJson.y, tmJson.width, tmJson.height);
|
||||
let region =captureGameRegion()
|
||||
// let button = captureGameRegion().find(templateMatchButtonRo);
|
||||
let button = region.find(templateMatchButtonRo);
|
||||
region.Dispose()
|
||||
await sleep(ms)
|
||||
if (!button.isExist()) {
|
||||
log.error(`${tmJson.path} 匹配异常`)
|
||||
throwError(`${tmJson.path} 匹配异常`)
|
||||
try {
|
||||
await sleep(ms)
|
||||
if (!button.isExist()) {
|
||||
log.error(`${tmJson.path} 匹配异常`)
|
||||
throwError(`${tmJson.path} 匹配异常`)
|
||||
}
|
||||
}finally {
|
||||
region.Dispose()
|
||||
}
|
||||
|
||||
log.debug(`===[定位/200]===`)
|
||||
/* log.debug(`===[定位/200]===`)
|
||||
//定位200
|
||||
let jsonPath2 = getJsonPath('200');
|
||||
let tmJson2 = {
|
||||
@@ -153,30 +158,30 @@ async function ocrPhysical(opToMainUi = false,openMap=false) {
|
||||
if (!button2.isExist()) {
|
||||
log.error(`${tmJson2.path} 匹配异常`)
|
||||
throwError(`${tmJson2.path} 匹配异常`)
|
||||
}
|
||||
}*/
|
||||
|
||||
log.debug(`===[识别原粹树脂]===`)
|
||||
//识别体力 x=1625,y=31,width=79,height=30 / x=1689,y=35,width=15,height=26
|
||||
let ocr_obj = {
|
||||
// x: 1623,
|
||||
x: button.x + button.width-20,
|
||||
x: button.x + button.width,
|
||||
// y: 32,
|
||||
y: button.y,
|
||||
// width: 61,
|
||||
width: Math.abs(button2.x - button.x - button.width+20),
|
||||
height: button2.height
|
||||
width: Math.abs(genshinJson.width - button.x - button.width),
|
||||
height: 26
|
||||
}
|
||||
|
||||
log.debug(`ocr_obj: x={x},y={y},width={width},height={height}`, ocr_obj.x, ocr_obj.y, ocr_obj.width, ocr_obj.height)
|
||||
let region3 = captureGameRegion()
|
||||
|
||||
try {
|
||||
let recognitionObjectOcr = RecognitionObject.Ocr(ocr_obj.x, ocr_obj.y, ocr_obj.width, ocr_obj.height);
|
||||
let region3 = captureGameRegion()
|
||||
let res = region3.find(recognitionObjectOcr);
|
||||
region3.Dispose()
|
||||
|
||||
log.info(`[OCR原粹树脂]识别结果: ${res.text}, 原始坐标: x=${res.x}, y=${res.y},width:${res.width},height:${res.height}`);
|
||||
let remainder = await saveOnlyNumber(res.text)
|
||||
let text=res.text.split('/')[0]
|
||||
let remainder = await saveOnlyNumber(text)
|
||||
let execute = (remainder - minPhysical) >= 0
|
||||
log.info(`最小可执行原粹树脂:{min},原粹树脂:{key}`, minPhysical, remainder,)
|
||||
|
||||
@@ -189,6 +194,7 @@ async function ocrPhysical(opToMainUi = false,openMap=false) {
|
||||
} catch (e) {
|
||||
throwError(`识别失败,err:${e.message}`)
|
||||
} finally {
|
||||
region3.Dispose()
|
||||
//返回地图操作
|
||||
if (opToMainUi) {
|
||||
await toMainUi(); // 切换到主界面
|
||||
|
||||
Reference in New Issue
Block a user