diff --git a/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/out_account.png b/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/out_account.png index 4e25371ca..1d11fa5a3 100644 Binary files a/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/out_account.png and b/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/out_account.png differ diff --git a/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/quit.png b/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/quit.png deleted file mode 100644 index 1d11fa5a3..000000000 Binary files a/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/quit.png and /dev/null differ diff --git a/repo/js/SwitchAccountMultipleMode/README.md b/repo/js/SwitchAccountMultipleMode/README.md index 9f3e77556..8096d3b62 100644 --- a/repo/js/SwitchAccountMultipleMode/README.md +++ b/repo/js/SwitchAccountMultipleMode/README.md @@ -21,7 +21,9 @@ ## 3.国际服 -目前已实现国际服账号+密码登陆,并能切换服务器(亚、欧、美、台港澳),部分未尽问题尚未处理,大家多测测,更诚邀大佬们来改良 +目前已实现国际服账号+密码和下拉列表登陆,并能切换服务器(亚、欧、美、台港澳),部分未尽问题尚未处理,大家多测测,更诚邀大佬们来改良 + +国际服有个坑点是账号密码登完后,是否保存记录的弹框是在退出的时候才弹的,本脚本没做处理,用下拉列表的望周知 ## 4.账号+密码 diff --git a/repo/js/SwitchAccountMultipleMode/main.js b/repo/js/SwitchAccountMultipleMode/main.js index 4e7e72e44..c13a6f7a2 100644 --- a/repo/js/SwitchAccountMultipleMode/main.js +++ b/repo/js/SwitchAccountMultipleMode/main.js @@ -152,8 +152,8 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { // Library functions var u = {}; // utilities 工具函数集合 - u.logi = function (message, args) { log.info("[切换账号]" + message, args) }; - u.logw = function (message, args) { log.warn("[切换账号]" + message, args) }; + u.logi = function (message, args) { log.info("[下拉列表切换账号]" + message, args) }; + u.logw = function (message, args) { log.warn("[下拉列表切换账号]" + message, args) }; u.loadTemplate = function (filePath, x /* 0 if omit */, y /* 0 if omit */, w /* maxWidth if omit */, h /* maxHeight if omit */) { return RecognitionObject.TemplateMatch(file.ReadImageMatSync(filePath), x, y, w, h); }; @@ -179,21 +179,32 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { }; u.matchUserRelaxed = function (text, username) { if (typeof text !== "string" || typeof username !== "string") return false; - // Check the head - for (let i = 0; i < text.length; i++) { - const a = text[i]; - const b = username[i]; - if (a === '*') break; // Stop checking when a '*' is found in text. - if (a !== b) return false; + + // 1. 规范化:将连续的 '*' 替换为单个 '*' + const pattern = text.replace(/\*+/g, '*'); + const target = username.replace(/\*+/g, '*'); + + // 2. 如果规范化后没有通配符,则进行全等匹配 + if (!pattern.includes('*')) { + return pattern === target; } - // Check the tail - for (let i = 0; i < text.length; i++) { - const a = text[text.length - 1 - i]; - const b = username[username.length - 1 - i]; - if (a === '*') break; // Stop checking when a '*' is found in text. - if (a !== b) return false; - } - return true; + + // 3. 获取前缀和后缀 + // split('*') 会将 "abc*def" 拆分为 ["abc", "def"] + // 如果是 "*abc",拆分为 ["", "abc"];如果是 "abc*",拆分为 ["abc", ""] + const parts = pattern.split('*'); + const prefix = parts[0]; + const suffix = parts[parts.length - 1]; + + // 4. 匹配逻辑: + // - 目标字符串必须以 prefix 开头 + // - 目标字符串必须以 suffix 结尾 + // - 目标字符串的长度必须足以容纳 prefix 和 suffix (避免重叠部分的逻辑错误) + return ( + target.startsWith(prefix) && + target.endsWith(suffix) && + target.length >= (prefix.length + suffix.length) + ); }; u.waitAndFindImage = async function (asset, internal = 500, timeout = 60000) { const start = Date.now(); @@ -370,7 +381,7 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { btnLogout.DrawSelf("LogoutBtn"); btnLogout.Click(); - const assetQuitTextButton = u.loadTemplate("Assets/RecognitionObject/quit.png", 680, 380, 1220, 700); + const assetQuitTextButton = u.loadTemplate("Assets/RecognitionObject/out_account.png", 680, 380, 1220, 700); let btnQuit = await u.waitAndFindImage(assetQuitTextButton, 200); // u.logi("识别到退出按钮,点击"); // btnQuit.DrawSelf("QuitBtn"); @@ -399,8 +410,9 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { { const start = Date.now(); let lastLog = start; - while (selectedUser == null) { - await sleep(200); + // 超时8秒直接跳出让下一步报错 + while (selectedUser == null && Date.now() - start <= 8000) { + await sleep(500); let captureRegion = captureGameRegion(); let resList = captureRegion.findMulti(RecognitionObject.ocr(680, 540, 540, 500)); @@ -411,16 +423,9 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { if (user) { selectedUser = res; break; - } - } - - if (Date.now() - lastLog >= 10000) { - let elapsed = ((Date.now() - start) / 1000).toFixed(1); - u.logw("等待匹配图像已持续 {0} 秒,仍在尝试寻找账号文本:{1}", elapsed, targetUser); - lastLog = Date.now(); - for (let i = 0; i < resList.count; i++) { - let res = resList[i]; - u.logw("账户文本:{0}", res.text); + } else { + u.logw("当前匹配文本:{0}", res.text); + lastLog = Date.now(); } } } @@ -467,8 +472,10 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { await BilibiliKeyboardMouseMode(); } else if (settings.Modes == "B服切换另一个账号匹配+键鼠") { await BilibiliMatchAndKeyboardMouseMode(); - } else if (settings.Modes == "国际服账号+密码+OCR") { + } else if (settings.Modes == "国际服+账号+密码+OCR") { await GlobalOcrMode(); + } else if (settings.Modes == "国际服+下拉列表") { + await GlobalDropDownMode(); } else { log.info("尖尖哇嘎乃") } @@ -490,6 +497,60 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { } + // 国际服下拉列表模式 + async function GlobalDropDownMode() { + const script_mode = "国际服下拉列表模式"; + const page = new BvPage(); + setGameMetrics(1920, 1080, 1); + const isInGame = await waitAndDetermineCurrentView(); + if (isInGame) { + await stateReturnToGenshinGate(); + await sleep(1000); + } + await page.WaitForOcrMatch("开始游戏"); + await matchImgAndClick(login_out_account, "登录页的右下角退出按钮"); + await page.WaitForOcrMatch("切换账号"); + await matchImgAndClick(confirm_switch_account, "确认切换账号"); + await sleep(500); + await stateChangeUser(); + await sleep(500); + // 换服务器操作 + if (settings.Servers) { + await page.WaitForOcrMatch("开始游戏"); + log.info("正在更换服务器") + await matchImgAndClick(switch_server, "更换服务器"); + let serversMatched = true; + if (settings.Servers == "Asia") { + await matchImgAndClick(asia_server, "亚服"); + } else if (settings.Servers == "Europe") { + await matchImgAndClick(europe_server, "欧服"); + } else if (settings.Servers == "America") { + await matchImgAndClick(america_server, "美服"); + } else if (settings.Servers == "TW,HK,MO") { + await matchImgAndClick(twhkmo_server, "台港澳"); + } else { + log.info("尖尖哇嘎乃") + serversMatched = false; + } + if (serversMatched) { + await matchImgAndClick(confirm_button, "确认换服"); + } + } + await keyPress("VK_ESCAPE"); + await page.WaitForOcrMatch("开始游戏"); + await click(960, 640); + await page.Wait(5000); + log.info('等待提瓦特大门加载'); + await page.WaitForOcrMatch("点击进入"); + await click(960, 640); + // 可能登录账号的时候出现月卡提醒,则先点击一次月卡。 + await genshin.blessingOfTheWelkinMoon(); + await page.Wait(1000); + await genshin.returnMainUi(); + // 如果配置了通知 + notification.send("账号【" + settings.username + "】切换成功"); + } + // 纯键鼠模式 对应:账号+密码+键鼠(根据分辨率确定鼠标位置) async function KeyboardMouseMode() { setGameMetrics(1920, 1080, 2.0); @@ -871,6 +932,7 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { await click(960, 640); // 可能登录账号的时候出现月卡提醒,则先点击一次月卡。 await genshin.blessingOfTheWelkinMoon(); + await page.Wait(1000); await genshin.returnMainUi(); // 如果配置了通知 notification.send("账号【" + settings.username + "】切换成功"); diff --git a/repo/js/SwitchAccountMultipleMode/manifest.json b/repo/js/SwitchAccountMultipleMode/manifest.json index 52f510934..b2fa7353c 100644 --- a/repo/js/SwitchAccountMultipleMode/manifest.json +++ b/repo/js/SwitchAccountMultipleMode/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "切换账号多模式", - "version": "1.8", + "version": "1.9", "bgi_version": "0.57.0", "description": "多种模式的切换账号,有下拉列表、填写账号密码OCR操作或键鼠操作,目前支持B服/国际服但不完整\n免责申明:所有的账号密码均保存在本地,请使用者妥善保管账号密码,请勿外泄账号密码。若因使用此脚本导致的账号泄露、封禁问题与脚本作者无关。", "tags": [ diff --git a/repo/js/SwitchAccountMultipleMode/settings.json b/repo/js/SwitchAccountMultipleMode/settings.json index 9b3b51592..939557509 100644 --- a/repo/js/SwitchAccountMultipleMode/settings.json +++ b/repo/js/SwitchAccountMultipleMode/settings.json @@ -7,16 +7,17 @@ "下拉列表", "账号+密码+键鼠", "账号+密码+OCR", + "国际服+下拉列表", + "国际服+账号+密码+OCR", "B服切换另一个账号纯键鼠", - "B服切换另一个账号匹配+键鼠", - "国际服账号+密码+OCR" + "B服切换另一个账号匹配+键鼠" ], "default": "下拉列表" }, { "name": "username", "type": "input-text", - "label": "账号(只保存在本地,请妥善保管)\n下拉列表手机号格式:114******98\n下拉列表邮箱格式:11****1@919.com\n账号密码模式请输入完整的手机号或邮箱" + "label": "账号(只保存在本地,请妥善保管)\n下拉列表手机号格式:114******98\n下拉列表邮箱格式:11****1@919.com\n下拉列表第三方登陆格式:apple\n账号+密码模式请输入完整的手机号或邮箱" }, { "name": "password",