It turns out that the "message ID" column in the DBRequestWrapperPDU section of the protocol page is some number which is not necessarily the message ID.
Today, I was trying to get the search-for-Sim/search-for-lot functionality working. When you do a search with the Search Exact button, the client sends a SearchExactMatch DBRequestWrapperPDU to the server. I figured out the structure of the SearchExactMatch body, but after sending the packet, the client did nothing. I was using what I thought was the correct "message ID", 0xE9A2E6CC, but when I did ctrl+F for it in the Regulators section of the article, it wasn't found.
So I put a hardware breakpoint on the dword that holds the message ID directly after the client reads it from the packet so I could jump to the code that looks at the message ID. The code is located at TSOServiceClientD_base+0x3a479 (in TSO New & Improved trial, as always); whatever the packet specifies as the message ID, this code searches for that key in a binary search tree. I wrote some code at the bottom of the .text section of TSOServiceClientD.dll that dumps the binary search tree:
As a result: there were 366 keys in that tree, but there were many duplicate keys for some reason, and the first 161 keys corresponded to "0x00000001, 0x00000002, 0x00000003, ..." in PDURegulator which should not be applicable... This left us with exactly 170 potential message IDs. I wrote some C code to create "0.dat", "1.dat", "2.dat", etc. up to "169.dat" which were all the same packet as before but with the message ID (previously 0xE9A2E6CC) swapped out for one in the list.
I tried out every one, and I found some interesting message IDs.
First of all, 0xDBF301A9 is the real message ID that handles the SearchExactMatch response body. 0x4947E8F6 causes the map view to become dark, without changing the time. 0xBBFAABC8 causes the map view to become bright again, also without changing the time. Lastly, I found that 0x3BFC2808 changes the time, changes the brightness of the map view to match the time, and makes time begin moving (1 game second per real-life 5 seconds, like normal). After experimenting with the packet, I found that the "Parameter" field specifies the number of real-life seconds (or 5 times the number of game seconds) that have passed since 12:00am ingame. It looks like the "simulate to current time" function might be running on its own without ever synchronizing with the server (until the server explicitly sends another 0x3BFC2808 packet with the current time), indefinitely, without a limit. If so, that's weird...
If you look at the EA-Land Final Countdown video at 4 minutes in, you can see that when the simulation stops at 4:31, the game time also stops at "7:03 pm", until the game disconnects at 4:49 (about 20 seconds after the disconnect), at which point the game time skips to 7:06 ((6-3 +/- 1)*5 = 20 seconds in this case) and begins moving again. I'm not sure what to take from that. It looks like time can pass without running a simulation when the player is outside of a (functional) lot and can pass in sync with the simulation when the player is inside a (functional) lot.
Here is the PDU: http://niotso.org/files/starttime.dat
Today, I was trying to get the search-for-Sim/search-for-lot functionality working. When you do a search with the Search Exact button, the client sends a SearchExactMatch DBRequestWrapperPDU to the server. I figured out the structure of the SearchExactMatch body, but after sending the packet, the client did nothing. I was using what I thought was the correct "message ID", 0xE9A2E6CC, but when I did ctrl+F for it in the Regulators section of the article, it wasn't found.
So I put a hardware breakpoint on the dword that holds the message ID directly after the client reads it from the packet so I could jump to the code that looks at the message ID. The code is located at TSOServiceClientD_base+0x3a479 (in TSO New & Improved trial, as always); whatever the packet specifies as the message ID, this code searches for that key in a binary search tree. I wrote some code at the bottom of the .text section of TSOServiceClientD.dll that dumps the binary search tree:
Code:
function: ; TSOServiceClientD_base+0x7b800
mov ecx, dword [esp+0x04] ; arg1: a node
test ecx, ecx
jz function_ret
push dword [ecx+0x0c] ; this node's right child
push dword [ecx+0x10] ; this node's value
push dword [ecx+0x08] ; this node's left child
call function
mov eax, dword [destptr]
pop dword [eax]
add dword [destptr], 0x04
call function
function_ret:
ret 0x04
pusha
push 0x01000000 ; 16 MB, more than enough
call malloc_cdecl
pop ecx ; place breakpoint here; let ptr = eax, destptr = the first value >= ptr such that
push 043A2308 ; destptr ends in "00" in hex, and set dword [destptr] = destptr+4
call function
push ptr ; place breakpoint here and copy the output to your text editor
call free_cdecl
pop ecx
popa
jmp 00407DD1
As a result: there were 366 keys in that tree, but there were many duplicate keys for some reason, and the first 161 keys corresponded to "0x00000001, 0x00000002, 0x00000003, ..." in PDURegulator which should not be applicable... This left us with exactly 170 potential message IDs. I wrote some C code to create "0.dat", "1.dat", "2.dat", etc. up to "169.dat" which were all the same packet as before but with the message ID (previously 0xE9A2E6CC) swapped out for one in the list.
I tried out every one, and I found some interesting message IDs.
First of all, 0xDBF301A9 is the real message ID that handles the SearchExactMatch response body. 0x4947E8F6 causes the map view to become dark, without changing the time. 0xBBFAABC8 causes the map view to become bright again, also without changing the time. Lastly, I found that 0x3BFC2808 changes the time, changes the brightness of the map view to match the time, and makes time begin moving (1 game second per real-life 5 seconds, like normal). After experimenting with the packet, I found that the "Parameter" field specifies the number of real-life seconds (or 5 times the number of game seconds) that have passed since 12:00am ingame. It looks like the "simulate to current time" function might be running on its own without ever synchronizing with the server (until the server explicitly sends another 0x3BFC2808 packet with the current time), indefinitely, without a limit. If so, that's weird...
If you look at the EA-Land Final Countdown video at 4 minutes in, you can see that when the simulation stops at 4:31, the game time also stops at "7:03 pm", until the game disconnects at 4:49 (about 20 seconds after the disconnect), at which point the game time skips to 7:06 ((6-3 +/- 1)*5 = 20 seconds in this case) and begins moving again. I'm not sure what to take from that. It looks like time can pass without running a simulation when the player is outside of a (functional) lot and can pass in sync with the simulation when the player is inside a (functional) lot.
Here is the PDU: http://niotso.org/files/starttime.dat
Last edited: