#샘플 코드
#Include <classMemory>
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; You can use this code to check if you have installed the class correctly.
if (_ClassMemory.__Class != "_ClassMemory")
{
msgbox class memory not correctly installed. Or the (global class) variable "_ClassMemory" has been overwritten
ExitApp
}
Gui, font,, arial
Gui, Add, GroupBox, x10 y10 w210 h120, 현황판
Gui, Add, Button, x10 y160 w105 h30 vSTART, START
Gui, Add, Button, x115 y160 w105 h30 vPAUSE, PAUSE
Gui, add, Text, x20 y30 vClassName w140, N/A
Gui, Add, Text, x20 y50 vBP w140 cBF8F00, BP: N/A
Gui, Add, Text, x20 y65 vHP w100 cRed, HP: N/A
Gui, Add, Progress, x20 y80 w80 h10 cRed BackgroundWhite Range0-100 vHBar
Gui, Add, Text, x110 y65 vMP w100 cBlue, MP: N/A
Gui, Add, Progress, x110 y80 w80 h10 cBlue BackgroundWhite Range0-100 vMBar
Gui, Add, Text, x43 y95 vHPotion w140, HP포션: N/A
Gui, Add, Text, x43 y110 vMPotion w140, MP포션: N/A
Gui, Add, Checkbox, x20 y95 w23 vUseItemHP
Gui, Add, Checkbox, x20 y110 w23 vUseItemMP
Gui, Add, Text, x10 y135 vMoney w100, 소지금: N/A
GuiControl,, START, START(F1)
GuiControl,, PAUSE, PAUSE(F2)
GuiControl, Enable, START
GuiControl, Disable, PAUSE
Gui, Show, w230 h200, Octopath Traveler Support
Gui, -MinimizeBox -MaximizeBox
return
GuiClose:
ExitApp
F1::
ButtonSTART:
GuiControl, Disable, START
GuiControl, Enable, PAUSE
PlayAndStop := 1
goto, PLAY
F2::
ButtonPAUSE:
GuiControl, Enable, START
GuiControl, Disable, PAUSE
PlayAndStop := 0
WinActivate, Octopath Traveler Support
goto, STOP
isMyTurn(ByRef character, ByRef characterName, ByRef myTurn, ByRef bpText, bp)
{
character := 0
characterName := "Enermy"
myTurn := 0
bpText := "○○○○○"
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 opilea.bmp
if(ErrorLevel = 0)
{
character := 1
characterName := "오필리아"
myTurn := 1
}
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 hanit.bmp
if(ErrorLevel = 0)
{
character := 2
characterName := "하닛"
myTurn := 1
}
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 terion.bmp
if(ErrorLevel = 0)
{
character := 3
characterName := "테리온"
myTurn := 1
}
if bp = 1
bpText := "●○○○○"
if bp = 2
bpText := "●●○○○"
if bp = 3
bpText := "●●●○○"
if bp = 4
bpText := "●●●●○"
if bp = 5
bpText := "●●●●●"
return
}
isMyMenu(ByRef i)
{
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *50 isMyTurn.png
if(ErrorLevel = 0)
{
i := 1
}
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 isMagic1.png
if(ErrorLevel = 0)
{
i := 31
}
return i
}
zKeySend(cnt)
{
loopCount := 1
if (cnt > 0)
{
loopCount := cnt
}
loop, %loopCount%
{
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
return
}
sKeySend(cnt)
{
loopCount := 1
if (cnt > 0)
{
loopCount := cnt
}
loop, %loopCount%
{
ControlSend,,{s}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
return
}
downKeySend(cnt)
{
loopCount := 1
if (cnt > 0)
{
loopCount := cnt
}
loop, %loopCount%
{
ControlSend,,{down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
return
}
PLAY:
if(PlayAndStop = 1)
{
character := 0
myTurn := 0
myMenu := 0
loop
{
if(PlayAndStop = 0)
{
break
}
ifWinExist, ahk_exe Octopath_Traveler-Win64-Shipping.exe
{
WinActivate, ahk_exe Octopath_Traveler-Win64-Shipping.exe
}
mem := new _ClassMemory("ahk_exe Octopath_Traveler-Win64-Shipping.exe", "", hProcessCopy) ; *****
if !isObject(mem)
{
msgbox failed to open a handle
if (hProcessCopy = 0)
msgbox The program isn't running (not found) or you passed an incorrect program identifier parameter.
else if (hProcessCopy = "")
msgbox OpenProcess failed. If the target process has admin rights, then the script also needs to be ran as admin. Consult A_LastError for more information.
ExitApp
}
value := mem.read(mem.BaseAddress + 0x0289F030, "UInt", 0x78, 0x88, 0x78, 0x380, 0x3D8, 0x78, 0x428)
hPotion := mem.read(mem.BaseAddress + 0x0289F070, "UInt", 0x78, 0x20, 0xA0, 0x88, 0x78, 0x3A8, 0x4)
mPotion := mem.read(mem.BaseAddress + 0x0289F070, "UInt", 0x78, 0x20, 0xA0, 0x88, 0x78, 0x3A8, 0x14)
money := mem.read(mem.BaseAddress + 0x0289F070, "UInt", 0x78, 0x20, 0xA0, 0x88, 0x78, 0x370, 0x158)
GuiControl,, HPotion, HP포션:%hPotion%개
GuiControl,, MPotion, MP포션:%mPotion%개
GuiControl,, Money, 소지금:%money%
if (value != null)
{
ControlSend,,{Left up}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
ControlSend,,{Right up}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *20 next.png
if(ErrorLevel = 0){
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
else
{
isMyTurn(character, characterName, myTurn, bpText, value)
sleep, 250
GuiControl,, ClassName, %characterName%(%character%)
minHp := mem.read(mem.BaseAddress + 0x0289F030, "UInt", 0x78, 0x88, 0x78, 0x380, 0x3D8, 0x78, 0x3E4)
maxHp := mem.read(mem.BaseAddress + 0x0289F030, "UInt", 0x78, 0x88, 0x78, 0x380, 0x3D8, 0x78, 0x3EC)
minMp := mem.read(mem.BaseAddress + 0x0289F030, "UInt", 0x78, 0x88, 0x78, 0x380, 0x3D8, 0x78, 0x3E8)
maxMp := mem.read(mem.BaseAddress + 0x0289F030, "UInt", 0x78, 0x88, 0x78, 0x380, 0x3D8, 0x78, 0x3F0)
sleep, 250
GuiControl,, BP, BP:%value% %bpText%
GuiControl,, HP, HP:%minHp%/%maxHp%
GuiControl,, MP, MP:%minMp%/%maxMp%
Gui, submit, nohide
if(character != 0 && myTurn = 1)
{
hpRate := (minHp * 100) / maxHp
mpRate := (minMp * 100) / maxMp
GuiControl,, HBar, %hpRate%
GuiControl,, MBar, %mpRate%
isMyMenu(myMenu)
if(hpRate > 50 && myTurn = 1 && myMenu = 1)
{
if(value > 2)
{
sKeySend(3)
sleep, 250
}
zKeySend(2)
myTurn := 0
sleep, 1000
}
else if(hpRate <= 50 && minMp > 8 && character = 1 && myTurn = 1)
{
isMyMenu(myMenu)
if(myMenu = 31)
{
zKeySend(3)
myTurn := 0
}
else
{
downKeySend(1)
}
}
else if(hpRate <= 50 && character > 1 && hPotion > 0 && UseItemHP = 1 && myTurn = 1)
{
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 isUseItem.png
if(ErrorLevel = 1)
{
ControlSend,,{Down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
else if (ErrorLevel = 0)
{
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 isHPItem.png
if(ErrorLevel = 0)
{
loop, 2
{
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
myTurn := 0
}
}
else if(hpRate <= 50 && character = 1 && minMp < 8 && hPotion > 0 && UseItemHP = 1 && myTurn = 1)
{
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 isUseItem.png
if(ErrorLevel = 1)
{
ControlSend,,{Down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
else if (ErrorLevel = 0)
{
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
ImageSearch, vx, vy, 1, 1, A_ScreenWidth, A_ScreenHeight, *30 isHPItem.png
if(ErrorLevel = 0)
{
loop, 2
{
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
myTurn := 0
}
}
else if(minMp < 8 && mPotion > 0 && UseItemMP = 1 && myTurn = 1)
{
loop, 3
{
ControlSend,,{Down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
}
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
ControlSend,,{Down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 50
ControlSend,,{z}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
myTurn := 0
}
}
myMenu := null
myTurn := null
character := null
characterName := null
hpRate := null
mpRate := null
}
}
else
{
GuiControl,, ClassName, N/A
GuiControl,, BP, 전투중이 아닙니다.
GuiControl,, HP, HP:N/A
GuiControl,, MP, MP:N/A
GuiControl,, HBar, 0
GuiControl,, MBar, 0
ControlSend,,{Left down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 1000
ControlSend,,{Left up}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 100
ControlSend,,{Right down}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
sleep, 1000
ControlSend,,{Right up}, ahk_exe Octopath_Traveler-Win64-Shipping.exe
}
}
return
}
STOP:
return
classMemory가 설치되어 있어야 작동 한다.
참조: http://www.agmserver.com/main/blog_ahk/570
명령어도 동일하고 치트엔진에서도 포인터는 정확하게 값을 나타내는데
classmemory로 읽어내려고 하면 읽질 못하네요..
mem.BaseAddress 값도 잘 도출 하고, 치트엔진상의 오프셋 그대로 적어도 결과값 산출을 못하네요 ㅠ