§ASM Routine hunting
Here are some routines which are good to have identified which can be easily found using strings referenced.
The routine is listed, followed by the string which it references. Find the string first, then find the reference to that string, then your in the right routine.
- PrintLogMessage - "Logs\dbg.txt"
- This writes a printf-style message to the dbg.txt file.
- ProcessWorldAuth - "WorldAuthenticate. I got a message of"
- this is where you find pre-char select world opcodes.
- SendMessage - "Failed to send message %d"
- This writes a packet to the network. Opcode is the second arg.
- IncomingDispatch - "Item done, MSG_WEATHER_EVENT received" (OP_Weather)
- Where all incoming opcodes are processed after char select is displayed.
- This function currently has two major stages, the first one seems to be mainly zero-length opcodes. The start of the second stage is known as StartDispatchPhase2, and can be found by looking for the "fall through" case on the first set of conditionals.
- DisplayStringID - "%s (%d)" (theres 3 functions, no good way to tell which is correct right now)
- The name is a little off, but this at least takes a string id from eqstr_us.txt and shows a text box at world for things like "zone unavaliable". This is also used a lot in zone, prolly going down to the console. Not sure how it decides what to do.
- ConnectToZone - "Networking: Connection Established"
- CoreRoutineMainThread - "Fatal error occurred in mainthread"
- Seems to be the main thread body.
- ParseINIFile - "Parsing INI file"
- InitClientVariables - "ERROR: Unable to allocate memory for raw text buffer"
- Seems to load the INI file and pull a lot of settings out of it. Also leads to dispatch.
- YouHaveBeenDisconnected - "Discon.bmp" (theres a few of them)
- VerifyPlayerProfile - "ERROR: Corrupt PC , disconnecting"
- GetGuildByName - "Unknown Guild" - this method also sends OP_GetGuildsList
- ProcessGame - "Starting process game." - This seems to be one of the main loop/routines.
- StartCharSelect - "Starting network game."
These are subsystems which have a sub-dispatcher for their incoming opcodes:
To be written...
These are symbols which show up all over the code, and are almost certainly base pointers into very large and commonly used objects.
Finding OP_ZoneUnavail is somewhat involved. So here goes...
first we need to find the global symbolZoneInError
, to do this, find ProcessGame
is called twice from ProcesGame
, one in the begining, and once near a reference to ZoneInError
. Example asm:
.text:004AD4D4 mov ecx, [esp+0B0h+var_A0]
.text:004AD4D8 call sub_4A56B1 ; Call Procedure
.text:004AD4DD cmp dword_905C98, 0 ; Compare Two Operands
.text:004AD4E4 jnz short loc_4AD54F ; Jump if Not Zero (ZF=0)
.text:004AD4E6 cmp ZoneInError, 0 ; Compare Two Operands
.text:004AD4ED mov ecx, [esp+0B0h+var_A0]
.text:004AD4F1 jz short loc_4AD50D ; Jump if Zero (ZF=1)
.text:004AD4F3 push offset unk_905C18
.text:004AD4F8 push [esp+0B4h+hWndParent]
.text:004AD4FF push [esp+0B8h+hWnd]
.text:004AD506 call StartCharSelect ; Call Procedur
Once you have located ZoneInError
, you should cross reference it back into IncomingDispatch
. Theres currently four opcodes which set this variable, this gives you a set of four potential opcodes you can try, most likely, any of them will work.