From 8b730aca684f15099c04db26f86730b54753898e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E4=BA=91?= Date: Mon, 7 Jul 2025 00:54:42 +0800 Subject: [PATCH] =?UTF-8?q?archive:=20=E9=A3=9F=E6=9D=90=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=EF=BC=8C=E5=90=83=E9=87=91=E5=B8=81=E6=B4=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/pathing/continue.json | 22 ++ .../assets/pathing/start.json | 40 +++ archive/js/AutoEatCoinPVPEvent/main.js | 307 ++++++++++++++++++ archive/js/AutoEatCoinPVPEvent/manifest.json | 14 + archive/js/AutoEatCoinPVPEvent/settings.json | 7 + .../AutoProcess/assets/AutoPath/找厨房.json | 30 ++ archive/js/AutoProcess/main.js | 178 ++++++++++ archive/js/AutoProcess/manifest.json | 14 + archive/js/AutoProcess/settings.json | 7 + 9 files changed, 619 insertions(+) create mode 100644 archive/js/AutoEatCoinPVPEvent/assets/pathing/continue.json create mode 100644 archive/js/AutoEatCoinPVPEvent/assets/pathing/start.json create mode 100644 archive/js/AutoEatCoinPVPEvent/main.js create mode 100644 archive/js/AutoEatCoinPVPEvent/manifest.json create mode 100644 archive/js/AutoEatCoinPVPEvent/settings.json create mode 100644 archive/js/AutoProcess/assets/AutoPath/找厨房.json create mode 100644 archive/js/AutoProcess/main.js create mode 100644 archive/js/AutoProcess/manifest.json create mode 100644 archive/js/AutoProcess/settings.json diff --git a/archive/js/AutoEatCoinPVPEvent/assets/pathing/continue.json b/archive/js/AutoEatCoinPVPEvent/assets/pathing/continue.json new file mode 100644 index 00000000..7f4c9d5f --- /dev/null +++ b/archive/js/AutoEatCoinPVPEvent/assets/pathing/continue.json @@ -0,0 +1,22 @@ +{ + "info": { + "name": "未命名路径", + "type": "collect", + "author": "修改我的qq昵称", + "version": "1.0", + "description": "联机游戏结束返回世界后重新进入游戏", + "map_name": "Teyvat", + "bgi_version": "0.45.0" + }, + "positions": [ + { + "id": 1, + "x": 7354.68017578125, + "y": -1428.5908203125, + "type": "target", + "move_mode": "walk", + "action": "", + "action_params": "" + } + ] +} \ No newline at end of file diff --git a/archive/js/AutoEatCoinPVPEvent/assets/pathing/start.json b/archive/js/AutoEatCoinPVPEvent/assets/pathing/start.json new file mode 100644 index 00000000..00f7140c --- /dev/null +++ b/archive/js/AutoEatCoinPVPEvent/assets/pathing/start.json @@ -0,0 +1,40 @@ +{ + "info": { + "name": "pvp_event", + "type": "collect", + "author": "修改我的qq昵称", + "version": "1.0", + "description": "走到5.6联机吃金币pvp活动点.", + "map_name": "Teyvat", + "bgi_version": "0.45.0" + }, + "positions": [ + { + "id": 1, + "x": 7234.3056640625, + "y": -1433.24609375, + "type": "teleport", + "move_mode": "walk", + "action": "", + "action_params": "" + }, + { + "id": 2, + "x": 7316.3564453125, + "y": -1441.080078125, + "type": "path", + "move_mode": "walk", + "action": "", + "action_params": "" + }, + { + "id": 3, + "x": 7354.68017578125, + "y": -1428.5908203125, + "type": "target", + "move_mode": "walk", + "action": "", + "action_params": "" + } + ] +} \ No newline at end of file diff --git a/archive/js/AutoEatCoinPVPEvent/main.js b/archive/js/AutoEatCoinPVPEvent/main.js new file mode 100644 index 00000000..0b6654cd --- /dev/null +++ b/archive/js/AutoEatCoinPVPEvent/main.js @@ -0,0 +1,307 @@ +(async function () { + // 脚本配置参数 + // const ACTIVITY_LOCATION = { x: "1200.0", y: "1500.0" }; // 活动坐标 + const PATH_FILE_START = "assets/pathing/start.json"; // 地图追踪路径文件 + const PATH_FILE_CONTINUE = "assets/pathing/continue.json"; // 地图追踪路径文件 + + await sleep(1000); + + log.info("自动吃金币活动, 启动!") + + // 1. 脚本开始前确保在主界面 + log.info("确保游戏在主界面状态"); + await genshin.returnMainUi(); + await sleep(1000); + + // 在循环前添加游戏次数限制 + // const MAX_GAMES = 2; + const MAX_GAMES = typeof (settings.max_games) === 'undefined' ? 20 : parseInt(settings.max_games, 10); + let gameCount = 0; + + log.info("最大游戏次数设定: {MAX_GAMES}次", MAX_GAMES) + + + // 只要积分未满且游戏次数未达上限,就循环进行匹配和游戏 + while (gameCount < MAX_GAMES) { + gameCount++; // 增加游戏计数 + log.info("开始第{count}场游戏", gameCount); + + // 2. 使用地图追踪走到活动入口 + log.info("正在使用地图追踪前往活动入口"); + try { + // 运行路径追踪脚本 + if (gameCount == 1) { + await pathingScript.runFile(PATH_FILE_START); + } else { + await pathingScript.runFile(PATH_FILE_CONTINUE); + } + + log.info("已到达活动入口"); + } catch (error) { + log.error("地图追踪失败: {error}", error); + return; + } + + // 3. 检测F键交互窗口 - 使用正确的OCR方法 + let foundActivity = false; + for (let i = 0; i < 10; i++) { // 最多尝试10次 + // 获取游戏截图 + const screenshot = captureGameRegion(); + + // 对整个区域进行OCR - 使用ocrThis + const activityTextRegions = screenshot.findMulti(RecognitionObject.ocrThis); + + // 遍历所有OCR结果 + for (let j = 0; j < activityTextRegions.count; j++) { + const region = activityTextRegions[j]; + + if (region.text.includes("跨界挑战")) { + log.info("检测到活动入口"); + foundActivity = true; + break; + } + } + + if (foundActivity) break; + + keyPress('W'); + moveMouseBy(0, 100); // 轻微移动视角帮助识别 + await sleep(1000); + } + + // 4. 按F进入活动界面 + log.info("进入活动界面"); + keyPress("F"); + await sleep(2000); // 等待界面加载 + + // 5. 精确识别积分信息 + const scoreRegion = captureGameRegion().deriveCrop( + 1248, // x + 360, // y + 150, // width + 30 // height + ); + + // 对积分区域进行OCR + const scoreResults = scoreRegion.findMulti(RecognitionObject.ocrThis); + + let currentScore = 0; + let maxScore = 0; + let scoreFound = false; + // 遍历所有识别结果 + for (let i = 0; i < scoreResults.count; i++) { + const res = scoreResults[i]; + + // 使用正则表达式匹配积分格式 + const match = res.text.match(/(\d+)\s*\/\s*(\d+)/); + if (match && match.length >= 3) { + currentScore = parseInt(match[1]); + maxScore = parseInt(match[2]); + scoreFound = true; + break; + } + } + if (!scoreFound) { + log.error("未识别到积分信息"); + // await genshin.returnMainUi(); + return; + } + log.info("积分状态: {current}/{max}", currentScore, maxScore); + if (currentScore >= maxScore) { + log.info("PVP活动已完成"); + // notification.send("PVP活动已完成"); + await genshin.returnMainUi(); + await sleep(1000); + return; + } + + + // 6. 点击开始匹配 + log.info("匹配挑战"); + // 假设开始按钮在屏幕中间下方位置 + click(1560, 1012); + await sleep(1000); + + // 7. 等待并确认匹配 + let matchFound = false,matchFound_1st = false; //matchFound_1st:确认按钮是否点击过 + let matchTimeout = 0; //联机确认按钮超时等待(单位:秒) + let beRefusedCount = 0; //被拒绝次数 + for (let i = 0; i < 60; i++) { // 最多等待60秒 + const confirmRegion = captureGameRegion().deriveCrop( + 1037, + 706, + 280, + 64 + ); + + // 执行OCR识别 + const confirmResults = confirmRegion.findMulti(RecognitionObject.ocrThis); + log.info("匹配确认区域OCR识别结果数量: {count}", confirmResults.count); + + /*处理联机确认按钮 + 执行逻辑:(如有报错,自己改 或者 反馈naralan0502@gmail.com) + 如果OCR识别结果数量等于0,判断是否已经点击过确认按钮(通过变量matchFound_1st确认) + 是:超时等待时长matchTimeout++,若超时等待时长==13,设置matchFound为true,跳出循环 + 否:继续循环 + 如果OCR识别结果数量大于0,遍历所有识别结果 + 如果存在确认按钮,设置变量matchFound_1st = true,超时等待t=0 + */ + if(confirmResults.count){ + // 遍历所有识别结果 + for (let j = 0; j < confirmResults.count; j++) { + const region = confirmResults[j]; + // log.info("匹配确认区域OCR结果:位置({x},{y},{w},{h}), 文本: {text}", + // region.x, region.y, region.width, region.height, region.text); + + if (region.text.includes("接受")) { + click(1182, 737); // 点击确认按钮 + if(matchFound_1st && (++beRefusedCount >= 3)) log.info("兄啊有点点背,被拒绝了{count}次诶", beRefusedCount); + matchFound_1st = true; + log.info("匹配成功, 点击接受"); + matchTimeout = 0; + break; + } + } + } + else{ + if(matchFound_1st && (++matchTimeout == 13)) { //超时等待13s(游戏内联机确认超时时长10s+冷却CD3s) + matchFound = true; + log.info("点击确认成功"); + break; + } + } + + await sleep(1000); + } + + if (!matchFound) { + notification.error("匹配超时"); + return; + } + + // 7 等待进入游戏(直到出现"第1回合"提示) + let roundStarted = false; + const roundStartTime = Date.now(); + const ROUND_TIMEOUT = 90 * 1000; // 90秒超时 + + while (!roundStarted && Date.now() - roundStartTime < ROUND_TIMEOUT) { + const roundRegion = captureGameRegion().deriveCrop( + 770, + 246, + 373, + 60 + ); + + const roundText = roundRegion.find(RecognitionObject.ocrThis); + if (roundText && roundText.text && roundText.text.includes("第1回合")) { + log.info("游戏开始"); + roundStarted = true; + break; + } + + await sleep(1000); + } + + if (!roundStarted) { + log.error("未检测到回合开始提示"); + notification.error("进入游戏失败"); + return; + } + + // 8. 进入游戏后模拟操作 + log.info("开始模拟操作"); + + // 随机选择操作 + const actions = [ + // Shift+W 冲刺前进1秒 + async () => { + keyDown("SHIFT"); + keyDown("W"); + await sleep(1000); + keyUp("W"); + keyUp("SHIFT"); + }, + // Shift+A 冲刺左移1秒 + async () => { + keyDown("SHIFT"); + keyDown("A"); + await sleep(1000); + keyUp("A"); + keyUp("SHIFT"); + }, + // Shift+S 冲刺后退1秒 + async () => { + keyDown("SHIFT"); + keyDown("S"); + await sleep(1000); + keyUp("S"); + keyUp("SHIFT"); + }, + // Shift+D 冲刺右移1秒 + async () => { + keyDown("SHIFT"); + keyDown("D"); + await sleep(1000); + keyUp("D"); + keyUp("SHIFT"); + }, + // 空格跳跃1秒 + async () => { + keyDown("SPACE"); + await sleep(1000); + keyUp("SPACE"); + }, + // 1秒内按两下E(元素战技) + async () => { + // 第一次按E + keyPress("E"); + await sleep(700); // 短暂间隔 + + // 第二次按E + keyPress("E"); + await sleep(300); // 总时间1秒 + } + ]; + + const startTime = Date.now(); + const MAX_GAME_DURATION = 300 * 1000; + + while (Date.now() - startTime < MAX_GAME_DURATION) { + // 在屏幕顶部中央检测"挑战完成"文本 + const completionRegion = captureGameRegion().deriveCrop( + 800, 180, 320, 100 + ); + + const completionResults = completionRegion.findMulti(RecognitionObject.ocrThis); + let challengeCompleted = false; + + // 遍历识别结果 + for (let i = 0; i < completionResults.count; i++) { + const region = completionResults[i]; + if (region.text.includes("挑战完成")) { + challengeCompleted = true; + break; + } + } + + if (challengeCompleted) { + log.info("挑战完成"); + break; + } + // 随机执行一个操作 + const action = actions[Math.floor(Math.random() * actions.length)]; + await action(); + + } + + await sleep(20000); + await genshin.returnMainUi(); + await sleep(1000); + await genshin.returnMainUi(); + } + + log.info("已达到最大游戏次数{max}次", MAX_GAMES); + return; + + +})(); diff --git a/archive/js/AutoEatCoinPVPEvent/manifest.json b/archive/js/AutoEatCoinPVPEvent/manifest.json new file mode 100644 index 00000000..ba000c85 --- /dev/null +++ b/archive/js/AutoEatCoinPVPEvent/manifest.json @@ -0,0 +1,14 @@ +{ + "manifest_version": 1, + "name": "自动联机pvp吃金币活动", + "version": "5.6.0", + "bgi_version": "0.45.0", + "description": "自动完成5.6版本联机pvp吃金币「炽烈传说·跨界乱斗」活动", + "authors": [ + { + "name": "修改我的qq昵称" + } + ], + "settings_ui": "settings.json", + "main": "main.js" +} \ No newline at end of file diff --git a/archive/js/AutoEatCoinPVPEvent/settings.json b/archive/js/AutoEatCoinPVPEvent/settings.json new file mode 100644 index 00000000..5f028a25 --- /dev/null +++ b/archive/js/AutoEatCoinPVPEvent/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "max_games", + "type": "input-text", + "label": "最大尝试进行游戏次数. 默认: 20" + } +] diff --git a/archive/js/AutoProcess/assets/AutoPath/找厨房.json b/archive/js/AutoProcess/assets/AutoPath/找厨房.json new file mode 100644 index 00000000..427faa33 --- /dev/null +++ b/archive/js/AutoProcess/assets/AutoPath/找厨房.json @@ -0,0 +1,30 @@ +{ + "info": { + "name": "找厨房", + "type": "collect", + "author": "听雨♪", + "version": "1.1", + "description": "", + "bgi_version": "0.35.1" + }, + "positions": [ + { + "id": 1, + "x": 267.939453125, + "y": -665.13134765625, + "action": "", + "move_mode": "walk", + "action_params": "", + "type": "teleport" + }, + { + "id": 2, + "x": 254.6251423712256, + "y": -680.625, + "action": "", + "move_mode": "walk", + "action_params": "", + "type": "target" + } + ] +} \ No newline at end of file diff --git a/archive/js/AutoProcess/main.js b/archive/js/AutoProcess/main.js new file mode 100644 index 00000000..ca7660f0 --- /dev/null +++ b/archive/js/AutoProcess/main.js @@ -0,0 +1,178 @@ +// main.js + +const settingsInput = settings.process + +const FoodItems = { + 1: { name: '面粉', coordinate: [240, 260] }, + 2: { name: '兽肉', coordinate: [435, 260] }, + 3: { name: '鱼肉', coordinate: [630, 260] }, + 4: { name: '神秘肉加工产物', coordinate: [825, 260] }, + 5: { name: '奶油', coordinate: [1020, 260] }, + 6: { name: '熏禽肉', coordinate: [1215, 260] }, + 7: { name: '黄油', coordinate: [1410, 260] }, + 8: { name: '火腿', coordinate: [1605, 260] }, + 9: { name: '糖', coordinate: [240, 500] }, + 10: { name: '香辛料', coordinate: [435, 500] }, + 11: { name: '蟹黄', coordinate: [630, 500] }, + 12: { name: '果酱', coordinate: [825, 500] }, + 13: { name: '奶酪', coordinate: [1020, 500] }, + 14: { name: '培根', coordinate: [1215, 500] }, + 15: { name: '香肠', coordinate: [1410, 500] } +}; + +const coordinates = { + process: [1350, 64], + claimAll: [327, 1367], + cook: [2250, 1368], + amountStart: [990, 790], + confirm: [1577, 1011] +} + + +function validateAndStoreNumbers(input) { + // 定义存储结果的数组 + let storedNumbers = []; + + // 使用正则表达式检测是否符合期望格式 + const regex = /^(\b([1-9]|1[0-5])\b)(, (\b([1-9]|1[0-5])\b))*$/; + + // 检测输入字符串是否符合正则表达式 + if (regex.test(input)) { + // 将输入字符串按逗号和空格分割成数组 + const numbers = input.split(', '); + + // 将分割后的数字字符串转换为整数并存储到数组中 + storedNumbers = numbers.map(Number); + + return storedNumbers; + } else { + return false + } + + +} + +async function QucikCook() { + // 点击Cook + click(...coordinates.cook); + await sleep(100); // 等待窗口弹出 + + // 选中左边点 + moveMouseTo(...coordinates.amountStart); + await sleep(100); + leftButtonDown(); + await sleep(50); + + // 向右滑动 + moveMouseBy(1200, 0); + await sleep(200); + leftButtonUp(); + await sleep(100); + + // 点击弹出页的确认 + click(...coordinates.confirm); + await sleep(500); + + // 点击空白处关闭 + click(...coordinates.confirm); + await sleep(200); +} + +async function AutoPath(locationName) { + try { + let filePath = `assets/AutoPath/${locationName}.json`; + await pathingScript.runFile(filePath); + + return true; + } catch (error) { + log.error(`执行 ${locationName} 路径时发生错误`); + log.error(error.message); + } + + return false; +} + +(async function () { + + // 提醒别带内鬼 + log.warn("建议不要带某些靠近能灭火的\"内鬼\"角色.") + + + // 判断设置合法性 + var items = []; + + if (settingsInput) { + items = validateAndStoreNumbers(settingsInput); + if (items) { + const names = items + .map(id => FoodItems[id] ? FoodItems[id].name : null) // 检查是否存在 + .filter(name => name !== null) // 过滤掉不存在的项 + .join(', '); + log.info("已从设置中读取内容: ")| + await sleep(100) + log.info(names) + + } else { + log.info("设置所填内容不合法, 请仔细阅读设置要求, 或者在群里问其他玩家") + + return + } + + } else { + log.info("还没有设置需要制作食材呢") + log.info("请在调试器里添加本脚本->右键JS脚本->修改JS脚本自定义配置.") + + return + } + + // 前往灶台 + if (!await AutoPath("找厨房")) { + return + } + + + //设置脚本环境的游戏分辨率和DPI缩放 + setGameMetrics(2560, 1440, 1.5); + + // 交互, 进入烹饪界面 + await sleep(500) + keyPress("F") + await sleep(1000) + click(...coordinates.process) + await sleep(1000) + + // 收菜 + click(...coordinates.claimAll) + await sleep(500) + click(...coordinates.claimAll) + await sleep(500) + + // 批量Cook + for (let item of items) { + // 选择目标 + click(...FoodItems[item].coordinate) + await sleep(300) + + await QucikCook() + + log.info(`${FoodItems[item].name} = 制作完成 :)`); + await sleep(200) + } + + // 返回主菜单 + await genshin.returnMainUi() + + // 后退一下, 防止某些内鬼灭火 + keyDown("S") + await sleep(2000) + keyUp("S") + + log.info("┌────────────────────────────┐") + log.info(" 感谢您的使用, 任务已全部完成") + log.info(" 拜拜") + log.info(" Done.") + log.info("└────────────────────────────┘") + + + +})(); \ No newline at end of file diff --git a/archive/js/AutoProcess/manifest.json b/archive/js/AutoProcess/manifest.json new file mode 100644 index 00000000..614f1f29 --- /dev/null +++ b/archive/js/AutoProcess/manifest.json @@ -0,0 +1,14 @@ +{ + "manifest_version": 1, + "name": "自动食材加工", + "version": "1.0", + "description": "自动食材加工, 可自动获取加工完成食材,可指定制作食材.", + "authors": [ + { + "name": "听雨♪", + "links": "https://github.com/TingYu-lulumi" + } + ], + "settings_ui": "settings.json", + "main": "main.js" +} \ No newline at end of file diff --git a/archive/js/AutoProcess/settings.json b/archive/js/AutoProcess/settings.json new file mode 100644 index 00000000..17eff947 --- /dev/null +++ b/archive/js/AutoProcess/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "process", + "type": "input-text", + "label": "下面输入框填: 需要加工的食材, 序号为加工界面依次排序,\n英文逗号空格[, ]隔开, 不要输入括号, 只填数字逗号和空格\n如:\n[1, 5, 8, 9, 13](别填括号) 代表加工: 面粉, 奶油, 火腿, 糖, 奶酪" + } +] \ No newline at end of file