js:狗粮1.5.8,锄地1.1.9 (#1345)
This commit is contained in:
@@ -175,7 +175,7 @@ let enemyType = "无";
|
|||||||
lastRunRoute = line.substring("上次运行路线:".length).trim();
|
lastRunRoute = line.substring("上次运行路线:".length).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.startsWith("上次运行是否完成:t")) {
|
if (line.startsWith("上次运行是否完成: t")) {
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"name": "自动狗粮重制版",
|
"name": "自动狗粮重制版",
|
||||||
"version": "1.5.7",
|
"version": "1.5.8",
|
||||||
"tags": [
|
"tags": [
|
||||||
"好感",
|
"好感",
|
||||||
"盗宝团",
|
|
||||||
"愚人众",
|
|
||||||
"鳄鱼",
|
|
||||||
"兽肉",
|
|
||||||
"狗粮"
|
"狗粮"
|
||||||
],
|
],
|
||||||
"description": "通过不同好感任务卡时间后运行狗粮任务以提高狗粮总收益,需要正确配置好感队伍的战斗策略,并在自定义配置中指定好感和狗粮队伍名称",
|
"description": "通过不同好感任务卡时间后运行狗粮任务以提高狗粮总收益,需要正确配置好感队伍的战斗策略,并在自定义配置中指定好感和狗粮队伍名称",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"name": "runActivatePath",
|
"name": "runActivatePath",
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
"label": "是否启用激活路线,启用后将先花费约3分钟激活狗粮点\n启用该选项后可提高稳定性,并允许断点续跑和极大降低最短间隔时间"
|
"label": "是否启用激活路线,启用后将先花费约3分钟激活狗粮点\n启用该选项后可提高稳定性,并允许中断后重新运行和极大降低最短间隔时间"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "useABE",
|
"name": "useABE",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ if (settings.activeDumperMode) { //处理泥头车信息
|
|||||||
// 拾取黑白名单处理
|
// 拾取黑白名单处理
|
||||||
const ocrPickupContent = await file.readText("assets/拾取名单.json");
|
const ocrPickupContent = await file.readText("assets/拾取名单.json");
|
||||||
const ocrPickupJson = JSON.parse(ocrPickupContent);
|
const ocrPickupJson = JSON.parse(ocrPickupContent);
|
||||||
const targetTexts = ocrPickupJson["白名单"];
|
const whitelistKeywords = ocrPickupJson["白名单"];
|
||||||
const blacklistKeywords = ocrPickupJson["黑名单"];
|
const blacklistKeywords = ocrPickupJson["黑名单"];
|
||||||
|
|
||||||
if (!settings.accountName) {
|
if (!settings.accountName) {
|
||||||
@@ -98,7 +98,7 @@ if (settings.activeDumperMode) { //处理泥头车信息
|
|||||||
} else if (operationMode === "运行锄地路线") {
|
} else if (operationMode === "运行锄地路线") {
|
||||||
await switchPartyIfNeeded(partyName)
|
await switchPartyIfNeeded(partyName)
|
||||||
log.info("开始运行锄地路线");
|
log.info("开始运行锄地路线");
|
||||||
await processPathingsByGroup(pathings, targetTexts, blacklistKeywords, accountName);
|
await processPathingsByGroup(pathings, whitelistKeywords, blacklistKeywords, accountName);
|
||||||
} else {
|
} else {
|
||||||
log.info("强制刷新所有路线CD");
|
log.info("强制刷新所有路线CD");
|
||||||
await initializeCdTime(pathings, "");
|
await initializeCdTime(pathings, "");
|
||||||
@@ -420,13 +420,14 @@ async function assignGroups(pathings, group1Tags, group2Tags, group3Tags, group4
|
|||||||
return groupCounts;
|
return groupCounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeywords) {
|
async function runPath(pathFilePath, map_name, whitelistKeywords, blacklistKeywords) {
|
||||||
|
let lastCheckMainUi = new Date();
|
||||||
let thisMoveUpTime = 0;
|
let thisMoveUpTime = 0;
|
||||||
let lastMoveDown = 0;
|
let lastMoveDown = 0;
|
||||||
let lastPickupTime = new Date();
|
let lastPickupTime = new Date();
|
||||||
let lastPickupItem = "";
|
let lastPickupItem = "";
|
||||||
// 定义状态变量
|
// 定义状态变量
|
||||||
let state = { completed: false, cancelRequested: false };
|
let state = { completed: false, cancelRequested: false, atMainUi: false };
|
||||||
// 定义图像路径和目标文本列表
|
// 定义图像路径和目标文本列表
|
||||||
const imagePath = `assets/F_Dialogue.png`;
|
const imagePath = `assets/F_Dialogue.png`;
|
||||||
const textxRange = { min: 1210, max: 1412 };
|
const textxRange = { min: 1210, max: 1412 };
|
||||||
@@ -444,8 +445,8 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 定义一个函数用于执行OCR识别和交互
|
// 定义一个函数用于执行OCR识别和交互
|
||||||
async function performOcrAndInteract(imagePath, targetTexts, textxRange, texttolerance) {
|
async function performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance) {
|
||||||
async function performOcr(targetTexts, xRange, yRange, timeout = 200) {
|
async function performOcr(whitelistKeywords, xRange, yRange, timeout = 200) {
|
||||||
let startTime = Date.now();
|
let startTime = Date.now();
|
||||||
while (Date.now() - startTime < timeout) {
|
while (Date.now() - startTime < timeout) {
|
||||||
try {
|
try {
|
||||||
@@ -462,12 +463,12 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
let res = resList[i];
|
let res = resList[i];
|
||||||
let correctedText = res.text;
|
let correctedText = res.text;
|
||||||
|
|
||||||
// 如果 targetTexts 为空,则直接将所有文本视为匹配
|
// 如果 whitelistKeywords 为空,则直接将所有文本视为匹配
|
||||||
if (targetTexts.length === 0) {
|
if (whitelistKeywords.length === 0) {
|
||||||
results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height });
|
results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height });
|
||||||
} else {
|
} else {
|
||||||
// 否则,检查是否包含目标文本
|
// 否则,检查是否包含目标文本
|
||||||
for (let targetText of targetTexts) {
|
for (let targetText of whitelistKeywords) {
|
||||||
if (correctedText.includes(targetText)) {
|
if (correctedText.includes(targetText)) {
|
||||||
results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height });
|
results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height });
|
||||||
break; // 匹配到一个目标文本后即可跳出循环
|
break; // 匹配到一个目标文本后即可跳出循环
|
||||||
@@ -552,11 +553,13 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
|
|
||||||
// 尝试找到 F 图标
|
// 尝试找到 F 图标
|
||||||
let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 200);
|
let fRes = await findFIcon(imagePath, 1102, 335, 34, 400, 200);
|
||||||
if (!fRes) {
|
if (!fRes || new Date() - lastCheckMainUi > 2011) {
|
||||||
if (await isMainUI()) {
|
state.atMainUi = await isMainUI();
|
||||||
//log.info("在主界面,尝试下滑");
|
lastCheckMainUi = new Date();
|
||||||
await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
}
|
||||||
}
|
if (!fRes && state.atMainUi) {
|
||||||
|
//log.info("在主界面,尝试下滑");
|
||||||
|
await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +567,7 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
let centerYF = fRes.y + fRes.height / 2;
|
let centerYF = fRes.y + fRes.height / 2;
|
||||||
|
|
||||||
// 在当前屏幕范围内进行 OCR 识别
|
// 在当前屏幕范围内进行 OCR 识别
|
||||||
let ocrResults = await performOcr(targetTexts, textxRange, { min: fRes.y - texttolerance, max: fRes.y + fRes.height + texttolerance * 2 }, 200);
|
let ocrResults = await performOcr(whitelistKeywords, textxRange, { min: fRes.y - texttolerance, max: fRes.y + fRes.height + texttolerance * 2 }, 200);
|
||||||
|
|
||||||
// 检查所有目标文本是否在当前页面中
|
// 检查所有目标文本是否在当前页面中
|
||||||
let foundTarget = false;
|
let foundTarget = false;
|
||||||
@@ -651,62 +654,64 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!hasT) {
|
||||||
|
while (!state.completed && !state.cancelRequested) {
|
||||||
|
await sleep(2011);
|
||||||
|
if (state.atMainUi) {
|
||||||
|
//在主界面才尝试获取坐标
|
||||||
|
let dumperDistance = 0;
|
||||||
|
try {
|
||||||
|
let shouldPressKeys = false;
|
||||||
|
const currentPosition = await genshin.getPositionFromMap(map_name);
|
||||||
|
|
||||||
while (!state.completed && !state.cancelRequested) {
|
for (let i = 0; i < fightPositions.length; i++) {
|
||||||
if (hasT) {
|
const fightPos = fightPositions[i];
|
||||||
log.warn("当前路线含有按键T,暂时禁用泥头车")
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
await sleep(1011);
|
|
||||||
let dumperDistance = 0;
|
|
||||||
try {
|
|
||||||
let shouldPressKeys = false;
|
|
||||||
const currentPosition = await genshin.getPositionFromMap(map_name);
|
|
||||||
|
|
||||||
for (let i = 0; i < fightPositions.length; i++) {
|
if (fightPos.used) {
|
||||||
const fightPos = fightPositions[i];
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (fightPos.used) {
|
const distance = Math.sqrt(
|
||||||
continue;
|
Math.pow(currentPosition.x - fightPos.x, 2) +
|
||||||
}
|
Math.pow(currentPosition.y - fightPos.y, 2)
|
||||||
|
);
|
||||||
|
|
||||||
const distance = Math.sqrt(
|
if (distance <= 30) {
|
||||||
Math.pow(currentPosition.x - fightPos.x, 2) +
|
fightPositions[i].used = true;
|
||||||
Math.pow(currentPosition.y - fightPos.y, 2)
|
}
|
||||||
);
|
|
||||||
|
|
||||||
if (distance <= 30) {
|
if (distance > 5 && distance <= 30) {
|
||||||
fightPositions[i].used = true;
|
if ((new Date() - lastDumperTimer) > dumperCD) {
|
||||||
}
|
shouldPressKeys = true;
|
||||||
|
lastDumperTimer = new Date();
|
||||||
if (distance > 5 && distance <= 30) {
|
dumperDistance = distance;
|
||||||
if ((new Date() - lastDumperTimer) > dumperCD) {
|
}
|
||||||
shouldPressKeys = true;
|
}
|
||||||
lastDumperTimer = new Date();
|
|
||||||
dumperDistance = distance;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldPressKeys) {
|
if (shouldPressKeys) {
|
||||||
log.info(`距离下个战斗地点距离${dumperDistance.toFixed(2)},启用泥头车`);
|
log.info(`距离下个战斗地点距离${dumperDistance.toFixed(2)},启用泥头车`);
|
||||||
for (const key of dumpers) {
|
for (const key of dumpers) {
|
||||||
log.info(`[泥头车]:尝试切换${key}号角色施放e技能`)
|
log.info(`[泥头车]:尝试切换${key}号角色施放e技能`)
|
||||||
keyPress(String(key));
|
keyPress(String(key));
|
||||||
await sleep(400);
|
await sleep(400);
|
||||||
keyPress('e');
|
keyPress('e');
|
||||||
await sleep(400);
|
await sleep(400);
|
||||||
keyPress('e');
|
keyPress('e');
|
||||||
await sleep(400);
|
await sleep(400);
|
||||||
keyPress('e');
|
keyPress('e');
|
||||||
await sleep(400);
|
await sleep(400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
if (state.cancelRequested) {
|
||||||
}
|
break;
|
||||||
if (state.cancelRequested) {
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.info("当前路线含有按键T,不启用泥头车");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(`执行泥头车时出现异常: ${error.message}`);
|
log.error(`执行泥头车时出现异常: ${error.message}`);
|
||||||
@@ -719,7 +724,7 @@ async function runPathWithOcr(pathFilePath, map_name, targetTexts, blacklistKeyw
|
|||||||
// 根据条件决定是否启动 OCR 检测和交互任务
|
// 根据条件决定是否启动 OCR 检测和交互任务
|
||||||
let ocrTask = null;
|
let ocrTask = null;
|
||||||
if (pickupMode === "js拾取,默认只拾取狗粮和晶蝶") {
|
if (pickupMode === "js拾取,默认只拾取狗粮和晶蝶") {
|
||||||
ocrTask = performOcrAndInteract(imagePath, targetTexts, textxRange, texttolerance);
|
ocrTask = performOcrAndInteract(imagePath, whitelistKeywords, textxRange, texttolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动泥头车
|
// 启动泥头车
|
||||||
@@ -811,7 +816,7 @@ async function copyPathingsByGroup(pathings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPathingsByGroup(pathings, targetTexts, blacklistKeywords, accountName) {
|
async function processPathingsByGroup(pathings, whitelistKeywords, blacklistKeywords, accountName) {
|
||||||
let lastX = 0;
|
let lastX = 0;
|
||||||
let lastY = 0;
|
let lastY = 0;
|
||||||
let runningFailCount = 0;
|
let runningFailCount = 0;
|
||||||
@@ -899,8 +904,8 @@ async function processPathingsByGroup(pathings, targetTexts, blacklistKeywords,
|
|||||||
// 输出路径已刷新并开始处理的信息
|
// 输出路径已刷新并开始处理的信息
|
||||||
log.info(`该路线已刷新,开始处理。`);
|
log.info(`该路线已刷新,开始处理。`);
|
||||||
await fakeLog(`${pathing.fileName}`, false, true, 0);
|
await fakeLog(`${pathing.fileName}`, false, true, 0);
|
||||||
// 调用 runPathWithOcr 函数处理路径
|
// 调用 runPath 函数处理路径
|
||||||
await runPathWithOcr(pathing.fullPath, pathing.map_name, targetTexts, blacklistKeywords);
|
await runPath(pathing.fullPath, pathing.map_name, whitelistKeywords, blacklistKeywords);
|
||||||
try {
|
try {
|
||||||
await sleep(1);
|
await sleep(1);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -909,6 +914,7 @@ async function processPathingsByGroup(pathings, targetTexts, blacklistKeywords,
|
|||||||
await fakeLog(`${pathing.fileName}`, false, false, 0);
|
await fakeLog(`${pathing.fileName}`, false, false, 0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await genshin.returnMainUi();
|
||||||
const miniMapPosition = await genshin.getPositionFromMap(pathing.map_name);
|
const miniMapPosition = await genshin.getPositionFromMap(pathing.map_name);
|
||||||
// 比较坐标
|
// 比较坐标
|
||||||
const diffX = Math.abs(lastX - miniMapPosition.X);
|
const diffX = Math.abs(lastX - miniMapPosition.X);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"name": "锄地一条龙",
|
"name": "锄地一条龙",
|
||||||
"version": "1.1.8",
|
"version": "1.1.9",
|
||||||
"description": "一站式解决自动化锄地,支持只拾取狗粮,请阅读README.md后使用",
|
"description": "一站式解决自动化锄地,支持只拾取狗粮,请阅读README.md后使用",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user