Files

155 lines
5.0 KiB
JavaScript

(async function () {
setGameMetrics(1920, 1080, 1);
const STATUS_FILE = "status.json";
const requestId = String(settings.requestId || "").trim();
let lastCandidates = [];
function writeStatus(state, data) {
const payload = Object.assign({
state: state,
request_id: requestId,
party_name: "",
candidates: lastCandidates,
message: "",
updated_at: new Date().toISOString()
}, data || {});
file.writeTextSync(STATUS_FILE, JSON.stringify(payload, null, 2));
}
function normalizeText(value) {
return String(value || "").replace(/\s+/g, "").trim();
}
function isPartyNameCandidate(text) {
if (!text || text.length > 20) {
return false;
}
const ignored = [
"队伍配置",
"快速编队",
"元素共鸣",
"调整队伍",
"当前队伍",
"部署",
"出战",
"详情"
];
if (ignored.some((label) => text === label || text.includes(label))) {
return false;
}
return !/^(esc|enter|space|l|f\d{1,2})$/i.test(text);
}
function isPartyPageOpen() {
const capture = captureGameRegion();
try {
const results = capture.findMulti(RecognitionObject.ocr(0, 0, 720, 180));
for (let index = 0; index < results.count; index++) {
const text = normalizeText(results[index].text);
if (text.includes("队伍配置")) {
return true;
}
}
return false;
} finally {
capture.dispose();
}
}
function recognizePartyNameCandidates() {
const capture = captureGameRegion();
try {
const results = capture.findMulti(RecognitionObject.ocr(0, 940, 520, 140));
const candidates = [];
for (let index = 0; index < results.count; index++) {
const result = results[index];
const text = normalizeText(result.text);
log.info(
"当前队伍名称候选位置:({x},{y},{w},{h}), 识别结果:{text}",
result.x,
result.y,
result.Width,
result.Height,
text
);
if (isPartyNameCandidate(text)) {
candidates.push({
text: text,
x: Number(result.x || 0),
y: Number(result.y || 0)
});
}
}
candidates.sort((left, right) => {
if (left.x !== right.x) {
return left.x - right.x;
}
return right.y - left.y;
});
return candidates.filter(
(candidate, index, values) =>
values.findIndex((value) => value.text === candidate.text) === index
);
} finally {
capture.dispose();
}
}
async function openPartyPageAndRead() {
for (let attempt = 0; attempt < 3; attempt++) {
keyPress("VK_L");
await sleep(2200);
for (let scan = 0; scan < 4; scan++) {
if (isPartyPageOpen()) {
const candidates = recognizePartyNameCandidates();
if (candidates.length > 0) {
return candidates;
}
}
await sleep(600);
}
keyPress("VK_ESCAPE");
await sleep(800);
await genshin.returnMainUi();
}
return [];
}
try {
if (!requestId) {
throw new Error("读取请求标识为空");
}
writeStatus("running");
await genshin.returnMainUi();
const candidates = await openPartyPageAndRead();
lastCandidates = candidates.map((candidate) => candidate.text);
if (candidates.length === 0) {
throw new Error("未识别到当前队伍名称,请确认游戏处于可打开配队界面的状态");
}
if (candidates.length > 1) {
throw new Error("识别到多个队伍名称候选:" + lastCandidates.join("、"));
}
const partyName = candidates[0].text;
await genshin.returnMainUi();
await sleep(500);
writeStatus("success", {
party_name: partyName,
candidates: lastCandidates
});
log.info("当前队伍名称读取成功: {name}", partyName);
} catch (error) {
try {
await genshin.returnMainUi();
} catch (_) {
}
const message = String(error && error.message ? error.message : error);
writeStatus("error", {
candidates: lastCandidates,
message: message
});
log.error("当前队伍名称读取失败: {message}", message);
}
})();