mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-25 04:59:52 +08:00
717 lines
24 KiB
JavaScript
717 lines
24 KiB
JavaScript
// 原神每日委托自动执行脚本 - 委托识别模块
|
||
// 编辑距离算法,用于计算字符串相似度
|
||
function levenshteinDistance(str1, str2) {
|
||
const m = str1.length;
|
||
const n = str2.length;
|
||
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
||
|
||
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
||
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
||
|
||
for (let i = 1; i <= m; i++) {
|
||
for (let j = 1; j <= n; j++) {
|
||
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
||
dp[i][j] = Math.min(
|
||
dp[i - 1][j] + 1,
|
||
dp[i][j - 1] + 1,
|
||
dp[i - 1][j - 1] + cost
|
||
);
|
||
}
|
||
}
|
||
|
||
return dp[m][n];
|
||
}
|
||
|
||
// 获取最接近的匹配项(带阈值)
|
||
function getClosestMatch(target, candidates, threshold = Constants.MATCH_THRESHOLD.DEFAULT) {
|
||
if (!candidates || candidates.length === 0) return null;
|
||
|
||
let closest = candidates[0];
|
||
let minDistance = levenshteinDistance(target, closest);
|
||
let maxSimilarity = calculateSimilarity(target, closest);
|
||
|
||
for (let i = 1; i < candidates.length; i++) {
|
||
const distance = levenshteinDistance(target, candidates[i]);
|
||
const similarity = calculateSimilarity(target, candidates[i]);
|
||
|
||
if (similarity > maxSimilarity) {
|
||
maxSimilarity = similarity;
|
||
minDistance = distance;
|
||
closest = candidates[i];
|
||
}
|
||
}
|
||
|
||
// 检查相似度是否达到阈值
|
||
if (maxSimilarity < threshold) {
|
||
return null;
|
||
}
|
||
|
||
return closest;
|
||
}
|
||
|
||
// 计算字符串相似度
|
||
function calculateSimilarity(str1, str2) {
|
||
const distance = levenshteinDistance(str1, str2);
|
||
const maxLength = Math.max(str1.length, str2.length);
|
||
return maxLength === 0 ? 1 : 1 - (distance / maxLength);
|
||
}
|
||
|
||
var CommissionStandardizer = {
|
||
// 标准化列表
|
||
standardizationLists: {
|
||
fight: {},
|
||
talk: {}
|
||
},
|
||
|
||
// 初始化标准化列表
|
||
initialize: function() {
|
||
log.info("初始化委托标准化列表...");
|
||
|
||
try {
|
||
// 初始化战斗委托标准化列表
|
||
this.standardizationLists.fight = this.buildFightStandardizationList();
|
||
|
||
// 初始化对话委托标准化列表
|
||
this.standardizationLists.talk = this.buildTalkStandardizationList();
|
||
|
||
log.info("委托标准化列表初始化完成");
|
||
log.debug("战斗委托标准化列表: {count} 个委托", Object.keys(this.standardizationLists.fight).length);
|
||
log.debug("对话委托标准化列表: {count} 个委托", Object.keys(this.standardizationLists.talk).length);
|
||
log.debug("standardizationLists的值:{x}",JSON.stringify(this.standardizationLists))
|
||
} catch (error) {
|
||
log.error("初始化标准化列表时出错: {error}", error.message);
|
||
}
|
||
},
|
||
|
||
// 构建战斗委托标准化列表
|
||
buildFightStandardizationList: function() {
|
||
const fightList = {};
|
||
|
||
try {
|
||
// 读取assets目录下除process外的所有文件夹
|
||
const assetsPath = "assets";
|
||
const items = Array.from(file.readPathSync(assetsPath));
|
||
|
||
// 过滤出文件夹且不是process
|
||
const folders = items.filter(item => {
|
||
return file.isFolder(item) && !item.includes("process");
|
||
});
|
||
|
||
// 遍历每个战斗委托文件夹
|
||
for (const folderPath of folders) {
|
||
// 从完整路径中提取文件夹名称
|
||
const folderName = folderPath.replace(assetsPath + "/", "").replace(assetsPath + "\\", "");
|
||
const files = Array.from(file.readPathSync(folderPath));
|
||
|
||
// 过滤出json文件
|
||
const jsonFiles = files.filter(file => file.endsWith(".json"));
|
||
|
||
// 提取文件名(不包含路径和.json后缀),并去除-1 -2等数字后缀
|
||
const cleanFileNames = jsonFiles.map(filePath => {
|
||
// 从完整路径中提取文件名
|
||
const fileName = filePath.split("/").pop().split("\\").pop();
|
||
// 去除-1 -2等数字后缀和.json后缀
|
||
return fileName.replace(/-(\d+)?\.json$/, "");
|
||
});
|
||
|
||
fightList[folderName] = cleanFileNames;
|
||
}
|
||
} catch (error) {
|
||
log.error("构建战斗委托标准化列表时出错: {error}", error.message);
|
||
}
|
||
|
||
return fightList;
|
||
},
|
||
|
||
// 构建对话委托标准化列表
|
||
buildTalkStandardizationList: function() {
|
||
const talkList = {};
|
||
|
||
try {
|
||
// 读取assets/process目录下的所有文件夹
|
||
const processPath = "assets/process";
|
||
const items = Array.from(file.readPathSync(processPath));
|
||
|
||
// 过滤出文件夹
|
||
const folders = items.filter(item => {
|
||
return file.isFolder(item);
|
||
});
|
||
|
||
// 遍历每个对话委托文件夹
|
||
for (const folderPath of folders) {
|
||
// 从完整路径中提取文件夹名称
|
||
const folderName = folderPath.split("/").pop().split("\\").pop();
|
||
const subItems = Array.from(file.readPathSync(folderPath));
|
||
|
||
// 过滤出子文件夹
|
||
const subFolders = subItems.filter(subItem => {
|
||
return file.isFolder(subItem);
|
||
});
|
||
|
||
// 从完整路径中提取子文件夹名称
|
||
const cleanSubFolders = subFolders.map(subFolderPath => {
|
||
// 从完整路径中提取最后一级文件夹名称
|
||
return subFolderPath.split("/").pop().split("\\").pop();
|
||
});
|
||
|
||
talkList[folderName] = cleanSubFolders;
|
||
}
|
||
} catch (error) {
|
||
log.error("构建对话委托标准化列表时出错: {error}", error.message);
|
||
}
|
||
|
||
return talkList;
|
||
},
|
||
|
||
// 标准化委托名称
|
||
standardizeCommissionName: function(rawName) {
|
||
// 从所有标准化列表中查找最接近的名称
|
||
const allNames = [
|
||
...Object.keys(this.standardizationLists.fight),
|
||
...Object.keys(this.standardizationLists.talk)
|
||
];
|
||
|
||
return getClosestMatch(rawName, allNames, Constants.MATCH_THRESHOLD.COMISSIONS_NAME);
|
||
},
|
||
|
||
// 标准化委托地点
|
||
standardizeCommissionLocation: function(commissionName, rawLocation) {
|
||
// 根据委托类型选择对应的标准化列表
|
||
let candidates = [];
|
||
|
||
if (this.standardizationLists.fight[commissionName]) {
|
||
// 战斗委托
|
||
candidates = this.standardizationLists.fight[commissionName];
|
||
} else if (this.standardizationLists.talk[commissionName]) {
|
||
// 对话委托
|
||
candidates = this.standardizationLists.talk[commissionName];
|
||
}
|
||
|
||
if (candidates.length === 0) {
|
||
log.warn("没有找到委托 {name} 的标准化地点列表", commissionName);
|
||
return rawLocation;
|
||
}
|
||
|
||
// 获取最接近的地点
|
||
const closestLocation = getClosestMatch(rawLocation, candidates, Constants.MATCH_THRESHOLD.LOCATION);
|
||
|
||
if (closestLocation) {
|
||
log.info("标准化地点: {raw} -> {standard}", rawLocation, closestLocation);
|
||
return closestLocation;
|
||
} else {
|
||
log.info("地点相似度未达阈值,保持原地点: {raw}", rawLocation);
|
||
return rawLocation;
|
||
}
|
||
}
|
||
};
|
||
|
||
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 standardizedName = CommissionStandardizer.standardizeCommissionName(text);
|
||
if (standardizedName && standardizedName !== text) {
|
||
log.info('委托名称标准化: "{raw}" -> "{standard}"', text, standardizedName);
|
||
text = standardizedName;
|
||
} else {
|
||
log.debug('委托名称相似度未达阈值,保持原名称: "{raw}"', 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();
|
||
|
||
// 标准化委托地点
|
||
var standardizedLocation = CommissionStandardizer.standardizeCommissionLocation(commission.name, location);
|
||
if (standardizedLocation && standardizedLocation !== location) {
|
||
log.info('委托地点标准化: "{raw}" -> "{standard}"', location, standardizedLocation);
|
||
location = standardizedLocation;
|
||
}
|
||
|
||
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);
|
||
let scale = 2.0
|
||
let bigMapPosition
|
||
while (scale <= 5.0) {
|
||
try {
|
||
await genshin.setBigMapZoomLevel(scale);
|
||
bigMapPosition = genshin.getPositionFromBigMap();
|
||
break;
|
||
} catch {
|
||
scale += 0.1;
|
||
}
|
||
await sleep(100);
|
||
}
|
||
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 standardizedName = CommissionStandardizer.standardizeCommissionName(text);
|
||
if (standardizedName && standardizedName !== text) {
|
||
log.info('委托名称标准化: "{raw}" -> "{standard}"', text, standardizedName);
|
||
text = standardizedName;
|
||
} else {
|
||
log.info('委托名称相似度未达阈值,保持原名称: "{raw}"', 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();
|
||
|
||
// 标准化委托地点
|
||
var standardizedLocation = CommissionStandardizer.standardizeCommissionLocation(fourthCommission.name, location);
|
||
if (standardizedLocation && standardizedLocation !== location) {
|
||
log.info('委托地点标准化: "{raw}" -> "{standard}"', location, standardizedLocation);
|
||
location = standardizedLocation;
|
||
}
|
||
|
||
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);
|
||
let scale = 2.0
|
||
let bigMapPosition
|
||
while (scale <= 5.0) {
|
||
try {
|
||
await genshin.setBigMapZoomLevel(scale);
|
||
bigMapPosition = genshin.getPositionFromBigMap();
|
||
break;
|
||
} catch {
|
||
scale += 0.1;
|
||
}
|
||
await sleep(100);
|
||
}
|
||
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 [];
|
||
}
|
||
},
|
||
}; |