mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-25 04:59:52 +08:00
feat(auto-tool): 添加队伍切换功能并支持元素匹配
- 在SevenElement中新增矿物元素类型 - 实现基于路径的元素匹配和队伍切换逻辑 - 添加SwitchTeam工具模块实现队伍配置功能 - 集成OCR识别和图像匹配的队伍切换机制 - 支持自动翻页查找目标队伍功能 - 实现七天神像传送和队伍缓存清理功能
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Leave Button.png
Normal file
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Leave Button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Quick Setup Button.png
Normal file
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Quick Setup Button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Bottom.png
Normal file
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Bottom.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 307 B |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Top.png
Normal file
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Top.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 517 B |
@@ -40,8 +40,9 @@ const config_list = {
|
||||
}
|
||||
|
||||
const SevenElement = {
|
||||
SevenElements: ['火', '水', '风', '雷', '草', '冰', '岩'],
|
||||
SevenElements: ['矿物', '火', '水', '风', '雷', '草', '冰', '岩'],
|
||||
SevenElementsMap: new Map([
|
||||
['矿物', []],
|
||||
['火', []],
|
||||
['水', ['海露花']],
|
||||
['风', ['蒲公英籽']],
|
||||
@@ -51,6 +52,8 @@ const SevenElement = {
|
||||
['岩', []],
|
||||
]),
|
||||
}
|
||||
|
||||
|
||||
const team = {
|
||||
current: undefined,
|
||||
currentElementName: undefined,
|
||||
@@ -302,6 +305,7 @@ async function getValueByMultiCheckboxName(name) {
|
||||
async function init() {
|
||||
let settingsConfig = await initSettings();
|
||||
let utils = [
|
||||
"SwitchTeam",
|
||||
"uid",
|
||||
]
|
||||
for (let util of utils) {
|
||||
@@ -671,6 +675,30 @@ async function runPath(path, stopKey = AUTO_STOP) {
|
||||
log.info(`[{mode}] 路径已执行: {path},跳过执行`, settings.mode, path)
|
||||
return
|
||||
}
|
||||
|
||||
const entry = [...SevenElement.SevenElementsMap.entries()].find(([key, val]) => {
|
||||
return val.some(item => path.includes(`\\${item}\\`));
|
||||
});
|
||||
if (entry) {
|
||||
const [key, val] = entry;
|
||||
const index = SevenElement.SevenElements.indexOf(key);
|
||||
const teamName = team.SevenElements.length > index && index >= 0 ?
|
||||
team.SevenElements[index] : undefined;
|
||||
|
||||
if (!teamName || teamName === "") {
|
||||
log.debug(`[{mode}] 没有设置队伍: {teamName},跳过切换`, settings.mode, teamName);
|
||||
} else if (team.current === teamName) {
|
||||
log.debug(`[{mode}] 当前队伍为: {teamName},无需切换`, settings.mode, teamName);
|
||||
} else {
|
||||
log.info(`[{mode}] 检测到需要: {key},切换至{val}`, settings.mode, key, teamName);
|
||||
const teamSwitch = await switchUtil.SwitchPartyMain(teamName);
|
||||
if (teamSwitch) {
|
||||
team.current = teamSwitch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
const one = JSON.parse(file.readTextSync(path))
|
||||
if (one.info && one.info.description.includes("请配置好战斗策略")) {
|
||||
|
||||
@@ -49,13 +49,13 @@
|
||||
{
|
||||
"name": "teamSevenElements",
|
||||
"type": "input-text",
|
||||
"label": "7元素队伍配置 按 火,水,风,雷,草,冰,岩 该顺序填写",
|
||||
"label": "队伍配置 按 `矿物,火,水,风,雷,草,冰,岩` 该顺序填写",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "choose_best",
|
||||
"type": "checkbox",
|
||||
"label": "择优模式",
|
||||
"label": "择优模式(默认关闭 优先跑之前没跑过的)",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
@@ -66,6 +66,6 @@
|
||||
{
|
||||
"name": "autoSkip",
|
||||
"type": "input-text",
|
||||
"label": "自动跳过运行快捷键(独立BGI的快捷键请勿冲突)"
|
||||
"label": "【测试功能-无效配置】自动跳过运行快捷键(独立BGI的快捷键请勿冲突)"
|
||||
}
|
||||
]
|
||||
210
repo/js/FullyAutoAndSemiAutoTools/utils/SwitchTeam.js
Normal file
210
repo/js/FullyAutoAndSemiAutoTools/utils/SwitchTeam.js
Normal file
@@ -0,0 +1,210 @@
|
||||
// Party Setup
|
||||
const QuickSetupButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Quick Setup Button.png"), 1100, 900, 400, 180);
|
||||
const ConfigureTeamButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Configure Team Button.png"), 0, 900, 200, 180);
|
||||
const ConfirmDeployButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Confirm Deploy Button.png"), 0, 900, 1920, 180);
|
||||
// Slider
|
||||
const LeftSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 650, 50, 100, 100);
|
||||
const LeftSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 650, 100, 100, 900);
|
||||
const MiddleSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 1250, 50, 100, 200);
|
||||
const MiddleSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 1250, 100, 100, 900);
|
||||
const RightSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 1750, 100, 100, 100);
|
||||
const RightSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 1750, 100, 100, 900);
|
||||
|
||||
// 翻页
|
||||
async function pageDown(SliderBottomRo) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let SliderBottom = captureRegion.find(SliderBottomRo);
|
||||
captureRegion.dispose();
|
||||
if (SliderBottom.isExist()) {
|
||||
log.info("当前页面已识别&点击完毕,向下滑动");
|
||||
// log.info("滑块当前位置:({x},{y},{h},{w})", SliderBottom.x, SliderBottom.y, SliderBottom.Width, SliderBottom.Height);
|
||||
click(Math.ceil(SliderBottom.x + SliderBottom.Width / 2), Math.ceil(SliderBottom.y + SliderBottom.Height * 2));
|
||||
await moveMouseTo(0, 0);
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// 滑条顶端
|
||||
async function pageTop(SliderTopRo) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let SliderTop = captureRegion.find(SliderTopRo);
|
||||
captureRegion.dispose();
|
||||
if (SliderTop.isExist()) {
|
||||
log.info("识别到滑条顶端位置:({x},{y},{h},{w})", SliderTop.x, SliderTop.y, SliderTop.Width, SliderTop.Height);
|
||||
await moveMouseTo(Math.ceil(SliderTop.x + SliderTop.Width / 2), Math.ceil(SliderTop.y + SliderTop.Height * 1));
|
||||
leftButtonDown();
|
||||
await sleep(1000);
|
||||
leftButtonUp();
|
||||
await moveMouseTo(0, 0);
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// 切换队伍
|
||||
async function SwitchParty(partyName) {
|
||||
let ConfigureStatue = false;
|
||||
|
||||
let foundQuickSetup = false;
|
||||
for (let j = 0; j < 2; j++) { // 尝试两次
|
||||
keyPress("VK_L");
|
||||
await sleep(2000);
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let QuickSetupButton = captureRegion.find(QuickSetupButtonRo);
|
||||
captureRegion.dispose();
|
||||
if (QuickSetupButton.isExist()) {
|
||||
log.info("已进入队伍配置页面");
|
||||
foundQuickSetup = true;
|
||||
break;
|
||||
} else {
|
||||
await sleep(1000);
|
||||
}
|
||||
}
|
||||
if (foundQuickSetup) {
|
||||
break; // 第一次找到就退出循环
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundQuickSetup) {
|
||||
log.error("两次尝试都未能进入队伍配置页面");
|
||||
return false;
|
||||
}
|
||||
// 识别当前队伍
|
||||
let captureRegion = captureGameRegion();
|
||||
let resList = captureRegion.findMulti(RecognitionObject.ocr(100, 900, 300, 180));
|
||||
captureRegion.dispose();
|
||||
let currentPartyFound = false;
|
||||
|
||||
for (let i = 0; i < resList.count; i++) {
|
||||
let res = resList[i];
|
||||
log.info("当前队伍名称位置:({x},{y},{w},{h}), 识别结果:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
if (res.text.includes(partyName)) {
|
||||
log.info("当前队伍即为目标队伍,无需切换");
|
||||
notification.send(`当前队伍即为目标队伍:${partyName},无需切换`);
|
||||
keyPress("VK_ESCAPE");
|
||||
await sleep(500);
|
||||
currentPartyFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!currentPartyFound) {
|
||||
await sleep(1000);
|
||||
let captureRegion = captureGameRegion();
|
||||
let ConfigureTeamButton = captureRegion.find(ConfigureTeamButtonRo);
|
||||
captureRegion.dispose();
|
||||
if (ConfigureTeamButton.isExist()) {
|
||||
log.info("识别到配置队伍按钮");
|
||||
ConfigureTeamButton.click();
|
||||
await sleep(500);
|
||||
await pageTop(LeftSliderTopRo);
|
||||
|
||||
for (let p = 0; p < 4; p++) {
|
||||
// 识别当前页
|
||||
let captureRegion = captureGameRegion();
|
||||
let resList = captureRegion.findMulti(RecognitionObject.ocr(0, 100, 400, 900));
|
||||
captureRegion.dispose();
|
||||
for (let i = 0; i < resList.count; i++) {
|
||||
let res = resList[i];
|
||||
if (settings.enableDebug) {
|
||||
log.info("文本位置:({x},{y},{w},{h}), 识别内容:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
}
|
||||
if (res.text.includes(partyName)) {
|
||||
log.info("目标队伍位置:({x},{y},{w},{h}), 识别结果:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
click(Math.ceil(res.x + 360), res.y + Math.ceil(res.Height / 2));
|
||||
|
||||
// 找到目标队伍,点击确定、部署
|
||||
await sleep(1500);
|
||||
let ConfirmButtonCaptureRegion = captureGameRegion();
|
||||
let ConfirmButton = ConfirmButtonCaptureRegion.find(ConfirmDeployButtonRo);
|
||||
ConfirmButtonCaptureRegion.dispose();
|
||||
if (ConfirmButton.isExist()) {
|
||||
log.info("识别到确定按钮:({x},{y},{w},{h})", ConfirmButton.x, ConfirmButton.y, ConfirmButton.Width, ConfirmButton.Height);
|
||||
ConfirmButton.click();
|
||||
}
|
||||
await sleep(1500);
|
||||
let DeployButtonCaptureRegion = captureGameRegion();
|
||||
let DeployButton = DeployButtonCaptureRegion.find(ConfirmDeployButtonRo);
|
||||
DeployButtonCaptureRegion.dispose();
|
||||
if (DeployButton.isExist()) {
|
||||
log.info("识别到部署按钮:({x},{y},{w},{h})", DeployButton.x, DeployButton.y, DeployButton.Width, DeployButton.Height);
|
||||
DeployButton.click();
|
||||
notification.send(`寻找到目标队伍:${partyName}`);
|
||||
ConfigureStatue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ConfigureStatue) {
|
||||
await genshin.returnMainUi();
|
||||
break;
|
||||
} else {
|
||||
await pageDown(LeftSliderBottomRo);
|
||||
}
|
||||
}
|
||||
if (!ConfigureStatue) {
|
||||
// 没找到指定队伍名称的队伍,抛出异常
|
||||
log.error(`没有找到指定队伍名称:${partyName}`);
|
||||
notification.error(`没有找到指定队伍名称:${partyName}`);
|
||||
await genshin.returnMainUi();
|
||||
throw new Error(`没有找到指定队伍名称:${partyName}`);
|
||||
}
|
||||
} else {
|
||||
// 没找到配置队伍按钮,抛出异常
|
||||
log.error("没有找到配置队伍按钮");
|
||||
notification.error("没有找到配置队伍按钮");
|
||||
await genshin.returnMainUi();
|
||||
throw new Error("没有找到配置队伍按钮");
|
||||
}
|
||||
} else {
|
||||
// 当前队伍就是目标队伍,设置成功状态
|
||||
ConfigureStatue = true;
|
||||
}
|
||||
return ConfigureStatue;
|
||||
}
|
||||
|
||||
async function SwitchPartyMain(partyName, disableGoStatue) {
|
||||
if (!!partyName) {
|
||||
try {
|
||||
if (!disableGoStatue) {
|
||||
// 强制去七天神像换队
|
||||
log.info("强制传送到七天神像切换队伍");
|
||||
await genshin.TpToStatueOfTheSeven();
|
||||
log.info("正在尝试切换至" + partyName);
|
||||
await SwitchParty(partyName);
|
||||
} else {
|
||||
// 先尝试在当前位置换队
|
||||
await genshin.returnMainUi();
|
||||
log.info("正在尝试切换至" + partyName);
|
||||
let switchResult = await SwitchParty(partyName);
|
||||
|
||||
if (!switchResult) {
|
||||
// 如果当前位置换队失败,去七天神像再试一次
|
||||
log.info("当前位置换队失败,传送到七天神像重试");
|
||||
await genshin.TpToStatueOfTheSeven();
|
||||
log.info("正在七天神像重新尝试切换至" + partyName);
|
||||
await SwitchParty(partyName);
|
||||
}
|
||||
}
|
||||
genshin.clearPartyCache();
|
||||
return partyName
|
||||
} catch (error) {
|
||||
log.error("队伍切换失败:" + error.message);
|
||||
notification.error("队伍切换失败:" + error.message);
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
} else {
|
||||
log.error("没有设置切换队伍");
|
||||
notification.error("没有设置切换队伍");
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
}
|
||||
this.switchUtil={
|
||||
SwitchPartyMain
|
||||
}
|
||||
// /**
|
||||
// * @returns {Promise<void>}
|
||||
// */
|
||||
//
|
||||
// (async function () {
|
||||
// await SwitchPartyMain(settings.partyName, settings.disableGoStatue);
|
||||
// })();
|
||||
Reference in New Issue
Block a user