Update Live-streaming code (auto-daily features)
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
(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);
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "直播系统读取当前队伍",
|
||||
"version": "1.0.0",
|
||||
"bgi_version": "0.63.0",
|
||||
"description": "读取游戏当前队伍预设名称并通过状态文件返回给直播联动系统",
|
||||
"authors": [
|
||||
{
|
||||
"name": "BGI直播项目"
|
||||
}
|
||||
],
|
||||
"settings_ui": "settings.json",
|
||||
"main": "main.js",
|
||||
"saved_files": [
|
||||
"status.json"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"name": "requestId",
|
||||
"type": "input-text",
|
||||
"label": "读取请求标识",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user