From cd5a04eab98e27f2ebc4ac5c5491598a76aaeab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B7=E4=B8=AA=E5=90=8D=E5=AD=97=E5=A5=BD=E9=9A=BE?= =?UTF-8?q?=E7=9A=84=E5=96=B5?= <25520958+MisakaAldrich@users.noreply.github.com> Date: Tue, 31 Mar 2026 12:38:40 +0800 Subject: [PATCH] improvement: SwitchGlobalAccountMode (#3057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 精简模式选项,移除纯键鼠 * improvement: 账户匹配条件 * feat: 处理初次登陆后退出的弹框 --- .../RecognitionObject/clear_login_info.png | Bin 0 -> 2722 bytes .../RecognitionObject/save_login_info.png | Bin 0 -> 2681 bytes repo/js/SwitchAccountMultipleMode/main.js | 178 +++--------------- .../SwitchAccountMultipleMode/manifest.json | 2 +- .../SwitchAccountMultipleMode/settings.json | 11 +- 5 files changed, 36 insertions(+), 155 deletions(-) create mode 100644 repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/clear_login_info.png create mode 100644 repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/save_login_info.png diff --git a/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/clear_login_info.png b/repo/js/SwitchAccountMultipleMode/Assets/RecognitionObject/clear_login_info.png new file mode 100644 index 0000000000000000000000000000000000000000..2b82671ed714240e61b612fbb21d35b411c52caa GIT binary patch literal 2722 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 NM?*yiMo_X2`wz+=28aLv literal 0 HcmV?d00001 diff --git a/repo/js/SwitchAccountMultipleMode/main.js b/repo/js/SwitchAccountMultipleMode/main.js index c13a6f7a2..dfa7603fe 100644 --- a/repo/js/SwitchAccountMultipleMode/main.js +++ b/repo/js/SwitchAccountMultipleMode/main.js @@ -62,7 +62,14 @@ const confirm_button = { template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/confirm_button.png")), name: "confirm_button.png" }; - +const clear_login_info = { + template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/clear_login_info.png")), + name: "clear_login_info.png" +}; +const save_login_info = { + template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/save_login_info.png")), + name: "save_login_info.png" +}; // 人机验证识别图片 const login_verification = { template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/verification.png")), @@ -419,7 +426,7 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { captureRegion.dispose(); for (let i = 0; i < resList.count; i++) { let res = resList[i]; - let user = lastLog > start ? u.matchUserRelaxed(res.text, targetUser) : u.matchUser(res.text, targetUser); + let user = u.matchUserRelaxed(res.text, targetUser) || u.matchUser(res.text, targetUser); if (user) { selectedUser = res; break; @@ -462,19 +469,15 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { log.info("当前UID与设置UID相同,无需切换账号。"); return } - if (settings.Modes == "下拉列表") { + if (settings.Modes == "下拉列表" && !settings.GlobalAccount) { await DropDownMode(); - } else if (settings.Modes == "账号+密码+键鼠") { - await KeyboardMouseMode(); - } else if (settings.Modes == "账号+密码+OCR") { + } else if (settings.Modes == "账号+密码+OCR" && !settings.GlobalAccount) { await OcrMode(); - } else if (settings.Modes == "B服切换另一个账号纯键鼠") { - await BilibiliKeyboardMouseMode(); } else if (settings.Modes == "B服切换另一个账号匹配+键鼠") { await BilibiliMatchAndKeyboardMouseMode(); - } else if (settings.Modes == "国际服+账号+密码+OCR") { + } else if (settings.Modes == "账号+密码+OCR" && settings.GlobalAccount) { await GlobalOcrMode(); - } else if (settings.Modes == "国际服+下拉列表") { + } else if (settings.Modes == "下拉列表" && settings.GlobalAccount) { await GlobalDropDownMode(); } else { log.info("尖尖哇嘎乃") @@ -511,11 +514,17 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { await matchImgAndClick(login_out_account, "登录页的右下角退出按钮"); await page.WaitForOcrMatch("切换账号"); await matchImgAndClick(confirm_switch_account, "确认切换账号"); - await sleep(500); + // 检测是否弹出保存登陆记录弹框 + if (await page.WaitForOcrMatch("退出并", new OpenCvSharp.OpenCvSharp.Rect(0, 0, 1920, 1080), 0.8, 1000)) { + await matchImgAndClick(save_login_info, "保留登陆记录"); + await sleep(500); + await matchImgAndClick(confirm_switch_account, "确认切换账号"); + await sleep(500); + } await stateChangeUser(); await sleep(500); // 换服务器操作 - if (settings.Servers) { + if (settings.Servers && (settings.Servers !== "不切换服务器" || settings.Servers == "")) { await page.WaitForOcrMatch("开始游戏"); log.info("正在更换服务器") await matchImgAndClick(switch_server, "更换服务器"); @@ -551,85 +560,6 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { notification.send("账号【" + settings.username + "】切换成功"); } - // 纯键鼠模式 对应:账号+密码+键鼠(根据分辨率确定鼠标位置) - async function KeyboardMouseMode() { - setGameMetrics(1920, 1080, 2.0); - //到达主页面 - await genshin.returnMainUi();//使用新号(无派蒙)测试,请注释掉这一行 - await sleep(1000); - - //打开派蒙页面 - keyPress("VK_ESCAPE"); - await sleep(1000); - - //退出门图标 - click(50, 1030); - await sleep(1000); - - //退出至登录页面 - click(978, 540); - await sleep(15000); - - //登录页面退出当前账号的小门图标 - click(1828, 985); - await sleep(1000); - - //点击退出当前账号 - if (Account == "否") { - //长期账号->勾选:退出并保留登录记录 - click(698, 568); - } else { - //临时账号->勾选:退出并清除登录记录 - click(698, 476); - } - await sleep(1000); - - //点击退出大按钮 - click(1107, 684); - await sleep(1500); - - //登录其他账号 - click(946, 703); - await sleep(1000); - - //点击用户名输入框 - click(815, 400); - //如果有文本,清除 - await keyPress("VK_DELETE"); - // 输入文本 - await inputText(settings.username); - await sleep(500); - - //点击密码输入框 - click(815, 480); - //如果有文本,清除 - await keyPress("VK_DELETE"); - // 输入文本 - await inputText(settings.password); - await sleep(500); - - //回车弹出协议确定框(如果有的话) - for (let i = 0; i < 3; i++) { - //三次回车,规避强制点击进入游戏(如果开启了自动开门功能,这一步是必须的,后续维护者须知0.54.0版本对开门的“进入游戏”识别是和配置组同时进行的。多次回车+短时间点击,可以规避掉鼠标乱点的问题。彩虹QQ人于2026年1月5日留。) - keyPress("VK_RETURN"); - await sleep(500); - //用户协议弹窗,点击同意,等待8.5s,增加容错 - click(1093, 593); - await sleep(500); - } - await sleep(8000);//这一步根据各自网络环境和主机配置可以适当增减 - - //进入世界循环点击,增加容错 - for (let i = 5; i > 0; i--) { - click(960, 540); - await sleep(1200);//增加容错(例如进入人机验证时) - } - //确保进入主页面 - await sleep(12000); - //点击领月卡 - await genshin.blessingOfTheWelkinMoon(); - } - // OCR模式 对应:账号+密码+OCR async function OcrMode() { const script_mode = "OCR模式"; @@ -712,63 +642,6 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { } } - // B服切换纯键鼠模式 对应:B服切换另一个账号纯键鼠(根据分辨率确定鼠标位置) - async function BilibiliKeyboardMouseMode() { - setGameMetrics(1920, 1080, 2.0); - //到达主页面 - await genshin.returnMainUi();//使用新号(无派蒙)测试,请注释掉这一行 - await sleep(1000); - - //打开派蒙页面 - keyPress("VK_ESCAPE"); - await sleep(1000); - - //退出门图标 - click(50, 1030); - await sleep(1000); - - //退出至登录页面 - click(978, 540); - await sleep(7000); - - //登录其他账号 - click(1135, 478); - await sleep(1000); - - //点击用户名 - click(963, 635); - await sleep(500); - - //点击登录 - click(963, 635); - await sleep(500); - - //登录其他账号 - click(1135, 478); - await sleep(1000); - - //取消点击用户名(确保能登录) - click(963, 400); - await sleep(500); - - //点击登录 - click(963, 635); - await sleep(500); - - //这一步根据各自网络环境和主机配置可以适当增减 - await sleep(6000); - - //进入世界循环点击,增加容错 - for (let i = 5; i > 0; i--) { - click(960, 540); - await sleep(1200);//增加容错(例如进入人机验证时) - } - //确保进入主页面 - await sleep(12000); - //点击领月卡 - await genshin.blessingOfTheWelkinMoon(); - } - // B服切换匹配+键鼠模式 对应:B服切换另一个账号匹配+键鼠 async function BilibiliMatchAndKeyboardMouseMode() { const script_mode = "B服切换匹配+键鼠模式"; @@ -879,6 +752,13 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { await matchImgAndClick(login_out_account, "登录页的右下角退出按钮"); await page.WaitForOcrMatch("切换账号"); await matchImgAndClick(confirm_switch_account, "确认切换账号"); + // 检测是否弹出保存登陆记录弹框 + if (await page.WaitForOcrMatch("退出并", new OpenCvSharp.OpenCvSharp.Rect(0, 0, 1920, 1080), 0.8, 1000)) { + await matchImgAndClick(save_login_info, "保留登陆记录"); + await sleep(500); + await matchImgAndClick(confirm_switch_account, "确认切换账号"); + await sleep(500); + } await recognizeTextAndClick("登录其他账号", RecognitionObject.Ocr(300, 200, 1200, 800), 8000); await sleep(1000); await matchImgAndClick(input_email_username, "输入邮箱/用户名"); @@ -902,7 +782,7 @@ async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) { } } // 换服务器操作 - if (settings.Servers) { + if (settings.Servers && (settings.Servers !== "不切换服务器" || settings.Servers == "")) { await page.WaitForOcrMatch("开始游戏"); log.info("正在更换服务器") await matchImgAndClick(switch_server, "更换服务器"); diff --git a/repo/js/SwitchAccountMultipleMode/manifest.json b/repo/js/SwitchAccountMultipleMode/manifest.json index b2fa7353c..b2dfef834 100644 --- a/repo/js/SwitchAccountMultipleMode/manifest.json +++ b/repo/js/SwitchAccountMultipleMode/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "切换账号多模式", - "version": "1.9", + "version": "2.0", "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 939557509..9b399cd17 100644 --- a/repo/js/SwitchAccountMultipleMode/settings.json +++ b/repo/js/SwitchAccountMultipleMode/settings.json @@ -5,11 +5,7 @@ "label": "切换模式", "options": [ "下拉列表", - "账号+密码+键鼠", "账号+密码+OCR", - "国际服+下拉列表", - "国际服+账号+密码+OCR", - "B服切换另一个账号纯键鼠", "B服切换另一个账号匹配+键鼠" ], "default": "下拉列表" @@ -24,6 +20,11 @@ "type": "input-text", "label": "密码(只保存在本地,请妥善保管)\n切换模式为下拉列表时无需填写" }, + { + "name": "GlobalAccount", + "type": "checkbox", + "label": "国际服账号请勾选" + }, { "name": "Servers", "type": "select", @@ -45,7 +46,7 @@ { "name": "temporaryAccount", "type": "select", - "label": "是否临时账号(默认:\"否\"勾选:\"退出并保留登录记录\"。\n选择\"是\"将会勾选\"退出并清除登录记录\"\n用于设配临时账号登录需求,避免占用长期账号的下拉列表快捷登录。", + "label": "(此选项已停用)是否临时账号(默认:\"否\"勾选:\"退出并保留登录记录\"。\n选择\"是\"将会勾选\"退出并清除登录记录\"\n用于设配临时账号登录需求,避免占用长期账号的下拉列表快捷登录。", "options": [ "是", "否"