해보고 싶은 거 다 해 보는 블로그

일랜시아 매크로 제작에 유용한 포인터들-(1) 본문

매크로/게임을 위한 매크로

일랜시아 매크로 제작에 유용한 포인터들-(1)

넌출월귤아속 2020. 4. 30. 01:46

일랜시아에는 상당히 많은 정보를 메모리에서 확인할 수 있습니다. 아마 제 블로그를 모르는 분들은 치트엔진 CT파일을 플라이하이나 준치가 배포하는 CT파일을 받으실 텐데, 그 CT에는 HP, MP, FP의 최댓값과 현잿값을 확인할 수 있는 항목이 담겨있습니다. 물론 캐릭터의 이런 수치를 굳이 치트엔진을 통해 확인하진 않을 테니 CT에 담는다고 의미는 없겠다고 생각하고 제가 배포하는 짜깁기CT에는 뺐습니다. 다만 자사를 제작하려고 한다면 유용하게 사용할 수 있습니다. 현재 HP가 위험한 상태가 되면 접속 종료하도록 할 수도 있고 FP가 0이 되면 식빵을 먹도록 할 수도 있습니다. 이렇게 매크로에 일랜시아의 메모리에 접근해서 필요한 정보를 엿보거나 수정할 수 있게 되면 매크로의 세계는 백배 이상 넓어집니다.

제가 주로 사용하는 것을 나열하자면, 현재 있는 지역의 맵코드, 캐릭터의 위치 좌표, HP, FP, 장착 중인 무기 종류, 인벤토리 칸 수, 공격할 때마다 증가하는 수치, 텍스트 등입니다.

이런 정보들은 임의로 수정한다고 정말로 변하는 것은 없습니다. 하지만 이런 정보들을 확인함으로써 캐릭터가 원래 사냥하고 있어야 하는 지역에서 벗어나진 않았는지, 다음 맵으로 제대로 이동했는 지를 체크할 수 있고, 자동사냥을 좀 더 안정적으로 할 수 있게 됩니다. 이런 정보들은 이전에 언급한 비정상적으로 고가에 판매되고 있는 자사에는 모두 탑재되어 있을 거라 짐작합니다.

관심을 갖고 검색을 해보셨다면 이런 메모리 관련 함수들을 어렵지 않게 접하셨으리라 생각하지만, 이 글을 읽고 처음으로 관심을 가지게 된 분들을 위해 관련 함수들을 올려 보겠습니다.

ReadMemory(MADDRESS,PROGRAM){
winget, pid, PID, %PROGRAM%

VarSetCapacity(MVALUE,4,0)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "UInt")
DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)

Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)

return, result  
}
WriteMemory(WVALUE,MADDRESS,PROGRAM){
winget, pid, PID, %PROGRAM%

ProcessHandle := DllCall("OpenProcess", "int", 2035711, "char", 0, "UInt", PID, "UInt")
DllCall("WriteProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS, "Uint*", WVALUE, "Uint", 4, "Uint *", 0)
DllCall("CloseHandle", "int", ProcessHandle)

return
}

경험론적인 조언을 해드리자면, 메모리를 수정하는 writememory 함수는 CPU점유율를 꽤 잡아먹는 것 같았습니다. 또, Writememory나 Readmemory 함수의 MADDRESS 칸에 Readmemory함수를 넣으면 포인터 역할을 해서 순차적으로 메모리를 따라갈 수 있게 됩니다만, 저는 이렇게 되면 Readmemory함수를 여러 번 쓰게 되니 미리 찾도록 합니다. 전자와 후자의 예를 모두 모여드리자면 다음과 같이 됩니다. 이걸 갖고 어쩌라는 건지 싶으시다면, 고대로 전부 옮겨 적고 스크립트를 실행하면 어떻게 되는지 확인해보시는 게 제일 빠르겠습니다.

mainadd1:=ReadMemory(0x0058DAD4, title)	
inven1:=ReadMemory(mainadd+0x178, title)
inven2:=ReadMemory(inven1+0xBE, title)
inven3:=ReadMemory(inven2+0x14, title)


inven:=ReadMemory(ReadMemory(ReadMemory(ReadMemory(0x0058DAD4, title)+0x178, title)+0xBE, title)+0x14, title)

처음 네 줄짜리를 쓰게 되면, 일랜시아 클라이언트를 처음에 title 변수에 먹여준 다음 mainadd1부터 inven2까지만 읽어두면, 루프문 속에 inven3을 계속 지정해주면 계속 인벤토리를 차지하고 있는 아이템 개수를 확인할 수 있습니다. inven으로 시작하는 아래에 있는 한 줄짜리를 쓰면 미리 지정하지 않고 한 줄짜리를 루프문 안에 넣기만 하면 전자와 똑같은 기능을 할 수 있습니다. 다만, 관련 전공자가 아니기 때문에 근거 있는 소리는 아니지만, 매번 루프 안에서 포인터 체인을 처음부터 끝까지 다 읽도록 하면 아무래도 처리속도가 느리거나 CPU를 더 쓰게 되지 않겠나 하는 짐작으로 저는 전자를 선호합니다.

이런 메모리를 얻다가 써먹냐하면, 저는 여기에 써먹었습니다.

 

자동 생산 매크로를 만들어 봤다.

일랜시아의 생산직의 수련은 극한의 난이도를 자랑합니다. 재료의 압박과 횟수의 압박 모두 견뎌야 비로소 빛을 볼 수 있죠. 빛이란 일랜시아에 구현된 선에서의 최고 어빌을 달성하는 것일 수도 있고, 수요가 있..

nunchoolberry.tistory.com

또 가끔 돌리는 재료 모으는 자사에도 사용하고 있습니다. 이 블로그의 포스팅 거리가 저는 심히 걱정되기 때문에, 앞서 언급한 메모리 정보들 중 나머지는 또 다음에 보여드리도록 하겠습니다. 사실 찾기가 그리 어려운 녀석들도 아니기도 합니다.