Files
bettergi-scripts-list/repo/js/AutoPickLitter/main.js
古又 068d5de400 日常更新 (#1792)
* 优化梅洛彼得堡路线

* 更新

1、重构相关代码
2、替换解签后的识别模式

* 更新

1、重构相关代码
2、替换解签后的识别模式

* Add files via upload
2025-09-01 22:57:41 +08:00

610 lines
27 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 初始化游戏截图区域
let gameRegion;
// 对话识别区域
const dialogZone = { x: { min: 900, max: 1700 }, y: { min: 380, max: 880 } };
//文字识别,并返回相关信息
async function performOcr(keyWords, xRange, yRange, judge) {
//截取游戏截图
gameRegion = captureGameRegion();
try {
if (judge) {
//单个识别
let ocrResult = gameRegion.find(RecognitionObject.ocr(
xRange.min, yRange.min,
xRange.max - xRange.min, yRange.max - yRange.min
));
//释放内存
gameRegion.dispose();
if (ocrResult) {
//识别结果
let correctedText = ocrResult.text;
return correctedText;
} else {
// log.warn(`OCR 识别区域未找到内容`);
return "";
}
} else {
//多个识别
let resList = gameRegion.findMulti(RecognitionObject.ocr(
xRange.min, yRange.min,
xRange.max - xRange.min, yRange.max - yRange.min
));
//释放内存
gameRegion.dispose();
// 遍历识别结果,检查是否找到目标文本
let results = [];
for (let i = 0; i < resList.count; i++) {
let res = resList[i];
let correctedText = res.text;
if (correctedText.includes(keyWords)) {
results.push({ text: correctedText, x: res.x, y: res.y, width: res.width, height: res.height });
//点击中心
// await click(Math.round(res.x +res.width/2),Math.round(res.y + res.height/2));
keyDown("VK_MENU");
await sleep(500);
moveMouseTo(res.x, res.y);
leftButtonClick();
await sleep(800);
keyUp("VK_MENU");
await sleep(1000);
leftButtonClick();
break;
}
}
return results;
}
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
return null;
}
}
//图像识别,并返回相关信息
async function findImgIcon(imagePath, xRange, yRange, judge) {
// 读取图像模板
let template = file.ReadImageMatSync(imagePath);
// 创建识别对象
let recognitionObject = RecognitionObject.TemplateMatch(template, xRange.min, yRange.min,
xRange.max - xRange.min, yRange.max - yRange.min);
let results = [];
let results1 = [];
// 捕捉游戏截图
gameRegion = captureGameRegion();
// 查找图像
let result = gameRegion.find(recognitionObject);
// 释放内存
gameRegion.dispose();
try {
// 如果需要判断
if (judge) {
// 如果找到
if (result.isExist()) {
// 保存结果
results.push({ success: true, x: result.x, y: result.y, width: result.width, height: result.height });
// 点击该位置
keyDown("VK_MENU");
await sleep(500);
moveMouseTo(result.x, result.y);
leftButtonClick();
await sleep(800);
keyUp("VK_MENU");
} else {
// log.info("图像识别失败");
}
return results;
} else {
// 如果找到
if (result.isExist()) {
// 保存结果
results1.push({ success: true, x: result.x, y: result.y, width: result.width, height: result.height });
} else {
// log.info("图像识别失败");
}
return results1;
}
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
}
//添加信息
function writeContentToFile(content, judge) {
let finalAccountName = settings.accountName || "默认账户";
try {
const illegalCharacters = /[\\/:*?"<>|]/;
const reservedNames = [
"CON", "PRN", "AUX", "NUL",
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"
];
if (finalAccountName === "" ||
finalAccountName.startsWith(" ") ||
finalAccountName.endsWith(" ") ||
illegalCharacters.test(finalAccountName) ||
reservedNames.includes(finalAccountName.toUpperCase()) ||
finalAccountName.length > 255
) {
log.error(`账户名 "${finalAccountName}" 不合法,将使用默认值`);
finalAccountName = "默认账户";
}
} catch (error) {
// 只在文件完全不存在时创建,避免覆盖
file.writeTextSync(finalAccountName, content, false);
log.info(`创建新文件: ${finalAccountName}`);
}
let filePath = `records/${finalAccountName}.txt`;
//读取现有内容
let existingContent = "";
try {
existingContent = file.readTextSync(filePath);
} catch (e) {
}
if (judge) {
runDate = `==========${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}日==========`;
const finalContent1 = runDate + "\n" + existingContent;
//按行分割保留最近365条完整记录按原始换行分割不过滤
const lines = finalContent1.split("\n");
const keepLines = lines.length > 365 * 5 ? lines.slice(0, 365 * 5) : lines; // 假设每条记录最多5行
const result1 = file.writeTextSync(filePath, keepLines.join("\n"), false);
if (result1) {
log.info(`写入成功: ${filePath}`);
} else {
log.error(`写入失败: ${filePath}`);
}
} else {
//拼接
const finalContent = content + existingContent;
//按行分割保留最近365条完整记录按原始换行分割不过滤
const lines = finalContent.split("\n");
const keepLines = lines.length > 365 * 5 ? lines.slice(0, 365 * 5) : lines; // 假设每条记录最多5行
const result = file.writeTextSync(filePath, keepLines.join("\n"), false);
if (result) {
log.info(`写入成功: ${filePath}`);
} else {
log.error(`写入失败: ${filePath}`);
}
}
}
// 滚动页面
// totalDistance: 需要滚动的总距离
// stepDistance: 每次滚动的距离
// delayMs: 两次滚动之间的延迟
async function scrollPage(totalDistance, stepDistance = 10, delayMs = 5) {
// 移动鼠标到(999, 750)并按下左键
moveMouseTo(999, 750);
await sleep(50);
leftButtonDown();
// 估算需要滚动的步数
const steps = Math.ceil(totalDistance / stepDistance);
// 依次滚动
for (let j = 0; j < steps; j++) {
// 计算本次滚动剩余的距离
const remainingDistance = totalDistance - j * stepDistance;
// 如果剩余距离小于 stepDistance则滚动剩余的距离
// 否则滚动 stepDistance
const moveDistance = remainingDistance < stepDistance ? remainingDistance : stepDistance;
// 滚动
moveMouseBy(0, -moveDistance);
// 等待 delayMs ms
await sleep(delayMs);
}
// 等待700ms
await sleep(700);
// 释放左键
leftButtonUp();
// 等待100ms
await sleep(100);
}
(async function() {
//蒙德清泉镇圣水
if (settings.water) {
await genshin.returnMainUi();
await pathingScript.runFile("assets/霍普金斯.json");
await genshin.returnMainUi();
await pathingScript.runFile("assets/蒙德清泉镇路线.json");
await sleep(1000);
//识别区域
try {
//识别对话位置,并点击
let ocrResults = await performOcr("神奇的", dialogZone.x, dialogZone.y, false);
if (ocrResults.length != 0) {
await sleep(700);
await genshin.chooseTalkOption("如何才能获得强大的力量");
await sleep(1000);
leftButtonClick();
await sleep(1000);
let recognizedOver = await performOcr("已",{ min: 1482, max: 1630 }, { min: 912, max: 957 }, false)
if (recognizedOver.length != 0) {
log.info("已售罄!!!");
await genshin.returnMainUi();
} else {
let recognizedMora = await performOcr("", { min: 1600, max: 1780 }, { min: 30, max: 60 }, true)
if (BigInt(recognizedMora) >= 300) {
await sleep(800);
await click(1636,1019);
await sleep(1000);
await click(1168,785);
await sleep(1000);
} else {
log.info("不是哥们,你怎么比我还穷!!!");
await genshin.returnMainUi();
};
};
};
await genshin.returnMainUi();
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
};
//璃月璃沙娇上香
if (settings.sticks) {
await genshin.returnMainUi();
await pathingScript.runFile("assets/璃月璃沙娇路线.json");
await sleep(1000);
//识别区域
try {
//识别对话位置,并点击
// let ocrResults = await performOcr("王平安", { min: 1058, max: 1551 }, { min: 394, max: 680 }, false);
let ocrResults = await performOcr("王平安", dialogZone.x, dialogZone.y, false);
if (ocrResults.length != 0) {
await sleep(700);
await genshin.chooseTalkOption("能给我几支香吗");
await sleep(700);
leftButtonClick();
await sleep(700);
leftButtonClick();
await sleep(1500);
// let ocrResults1 = await performOcr("敬香", { min: 1060, max: 1550 }, { min: 400, max: 680 }, false);
let ocrResults1 = await performOcr("敬香", dialogZone.x, dialogZone.y, false);
if(ocrResults1.length != 0){
await sleep(700);
await click(1168,785);
await sleep(700);
} else {
log.error(`未识别到对话`);
await genshin.returnMainUi();
};
} else {
log.error(`识别图像时发生异常: ${error.message}`);
};
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
await genshin.returnMainUi();
};
//稻妻鸣神大社抽签
if (settings.lots) {
await genshin.returnMainUi();
await pathingScript.runFile("assets/稻妻鸣神大社路线.json");
await sleep(1000);
//识别区域
try {
//识别对话位置,并点击
let ocrResults = await performOcr("御神签箱", dialogZone.x, dialogZone.y, false);
if (ocrResults.length != 0) {
await sleep(700);
leftButtonClick();
await sleep(2000);
let ocrResults1 = await performOcr("求签吧", dialogZone.x, dialogZone.y, false);
if (ocrResults1.length != 0) {
await sleep(2000);
leftButtonClick();
await sleep(4000);
leftButtonClick();
await sleep(3000);
};
let ocrResults2 = await performOcr("玄冬林", dialogZone.x, dialogZone.y, false);
if (ocrResults2.length != 0) {
await sleep(1000);
leftButtonClick();
await sleep(700);
let ocrResults3 = await performOcr("我要", dialogZone.x, dialogZone.y, false);
if (ocrResults3.length != 0) {
await sleep(700);
leftButtonClick();
await sleep(1500);
//交互道具,直接选择位置点击
await click(111,184);
await sleep(1000);
await click(1250,817);
await sleep(1000);
await click(1603,1013);
await sleep(1500);
await genshin.returnMainUi();
//打开背包找签
await keyPress("B");
await sleep(1000);
await click(1150,50);
await sleep(700);
for(let scroll = 0; scroll <= 22; scroll++){
//识别御神签
let img = await findImgIcon("assets/RecognitionObject/YuShenQianHalf.png", { min: 99, max: 1295 }, { min: 104, max: 967 }, true)
if (img.length != 0) {
break;
};
//判断是否到底
let img1 = await findImgIcon("assets/RecognitionObject/SliderBottom.png", { min: 1284, max: 1293 }, { min: 916, max: 942 }, false)
if (img1.length != 0) {
log.info("已到达最后一页!");
break;
};
//滑动背包
await scrollPage(680, 10, 5);
await sleep(100);
};
await sleep(2000);
await click(1670,1025);
await sleep(2500);
// 通过图片识别
// 大凶or凶
let img2 = await findImgIcon("assets/RecognitionObject/Bad.png", { min: 630, max: 830 }, { min: 100, max: 160 }, false);
let img3 = await findImgIcon("assets/RecognitionObject/BigBad.png", { min: 630, max: 830 }, { min: 100, max: 160 }, false);
// 大吉、吉、末吉
let img4 = await findImgIcon("assets/RecognitionObject/BigLuck.png", { min: 630, max: 830 }, { min: 100, max: 160 }, false);
let img5 = await findImgIcon("assets/RecognitionObject/luck.png", { min: 630, max: 830 }, { min: 100, max: 160 }, false);
let img6 = await findImgIcon("assets/RecognitionObject/EndLuck.png", { min: 630, max: 830 }, { min: 100, max: 160 }, false);
await genshin.returnMainUi();
if (img2.length !== 0) {
log.info("抽签的结果:凶");
writeContentToFile(`抽签的结果:凶\n`, false);
await pathingScript.runFile("assets/挂签路线.json");
await performOcr("御签挂", { min: 900, max: 1700 }, { min: 380, max: 880 }, false);
await sleep(700);
await genshin.chooseTalkOption("挂起来吧");
await click(111,184);
await sleep(1000);
await click(1250,817);
await sleep(1000);
await click(1603,1013);
await sleep(1500);
await genshin.returnMainUi();
log.info("事事顺利");
} else if (img3.length !== 0) {
log.info("抽签的结果:大凶");
writeContentToFile(`抽签的结果:大凶\n`, false);
await pathingScript.runFile("assets/挂签路线.json");
await performOcr("御签挂", { min: 900, max: 1700 }, { min: 380, max: 880 }, false);
await sleep(700);
await genshin.chooseTalkOption("挂起来吧");
await click(111,184);
await sleep(1000);
await click(1250,817);
await sleep(1000);
await click(1603,1013);
await sleep(1500);
await genshin.returnMainUi();
log.info("事事顺利");
} else if (img4.length !== 0) {
log.info("抽签的结果:大吉");
writeContentToFile(`抽签的结果:大吉\n`, false);
} else if (img5.length !== 0) {
log.info("抽签的结果:吉");
writeContentToFile(`抽签的结果:吉\n`, false);
} else {
log.info("抽签的结果:末吉");
writeContentToFile(`抽签的结果:末吉\n`, false);
};
// // 通过文字识别
// let recognizedText = await performOcr("", { min: 630, max: 800 }, { min: 100, max: 160 }, true);
// await genshin.returnMainUi();
// if(recognizedText.includes("区")){
// await pathingScript.runFile("assets/挂签路线.json");
// await performOcr("御签挂", { min: 900, max: 1700 }, { min: 380, max: 880 }, false);
// await sleep(700);
// await genshin.chooseTalkOption("挂起来吧");
// await click(111,184);
// await sleep(1000);
// await click(1250,817);
// await sleep(1000);
// await click(1603,1013);
// await sleep(1500);
// await genshin.returnMainUi();
// log.info("事事顺利");
// };
} else {
await sleep(700);
await genshin.chooseTalkOption("再见");
await sleep(700);
leftButtonClick();
await sleep(1500);
log.info("对话出现再见,默认解签完毕以及查看签操作!!!");
};
};
} else {
log.error(`识别图像时发生异常: ${error.message}`);
await genshin.returnMainUi();
}
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
await genshin.returnMainUi();
};
//枫丹梅洛彼得堡领取福利餐
if(settings.meal){
await genshin.returnMainUi();
await pathingScript.runFile("assets/枫丹梅洛彼得堡路线.json");
await sleep(700);
try {
let ocrResults = await performOcr("布兰", dialogZone.x, dialogZone.y, false);
if (ocrResults.length != 0) {
await sleep(1000);
let ocrResults1 = await performOcr("没什么", dialogZone.x, dialogZone.y, false);
if(ocrResults1.length != 0){
await sleep(700);
log.info("对话出现没什么,默认领取和使用过!!!");
} else{
await genshin.chooseTalkOption("给我一份福利餐");
await sleep(1000);
leftButtonClick();
await sleep(1000);
leftButtonClick();
await sleep(1500);
//打开背包找签
log.info("打开背包");
await keyPress("B");
await sleep(1000);
await click(1250,50);
await sleep(1000);
for(let scroll = 0; scroll <= 10; scroll++){
let img = await findImgIcon("assets/RecognitionObject/WelffareMealHalf.png", { min: 99, max: 1295 }, { min: 104, max: 967 }, true)
if (img.length != 0) {
break;
}
//滑动背包
await sleep(1000);
await scrollPage(680, 10, 5);
await sleep(1000);
};
//这里是点击使用
await sleep(1000);
await click(1670,1025);
await sleep(2000);
//识别获得的食物名称
let recognizedText = await performOcr("", { min: 813, max: 985 }, { min: 585, max: 619 }, true);
log.info(`获得:${recognizedText}`);
//点击幸运签,并识别内容
await sleep(1000);
await click(1000,520);
await sleep(2000);
let recognizedText1 = await performOcr("", { min: 716, max: 1200 }, { min: 631, max: 710 }, true);
log.info(`幸运签内容:${recognizedText1}`);
writeContentToFile(`获得的食物:${recognizedText}\n幸运签内容:${recognizedText1}\n`, false);
};
} else {
log.error(`识别图像时发生异常: ${error.message}`);
await genshin.returnMainUi();
}
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
await genshin.returnMainUi();
};
//纳塔悠悠集市
if(settings.eggs){
await genshin.returnMainUi();
await pathingScript.runFile("assets/纳塔悠悠集市路线.json");
await sleep(1000);
try {
let ocrResults = await performOcr("察尔瓦", dialogZone.x, dialogZone.y, false);
await sleep(700);
leftButtonClick();
await sleep(2000);
let ocrResults1 = await performOcr("让我挑一枚", dialogZone.x, dialogZone.y, false);
if (ocrResults1 != 0) {
await sleep(5000);
let figure = 0;
//六龙蛋位置
let coordinates = [
[551, 153],
[881, 341],
[1087, 161],
[1342, 357],
[472, 572],
[572, 721]
];
switch (settings.pickupDragonEgg) {
case "闪闪礼蛋·山之血":
figure = 1;
writeContentToFile("获得的龙蛋:闪闪礼蛋·山之血\n", false);
break;
case "闪闪礼蛋·太阳的轰鸣":
figure = 2;
writeContentToFile("获得的龙蛋:闪闪礼蛋·太阳的轰鸣\n", false);
break;
case "闪闪礼蛋·圣龙君临":
writeContentToFile("获得的龙蛋:闪闪礼蛋·圣龙君临\n", false);
figure = 3;
break;
case "闪闪礼蛋·菲耶蒂娜":
writeContentToFile("获得的龙蛋:闪闪礼蛋·菲耶蒂娜\n", false);
figure = 4;
break;
case "闪闪礼蛋·献给小酒杯":
writeContentToFile("获得的龙蛋:闪闪礼蛋·献给小酒杯\n", false);
figure = 5;
break;
case "闪闪礼蛋·飞澜鲨鲨":
writeContentToFile("获得的龙蛋:闪闪礼蛋·飞澜鲨鲨\n", false);
figure = 6;
break;
default:
figure = Math.floor(Math.random() * 6) + 1;
log.info(`随机到第${figure}个蛋`);
switch (figure) {
case 1:
writeContentToFile("获得的龙蛋:闪闪礼蛋·山之血\n", false);
break;
case 2:
writeContentToFile("获得的龙蛋:闪闪礼蛋·太阳的轰鸣\n", false);
break;
case 3:
writeContentToFile("获得的龙蛋:闪闪礼蛋·圣龙君临\n", false);
break;
case 4:
writeContentToFile("获得的龙蛋:闪闪礼蛋·菲耶蒂娜\n", false);
break;
case 5:
writeContentToFile("获得的龙蛋:闪闪礼蛋·献给小酒杯\n", false);
break;
default:
writeContentToFile("获得的龙蛋:闪闪礼蛋·飞澜鲨鲨\n", false);
break;
}
break;
};
moveMouseTo(coordinates[figure - 1][0],coordinates[figure - 1][1]);
await sleep(100);
leftButtonClick();
await sleep(3000);
} else {
log.info("你今天已经领取过了");
};
} catch (error) {
log.error(`识别图像时发生异常: ${error.message}`);
}
await genshin.returnMainUi();
};
//输出日期
writeContentToFile("", true);
})();