Maxis Protocol

This page describes the protocol for ARIES/Voltron, an MMO framework developed by Kesmai (acquired by Electronic Arts) and used by Maxis for The Sims Online. For the new protocol being developed for Niotso, see Niotso Protocol.

Because the client uses the system-wide wininet.dll, it will happily connect to *any* HTTPS website with a valid X.509 certificate. All pages requested by the client may redirect but must eventually return 200 OK. All HTTP headers including content-type and date-modified are ignored by the client.

This page discusses the protocol and game binaries of the TSO New & Improved trial, version 1.1097.1.0.

Note: If suddenly The Sims Online starts crashing whenever you open it, delete status.dat.

Authorization server
Reference: authlogin.dll

The host for the authorization server is specified in (gamedata/)sys/gameentry.ini. HTTPS can be disabled by changing the 2 bytes at offset 0x8327 in authlogin.dll from 30 C0 to 00 40; the port can be changed from 443 to 80 by changing the 2 bytes at offset 0x82AD in authlogin.dll from BB 01 to 50 00.


 * Note: Pre-Alpha hard-codes the host name for the authorization server ("www.ea.com") at offset 0x7FB60 in TSOProtocolsD.dll. HTTPS can be disabled by changing the 2 bytes at offset 0x22B9 in authlogin.dll from 30 C0 to 00 40; the port can be changed from 443 to 80 by changing the 2 bytes at offset 0x20A3 in authlogin.dll from BB 01 to 50 00.

Interestingly, auth.east.ea.com is the only EA server still running to this day (even auth.west.ea.com is down). The DNS records for auth.east.ea.com (159.153.234.80) and auth.west.ea.com (159.153.199.220) went down in December 2014, but if you place those into your hosts file, the situation is otherwise the same; auth.east.ea.com is still running to this day, and it currently responds with the following:

AuthLogin
When the user attempts to log in, the client will connect to https://auth.east.ea.com/AuthLogin?username=&password=&serviceID=2147&version=2.5 with the "username" and "password" GET variables set to those supplied by the user. AuthLogin should log the player in and return a ticket (session cookie), which the client will later pass to the city selection server. The client must receive "Valid=TRUE" to continue.

The normal response is as such:

The error response is as such:

Certain reason codes will override the "reasontext" field with a hardcoded string. These reason codes are as such:

Other valid fields are as such:

City selection server
Reference: TSOServiceClientD.dll

The host for the city selection server is specified in (gamedata/)sys/cityselector.ini. HTTPS can be disabled by changing the 4 bytes at offset 0x923C4 in TSOServiceClientD.dll from 73 3A 2F 2F to 3A 2F 2F 00. The game makes two connections to the city selection server when requesting each page, one on port 443, and another on the port specified in cityselector.ini. To make it use the port in the INI file each time, change the byte at offset 0x17B2 in InternetServiceD.dll from 74 to EB.


 * Note: Pre-Alpha hard-codes the host name for the city selection server ("xo.max.ad.ea.com") at offset 0x7F860 in TSOProtocolsD.dll. HTTPS can be disabled by changing the 2 bytes at offset 0x22B9 in authlogin.dll from 30 C0 to 00 40; the port can be changed from 443 to 80 by changing the 2 bytes at offset 0x20A3 in authlogin.dll from BB 01 to 50 00.

Each page the client requests from the city selection server is in XML format.

Interestingly, the DNS records for tsocs.tso.ea.com are still up, with DNS 159.153.230.176. Putting this in your hosts file does nothing else though, as the page will take too long to respond.

InitialConnectServlet
Once authorized by the authorization server, the client connects to https://tsocs.tso.ea.com/cityselector/app/InitialConnectServlet/?ticket=&version= with the "ticket" variable set to that specified by the authorization server and the "version" variable set to a string such as "Version 1.1097.1.0". InitialConnectServlet should verify that the client is up-to-date and that the ticket (session cookie) is valid. InitialConnectServlet should set the "TSOSession" and "TSOSession2" HTTP cookies (see below for details) and respond with either Error-Message, User-Authorized, or Patch-Result as the root element of the XML response.

Error-Message indicates an error, usually an invalid session cookie. The format of Error-Message is as such:

The error number which the client will override the server's error text for is 132:

Patch-Result indicates that the client must download an update before it can continue. (InitialConnectServlet may wish to enforce this by logging the user out.) The format of Patch-Result is as such:

In response to Patch-Result, the client displays an error requiring the user to apply an update. If the user accepts, the client closes itself, launches the updater utility, and retrieves the update information from the "Patch-Address" field. Interestingly, if the user instead declines the update, the Create-A-Sim Hint dialog will appear if that hint has not yet been disabled, and the user is then brought back to the login dialog.

For experimentation purposes, it may be desired to allow the client to continue even if it is an old version (that is, do not return Patch-Result for old client versions). However, for the updater utility to work, it is important that InitialConnectServlet always returns Patch-Result for version "0.0.0.0". Specifically, when the updater wants to verify the TSOClient game directory, it sends a request with version=0.0.0.0 to ensure that the server responds with Patch-Result so that it can get the URL of the TSOClient Marimba transmitter (presumably Maxis-Patch-Production2). If User-Authorized is returned in this case, the updater will show an error saying that the game verification has failed.

User-Authorized specifies that the user is authorized to continue. The format of User-Authorized is as such:

In addition to sending User-Authorized, InitialConnectServlet should set the "TSOSession" HTTP cookie, which the other JSP pages will check to ensure that the user is logged in. However, there is a cookie-parsing bug in versions of TSO prior to New & Improved, in that the last cookie in the HTTP response is ignored. To ensure TSOSession is not the last cookie in the response, the city server should also set another cookie directly after TSOSession, such as "TSOSession2".

If the server responds with the optional tag, the client will log in as a Customer Service Representative (CSR). As a CSR, the player is not presented with SAS or CAS; instead, the player selects from a list of cities, and a new temporary character is created for this gameplay session with CSR capabilities (ejecting Sims).


 * Note: Pre-Alpha connects to /cityselector/initial-connect.jsp rather than /cityselector/app/InitialConnectServlet/. The server responses are the same for all elements except User-Authorized; in Pre-Alpha, User-Authorized does not provide a child.

AvatarDataServlet
After passing InitialConnectServlet, the client connects to https://tsocs.tso.ea.com/cityselector/app/AvatarDataServlet to request the list of avatars. AvatarDataServlet should respond with either Error-Message or The-Sims-Online as the root element of the XML response.

Error-Message follows the same format as described in InitialConnectServlet with the same recognized error number of 132. Interestingly, if AvatarDataServlet returns Error-Message, once the user dismisses the error, the user is still brought to the Select-A-Sim screen.

The-Sims-Online provides a list of 0-3 avatars. The format of The-Sims-Online is as follows:

The "Shard-Name" field for each avatar should refer to a shard (city server) defined later in shard-status.jsp.


 * Note: Pre-Alpha connects to /cityselector/avatar-data.jsp rather than /cityselector/app/AvatarDataServlet. The format of the The-Sims-Online element in Pre-Alpha is different, shown below:

shard-status.jsp
After passing AvatarDataServlet, the client connects to https://tsocs.tso.ea.com/cityselector/shard-status.jsp to obtain the status of each shard (city server). shard-status.jsp should respond with either Error-Message or Shard-Status-List as the root element of the XML response.

Error-Message follows the same format as described in InitialConnectServlet with the same recognized error number of 132. Interestingly, if shard-status.jsp returns Error-Message, once the user dismisses the error, the user is still brought to the Select-A-Sim screen.

TSOMania.net has shared packet logs of shard-status.jsp from 2007 and 2008, which you can find here:
 * http://niotso.org/files/shard-status-2007-08-31.xml
 * http://niotso.org/files/shard-status-2008-08-01.xml

The format of Shard-Status-List is as such:

Status should be one or more of the following: Up, Down, Busy, Full, Closed, Frontier. "Closed" seems to be the same as Busy. "Frontier" means the hardcore city and was used only with Dragon's Cove. Multiple statuses can be combined, usually in this order:
 * (Required) One of the following: Up, Down
 * (Optional) One of the following: Busy, Closed
 * (Optional) Full
 * (Optional) Frontier

For example, specifying Down, Busy, and Full causes the game to say "Online: No, Status: Busy/Full" under the "What City Do You Want to Live In?" menu.

The list of maps is as follows:


 * Note: Pre-Alpha connects to the same location, /cityselector/shard-status.jsp. The format of Shard-Status-List in Pre-Alpha is as follows:


 * In Pre-Alpha, if Location is not defined (anywhere in the server response) as "public", the rest of the XML file is ignored. Also, Status should be only: Up, Down.

ShardSelectorServlet
The user can enter the city by selecting an existing Sim or by asking to create a Sim in a new city.

When the user enters the city, the client connects to https://tsocs.tso.ea.com/cityselector/app/ShardSelectorServlet?shardName=&avatarId= in order to get the hostname and port of the city server, as well as obtain the avatar id of the newly created Sim (if entering Create-A-Sim). The client passes two GET variables:
 * The "shardName" GET variable is set to the name of the city (as specified by shard-status.jsp).
 * If the player is entering the city as an existing Sim, the "avatarId" GET variable is set to that avatar's ID. (If the player is instead asking to create a new Sim, no avatarId is specified in the request.)

ShardSelectorServlet should verify that the action is legal, generate an avatar id for the newly created Sim (if the player is entering CAS), and respond with either Error-Message, Patch-Result, or Shard-Selection as the root element.

Error-Message follows the same format as described in InitialConnectServlet with the same recognized error number of 132. If shard-status.jsp returns Error-Message, once the user dismisses the error, the user is brought back to the login screen.

Patch-Result follows the same format as described in InitialConnectServlet.

The format of Shard-Selection is as such:

In response to Shard-Selection, the client will produce the file launchfile.lch with the following data:

Notice that "100" will be appended to the port specified by Shard-Selection. For instance, if Shard-Selection specifies a port of 33, the client will connect over port 33100.


 * Note: Pre-Alpha connects to /cityselector/shard-selector.jsp rather than /cityselector/app/ShardSelectorServlet. The format of Shard-Selection in Pre-Alpha is as follows:

DeleteAvatarServlet
DeleteAvatarServlet is used for three functions:
 * Retiring a Sim (command=delete) - If the player chooses to retire a Sim, the client connects to https://tsocs.tso.ea.com/cityselector/app/DeleteAvatarServlet?command=delete&avatarId= with the "avatarId" GET variable set to the ID of the avatar to be deleted. DeleteAvatarServlet should delete the avatar and respond with either Error-Message, or any arbitrarily-named tag other than Error-Message (such as " " or ""), as the root element. (Note that if there is no root element in the response, the client will display the error "The game has experienced an internal error".)
 * Moving a Sim (command=move) - If the player chooses to move a Sim to another city, the client connects to https://tsocs.tso.ea.com/cityselector/app/DeleteAvatarServlet?command=move&avatarId=&city= with the "avatarId" GET variable set to the ID of the avatar to be moved and the "city" GET variable set to the name of the destination city. DeleteAvatarServlet should move the avatar; the response is the same as for command=delete.
 * Moving a Sim (command=primary) - If the player chooses to change his primary Sim, the client connects to https://tsocs.tso.ea.com/cityselector/app/DeleteAvatarServlet?command=primary&avatarId= with the "avatarId" GET variable set to the ID of the new primary Sim.

Error-Message follows the same format as described in InitialConnectServlet with the same recognized error number of 132.

Afterwards, if the server did not return Error-Message, the client reconnects to AvatarDataServlet to reload the list of avatars.

Note that if there is no root element in the response, the client will display the error "The game has experienced an internal error".


 * Note: Pre-Alpha connects to /cityselector/delete.jsp rather than /cityselector/app/DeleteAvatarServlet. The server responses are the same.

LogoutServlet
When the player logs out, the client connects to https://tsocs.tso.ea.com/cityselector/app/LogoutServlet to log out. LogoutServlet should simply log the user out; the client discards the server's response, even if it was not 200 OK.


 * Note: Pre-Alpha does not make use of LogoutServlet.

City server
After passing ShardSelectorServlet, the client opens an encrypted TCP connection, using TLS 1.0, to the city server with the IP address and port specified by launchfile.lch. The X.509 certificate supplied by the server may be self-signed; the common name (CN) must simply be a hostname that corresponds with the server's current IP address.

Cracking the city server protocol is currently a subject of interest, as it's necessary to get into the map view, a lot, etc. and play online with others. The associated DLLs are TSOServiceClientD.dll, TSONetServiceSimClientD.dll, and Aries.dll.


 * Note: Pre-Alpha uses an unencrypted connection. Also, in Pre-Alpha, TSONetServiceSimClientD.dll is known as TSOVoltronDMServiceD.dll.

Aries packets
The function that reads an Aries packet is AriesClientConnection::PacketFilter (located at Aries_base+0x6e10).

Each TLS packet that the city server sends to the client, and vice versa, consists of one or more Aries frames in succession. An Aries frame begins with the Aries header, using little-endian integers:
 * Aries packet type - A 4-byte unsigned integer specifying the Aries type of this packet. Values greater than zero indicate low-level Aries commands. A value of zero indicates an application-defined packet which will be handled by Voltron rather than Aries. The TSO programmers likely never dealt with Aries commands directly. Valid Aries commands are:
 * Timestamp - A 4-byte unsigned integer representing the timestamp for this packet in milliseconds. This timestamp does not correspond to any timezone or epoch. When the client sends packets to the server, it uses GetTickCount to fill in this field, a Windows API function that returns the number of milliseconds that have elapsed since the system was started&mdash;however, it does this in a broken way. When the server sends packets to the client, the client does not even look at this field.
 * The code where the client fills in the timestamp field can be found at Aries_base+0x5630. It appears that the programmers had a preprocessor macro similar to write_dword(dest, src), so they wrote "write_dword(ptr, GetSystemTime);" which expands out into " ptr[0] = (GetSystemTime >> 0) & 0xFF; ptr[1] = (GetSystemTime >> 8) & 0xFF; ptr[2] = (GetSystemTime >> 16) & 0xFF; ptr[3] = (GetSystemTime >> 24) & 0xFF;" when what they were supposed to write is "temp = GetSystemTime; write_dword(ptr, temp)".
 * Aries payload size - A 4-byte unsigned integer specifying the size of the payload that follows the Aries header. If there is one Aries frame in the TCP packet, this should be equal to the size of the TCP packet minus 12.

The payload directly follows this header; its contents are specific to the Aries command.

Type 1
This packet causes the client to disconnect from the server.

The payload of this packet is empty.

Type 3
This packet causes the client to reconnect to another server without interrupting gameplay.

The format of the payload is as follows:
 * Unknown - 256 bytes containing a null-terminated string
 * Server - 256 bytes containing a null-terminated string in the format "host:port" where "host" is an IPv4 address or a host name
 * Password - 60 bytes containing a null-terminated string corresponding to the "password" field of launchfile.lch

Type 21
The client sends this in response to the Type 22 Aries packet.

The format of the payload is as follows, using little-endian integers:
 * User - 112 bytes containing a null-terminated string corresponding to the "user" field of launchfile.lch. All data after the string is uninitialized memory (just like Heartbleed).
 * AriesClient version - 80 bytes containing a null-terminated string set to "6.0.2.0o"
 * Email - 40 bytes containing a null-terminated string corresponding to the "email" field of launchfile.lch
 * Authserv - 84 bytes containing a null-terminated string corresponding to the "Authserv" field of launchfile.lch
 * Product - A 2-byte unsigned integer corresponding to the "Product" field of launchfile.lch; should be 0x0001
 * Unknown - 1 byte set to the character '9' (0x39)
 * ServiceIdent - 3 bytes containing a null-terminated string corresponding to the "ServiceIdent" field of launchfile.lch; should be "P"
 * Unknown - A 2-byte unsigned integer, typically equal to 1 (after a Type 3 packet) or 4 (before any Type 3 packets)
 * Password - A non-null-terminated string corresponding to the "password" field of launchfile.lch; this field has a variable length which should be calculated based on the size of the payload: password_len = payload_size - 331.
 * Reserved - 7 bytes of uninitialized memory

Note: The Password field is initially null-terminated when the client reads from launchfile.lch (with the null terminator residing in the first byte of the 7-byte Reserved field); however, when the client receives a Type 3 Aries packet from the city server, the client first copies the password from the Type 3 packet without copying the null-terminator and then subsequently inserts the null-terminator one byte past the end of the string into the second byte of the 7-byte Reserved Data field. (See Aries_base+0x73f9.) Hence, the city server should not assume that the Password field is null-terminated.

Type 22
When the server sends the Type 22 Aries packet to the client, the client responds with a Type 21 Aries packet containing information about the client's session.

The payload of this packet is empty.

Type 26
The format of the payload is as follows:
 * Error - A null-terminated string of the form "subject:[error]", where subject is "ARIES OS" or "CADENCE" and error is one of the following: PM1000A, PM1001E, PM1002A, PM1003F, PM1004A, PM1005F, PM1006F, PM1007F, PM1008E, PM1009A, PM1010F, PM1011F, PM1012A, PM1013E, PM1014E, PM1015E, PM1016A, PM1017A, PM1018E, PM1019A, PM1020F, AU1000F, AU1001E, AU1002E, AU1003F, AU1004F, AU1005A, AU1006E, AU1007A, AU1008E, AU1009F, AU1010F, AU1011E, AU1012E.

The client does not close the connection, or show any kind of error, in response to this packet. Perhaps the Error field is really a "last error".

Type 27
The format of the payload is as follows:
 * Timestamp - A 4-byte unsigned integer specifying the server's prediction of the client's clock once the client receives this packet (in milliseconds)

Type 28
The format of the payload is as follows:
 * Histogram width - A 4-byte unsigned integer specifying the width of the histogram, that is, the highest prediction error that can be displayed on the histogram (larger errors will be clamped); must be nonzero
 * Unknown - A 4-byte unsigned integer; must be nonzero (e.g. 1)
 * Unknown - A 4-byte unsigned integer; must be nonzero (e.g. 1)

The Type 27 and 28 Aries packets can be used to measure the variance in one-way latency. For an explanation, see: http://niotso.org/files/aries_ping_packets.txt

It turns out that this timing test is not useful for finding the latency itself. To determine round-trip latency, the server should simply use the Type 22 packet as a "ping" packet: that is, find the current time (call it t0), send a Type 22 packet, wait for a response, and find the new current time (call it t1). The round-trip latency is given by t1-t0.

Type 29
The format is as follows, using little-endian integers:
 * Unknown - 88 bytes set to zero
 * Histogram - 84 bytes (A 4-byte unsigned integer for all 21 bins in the histogram)
 * Total clock drift - A 4-byte unsigned integer specifying the sum of the clock drift over all tests

Type 31
The payload of this packet is empty.

The relogon start callback function is null (as can be observed by the "test eax, eax" check at Aries_base+0x7cf7), hence the client does not do anything in response to this packet.

Type 44
The payload of this packet is empty.

The relogon complete callback function is null (as can be observed by the "test eax, eax" check at Aries_base+0x7d67), hence the client does not do anything in response to this packet.

Voltron packets
The payload of a type 0 Aries frame consists of one or more Voltron packets in succession; in addition, Voltron packets can be split across multiple Aries frames. The Voltron function that looks at the payload is located at offset TSONetServiceSimClientD_base+0x570d0, taking 2 arguments: Arg1 is the Aries payload contents, and Arg2 is the Aries payload size.

Unlike Aries, Voltron generally uses big-endian integers rather than little-endian integers.

A Voltron packet begins with the following header:
 * Voltron packet type - A 2-byte unsigned integer specifying the type of this Voltron packet.
 * Voltron packet size - A 4-byte unsigned integer specifying the size of the entire Voltron packet, including these 6 bytes; this value can be greater than the Aries payload size to indicate that the rest of the Voltron packet will arrive in additional Aries packets.

Aries.dll does not have RTTI (RunTime Type Information) in any version of the game in our possession. TSONetServiceSimClientD.dll has RTTI only in EA-Land; based on this information, assuming the Voltron packet type values did not change, we can give names to the packets. These are the classes whose names contain "PDU," short for "Protocol Data Unit":

class Voltron::ActionRoomNamePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ActionRoomNameResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::AlertHandledPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::AlertMsgPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::AlertMsgResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::AnnouncementMsgPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::AnnouncementMsgResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class AvatarHasNewLotIDPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::BBSMessageDataPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class BC_PlayerLoginEventPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class BC_PlayerLogoutEventPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class BroadcastDataBlobPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::PDU : dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ChatMsgFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ChatMsgPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class CheatPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ClientByePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class ClientConfigPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ClientOnlinePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ClientPDUFactory : Voltron::PDUFactory; class Voltron::ClientPersistentPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ClientResponsePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ClientPersistentResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class ComponentVersionRequestPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class ComponentVersionResponsePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::CreateAndJoinRoomFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::CreateAndJoinRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::CreateRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::CreateRoomResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class CsrEjectAvatarPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class CsrEjectAvatarResponsePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class DBRequestWrapperPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class DataServiceWrapperPDU : IDataServiceWrapperPDU, cIGZUnknown, cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DeleteMPSMessagePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DeleteMPSMessageResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DestroyRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DestroyRoomResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DetachFromRoomFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::DetachFromRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class EjectAvatarPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::EjectOccupantPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::EjectOccupantResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ErrorPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ExitRoomFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ExitRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FindPlayerPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FindPlayerResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FlashGroupPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FlashGroupResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FlashMsgPDU : Voltron::ClientPersistentPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::FlashMsgResponsePDU : Voltron::ClientPersistentResponsePDU, Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class GenericFlashPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class GenericFlashRequestPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class GenericFlashResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetBBSMessageListPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetBBSMessageListResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetMPSMessagesPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetMPSMessagesResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetRoomAdminListPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GetRoomAdminListResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GpsChatPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GpsChatResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupAdminRequestPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupAdminResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupInfoRequestPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupInfoResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupMembershipRequestPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::GroupMembershipResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class HSB_ShutdownSimulatorPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::HandleAlertPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::HostOfflinePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::HostOnlinePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class HouseSimConstraintsPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class HouseSimConstraintsResponsePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class IDataServiceWrapperPDU : cIGZUnknown; class Voltron::InvitationMsgPDU : Voltron::ClientPersistentPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::InvitationMsgResponsePDU : Voltron::ClientPersistentResponsePDU, Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class InviteRoommatePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::JoinPlayerFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::JoinPlayerPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::JoinRoomFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::JoinRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class KickoutRoommatePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::List20RoomsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::List20RoomsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListBBSFoldersPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListBBSFoldersResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListGroupsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListGroupsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListJoinedGroupsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListJoinedGroupsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListOccupantsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListOccupantsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListRoomsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ListRoomsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class LoadHouseResponsePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class LogAvatarActionPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class LogCsrActionPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::LogEventPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::LogEventResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::LogGPSPetitionPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::LogGPSPetitionResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class LotEntryRequestPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::MessageLostPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ModifyProfilePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ModifyProfileResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::NotifyRoomActionedPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::OccupantArrivedPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::OccupantDepartedPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::PDUFactory; class Voltron::PetitionStatusUpdatePDU : Voltron::ClientPersistentPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::PostBBSMessagePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::PostBBSMessageResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::PostBBSReplyPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class RSGZWrapperPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown, cIRSGZWrapperPDU, cIGZUnknown; class Voltron::ReadProfilePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ReadProfileResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ReleaseProfilePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ReleaseProfileResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ResetWatchdogPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ResetWatchdogResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class RoommateGDMPDU : Voltron::ClientPersistentPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class RoommateGDMResponsePDU : Voltron::ClientPersistentResponsePDU, Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class RoommateInvitationAnswerPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class RoomserverUserlistPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::ServerByePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetAcceptAlertsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetAcceptAlertsResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetAcceptFlashesPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetAcceptFlashesResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetIgnoreListPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetIgnoreListResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetInvinciblePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetInvincibleResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetInvisiblePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetInvisibleResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetRoomNamePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::SetRoomNameResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class SimsClientPDUFactory : Voltron::ClientPDUFactory, Voltron::PDUFactory; class Voltron::SplitBufferPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class TSOLogGPSPetitionPDU : Voltron::LogGPSPetitionPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class TestPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class TransmitCreateAvatarNotificationPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class TransmitDataBlobPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class TransmitGenericGDMPDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateGroupAdminPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateGroupAdminResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateGroupMemberPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateGroupMemberResponsePDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateIgnoreListPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateOccupantsPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdatePlayerPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateProfilePDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateRoomAdminListPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::UpdateRoomPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::YankPlayerFailedPDU : Voltron::ClientResponsePDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class Voltron::YankPlayerPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown; class cIRSGZWrapperPDU : cIGZUnknown; class cITSONetMessagePDU : cIGZUnknown; class cTSONetMessagePDU : cTSOPDU, Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown, cITSONetMessagePDU, cIGZUnknown; class cTSOPDU : Voltron::PDU, dead::Encodable, dead::IEncodable, opencom::IOCUnknown, cIGZUnknown;

cTSOPDU objects are constructed by the function at the virtual address 0x10040a70, which takes the packet type as an argument. Every call to this function in the DLL is immediately afterwards followed by an overwriting of the v-table pointer with the one corresponding to the child class. Using this information, the following information was obtained:


 * Note: RazorWing from the http://battletech3025.org/ project has pointed out that the PDUs with value less than 0x2710 also appear in the game Multiplayer BattleTech 3025, a game developed by Kesmai, released as a beta in 2001, and shut down later that same year. (The strings "ALERT_HANDLED_PDU", "HOST_ONLINE_PDU", etc. appear in BT3025.exe.) The PDUs >= 0x2710 are specific to The Sims Online.


 * Note: TSO Pre-Alpha has separate PDU tables inside TSOVoltronDMServiceD.dll with different PDU values: http://niotso.org/files/prealpha_pdu_tables.txt

AlertHandledPDU

 * m_senderID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_gameOPID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

AlertMsgPDU
The format is as such:
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_text - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

AlertMsgResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

AnnouncementMsgPDU
This PDU can be sent by the server to broadcast a server announcement to a player. e.g. http://niotso.org/files/AnnouncementMsgPDU.png

The format is as such:
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped; for some reason, the first 2 bytes of the string (after the length) are ignored. This field is used as the "From" field in the announcement.
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped. This field does not appear in the announcement.
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_subject - A Pascal string with 4 string length bytes with the most significant bit of the length flipped. This field is used as the "Subject" field of the announcement.
 * m_text - A Pascal string with 4 string length bytes with the most significant bit of the length flipped. This field is used as the body of the announcement.

AnnouncementMsgResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_messageText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ClientByePDU
The client sends this packet when the user clicks cancel on Create-A-Sim, and also in response to ServerByePDU (but not to an Aries disconnect packet or a general closed or lost TLS or TCP connection).

The format is as such:
 * m_reasonCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_requestTicket - 1 byte

ServerByePDU
The format is as such:
 * m_reasonCode - A 4-byte unsigned integer.
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_ticket - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

According to the switch/case at TSOServiceClientD_base+0x2aab6, valid reason codes are:

ChatMsgFailedPDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ChatMsgPDU
This PDU can be sent by the server to create a chat bubble above a Sim, and it is also sent by the client when the player attempts to chat. e.g. http://niotso.org/files/chatmsgpdu-2016-03-16.png

The format is as such:
 * m_echoRequested - 1 byte set to either 0 or 1
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_messageText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ClientOnlinePDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_pVersionInfo
 * m_majorVersion - 1 byte
 * m_minorVersion - 1 byte
 * m_pointVersion - 1 byte
 * m_artVersion - 1 byte
 * m_pRelogStats
 * Unknown - 4 bytes
 * m_timeRequired
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * m_numberOfAttempts - A 2-byte unsigned integer; must be nonzero, or the client will refuse the packet
 * m_pClientStatus
 * m_lastExitCode - A 4-byte unsigned integer
 * m_lastFailureType - 1 byte
 * m_failureCount - 1 byte
 * m_isRunning - 1 byte set to either 0 or 1
 * m_isRelogging - 1 byte set to either 0 or 1
 * Unknown - 1 byte set to either 0 or 1

At TSONetServiceSimClientD_base+0x3986e, if m_numberOfAttempts is nonzero, then the client will unread those 2 bytes (that is, seek backwards by 2 bytes). However, it does not read anything else in its place. Thus, the "Have we read all bytes in the packet?" check at TSONetServiceSimClientD_base+0x3bfea will fail. Alternatively, if m_numberOfAttempts is missing from the packet altogether, then the stream error will be set to -4 (buffer overrun), and the "Do we have no errors?" check at TSONetServiceSimClientD_base+0x249a7 will fail. Thus, m_numberOfAttempts must be nonzero for the client to accept the packet.

CreateAndJoinRoomFailedPDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pRoomInfo
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nameLocked - 1 byte set to either 0 or 1
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_stageID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentOccupancy - 4 bytes
 * m_maxOccupancy - A 4-byte unsigned integer
 * m_pwdRequired - 1 byte set to either 0 or 1
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_AdminList
 * Admin player count - A 2-byte unsigned integer specifing the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admin list is enabled
 * m_AdmitList
 * Admit player count - A 2-byte unsigned integer specifing the number of admit players that follow
 * Admit players - For each admit player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admit list is enabled
 * m_DenyList
 * Deny player count - A 2-byte unsigned integer specifing the number of deny players that follow
 * Deny players - For each deny player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this deny list is enabled
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes

CreateAndJoinRoomPDU
The format is as such:
 * m_pCreateRoomInfo
 * m_Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * m_Password - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_MaxOccupancy - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_StageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

CreateRoomPDU
The format is as such:
 * m_pCreateRoomInfo
 * m_Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * m_Password - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_MaxOccupancy - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_StageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

CreateRoomResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomID
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

EjectOccupantResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

FindPlayerPDU
The client sends this to the server when the player clicks the "Where Am I?" button on another player's SimPage, clicks the "Send this Sim a message" button, or clicks the "Send Message" button in the inbox. The format is as such:
 * m_senderID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

FindPlayerResponsePDU
This packet is used to find another player via the "Where Am I?" Option on the SimPage. Alternatively, it is also used to send a Message to a either a bookmarked Sim, or via the "Send a Message to this Sim" option on the SimPage.

The format is as such:
 * m_statusCode - A 4-byte unsigned integer
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pRoomInfo
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nameLocked - 1 byte set to either 0 or 1
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_stageID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentOccupancy - 4 bytes
 * m_maxOccupancy - A 4-byte unsigned integer
 * m_pwdRequired - 1 byte set to either 0 or 1
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_AdminList
 * Admin player count - A 2-byte unsigned integer specifing the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admin list is enabled
 * m_AdmitList
 * Admit player count - A 2-byte unsigned integer specifing the number of admit players that follow
 * Admit players - For each admit player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admit list is enabled
 * m_DenyList
 * Deny player count - A 2-byte unsigned integer specifing the number of deny players that follow
 * Deny players - For each deny player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this deny list is enabled
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

According to the switch/case at TSONetServiceSimClientD_base+0x731ee, valid status codes are:

FlashMsgResponsePDU
FlashMsgResponsePDU is a confirmation packet which is required in order for a message or a letter to be sent. Sending a letter will send its contents, both your info from UpdatePlayerPDU and the other user's avatar ID.

The format is as such:
 * m_statusCode - 4 bytes -- The status code determines if the server accepts or denies the Letter/IM request.
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_statusCode - 4 bytes
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pCorrespondentInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_messageText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

FlashMsgPDU
This PDU can be sent by the server to send an instant message or a letter to the client, and it is also sent by the client when the user sends a message to another player or when the game asks for confirmation to send the letter. e.g. http://niotso.org/files/FlashMsgPDU.png

The format is as such:
 * m_persistMessage - 1 byte set to either 0 or 1
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_persistentMessageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_receiverID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_text - A Pascal string with 4 string length bytes with the most significant bit of the length flipped. This field is used as the content of the message.

When the server sends this packet to the client, the client does *not* send FlashMsgResponsePDU in response (yet); however, when the client sends it to the server, the server must send FlashMsgResponsePDU in response to get the message or the letter to appear as "accepted" on the client.

HandleAlertPDU
The format is as such:
 * m_pagingID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

HostOfflinePDU
The body of this packet is empty.

HostOnlinePDU
The format is as such:
 * m_HostReservedWords
 * Number of words - A 2-byte unsigned integer specifying the number of reserved words that follow
 * Words - Each word is a Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pHostParams
 * m_hostVersion - A 2-byte unsigned integer; this field is ignored by the client.
 * m_clientBufSize - A 2-byte unsigned integer specifying the maximum size Aries packet that the server can accept. Before HostOnlinePDU is sent, the Aries buffer size defaults to 1024.

In the function at TSONetServiceSimClientD_base+0x11320, a buffer is (re-)allocated with size m_clientBufSize - 12. This buffer is then used for outgoing Aries packets (but is not used for incoming Aries packets). Since 12 is the size of the Aries header, we can assume that m_clientBufSize specifies the maximum size of any Aries packet that the server can accept from the client.

In response to HostOnlinePDU, the client will send:
 * First time the packet is sent at "35%: Sockets sterilized": ClientOnlinePDU, SetIgnoreListPDU, SetInvisiblePDU, SetInvinciblePDU, SetAcceptAlertsPDU, SetAcceptFlashesPDU, DataServiceWrapperPDU (a MyAvatar request), DBRequestWrapperPDU (an UpdatePreferedLanguageByID request), GetMPSMessagesPDU, three GenericFlashRequestPDUs, ResetWatchdogPDU, ComponentVersionRequestPDU, DBRequestWrapperPDU (a LoadAvatarByID request), DataServiceWrapperPDU (FriendshipWeb_Avatar), DataServiceWrapperPDU (Neighbor_Avatar), DataServiceWrapperPDU (CurrentCity), DataServiceWrapperPDU (CurrentCityTopTenNeighborhoods), and DataServiceWrapperPDU (SimPage_Main) in that order.
 * Past "35%: Sockets sterilized": ClientOnlinePDU, SetIgnoreListPDU, SetInvisiblePDU, SetInvinciblePDU, SetAcceptAlertsPDU, and SetAcceptFlashesPDU, in that order.

InvitationMsgResponsePDU

 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_statusCode - 4 bytes
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pCorrespondentInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_action - 4 bytes

InvitationMsgPDU

 * m_persistMessage - 1 byte set to either 0 or 1
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_persistentMessageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * m_receiverID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_action - 4 bytes

JoinPlayerPDU
The format is as such:
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

JoinRoomFailedPDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

According to the switch/case at TSONetServiceSimClientD_base+0x6a21e, valid status codes are:

JoinRoomPDU
The format is as such:
 * m_RoomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_password - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ListOccupantsPDU
The format is as such:
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ListOccupantsResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Number of occupants - A 4-byte unsigned integer specifying the number of occupants that follow
 * Occupants - For each occupant:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

ListRoomsPDU
The format is as such:
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ListRoomsResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Room count - A 4-byte unsigned integer specifying the number of rooms that follow
 * Rooms - For each room:
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nameLocked - 1 byte set to either 0 or 1
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_stageID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentOccupancy - 4 bytes
 * m_maxOccupancy - 4 bytes
 * m_pwdRequired - 1 byte set to either 0 or 1
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_AdminList
 * Number of admin players - A 2-byte unsigned integer specifying the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admin list is enabled
 * m_AdmitList
 * Number of admit players - A 2-byte unsigned integer specifying the number of admit players that follow
 * Admit players - For each admit player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admit list is enabled
 * m_DenyList
 * Number of deny players - A 2-byte unsigned integer specifying the number of deny players that follow
 * Deny players - For each deny player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this deny list is enabled
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes

OccupantArrivedPDU
The format is as such:
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

MessageLostPDU
The body of this packet is empty.

OccupantDepartedPDU
The format is as such:
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

GetMPSMessagesPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * Player ID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

The server should respond with GetMPSMessagesResponsePDU.

The client does not provide names for the GetMPSMessagesPDU fields. However, when it parses GetMPSMessagesPDU, it calls the "read player ID" function at TSONetServiceSimClientD_base+0x17a10. This function is used for reading m_ariesID/m_masterAccount pairs in other PDUs such as FindPlayerPDU.

GetMPSMessagesResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

DeleteMPSMessagePDU
The client sends this packet in response to RoommateGDMPDU as well as PetitionStatusUpdatePDU. This packet is also sent when you try to open more than 3 IM sessions with the text: "Sorry, I can't respond now. My message queue is full."

The format is as such:
 * m_persistentMessageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped

UpdateRoomAdminListPDU
The format is as such:
 * m_action - 4 bytes
 * m_listType - 1 byte
 * m_subjectID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

GetRoomAdminListPDU
The format is as such:
 * m_listType - 1 byte

GetRoomAdminListResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_listType - 1 byte
 * m_list
 * Number of admin players - A 2-byte unsigned integer specifying the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1

FlashGroupPDU
The format is as such:
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * Unknown - 1 byte set to either 0 or 1
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown1 count - 2 bytes
 * Unknown1s - For each Unknown1:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * Unknown2 count - 2 bytes
 * Unknown2s - For each Unknown2:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * Unknown3 count - 2 bytes
 * Unknown3s - For each Unknown3:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * Unknown4 count - 2 bytes
 * Unknown4s - For each Unknown4:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 1 byte set to either 0 or 1
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_text - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

FlashGroupResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_groupID - 4 bytes

UpdateGroupMemberPDU
The format is as such:
 * m_memberID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_groupID - 4 bytes
 * m_action - 4 bytes

UpdateGroupMemberResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_action - 4 bytes
 * m_groupID - 4 bytes
 * m_subjectID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

UpdateGroupAdminPDU
The format is as such:
 * m_subjectID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_groupID - 4 bytes
 * m_listType - 1 byte
 * m_action - 4 bytes

UpdateGroupAdminResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_action - 4 bytes
 * m_groupID - 4 bytes
 * m_listType - 1 byte
 * m_subjectID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

GpsChatPDU
The format is as such:
 * m_senderID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_receiverID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * AttributeSet
 * Attribute count - A 4-byte unsigned integer with the most significant bit flipped specifying the number of attributes that follow
 * Attributes - For each attribute:
 * Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Value - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

GpsChatResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_senderID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_receiverID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * AttributeSet
 * Attribute count - A 4-byte unsigned integer with the most significant bit flipped specifying the number of attributes that follow
 * Attributes - For each attribute:
 * Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Value - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

PetitionStatusUpdatePDU
The format is as such:
 * m_persistMessage - 1 byte set to either 0 or 1
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_persistentMessageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_receiverID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_timeReceived - A 4-byte Unix timestamp with the most significant bit flipped
 * AttributeSet
 * Attribute count - A 4-byte unsigned integer with the most significant bit flipped specifying the number of attributes that follow
 * Attributes - For each attribute:
 * Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Value - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ReadProfileResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pProfileInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_handle - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_handleLock - 1 byte set to either 0 or 1
 * m_handleModified
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * m_pPermissionInfo
 * perm_CanAlert - 1 byte set to either 0 or 1
 * perm_CanReport - 1 byte set to either 0 or 1
 * perm_CanMessageAll - 1 byte set to either 0 or 1
 * perm_IsAlertable - 1 byte set to either 0 or 1
 * perm_CanSetInvisible - 1 byte set to either 0 or 1
 * perm_CanSetInvincible - 1 byte set to either 0 or 1
 * perm_CanSetAcceptAlerts - 1 byte set to either 0 or 1
 * perm_CanSetAcceptFlashes - 1 byte set to either 0 or 1
 * perm_CanChangeRoomName - 1 byte set to either 0 or 1
 * perm_CanActionRoomName - 1 byte set to either 0 or 1
 * perm_CanChangePlayerName - 1 byte set to either 0 or 1
 * perm_CanActionPlayerName - 1 byte set to either 0 or 1
 * perm_CanGagPlayer - 1 byte set to either 0 or 1
 * perm_CanBanPlayer - 1 byte set to either 0 or 1
 * perm_CanEjectPlayer - 1 byte set to either 0 or 1
 * perm_CanBlacklistPlayer - 1 byte set to either 0 or 1
 * perm_CanYankPlayer - 1 byte set to either 0 or 1
 * perm_CanKillRoom - 1 byte set to either 0 or 1
 * perm_CanModifyPermissions - 1 byte set to either 0 or 1
 * perm_CanOverrideIgnore - 1 byte set to either 0 or 1
 * perm_CanOverrideNoAcceptFlashes - 1 byte set to either 0 or 1
 * perm_CanEnterAnyRoom - 1 byte set to either 0 or 1
 * perm_IgnorePersistLimit - 1 byte set to either 0 or 1
 * perm_CanAdministrateRooms - 1 byte set to either 0 or 1
 * perm_HasAllGroupPrivileges - 1 byte set to either 0 or 1
 * perm_CanRunCheats - 1 byte set to either 0 or 1
 * perm_IsCSR - 1 byte set to either 0 or 1
 * m_appPerms - 4 bytes
 * m_timeCreated
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * m_timeModified
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped
 * m_exileType - 1 byte
 * Unknown - 1 byte set to either 0 or 1
 * m_badge - 1 byte
 * m_lastLogin
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped

SetAcceptAlertsPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_action - 4 bytes

The server should respond with SetAcceptAlertsResponsePDU.

SetAcceptAlertsResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_acceptsAlerts - 1 byte set to either 0 or 1

SetIgnoreListPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_Ignored
 * Number of PlayerIDs - A 2-byte unsigned integer
 * PlayerIDs - For each PlayerID:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

The server should respond with SetIgnoreListResponsePDU.

SetIgnoreListResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_maxNumberOfIgnored - A 4-byte unsigned integer

SetInvinciblePDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_action - 4 bytes

The server should respond with SetInvincibleResponsePDU.

SetInvincibleResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentInvincibilitySetting - 1 byte set to either 0 or 1

SetInvisiblePDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_action - 4 bytes

The server should respond with SetInvisibleResponsePDU.

SetInvisibleResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentInvisibleSetting - 1 byte set to either 0 or 1

SetRoomNamePDU
The format is as such:
 * m_lockName 1 byte set to either 0 or 1
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

SetRoomNameResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomID
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

UpdateOccupantsPDU
The format is as such:
 * m_requestStatus - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_pRoomInfo
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nameLocked - 1 byte set to either 0 or 1
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_stageID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentOccupancy - 4 bytes
 * m_maxOccupancy - A 4-byte unsigned integer
 * m_pwdRequired - 1 byte set to either 0 or 1
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_AdminList
 * Admin player count - A 2-byte unsigned integer specifing the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admin list is enabled
 * m_AdmitList
 * Admit player count - A 2-byte unsigned integer specifing the number of admit players that follow
 * Admit players - For each admit player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admit list is enabled
 * m_DenyList
 * Deny player count - A 2-byte unsigned integer specifing the number of deny players that follow
 * Deny players - For each deny player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this deny list is enabled
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Occupant count - A 2-byte unsigned integer specifying the number of occupants that follow
 * Occupants - For each occupant:
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

UpdatePlayerPDU
The format is as such:
 * m_pPlayerInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1

UpdateProfilePDU
The format is as such:
 * m_pProfileInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_handle - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_handleLock - 1 byte set to either 0 or 1
 * m_handleModified
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * m_pPermissionInfo
 * perm_CanAlert - 1 byte set to either 0 or 1
 * perm_CanReport - 1 byte set to either 0 or 1
 * perm_CanMessageAll - 1 byte set to either 0 or 1
 * perm_IsAlertable - 1 byte set to either 0 or 1
 * perm_CanSetInvisible - 1 byte set to either 0 or 1
 * perm_CanSetInvincible - 1 byte set to either 0 or 1
 * perm_CanSetAcceptAlerts - 1 byte set to either 0 or 1
 * perm_CanSetAcceptFlashes - 1 byte set to either 0 or 1
 * perm_CanChangeRoomName - 1 byte set to either 0 or 1
 * perm_CanActionRoomName - 1 byte set to either 0 or 1
 * perm_CanChangePlayerName - 1 byte set to either 0 or 1
 * perm_CanActionPlayerName - 1 byte set to either 0 or 1
 * perm_CanGagPlayer - 1 byte set to either 0 or 1
 * perm_CanBanPlayer - 1 byte set to either 0 or 1
 * perm_CanEjectPlayer - 1 byte set to either 0 or 1
 * perm_CanBlacklistPlayer - 1 byte set to either 0 or 1
 * perm_CanYankPlayer - 1 byte set to either 0 or 1
 * perm_CanKillRoom - 1 byte set to either 0 or 1
 * perm_CanModifyPermissions - 1 byte set to either 0 or 1
 * perm_CanOverrideIgnore - 1 byte set to either 0 or 1
 * perm_CanOverrideNoAcceptFlashes - 1 byte set to either 0 or 1
 * perm_CanEnterAnyRoom - 1 byte set to either 0 or 1
 * perm_IgnorePersistLimit - 1 byte set to either 0 or 1
 * perm_CanAdministrateRooms - 1 byte set to either 0 or 1
 * perm_HasAllGroupPrivileges - 1 byte set to either 0 or 1
 * perm_CanRunCheats - 1 byte set to either 0 or 1
 * perm_IsCSR - 1 byte set to either 0 or 1
 * m_appPerms - 4 bytes
 * m_timeCreated
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * m_timeModified
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - A 4-byte Unix timestamp with the most significant bit flipped
 * Unknown - string
 * m_exileType - 1 byte
 * Unknown - 1 byte set to either 0 or 1
 * m_badge - 1 byte
 * m_lastLogin
 * m_time - A 4-byte Unix timestamp with the most significant bit flipped

UpdateRoomPDU
UpdateRoomPDU is used to update the list of players on the lot at the client side. (On the HouseSimServer side, UpdateOccupantsPDU/OccupantArrivedPDU/OccupantDepartedPDU may be used instead.)

The city server should send UpdateRoomPDU in three cases:
 * When the player attempts to join a lot.
 * When any player joins/leaves the lot.
 * UpdateRoomPDU may be used to kick/disconnect the player off the lot.

The format is as such:
 * m_reasonCode - 4 bytes
 * m_occupantListFollows - 1 byte set to either 0 or 1
 * m_pRoomInfo
 * m_roomID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nameLocked - 1 byte set to either 0 or 1
 * m_ownerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_stageID
 * m_roomName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_hostName - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_currentOccupancy - 4 bytes
 * m_maxOccupancy - A 4-byte unsigned integer
 * m_pwdRequired - 1 byte set to either 0 or 1
 * m_RoomType - 1 byte
 * m_Group - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_AdminList
 * Admin player count - A 2-byte unsigned integer specifing the number of admin players that follow
 * Admin players - For each admin player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admin list is enabled
 * m_AdmitList
 * Admit player count - A 2-byte unsigned integer specifing the number of admit players that follow
 * Admit players - For each admit player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this admit list is enabled
 * m_DenyList
 * Deny player count - A 2-byte unsigned integer specifing the number of deny players that follow
 * Deny players - For each deny player:
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_EnabledFlag - 1 byte set to either 0 or 1 specifying whether or not this deny list is enabled
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes

According to the switch/case at TSOSimulatorClientD_base+0x51c3, valid reason codes are:

SetAcceptFlashesPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * m_action - 4 bytes

The server should respond with SetAcceptFlashesResponsePDU.

SetAcceptFlashesResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_acceptsFlashes - 1 byte set to either 0 or 1

SplitBufferPDU
Although the client is free to split Voltron PDUs verbatim across multiple Aries packets, in practice, the client always wraps each Voltron fragment inside a SplitBufferPDU, with one SplitBufferPDU per Aries packet, such that each SplitBufferPDU fits within the server's receive limit (SplitBufferPDU.pdu_length <= HostOnlinePDU.m_clientBufSize - 12).

The format is as such:
 * EOF - 1 byte set to either 0 or 1 specifying whether or not this is the last SplitBufferPDU in the sequence. If this flag is set, the client pushes all fragments to the beginning of the client's receive buffer.
 * Fragment size - A 4-byte unsigned integer specifying the size of the fragment that follows.
 * Fragment body - Variable bytes.

UpdateIgnoreListPDU
The format is as such:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 2 bytes

ResetWatchdogPDU
The client sends this packet in response to HostOnlinePDU.

The body of this packet is empty.

The server should respond with ResetWatchdogResponsePDU.

ResetWatchdogResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_nextTimeout - A 4-byte unsigned integer

BroadcastDataBlobPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Body size - A 4-byte unsigned integer specifying the size of the rest of the packet
 * Body

TransmitDataBlobPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * Body size - A 4-byte unsigned integer specifying the size of the rest of the packet
 * Body

DBRequestWrapperPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * SendingAvatarID - 4 bytes
 * m_pSenderInfo
 * m_playerID
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_badge - 1 byte
 * m_isAlertable - 1 byte set to either 0 or 1
 * Message size - A 4-byte unsigned integer specifying the size of the rest of the packet
 * Message
 * Message clsid - 4 bytes; should be the clsid of a Message class, i.e., one that accepts the iid 0x1136D2BF. For DBRequestWrapperPDU, this field is normally 0x125194E5 (cTSONetMessageStandard). Valid values are: 0x125194E5 (cTSONetMessageStandard), 0x125194F5 (cTSONetMessageStream), 0x3EA44787 (cTSOAvatarCreationRequest), 0xAA3ECCB3 (cTSOInterdictor), 0xAA5FA4D8 (cTSOInterdictionPass), 0xCA5FA4E0 (cTSOInterdictionPassAndLog), 0xCA5FA4E3 (cTSOInterdictionDrop), 0xCA5FA4EB (cTSOInterdictionDropAndLog), 0xAA7B191E (cTSONetMessageEnvelope), 0x2A7B4E6A (cTSOChannelMessageEnvelope), 0x0A9D7E3A (cTSODeadStream), 0x09736027 (cTSOTopicUpdateMessage), 0x0A2C6585 (cTSODataTransportBuffer), 0x2A404946 (cTSOTopicUpdateErrorMessage).
 * Message body - variable bytes

The RTTI in EA-Land's version of DBAppServiceSimClientD.dll, and the fact that the cDBRequest constructor (0x100235F0) and cDBResponse constructor (0x10023A90) accept the Request/Response ID as arg1 and message ID as arg2, tell us that these are the possible requests and responses:

TransmitCreateAvatarNotificationPDU
This packet is similar in format to the DataServiceWrapperPDU (with request/response ID 0x3EA44787) that the client sends to the server when the player has clicked OK in Create-A-Sim.

The format of TransmitCreateAvatarNotificationPDU is as such:
 * SendingAvatarID - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Gender - 1 byte specifying the gender; a value of 0 means male, and 1 means female
 * Skin color - 1 byte specifying the skin color; a value of 0 means light, 1 means medium, and 2 means dark
 * Head outfit File ID - A 4-byte unsigned integer specifying the File ID of the head outfit
 * Head outfit Type ID - A 4-byte unsigned integer specifying the Type ID of the head outfit; should be equal to 13 for OFT
 * Body outfit File ID - A 4-byte unsigned integer specifying the File ID of the body outfit
 * Body outfit Type ID - A 4-byte unsigned integer specifying the Type ID of the body outfit; should be equal to 13 for OFT

BC_PlayerLoginEventPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

BC_PlayerLogoutEventPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

RoomserverUserlistPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * Unknown - 1 byte set to either 0 or 1
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * User count - A 2-byte unsigned integer specifying the number of users that follow
 * Users - For each user:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

LotEntryRequestPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * mGridXY - 4 bytes
 * mpHouseSimsConstraints
 * AttributeSet
 * Attribute count - A 4-byte unsigned integer with the most significant bit flipped specifying the number of attributes to follow
 * Name - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Value - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

ClientConfigPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * LotID - 4 bytes
 * ProvideLocalHosting - 1 byte set to either 0 or 1

GenericFlashPDU
This packet can be sent by the server to send a private message (PM) to a player, e.g. http://niotso.org/files/GenericFlashPDU.png

The format is as such:
 * SendingAvatarID - 4 bytes
 * m_sequenceDBID - 4 bytes
 * m_messageType - 4 bytes
 * m_messageSubType - 4 bytes
 * m_displayType - 4 bytes
 * m_sourceType - 4 bytes
 * m_sourceID - 4 bytes
 * m_targetType - 4 bytes
 * m_targetID - 4 bytes
 * m_data1 - 4 bytes
 * m_data2 - 4 bytes
 * m_data3 - 4 bytes
 * m_data4 - 4 bytes
 * m_subject - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_body - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_year - A 2-byte unsigned integer
 * m_month - A 1 byte unsigned integer
 * m_day - A 1 byte unsigned integer
 * m_hour - A 1 byte unsigned integer
 * m_minute - A 1 byte unsigned integer
 * m_second - A 1 byte unsigned integer

GenericFlashRequestPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * SendingAvatarID - A 4-byte unsigned integer
 * mRequesterType - 4 bytes
 * mRequesterID - 4 bytes
 * mTargetType - 4 bytes
 * mTargetID - 4 bytes
 * mSequenceID - 4 bytes

The server should respond with GenericFlashResponsePDU.

GenericFlashResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

TransmitGenericGDMPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A 4-byte unsigned integer with the most significant bit flipped
 * Unknown - 4 bytes

HouseSimConstraintsPDU
The format is as such:
 * Unknown count - A 4-byte unsigned integer with the most significant bit flipped specifying the number of unknowns that follow
 * Unknowns - For each unknown:
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

HouseSimConstraintsResponsePDU
The format is as such:
 * SendingAvatarID - 4 bytes

LoadHouseResponsePDU
The format is as such:
 * SendingAvatarID - 4 bytes

ComponentVersionRequestPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * SendingAvatarID - 4 bytes

The server should respond with ComponentVersionResponsePDU.

ComponentVersionResponsePDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * Number of string pairs - A 2-byte unsigned integer with the most significant bit flipped specifying the number of string pairs to follow
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

RoommateGDMPDU
The format is as such:
 * m_persistMessage - 1 byte set to either 0 or 1
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_persistentMessageID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * mMessageType - 4 bytes
 * mLotID - 4 bytes
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * mMoney - 4 bytes
 * m_time A 4-byte Unix timestamp with the most significant bit flipped

RoommateGDMResponsePDU
The format is as such:
 * m_statusCode - 4 bytes
 * m_reasonText - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_wasPersisted - 1 byte set to either 0 or 1
 * m_statusCode - 4 bytes
 * Unknown - 4 bytes
 * mMessageType - 4 bytes
 * mLotID - 4 bytes
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_ariesID - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * m_masterAccount - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Unknown - 4 bytes

RSGZWrapperPDU
The client sends an RSGZWrapperPDU when the player clicks OK in CAS.

The format is as such:
 * SendingAvatarID - 4 bytes
 * Message ID - 4 bytes
 * Body size - A 4-byte unsigned integer specifying the size of the rest of the packet
 * Message
 * Message clsid - 4 bytes; should be the clsid of a Message class, i.e., one that accepts the iid 0x1136D2BF. For RSGZWrapperPDU, this field is normally 0x125194E5 (cTSONetMessageStandard). Valid values are: 0x125194E5 (cTSONetMessageStandard), 0x125194F5 (cTSONetMessageStream), 0x3EA44787 (cTSOAvatarCreationRequest), 0xAA3ECCB3 (cTSOInterdictor), 0xAA5FA4D8 (cTSOInterdictionPass), 0xCA5FA4E0 (cTSOInterdictionPassAndLog), 0xCA5FA4E3 (cTSOInterdictionDrop), 0xCA5FA4EB (cTSOInterdictionDropAndLog), 0xAA7B191E (cTSONetMessageEnvelope), 0x2A7B4E6A (cTSOChannelMessageEnvelope), 0x0A9D7E3A (cTSODeadStream), 0x09736027 (cTSOTopicUpdateMessage), 0x0A2C6585 (cTSODataTransportBuffer), 0x2A404946 (cTSOTopicUpdateErrorMessage).
 * Message body - variable bytes

AvatarHasNewLotIDPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * LotID - 4 bytes
 * AvatarID - 4 bytes
 * Money - 4 bytes
 * Message - 4 bytes

CheatPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * CheatString - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

DataServiceWrapperPDU
The client sends this packet in response to HostOnlinePDU.

The format is as such:
 * SendingAvatarID - 4 bytes
 * String ID - A 4-byte unsigned integer specifying the string ID of a string in TSOData_datadefinition.dat
 * Body size - A 4-byte unsigned integer specifying the size of the rest of the packet
 * Message
 * Message clsid - 4 bytes; should be the clsid of a Message class, i.e., one that accepts the iid 0x1136D2BF. For DataServiceWrapperPDU, this field is normally 0x125194E5 (cTSONetMessageStandard) for topic subscribe/unsubscribe requests and 0x09736027 (cTSOTopicUpdateMessage) for topic update notifications. Valid values are: 0x125194E5 (cTSONetMessageStandard), 0x125194F5 (cTSONetMessageStream), 0x3EA44787 (cTSOAvatarCreationRequest), 0xAA3ECCB3 (cTSOInterdictor), 0xAA5FA4D8 (cTSOInterdictionPass), 0xCA5FA4E0 (cTSOInterdictionPassAndLog), 0xCA5FA4E3 (cTSOInterdictionDrop), 0xCA5FA4EB (cTSOInterdictionDropAndLog), 0xAA7B191E (cTSONetMessageEnvelope), 0x2A7B4E6A (cTSOChannelMessageEnvelope), 0x0A9D7E3A (cTSODeadStream), 0x09736027 (cTSOTopicUpdateMessage), 0x0A2C6585 (cTSODataTransportBuffer), 0x2A404946 (cTSOTopicUpdateErrorMessage).
 * Message body - variable bytes

The RTTI for EA-Land's version of TSODataServiceClientD.dll mimics the contents of TSOData_datadefinition.dat.

LogCsrActionPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * actionType - 4 bytes
 * csrID - 4 bytes
 * targetAvatarID - 4 bytes
 * Detail - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Note - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

LogAvatarActionPDU
The format is as such:
 * SendingAvatarID - 4 bytes
 * actionType - 4 bytes
 * avatarID - 4 bytes
 * targetAvatarID - 4 bytes
 * CSR - 1 byte set to either 0 or 1
 * Detail - A Pascal string with 4 string length bytes with the most significant bit of the length flipped
 * Note - A Pascal string with 4 string length bytes with the most significant bit of the length flipped

LoadAvatarByID
The client sends a LoadAvatarByID request after receiving a HostOnlinePDU. (LoadAvatarByID was originally GetCharBlobByID prior to FilePlanet Play Test.)

Request:

The client sends the request with 0x3BF82D4E as the message ID. The format of the body is as such:
 * Avatar ID - A 4-byte unsigned integer specifying the avatar ID
 * Unknown - 4 bytes equal to 0
 * Reserved - 32 bytes of uninitialized memory (just like Heartbleed); equal to "BA AD F0 0D BA AD F0 0D ..." if you are running the game in a debugger
 * Unknown - 4 bytes equal to 0x69f4d5e8

Response:

Figuring out LoadAvatarByID is currently a subject of interest. Originally, the only thing that mattered for getting into the map view was the structure of the body (string, string, short, short, ...). Since then, more fields have been figured out which make the avatar visible on the lot, even though more than 50% of the packet is still unknown.

The second-to-last field must be 0x69f4d5e8 for the 0x8ADF865D guard function to return 0. (The guard function is located at TSOServiceClientD_base+0x2c574, and the comparison against 0x69f4d5e8 is made at TSOServiceClientD_base+0x2c5a0.) The response should be made with 0xDBF301A9 as the message ID. The format of the body is as such: dword Avatar ID: 0x00000539 pascalv Avatar name: "JollySim" pascalv unknown: "B" short Mechanical Skill: 0x1011 (in one-hundredths) short Cooking Skill: 0x1213 short Charisma Skill: 0x1415 short Logic Skill: 0x1617 short Body Skill: 0x1819 short Creativity Skill: 0x1a1b short SkillLockMechanical: 0x1c1d short SkillLockCooking: 0x1e1f short SkillLockCharisma: 0x2021 short SkillLockLogic: 0x2223 short SkillLockBody: 0x2425 short SkillLockCreativity: 0x2627 dword unknown: 0x28292a2b dword unknown: 0x2c2d2e2f dword unknown: 0x30313233 dword unknown: 0x34353637 dword unknown: 0x38393a3b dword unknown: 0x3c3d3e3f dword unknown: 0x40414243 byte Gender: 0x00 (nonzero means female, zero means male) byte Skin color: 0x00 (0 means light, 1 means medium, 2 means dark) dword cash: 0x46474849 dword unknown: 0x4a4b4c4d dword lot coordinates: 0x4e4f5051 byte unknown: 0x52 pascalv Head Outfit ID: "0x000003A10000000D" pascalv Body Normal ID: "0x0000024A0000000D" pascalv Body Swimwear ID: "0x000002B70000000D" pascalv Body Sleepwear ID: "0x000002B60000000D" pascalv Body Nude ID: "0x0000024E0000000D" dword unknown: 0x54555657 dword unknown: 0x58595A5B dword unknown: 0x5C5D5E5F dword unknown: 0x60616263 dword unknown: 0x64656667 dword unknown: 0x68690000 (note: the bottom two bytes correspond to the "Is Ghost?" person data attribute and should be set to 0 for a normal person) dword unknown: 0x6C6D6E6F dword unknown: 0x70717273 dword unknown: 0x74757677 dword bonus count (cDBRowBonus): 0x00000001 dword clothes count (cDBRowAvatarCloth): 0x00000001 dword simulator_attribute count (cDBRowAvatarSimulatorAttribute): 0x00000001 dword job count (cDBRowJobLevel): 0x00000001 short OnlineJobID: 0xbbbc short unknown: 0xbdbe dword unknown: 0xbfc0c1c2 dword unknown: 0xc3c4c5c6 dword friend count (cDBRowFriend): 0x00000001 dword (enemy?) count (cDBRowFriend): 0x00000001 dword task count (cDBRowLoadAvatarTask): 0x00000001 dword wearable count (cDBRowWearable): 0x00000001 dword unknown: 0x7a7b7c7d dword unknown: 0x7e7f6061 dword unknown: 0x62636465 dword unknown: 0x66676869 dword unknown: 0x6a6b6c6d dword unknown: 0x6e6f5051 dword unknown: 0x52535455 dword unknown: 0x56575859 dword unknown: 0x69f4d5e8 dword unknown: 0x5e5f4041
 * dword unknown: 0x7C7D7E7F
 * dword unknown: 0x80818283
 * dword Sim bonus: 0x84858687
 * dword Property bonus: 0x88898A8B
 * dword Visitor bonus: 0x8C8D8E8F
 * pascalv date string: "H"
 * dword unknown: 0x94959697
 * qword unknown: 0x98999a9b9c9d9e9f
 * dword unknown: 0xa5a6a7a8
 * dword unknown: 0xa9aaabac
 * short unknown: 0xb1b2
 * short unknown: 0xb3b4
 * dword unknown: 0xb5b6b7b8
 * short unknown: 0xb9ba
 * dword unknown: 0xcbcccdce
 * dword unknown: 0xcfd0d1d2
 * dword unknown: 0xd3d4d5d6
 * byte unknown: 0xd7
 * byte unknown: 0xd8
 * dword unknown: 0xd9dadbdc
 * dword unknown: 0xdddedfe0
 * dword unknown: 0xe1e2e3e4
 * dword unknown: 0xe9eaebec
 * dword unknown: 0xedeeeff0
 * dword unknown: 0xf1f2f3f4
 * byte unknown: 0xf5
 * byte unknown: 0xf6
 * dword unknown: 0xf7f8f9fa
 * dword unknown: 0xfbfcfdfe
 * dword unknown: 0xff808182
 * dword unknown: 0x8788898a
 * short unknown: 0x8b8c
 * dword unknown: 0x8d8e8f90
 * dword unknown: 0x91929394
 * dword unknown: 0x95969798
 * dword unknown: 0x999a9b9c
 * short unknown: 0x7071
 * qword unknown: 0x7273747576777879

In all Play Test versions of the game, the file "userdata/characters/netuser00000.iff" is generated in NoNetwork mode; the NoNetwork Sim's outfit IDs are stored in the "bodystring" chunk. In New & Improved Trial, in response to LoadAvatarByID, it turns out that the bodystring table for the Sim is created at TSOSimulatorClientD_base+0x699d3 with the exact same entries that are in Play Test ("Adult", string, string, "HEAD", "Top", ...). Each entry can be stepped through by placing a breakpoint at TSOSimulatorClientD_base+0x69b42. Using this information, the Outfit ID fields, the Gender field, and the Skin Color field were determined, which are sufficient to make the avatar visible on the lot (once the 0x0ac11f1e packet is sent to the client).

Search
The client sends a Search request when the user searches for a lot or property using the Wildcard Match button.

Request:

The client sends the request with 0x3BF82D4E as the message ID. The format of the body is as such:
 * Search string - A Pascal string with variable-length coding for the length
 * Search type - A 4-byte unsigned integer specifying what type of search to perform; a value of 1 means Sims; a value of 2 means Properties
 * Unknown - 4 bytes equal to 0
 * Unknown - 4 bytes equal to 0
 * Reserved - 32 bytes of uninitialized memory (just like Heartbleed); equal to "BA AD F0 0D BA AD F0 0D ..." if you are running the game in a debugger
 * Unknown - 4 bytes equal to 0

Response:

The response should be made with 0xDBF301A9 as the message ID. The format of the body is as such:
 * Search string - A Pascal string with variable-length coding for the length
 * Search type - A 4-byte unsigned integer specifying what type of search to perform; a value of 1 means Sims; a value of 2 means Properties
 * Unknown - 4 bytes
 * Result count - A 4-byte unsigned integer specifying the number of search results
 * Results - For each result:
 * Id - 4 bytes, Id associated with the result, sim id for sims and lot id for lots
 * Name - A Pascal string with variable-length coding for the length specifying the name of this search result
 * Reserved
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes

SearchExactMatch
The client sends a Search request when the user searches for a lot or property using the Exact Match button.

The requests and responses and their message IDs are the same as those of Search.

UpdatePreferedLanguageByID
The client sends an UpdatePreferedLanguageByID request after receiving a HostOnlinePDU.

Request:

The client sends the request with 0x3BF82D4E as the message ID. The format of the body is as such:
 * Avatar ID - A 4-byte unsigned integer specifying the avatar ID of the currently selected avatar
 * Language - A 4-byte unsigned integer specifying a language code (defined in the IFF STR# chunk)
 * Unknown - 4 bytes equal to 0
 * Reserved - 32 bytes of uninitialized memory (just like Heartbleed); equal to "BA AD F0 0D BA AD F0 0D ..." if you are running the game in a debugger
 * Unknown - 4 bytes equal to 0x69f4d5e8

There is no response ID for UpdatePreferedLanguageByID; therefore, we can assume that the server does not respond to this packet.

Regulators
The game uses message queues to carry out its logic for various tasks. Each message queue can be thought of as an independently running program. The programs wait for events to arrive and perform short computations in response to those events. After completing a computation to handle an event, the program goes back to sleep. And a program can communicate with other programs by "posting" events into the queues for those programs.

As we see from the debugging strings in TSOServiceClientD.dll (in any version of the game), Maxis calls these message queues "regulators". Very fortunately for us, the game provides a string name for each regulator. The regulator known as "mClientLoginRegulator" is involved when the client connects to the city server, when it enters Create-A-Sim and the map view, and when it disconnects from the city server.

Each regulator has a list of message IDs that it accepts and a callback function for each message ID, similar to event handlers in JavaScript (e.g. 'onmouseover="dosomething;"'). In TSO New & Improved, the subroutines that actually remove the message from the message queue and call the associated callback function are duplicated across many dlls (and TSOClient.exe):
 * TSOClient.exe
 * TSODataServiceClientD.dll
 * TSOEdithPluginClientD.dll
 * TSONetServiceSimClientD.dll
 * TSOServiceClientD.dll
 * TSOSimulatorClientD.dll
 * TSOViewerClientD.dll
 * TSOWinAppD.dll

You can see for yourself if you do a ctrl+f for "regulator" (case-insensitive) in these dlls and look at the duplicated strings. We'll discuss the ones that are found in TSOServiceClientD.dll in the New & Improved trial.

Based on the debugging string found at TSOServiceClientD_base+0x2a674, the function cTSOClientLoginRegulator::HandleInitLogin is found at TSOServiceClientD_base+0x2a65b. If you set a breakpoint on this function, you'll see it gets called when you enter Select-A-Sim. Using "Right-click -> Find references to -> Selected command" in OllyDbg, we see that this function has 5 references. The references are each part of a function call to TSOServiceClientD_base+0x2c76c, one of which looks like this: CPU Disasm Address  Hex dump          Command                                  Comments 03229FF6     BE 15D82203   MOV ESI,0322D815 ; "xor eax, eax; ret 4" function 03229FFB     85C0          TEST EAX,EAX 03229FFD     74 1A         JE SHORT 0322A019 03229FFF     33C9          XOR ECX,ECX 0322A001     51            PUSH ECX 0322A002     56            PUSH ESI 0322A003     51            PUSH ECX 0322A004     B9 5BA62203   MOV ECX,cTSOClientLoginRegulator::HandleInitLogin 0322A009     51            PUSH ECX 0322A00A     57            PUSH EDI 0322A00B     68 8951FF89   PUSH 89FF5189 0322A010     8BC8          MOV ECX,EAX 0322A012     E8 55270000   CALL 0322C76C

One would guess that this function call registers the message ID 0x89FF5189 with the function we were just looking at. And it turns out that this function simply constructs and returns an object, which the code then immediately passes (as a pointer) as arg1 to TSOServiceClientD_base+0x33528, which registers the message type with a Regulator object passed as the "this" pointer in ecx. (You can verify that you're looking at a Regulator object by looking for its name. In every regulator object at offset +0x04 is a pointer to a cRZString object representing the name of the regulator.)

We see from the function call shown above that there are actually 2 callback functions associated with a message type (in this case, message type 0x89FF5189 has cTSOClientLoginRegulator::HandleInitLogin as one callback function and "xor eax, eax; ret 4" as another callback function). There is a debugging string at TSOServiceClientD_base+0x33c35 that refers to the second callback function as a "Regulator message guard", so we will call this the "guard function". The first callback function is where the handling logic really appears to occur, so we will call this the "process function".

Looking back at the cTSOClientLoginRegulator::HandleInitLogin example, if you place a breakpoint on this function, enter Select-A-Sim, allow the breakpoint to trip, and look at the call stack, you'll see that the function that calls this function is TSOServiceClientD_base+0x2c81d, which is the second in a sequence of 5 similar-looking small functions. If you place a breakpoint on all 5 functions, you'll see that the guard function of any message gets called by the first and the process function gets called by the second.

It turns out that the guard function determines whether or not the process function gets called; the guard function evaluates whether or not the message (and the payload attached to it) are valid (at the present time) and returns zero to specify that the process function should be called, and nonzero otherwise.

Messages can have different callback functions depending on the current state of the regulator. Maxis decided to model regulators as finite state machines. The debugging string at TSOServiceClientD_base+0x33e46 ("Regulator %s: RequestStateChange to %s when %s has no transition to that state.") tells us two things: that the function at TSOServiceClientD_base+0x33db3 (which accepts a Regulator object in ecx) is called "RequestStateChange", and that state changes must be done through an acceptable "transition" from the current state to the next state. We will discuss this in a moment.

If you do "Find all referenced strings" in OllyDbg and follow the strings that are clearly the name of Regulator objects (e.g. "LeaseManagerRegulator", "AvatarJoinRegulator", and so on), typically there is a specific function call shortly after the reference to that string, e.g. shortly after the reference to "LeaseManagerRegulator" is: CPU Disasm Address  Hex dump          Command                                 Comments 031BD52C     6A 06         PUSH 6 031BD52E     68 00172403   PUSH OFFSET 03241700 031BD533     8B01          MOV EAX,DWORD PTR DS:[ECX] 031BD535     FF50 30       CALL DWORD PTR DS:[EAX+30]

It turns out that this function (TSOServiceClientD_base+0x32fd5) registers a list of "message triples", as I called them, with the regulator in ecx. Arg1 specifies the location of the message triples, and arg2 specifies the number of message triples. Each message triple consists of 3 dwords, the second of which can be confirmed to be a message ID; the first and third fields are often the same as each other, but sometimes different. Based on our finding of the "RequestStateChange" function, we can guess that the first and third fields are state IDs. If you enumerate the complete list of all message triples for all regulators in all DLLs (which I will display shortly), there are occasionally message triples with duplicate message IDs. The message triples are only unique when you look at the first field in combination with the second field. It is therefore a reasonable guess that the second field specifies the message ID, the first field specifies the current state ID, and the third field specifies the transition state ID. (It is important to note that this function registers the list of valid message IDs for a given regulator, but does not register what callback functions will handle them; this is done separately by a call to TSOServiceClientD_base+0x33528, which e.g. occurs shortly after the "CALL 0322C76C" instruction in the example provided for cTSOClientLoginRegulator::HandleInitLogin).

Here is the complete list of message triples for all regulators in all dlls, with many constants given names from the Pre-Alpha constants table:
 * Note that we can add another constant that does not exist in the table, kMSGID_TellRoommateMoveOutSucceeded = 0xAD0E4BA4, according to the file _208_roommateprotocolstrings.cst in New & Improved Trial and the code that looks at entry #130, TSOServiceClientD_base+0x2edb1.


 * BridgedSimulatorLoginRegulator: 2 entries at TSOClient_base+0x45ea8
 * message 0x1BFAACDC (kMSGID_InitLogin) in state 0x69E25134: transition to state 0x89E2514F
 * message 0x3BF7000A (kConnectionEstablished) in state 0x89E2514F: transition to state 0x89E25157
 * LegacyMessageRegulator: 27 entries, list determined by viewing memory at time of call to Regulator::RegisterMessages
 * message 0xBD83DA84 (kMSGID_SetLotID) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xBD7E8B0B (kMSGID_EnterLotAsVisitor) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x5BF7002F (kPartedRoom) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x6B6F23A1 (kServerTickConfirmationMsg) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x1D6AB192 (kMSGID_AvatarOnlineResponse) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x3BFC2808 (kMSGID_JoinHouseResponse) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x9B7ED631 (kMSGID_HouseData) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xFBF7001B (kConnectionFailed) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x099DA5B8 (kMSGID_MessageHouseOccupants) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xA92CB404 (kMSGID_FlashMessage) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xE92DA3D1 (kMSGID_FlashMessageResponse) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x3D98E704 (kMSGID_ConfirmRoommateInviteRequest) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xC98B8830 (kMSGID_TellInviterSetAcceptRMSucceeded) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x9D973DB1 (kMSGID_ConfirmMoveOutAvatarRequest) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x7DFE4263 (kMSGID_TellOwnerKickoutRMSucceeded) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xC98B881F (kMSGID_AskInviteeToAcceptRMInvite) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xC98B8835 (kMSGID_TellInviteeSetAcceptRMSucceeded) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x89EE097C in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xC96E2FC3 (kMSGID_GDMQueryStatusResponse) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x1E04C15A (kAudioRadioSyncSound) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x09C82624 in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x69A2E641 (kDBGetLotList_Query) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xE9A2E6BF (kDBGetBookmarks_Query) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x3DD9B59E (kAudioAmbienceSync) in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0xEA42965C in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x3EC72BF7 in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * message 0x4AE9DD30 in state 0x09EF8F3C: transition to state 0x09EF8F3C
 * DataServiceRegulator: 16 entries at TSODataServiceClientD_base+0x9d6d0
 * message 0xA97360C5 (GZMSGID_cITSOApprovedTopicUpdate) in state 0x6A131659: transition to state 0x6A131659
 * message 0x8A2726E0 in state 0x6A131659: transition to state 0x6A131659
 * message 0xA97360C5 (GZMSGID_cITSOApprovedTopicUpdate) in state 0x0A6E228E: transition to state 0x0A6E228E
 * message 0x8A2726E0 in state 0x0A6E228E: transition to state 0x0A6E228E
 * message 0xA97360C5 (GZMSGID_cITSOApprovedTopicUpdate) in state 0x8A6E4705: transition to state 0x8A6E4705
 * message 0x8A2726E0 in state 0x8A6E4705: transition to state 0x8A6E4705
 * message 0x89FF5197 in state 0x6A131659: transition to state 0x2A92E7ED
 * message 0xEA6C8D8F in state 0x6A131659: transition to state 0x2A92E7ED
 * message 0x89FF519C in state 0x6A131659: transition to state 0x2A92E7ED
 * message 0x7EA33D4D in state 0x2A92E7ED: transition to state 0x0A6E228E
 * message 0x3BF7000A (kConnectionEstablished) in state 0x6A131659: transition to state 0x0A6E228E
 * message 0x3BF7000A (kConnectionEstablished) in state 0x8A6E4705: transition to state 0x0A6E228E
 * message 0xEA6E1298 in state 0x0A6E228E: transition to state 0x8A6E4705
 * message 0xFBF7001B (kConnectionFailed) in state 0x0A6E228E: transition to state 0x6A131659
 * message 0xFBF7001B (kConnectionFailed) in state 0x8A6E4705: transition to state 0x6A131659
 * message 0xFBF7001B (kConnectionFailed) in state 0x2A92E7ED: transition to state 0x6A131659
 * InterestRegulator: 2 entries at TSODataServiceClientD_base+0x9e1c8
 * message 0x09C83484 in state 0xCA8EF0CB: transition to state 0xCA8EF0CB
 * message 0x29C8348F in state 0xCA8EF0CB: transition to state 0xCA8EF0CB
 * TwoPersonJobObjectMaze Regulator: 8 entries at TSOEdithPluginClientD_base+0x84468
 * message 0x4A245A2A in state 0x4A245A3C: transition to state 0x6A245A41
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x6A245A41: transition to state 0x6A245A41
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x6A245A41: transition to state 0x6A245A41
 * message 0xBD83B022 (kMSGID_EdithUserEvent) in state 0x6A245A41: transition to state 0x6A245A41
 * message 0x0A284B40 in state 0x6A245A41: transition to state 0x6A245A41
 * message 0xCA298049 in state 0x6A245A41: transition to state 0x6A245A41
 * message 0xCA36B826 in state 0x6A245A41: transition to state 0x6A245A41
 * message 0x6A36DA90 in state 0x6A245A41: transition to state 0x6A245A41
 * Client NightClubDanceFloor Regulator: 2 entries at TSOEdithPluginClientD_base+0x844f0
 * message 0x0A3DDC22 in state 0x8D113953: transition to state 0x8D113953
 * message 0x2A3DDE2A in state 0x8D113953: transition to state 0x8D113953
 * Client NightClubController Regulator: 2 entries at TSOEdithPluginClientD_base+0x84530
 * message 0x0A3DDC22 in state 0xCCC5BC52: transition to state 0xCCC5BC52
 * message 0x2A3DDE2A in state 0xCCC5BC52: transition to state 0xCCC5BC52
 * Client WarGame Regulator: 16 entries at TSOEdithPluginClientD_base+0x84570
 * message 0xAD65639D in state 0xED6432FE: transition to state 0x0D643305
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xED6432FE: transition to state 0xED6432FE
 * message 0x2A3DDE2A in state 0xED6432FE: transition to state 0xED6432FE
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x0D643305: transition to state 0x0D643305
 * message 0x2D6D23DB in state 0x0D643305: transition to state 0x0D643305
 * message 0xCD657A93 in state 0x0D643305: transition to state 0xAD6D682D
 * message 0xCD657A99 in state 0x0D643305: transition to state 0xED654AE2
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x0D643305: transition to state 0x0D643305
 * message 0x2A3DDE2A in state 0x0D643305: transition to state 0x0D643305
 * message 0x8D6E8CDF in state 0xAD6D682D: transition to state 0x0D643305
 * message 0xCD657A99 in state 0xAD6D682D: transition to state 0xED654AE2
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xAD6D682D: transition to state 0xAD6D682D
 * message 0x2A3DDE2A in state 0xAD6D682D: transition to state 0xAD6D682D
 * message 0xAD65639D in state 0xED654AE2: transition to state 0x0D643305
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xED654AE2: transition to state 0xED654AE2
 * message 0x2A3DDE2A in state 0xED654AE2: transition to state 0xED654AE2
 * Client DJStation Regulator: 8 entries at TSOEdithPluginClientD_base+0x84650
 * message 0x8C5C7163 in state 0x4C5C701E: transition to state 0x4C5C7026
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x4C5C701E: transition to state 0x4C5C701E
 * message 0x2A3DDE2A in state 0x4C5C701E: transition to state 0x4C5C701E
 * message 0xCC620837 in state 0x4C5C7026: transition to state 0x4C5C7026
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x4C5C7026: transition to state 0x4C5C7026
 * message 0x0A3DDC22 in state 0x4C5C7026: transition to state 0x4C5C7026
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x4C5C7026: transition to state 0x4C5C7026
 * message 0x2A3DDE2A in state 0x4C5C7026: transition to state 0x4C5C7028
 * Client DancePlatform Regulator: 8 entries at TSOEdithPluginClientD_base+0x846d0
 * message 0x6C5A326C in state 0x0C5A3211: transition to state 0xCC55D7CD
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x0C5A3211: transition to state 0x0C5A3211
 * message 0x2A3DDE2A in state 0x0C5A3211: transition to state 0x0C5A3211
 * message 0x2C58F74F in state 0xCC55D7CD: transition to state 0xCC55D7CD
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCC55D7CD: transition to state 0xCC55D7CD
 * message 0x0A3DDC22 in state 0xCC55D7CD: transition to state 0xCC55D7CD
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCC55D7CD: transition to state 0xCC55D7CD
 * message 0x2A3DDE2A in state 0xCC55D7CD: transition to state 0xCC55D7D2
 * Client VideoPoker Regulator: 4 entries at TSOEdithPluginClientD_base+0x84750
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x0B709E8C: transition to state 0x0B709E8C
 * message 0x0A3DDC22 in state 0x0B709E8C: transition to state 0x0B709E8C
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x0B709E8C: transition to state 0x0B709E8C
 * message 0x2A3DDE2A in state 0x0B709E8C: transition to state 0x0B709E97
 * Client RackCustomer Regulator: 7 entries at TSOEdithPluginClientD_base+0x847a0
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCB492996: transition to state 0xCB492996
 * message 0xEB4D2965 in state 0xCB492996: transition to state 0xCB492996
 * message 0x2DEE6BE4 in state 0xCB492996: transition to state 0xCB492996
 * message 0xEB4D296D in state 0xCB492996: transition to state 0xEB49299B
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCB492996: transition to state 0xCB492996
 * message 0x2A3DDE2A in state 0xCB492996: transition to state 0xEB49299B
 * message 0xCDEEA04D in state 0xEB49299B: transition to state 0xEB49299B
 * Client RackOwner Regulator: 5 entries at TSOEdithPluginClientD_base+0x847f8
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCB492996: transition to state 0xCB492996
 * message 0x0B8306F5 in state 0xCB492996: transition to state 0xCB492996
 * message 0xAB6628E7 in state 0xCB492996: transition to state 0xCB492996
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCB492996: transition to state 0xCB492996
 * message 0x2A3DDE2A in state 0xCB492996: transition to state 0xEB49299B
 * Client Spotlight Regulator: 4 entries at TSOEdithPluginClientD_base+0x84870
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x4B6AA0CD: transition to state 0x4B6AA0CD
 * message 0x0A3DDC22 in state 0x4B6AA0CD: transition to state 0x4B6AA0CD
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x4B6AA0CD: transition to state 0x4B6AA0CD
 * message 0x2A3DDE2A in state 0x4B6AA0CD: transition to state 0x6B6AA0D9
 * Client SkillMiniGame Regulator: 4 entries at TSOEdithPluginClientD_base+0x848c0
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xEB5E42AC: transition to state 0xEB5E42AC
 * message 0x0A3DDC22 in state 0xEB5E42AC: transition to state 0xEB5E42AC
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xEB5E42AC: transition to state 0xEB5E42AC
 * message 0x2A3DDE2A in state 0xEB5E42AC: transition to state 0x0B5E42B0
 * Client Trade Regulator: 1 entry at TSOEdithPluginClientD_base+0x84910
 * message 0x8D6EF45A in state 0xCB79F25D: transition to state 0xCB79F25D
 * Client Dresser Regulator: 3 entries at TSOEdithPluginClientD_base+0x84938
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x49FF5620: transition to state 0x49FF5620
 * message 0x4B39A801 in state 0x49FF5620: transition to state 0xA9FF5683
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x49FF5620: transition to state 0x49FF5620
 * Client Blackjack Regulator: 4 entries at TSOEdithPluginClientD_base+0x84978
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x2B2FCC15: transition to state 0x2B2FCC15
 * message 0x0A3DDC22 in state 0x2B2FCC15: transition to state 0x2B2FCC15
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x2B2FCC15: transition to state 0x2B2FCC15
 * message 0x2A3DDE2A in state 0x2B2FCC15: transition to state 0x2B2FCC19
 * Client Slots Regulator: 6 entries at TSOEdithPluginClientD_base+0x849c8
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xEB280FE8: transition to state 0xEB280FE8
 * message 0x0A3DDC22 in state 0xEB280FE8: transition to state 0xEB280FE8
 * message 0xEB32A594 in state 0xEB280FE8: transition to state 0xEB280FE8
 * message 0x2B3CFF89 in state 0xEB280FE8: transition to state 0xEB280FE8
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xEB280FE8: transition to state 0xEB280FE8
 * message 0x2A3DDE2A in state 0xEB280FE8: transition to state 0xEB280FF1
 * Client Band Regulator: 8 entries at TSOEdithPluginClientD_base+0x84a28
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0xCAE26E71 in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0xCAE2962D in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0x4AE280EC in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0xAAE3605C in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0xAAEB8088 in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * message 0x0B16F720 in state 0xAADFC7D8: transition to state 0xAADFC7D8
 * Client Door Regulator: 6 entries at TSOEdithPluginClientD_base+0x84aa0
 * message 0x4A6A10B9 in state 0xCA69F25D: transition to state 0xCA69F25D
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCA69F25D: transition to state 0xCA69F25D
 * message 0x8A6A4DDA in state 0xCA69F25D: transition to state 0xCA69F25D
 * message 0x8A95DD0E in state 0xCA69F25D: transition to state 0xCA69F256
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA69F25D: transition to state 0xCA69F25D
 * message 0x2A3DDE2A in state 0xCA69F25D: transition to state 0xCA69F256
 * Client Timer Regulator: 4 entries at TSOEdithPluginClientD_base+0x84b00
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xAA65FF8F: transition to state 0xAA65FF8F
 * message 0x0A3DDC22 in state 0xAA65FF8F: transition to state 0xAA65FF8F
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xAA65FF8F: transition to state 0xAA65FF8F
 * message 0x2A3DDE2A in state 0xAA65FF8F: transition to state 0xAA65FF8F
 * Client Signs Regulator: 5 entries at TSOEdithPluginClientD_base+0x84b48
 * message 0xCA64DBBB in state 0x8A6355FD: transition to state 0x8A6355FD
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x8A6355FD: transition to state 0x8A6355FD
 * message 0x2A3DDE2A in state 0x8A6355FD: transition to state 0x8A635602
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x8A6355FD: transition to state 0x8A6355FD
 * message 0xAA63B4C5 in state 0x8A6355FD: transition to state 0x8A635602
 * Client Trunk Regulator: 4 entries at TSOEdithPluginClientD_base+0x84ba0
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x6A5E41A0: transition to state 0x6A5E41A0
 * message 0x2A3DDE2A in state 0x6A5E41A0: transition to state 0x8A5E41B8
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x6A5E41A0: transition to state 0x6A5E41A0
 * message 0xCA5FA3B6 in state 0x6A5E41A0: transition to state 0x8A5E41B8
 * Client Roulette Regulator: 19 entries at TSOEdithPluginClientD_base+0x84bf8
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCB2A7B4A: transition to state 0xCB2A7B4A
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCB2A7B4E: transition to state 0xCB2A7B4E
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCB2A7B4A: transition to state 0xCB2A7B4A
 * message 0x6B2A7BD6 in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0x6B2A7BD6 in state 0xCB2A7B4A: transition to state 0xCB2A7B4A
 * message 0x6B2A7BD6 in state 0xCB2A7B4E: transition to state 0xCB2A7B4E
 * message 0xEB2A6B70 in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0x4B327E42 in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0xEB2A6B70 in state 0xCB2A7B4A: transition to state 0xCB2A7B4A
 * message 0x4B327E42 in state 0xCB2A7B4A: transition to state 0xCB2A7B4A
 * message 0x8B2A7306 in state 0xCB2A7B46: transition to state 0xCB2A7B4A
 * message 0xAB2A7325 in state 0xCB2A7B4A: transition to state 0xCB2A7B4E
 * message 0xBB2A7335 in state 0xCB2A7B4E: transition to state 0xCB2A7B46
 * message 0xCB429ADD in state 0xCB2A7B4E: transition to state 0xCB2A7B52
 * message 0x4B464D66 in state 0xCB2A7B46: transition to state 0xCB2A7B46
 * message 0x4B464D66 in state 0xCB2A7B4A: transition to state 0xCB2A7B46
 * message 0x4B464D66 in state 0xCB2A7B4E: transition to state 0xCB2A7B46
 * Client PizzaMaker Regulator: 17 entries at TSOEdithPluginClientD_base+0x84d08
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA496966: transition to state 0xCA496966
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA49696B: transition to state 0xCA49696B
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA496970: transition to state 0xCA496970
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA496974: transition to state 0xCA496979
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA496979: transition to state 0xCA496979
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCA496970: transition to state 0xCA496970
 * message 0x2A4969C6 in state 0xCA496966: transition to state 0xCA496966
 * message 0x2A4969C6 in state 0xCA49696B: transition to state 0xCA49696B
 * message 0x2A4969C6 in state 0xCA496970: transition to state 0xCA496970
 * message 0x2A4969C6 in state 0xCA496974: transition to state 0xCA496974
 * message 0x2A4969C6 in state 0xCA496979: transition to state 0xCA496979
 * message 0x4A4969F7 in state 0xCA496966: transition to state 0xCA49696B
 * message 0x4A4969FC in state 0xCA49696B: transition to state 0xCA496970
 * message 0x4A496A00 in state 0xCA496970: transition to state 0xCA496970
 * message 0x6A496A08 in state 0xCA496970: transition to state 0xCA496974
 * message 0x6A496A0C in state 0xCA496974: transition to state 0xCA496979
 * message 0x6A496A11 in state 0xCA496979: transition to state 0xCA496966
 * Client PaperChase Regulator: 6 entries at TSOEdithPluginClientD_base+0x84df0
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0xCA41A464: transition to state 0xCA41A464
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0xCA41A464: transition to state 0xCA41A464
 * message 0xAA419468 in state 0xCA41A464: transition to state 0xCA41A464
 * message 0xAA47FCC3 in state 0xCA41A464: transition to state 0xCA41A464
 * message 0xAA47FCCF in state 0xCA41A464: transition to state 0xCA41A464
 * message 0xEA41CC60 in state 0xCA41A464: transition to state 0xCA41A464
 * Client DanceFloor Regulator: 3 entries at TSOEdithPluginClientD_base+0x84e80
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x49FF5620: transition to state 0x49FF5620
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x49FF5620: transition to state 0x49FF5620
 * message 0x0A3DDC22 in state 0x49FF5620: transition to state 0x49FF5620
 * Client Scoreboard Regulator: 4 entries at TSOEdithPluginClientD_base+0x84ec0
 * message 0x9D83BC2D (kMSGID_EODEvent) in state 0x49FF5620: transition to state 0x49FF5620
 * message 0x0A3DDC22 in state 0x49FF5620: transition to state 0x49FF5620
 * message 0xFD7FCA5B (kMSGID_EODShutDown) in state 0x49FF5620: transition to state 0x49FF5620
 * message 0x2A3DDE2A in state 0x49FF5620: transition to state 0xA9FF5683
 * NetMessagePDURegulator: 2 entries at TSONetServiceSimClientD_base+0xa8e28
 * message 0x4ABA95B3 in state 0xCA3FF2A6: transition to state 0xCA3FF2A6
 * message 0xDBF301A9 (kDBServiceResponseMsg) in state 0xCA3FF2A6: transition to state 0xCA3FF2A6
 * PDURegulator: 162 entries, list determined by viewing memory at time of call to Regulator::RegisterMessages
 * message 0x0A411AC7 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000001 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000002 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000003 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000004 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000005 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000006 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000007 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000008 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000009 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000000F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000010 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000011 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000012 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000013 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000014 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000015 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000016 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000017 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000018 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000019 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000001F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000020 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000021 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000022 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000023 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000024 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000025 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000026 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000027 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000028 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000029 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000002F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000030 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000031 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000032 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000033 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000034 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000035 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000036 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000037 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000038 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000039 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000003F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000040 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000041 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000042 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000043 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000044 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000045 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000046 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000047 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000048 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000049 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000004F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000050 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000051 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000052 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000053 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000054 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000055 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000056 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000057 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000058 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000059 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000005F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000060 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000061 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000062 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000063 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000064 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000065 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000066 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000067 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000068 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000069 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000006F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000070 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000071 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00000072 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002710 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002711 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002712 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002713 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002714 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002715 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002716 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002717 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002718 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002719 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000271F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002720 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002721 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002722 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002723 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002724 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002725 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002726 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002727 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002728 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002729 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272B in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000272F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002730 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002731 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002732 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002733 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002734 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002735 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002736 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002737 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002738 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x00002739 in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000273A in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000273C in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000273D in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000273E in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * message 0x0000273F in state 0xCA3FF2A5: transition to state 0xCA3FF2A5
 * LeaseManagerRegulator: 6 entries at TSOServiceClientD_base+0x91700
 * message 0x6B9D4335 in state 0xCBA150AE: transition to state 0xCBA150AE
 * message 0x2B9E5AE7 in state 0xCBA150AE: transition to state 0xCBA150AE
 * message 0x0B9EAF6D in state 0xCBA150AE: transition to state 0xCBA150AE
 * message 0x0B9EAF64 in state 0xCBA150AE: transition to state 0xCBA150AE
 * message 0xDBF301A9 (kDBServiceResponseMsg) in state 0xCBA150AE: transition to state 0xCBA150AE
 * message 0xEC7195C8 in state 0xCBA150AE: transition to state 0xCBA150AE
 * AvatarJoinRegulator: 38 entries at TSOServiceClientD_base+0x92928, 1 entry at TSOServiceClientD_base+0x92af0
 * message 0xC984DE7B (kMSGID_AvatarJoinRequest) in state 0x2984DCF8 (kAvatarIdleState): transition to state 0x49DB85B0
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x2984DCF8 (kAvatarIdleState): transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x2984DCF8 (kAvatarIdleState): transition to state 0xEA5410D3
 * message 0x69DB85D9 in state 0x49DB85B0: transition to state 0x6B9D5123
 * message 0xA9BEF212 (kMSGID_HouseLoaded) in state 0x49DB85B0: transition to state 0x6B9D5123
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x49DB85B0: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x49DB85B0: transition to state 0xEA5410D3
 * message 0x2B9D43E9 in state 0x6B9D5123: transition to state 0x4984DD01 (kAvatarJoiningState)
 * message 0x4B9D43F8 in state 0x6B9D5123: transition to state 0xEA5410D3
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x6B9D5123: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x6B9D5123: transition to state 0xEA5410D3
 * message 0x8ADF865D in state 0x4984DD01 (kAvatarJoiningState): transition to state 0x8C93180D
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x4984DD01 (kAvatarJoiningState): transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x4984DD01 (kAvatarJoiningState): transition to state 0xEA5410D3
 * message 0x4B9D43F8 in state 0x4984DD01 (kAvatarJoiningState): transition to state 0xEA5410D3
 * message 0xAC3B863F in state 0x8C93180D: transition to state 0x0CDC594A
 * message 0x8CDC2DF4 in state 0x8C93180D: transition to state 0x0CDC594A
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x8C93180D: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x8C93180D: transition to state 0xEA5410D3
 * message 0x4B9D43F8 in state 0x8C93180D: transition to state 0xEA5410D3
 * message 0xACDC4FF2 in state 0x0CDC594A: transition to state 0xCA5420A1
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x0CDC594A: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x0CDC594A: transition to state 0xEA5410D3
 * message 0x4B9D43F8 in state 0x0CDC594A: transition to state 0xEA5410D3
 * message 0xA980F3FD (kMSGID_AvatarJoinDone) in state 0xCA5420A1: transition to state 0x4984DD07 (kAvatarJoinedState)
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0xCA5420A1: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0xCA5420A1: transition to state 0xEA5410D3
 * message 0x4B9D43F8 in state 0xCA5420A1: transition to state 0xEA5410D3
 * message 0x8A736D18 in state 0x4984DD07 (kAvatarJoinedState): transition to state 0x8A736719
 * message 0x4B9D43F8 in state 0x4984DD07 (kAvatarJoinedState): transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x4984DD07 (kAvatarJoinedState): transition to state 0x6A736712
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x4984DD07 (kAvatarJoinedState): transition to state 0xEA5410D3
 * message 0x8A736D18 in state 0x6A736712: transition to state 0x4984DD0D (kAvatarLeavingState)
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x8A736719: transition to state 0x4984DD0D (kAvatarLeavingState)
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0x4984DD0D (kAvatarLeavingState): transition to state 0x4984DD0D (kAvatarLeavingState)
 * message 0x521A94E0 (kClientHasDisconnected) in state 0x4984DD0D (kAvatarLeavingState): transition to state 0x4984DD0D (kAvatarLeavingState)
 * message 0xC984DE88 (kMSGID_AvatarLeaveRequest) in state 0xEA5410D3: transition to state 0xEA5410D3
 * message 0x521A94E0 (kClientHasDisconnected) in state 0xEA5410D3: transition to state 0xEA5410D3
 * (in the second list) message 0x00000000 in state 0x2984DCF8 (kAvatarIdleState): transition to state 0x2984DCF8 (kAvatarIdleState)
 * mMapViewRegulator: 22 entries at TSOServiceClientD_base+0x92b10
 * message 0xBBFAABC8 (kMSGID_InitMapView) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x3BF68DAA (kMSGID_RoomListResponse) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x4947E8F6 (kMSGID_CreateFilterResults_MostPopularHouses) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x6947E915 (kMSGID_CreateFilterResults_RecentlyVisitedHouses) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x09488E0E (kMSGID_ClearFilterResults) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xE9664888 (kMSGID_TuningVariablesReady) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x3C017DF8 (kMSGID_SelectLot) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xDBF301A9 (kDBServiceResponseMsg) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xC9A2E6B3 (kDBBuyLotByAvatarID_Query) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xDC17B470 (kMSGID_BuyLot) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xDC17B472 in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x7C39E037 (kMSGID_AutoJoinSelectedAvatarsLot) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xA92C873A (kMSGID_PurgeVisitorAndDelayedJoinHouse) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xBD7E8B0B (kMSGID_EnterLotAsVisitor) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xC991C894 (kMSGID_CreateRoomFailed) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x5BF7002F (kPartedRoom) in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x69FF6855 in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x8A91C0E3 in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xEB3D1B30 in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x0B45338E in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0x20AA4123 in state 0x6A1995A2: transition to state 0x6A1995A2
 * message 0xEC97A26F in state 0x6A1995A2: transition to state 0x6A1995A2
 * GameEntryRegulator: 14 entries at TSOServiceClientD_base+0x93250
 * message 0x9C86B025 (kMSGID_InitCitySelector) in state 0xE9EE7711: transition to state 0x49EE7F7C
 * message 0xE9F521D7 in state 0x49EE7F7C: transition to state 0x09EE7736
 * message 0x69F52253 in state 0x49EE7F7C: transition to state 0x09EE7736
 * message 0x3C8C05AD (kMSGID_CSPatch) in state 0x49EE7F7C: transition to state 0x49EE7F7C
 * message 0xCAC80225 in state 0x49EE7F7C: transition to state 0x89FFD18B
 * message 0x89FF5189 in state 0x49EE7F7C: transition to state 0x29F53607
 * message 0x89FF518E in state 0x49EE7F7C: transition to state 0x29F53607
 * message 0x89FF5197 in state 0x49EE7F7C: transition to state 0x29F53607
 * message 0xEA6C8D8F in state 0x49EE7F7C: transition to state 0x29F53607
 * message 0x89FF519C in state 0x49EE7F7C: transition to state 0x29F53607
 * message 0x0A03BE32 in state 0x49EE7F7C: transition to state 0xE9EE7711
 * message 0x0A03BE32 in state 0x29F53607: transition to state 0xE9EE7711
 * message 0x9C86B025 (kMSGID_InitCitySelector) in state 0x29F53607: transition to state 0x49EE7F7C
 * message 0xCA947042 in state 0x29F53607: transition to state 0x29F53607
 * CitySelectorRegulator: 19 entries at TSOServiceClientD_base+0x932f8
 * message 0x7C86B02D (kMSGID_CSAuthorize) in state 0xE9F6869B: transition to state 0x29EBEAC9
 * message 0xCA039216 in state 0xE9F6869B: transition to state 0x2A00896B
 * message 0x6A8D7300 in state 0xE9F6869B: transition to state 0xE9F6869B
 * message 0x6A8D7300 in state 0x29EBEAC9: transition to state 0x2A00896B
 * message 0x7C86B02D (kMSGID_CSAuthorize) in state 0x29EBEAC9: transition to state 0x29EBEAC9
 * message 0xBC86B033 (kMSGID_CSInitialConnect) in state 0x29EBEAC9: transition to state 0x2A00896B
 * message 0x8A03539C in state 0x2A00896B: transition to state 0xCA0352CF
 * message 0x6A8D7300 in state 0x2A00896B: transition to state 0xCA0352CF
 * message 0xA97360C5 (GZMSGID_cITSOApprovedTopicUpdate) in state 0xCA0352CF: transition to state 0xCA0352CF
 * message 0x8A0353A2 in state 0xCA0352CF: transition to state 0xCA0352D7
 * message 0x6A8D7300 in state 0xCA0352CF: transition to state 0xCA0352D7
 * message 0x3C8C0552 (kMSGID_CSSelectShardWithAvatar) in state 0xCA0352D7: transition to state 0x6C153B3D
 * message 0xDCE95E19 (kMSGID_CSSelectAvatar) in state 0xCA0352D7: transition to state 0x29EE765A
 * message 0x6A8D7300 in state 0xCA0352D7: transition to state 0x29EE765A
 * message 0x3C8C0552 (kMSGID_CSSelectShardWithAvatar) in state 0x29EE765A: transition to state 0x6C153B3D
 * message 0x6A8D7300 in state 0x29EE765A: transition to state 0x6C153B3D
 * message 0x3C8C0552 (kMSGID_CSSelectShardWithAvatar) in state 0x6C153B3D: transition to state 0x6C153B3D
 * message 0x6A8D7300 in state 0x6C153B3D: transition to state 0x29EE765A
 * message 0x6A8D7300 in state 0x6C153B3D: transition to state 0x6C153B3D
 * mClientLoginRegulator: 8 entries at TSOServiceClientD_base+0x93860
 * message 0x89FF5189 in state 0xEA01E68B: transition to state 0xEA01E683
 * message 0x89FF518E in state 0xEA01E68B: transition to state 0xEA01E683
 * message 0x89FF5197 in state 0xEA01E68B: transition to state 0xEA01E683
 * message 0xEA6C8D8F in state 0xEA01E68B: transition to state 0xEA01E683
 * message 0x89FF519C in state 0xEA01E68B: transition to state 0xEA01E683
 * message 0x3BF7000A (kConnectionEstablished) in state 0xEA01E683: transition to state 0xEA01E67C
 * message 0xFBF7001B (kConnectionFailed) in state 0xEA01E683: transition to state 0xEA01E68B
 * message 0xFBF7001B (kConnectionFailed) in state 0xEA01E67C: transition to state 0xEA01E68B
 * mClientLoginConnectedRegulator: 18 entries at TSOServiceClientD_base+0x938c0
 * message 0xAA0234F9 in state 0x29FA0DCD: transition to state 0x29FA0DD4
 * message 0x69FF6866 in state 0x29FA0DCD: transition to state 0x29FA0DD4
 * message 0xAA023502 in state 0x29FA0DCD: transition to state 0x49FA0DE1
 * message 0xEA6CA161 in state 0x29FA0DCD: transition to state 0x49FA0DE1
 * message 0xAA023506 in state 0x29FA0DCD: transition to state 0x49FA0DEB
 * message 0x49FF7D2C in state 0x49FA0DE1: transition to state 0x29FA0DCD
 * message 0x69FF6866 in state 0x49FA0DE1: transition to state 0x29FA0DD4
 * message 0xAA0234F9 in state 0x49FA0DE1: transition to state 0x29FA0DD4
 * message 0x69FF6855 in state 0x49FA0DE1: transition to state 0x29FA0DCD
 * message 0x49FF7D2C in state 0x49FA0DEB: transition to state 0x29FA0DCD
 * message 0x69FF6866 in state 0x49FA0DEB: transition to state 0x29FA0DD4
 * message 0xAA0234F9 in state 0x49FA0DEB: transition to state 0x29FA0DD4
 * message 0x69FF6855 in state 0x49FA0DEB: transition to state 0x29FA0DCD
 * message 0x69FF6855 in state 0x29FA0DD4: transition to state 0x29FA0DCD
 * message 0xAA0234F9 in state 0x29FA0DD4: transition to state 0x29FA0DD4
 * message 0x69FF6855 in state 0x29FA0DD4: transition to state 0x29FA0DCD
 * message 0x69FF6866 in state 0x29FA0DD4: transition to state 0x29FA0DD4
 * message 0x4B043159 in state 0x29FA0DD4: transition to state 0x29FA0DD4
 * mClientLoginDatabaseRegulator: 7 entries at TSOServiceClientD_base+0x93808
 * message 0x2A03513F in state 0xEA0356E6: transition to state 0xEA0356F1
 * message 0x8ADF865D in state 0xEA0356F1: transition to state 0xEA0356E6
 * message 0x49FF8D1D in state 0xEA0356E6: transition to state 0x9EA3328A
 * message 0x29FF7D18 in state 0xEA0356E6: transition to state 0x9EA3328A
 * message 0x29FF7D1D in state 0xEA0356E6: transition to state 0x9EA3328A
 * message 0x7EA33D4D in state 0x9EA3328A: transition to state 0xEA0356E6
 * message 0xDBF301A9 (kDBServiceResponseMsg) in state 0xEA0356E6: transition to state 0xEA0356E6
 * SystemMessageRegulator: 6 entries at TSOServiceClientD_base+0x93d10
 * message 0x3C817530 (kMSGID_DisciplinaryActionNotification) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x1C828202 (kMSGID_ReceivedMOTD) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x0A2C5702 in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x6A2C5756 in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x6A2C5757 in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x6A2C5758 in state 0x0A160F18: transition to state 0x0A160F18
 * RoommateRegulator: 40 entries at TSOServiceClientD_base+0x93dd0
 * message 0xDCDDD019 (kMSGID_RoommateAddEdithEvent) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x7D8CA534 (kMSGID_RequestMoveOutAvatar) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x3D9600B6 (kMSGID_RequestKickOutVisitor) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x9D973DB1 (kMSGID_ConfirmMoveOutAvatarRequest) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x3D973DB8 (kMSGID_ConfirmMoveOutAvatarResponse) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x3D98E704 (kMSGID_ConfirmRoommateInviteRequest) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x5D98E70C (kMSGID_ConfirmRoommateInviteResponse) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x898F94A5 (kMSGID_RoommateAddPersonPage) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C897 (kMSGID_RoommateCreditMoney) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B881F (kMSGID_AskInviteeToAcceptRMInvite) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B8822 (kMSGID_TellInviterInviteeRejectedRMInvite) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B882B (kMSGID_TellInviteeSetAcceptRMFailed) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xFDFF5886 (kMSGID_TellInviterSetAcceptRMFailed_NumRM) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x3DFF588B (kMSGID_TellInviterSetAcceptRMFailed_NoOwnerLot) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xA98B8811 (kMSGID_TellInviterSetPendingRMFailed) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xA98B8815 (kMSGID_TellInviterSetPendingRMFailed_RMHistory) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xA98B8818 (kMSGID_TellInviterSetPendingRMFailed_NumRM) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B881B (kMSGID_TellInviterSetPendingRMFailed_AlreadyRM) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xDDFF587E (kMSGID_TellInviterSetPendingRMFailed_NoOwnerLot) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B8835 (kMSGID_TellInviteeSetAcceptRMSucceeded) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xC98B8830 (kMSGID_TellInviterSetAcceptRMSucceeded) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x7DFE4263 (kMSGID_TellOwnerKickoutRMSucceeded) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x3DFE4269 (kMSGID_TellOwnerKickoutRMFailed) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xFDFE4300 (kMSGID_TellRoommateTheyWereKickedout) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xAD0E4BA4 (kMSGID_TellRoommateMoveOutSucceeded) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x9DFFA106 (kMSGID_TellRMThatRMMovedOut) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xBDFF5F58 (kMSGID_TellRMKickoutRM) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x5DFF588E (kMSGID_TellRMNewRM) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x8A2C281B in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x298E16CA (kMSGID_TellSimulatorRMInviteSucceeded) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x298E16CD (kMSGID_TellSimulatorMoveOutAvatar) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xDBF301A9 (kDBServiceResponseMsg) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C899 (kMSGID_ExecuteMoneyTask) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x09A2E6DD (kDBInsertGenericTask_Query) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x09A2E6DA (kDBGetDebitCreditTask_Query) in state 0x0A160F18: transition to state 0x0A160F18
 * message 0xECF2B8BE in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C89B in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C89A in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C89E in state 0x0A160F18: transition to state 0x0A160F18
 * message 0x4989C89D in state 0x0A160F18: transition to state 0x0A160F18
 * NeighborhoodClientRegulator: 6 entries at TSOSimulatorClientD_base+0xf8348
 * message 0x0AC11F1E in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x09F627FE in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xA9DD088D in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x2A3AAB1C in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x0BB4E694 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xCD191ADB in state 0xCA392E28: transition to state 0xCA392E28
 * ObjectConfigurationRegulator: 1 entry at TSOSimulatorClientD_base+0xf84b8
 * message 0x0B341D90 in state 0x0B34259A: transition to state 0x0B34259A
 * ConnectionRegulator: 9 entries at TSOSimulatorClientD_base+0xf84e8
 * message 0xE9664888 (kMSGID_TuningVariablesReady) in state 0x4989FB48 (kDisconnectedState): transition to state 0x4989FB48 (kDisconnectedState)
 * message 0x3BF7000A (kConnectionEstablished) in state 0x4989FB48 (kDisconnectedState): transition to state 0x4989FB4F (kConnectedState)
 * message 0xFBF7001B (kConnectionFailed) in state 0x4989FB48 (kDisconnectedState): transition to state 0x4989FB48 (kDisconnectedState)
 * message 0xCBBC0936 in state 0x4989FB48 (kDisconnectedState): transition to state 0x4989FB48 (kDisconnectedState)
 * message 0xEA24791E in state 0x4989FB48 (kDisconnectedState): transition to state 0x4989FB48 (kDisconnectedState)
 * message 0xFBF7001B (kConnectionFailed) in state 0x4989FB4F (kConnectedState): transition to state 0x4989FB48 (kDisconnectedState)
 * message 0xCBBC0936 in state 0x4989FB4F (kConnectedState): transition to state 0x4989FB4F (kConnectedState)
 * message 0xEA24791E in state 0x4989FB4F (kConnectedState): transition to state 0x4989FB4F (kConnectedState)
 * message 0xE9664888 (kMSGID_TuningVariablesReady) in state 0x4989FB4F (kConnectedState): transition to state 0x4989FB4F (kConnectedState)
 * HouseLoadRegulator: 14 entries at TSOSimulatorClientD_base+0xf8558
 * message 0x5BF7002C (kJoinedRoom) in state 0x6974F26C (kStartedState): transition to state 0x6974F26C (kStartedState)
 * message 0x3BFC2808 (kMSGID_JoinHouseResponse) in state 0x6974F26C (kStartedState): transition to state 0x6974F26C (kStartedState)
 * message 0x7D1A4415 (kMSGID_GenericMessage) in state 0x6974F26C (kStartedState): transition to state 0x6974F26C (kStartedState)
 * message 0x5BF828CB (kRoomJoinFailed) in state 0x6974F26C (kStartedState): transition to state 0x6974F26C (kStartedState)
 * message 0x5BF7002F (kPartedRoom) in state 0x6974F26C (kStartedState): transition to state 0x6974F26C (kStartedState)
 * message 0x9B7ED631 (kMSGID_HouseData) in state 0x6974F26C (kStartedState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x7D1A4415 (kMSGID_GenericMessage) in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x1C0A629E (kMSGID_PurgeVisitorRequest) in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x294F5AF5 (kMSGID_PurgeVisitorAndDelayedSwitchGameView) in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x6A3ED2E9 in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x6A4A96D5 in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x6A4A96E0 in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F27B (kLoadedEmptyState)
 * message 0x5BF828CB (kRoomJoinFailed) in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F26C (kStartedState)
 * message 0x5BF7002F (kPartedRoom) in state 0x6974F27B (kLoadedEmptyState): transition to state 0x6974F26C (kStartedState)
 * ClientGamePlayRegulator: 21 entries at TSOSimulatorClientD_base+0xf8600
 * message 0xCA135AB9 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x2B09D908 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xCB09DAAD in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x8ED12D38 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x4976558A (kAddObjectToInventoryEvent) in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x4976558F (kMoveObjectToLotEvent) in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x697655A7 (kDeleteObjectFromInventoryEvent) in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x0A397EB1 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x697655B4 (kFailedAddObjectEvent) in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x0B567293 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x697655B6 (kFailedMoveObjectEvent) in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x2A8B26C3 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x6B32CF19 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x6BA15097 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x69FF4A62 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xCB3BA585 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xEF7FBB07 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xEF7FBB0E in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xEF7FBB15 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0xEF7FBB16 in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * message 0x0CB4CF8E in state 0x2A0AFC54: transition to state 0x2A0AFC54
 * ObjectModuleServerRegulator: 18 entries at TSOSimulatorClientD_base+0xf9b28
 * message 0x092B2A57 (kServerCreateObjectEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A59 (kServerKillObjectEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x09512A6B in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5B (kServerCancelInteractionEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A6B in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xCA19D865 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x4A1DE60D in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xAA3DB7C2 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8A3BFE54 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xAA3D4D38 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6CBE3481 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8CBE3489 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x0A5D1A43 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5F in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x4B50D2D9 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6A3D4FEE in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6CF2B5EE in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6CF2FA95 in state 0xCA392E28: transition to state 0xCA392E28
 * ObjectModuleClientRegulator: 23 entries at TSOSimulatorClientD_base+0xf9c00
 * message 0x092B2A58 (kClientCreateObjectEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5D in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5E in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x4B50D2D2 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5A (kClientKillObjectEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A5C (kClientCancelInteractionEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A6C in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x092B2A7C in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x4A1DE615 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xAA3DB7B9 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xA93EA4D6 (kClientGotoDestObjectEvent) in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8A3BFE59 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x0A3D4D91 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6CBE3486 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8CBE348D in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8A3D4FF2 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0xCA5D0217 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8A484F92 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6AA71D17 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8B049413 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x4BA2A373 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x6BA2A390 in state 0xCA392E28: transition to state 0xCA392E28
 * message 0x8D05C47C in state 0xCA392E28: transition to state 0xCA392E28
 * SimulatorRegulator: 1 entry at TSOSimulatorClientD_base+0xfd0a0
 * message 0x1B6F221B (kSimRequestMsg) in state 0xCA3FF2A7: transition to state 0xCA3FF2A7
 * ToolRegulator: 9 entries at TSOViewerClientD_base+0x707a0
 * message 0xA952C7A6 (kShoppingClientChangeToolEvent) in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x09C80739 in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x6976F109 (kShoppingClientMoveObjectEvent) in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x69878885 (kClientSetOwnerEvent) in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x4980E554 (kShoppingClientClearChangeEvent) in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0xA952C7AF (kShoppingChangeToolFailedEvent) in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x4B941965 in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x8B96CF0A in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * message 0x2A00E84E in state 0x89F4E4BC: transition to state 0x89F4E4BC
 * Presentation Layer Regulator: 4 entries at TSOViewerClientD_base+0x70958
 * message 0x4A79FA73 in state 0x2A7A0B52: transition to state 0x2A7A0B52
 * message 0x6ABFF7B0 in state 0x2A7A0B52: transition to state 0x2A7A0B52
 * message 0x4989C89C in state 0x2A7A0B52: transition to state 0x2A7A0B52
 * message 0x4989C89F in state 0x2A7A0B52: transition to state 0x2A7A0B52
 * ActionQueueUIRegulator: 9 entries at TSOWinAppD_base+0x217008
 * message 0x092B2A5C (kClientCancelInteractionEvent) in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0x092B2A6C in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0xEA19D86B in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0x4A1DE615 in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0xAA48042D in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0xCA135AB9 in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0x0A08AA60 in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0xAA31900F in state 0x2A3D8466: transition to state 0x2A3D8466
 * message 0x5BF7002F (kPartedRoom) in state 0x2A3D8466: transition to state 0x2A3D8466
 * MessagingRegulator: 10 entries at TSOWinAppD_base+0x21c348
 * message 0xA92CB404 (kMSGID_FlashMessage) in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0xE92DA3D1 (kMSGID_FlashMessageResponse) in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0x6A2E8CD3 in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0xA92D84BD (kMSGID_SendInstantMessage) in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0xC961562B (kMSGID_SendLetter) in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0x8A36889A in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0x0A2EC64F in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0x0A2EC650 in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0x1D6AB192 (kMSGID_AvatarOnlineResponse) in state 0x8A10C29E: transition to state 0x8A10C29E
 * message 0xA97360C5 (GZMSGID_cITSOApprovedTopicUpdate) in state 0x8A10C29E: transition to state 0x8A10C29E

cTSONetMessageStandard
Fortunately for us, there is a leftover message logging function from developer builds located at TSOServiceClientD_base+0x675c0 which some message handlers (such as cTSOClientLoginRegulator::HandleConnectionEstablished) use to log the messages they receive. (The function constructs a string of the form "cTSOClientLoginRegulator::HandleConnectionEstablished Type = %s, Data1 = %ld, Data2 = %ld, Data3 = %ld, Data4 = %ld, String = '%s', (with extra)" but destroys it at the very end without outputting it.)

By placing a breakpoint on it and single-stepping, we can identify which fields of the cTSONetMessageStandard packet those names refer to.

Thus, using names provided by TSOServiceClientD_base+0x675c0, the format is as follows:


 * Transaction ID - This 4-byte field consists of two shorts, the lower of which increments over time. We can guess that this is a Transaction ID.
 * SendingAvatarID - 4 bytes
 * Flags - 1 byte
 * Message ID - 4 bytes (most common values are 0x3BF82D4E or 0xDBF301A9; 0x897360BF or 0xA97360C5; 0x49736C62 or 0xC9736CE8; 0x09C83484 or 0x29C8348F)
 * If (Flags & (1<<1)):
 * Data1 - 4 bytes
 * If (Flags & (1<<2)):
 * Data2 - 4 bytes
 * If (Flags & (1<<3)):
 * Data3 - 4 bytes
 * If (Flags & (1<<5)):
 * Extra clsid - 4 bytes
 * Extra body - variable bytes
 * If (Flags & (1<<6)):
 * String - A Pascal-like string using the variable-length coding scheme defined in the FC FF STR# format
 * If (Flags & (1<<4)):
 * Data4 - 4 bytes

cTSONetMessageStream
The format is as follows:
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Compressed data - A cTSOSerializableStream

Note: Using a cTSONetMessageStream where a cTSONetMessageStandard is normally used will cause the game to crash at TSONetServiceSimClientD_base+0x66f8b because cTSONetMessageStream does not support the cITSONetMessageStandard (iid=0x1136D2BF) interface.

It's unknown if this class is used for anything.

cTSOTopicUpdateMessage
The format is as follows:
 * Update counter - 4 bytes
 * Message ID - 4 bytes; should be 0xA97360C5 for GZMSGID_cITSOApprovedTopicUpdate
 * Unknown - 4 bytes (Probably m_statusCode)
 * Vector size - A 4-byte unsigned integer specifying the number of elements in the following vector
 * Vector - For each element of the vector
 * Data - 4 bytes
 * cTSOValue clsid - A 4-byte unsigned integer specifying the clsid of a class that accepts the IID 0xE96D0B02 (GZIID_cITSOValueBase). Valid clsids are (note that names are supplied by the RTTI in EA-Land's TSODataServiceClientD.dll):
 * 0x09736027: cTSOTopicUpdateMessage
 * 0x097608AB: cTSOValueVector
 * 0x097608AF: cTSOValueVector
 * 0x097608B3: cTSOValueVector
 * 0x097608B6: cTSOValueVector
 * 0x0A2C6585: cTSODataTransportBuffer
 * 0x29739B14: cTSOTopic
 * 0x2A404946: cTSOTopicUpdateErrorMessage
 * 0x496A78BC: cTSODataDefinitionContainer
 * 0x696D1183: cTSOValue
 * 0x696D1189: cTSOValue
 * 0x69D3E3DB: cTSOValue
 * 0x896D1196: cTSOValue
 * 0x896D11A2: cTSOValueMap >
 * 0x896D1688: cTSOValue >
 * 0x89738492: cTSOValueBVector
 * 0x89738496: cTSOValueVector
 * 0x8973849A: cTSOValueVector
 * 0x8973849E: cTSOValueVector >
 * 0x89739A79: cTSOProperty
 * 0x89D3E3EF: cTSOValue<__int64>
 * 0x89D3E40E: cTSOValueMap
 * 0xA96E38A0: cTSOValueMap
 * 0xA96E38A8: cTSOValueMap
 * 0xA96E38AC: cTSOValueMap >
 * 0xA96E7E5B: cTSOValue >
 * 0xA97353EE: cTSODataService
 * 0xA97384A3: cTSOValueVector >
 * 0xA975FA6E: cTSODataServiceClient
 * 0xA99AF3A8: cTSOValueMap >
 * 0xA99AF3AC: cTSOValueVector >
 * 0xA99AF3B7: cTSOValue >
 * 0xA9D3E412: cTSOValueMap<__int64>
 * 0xA9D3E428: cTSOValueVector
 * 0xA9D3E42D: cTSOValueVector<__int64>
 * 0xC976087C: cTSOValue
 * 0xC97757F5: cTSOValueMap
 * 0xE976088A: cTSOValue
 * 0xE9760891: cTSOValue
 * 0xE9760897: cTSOValue
 * 0xE976089F: cTSOValueMap
 * 0xE97608A2: cTSOValueMap
 * 0xE97608A5: cTSOValueMap
 * 0xE97608A8: cTSOValueMap
 * cTSOValue body - To be documented...
 * String - A pascalvlc string (Probably m_reasonText)

cTSODataTransportBuffer

 * Body size - 4 bytes
 * Body - variable bytes

cTSOTopicUpdateErrorMessage

 * Unknown - 4 bytes
 * Unknown - 4 bytes
 * Vector size - A 4-byte unsigned integer specifying the number of elements in the following vector
 * Vector - For each element of the vector
 * Data - 4 bytes
 * cTSOValue clsid - A 4-byte unsigned integer specifying the clsid of a class that accepts the IID 0xE96D0B02 (GZIID_cITSOValueBase). For valid clsids, see cTSOTopicUpdateMessage.
 * String - A pascalvlc string (Probably m_reasonText)

Packet logging patch
On November 17, 2013, Fatbag released a patch to enable packet logging in the client. Incoming and outgoing PDUs are now logged to a file called "packetlog.dat" using the packet logging functionality left over from developer builds, which supplies names to many fields of the PDUs.

The patch can be downloaded here and should be applied to TSONetServiceSimClientD.dll (please keep a copy of the original TSONetServiceSimClientD.dll):
 * packetlog.bps
 * Patch tool

Here is what packetlog.dat looks like when the server sends HostOnlinePDU: --- INCOMING PDUS --- Unknown Message ID: 30 m_HostReservedWords: Number of words: 0 m_pHostParams: m_hostVersion: 32767 m_clientBufSize: 4096 --- OUTGOING PDUS --- Unknown Message ID: 10 m_pVersionInfo: m_majorVersion: 0 m_minorVersion: 0 m_pointVersion: 0 m_artVersion: 0 m_pRelogStats: m_timeRequired: m_time: Wed Dec 31 18:00:00 1969

m_numberOfAttempts: 0 m_pClientStatus: m_lastExitCode: 13 m_lastFailureType: 3 m_failureCount: \x02 m_isRunning: 1 m_isRelogging: 0 Unknown Message ID: 52 m_Ignored: Number of PlayerIDs: 0 Unknown Message ID: 56 m_action: 0 Unknown Message ID: 54 m_action: 0 Unknown Message ID: 50 m_action: 0 Unknown Message ID: 66 m_action: 0 Unknown Message ID: 10036 SendingAvatarID :4277006349 Unknown Message ID: 10002 SendingAvatarID :4277006349 m_pSenderInfo: m_playerID: m_ariesID: m_masterAccount: m_badge: \x00 m_isAlertable: 0 Unknown Unknown Unknown Message ID: 10014 SendingAvatarID :4277006349 mRequesterType [1] mRequesterID [1337] mTargetType [1] mTargetID [1337] mSequenceID [0] Unknown Unknown Message ID: 10014 SendingAvatarID :4277006349 mRequesterType [1] mRequesterID [1337] mTargetType [5] mTargetID [0] mSequenceID [0] Unknown Unknown Message ID: 10014 SendingAvatarID :4277006349 mRequesterType [1] mRequesterID [1337] mTargetType [6] mTargetID [0] mSequenceID [0] Unknown Message ID: 113 Unknown Message ID: 10025 SendingAvatarID :4277006349 Unknown Message ID: 10002 SendingAvatarID :4277006349 m_pSenderInfo: m_playerID: m_ariesID: m_masterAccount: m_badge: \x00 m_isAlertable: 0 Unknown Message ID: 10036 SendingAvatarID :4277006349 Unknown Message ID: 10036 SendingAvatarID :4277006349

Regulator logging patch
On February 03, 2016, Fatbag released a patch that logs (to the terminal) when regulators are created and destroyed and when regulators receive messages. This patch allows us see how the game creates TSOData topic update messages and cTSOSimEvent messages, allowing one to make packets that send the same messages. (This is easy because the cTSONetMessageStandard layout in memory has a very near correspondence with the cTSONetMessageStandard packet structure, and likewise for cTSOTopicUpdateMessage.)

The patch can be downloaded here and should be applied to TSOServiceClientD.dll (please keep a copy of the original TSOServiceClientD.dll):
 * regulator_logging_naitrial.bps
 * Patch tool

Before applying the patch, you should enable the command line by opening TSOClient.exe with a hex editor and changing the byte at offset 0x15c from 02 to 03.

Progress bar
_251_connectprogressdialog.cst carries very useful comments about each stage of the progress bar:

1 ^Connect Progress^ 2 ^Overall Progress^ 3 ^Current Task^


 * 1) Login Steps to enter a city

4 ^Starting engines^                 # City is Selected... 5 ^Talking with the mothership^      # Connecting to City Selector... 6 ^Mapping information superhighway^ # Processing XML response... 7 ^Sterilizing TCP/IP sockets^       # Connecting to City... 8 ^Sockets sterilized^               # Connection Established... 9 ^Reticulating spleens^             # Asking for Avatar data from DB... 10 ^Spleens Reticulated^             # Received Avatar data from DB... 11 ^Purging psychographic metrics^   # Asking for Character data from DB... 12 ^Metrics Purged^                  # Received Character data from DB... 13 ^Pressurizing peer network^       # Asking for Relationships data from DB... 14 ^Network pressurized^             # Received Relationships data from DB... 15 ^Aligning social agendas^         # Asking for Reversed Relationships data from DB... 16 ^Agendas aligned^                 # Received Reversed Relationships data from DB... 17 ^Preparing cartography^           # Loading City map...

The function that updates the progress bar when asked has been spotted at TSOWinAppD_base+0x306d9, taking the number of the CST file as the first argument (251) and the ID of the string as the second argument. The following calls to this function have been found:

Current progress
Specifying niotso.org as the host for the authorization server and city selection server is enough to get into Select-A-Sim in any version of the game. The instructions are:


 * Make a backup of sys/gameentry.ini. Then open it with a text editor and set the "Server" field to niotso.org. If your version of TSO also has a gamedata/sys/ folder, do the same thing with the copy of gameentry.ini in that folder.
 * Make a backup of sys/cityselector.ini. Then open it with a text editor and set the "ServerName" field to niotso.org. Keep "ServerPort" at 80. If your version of TSO also has a gamedata/sys/ folder, do the same thing with the copy of cityselector.ini in that folder.
 * The niotso.org server does not support HTTPS, so disable it in your client through the following steps:
 * Make a backup of authlogin.dll. Then open it with a hex editor. Replace the 5 bytes "68 00 30 C0 84" (in version 1.1097.1.0 these appear at offset 0x8325) with "68 00 00 40 84". Also, replace the 5 bytes "68 BB 01 00 00" (in version 1.1097.1.0 these appear at offset 0x82AC) with "68 50 00 00 00".
 * Make a backup of TSOServiceClientD.dll. Then open it with a hex editor. Replace the 8 bytes "68 74 74 70 73 3A 2F 2F" (in version 1.1097.1.0 these appear at offset 0x923C0) with "68 74 74 70 3A 2F 2F 00".
 * Make a backup of InternetServiceD.dll. Then open it with a hex editor. Replace the 7 bytes "74 07 68 BB 01 00 00" (in version 1.1097.1.0 these appear at offset 0x17B2) with "EB 07 68 BB 01 00 00". Not all versions of the game contain this code (Play Test and EA-Land do not), so for those versions, this file should remain untouched.

The niotso.org server specifies 127.0.0.1:49100 as the city server to the client. If you decide to proceed into Create-A-Sim, the map view, or a lot, you will need to run TSO-SE in the background before doing this.

To login, the username is asdf and the password is hjkl.

You can download pre-made PDUs here:
 * http://niotso.org/files/disconnect.dat
 * http://niotso.org/files/hostonlinepdu.dat
 * http://niotso.org/files/loadavatarbyid.dat
 * http://niotso.org/files/announcementmsgpdu.dat
 * http://niotso.org/files/flashmsgpdu.dat
 * http://niotso.org/files/flashmsgresponsepdu.dat
 * http://niotso.org/files/genericflashpdu.dat
 * http://niotso.org/files/starttime.dat
 * http://niotso.org/files/hostonlinepdu_ealand.dat
 * http://niotso.org/files/loadavatarbyid_ealand.dat

When you get to "35%: Sockets sterilized", TSO-SE should report "Accepted connection. To see the list of commands, type 'help'." (If it does not do this, make sure TSO-SE is whitelisted in Windows Firewall, because it listens on port 49100.) To advance past this, type "send hostonlinepdu.dat" in TSO-SE. This is enough to get you into Create-A-Sim; for the map view, this gets you to "64%: Metrics purged", so type "send loadavatarbyid.dat" (after hostonlinepdu.dat) and this will get you into the map view.

Some screenshots of the current progress:
 * Select-A-Sim: http://niotso.org/wp-content/uploads/2013/06/select-a-sim.png
 * Create-A-Sim: http://niotso.org/wp-content/uploads/2013/06/create-a-sim.png
 * Map view: http://niotso.org/files/mapview-2014-06-17.png