Files
bettergi-scripts-list/repo/js/AutoSwitchRoles/main.js
Tool_tingsu 15e958c018 js 配对界面切换角色 更新清理角色缓存 (#1513)
* Delete repo/pathing/地方特产/枫丹/苍晶螺/13-苍晶螺-自然哲学学院2-7个.json

* Add files via upload

* 自动修复 JSON 格式和版本号 [ci skip]

* Update 13-苍晶螺-自然哲学学院2-7个.json

* 123

* 自动修复 JSON 格式和版本号 [ci skip]

* 1

---------

Co-authored-by: GitHub Actions Bot <actions@github.com>
2025-08-08 22:32:51 +08:00

400 lines
15 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.

// 滚动页面函数
async function scrollPage(totalDistance, stepDistance = 10, delayMs = 5) {
moveMouseTo(400, 750);
await sleep(50);
leftButtonDown();
const steps = Math.ceil(totalDistance / stepDistance);
for (let j = 0; j < steps; j++) {
const remainingDistance = totalDistance - j * stepDistance;
const moveDistance = remainingDistance < stepDistance ? remainingDistance : stepDistance;
moveMouseBy(0, -moveDistance);
await sleep(delayMs);
}
await sleep(700);
leftButtonUp();
await sleep(100);
}
// 读取别名文件
function readAliases() {
const combatText = file.ReadTextSync('combat_avatar.json');
const combatData = JSON.parse(combatText);
const aliases = {};
for (const character of combatData) {
if (character.alias && character.name) {
for (const alias of character.alias) {
aliases[alias] = character.name;
}
}
}
return aliases;
}
(async function () {
// 设置分辨率
setGameMetrics(1920, 1080, 1);
// 返回主界面
await genshin.returnMainUi();
//切换配对
if (settings.switchPartyName) {
await genshin.switchParty(settings.switchPartyName);
}
const option = settings.option;
if (option === '推荐-非快速配对模式 @Tool_tingsu') {
// main.js 的逻辑
const positionCoordinates = [
[460, 538],
[792, 538],
[1130, 538],
[1462, 538]
];
// 读取别名
const aliases = readAliases();
const positionSettings = [
settings.position1,
settings.position2,
settings.position3,
settings.position4
].map(input => {
if (input && input.trim()!== "") {
const actualName = aliases[input] || input;
log.info(`设置对应号位为【${input}】,切换角色为【${actualName}`);
return actualName;
}
return null;
});
// 识别对象定义
const roTeamConfig = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/队伍配置.png`), 0, 0, 1920, 1080);
const roReplace = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/更换.png`), 0, 0, 1920, 1080);
const roJoin = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/加入.png`), 0, 0, 1920, 1080);
let openPairingTries = 0;
let totalOpenPairingTries = 0;
// 在进入角色切换逻辑前进行检测,如果所有角色设置均为空则直接退出
if (positionSettings.every((item) =>!item)) {
log.info("未设置任何角色,跳过切换队伍步骤");
await genshin.returnMainUi();
return;
}
async function openPairingInterface() {
while (openPairingTries < 3) {
keyPress("l");
await sleep(3500);
const teamConfigResult = captureGameRegion().find(roTeamConfig);
if (teamConfigResult.isExist()) {
openPairingTries = 0;
return true;
}
openPairingTries++;
totalOpenPairingTries++;
}
if (totalOpenPairingTries < 6) {
await genshin.tp("2297.630859375", "-824.5517578125");
openPairingTries = 0;
return openPairingInterface();
} else {
log.error("无法打开配对界面,任务结束");
return false;
}
}
if (!(await openPairingInterface())) {
return;
}
// 角色切换逻辑
for (let i = 0; i < positionSettings.length; i++) {
let rolenum = i + 1;
const selectedCharacter = positionSettings[i];
if (!selectedCharacter) {
log.info(`未设置${rolenum}号位角色,跳过`);
continue;
}
const [x, y] = positionCoordinates[i];
click(x, y);
log.info(`开始设置${rolenum}号位角色`);
await sleep(1000);
let characterFound = false;
let pageTries = 0;
// 最多尝试滚动页面20次
while (pageTries < 20) {
// 尝试识别所有可能的角色文件名
for (let num = 1; ; num++) {
const paddedNum = num.toString().padStart(2, "0");
const characterFileName = `${selectedCharacter}${paddedNum}`;
try {
const characterRo = RecognitionObject.TemplateMatch(
file.ReadImageMatSync(`Assets/characterimage/${characterFileName}.png`),
0,
0,
1920,
1080
);
const characterResult = captureGameRegion().find(characterRo);
if (characterResult.isExist()) {
log.info(`已找到角色${selectedCharacter}`);
// 计算向右偏移70像素、向下偏移70像素的位置
const targetX = characterResult.x + 35;
const targetY = characterResult.y + 35;
// 边界检查,确保坐标在屏幕范围内
const safeX = Math.min(Math.max(targetX, 0), 1920);
const safeY = Math.min(Math.max(targetY, 0), 1080);
click(safeX, safeY);
await sleep(500); // 点击角色后等待0.5秒
characterFound = true;
break;
}
} catch (error) {
// 如果文件不存在,跳出循环
break;
}
}
if (characterFound) {
break;
}
// 如果不是最后一次尝试,尝试滚动页面
if (pageTries < 15) {
log.info("当前页面没有目标角色,滚动页面");
await scrollPage(200); // 滚动距离可根据实际情况调整
}
pageTries++;
}
if (!characterFound) {
log.error(`未找到【${selectedCharacter}`);
continue;
}
// 识别"更换"或"加入"按钮
const replaceResult = captureGameRegion().find(roReplace);
const joinResult = captureGameRegion().find(roJoin);
if (replaceResult.isExist() || joinResult.isExist()) {
await sleep(300);
click(68, 1020);
keyPress("VK_LBUTTON");
await sleep(500);
} else {
log.error(`该角色已在队伍中,无需切换`);
await sleep(300);
keyPress("VK_ESCAPE");
await sleep(500);
}
await sleep(500);
}
} else if (option === '存在bug-快速配对模式 @兩夢三醒') {
// 切换队伍
if (!!settings.partyName) {
try {
log.info("正在尝试切换至" + settings.partyName);
if (!await genshin.switchParty(settings.partyName)) {
log.info("切换队伍失败,前往七天神像重试");
await genshin.tpToStatueOfTheSeven();
await genshin.switchParty(settings.partyName);
}
} catch {
log.error("队伍切换失败,可能处于联机模式或其他不可切换状态");
notification.error(`队伍切换失败,可能处于联机模式或其他不可切换状态`);
await genshin.returnMainUi();
}
} else {
await genshin.returnMainUi();
}
// 角色位置坐标
const positionCoordinates = [
[107, 190],
[254, 188],
[414, 189],
[554, 198],
];
// 读取别名
const aliases = readAliases();
// 获取需要切换的角色,并进行别名替换
const positionSettings = [settings.position1, settings.position2, settings.position3, settings.position4].map(input => {
if (input && input.trim()!== "") {
const actualName = aliases[input] || input;
log.info(`设置对应号位为【${input}】,切换角色为【${actualName}`);
return actualName;
}
return null;
});
// 识别对象定义
const roTeamConfig = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/队伍配置.png`), 0, 0, 1920, 1080);
// const roReplace = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/更换.png`), 0, 0, 1920, 1080);
// const roJoin = RecognitionObject.TemplateMatch(file.ReadImageMatSync(`Assets/RecognitionObject/加入.png`), 0, 0, 1920, 1080);
let openPairingTries = 0;
let totalOpenPairingTries = 0;
// 在进入角色切换逻辑前进行检测,如果所有角色设置均为空则直接退出
if (positionSettings.every((item) =>!item)) {
log.info("未设置任何角色,跳过切换队伍步骤");
await genshin.returnMainUi();
return;
}
// 打开配对界面
async function openPairingInterface() {
while (openPairingTries < 3) {
keyPress("l");
await sleep(3500);
const teamConfigResult = captureGameRegion().find(roTeamConfig);
if (teamConfigResult.isExist()) {
openPairingTries = 0;
return true;
}
openPairingTries++;
totalOpenPairingTries++;
}
if (totalOpenPairingTries < 6) {
await genshin.tp("2297.630859375", "-824.5517578125");
openPairingTries = 0;
return openPairingInterface();
} else {
log.error("无法打开配对界面,任务结束");
return false;
}
}
if (!(await openPairingInterface())) {
return;
}
// 需要取消选择的数量
const ocrRegions = [
[340, 181, 315, 330],
[655, 181, 315, 330],
[970, 181, 315, 330],
[1285, 181, 315, 330],
];
let regionsWithTextCount = 0;
let captureRegion = captureGameRegion();
for (const [x, y, w, h] of ocrRegions) {
const regionOcrResult = captureRegion.findMulti(RecognitionObject.ocr(x, y, w, h));
if (regionOcrResult.count > 0) {
regionsWithTextCount++;
}
}
log.info(`有文字的区域数量为: ${regionsWithTextCount}`);
// 角色切换逻辑
click(1212, 1020); // 点击快速编队
await sleep(1000);
log.info(`点击快速编队`);
for (let i = 0; i < regionsWithTextCount; i++) {
if (i >= positionCoordinates.length) {
break;
}
const [x, y] = positionCoordinates[i];
click(x, y);
await sleep(1000);
log.info(`取消选择${x},${y}位置的角色`);
}
for (let i = 0; i < positionSettings.length; i++) {
let rolenum = i + 1;
const selectedCharacter = positionSettings[i];
const [x, y] = positionCoordinates[i];
click(800, 123);
await sleep(1000);
if (!selectedCharacter) {
log.info(`未设置${rolenum}号位角色保持原来的选择可能存在未知bug`);
click(x, y);
await sleep(1000);
continue;
}
log.info(`开始设置${rolenum}号位角色`);
log.info(`目标角色为:【${selectedCharacter}`);
let characterFound = false;
let pageTries = 0;
// 最多尝试滚动页面20×2次
while (pageTries < 40) {
// 尝试识别所有可能的角色文件名
for (let num = 1; ; num++) {
const paddedNum = num.toString().padStart(2, "0");
const characterFileName = `${selectedCharacter}${paddedNum}`;
try {
const characterRo = RecognitionObject.TemplateMatch(
file.ReadImageMatSync(`Assets/characterimage/${characterFileName}.png`),
0,
0,
1920,
1080
);
const characterResult = captureGameRegion().find(characterRo);
if (characterResult.isExist()) {
log.info(`已找到角色【${selectedCharacter}`);
// 计算向右偏移70像素、向下偏移70像素的位置
const targetX = characterResult.x + 35;
const targetY = characterResult.y + 35;
// 边界检查,确保坐标在屏幕范围内
const safeX = Math.min(Math.max(targetX, 0), 1920);
const safeY = Math.min(Math.max(targetY, 0), 1080);
click(safeX, safeY);
await sleep(500); // 点击角色后等待0.5秒
characterFound = true;
break;
}
} catch (error) {
// 如果文件不存在,跳出循环
break;
}
}
if (characterFound) {
break;
}
// 如果不是最后一次尝试,尝试滚动页面
if (pageTries < 30) {
log.info(`当前页面没有目标角色【${selectedCharacter}】,滚动页面`);
await scrollPage(200); // 滚动距离可根据实际情况调整
}
if (pageTries == 15) {
log.info("滚动完毕,重置位置,再试一次");
click(800, 123);
await sleep(1000);
}
pageTries++;
}
if (!characterFound) {
log.error(`未找到【${selectedCharacter}】,尝试选择原来的角色`);
click(800, 123);
await sleep(1000);
click(x, y);
await sleep(1000);
continue;
}
}
// 点击保存
click(427, 1024);
await sleep(1000);
keyPress("VK_LBUTTON");
await sleep(500);
}
// 返回主界面
await genshin.returnMainUi();
//清空角色缓存
genshin.ClearPartyCache();
})();