Files
bettergi-scripts-list/repo/js/AutoCommission/lib/commission-recognition.js
2025-08-14 22:46:12 +08:00

459 lines
16 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.
// 原神每日委托自动执行脚本 - 委托功能识别模块
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 [];
}
},
};