스크립트¶
이 프로그램에 필요한 최소한의 스크립트 기능을 구현하여 사용합니다. 멀티 로더에서 반복작업을 자동화하기 위해서 자체 구현한 스크립트 기능입니다. 명령어 처리기에서는 아래의 스크립트 명령어들만 처리할 수 있으며 문법을 정확하게 지켜야 동작합니다. 명령어 간에는 콤마(,)로 파라미터 간에는 공백문자(스페이스)로 구분합니다.
문자열 값 쓰기 (따옴표·공백·특수문자)¶
copy, write, log 처럼 글자를 다루는 명령에 값을 넣을 때 알아 둬야 할 규칙입니다.
스크립트가 처리되는 순서가 아래와 같아서, 값에 특정 글자가 들어가면 명령이 중간에 잘립니다.
주석 제거(
#) → 콤마로 명령 나누기(,) → 변수 치환({ }) → 공백으로 파라미터 나누기
공백이 든 값은 따옴표로 묶습니다¶
파라미터는 공백으로 나뉘므로, 공백이 든 값은 " 나 ' 로 묶어야 한 덩어리가 됩니다.
묶은 따옴표는 입력될 때 벗겨집니다.
단, copy 와 log 는 따옴표를 벗기지 않습니다. 이 둘은 명령어 뒤의 줄 전체를 그대로
쓰기 때문에 공백이 이미 그대로 살아 있고, 따옴표를 쓰면 따옴표까지 값에 들어갑니다.
copy hello world # 'hello world' 가 복사됩니다 (따옴표 필요 없음)
copy "hello world" # '"hello world"' 가 복사됩니다 (따옴표까지 복사됨)
값에 쓸 수 없는 글자: 콤마(,)와 샵(#)¶
이 둘은 빠져나갈 방법이 없습니다. 값에 넣으면 명령이 거기서 잘립니다.
| 글자 | 무슨 일이 일어나나 |
|---|---|
, |
명령을 나누는 기호입니다. copy pa,ss 는 copy pa 와 ss 두 명령이 됩니다 |
# |
주석 시작입니다. copy pa#ss 는 copy pa 가 됩니다 |
계정 비밀번호나 게임 방 제목에 , 나 # 이 들어 있으면 스크립트로 입력할 수 없습니다.
다른 글자로 바꿔 주세요.
# 만 혼자 있는 줄은 쓰지 마세요
주석을 지우는 규칙이 # 뒤에 글자가 있을 때만 지우도록 되어 있어서, # 하나만 있는 줄은
남습니다. 남은 # 이 다음 줄과 붙어 그 줄의 명령을 통째로 먹어 버립니다.
줄을 비우고 싶으면 빈 줄로 두세요. 문법 검사 버튼을 누르면 이 경우를 잡아 줍니다.
변수 { } 는 파라미터를 나누기 전에 바뀝니다¶
{password} 같은 변수는 값으로 먼저 치환되고, 그 결과를 가지고 파라미터를 나눕니다.
그래서 값에 공백이 있으면 치환된 뒤에 쪼개집니다.
공백이 들어갈 수 있는 값(비밀번호 등)은 copy 로 클립보드에 넣고 붙여넣는 쪽이 안전합니다.
기본으로 들어 있는 로그인 스크립트도 그렇게 되어 있습니다.
정의되지 않은 변수({abc})는 바뀌지 않고 글자 그대로 남으며, 로그에 경고가 남습니다.
역슬래시(\)와 따옴표¶
- 역슬래시는 특별한 뜻이 없습니다.
pa\ss는 그대로pa\ss로 입력됩니다. - 따옴표로 묶은 값 안에 같은 따옴표를 넣을 수는 없습니다. 큰따옴표가 든 값은
작은따옴표로 묶으세요(
'say "hi"').
마우스 명령어¶
click¶
마우스 왼쪽 버튼을 클릭합니다. 좌표가 지정되면 해당 좌표로 이동 후 클릭합니다. 좌표 값이 1 이하이면 창 크기 대비 비율로 계산합니다.
형식: click 또는 click [가로좌표] [세로좌표]
예제:
double_click¶
마우스 왼쪽 버튼을 더블클릭합니다.
형식: double_click 또는 double_click [가로좌표] [세로좌표]
right_click¶
마우스 오른쪽 버튼을 클릭합니다.
형식: right_click 또는 right_click [가로좌표] [세로좌표]
move¶
마우스 커서를 주어진 좌표로 이동합니다. click과 마찬가지로 1 이하면 비율로 계산합니다.
형식: move [가로좌표] [세로좌표]
키보드 명령어¶
send¶
주어진 키의 키보드 입력을 만듭니다. 특수키와 조합할 때는 +로 연결합니다 (+ 자체는 plus 사용).
사용 가능한 특수키: alt, alt gr, ctrl, left alt, left ctrl, left shift, left windows, right alt, right ctrl, right shift, right windows, shift, windows
형식: send [키]
예제:
press¶
주어진 키를 누른 상태로 유지합니다. release로 해제할 때까지 눌려진 상태가 유지됩니다. send는 press + release의 조합입니다.
형식: press [키]
release¶
눌려진 키를 해제합니다.
형식: release [키]
예제:
write¶
주어진 문자열의 키보드 입력을 만듭니다.
형식: write [문자열]
예제:
공백·특수문자 규칙은 문서 위쪽의 문자열 값 쓰기 절을 참고하세요.
유틸리티 명령어¶
copy¶
클립보드에 내용을 저장합니다.
형식: copy [문자열]
예제:
copy 는 명령어 뒤의 줄 전체를 그대로 쓰므로 따옴표로 묶지 마세요 — 따옴표까지 복사됩니다.
자세한 규칙은 문서 위쪽의 문자열 값 쓰기 절을 참고하세요.
sleep¶
지정한 시간(초, 실수) 만큼 멈추었다가 진행합니다.
형식: sleep [초]
예제:
beep¶
비프음을 냅니다.
형식: beep [주파수] [밀리초] — 생략하면 1000Hz / 100ms
예제:
play¶
wav 파일을 재생합니다.
형식: play
activate¶
스크립트가 실행 중인 창을 활성화하고 앞으로 가져옵니다.
형식: activate
resize¶
창의 크기 또는 위치를 변경합니다.
형식: resize [너비] [높이] 또는 resize [x좌표] [y좌표] [너비] [높이]
count¶
게임 번호를 증가하거나 감소합니다.
형식: count plus 또는 count minus
log¶
스크립트 디버깅용 로그를 출력합니다. 프로그램 로그에 [SCRIPT] 접두사로 기록됩니다.
형식: log [메시지]
예제:
반복 명령어¶
loop¶
주어진 핸들 리스트를 순회하며 end까지 반복합니다.
형식: loop [핸들 리스트] ~ end
| 핸들 리스트 | 설명 |
|---|---|
| {all_games} | 모든 게임 목록, {master_game}: 스크립트를 실행한 게임 |
| {slave_games} | {all_games}에서 {master_game}이 빠진 목록 |
| {slave0} ~ | 활성화된 게임에 대응 (계정 목록 순) |
예제:
for¶
조건 없이 주어진 구간을 반복합니다. 카운터 변수명을 지정하면 반복 인덱스를 {변수명}으로 사용할 수 있습니다.
형식: for [시작] [끝] ~ end 또는 for [변수명] [시작] [끝] ~ end
예제:
while¶
조건이 참인 동안 반복합니다. 조건은 매 반복마다 다시 평가됩니다. 무한 루프 방지를 위해 최대 10,000회까지 반복합니다.
형식: while [조건] ~ end
예제:
while과 break를 조합하여 특정 조건에서 루프를 중단하는 예제:
set sum 0,
set i 1,
while {i} <= 100,
set sum = {sum} + {i},
if {sum} > 1000, # 합이 1000 초과 시 중단
break,
end,
set i = {i} + 1,
end,
beep
break¶
현재 실행 중인 루프(loop, for, while)를 즉시 빠져나옵니다.
형식: break
예제:
exit¶
스크립트 실행을 즉시 종료합니다. 루프나 조건문 내부 어디에서든 사용할 수 있습니다.
형식: exit
예제:
return¶
스크립트 실행을 종료하면서 반환값을 글로벌 변수 {_return}에 저장합니다. exec_script_file로 호출한 서브 스크립트에서 결과를 돌려줄 때 유용합니다. 값 없이 사용하면 exit와 동일하게 동작합니다.
형식: return [값]
예제:
호출 측에서 반환값 사용:
조건 명령어¶
if¶
조건으로 분기합니다. 조건은 python 문법을 사용합니다. 중첩 가능합니다.
형식: if [조건] ~ else ~ end
예제:
loop {all_games},
execute exit,
end,
loop {master_game},
execute create,
end,
if ‘{slave_games}’ != ‘’, # 보조 게임이 있는 경우에만
loop {slave_games},
execute join,
end,
end,
sleep 4.5,
activate {master_game},
beep
중첩 예제:
set slave_count = len(‘{slave_games}’.split()),
if {slave_count} > 0,
loop {slave_games},
execute join,
end,
if {slave_count} >= 3, # 보조 3개 이상이면 오래 대기
sleep 8,
else,
sleep 4.5,
end,
end
변수 명령어¶
set¶
스크립트 실행 중 사용할 로컬 변수를 설정합니다. 스크립트가 끝나면 초기화됩니다. 설정된 변수는 {변수명} 형태로 사용할 수 있습니다.
형식: set [변수명] [값] 또는 set [변수명] = [표현식]
set 변수명 값— 문자열 값을 그대로 할당set 변수명 = 표현식— 산술/비교 표현식을 계산한 결과를 할당
예제:
set sum 0, # sum 변수에 0 할당
set name hello, # name 변수에 "hello" 할당
set sum = {sum} + 10, # sum = 0 + 10 → "10"
set result = max(100, 200), # result = "200"
1 ~ 100까지 합산하는 예제:
참고:
{game_name},{master_game},{slave0}등 시스템 예약 변수는 set으로 덮어쓸 수 없습니다.
gset¶
글로벌 변수를 설정합니다. 프로그램이 실행되는 동안 유지되며 다른 스크립트에서도 공유됩니다.
형식: gset [변수명] [값] 또는 gset [변수명] = [표현식] 또는 gset [변수명] ?= [값]
gset 변수명 값— 문자열 값 할당gset 변수명 = 표현식— 표현식 계산 결과 할당gset 변수명 ?= 값— 변수가 미정의일 때만 할당 (초기화용)
예제:
홀짝 교대 실행 예제 (auto 스크립트에서 매번 다른 동작):
gset toggle ?= 0,
gset toggle = 1 - {toggle}, # 0↔1 전환
loop {all_games},
execute exit,
end,
loop {master_game},
execute create,
end,
if ‘{slave_games}’ != ‘’,
loop {slave_games},
execute join,
end,
sleep 4.5,
if {toggle} == 1, # 홀수 회차: 레거시 모드 전환
loop {slave_games},
execute legacy,
end,
end,
end,
activate {master_game},
beep
현재 핸들 값을 전역변수로 저장하는 예제:
gset master {master_game},
gset s0 {slave0},
gset s1 {slave1},
gset s2 {slave2},
gset s3 {slave3},
beep
참고: 변수 우선순위는 시스템 예약 변수 > 로컬 변수(set) > 글로벌 변수(gset) 순서입니다.
실행 명령어¶
execute¶
다른 스크립트를 실행합니다. 지정한 스크립트는 사전에 스크립트 관리에서 생성해야 합니다.
형식: execute [스크립트명]
예제:
exec_ahk¶
AHK 스크립트를 실행합니다. 창 핸들(hwnd)이나 게임명, 패스워드 등을 추가 파라미터로 전달할 수 있습니다.
형식: exec_ahk [스크립트명.ahk] [파라미터...]
예제:
sample.ahk — 전달받은 창 핸들로 최대화하고 메시지를 출력하는 AHK 스크립트:
for n, param in A_Args ; For each parameter:
{
WinMaximize, ahk_id %param%
WinActivate, ahk_id %param%
MsgBox Parameter number %n% is %param% is maxmized and activated.
}
exec_script_file¶
확장자 .script인 스크립트 파일을 실행합니다.
형식: exec_script_file [파일명]
예제:
화면 요소 명령어 (배틀넷 런처)¶
배틀넷 런처는 Qt 창 안에 Chromium(웹 화면)이 들어 있는 구조라, 입력칸이 윈도우 컨트롤이 아니라 그림입니다. 그래서 좌표로 클릭할 수밖에 없었고, 런처가 업데이트되거나 로그인 상태에 따라 창 높이가 바뀌면(653px ↔ 631px) 좌표가 어긋났습니다.
아래 두 명령은 화면 요소를 이름(DOM id)으로 찾습니다. 좌표가 아니라 이름이라 런처 업데이트에 덜 깨집니다.
배틀넷 런처 전용입니다
게임 화면(D2R)에는 쓸 수 없습니다. D2R은 DirectX로 직접 그리므로 요소라는 것이 없습니다. 게임 화면은 getpixel · imgfind 같은 화면 인식 명령을 씁니다.
uia_find¶
요소의 위치를 찾아 좌표를 변수에 담습니다. 글자 입력은 지금처럼 click + write 로 합니다.
형식: uia_find [선택자] [x변수] [y변수] [타임아웃초] [폴백x] [폴백y]
- 타임아웃 기본값은 5초입니다.
- 폴백 좌표를 주면 못 찾았을 때 그 좌표를 대신 넣습니다.
- 폴백이 없고 못 찾으면 변수에
-1이 들어갑니다. 그래서if {x} > 0으로 판정할 수 있습니다. - 좌표는
click과 같은 기준(창 기준)이라 그대로 넘기면 됩니다.
| 선택자 | 가리키는 것 |
|---|---|
accountName |
계정(이메일/전화번호) 입력칸 |
password |
비밀번호 입력칸 |
submit |
로그인 / 계속 버튼 |
play-btn-main |
메인 화면의 실행 버튼 |
game-nav-btn-OSI |
D2R 탭 |
@switch_account |
'계정 전환' 링크 (id가 없어 구조로 찾는 예약 선택자) |
예제:
uia_find password px py 5 0.5 0.45, # 못 찾으면 비율 좌표 0.5 0.45 사용
if {px} > 0,
click {px} {py},
write {account_password},
end
이름은 번역되지 않는 것으로 고르세요
버튼에 보이는 글자(로그인, 비밀번호)는 언어에 따라 바뀝니다. 위 선택자들은 화면에 보이지 않는 내부 이름이라 언어와 무관합니다.
uia_invoke¶
버튼이나 링크를 직접 누릅니다. 좌표를 거치지 않습니다.
형식: uia_invoke [선택자] [타임아웃초]
예제:
글자 입력에는 쓰지 마세요
요소에 값을 직접 넣는 방식은 페이지의 스크립트가 입력 이벤트를 받지 못해, 글자는 보이는데 로그인은 안 되는 상태가 됩니다. 입력은 반드시 click + write 로 하세요.
화면 인식 명령어¶
getpixel¶
지정한 좌표의 픽셀 RGB 값을 변수에 저장합니다. 좌표가 1 이하이면 비율 좌표로 처리합니다.
형식: getpixel [x] [y] [r변수] [g변수] [b변수]
예제:
getpixelavg¶
지정한 좌표 주변 영역의 평균 RGB 값을 변수에 저장합니다. 반지름(픽셀)만큼의 영역을 샘플링합니다.
형식: getpixelavg [x] [y] [반지름] [r변수] [g변수] [b변수]
예제:
debugcapture¶
현재 게임 화면을 DXGI 캡처하여 이미지로 저장합니다. getpixel/getpixelavg 좌표를 확인할 때 유용합니다.
형식: debugcapture [옵션] [x1] [y1] [x2] [y2] ...
옵션:
crop=x,y,w,h— 지정한 영역만 부분 캡처 (비율 좌표 가능)file=파일명— 저장할 파일명 지정 (기본:debug_capture.png)- 좌표쌍 — 해당 위치에 노란색 마커를 표시
예제:
debugcapture, # 전체 화면 캡처 (debug_capture.png)
debugcapture 0.270 0.897 0.729 0.897, # 체력/마나 오브 위치에 마커 표시
debugcapture file=health_orb.png crop=0.2,0.85,0.15,0.1, # 체력 오브 영역만 부분 캡처
debugcapture file=slots.png 0.591 0.965 0.676 0.965, # 슬롯 위치에 마커 표시, 파일명 지정
imgcmp¶
두 이미지 파일을 비교하여 유사도(0~100%)를 변수에 저장합니다. 픽셀 단위로 비교하며, 크기가 다르면 자동으로 리사이즈합니다.
형식: imgcmp [파일1] [파일2] [결과변수]
예제:
debugcapture file=before.png, # 기준 이미지 저장
sleep 3,
debugcapture file=after.png, # 현재 화면 저장
imgcmp before.png after.png sim, # 비교 → sim에 유사도 저장
if {sim} > 95, # 95% 이상이면
log 화면 변화 없음 (유사도: {sim}%),
else,
log 화면이 변경됨 (유사도: {sim}%),
end
imgfind¶
현재 게임 화면에서 템플릿 이미지를 찾아 일치도(0~100%)와 중앙 좌표를 변수에 저장합니다. 화면을 1280x720으로 리사이즈한 뒤 FFT 기반 정규화 교차 상관(NCC)으로 매칭하므로, 게임 해상도와 무관하게 동일한 기준 이미지를 사용할 수 있습니다.
형식: imgfind [템플릿파일] [결과변수] [cx변수 cy변수] [w변수 h변수] [rx변수 ry변수]
옵션:
file=파일명— 현재 화면 대신 저장된 이미지 파일에서 검색
결과 변수:
결과변수— 일치도 (0~100)cx변수 cy변수— 찾은 영역의 중앙 좌표 (1280x720 기준 픽셀)w변수 h변수— 템플릿 크기 (1280x720 기준 픽셀)rx변수 ry변수— 찾은 영역의 중앙 좌표 (0.0~1.0 비율, click에 바로 사용 가능)
기준 이미지 준비
기준(템플릿) 이미지는 1280x720 스케일에서 캡처해야 합니다. 도구 → Image Capture 메뉴에서 게임 화면을 캡처하고 영역을 선택하여 저장할 수 있습니다.
예제:
# 로비 버튼 아이콘이 화면에 있는지 확인
imgfind lobby_btn.png score,
if {score} > 80,
log 로비 버튼 발견 (일치도: {score}%),
end
# 비율 좌표로 바로 클릭 (해상도 무관)
imgfind lobby_btn.png score cx cy w h rx ry,
if {score} > 80,
click {rx} {ry},
end
# 픽셀 좌표 사용 (게임이 1280x720일 때)
imgfind lobby_btn.png score cx cy,
if {score} > 80,
click {cx} {cy},
end
# 저장된 화면 파일에서 검색
debugcapture file=screen.png,
imgfind file=screen.png lobby_btn.png score cx cy,
readtext¶
화면 영역 또는 이미지 파일에서 텍스트를 인식(OCR)하여 변수에 저장합니다. Windows OCR API를 사용합니다.
형식: readtext [x] [y] [w] [h] [결과변수] 또는 readtext file=[파일명] [결과변수]
옵션:
lang=언어코드— OCR 언어 지정 (예:en,ko,ja)file=파일명— 이미지 파일에서 읽기 (화면 캡처 대신)
예제:
readtext 0.3 0.1 0.4 0.05 title, # 화면 영역에서 텍스트 읽기
readtext 0.3 0.1 0.4 0.05 title lang=ko, # 한국어로 읽기
readtext file=capture.png result, # 파일에서 읽기
log 인식된 텍스트: {title}
활용 예제 — 화면 상태 감지:
debugcapture file=screen.png crop=0.4,0.0,0.2,0.05, # 화면 상단 영역 캡처
readtext file=screen.png status lang=en, # 텍스트 읽기
log 현재 상태: {status}
Windows OCR 언어팩
OCR 기능을 사용하려면 Windows에 해당 언어팩이 설치되어 있어야 합니다. Windows 설정 → 시간 및 언어 → 언어 및 지역에서 추가할 수 있습니다.
gamestate¶
지금 게임이 어느 화면에 있는지 가려 변수에 넣습니다. 값은 lobby(대기실) · charselect(캐릭터 선택) · ingame(게임 안) · loading(로딩/전환) · unknown(가릴 수 없음) 중 하나입니다.
형식: gamestate [결과변수]
예제:
양쪽 모두 따옴표로
if "{st}" == "ingame", 처럼 변수 쪽에도 따옴표를 붙여야 합니다. if {st} == "ingame", 은 변수가 바뀐 뒤 if ingame == "ingame", 이 되어 비교가 되지 않고 항상 거짓이 됩니다.
어떻게 가리는가:
| 화면 | 판정 방법 |
|---|---|
ingame |
체력 오브가 붉고 마나 오브가 푸른지 — 게임 안에만 있는 HUD 입니다 |
loading |
화면 중앙이 거의 검은지 |
lobby / charselect |
저장된 기준 화면과 비교 |
대기실과 캐릭터 선택은 규칙으로 가릴 수 있는 특징이 없어서, 저장해 둔 기준 화면과 견주어 더 닮은 쪽을 고릅니다. 바닐라(모드 없음) 기준 화면은 프로그램에 들어 있습니다.
gamestate learn¶
모드가 대기실이나 캐릭터 선택 화면을 바꿔 놓으면 기준 화면이 어긋나 unknown 이 나옵니다. 그때 지금 보고 있는 화면을 기준으로 다시 가르칩니다.
형식: gamestate learn [화면이름] — 화면이름은 lobby · charselect · ingame
가르치는 방법:
- 게임을 대기실 화면에 둡니다
gamestate learn lobby,한 줄만 있는 스크립트를 실행합니다- 게임을 캐릭터 선택 화면으로 옮기고
gamestate learn charselect,를 실행합니다
기준 화면은 모드별로 따로 저장되므로(계정의 모드 칸 값이 기준), 모드를 여럿 섞어 쓰면 쓰는 조합마다 한 번씩 가르쳐야 합니다. 저장 위치는 실행 파일 옆 settings/screen_states.json 이고, 프로그램에 들어 있는 기본값보다 우선합니다. 화면 하나만 다시 가르쳐도 그 화면만 바뀝니다.
모르겠으면 unknown
닮은 정도가 모자라거나 두 화면이 비슷하게 나오면 억지로 고르지 않고 unknown 을 돌려줍니다. 엉뚱한 화면으로 단정하면 스크립트가 엉뚱한 곳을 클릭하기 때문입니다. unknown 이 계속 나오면 위 방법으로 다시 가르쳐 주세요.
로그에 판정 근거가 남습니다
도움말 → 로그 보기에 오브 색·화면 중앙 색·기준 화면과의 거리가 함께 적힙니다. 판정이 틀릴 때 무엇을 보고 그랬는지 알 수 있습니다.
스크립트 설정¶
환경설정 → 환경설정 변경 → 스크립트 관리에서 스크립트를 변경하거나 추가, 삭제할 수 있습니다. 내부적으로 사용하는 스크립트는 [System] 으로 시작하고 수정은 가능하지만 삭제할 수 없습니다.

스크립트 예제¶
게임 만들기¶
activate, # 현재 게임 클라이언트 활성화
count plus, # 게임 번호를 하나 증가
copy {game_name}, # 게임 이름을 클립보드에 복사
click {create_x} {create_y}, # 대기실의 "게임 생성" 탭 좌표 클릭 {create_x} {create_y} 값은 자동 계산 대체됨
click {create_title_x} {create_title_y}, # 대기실의 "게임 생성" 탭에서 "게임 이름" 입력창 클릭
send ctrl+a, # 이전 게임 이름을 삭제하기 위해 전체 선택(ctrl+a)
send del, # 이전 게임 이름 삭제
send ctrl+v, # 클립보드에서 게임 이름 붙여넣기
sleep 0.1, # 0.1초 대기
copy {game_password}, # 비밀번호를 클립보드에 복사
send tab, # 비밀번호 입력창으로 이동
send ctrl+a, # 이전 비밀번호를 삭제하기 위해 전체 선택(ctrl+a)
send del, # 이전 패스워드 삭제
send ctrl+v, # 클립보드에서 비밀번호 붙여넣기
send enter, # 게임 생성 (enter를 누르면 게임이 생성됨)
sleep 0.2 # 0.2초 대기

- 게임을 생성할 캐릭터를 대기실에 위치시킵니다.
- 난이도 선택, 레벨 차이, 친구참가 허용 등 기본적인 설정을 합니다.
-
단축키가 설정되어 있으면
ctrl+n, 해당 계정(들)을 선택 후 오른쪽 마우스로 컨텍스트 메뉴를 활성화 한 후에게임 옵션에서게임 만들기를 선택합니다.
-
기능이 정상적으로 동작하면
환경설정 변경→게임 정보에 입력한 정보로 게임을 만들게 됩니다. 게임 생성시 게임번호(Count)가 하나씩 증가합니다. - 여러 계정 목록을 선택 후 "게임 생성"을 하는 경우에는 게임번호가 하나씩 증가하면서 별도 게임을 만들게 됩니다. (우버 디아블로용으로 여러 게임을 만드는 경우에 편리)
방 제목에 암호가 입력되는 등 입력 문제가 발생하는 경우
클립보드 방식(copy + send ctrl+v)에서 문제가 발생하면 write 명령어로 변경하세요.
write는 키보드로 직접 타이핑하는 방식이므로 클립보드 충돌 없이 안정적으로 입력됩니다.
예: copy {game_name} + send ctrl+v → write {game_name}
게임 참가¶
activate, # 현재 게임 클라이언트 활성화
copy {game_name}, # 게임 이름을 클립보드에 복사
click {join_x} {join_y}, # 대기실의 "게임 참가" 탭 좌표 클릭 {join_x} {join_y} 값은 자동 계산 대체됨
click {join_title_x} {join_title_y}, # 대기실의 "게임 참가" 탭에서 "게임 이름" 입력창 클릭
send ctrl+a, # 이전 게임 이름을 삭제하기 위해 전체 선택(ctrl+a)
send del, # 이전 게임 이름 삭제
send ctrl+v, # 클립보드에서 게임 이름 붙여넣기
sleep 0.1, # 0.1초 대기
copy {game_password}, # 비밀번호를 클립보드에 복사
send tab, # 비밀번호 입력창으로 이동
send ctrl+a, # 이전 비밀번호를 삭제하기 위해 전체 선택(ctrl+a)
send del, # 이전 패스워드 삭제
send ctrl+v, # 클립보드에서 비밀번호 붙여넣기
send enter, # 게임 참가
sleep 0.2 # 0.2초 대기
- 참가할 게임이 게임 정보로 미리 만들어져 있어야 합니다.
- 위에서 게임을 생성한 캐릭터와 다른 캐릭터를 대기실에 위치시킵니다.
- 단축키가 설정되어 있으면
ctrl+j, 해당 계정(들)을 선택 후 오른쪽 마우스로 컨텍스트 메뉴를 활성화 한 후에게임 옵션에서게임 참가를 선택합니다. - 기능이 정상적으로 동작하면
환경설정 변경→게임 정보에 입력한 정보로 입장하게 됩니다.
※ 여러 계정 목록을 선택 후 "게임 참가"하는 경우 현재 "게임 정보"의 게임 하나에 모두 입장하게 됩니다.
게임 나가기¶
activate, # 현재 게임 클라이언트 활성화
send space, # 캐릭터 상태나 인벤토리 창을 닫음
send esc, # 게임 메뉴 팝업
sleep 0.1, # 0.1초 대기
click 0.5 0.436, # 나가기 버튼 클릭 (비율 좌표)
sleep 0.2 # 0.2초 대기
- 캐릭터가 게임에 들어와 있는 상태(게임 중)이어야 합니다.
- 단축키가 설정되어 있으면 "ctrl+x", 적용할 계정(들)을 선택 후 오른쪽 마우스로 컨텍스트 메뉴를 활성화 한 후에
게임 옵션에서게임 나가기를 선택합니다. -
기능이 정상적으로 동작하면 캐릭터는 대기실 화면에 있게 됩니다.
-
게임 중에 "게임 나가기"를 두 번 실행하면 캐릭터 선택 화면으로 나가게 됩니다.
레거시 모드로 전환¶
- 캐릭터가 게임에 들어와 있는 상태(게임 중)이어야 합니다.
-
단축키가 설정되어 있으면
ctrl+l, 계정(들)을 선택 후 오른쪽 마우스로 컨텍스트 메뉴를 활성화 한 후에게임 옵션에서레거시 모드로 전환을 선택합니다. -
악마술사의 군림에서는 레거시 모드가 지원되지 않습니다.
자동(auto) 스크립트¶
loop {all_games}, # 모든 게임에 대해서 순회
execute exit, # 게임 나가기 스크립트 실행
end,
loop {master_game}, # 주 게임에 대해서 순회
execute create, # 게임 생성 스크립트 실행
end,
loop {slave_games}, # 보조 게임들만 순회
execute join, # 게임 참가 스크립트 실행
end,
sleep 4.5, # 참가완료까지 4.5초 대기
loop {slave_games}, # 보조 게임들만 순회
execute legacy, # 레거시 모드로 전환
end,
activate {master_game}, # 주 게임 활성화
beep
위 스크립트는 여러 작업을 자동화 한 것입니다. 하나씩 따라해 봐야 이해가 쉽습니다.
- 메인 캐릭터와 서브 캐릭터가 모두 게임에 들어와 있는 상태(게임 중) 이어야 합니다.
- 단축키가 설정되어 있으면
ctrl+a, 또는게임 옵션에서자동을 선택합니다. -
기능이 정상적으로 동작하면 모든 캐릭터는 새로 만들어진 게임에 들어와 있어야 합니다.
-
단축키로 실행 시 활성화된 게임에 계정이 이 메인 캐릭터로 게임을 만들게 됩니다. 컨텍스트 메뉴에서 실행 시에는 클릭한 계정이 메인 캐릭터가 됩니다. 게임 나가기, 게임 만들기, 게임 참가, 레거시 모드로 전환을 반복합니다.
자동(auto) 스크립트 — 부캐 전용 모드¶
주 게임이 이미 만들어져 있는 상태에서, 게임을 새로 생성하지 않고 모든 클라이언트가 참가만 수행하는 스크립트입니다.
loop {all_games}, # 모든 게임에 대해서 순회
execute exit, # 게임 나가기 스크립트 실행
end,
count plus, # 게임 번호 증가 (create 없이 번호만 맞춤)
loop {all_games}, # 모든 게임에 대해서 순회 (전원 참가)
execute join, # 게임 참가 스크립트 실행
end,
sleep 4.5, # 참가완료까지 4.5초 대기
activate {master_game}, # 주 게임 활성화
beep
- 다른 계정이 이미 게임을 만든 상태에서 사용합니다.
count plus로 게임 번호만 증가시킨 후 전원join을 실행합니다.
게임 나가기 (키보드 방식)¶
마우스 클릭 대신 키보드 방향키로 나가기를 수행하는 스크립트입니다. 마우스 좌표 문제가 있을 때 대안으로 사용할 수 있습니다.
activate, # 현재 게임 클라이언트 활성화
send space, # 캐릭터 상태나 인벤토리 창을 닫음
send esc, # 게임 메뉴 팝업
send up, # 나가기 버튼 위치로 이동
send up,
send up,
send down,
send enter # 나가기 버튼 선택
체력/마나 자동 물약 (check_status)¶
체력/마나 오브의 색상을 감시하여 부족할 때 자동으로 물약을 사용하는 스크립트입니다. 스케줄 대시보드에 등록하여 주기적으로(1~3초 간격) 실행합니다.
activate, # 현재 게임 클라이언트 활성화
getpixelavg 0.270 0.897 5 r g b, # 체력 오브 중심 5px 평균 색상 → r, g, b
if {r} < 100, # 체력 오브 R값이 100 미만이면 (체력 부족)
send 1, # 물약 슬롯 1번 사용 (체력 포션)
end,
getpixelavg 0.729 0.897 5 r g b, # 마나 오브 중심 5px 평균 색상 → r, g, b
if {b} < 100, # 마나 오브 B값이 100 미만이면 (마나 부족)
send 3, # 물약 슬롯 3번 사용 (마나 포션)
end
동작 원리:
- DXGI 캡처로 오브 유리 중심 픽셀의 평균 색상을 읽어 체력/마나 잔량을 판단합니다.
- 체력 오브 좌표:
(0.270, 0.897), 마나 오브 좌표:(0.729, 0.897)(비율 좌표) - 정상 수치: 체력 R≈117+, 마나 B≈112+ / 위험: R<100 또는 B<100
- 물약 슬롯 배치: 1번=체력, 3번=마나
체력/마나 자동 물약 — 빈 슬롯 감지 (check_status2)¶
check_status의 개선판으로, 물약 슬롯이 비어있으면 다음 슬롯의 물약을 자동으로 사용합니다. 또한 순정 또는 모드에 따라 슬롯 좌표를 자동 분기합니다.
activate, # 현재 게임 클라이언트 활성화
if "{mod}" == "mymod", # mymod 모드명인 경우
gset slot1_x = 0.344, # 슬롯1 X 좌표 (체력 포션 1번)
gset slot2_x = 0.377, # 슬롯2 X 좌표 (체력 포션 2번)
gset slot3_x = 0.414, # 슬롯3 X 좌표 (마나 포션 1번)
gset slot4_x = 0.445, # 슬롯4 X 좌표 (마나 포션 2번)
gset slot_y = 0.958, # 슬롯 공통 Y 좌표
else, # 바닐라 모드인 경우
gset slot1_x = 0.591, # 슬롯1 X 좌표
gset slot2_x = 0.613, # 슬롯2 X 좌표
gset slot3_x = 0.645, # 슬롯3 X 좌표
gset slot4_x = 0.676, # 슬롯4 X 좌표
gset slot_y = 0.965, # 슬롯 공통 Y 좌표
end,
getpixelavg 0.270 0.897 5 r g b, # 체력 오브 중심 5px 평균 색상 → r, g, b
if {r} < 100, # 체력 부족 감지 (R < 100)
getpixel {slot1_x} {slot_y} sr sg sb, # 슬롯1 픽셀 색상 확인
if {sr} + {sg} + {sb} > 120, # 슬롯1에 포션이 있으면
send 1, # 슬롯1 사용 (체력 포션)
else, # 슬롯1이 비어있으면
send 2, # 슬롯2 사용 (예비 체력 포션)
end,
end,
getpixelavg 0.729 0.897 5 r g b, # 마나 오브 중심 5px 평균 색상 → r, g, b
if {b} < 100, # 마나 부족 감지 (B < 100)
getpixel {slot3_x} {slot_y} sr sg sb, # 슬롯3 픽셀 색상 확인
if {sr} + {sg} + {sb} > 120, # 슬롯3에 포션이 있으면
send 3, # 슬롯3 사용 (마나 포션)
else, # 슬롯3이 비어있으면
send 4, # 슬롯4 사용 (예비 마나 포션)
end,
end
check_status와의 차이점:
| 기능 | check_status | check_status2 |
|---|---|---|
| 체력 부족 시 | 슬롯 1번 사용 | 슬롯 1번 사용, 비어있으면 슬롯 2번 자동 전환 |
| 마나 부족 시 | 슬롯 3번 사용 | 슬롯 3번 사용, 비어있으면 슬롯 4번 자동 전환 |
| 모드 지원 | 바닐라 전용 | 바닐라 / mymod 자동 분기 |
| 빈 슬롯 감지 | 미지원 | 슬롯 픽셀 색상으로 판별 |
빈 슬롯 판정 기준:
- 비어있을 때 RGB: ~26-37 (합계 78-111, 어두운 색)
- 포션이 있을 때 RGB: 155+ (합계 500+, 밝은 색)
- 판정 기준: RGB 합계 > 120 → 포션 있음
권장 슬롯 배치:
| 슬롯 | 용도 |
|---|---|
| 1번 | 체력 포션 (메인) |
| 2번 | 체력 포션 (예비) |
| 3번 | 마나 포션 (메인) |
| 4번 | 마나 포션 (예비) |
사용 방법:
- 환경설정 → 스케줄에서 check_status 또는 check_status2 스크립트를 선택합니다.
- 실행 주기를 설정합니다 (1~3초 간격 권장).
- 모드(바닐라/mymod)는 계정 설정의 mod 값에 따라 자동 판별되므로 별도 설정이 필요 없습니다.
주의사항
- 화면이 가려지거나 인벤토리가 열려 있으면 오브/슬롯 색상 인식이 정확하지 않을 수 있습니다.
- 순정(바닐라) 외 다른 모드를 사용하는 경우, 슬롯 좌표가 다를 수 있어 스크립트를 커스텀 수정해야 합니다.
버프 스킬 자동 사용 (custom1)¶
보조 무기로 전환 후 함성/버프 스킬을 사용하고 주 무기로 복귀하는 스크립트입니다. 스킬 단축키(F8~F11)는 게임 내 설정에 맞게 수정해서 사용합니다.
activate, # 현재 게임 클라이언트 활성화
send w, # 보조 무기 전환 (소집)
sleep 0.3,
send f9, # 전투명령 (f9 할당)
sleep 0.1,
send f9,
sleep 0.1,
send f10, # 전투지시 (f10 할당)
sleep 0.1,
send f10,
sleep 0.1,
send f11, # 전투의 함성 (f11 할당)
sleep 0.1,
send f11,
sleep 0.1,
send f8, # 에너지 쉴드 (f8 할당)
sleep 0.5,
send w # 주 무기 전환
도박용 거래 (custom2)¶
상점에서 물건을 구매하고 인벤토리에서 바로 판매하는 것을 반복하는 도박용 스크립트입니다. 좌표는 게임 해상도와 상점 위치에 따라 수정이 필요합니다.
activate, # 현재 창 활성화
for 1 100, # 100회 반복
right_click 844 398, # 상점 물건 클릭 (좌표 수정 필요)
sleep 0.1,
press ctrl, # 컨트롤키를 누르고 있음
click 2333 976, # 인벤토리 물건 클릭 (좌표 수정 필요)
release ctrl, # 컨트롤키를 뗌
sleep 0.1,
end
이미지 찾아서 서브 클라이언트 클릭 (custom3)¶
메인 게임 화면에서 특정 이미지(캐릭터 등)를 찾고, 서브 게임 클라이언트들을 순회하며 해당 좌표를 클릭한 뒤 메인 게임으로 포커스를 되돌리는 스크립트입니다.
loop {slave_games}, # 서브 게임들 순회
activate, # 서브 게임 활성화
sleep 0.2, # 화면 전환 대기
imgfind target.png score cx cy w h rx ry, # 현재 서브 화면에서 이미지 검색
if {score} > 80, # 일치도 80% 이상이면
click {rx} {ry}, # 비율 좌표로 클릭 (해상도 무관)
log 클릭 완료 (일치도: {score}%, 좌표: {rx} {ry}),
else,
log 이미지를 찾지 못함 (일치도: {score}%),
end,
sleep 0.1,
end,
activate {master_game}, # 메인 게임으로 포커스 복귀
beep
target.png는 도구 → Image Capture에서 1280x720 기준으로 캡처한 기준 이미지입니다.- 각 서브 클라이언트 화면에서 개별로 이미지를 검색하므로 클라이언트마다 위치가 달라도 정확히 클릭합니다.
- 비율 좌표(
rx,ry)를 사용하므로 해상도가 달라도 동작합니다. - 일치도 기준값(80)은 상황에 따라 조정합니다.
지금 어느 화면인지 확인 (example_gamestate)¶
지금 대기실인지 캐릭터 선택 화면인지 게임 안인지 소리와 로그 두 가지로 알려 줍니다. gamestate 가 이 PC 에서 제대로 가리는지 확인할 때 씁니다.
# 지금 어느 화면인지 소리와 로그로 알려 준다.
# 높은 삐 = 게임 안 중간 삐 = 캐릭터 선택
# 낮은 삐 = 대기실 긴 삐 = 로딩
# 삐삐 두 번 = 가릴 수 없음 (학습이 필요하다)
# 판정 근거는 도움말 > 로그 보기 에 남는다.
activate, # 화면에 보이는 것을 찍으므로 게임 창을 앞으로
sleep 1.0, # 창이 올라오고 화면이 갱신될 틈
gamestate st,
if "{st}" == "ingame",
log [화면] 게임 안 (인게임),
beep 1400 150,
end,
if "{st}" == "charselect",
log [화면] 캐릭터 선택,
beep 1000 150,
end,
if "{st}" == "lobby",
log [화면] 대기실 (게임 목록),
beep 700 150,
end,
if "{st}" == "loading",
log [화면] 로딩 또는 전환 중,
beep 500 300,
end,
if "{st}" == "unknown",
log [화면] 가릴 수 없음 - 기준 화면을 학습해야 한다,
log 대기실에서 실행 : gamestate learn lobby,
log 캐릭터 선택에서 실행 : gamestate learn charselect,
beep 400 120,
sleep 0.1,
beep 400 120,
end
쓰는 방법: 이 스크립트를 단축키에 배정해 두고(환경설정 → 단축키) 게임을 하면서 눌러 보면 됩니다. 게임을 전체화면으로 하고 있으면 로그 창이 가려지므로 소리로 알 수 있도록 만들었습니다.
activate 와 sleep 이 먼저 와야 합니다
gamestate 는 화면에 실제로 보이는 것을 찍습니다(DirectX 게임이라 다른 방법이 통하지 않습니다). 프로그램 창이 게임을 가린 채로 찍으면 프로그램 창이 찍혀 엉뚱한 결과가 나옵니다. 그래서 게임 창을 먼저 앞으로 보내고 잠깐 기다립니다.
- 소리가 안 나는 상태를 쓰고 있으면
beep줄을 지우고 로그만 보면 됩니다. unknown이 나오면 gamestate learn 으로 기준 화면을 가르쳐 주세요.