From f60e778486206564775fc60129f7634a61533a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BA=81=E5=8A=A8=E7=9A=84=E6=B0=A8=E6=B0=94?= <131591012+zaodonganqi@users.noreply.github.com> Date: Sun, 30 Nov 2025 11:52:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E6=96=B0=E5=8D=83?= =?UTF-8?q?=E6=98=9F=E8=84=9A=E6=9C=AC=20(#2416)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加全新千星脚本 * 添加全新千星脚本 * 添加全新千星脚本 * 添加全新千星脚本 --- repo/js/WeeklyThousandStarRealm/README.md | 56 +++ .../assets/check_box.png | Bin 0 -> 473 bytes .../assets/close_manage.png | Bin 0 -> 1031 bytes .../assets/close_star_manage.png | Bin 0 -> 3488 bytes .../assets/exit_room.png | Bin 0 -> 2863 bytes .../WeeklyThousandStarRealm/data/store.json | 5 + repo/js/WeeklyThousandStarRealm/main.js | 334 ++++++++++++++++++ repo/js/WeeklyThousandStarRealm/manifest.json | 18 + repo/js/WeeklyThousandStarRealm/settings.json | 31 ++ 9 files changed, 444 insertions(+) create mode 100644 repo/js/WeeklyThousandStarRealm/README.md create mode 100644 repo/js/WeeklyThousandStarRealm/assets/check_box.png create mode 100644 repo/js/WeeklyThousandStarRealm/assets/close_manage.png create mode 100644 repo/js/WeeklyThousandStarRealm/assets/close_star_manage.png create mode 100644 repo/js/WeeklyThousandStarRealm/assets/exit_room.png create mode 100644 repo/js/WeeklyThousandStarRealm/data/store.json create mode 100644 repo/js/WeeklyThousandStarRealm/main.js create mode 100644 repo/js/WeeklyThousandStarRealm/manifest.json create mode 100644 repo/js/WeeklyThousandStarRealm/settings.json diff --git a/repo/js/WeeklyThousandStarRealm/README.md b/repo/js/WeeklyThousandStarRealm/README.md new file mode 100644 index 000000000..c39928ae3 --- /dev/null +++ b/repo/js/WeeklyThousandStarRealm/README.md @@ -0,0 +1,56 @@ +# 🌌 千星奇域 · 成就经验自动慢刷脚本 + +**⚠️ 提醒:由于奇域地图经常下架,默认地图也可能无法使用。若默认地图被下架,请使用 MiliastraExperienceAutomation 脚本刷取固定 20 经验的关卡,并将房间号填写到本脚本设置中。** + +> 与 MiliastraExperienceAutomation 脚本存在部分逻辑重复,这里就不再重新撰写啦😇 + +--- + +## ❗ 使用前重要说明(免责声明) + +本脚本依赖“**删除奇域地图存档**”来实现重复获取成就经验。 + +这意味着: + +- 当脚本执行删除存档时,如果 **第一个存档不是你正在刷的地图**,可能会误删你正常游玩的关卡数据。 +- 若你完全理解并接受此风险,请在脚本的 *自定义 JS 配置* 中手动勾选 `我已阅读说明中的免责声明` 才可继续执行脚本。 + +请务必确认你能承担潜在损失后再继续使用。 + +--- + +## 🌟 功能特点 + +- 🔁 自动重复通关指定奇域地图 +- 🧹 自动删除存档,实现成就经验可重复获取 +- 📅 自动监测每周经验上限,到达后自动停止 +- 🏞️ 完成后自动返回提瓦特大陆,不影响其他自动化脚本 + +--- + +## 🛠️ 脚本设置项说明 + +| 配置项 | 描述 | 默认值 | +|--------------|---------------------------------------------------------------------|--------------| +| **runJS** | 我已阅读免责声明(未勾选无法执行) | `false` | +| **room** | 奇域关卡关键词或 GUID(仅支持单个;空则使用默认地图) | `37135473336` | +| **thisAttempts** | 指定通关次数(`0` = 无限,直到达到每周上限) | `0` | +| **weekMaxExp** | 每周可获取的经验值上限 | `4000` | +| **singleExp** | 每次通关可获得的经验值 | `270` | + +--- + +## ❗ 注意事项 + +- 游戏窗口需保持 **16:9** 的宽高比例,否则可能影响图像识别。 +- `singleExp` 请填写正确,否则脚本的剩余次数计算会不准确。 +- 若默认地图下架,请手动输入可游玩的房间号。 + +--- + +## 📅 更新计划 + +未来可能会支持运行“收藏页面”中的奇域地图。 +但由于收藏地图状态不稳定(部分下架 → 能进;彻底取消发布 → 无法进入),**暂不确定是否正式加入**。 + +--- diff --git a/repo/js/WeeklyThousandStarRealm/assets/check_box.png b/repo/js/WeeklyThousandStarRealm/assets/check_box.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc5b5c33c3dc0d7275731374399a91971fdcb1c GIT binary patch literal 473 zcmV;~0Ve*5P)1-#ZYQ4~?AG1hwTqEoT$g7vYRL%xI%Ci#A5 zX2T)gey-`%syDPuwvOfV}?t>N3*=7>b=EswcQ;MVOq9a zP(m~h37`is1)@-{!owXa4h{2o`b5q8W1A~f-6_Bx5HNDkXN$^ayYp6~z_jM>6!Im7 zaF?Q~cMr#tw-g22-5&M;q{(#t-}JC;sZ0Uuu^#KO{t93{)?+=^V?EYm{T0A^tUv3? z^UwZsP2C@k-cl4SmMe-8eW9qFuMkpF2E7nZy{|XkQWR+ImmtLf^@dLL2d}r`7$kr! ztMvwY08>B&w0&rpEH8mB5{r)~CNZ1M({jm8@E|@_YE8A(Lqx7vrOyWo;fSE=oy)-* zq{w7139bOcB~-2LIL_a>9`pdF0DAzN=qIBn2vA&V6AO<|j3lP*q@!*jBh`cayU3w1|U1BQb ztNF0C^QPx*Pxti9zWVtu;T3)Htawo)4XP%a19@2@u(|ltiKvN0ao4EndWMXkxHNvG3B%P<>{h1>84MNJe0M$Im)zJ1rmO!W7Al7dYEZ(s z5W&VzyNkhprv^v3hm|^&D;EXvcs1c@92=cu%!7jmKZ^;~FOO@dwyPtK0aP*!1grolMr@S)s4~-L!uEU~m)rwFvHYrv$ zLwkfd?33XMQX@N6grS8Co!sn4^%M(I9FU*!+KF(J_@LTZ*jtXUG?C3_+0rZ9e(1gfgNPK z%-8~Iu(wuf+c-5g#}sZPN+N*cKzfhW!Kq>SMcMa|RFlo!?o7Gc9ju@jAv|Ra$pE9K zXP3Eq+2F_|``L^JuviUdPz}AkaHAyw_Ft&D70MERSzxO`{_#~%m zMw7coi=KqU)o_1ILZ$d);ty)y8@qaKv`Us?M~da0W1-}}>+ zM)a@@^=Yh literal 0 HcmV?d00001 diff --git a/repo/js/WeeklyThousandStarRealm/assets/close_star_manage.png b/repo/js/WeeklyThousandStarRealm/assets/close_star_manage.png new file mode 100644 index 0000000000000000000000000000000000000000..1a8ba7641e3a7ef417ddf185e43638a9f4116024 GIT binary patch literal 3488 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 O0000co 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 N002ovPDHLkV1g 0; +const weekMaxExp = Number(settings.weekMaxExp || "4000"); +const singleExp = Number(settings.singleExp || "270"); +let weekTotal = initWeekTotal(); + +// 获取图片资源 +function getImgMat(path) { + return file.readImageMatSync('assets/' + path + '.png'); +} + +// 读取存档 +function loadWeekData() { + try { + const t = file.readTextSync(storePath); + return JSON.parse(t); + } catch (_) { + return null; + } +} + +// 保存存档 +function saveWeekData(data) { + file.writeTextSync(storePath, JSON.stringify(data)); +} + +// 初始化或更新 weekTotal +function initWeekTotal() { + const stored = loadWeekData(); + const calculated = Math.ceil(weekMaxExp / singleExp); + + // 首次 OR 配置变化 → 重写 + if ( + !stored || + stored.weekMaxExp !== weekMaxExp || + stored.singleExp !== singleExp + ) { + const newData = { + weekMaxExp, + singleExp, + weekTotal: calculated + }; + saveWeekData(newData); + return calculated; + } + + return stored.weekTotal; +} + +// 刷完一次 → 计数 -1 +function decreaseWeekTotal() { + const stored = loadWeekData(); + if (!stored) return; + + stored.weekTotal = Math.max(stored.weekTotal - 1, 0); + saveWeekData(stored); + weekTotal = stored.weekTotal; +} + +// 查找文本 +async function findText(text, x, y, w, h, textAttempts = attempts) { + const searchText = text.toLowerCase(); + + for (let i = 0; i < textAttempts; i++) { + const captureRegion = captureGameRegion(); + const ro = RecognitionObject.ocr(x, y, w, h); + const results = captureRegion.findMulti(ro); + captureRegion.dispose(); + + for (let j = 0; j < results.count; j++) { + const region = results[j]; + if (region.isExist() && region.text.toLowerCase().includes(searchText)) { + return region; + } + } + + await sleep(interval); + } + + return null; +} + +// 查找图片 +async function findImage(imgMat, x, y, w, h, imgAttempts = attempts) { + const searchImg = RecognitionObject.TemplateMatch(imgMat, x, y, w, h); + + for (let i = 0; i < imgAttempts; i++) { + const captureRegion = captureGameRegion(); + const result = captureRegion.find(searchImg); + captureRegion.dispose(); + + if (result.isExist()) { + return result; + } + + await sleep(interval); + } + + return null; +} + +// 查找文本并点击 +async function findTextAndClick(text, x, y, w, h, textAttempts = attempts) { + const target = await findText(text, x, y, w, h, textAttempts); + if (target) { + await sleep(duration); + target.click(); + } else { + log.error("文本{text}查找失败", text); + } +} + +// 查找图片并点击 +async function findImageAndClick(path, x, y, w, h, imgAttempts = attempts) { + const imgMat = getImgMat(path); + const target = await findImage(imgMat, x, y, w, h, imgAttempts); + if (target) { + await sleep(duration); + target.click(); + } else { + log.error("图标{path}查找失败", path); + } +} + +// 清除游玩数据 +async function deleteSource() { + await sleep(duration); + await genshin.returnMainUi(); + log.info("开始清除地图数据"); + await sleep(duration); + keyPress("VK_B"); + await sleep(duration); + await findTextAndClick("管理关卡", 960, 0, 960, 100); + await findTextAndClick("管理", 960, 980, 960, 100); + await findImageAndClick("check_box", 0, 0, 1480, 340); + await findTextAndClick("删除",960, 980, 960, 100); + await findTextAndClick("确认", 960, 600, 960, 400); + await findTextAndClick("确认", 960, 600, 960, 400); + log.info("数据清除完成"); + await sleep(duration); + await genshin.returnMainUi(); +} + +// 进入千星奇域的全部奇域页面 +async function enterSourcePage() { + // 1. 检测是否在房间内,在则退出 + const inRoom = await findText("房间", 1500, 0, 420, 500, 5); + if (inRoom) { + keyPress("VK_P"); + await sleep(duration); + await findImageAndClick("exit_room", 960, 0, 960, 540); + await findTextAndClick("确认", 960, 600, 960, 400); + await genshin.returnMainUi(); + keyPress("VK_F6"); + } else { + keyPress("VK_F6"); + } + + await sleep(duration); +} + +// 创建关卡 +async function createMap() { + await findTextAndClick("全部", 1320, 0, 600, 95); + await findTextAndClick("搜索", 0, 120, 1920, 60); + inputText(roomID); + await sleep(1000); + await findTextAndClick("搜索", 0, 120, 1920, 60); + await sleep(duration); + click(355, 365); + await sleep(duration); + while (true) { + const result = await findText("房间", 960, 100, 960, 200, 2); + if (result) { + await sleep(duration); + result.click(); + await sleep(duration); + break; + } else { + const result2 = await findText("大厅", 960, 600, 960, 400, 2); + if (result2) { + result2.click(); + await sleep(duration); + } + } + } + await findText("开始游戏", 960, 540, 960, 540); + click(770, 275); + await sleep(duration); +} + +// 游玩关卡 +async function playMap() { + const stored = loadWeekData(); + const leave = stored ? stored.weekTotal : weekTotal; + const total = useFixedAttempts ? userAttempts : leave; + await createMap(); + while (true) { + await sleep(duration); + const result = await findText("开始游戏", 960, 540, 960, 540, 5); + if (result) { + await sleep(duration); + result.click(); + log.info("开始执行第{i}/{total}次奇域挑战", 1, total); + await sleep(duration); + } else { + await sleep(duration); + break; + } + } + let firstOutputCount = 0; + while (true) { + const result = await findText("返回大厅", 960, 540, 960, 540, 1); + if (result) { + await sleep(duration); + result.click(); + await sleep(duration); + if (!useFixedAttempts) { + decreaseWeekTotal(); + } + log.info("本次关卡结束"); + break; + } else { + const inRoom = await findText("房间", 1500, 0, 420, 500, 1); + if (inRoom) { + break; + } + if (firstOutputCount % 16 === 0) { + log.info("等待本次关卡结束..."); + } + firstOutputCount++; + await sleep(interval); + } + } + + await deleteSource(); + + for (let i = 1; i < total; i++) { + const inRoom = await findText("房间", 1500, 0, 420, 500); + if (inRoom) { + await sleep(duration); + keyPress("VK_P"); + await sleep(duration); + while (true) { + const result = await findText("开始游戏", 960, 540, 960, 540, 1); + if (result) { + await sleep(duration); + result.click(); + log.info("开始执行第{i}/{total}次奇域挑战", i + 1, total); + await sleep(duration); + break; + } else { + await sleep(duration); + } + } + let outputCount = 0; + while (true) { + const result = await findText("返回大厅", 960, 540, 960, 540, 1); + if (result) { + await sleep(duration); + result.click(); + await sleep(duration); + if (!useFixedAttempts) { + decreaseWeekTotal(); + } + log.info("本次关卡结束"); + break; + } else { + const inRoom = await findText("房间", 1500, 0, 420, 500, 1); + if (inRoom) { + break; + } + if (outputCount % 10 === 0) { + log.info("等待本次关卡结束..."); + } + outputCount++; + await sleep(interval); + } + } + await deleteSource(); + } + } +} + +// 退出到提瓦特 +async function exitToTeyvat() { + await genshin.returnMainUi(); + await sleep(duration); + keyPress("VK_F2"); + await sleep(duration); + await findTextAndClick("返回", 960, 0, 960, 100); + await sleep(duration); + await findTextAndClick("确认", 960, 600, 960, 400); +} + +(async function () { + if (!runJS) { + log.error("您未同意此脚本的免责声明,请先同意后重新运行此脚本!"); + return; + } + + await genshin.returnMainUi(); + + if (useFixedAttempts) { + // 手动模式:忽略本周计数 + log.info( + "已进入指定次数模式,本次将执行{count}次挑战(不计入周进度)", + userAttempts + ); + } else { + // 每周模式 + const stored = loadWeekData(); + const leave = stored.weekTotal; + const done = Math.ceil(weekMaxExp / singleExp) - leave; + + log.info( + "本周共需刷取 {total} 次,已刷 {done} 次,剩余 {leave} 次", + Math.ceil(weekMaxExp / singleExp), + done, + leave + ); + } + + await enterSourcePage(); + await playMap(); + await exitToTeyvat(); +})(); diff --git a/repo/js/WeeklyThousandStarRealm/manifest.json b/repo/js/WeeklyThousandStarRealm/manifest.json new file mode 100644 index 000000000..990fd15f7 --- /dev/null +++ b/repo/js/WeeklyThousandStarRealm/manifest.json @@ -0,0 +1,18 @@ +{ + "manifest_version": 1, + "name": "千星奇域每周成就经验刷取", + "version": "1.0", + "bgi_version": "0.53.0", + "description": "可用于利用成就高经验值刷取经验", + "authors": [ + { + "name": "躁动的氨气", + "link": "https://github.com/zaodonganqi" + } + ], + "main": "main.js", + "settings_ui": "settings.json", + "saved_files": [ + "store/*.json" + ] +} diff --git a/repo/js/WeeklyThousandStarRealm/settings.json b/repo/js/WeeklyThousandStarRealm/settings.json new file mode 100644 index 000000000..99198f0e7 --- /dev/null +++ b/repo/js/WeeklyThousandStarRealm/settings.json @@ -0,0 +1,31 @@ +[ + { + "name": "runJS", + "type": "checkbox", + "label": "我已阅读说明中的免责声明" + }, + { + "type": "input-text", + "name": "room", + "label": "奇域关卡关键词或关卡GUID\n(仅支持单个,默认为作者特供地图)", + "default": "37135473336" + }, + { + "type": "input-text", + "name": "thisAttempts", + "label": "指定通关次数", + "default": "0" + }, + { + "type": "input-text", + "name": "weekMaxExp", + "label": "每周可获取的经验值上限", + "default": "4000" + }, + { + "type": "input-text", + "name": "singleExp", + "label": "每次通关获取的经验值数量", + "default": "270" + } +]