diff --git a/repo/js/博士周本充能/222.json b/repo/js/博士周本充能/222.json new file mode 100644 index 000000000..f215f1354 --- /dev/null +++ b/repo/js/博士周本充能/222.json @@ -0,0 +1 @@ +{"macroEvents":[{"type":2,"mouseX":1269,"mouseY":747,"time":2016},{"type":2,"mouseX":1265,"mouseY":774,"time":2047},{"type":2,"mouseX":1258,"mouseY":816,"time":2078},{"type":2,"mouseX":1253,"mouseY":840,"time":2110},{"type":2,"mouseX":1250,"mouseY":864,"time":2141},{"type":2,"mouseX":1248,"mouseY":891,"time":2172},{"type":2,"mouseX":1248,"mouseY":906,"time":2203},{"type":2,"mouseX":1248,"mouseY":917,"time":2235},{"type":2,"mouseX":1251,"mouseY":925,"time":2266},{"type":4,"mouseX":1251,"mouseY":925,"mouseButton":"Left","time":2422},{"type":5,"mouseX":1251,"mouseY":925,"mouseButton":"Left","time":2500},{"type":0,"keyCode":87,"mouseX":0,"mouseY":0,"time":3375},{"type":4,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":3594},{"type":5,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":3719},{"type":4,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":4094},{"type":5,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":4188},{"type":1,"keyCode":87,"mouseX":0,"mouseY":0,"time":4281},{"type":0,"keyCode":83,"mouseX":0,"mouseY":0,"time":4625},{"type":4,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":5078},{"type":5,"mouseX":1279,"mouseY":718,"mouseButton":"Right","time":5172},{"type":0,"keyCode":65,"mouseX":0,"mouseY":0,"time":5906},{"type":1,"keyCode":83,"mouseX":0,"mouseY":0,"time":5969},{"type":1,"keyCode":65,"mouseX":0,"mouseY":0,"time":8235},{"type":0,"keyCode":65,"mouseX":0,"mouseY":0,"time":8969},{"type":1,"keyCode":65,"mouseX":0,"mouseY":0,"time":9844},{"type":0,"keyCode":27,"mouseX":0,"mouseY":0,"time":18188},{"type":1,"keyCode":27,"mouseX":0,"mouseY":0,"time":18344},{"type":3,"mouseX":2,"mouseY":0,"time":18417},{"type":3,"mouseX":11,"mouseY":11,"time":18448},{"type":3,"mouseX":13,"mouseY":10,"time":18480},{"type":3,"mouseX":41,"mouseY":26,"time":18511},{"type":3,"mouseX":46,"mouseY":35,"time":18542},{"type":3,"mouseX":31,"mouseY":31,"time":18573},{"type":3,"mouseX":7,"mouseY":15,"time":18605},{"type":3,"mouseX":3,"mouseY":21,"time":18636},{"type":3,"mouseX":0,"mouseY":9,"time":18667},{"type":3,"mouseX":0,"mouseY":10,"time":18698},{"type":3,"mouseX":0,"mouseY":8,"time":18730},{"type":3,"mouseX":-1,"mouseY":5,"time":18761},{"type":3,"mouseX":-2,"mouseY":4,"time":18792},{"type":3,"mouseX":-2,"mouseY":4,"time":18823},{"type":3,"mouseX":0,"mouseY":1,"time":18855},{"type":4,"mouseX":1457,"mouseY":939,"mouseButton":"Left","time":18938},{"type":5,"mouseX":1457,"mouseY":939,"mouseButton":"Left","time":19110},{"type":3,"mouseX":-1,"mouseY":4,"time":20042},{"type":3,"mouseX":-2,"mouseY":6,"time":20073},{"type":3,"mouseX":-3,"mouseY":7,"time":20105},{"type":3,"mouseX":-4,"mouseY":25,"time":20136},{"type":3,"mouseX":-3,"mouseY":31,"time":20167},{"type":3,"mouseX":1,"mouseY":41,"time":20198},{"type":3,"mouseX":6,"mouseY":40,"time":20230},{"type":3,"mouseX":3,"mouseY":20,"time":20261},{"type":3,"mouseX":11,"mouseY":51,"time":20292},{"type":3,"mouseX":6,"mouseY":25,"time":20323},{"type":3,"mouseX":3,"mouseY":16,"time":20355},{"type":3,"mouseX":0,"mouseY":10,"time":20386},{"type":3,"mouseX":-1,"mouseY":13,"time":20417},{"type":3,"mouseX":-3,"mouseY":12,"time":20448},{"type":3,"mouseX":-1,"mouseY":10,"time":20480},{"type":3,"mouseX":-1,"mouseY":5,"time":20511},{"type":3,"mouseX":-3,"mouseY":9,"time":20542},{"type":3,"mouseX":-1,"mouseY":6,"time":20573},{"type":3,"mouseX":-2,"mouseY":7,"time":20605},{"type":3,"mouseX":-1,"mouseY":5,"time":20636},{"type":3,"mouseX":-3,"mouseY":10,"time":20667},{"type":3,"mouseX":-2,"mouseY":4,"time":20714},{"type":3,"mouseX":-1,"mouseY":3,"time":20745},{"type":3,"mouseX":-2,"mouseY":0,"time":20886},{"type":3,"mouseX":-4,"mouseY":0,"time":20917},{"type":3,"mouseX":-8,"mouseY":1,"time":20948},{"type":3,"mouseX":-2,"mouseY":0,"time":20980},{"type":3,"mouseX":-1,"mouseY":0,"time":21042},{"type":3,"mouseX":0,"mouseY":2,"time":21136},{"type":3,"mouseX":-1,"mouseY":4,"time":21167},{"type":3,"mouseX":0,"mouseY":3,"time":21198},{"type":3,"mouseX":0,"mouseY":2,"time":21230},{"type":3,"mouseX":0,"mouseY":3,"time":21261},{"type":3,"mouseX":0,"mouseY":1,"time":21292},{"type":3,"mouseX":0,"mouseY":1,"time":21323},{"type":3,"mouseX":0,"mouseY":1,"time":21511},{"type":3,"mouseX":-1,"mouseY":3,"time":21698},{"type":3,"mouseX":-1,"mouseY":6,"time":21730},{"type":3,"mouseX":-1,"mouseY":4,"time":21761},{"type":3,"mouseX":-1,"mouseY":4,"time":21792},{"type":3,"mouseX":-1,"mouseY":5,"time":21823},{"type":3,"mouseX":0,"mouseY":1,"time":21855},{"type":3,"mouseX":1,"mouseY":1,"time":21933},{"type":3,"mouseX":3,"mouseY":1,"time":21964},{"type":3,"mouseX":1,"mouseY":1,"time":22026},{"type":3,"mouseX":4,"mouseY":1,"time":22073},{"type":3,"mouseX":3,"mouseY":1,"time":22105},{"type":3,"mouseX":1,"mouseY":0,"time":22136},{"type":4,"mouseX":1265,"mouseY":1185,"mouseButton":"Left","time":22172},{"type":5,"mouseX":1265,"mouseY":1185,"mouseButton":"Left","time":22281},{"type":3,"mouseX":0,"mouseY":1,"time":22308},{"type":3,"mouseX":0,"mouseY":1,"time":22542},{"type":2,"mouseX":1280,"mouseY":720,"time":22735},{"type":2,"mouseX":1280,"mouseY":721,"time":22813},{"type":2,"mouseX":1280,"mouseY":722,"time":23188},{"type":2,"mouseX":1280,"mouseY":723,"time":23266},{"type":2,"mouseX":1280,"mouseY":724,"time":23328},{"type":2,"mouseX":1280,"mouseY":725,"time":23547},{"type":2,"mouseX":1280,"mouseY":726,"time":23875},{"type":2,"mouseX":1280,"mouseY":728,"time":24094},{"type":2,"mouseX":1280,"mouseY":729,"time":24281}],"info":{"name":"","description":"","x":319,"y":192,"width":1920,"height":1080,"recordDpi":1}} \ No newline at end of file diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Configure Team Button.png b/repo/js/博士周本充能/Assets/RecognitionObject/Configure Team Button.png new file mode 100644 index 000000000..e6bdd02af Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Configure Team Button.png differ diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Confirm Deploy Button.png b/repo/js/博士周本充能/Assets/RecognitionObject/Confirm Deploy Button.png new file mode 100644 index 000000000..6c870dfc6 Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Confirm Deploy Button.png differ diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Leave Button.png b/repo/js/博士周本充能/Assets/RecognitionObject/Leave Button.png new file mode 100644 index 000000000..58c150b41 Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Leave Button.png differ diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Quick Setup Button.png b/repo/js/博士周本充能/Assets/RecognitionObject/Quick Setup Button.png new file mode 100644 index 000000000..4b7e37512 Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Quick Setup Button.png differ diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Slider Bottom.png b/repo/js/博士周本充能/Assets/RecognitionObject/Slider Bottom.png new file mode 100644 index 000000000..4af2e3cb2 Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Slider Bottom.png differ diff --git a/repo/js/博士周本充能/Assets/RecognitionObject/Slider Top.png b/repo/js/博士周本充能/Assets/RecognitionObject/Slider Top.png new file mode 100644 index 000000000..7334e462d Binary files /dev/null and b/repo/js/博士周本充能/Assets/RecognitionObject/Slider Top.png differ diff --git a/repo/js/博士周本充能/README.md b/repo/js/博士周本充能/README.md new file mode 100644 index 000000000..98b3a19c1 --- /dev/null +++ b/repo/js/博士周本充能/README.md @@ -0,0 +1,12 @@ +## 一、功能概述 + +### 1. 充能 + +- 在神像切换队伍后,前往博士周本直接把角色大招回满 + +## 二、版本与环境 + +- BGI ≥ v0.55 + +1.0 +切换队伍充能 \ No newline at end of file diff --git a/repo/js/博士周本充能/main.js b/repo/js/博士周本充能/main.js new file mode 100644 index 000000000..c75d79a42 --- /dev/null +++ b/repo/js/博士周本充能/main.js @@ -0,0 +1,307 @@ +const repeatOperationUntilTextFound = async ({ + //默认区域为单个F图标右边的文字,最多6个 + x = 1210, + y = 515, + width = 200, + height = 50, + targetText = null, + maxSteps = 100, + stepDuration = 200, + waitTime = 10, + moveKey = "w", + ifClick = false, +} = {}) => { + /** + * 转义正则表达式中的特殊字符 + * @param {string} string 要转义的字符串 + * @returns {string} 转义后的字符串 + */ + const escapeRegExp = (string) => { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + }; + + // 预编译正则表达式(如果是字符串则转换并转义) + const textPattern = typeof targetText === 'string' + ? new RegExp(escapeRegExp(targetText)) + : targetText; + + let stepsTaken = 0; + + while (stepsTaken <= maxSteps) { + // 1. 捕获游戏区域并裁剪出检测区域 + const captureRegion = captureGameRegion(); + const textArea = captureRegion.DeriveCrop(x, y, width, height); + + // 2. 执行OCR识别 + const ocrResult = textArea.find(RecognitionObject.ocrThis); + captureRegion.dispose(); + textArea.dispose(); + + const hasAnyText = ocrResult.text.trim().length > 0; + const matchesTarget = targetText === null + ? hasAnyText + : textPattern.test(ocrResult.text); + + if (matchesTarget) { + log.info(`检测到${targetText === null ? '文字' : '目标文字'}: ${ocrResult.text}`); + await sleep(1000); + if (ifClick) click(Math.round(x + width / 2), Math.round(y + height / 2)); + return true; + } + + // 4. 检查步数限制 + if (stepsTaken >= maxSteps) { + throw new Error(`检查次数超过最大限制: ${maxSteps},未查询到文字"${targetText}"`); + } + + // 5. 前进一小步 + if (stepDuration != 0) { + keyDown(moveKey); + await sleep(stepDuration); + keyUp(moveKey); + } + await sleep(waitTime); + stepsTaken++; + } +} + +// Party Setup +const QuickSetupButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Quick Setup Button.png"), 1100, 900, 400, 180); +const ConfigureTeamButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Configure Team Button.png"), 0, 900, 200, 180); +const ConfirmDeployButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Confirm Deploy Button.png"), 0, 900, 1920, 180); +// Slider +const LeftSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Top.png"), 650, 50, 100, 100); +const LeftSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Bottom.png"), 650, 100, 100, 900); +const MiddleSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Top.png"), 1250, 50, 100, 200); +const MiddleSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Bottom.png"), 1250, 100, 100, 900); +const RightSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Top.png"), 1750, 100, 100, 100); +const RightSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("Assets/RecognitionObject/Slider Bottom.png"), 1750, 100, 100, 900); + +(async function () { + // 翻页 + 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 goToWeeklyBossAndEnter() { + // 确保主界面 + await genshin.returnMainUi(); + + await genshin.tp(9530.678, 6394.4453); + + // 等待传送完成 + await sleep(1000); + + // 靠近副本门口,直到可交互 + await repeatOperationUntilTextFound(); + + await sleep(500); + + // 打开挑战界面 + keyPress("F"); + + await sleep(2000); + + // 等待「单人挑战」按钮出现 + await repeatOperationUntilTextFound({ + x: 1650, + y: 1000, + width: 160, + height: 45, + targetText: "单人挑战", + stepDuration: 0, + waitTime: 100 + }); + + // 点击「单人挑战」 + click(1725, 1020); + + await sleep(300); + + // 处理可能出现的提示弹窗 + click(1180, 760); + + // 等待并点击「开始挑战」 + await repeatOperationUntilTextFound({ + x: 1650, + y: 1000, + width: 160, + height: 45, + targetText: "开始挑战", + stepDuration: 0, + waitTime: 100, + ifClick: true + }); + log.info(`已进入周本`); + await sleep(3000); + log.info("开始充能"); + await keyMouseScript.runFile("222.json"); + log.info("充能完成"); + } + + // 切换队伍 + 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) { + await goToWeeklyBossAndEnter(); + await genshin.TpToStatueOfTheSeven(); + 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 (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(); + await sleep(100); + 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 { + await genshin.returnMainUi(); + } + } else { + // 当前队伍就是目标队伍,设置成功状态 + ConfigureStatue = true; + } + return ConfigureStatue; + } + + // Main + if (!!settings.partyName) { + try { + log.info("强制传送到七天神像切换队伍"); + await genshin.TpToStatueOfTheSeven(); + + log.info("正在尝试切换至" + settings.partyName); + await SwitchParty(settings.partyName); + + genshin.clearPartyCache(); + + } catch (error) { + log.error("队伍切换失败:" + error.message); + notification.error("队伍切换失败:" + error.message); + await genshin.returnMainUi(); + } + } else { + log.error("没有设置切换队伍"); + notification.error("没有设置切换队伍"); + await genshin.returnMainUi(); + } +})(); diff --git a/repo/js/博士周本充能/manifest.json b/repo/js/博士周本充能/manifest.json new file mode 100644 index 000000000..4c3acc3de --- /dev/null +++ b/repo/js/博士周本充能/manifest.json @@ -0,0 +1,15 @@ +{ + "manifest_version": 1, + "name": "切换队伍并传送博士周本充能", + "version": "1.0", + "bgi_version": "0.55.3", + "description": "进入博士周本给角色充能", + "authors": [ + { + "name": "爱丽丝", + "links":"https://github.com/itslyh" + } + ], + "settings_ui": "settings.json", + "main": "main.js" +} diff --git a/repo/js/博士周本充能/settings.json b/repo/js/博士周本充能/settings.json new file mode 100644 index 000000000..3322080d9 --- /dev/null +++ b/repo/js/博士周本充能/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "partyName", + "type": "input-text", + "label": "需要充能的队伍名称" + } +] \ No newline at end of file diff --git a/repo/js/原石购买粉球/README.md b/repo/js/原石购买粉球/README.md new file mode 100644 index 000000000..a00ac0ddf --- /dev/null +++ b/repo/js/原石购买粉球/README.md @@ -0,0 +1,2 @@ +适用于每天换粉球的用户,一个一个换。 +ps:正常运行不会换错,意外换错了别抽可以找客服换回来。 diff --git a/repo/js/原石购买粉球/assets/pinkBall.png b/repo/js/原石购买粉球/assets/pinkBall.png new file mode 100644 index 000000000..ad68efc17 Binary files /dev/null and b/repo/js/原石购买粉球/assets/pinkBall.png differ diff --git a/repo/js/原石购买粉球/main.js b/repo/js/原石购买粉球/main.js new file mode 100644 index 000000000..c49c8331f --- /dev/null +++ b/repo/js/原石购买粉球/main.js @@ -0,0 +1,121 @@ +const replacementMap = { + "监": "盐", + "卵": "卯" +}; + +// 定义一个独立的函数用于在指定区域进行 OCR 识别并输出识别内容 +async function recognizeTextInRegion(ocrRegion, timeout = 5000) { + let startTime = Date.now(); + let retryCount = 0; // 重试计数 + while (Date.now() - startTime < timeout) { + try { + // 在指定区域进行 OCR 识别 + const ro = captureGameRegion(); + let ocrResult = ro.find(RecognitionObject.ocr(ocrRegion.x, ocrRegion.y, ocrRegion.width, ocrRegion.height)); + ro.dispose(); + if (ocrResult) { + // 后处理:根据替换映射表检查和替换错误识别的字符 + let correctedText = ocrResult.text; + for (let [wrongChar, correctChar] of Object.entries(replacementMap)) { + correctedText = correctedText.replace(new RegExp(wrongChar, 'g'), correctChar); + } + return correctedText; // 返回识别到的内容 + } else { + log.warn(`OCR 识别区域未找到内容`); + await sleep(500); + return null; // 如果 OCR 未识别到内容,返回 null + } + } catch (error) { + retryCount++; // 增加重试计数 + await sleep(500); + log.warn(`OCR 数识别失败,正在进行第 ${retryCount} 次重试...`); + } + await sleep(500); // 短暂延迟,避免过快循环 + } + log.warn(`经过多次尝试,仍然无法在指定区域识别到文字`); + return null; // 如果未识别到文字,返回 null +} + +// 获取并判断原石数量的函数 +async function checkAndExchangeYuanShi() { + + // 获取原石数量的OCR区域 + let ocrRegionYuanShi = { x: 1585, y: 25, width: 180, height: 46 }; // 设置原石的OCR区域 + let recognizedText1 = await recognizeTextInRegion(ocrRegionYuanShi); + + if (recognizedText1) { + // 提取有效的数字(只保留数字部分) + recognizedText1 = recognizedText1.replace(/\D/g, ''); + log.info(`成功识别到原石数值: ${recognizedText1}`); + + // 判断原石数量是否足够兑换一个粉球(160原石) + if (parseInt(recognizedText1, 10) >= 160) { + log.info(`原石数量充足,执行兑换操作...`); + return true; // 返回 true 表示原石数量足够,继续兑换 + } else { + log.warn(`原石数量不足,跳过兑换`); + return false; // 如果未识别到原石数量,返回 false + } + } else { + log.warn(`未能识别到原石数量,跳过兑换`); + return false; // 如果未识别到原石数量,返回 false + } +} + +// 执行兑换操作的函数 +async function executeExchange() { + let continueExchanging = true; // 用于控制是否继续兑换 + + while (continueExchanging) { + + // 模板匹配粉球并进行兑换 + const pinkBallRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/pinkBall.png")); + let ro1 = captureGameRegion(); // 获取游戏区域 + let pinkBall = ro1.find(pinkBallRo); // 使用模板匹配查找粉球按钮 + ro1.dispose(); // 清理资源 + + if (pinkBall.isExist()) { + pinkBall.click(); await sleep(1000); // 点击粉球按钮 + click(1164, 782); await sleep(500); // 确认兑换 + click(960, 754); await sleep(1000); // 点击空白处继续 + + // 每次兑换后检查原石数量 + continueExchanging = await checkAndExchangeYuanShi(); // 如果原石不足,继续为 false,停止兑换 + + // 如果原石不足,不需要继续兑换 + if (!continueExchanging) { + break; + } + + } else { + log.warn("未能找到粉球按钮,跳过兑换"); + continueExchanging = false; // 如果没有找到粉球按钮,停止兑换 + } + } +} + +async function exchangeGoods() { + + await genshin.returnMainUi();await sleep(1000);// 返回主界面 + keyPress("ESCAPE"); await sleep(2000);//呼叫派蒙 + click(198,416);await sleep(2000);//点击商城 + + // 如果原石数量充足,继续进行尘辉兑换 + click(127,434);await sleep(1000);//尘辉兑换 + let canExchange = await checkAndExchangeYuanShi(); // 获取原石数量并判断是否足够 + if (!canExchange) { + log.warn("原石不足,跳过商城兑换"); + return; // 如果原石不足,直接退出,不执行后续操作 + } + click(1230,120);await sleep(1000);//原石购买 + await executeExchange(); + + // 通知完成 + notification.send(`商城抽卡资源兑换完成`); +} + + + +(async function () { + await exchangeGoods(); // 调用兑换函数 +})(); diff --git a/repo/js/原石购买粉球/manifest.json b/repo/js/原石购买粉球/manifest.json new file mode 100644 index 000000000..3403ed49c --- /dev/null +++ b/repo/js/原石购买粉球/manifest.json @@ -0,0 +1,14 @@ +{ + "manifest_version": 1, + "name": "原石购买粉球", + "version": "1.0", + "description": "运行即可实现原石换粉球", + "authors": [ + { + "name": "爱丽丝", + "links": "https://github.com/itslyh" + } + ], + "settings_ui": "settings.json", + "main": "main.js" +} \ No newline at end of file