js:锄地一条龙1.3.0 (#1467)

* js:锄地一条龙1.3.0

### 1.3.0(2025.08.04)
1.增加了识图频率限制,可以通过自定义配置中触发器间隔调节
1.优化了拾取时的滚动效果

* 保留records文件夹

---------

Co-authored-by: 躁动的氨气 <131591012+zaodonganqi@users.noreply.github.com>
This commit is contained in:
mno
2025-08-04 12:51:06 +08:00
committed by GitHub
parent f3db91d934
commit 5913ed7a87
5 changed files with 90 additions and 23 deletions

View File

@@ -74,6 +74,9 @@
--- ---
### 更新日志 ### 更新日志
### 1.3.02025.08.04
1.增加了识图频率限制,可以通过自定义配置中触发器间隔调节
1.优化了拾取时的滚动效果
### 1.2.52025.07.31 ### 1.2.52025.07.31
1.运行线路前删除部分中间信息,略微减少内存占用 1.运行线路前删除部分中间信息,略微减少内存占用
2.当权重涉及指数运算过大时修正到五过小时修正到0 2.当权重涉及指数运算过大时修正到五过小时修正到0

View File

@@ -1,3 +1,25 @@
{"macroEvents":[{"type":6,"mouseX":0,"mouseY":-120,"time":0}, {
{"type":6,"mouseX":0,"mouseY":0,"time":100}], "macroEvents": [
"info":{"name":"","description":"","x":0,"y":0,"width":1920,"height":1080,"recordDpi":1}} {
"type": 6,
"mouseX": 0,
"mouseY": -120,
"time": 0
},
{
"type": 6,
"mouseX": 0,
"mouseY": 0,
"time": 25
}
],
"info": {
"name": "",
"description": "",
"x": 0,
"y": 0,
"width": 1920,
"height": 1080,
"recordDpi": 1
}
}

View File

@@ -1,12 +1,13 @@
//拾取时上下滑动的时间 //拾取时上下滑动的时间
const timeMoveUp = 500; const timeMoveUp = 1000;
const timeMoveDown = 1000; const timeMoveDown = 1500;
const pickupMode = settings.pickupMode || "js拾取默认只拾取狗粮和晶蝶"; const pickupMode = settings.pickupMode || "js拾取默认只拾取狗粮和晶蝶";
if (settings.activeDumperMode) { //处理泥头车信息 if (settings.activeDumperMode) { //处理泥头车信息
dumpers = settings.activeDumperMode.split('').map(Number).filter(num => num === 1 || num === 2 || num === 3 || num === 4); dumpers = settings.activeDumperMode.split('').map(Number).filter(num => num === 1 || num === 2 || num === 3 || num === 4);
} else { } else {
dumpers = []; dumpers = [];
} }
const trigger = settings.trigger || 50;
(async function () { (async function () {
//自定义配置处理 //自定义配置处理
@@ -494,12 +495,20 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
const maxAttempts = 2; const maxAttempts = 2;
let attempts = 0; let attempts = 0;
let lastOcrTime = new Date();
while (attempts < maxAttempts && !state.cancelRequested) { while (attempts < maxAttempts && !state.cancelRequested) {
const ocrTime = new Date();
if (ocrTime - lastOcrTime < trigger) {
//限制识别频率
await sleep(trigger - (ocrTime - lastOcrTime));
}
lastOcrTime = ocrTime;
try { try {
let template = file.ReadImageMatSync(imagePath); let template = file.ReadImageMatSync(imagePath);
let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height);
let result = captureGameRegion().find(recognitionObject); resultMainUi = captureGameRegion().find(recognitionObject);
if (result.isExist()) { //captureGameRegion().dispose;
if (resultMainUi.isExist()) {
return true; // 如果找到图标,返回 true return true; // 如果找到图标,返回 true
} }
} catch (error) { } catch (error) {
@@ -533,11 +542,20 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
// 定义一个函数用于执行OCR识别和交互 // 定义一个函数用于执行OCR识别和交互
async function performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance) { async function performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance) {
async function performOcr(whitelistKeywords, xRange, yRange, timeout = 200) { async function performOcr(whitelistKeywords, xRange, yRange, timeout = 200) {
let lastOcrTime = new Date();
let startTime = Date.now(); let startTime = Date.now();
while (Date.now() - startTime < timeout) { while (Date.now() - startTime < timeout && !state.cancelRequested) {
const ocrTime = new Date();
//log.info(`当前触发间隔为${ocrTime - lastOcrTime}`);
if (ocrTime - lastOcrTime < trigger) {
//限制识别频率
await sleep(trigger - (ocrTime - lastOcrTime));
}
lastOcrTime = ocrTime;
try { try {
// 在捕获的区域内进行OCR识别 // 在捕获的区域内进行OCR识别
let ra = captureGameRegion(); ra = captureGameRegion();
//captureGameRegion().dispose;
let resList = ra.findMulti(RecognitionObject.ocr( let resList = ra.findMulti(RecognitionObject.ocr(
xRange.min, yRange.min, xRange.min, yRange.min,
xRange.max - xRange.min, yRange.max - yRange.min xRange.max - xRange.min, yRange.max - yRange.min
@@ -571,18 +589,33 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
log.warn("OCR识别超时"); log.warn("OCR识别超时");
return []; return [];
} }
await sleep(5000);//启动地图追踪前五秒不执行ocr
let lastOcrTime = new Date();
while (!state.completed && !state.cancelRequested) { while (!state.completed && !state.cancelRequested) {
const ocrTime = new Date();
if (ocrTime - lastOcrTime < trigger) {
//限制识别频率
await sleep(trigger - (ocrTime - lastOcrTime));
}
// 尝试找到 F 图标并返回其坐标 // 尝试找到 F 图标并返回其坐标
async function findFIcon(imagePath, xMin, yMin, width, height, timeout = 500) { async function findFIcon(imagePath, xMin, yMin, width, height, timeout = 500) {
let lastOcrTime = new Date();
let startTime = Date.now(); let startTime = Date.now();
while (Date.now() - startTime < timeout && !state.cancelRequested) { while (Date.now() - startTime < timeout && !state.cancelRequested) {
const ocrTime = new Date();
//log.info(`当前触发间隔为${ocrTime - lastOcrTime}`);
if (ocrTime - lastOcrTime < trigger) {
//限制识别频率
await sleep(trigger - (ocrTime - lastOcrTime));
}
lastOcrTime = ocrTime;
try { try {
let template = file.ReadImageMatSync(imagePath); let template = file.ReadImageMatSync(imagePath);
let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height); let recognitionObject = RecognitionObject.TemplateMatch(template, xMin, yMin, width, height);
let result = captureGameRegion().find(recognitionObject); resultFIcon = captureGameRegion().find(recognitionObject);
if (result.isExist()) { //captureGameRegion().dispose;
return { success: true, x: result.x, y: result.y, width: result.width, height: result.height }; if (resultFIcon.isExist()) {
return { success: true, x: resultFIcon.x, y: resultFIcon.y, width: resultFIcon.width, height: resultFIcon.height };
} }
} catch (error) { } catch (error) {
log.error(`识别图像时发生异常: ${error.message}`); log.error(`识别图像时发生异常: ${error.message}`);
@@ -591,7 +624,6 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
} }
return null; return null;
} }
await sleep(2); // 每次检测间隔 2 毫秒
} }
if (state.cancelRequested) { if (state.cancelRequested) {
log.info("图像识别任务已取消"); log.info("图像识别任务已取消");
@@ -600,14 +632,15 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
} }
// 尝试找到 F 图标 // 尝试找到 F 图标
let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 200); let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 500);
if (!fRes) { if (!fRes) {
state.atMainUi = await isMainUI(); state.atMainUi = await isMainUI();
state.lastCheckMainUi = new Date(); state.lastCheckMainUi = new Date();
if (state.atMainUi) { if (state.atMainUi) {
//log.info("在主界面,尝试下滑"); //log.info("在主界面,尝试下滑");
await keyMouseScript.runFile(`assets/滚轮下翻.json`); keyMouseScript.runFile(`assets/滚轮下翻.json`);
} }
await sleep(trigger);
continue; continue;
} }
@@ -636,7 +669,7 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
let centerYTargetText = ocrResult.y + ocrResult.height / 2; let centerYTargetText = ocrResult.y + ocrResult.height / 2;
if (Math.abs(centerYTargetText - centerYF) <= texttolerance) { if (Math.abs(centerYTargetText - centerYF) <= texttolerance) {
keyPress("F"); // 执行交互操作 keyPress("F"); // 执行交互操作
await sleep(5); // 操作后暂停 5 毫秒 await sleep(trigger);
foundTarget = true; foundTarget = true;
break; break;
} }
@@ -648,7 +681,7 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
// 如果距离上次下翻超过timeMoveUp秒则执行下翻 // 如果距离上次下翻超过timeMoveUp秒则执行下翻
if (currentTime - lastMoveDown > timeMoveUp) { if (currentTime - lastMoveDown > timeMoveUp) {
await keyMouseScript.runFile(`assets/滚轮下翻.json`); keyMouseScript.runFile(`assets/滚轮下翻.json`);
// 如果这是第一次下翻,记录这次下翻的时间 // 如果这是第一次下翻,记录这次下翻的时间
if (thisMoveUpTime === 0) { if (thisMoveUpTime === 0) {
@@ -662,7 +695,7 @@ async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywo
} }
} else { } else {
// 否则执行下翻 // 否则执行下翻
await keyMouseScript.runFile(`assets/滚轮上翻.json`); keyMouseScript.runFile(`assets/滚轮上翻.json`);
} }
} }

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"name": "锄地一条龙", "name": "锄地一条龙",
"version": "1.2.5", "version": "1.3.0",
"description": "一站式解决自动化锄地支持只拾取狗粮请仔细阅读README.md后使用", "description": "一站式解决自动化锄地支持只拾取狗粮请仔细阅读README.md后使用",
"authors": [ "authors": [
{ {
@@ -10,5 +10,8 @@
} }
], ],
"settings_ui": "settings.json", "settings_ui": "settings.json",
"main": "main.js" "main": "main.js",
} "saved_files": [
"records/"
]
}

View File

@@ -38,10 +38,16 @@
], ],
"default": "js拾取默认只拾取狗粮和晶蝶" "default": "js拾取默认只拾取狗粮和晶蝶"
}, },
{
"name": "trigger",
"type": "input-text",
"label": "触发器间隔(毫秒)只对js拾取生效\n越长占用性能越低拾取越慢只建议性能不足时调高至不超过200",
"default": "50"
},
{ {
"name": "activeDumperMode", "name": "activeDumperMode",
"type": "input-text", "type": "input-text",
"label": "泥头车模式,将在接近战斗点前提前释放部分角色e技能\n需要启用时填写这些角色在队伍中的编号\n有多个角色需要释放时用中文逗号分隔\n警告实验性功能可能增加性能开销和降低稳定性" "label": "泥头车模式,将在接近战斗点前提前释放部分角色e技能\n需要启用时填写这些角色在队伍中的编号\n有多个角色需要释放时用中文逗号分隔"
}, },
{ {
"name": "runByEfficiency", "name": "runByEfficiency",