diff --git a/repo/js/AutoEatCoinPVPEvnet/assets/pathing/continue.json b/repo/js/AutoEatCoinPVPEvnet/assets/pathing/continue.json new file mode 100644 index 00000000..b8f09d40 --- /dev/null +++ b/repo/js/AutoEatCoinPVPEvnet/assets/pathing/continue.json @@ -0,0 +1,31 @@ +{ + "info": { + "name": "未命名路径", + "type": "collect", + "author": "修改我的qq昵称", + "version": "1.0", + "description": "联机游戏结束返回世界后重新进入游戏", + "map_name": "Teyvat", + "bgi_version": "0.45.0" + }, + "positions": [ + { + "id": 1, + "x": 7348.14697265625, + "y": -1428.5224609375, + "type": "path", + "move_mode": "walk", + "action": "", + "action_params": "" + }, + { + "id": 2, + "x": 7354.49951171875, + "y": -1428.64404296875, + "type": "target", + "move_mode": "walk", + "action": "", + "action_params": "" + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoEatCoinPVPEvnet/assets/pathing/start.json b/repo/js/AutoEatCoinPVPEvnet/assets/pathing/start.json new file mode 100644 index 00000000..00f7140c --- /dev/null +++ b/repo/js/AutoEatCoinPVPEvnet/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/repo/js/AutoEatCoinPVPEvnet/main.js b/repo/js/AutoEatCoinPVPEvnet/main.js new file mode 100644 index 00000000..6f31ec9c --- /dev/null +++ b/repo/js/AutoEatCoinPVPEvnet/main.js @@ -0,0 +1,287 @@ +(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; + 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); + + // 遍历所有识别结果 + 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("接受")) { + log.info("匹配成功, 点击接受"); + click(1182, 737); // 点击确认按钮 + matchFound = true; + break; + } + } + + if (matchFound) 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/repo/js/AutoEatCoinPVPEvnet/manifest.json b/repo/js/AutoEatCoinPVPEvnet/manifest.json new file mode 100644 index 00000000..ba000c85 --- /dev/null +++ b/repo/js/AutoEatCoinPVPEvnet/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/repo/js/AutoEatCoinPVPEvnet/settings.json b/repo/js/AutoEatCoinPVPEvnet/settings.json new file mode 100644 index 00000000..5f028a25 --- /dev/null +++ b/repo/js/AutoEatCoinPVPEvnet/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "max_games", + "type": "input-text", + "label": "最大尝试进行游戏次数. 默认: 20" + } +]