(async function () { const defaultExitDelay = 10000; const defaultLoadingDelay = 13000; const seen = new Set(); function validateAndSetDefaults(exitDelay, loadingDelay) { if (isNaN(exitDelay) || exitDelay <= 0) { log.warn("你没有设置退出延迟,将使用默认值"); exitDelay = defaultExitDelay; } if (isNaN(loadingDelay) || loadingDelay <= 0) { log.warn("你没有设置加载延迟,将使用默认值"); loadingDelay = defaultLoadingDelay; } return { exitDelay, loadingDelay }; } async function runGameActionsMultipleTimes(times, locationName) { for (let i = 0; i < times; i++) { await sleep(1000); keyPress("ESCAPE"); await sleep(1000); click(50, 1030); await sleep(1000); click(1000, 750); await sleep(validatedExitDelay); click(1000, 550); await sleep(validatedLoadingDelay); keyPress("z"); log.info(`${locationName} 循环次数:${i + 1}/${times}`); } } async function resetMap() { log.info("重置地图大小..."); await sleep(1000); keyPress("M"); await sleep(1000); click(1840, 1010); await sleep(1000); click(1450, 460); await sleep(1000); click(1840, 1010); await sleep(1000); click(1450, 140); await sleep(1000); keyPress("M"); log.info("重置地图大小完成"); } async function KeyMouse(locationNameEx) { log.info(`前往 ${locationNameEx}`); let tpPath = `assets/AutoPath/tp/${locationNameEx}tp.json`; let filePath = `assets/KeyMouse/${locationNameEx}.json`; try { await pathingScript.runFile(tpPath); await sleep(1000); await keyMouseScript.runFile(filePath); } catch (error) { log.error(`执行 ${locationNameEx} 脚本时发生错误: ${error}`); } await sleep(1000); } async function woodcutting(locationName) { log.info(`砍伐 ${locationName}`); if (!map[locationName]) { log.info(`未找到 ${locationName} 对应的木材`); return; } const { description, available, times } = map[locationName]; if (description === 'NULL' || !description) { log.info(`${locationName} 暂不支持`); return; } if (Array.from(seen).some(item => item.includes(locationName))) { log.info(`${locationName} 已经砍伐过,将执行下一个`); return; } log.info(`前往 ${description}`); await sleep(1000); try { if (locationName === "炬木" || locationName === "桃椰子木") { await KeyMouse(description); } else { const filePath = `assets/AutoPath/${description}.json`; await pathingScript.runFile(filePath); } await sleep(1000); if (!available) { await runGameActionsMultipleTimes(times, description); } else { await dispatcher.runTask(new SoloTask("AutoWood")); } seen.add(map[locationName].description); log.info(`${locationName} 伐木完成,将执行下一个`); log.info(`已运行木材: ${[...seen].join(", ")}`); } catch (error) { log.error(`在砍伐 ${locationName} 时发生错误: ${error}`); } } // Set game environment settings setGameMetrics(1920, 1080, 1); const map = { '桦木': { description: '桦木15个', available: true, times: 134 }, '萃华木': { description: '萃华木6个(垂香木3个)', available: true, times: 334 }, '松木': { description: '松木24个', available: true, times: 84 }, '却砂木': { description: '却砂木12个', available: true, times: 167 }, '竹节': { description: '竹节30个', available: true, times: 67 }, '垂香木': { description: '垂香木15个', available: true, times: 134 }, '杉木': { description: '杉木12个', available: true, times: 167 }, '梦见木': { description: '梦见木12个', available: true, times: 167 }, '枫木': { description: '枫木9个', available: true, times: 223 }, '孔雀木': { description: '御伽木9个(孔雀木6个)', available: false, times: 334 },//利用手动重置仇恨 '御伽木': { description: '御伽木9个(孔雀木6个)', available: false, times: 334 },//利用手动重置仇恨 '辉木': { description: '业果木15个(辉木15个)', available: true, times: 134 }, '业果木': { description: '业果木15个(辉木15个)', available: true, times: 134 }, '证悟木': { description: '证悟木15个(业果木6个)', available: true, times: 334 }, '刺葵木': { description: '刺葵木6个', available: true, times: 334 }, '柽木': { description: '柽木15个', available: false, times: 134 }, '悬铃木': { description: '悬铃木18个', available: true, times: 112 }, '椴木': { description: '椴木9个', available: true, times: 223 }, '白梣木': { description: '白梣木15个', available: true, times: 134 }, '香柏木': { description: '香柏木27个', available: true, times: 75 }, '炬木': { description: '炬木15个', available: true, times: 134 }, '白栗栎木': { description: '燃爆木6个(白栗栎木6个)', available: false, times: 334 }, '灰灰楼林木': { description: '灰灰楼木6个', available: false, times: 334 }, '燃爆木': { description: '燃爆木15个', available: false, times: 134 }, '桃椰子木': { description: '桃椰子木12个', available: false, times: 167 } }; let exitdelay = Number(settings.exitdelay); let loadingdelay = Number(settings.loadingdelay); const { exitDelay: validatedExitDelay, loadingDelay: validatedLoadingDelay } = validateAndSetDefaults(exitdelay, loadingdelay); const messages = [ '确保装备有[王树瑞佑]', '确保使用小道具快捷键为Z键', '确保开启了BGI独立任务中自动伐木的“启用OCR伐木数量限制”', '若要运行炬木或桃椰子木:', '运行时是琳妮特前台且拥有双风共鸣', '元素共鸣需要四个角色组队触发,仅两个风系角色无效', '不要带其他有移速加成的角色' ]; for (let message of messages) { log.info(message); await sleep(1000); } log.info('自动伐木开始...'); log.info(`退出延迟: ${validatedExitDelay}毫秒, 加载延迟: ${validatedLoadingDelay}毫秒`); let woodsArray = settings.woods.split(" "); await resetMap(); for (const wood of woodsArray) { if (wood.trim()) { await woodcutting(wood); } else { log.info('请在自定义选项输入木材名,用空格隔开'); } } })();