|
2025-12-11 15:06
조회: 35,695
추천: 92
눈사람 구출 작전 자동화 (12/17 최적화)안녕하세요 이전에 카드 메모리 게임 자동화 스크립트를 만들었던 킹암살입니다. 단순히 귀찮아서 혼자 쓰려고 만든 스크립트를 공유해드렸는데 많은 관심 주셔서 감사했습니다. 유튜브에 소개해주신 갓냥이님도 감사드립니다. (12/13) 5스테이지에서 층수가 증가하는 것을 확인하여 이에 맞게 코드를 수정했습니다. 현재 버전은 스테이지별로 층수를 자동으로 감지하도록 구현되어 있어, 이후 층수가 증가하더라도 문제없이 사용할 수 있습니다. 이 부분은 제 구현 능력이 부족한 탓도 있는 만큼, 더 나은 개선 코드나 조언이 있다면 공유해주시면 감사하겠습니다. (12/15) 9스테이지부터 문이 5개가 되는 것을 확인하여 코드를 수정했습니다. 아직 9스테이지에서 확인해 본 것은 아니나, 자동 층수, 문 개수 감지 코드로 이전 스테이지들까지 문제 없이 실행되는 것을 확인하여 코드를 공유드립니다. 버그 발생시 알려주시면 감사하겠습니다. 해당 스크립트는 웹페이지에서 실행하여야 정상적으로 작동합니다. https://lostark.game.onstove.com/Promotion/Mission/251210 사용 방법 (마이크로소프트 엣지 기준)
요청 딜레이로 인한 버그들이 많아 이들을 방지하려다 보니 한층 한층 플레이가 오래걸립니다. 더 개선하고 싶었으나 토큰이 부족하여 우선은 작동시 문제가 없었던 버전을 공유드립니다. 사용 중 오류나 비정상 동작이 발견되면 댓글로 알려주시면 감사하겠습니다. 수정 사항 (12/12) 1. 층을 인식하는 방식과 문을 찾는 방식을 더 단순하고 안정적으로 바꿨습니다. 2. 정답/오답을 기록하는 로직을 최소한으로 정리하여 속도를 올렸습니다. 3. 자동 클릭 흐름을 간단하게 개선해 불필요한 시도를 줄였습니다. (12/13) 1. 층을 자동으로 인식하게 하여 4층 ,5층에서도 문제가 없도록 변경하였습니다. (12/15) 1. 문을 자동으로 인식하게 하여 9스테이지에서도 문제가 없도록 변경하였습니다. 2. 층수 확인 딜레이를 줄여 게임 속도가 빨라졌습니다. (12/16) 1. 일부 환경에서 문 개수를 잘못 인식하는 문제가 있어 로직을 변경하였습니다. (12/17) 1. 이제 오답 문을 클릭해도 1층으로 리셋되지 않음에 따라 코드를 개선하였습니다. (function () { 'use strict'; if (window.__snowmanAutoLight) return; window.__snowmanAutoLight = true; const sleep = ms => new Promise(r => setTimeout(r, ms)); function getCurrentFloor() { const floors = document.querySelectorAll('[class^="floor"]'); for (const el of floors) { if (el.querySelector('.obj_character')) { const name = el.className; const num = Number(name.slice(5)); if (!isNaN(num)) return num; } } return null; } function getDoors(floor) { const el = document.querySelector('.floor' + floor); if (!el) return []; return Array.from(el.querySelectorAll('button.door')); } const nextDoorIndex = {}; let lastClicked = null; let stopFlag = false; function clickNextDoor(floor) { const doors = getDoors(floor); if (!doors.length) return; if (nextDoorIndex[floor] == null) { nextDoorIndex[floor] = 0; } const idx = nextDoorIndex[floor]; const btn = doors[idx]; if (!btn || btn.disabled) return; lastClicked = { floor, idx }; btn.click(); } (function hookXHR() { if (window.__snowmanXHRHooked) return; window.__snowmanXHRHooked = true; const OriginalXHR = window.XMLHttpRequest; function WrappedXHR() { const xhr = new OriginalXHR(); let url = null; const open = xhr.open; xhr.open = function (m, u) { url = u; return open.apply(xhr, arguments); }; const send = xhr.send; xhr.send = function () { xhr.addEventListener('load', () => { try { if (!url || url.indexOf('SetDoor') === -1) return; if (!lastClicked) return; const res = JSON.parse(xhr.responseText); const { floor } = lastClicked; if (res.isCorrect) { nextDoorIndex[floor + 1] = 0; } else { nextDoorIndex[floor]++; } } catch {} }); return send.apply(xhr, arguments); }; return xhr; } WrappedXHR.prototype = OriginalXHR.prototype; window.XMLHttpRequest = WrappedXHR; })(); async function loop() { while (!stopFlag) { const floor = getCurrentFloor(); if (floor != null) { clickNextDoor(floor); } await sleep(150); } } window.addEventListener('keydown', e => { if (e.key === 'Escape') stopFlag = true; }); loop(); })();
|



