mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-21 04:19:51 +08:00
459 lines
16 KiB
JavaScript
459 lines
16 KiB
JavaScript
// 原神每日委托自动执行脚本 - 委托功能识别模块
|
||
var CommissionRecognition = {
|
||
// 识别委托地点
|
||
recognizeCommissionLocation: async function() {
|
||
try {
|
||
log.info(
|
||
"识别委托地点 ({x}, {y}) ({width}, {height})...",
|
||
Constants.OCR_REGIONS.LOCATION.X,
|
||
Constants.OCR_REGIONS.LOCATION.Y,
|
||
Constants.OCR_REGIONS.LOCATION.X + Constants.OCR_REGIONS.LOCATION.WIDTH,
|
||
Constants.OCR_REGIONS.LOCATION.Y + Constants.OCR_REGIONS.LOCATION.HEIGHT
|
||
);
|
||
|
||
// 使用Utils.easyOCROne进行识别
|
||
var location = await Utils.easyOCROne(Constants.OCR_REGIONS.LOCATION);
|
||
|
||
if (location && location.trim()) {
|
||
return location.trim();
|
||
}
|
||
|
||
return "未知地点";
|
||
} catch (error) {
|
||
log.error("识别委托地点时出错: {error}", error.message);
|
||
return "识别失败";
|
||
}
|
||
},
|
||
|
||
// 检测是否进入委托详情界面
|
||
checkDetailPageEntered: async function() {
|
||
try {
|
||
// 尝试3次OCR识别
|
||
for (var i = 0; i < 3; i++) {
|
||
// 使用Utils.easyOCR进行识别
|
||
var results = await Utils.easyOCR(Constants.OCR_REGIONS.DETAIL_COUNTRY);
|
||
|
||
if (results.count > 0) {
|
||
// 检查OCR结果
|
||
for (var j = 0; j < results.count; j++) {
|
||
var text = results[j].text.trim();
|
||
|
||
// 如果有"蒙德",表示进入了详情界面
|
||
if (text.includes("蒙德")) {
|
||
log.info("检测到蒙德委托,成功进入详情界面");
|
||
return "蒙德";
|
||
}
|
||
// 如果没有文字,可能是已完成委托
|
||
else if (text === "") {
|
||
log.info("未检测到地区文本,可能是已完成委托");
|
||
return "已完成";
|
||
}
|
||
// 其他地区委托
|
||
else if (text.length >= 2) {
|
||
log.info("检测到其他地区委托: {text}", text);
|
||
return text;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果没有检测到,等待一会再试
|
||
await sleep(500);
|
||
}
|
||
|
||
log.info("三次OCR检测后仍未确认委托国家");
|
||
return "未知";
|
||
} catch (error) {
|
||
log.error("检测委托详情界面时出错: {error}", error.message);
|
||
return "错误";
|
||
}
|
||
},
|
||
|
||
// 识别委托列表 - 进行4个单独识别
|
||
recognizeCommissions: async function(supportedCommissions) {
|
||
try {
|
||
log.info("开始执行委托识别");
|
||
|
||
// 初始化当前委托位置变量
|
||
var currentCommissionPosition = null;
|
||
|
||
// 步骤1: 识别前3个委托(索引0-2)
|
||
log.info("步骤1: 使用识别前3个委托");
|
||
|
||
var allCommissions = [];
|
||
|
||
// 先识别前3个区域(索引0-2)
|
||
for (var regionIndex = 0; regionIndex < 3; regionIndex++) {
|
||
var region = Constants.OCR_REGIONS.Main_Dev[regionIndex];
|
||
|
||
log.info(
|
||
"识别第{index}个委托区域 ({x}, {y}) ({width}, {height})",
|
||
regionIndex + 1,
|
||
region.X,
|
||
region.Y,
|
||
region.X + region.WIDTH,
|
||
region.Y + region.HEIGHT
|
||
);
|
||
|
||
try {
|
||
var results = await Utils.easyOCR(region);
|
||
log.info(
|
||
"第{index}个区域OCR识别结果数量: {count}",
|
||
regionIndex + 1,
|
||
results.count
|
||
);
|
||
|
||
// 处理识别结果,取第一个有效结果
|
||
for (var i = 0; i < results.count; i++) {
|
||
try {
|
||
var result = results[i];
|
||
var text = Utils.cleanText(result.text);
|
||
if (text && text.length >= Constants.MIN_TEXT_LENGTH) {
|
||
log.info('第{index}个委托: "{text}"', regionIndex + 1, text);
|
||
|
||
// 检查委托类型
|
||
var isFightCommission = supportedCommissions.fight.includes(text);
|
||
var isTalkCommission = supportedCommissions.talk.includes(text);
|
||
var isSupported = isFightCommission || isTalkCommission;
|
||
var commissionType = isFightCommission
|
||
? Constants.COMMISSION_TYPE.FIGHT
|
||
: isTalkCommission
|
||
? Constants.COMMISSION_TYPE.TALK
|
||
: "";
|
||
|
||
allCommissions.push({
|
||
id: regionIndex + 1,
|
||
name: text,
|
||
supported: isSupported,
|
||
type: commissionType,
|
||
location: "",
|
||
});
|
||
|
||
// 找到有效结果后跳出循环
|
||
break;
|
||
}
|
||
} catch (ocrError) {
|
||
log.error(
|
||
"处理第{regionIndex}个区域第{resultIndex}个OCR识别结果时出错: {error},跳过该结果",
|
||
regionIndex + 1,
|
||
i + 1,
|
||
ocrError
|
||
);
|
||
// 跳过该结果,继续处理下一个
|
||
continue;
|
||
}
|
||
}
|
||
} catch (regionError) {
|
||
log.error(
|
||
"识别第{index}个委托区域时出错: {error},跳过该区域",
|
||
regionIndex + 1,
|
||
regionError
|
||
);
|
||
continue;
|
||
}
|
||
}
|
||
|
||
// 步骤2: 使用图像识别检测所有委托的完成状态
|
||
log.info("步骤2: 检测所有委托的完成状态");
|
||
|
||
// 处理前3个委托
|
||
for (var i = 0; i < Math.min(3, allCommissions.length); i++) {
|
||
var commission = allCommissions[i];
|
||
|
||
try {
|
||
// 使用图像识别检测完成状态
|
||
var status = await CommissionBasic.detectCommissionStatusByImage(i);
|
||
|
||
if (status === "completed") {
|
||
log.info(
|
||
"委托{id} {name} 已完成,跳过详情查看",
|
||
commission.id,
|
||
commission.name
|
||
);
|
||
commission.location = "已完成";
|
||
continue;
|
||
} else if (status === "uncompleted") {
|
||
log.info(
|
||
"委托{id} {name} 未完成,查看详情",
|
||
commission.id,
|
||
commission.name
|
||
);
|
||
} else {
|
||
log.warn(
|
||
"委托{id} {name} 状态未知,尝试查看详情",
|
||
commission.id,
|
||
commission.name
|
||
);
|
||
}
|
||
|
||
// 只有未完成或状态未知的委托才点击查看详情
|
||
log.info(
|
||
"查看第{id}个委托详情: {name}",
|
||
commission.id,
|
||
commission.name
|
||
);
|
||
|
||
// 点击详情按钮
|
||
var detailButton = Constants.COMMISSION_DETAIL_BUTTONS[commission.id - 1];
|
||
log.info(
|
||
"点击委托详情按钮 ({x}, {y})",
|
||
detailButton.x,
|
||
detailButton.y
|
||
);
|
||
click(detailButton.x, detailButton.y);
|
||
await sleep(700);
|
||
|
||
// 检测委托国家
|
||
var detailStatus = await CommissionRecognition.checkDetailPageEntered();
|
||
log.info("委托国家: {status}", detailStatus);
|
||
commission.country = detailStatus;
|
||
var location = await CommissionRecognition.recognizeCommissionLocation();
|
||
commission.location = location;
|
||
log.info(
|
||
"委托 {name} 的地点: {location}",
|
||
commission.name,
|
||
location
|
||
);
|
||
|
||
// 退出详情页面并获取地图坐标
|
||
if (commission.location !== "已完成") {
|
||
log.info("退出详情页面 - 按ESC");
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
await genshin.setBigMapZoomLevel(2);
|
||
// 获取地图坐标并保存
|
||
var bigMapPosition = genshin.getPositionFromBigMap();
|
||
if (bigMapPosition) {
|
||
commission.CommissionPosition = bigMapPosition;
|
||
log.info(
|
||
"当前委托位置: ({x}, {y})",
|
||
bigMapPosition.x,
|
||
bigMapPosition.y
|
||
);
|
||
}
|
||
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
}
|
||
} catch (commissionError) {
|
||
log.error(
|
||
"处理委托{id} {name} 时出错: {error},跳过该委托",
|
||
commission.id,
|
||
commission.name,
|
||
commissionError
|
||
);
|
||
// 设置错误状态,但不中断整个流程
|
||
commission.location = "处理失败";
|
||
commission.country = "未知";
|
||
|
||
// 尝试退出可能打开的详情页面
|
||
try {
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
} catch (escapeError) {
|
||
log.warn("尝试退出详情页面时出错: {error}", escapeError);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 步骤3: 翻页后识别第4个委托
|
||
log.info("步骤3: 翻页后识别第4个委托");
|
||
await UI.pageScroll(1);
|
||
|
||
// 识别第4个区域(索引3)
|
||
var region = Constants.OCR_REGIONS.Main_Dev[3];
|
||
var fourthCommission = null;
|
||
|
||
log.info(
|
||
"识别第4个委托区域 ({x}, {y}) ({width}, {height})",
|
||
region.X,
|
||
region.Y,
|
||
region.X + region.WIDTH,
|
||
region.Y + region.HEIGHT
|
||
);
|
||
|
||
try {
|
||
var results = await Utils.easyOCR(region);
|
||
log.info("第4个区域OCR识别结果数量: {count}", results.count);
|
||
|
||
// 处理识别结果,取第一个有效结果
|
||
for (var i = 0; i < results.count; i++) {
|
||
try {
|
||
var result = results[i];
|
||
var text = Utils.cleanText(result.text);
|
||
if (text && text.length >= Constants.MIN_TEXT_LENGTH) {
|
||
log.info('第4个委托: "{text}"', text);
|
||
|
||
// 检查委托类型
|
||
var isFightCommission = supportedCommissions.fight.includes(text);
|
||
var isTalkCommission = supportedCommissions.talk.includes(text);
|
||
var isSupported = isFightCommission || isTalkCommission;
|
||
var commissionType = isFightCommission
|
||
? Constants.COMMISSION_TYPE.FIGHT
|
||
: isTalkCommission
|
||
? Constants.COMMISSION_TYPE.TALK
|
||
: "";
|
||
|
||
fourthCommission = {
|
||
id: 4,
|
||
name: text,
|
||
supported: isSupported,
|
||
type: commissionType,
|
||
location: "",
|
||
};
|
||
|
||
// 找到有效结果后跳出循环
|
||
break;
|
||
}
|
||
} catch (ocrError) {
|
||
log.error(
|
||
"处理第4个区域第{resultIndex}个OCR识别结果时出错: {error},跳过该结果",
|
||
i + 1,
|
||
ocrError
|
||
);
|
||
// 跳过该结果,继续处理下一个
|
||
continue;
|
||
}
|
||
}
|
||
} catch (regionError) {
|
||
log.error("识别第4个委托区域时出错: {error}", regionError);
|
||
}
|
||
|
||
// 如果识别到第4个委托,添加到列表中
|
||
if (fourthCommission) {
|
||
allCommissions.push(fourthCommission);
|
||
}
|
||
|
||
// 步骤4: 处理第4个委托的完成状态
|
||
if (fourthCommission) {
|
||
try {
|
||
// 使用图像识别检测第4个委托的完成状态
|
||
var status = await CommissionBasic.detectCommissionStatusByImage(3); // 第4个委托索引为3
|
||
|
||
if (status === "completed") {
|
||
log.info(
|
||
"委托{id} {name} 已完成,跳过详情查看",
|
||
fourthCommission.id,
|
||
fourthCommission.name
|
||
);
|
||
fourthCommission.location = "已完成";
|
||
} else if (status === "uncompleted") {
|
||
log.info(
|
||
"委托{id} {name} 未完成,查看详情",
|
||
fourthCommission.id,
|
||
fourthCommission.name
|
||
);
|
||
} else {
|
||
log.warn(
|
||
"委托{id} {name} 状态未知,尝试查看详情",
|
||
fourthCommission.id,
|
||
fourthCommission.name
|
||
);
|
||
}
|
||
|
||
// 只有未完成或状态未知的委托才点击查看详情
|
||
if (status !== "completed") {
|
||
log.info("查看第4个委托详情: {name}", fourthCommission.name);
|
||
|
||
// 点击详情按钮
|
||
var detailButton = Constants.COMMISSION_DETAIL_BUTTONS[3]; // 第4个按钮索引为3
|
||
log.info(
|
||
"点击委托详情按钮 ({x}, {y})",
|
||
detailButton.x,
|
||
detailButton.y
|
||
);
|
||
click(detailButton.x, detailButton.y);
|
||
await sleep(700);
|
||
|
||
// 检测是否成功进入详情界面并获取委托国家
|
||
var detailStatus = await CommissionRecognition.checkDetailPageEntered();
|
||
log.info("委托国家: {status}", detailStatus);
|
||
fourthCommission.country = detailStatus;
|
||
|
||
// 识别委托地点
|
||
var location = await CommissionRecognition.recognizeCommissionLocation();
|
||
fourthCommission.location = location;
|
||
log.info(
|
||
"委托 {name} 的地点: {location}",
|
||
fourthCommission.name,
|
||
location
|
||
);
|
||
|
||
// 退出详情页面并获取地图坐标
|
||
if (fourthCommission.location !== "已完成") {
|
||
log.info("退出详情页面 - 按ESC");
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
await genshin.setBigMapZoomLevel(2);
|
||
// 获取地图坐标并保存
|
||
var bigMapPosition = genshin.getPositionFromBigMap();
|
||
if (bigMapPosition) {
|
||
fourthCommission.CommissionPosition = bigMapPosition;
|
||
log.info(
|
||
"当前委托位置: ({x}, {y})",
|
||
bigMapPosition.x,
|
||
bigMapPosition.y
|
||
);
|
||
}
|
||
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
}
|
||
}
|
||
} catch (fourthCommissionError) {
|
||
log.error(
|
||
"处理第4个委托{name} 时出错: {error},跳过该委托",
|
||
fourthCommission.name,
|
||
fourthCommissionError
|
||
);
|
||
// 设置错误状态,但不中断整个流程
|
||
fourthCommission.location = "处理失败";
|
||
fourthCommission.country = "未知";
|
||
|
||
// 尝试退出可能打开的详情页面
|
||
try {
|
||
keyDown("VK_ESCAPE");
|
||
await sleep(300);
|
||
keyUp("VK_ESCAPE");
|
||
await sleep(1200);
|
||
} catch (escapeError) {
|
||
log.warn("尝试退出详情页面时出错: {error}", escapeError);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 输出完整委托列表
|
||
log.info("完整委托列表:");
|
||
for (var i = 0; i < allCommissions.length; i++) {
|
||
var commission = allCommissions[i];
|
||
var supportStatus = commission.supported ? "✅ 支持" : "❌ 不支持";
|
||
var typeInfo = commission.type ? "[" + commission.type + "]" : "";
|
||
var locationInfo = commission.location ? "(" + commission.location + ")" : "";
|
||
var countryInfo = commission.country ? "{" + commission.country + "}" : "";
|
||
log.info(
|
||
"{id}. {name} {location} {country} {type} - {status}",
|
||
commission.id,
|
||
commission.name,
|
||
locationInfo,
|
||
countryInfo,
|
||
typeInfo,
|
||
supportStatus
|
||
);
|
||
}
|
||
|
||
return allCommissions;
|
||
} catch (error) {
|
||
log.error("识别委托时出错: {error}", error.message);
|
||
return [];
|
||
}
|
||
},
|
||
}; |