#샘플 코드
#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가 설치되어 있어야 작동 한다.
명령어도 동일하고 치트엔진에서도 포인터는 정확하게 값을 나타내는데
classmemory로 읽어내려고 하면 읽질 못하네요..
mem.BaseAddress 값도 잘 도출 하고, 치트엔진상의 오프셋 그대로 적어도 결과값 산출을 못하네요 ㅠ