Files
bettergi-scripts-list/repo/js/切换账号(OCR)版本/main.js
彩虹QQ人 b3e1affaa6 JS: 切换账号解决循环跳出问题 (#1211)
* Update README.md

* Update main.js

解决循环无法跳出

* Update README.md

增加更新记录

* Update README.md

* Update manifest.json

---------

Co-authored-by: 起个名字好难 <25520958+MisakaAldrich@users.noreply.github.com>
2025-06-27 15:40:32 +08:00

171 lines
8.0 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.

const author = "彩虹QQ人";
const script_name = "切换账号(OCR)版本";
const pm_out = {
template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/pm_out.png")),
name: "pm_out.png"
};
const out_to_login = {
template: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/out_to_login.png")),
name: "out_to_login.png"
};
const login_out_account = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/login_out_account.png")),
name: "login_out_account.png"
};
const out_account = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/out_account.png")),
name: "out_account.png"
};
const login_other_account = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/login_other_account.png")),
name: "login_other_account.png"
};
const input_phone_or_email = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/input_phone_or_email.png")),
name: "input_phone_or_email.png"
};
const input_password = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/input_password.png")),
name: "input_password.png"
};
const agree = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/agree.png")),
name: "agree.png"
};
//人机验证识别图片
const login_verification = {
template:RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/verification.png")),
name: "verification.png"
};
async function clickCenter(x, y, width, height) {
let centerX = Math.round(x + width / 2);
let centerY = Math.round(y + height / 2);
await click(centerX, centerY);
await sleep(500); // 确保点击后有足够的时间等待
return { success: true, x: centerX, y: centerY };
}
async function matchImgAndClick(obj, desc, timeout = 8000) {
const start = Date.now();
let retryCount = 0; // 识别次数计数
let status = false; // 用于记录是否匹配成功
try {
while (Date.now() - start < timeout && !status) {
let result = captureGameRegion().Find(obj.template);
await sleep(500); // 短暂延迟,避免过快循环
if (result.isExist()) {
let clickResult = await clickCenter(result.x, result.y, result.width, result.height);
log.info(`【IMG】成功识别并点击 ${desc}| 耗时: ${Date.now() - start}ms`);
status = true; // 设置匹配成功状态
return {success: true, x: clickResult.x, y: clickResult.y};
}
await sleep(200); // 短暂延迟,避免过快循环
log.info(`【IMG】第${retryCount++}次识别并点击 ${desc} 失败 | 耗时: ${Date.now() - start}ms`);
}
} catch (error) {
log.error(`【IMG】${script_name}等待超时,请人工介入。===待切换账号:${settings.username}===超时原因:未找到目标 [${desc}] | 文件:${obj.name}`);
//如果有配置通知……
notification.error(`【IMG】${script_name}等待超时,请人工介入。===待切换账号:${settings.username}===超时原因:未找到目标 [${desc}] | 文件:${obj.name}`);
throw new Error(`【IMG】识别图像时发生异常: ${error.message}`);
}
return {success: false};
}
async function recognizeTextAndClick(targetText, ocrRegion, timeout = 8000) {
let start = Date.now();
let retryCount = 0; // 重试计数
let status = false; // 用于记录是否匹配成功
try {
while (Date.now() - start < timeout && !status) {
let resultList = captureGameRegion().findMulti(ocrRegion);
await sleep(500); // 短暂延迟,避免过快循环
for (let result of resultList) {
if (result.text.includes(targetText)) {
let clickResult = await clickCenter(result.x, result.y, result.width, result.height);
log.info(`【OCR】成功识别并点击 ${targetText}| 耗时: ${Date.now() - start}ms`);
status = true; // 设置匹配成功状态
return {success: true, x: clickResult.x, y: clickResult.y};
}
}
// await sleep(200); // 短暂延迟,避免过快循环
log.info(`【OCR】${targetText}失败,正在进行第 ${retryCount++} 次重试...`);
}
}catch (error) {
log.warn(`【OCR】经过多次尝试仍然无法识别文字: ”${targetText}“,尝试点击默认中心位置`);
await clickCenter(result.x, result.y, result.width, result.height);
//如果有配置通知……
notification.error(`【OCR】识别文字: “${targetText}”,发生异常`);
throw new Error(`【OCR】识别文字时发生异常: ${error.message}`);
}
return {success: false };
}
/**
* main流程开始
*/
(async function () {
setGameMetrics(1920, 1080, 1);
// 如果切换账号是第一个脚本,则有可能出现月卡选项
await genshin.blessingOfTheWelkinMoon();
await sleep(1000);
await genshin.blessingOfTheWelkinMoon();
await sleep(1000);
await genshin.returnMainUi();
await keyPress("VK_ESCAPE");
await sleep(500);
try {
await matchImgAndClick(pm_out,"左下角退出门");
await matchImgAndClick(out_to_login,"退出至登陆页面");
//这一步根据 电脑配置和当前网络情况不同休眠时间不同,建议实际运行之后,如果有日志 第x次 识别失败,就适当增加休眠时间
await sleep(9000);
await matchImgAndClick(login_out_account,"登录页的右下角退出按钮");
await matchImgAndClick(out_account,"退出当前账号");
await matchImgAndClick(login_other_account,"登录其他账号");
await sleep(1000);
await matchImgAndClick(input_phone_or_email,"填写邮箱/手机号");
await inputText(settings.username);
await sleep(1000);
await matchImgAndClick(input_password,"填写密码");
await inputText(settings.password);
await sleep(1000);
//按下回车登录账号,弹出用户协议对话框
await keyPress("VK_RETURN");
//点击回车后,等待特瓦特大门加载
await matchImgAndClick(agree,"同意用户协议");
//如果当天上下线次数过于频繁
for(let i = 1;i<=2;i++){
let verify = captureGameRegion().Find(login_verification.template);
//等待1s避免循环速度过快
await sleep(1000);
if (verify.isExist()) {
//这里可配置通知方法
notification.error(`${script_name}触发人机验证,请手动登录。===待切换UID${settings.UID}`);
log.error(`${script_name}触发人机验证,请手动登录。===待切换UID${settings.UID}`);
}
}
/**
* 根据不同网络环境和电脑配置,此操作可能会将领取月卡操作取代,但是不影响使用
* 如果发现卡在这一步请适当延长sleep时间
*/
await sleep(8000);
await recognizeTextAndClick("点击进入", RecognitionObject.Ocr(862, 966, 206, 104), 960, 540, 5000);
await sleep(12000);
//可能登录账号的时候出现月卡提醒,则先点击一次月卡。
await genshin.blessingOfTheWelkinMoon();
await sleep(1000);
await genshin.blessingOfTheWelkinMoon();
await sleep(1000);
// 如果配置了通知
notification.send("【UID" + settings.UID + "】切换成功");
}catch (error) {
log.error(`${script_name}脚本执行过程中发生错误:${error.message}`);
//如果发生错误,则发送通知
notification.error(`${script_name}脚本执行过程中发生错误:${error.message}`);
throw new Error(`${script_name}脚本执行过程中发生错误:${error.message}`);
}
})();