[[Category Packet]] [[Category Packet 317]] {{Crappy}}
[[File 317 1.jpg|thumb|Client logged in]]
== '''Packet structure''' == When the client sends a packet to the server, the first byte encapsulates its opcode. This specific opcode is encrypted with a value generated by the ISAAC PRNG seeded with a dynamically server generated key during the login block. The server decrypts it and associates the opcode to the packet's respective predefined size. If the packet does not contain a fixed size, the opcode will be followed by either a byte or a word - varying per packet - for its proper size. This is then followed by the payload. == '''Login''' == Every connection to the main 'gateway' server sends a single byte of data, mostly well known as the connection type. The connection type tells the main server which type of connection you wish to initiate. The old engine list consists of: * Login request - connection type 14 * Update - connection type 15 * New connection login - connection type 16 * Reconnecting login - connection type 18 The connection type we will cover in the following paragraphs is the login connection type, 14. After the login handshake initiating connection type, the client writes a small bit of data derived from the logging in player's username. This is believed to help select the appropriate login server. On successful handshake, the server sends back 8 ignored bytes.long l = TextUtils.encodeAsBase37Integer(username); int i = (int) (l >> 16 & 31L); out.offset = 0; out.writeByte(14); // Initiate connection type out.writeByte(i); // "small bit of data derived from... player's username" in.queueBytes(2, out.payload); for (int j = 0; j < 8; j++) in.read();At this point, the client reads in one byte, called the status code. The status code 0 is expected to start the login protocol correctly. If the status code is 0, the client reads a long, dubbed by many as the server session key. This is used to help generate a unique seed for the client session's packet opcode masking. The client then stores two ints that are the upper and lower ints of the client session key, which has the same purpose as the server's key. The client then starts writing the login block, which is RSA encrypted. The login block starts with the byte 10, which is considered a magic number. Following it is the client session key and server session key longs. After the session keys, the session's UID (unique identifier or user identifier) is written to the block. This is used to distinguish between multiple sessions. Trailing behind the UID comes the client's username and password written as modified C-strings that are rather terminated with a 10 byte than a NUL byte. This block is then RSA encrypted and stored for later use. Now starts the login request packet. It starts off with a flag telling the server whether or not the client is reconnecting or connecting for the first time. The byte is 18 or 16, respectively. [NOW CLASSIFIED AS A CONNECTION TYPE] Following is the size of the rest of the login response packet, including the login block that trails at the end, to tip the server how much data it should expect. Later comes the magic number byte 255, and right behind it the client revision short. The packet is just about crafted completely. A flag byte that represents if the client is running in low memory or high memory modes is sent, and after the 9 CRC32 checksums of the file system 0 basic archives (this includes versionlist, media, config, etc.). To top it off, the RSA encrypted login block is appended to the end and the packet is sent to the server. The ISAAC ciphers are seeded for packet opcode masking after adding 50 to each int of the session keys, and the status code is reread. This finishes the login protocol. == '''Player Updating''' == The player updating process consists of 4 parts: * a) Our player movement updates * b) Other player movement updates * c) Player list updating * c.a) Apperance updating * c.b) Location updating * d) Player update block flag-based updates '''Our player movement updates''' The client begins by reading 1 bit. This bit tells the client whether or not it is currently updating 'our player', or the player the client is controlling. If it's not updating our player, it exits and goes onto step b. If it is, it then reads 2 bits. The value is called the movement update type. There are 4 recognized movement update types: * Type 0 basically tells the client there is nothing to update for our player, just add its index to the local updating list. * Type 1 tells the client you moved in one direction. The client reads 3 bits, which represents the direction you moved in, and then 1 bit, which states whether further update is required. If so, it adds it to the updating list. This is used in walking. * Type 2 functions in much of the same way as its previous, only this time it reads two 3 bit values. The first represents the player's last direction, and the second it's current direction. Trailing behind it is also the 1 bit 'update required' flag as type 1. This is used in running. * Type 3 on the other hand is different. It reads in 2 bits which represents our player's plane, or its level of height, in the game world. Only 0-3 inclusive are appropriate planes supported by the client. It then reads 1 bit, which describes whether or not to clear the awaiting-waypoint queue, basically to stop client from further queued stepping, such as used in teleporting. After this, it reads the 'update required' bit, and checks to see if further update is required. Directly after, it reads two 7 bit quantities, representing the new relative X and relative Y coordinates of our player to our current map region's origin. It then sets our players position to the plane, x, and y positions as told to. '''Other player movement updates''' The client begins by reading an 8 bit value telling the client how many players there are to update. It then enters a loop for each player there is to update. Inside this loop, the client reads 1 bit. This is the movement update required flag. If the flag is 0, it sets the current updating player's last update cycle time to the current game logic loop cycle time, and adds the player to the local player list. If the flag is not 0, it then reads the movement update type, which is a 2 bit quantity. The following known types are: * 0, the client updates the current player's last update cycle time, adds the current player to the local player list, and adds it to the updating list. * 1, the client updates the current player's last update cycle time and adds the current player to the local player list as well, but also reads in 3 bit quantity. This represents the current player's direction it walked to. It then reads the a 1 bit value that specifies whether or not to add the player to the updating list. * 2, the client does the exact same thing as the type 2 update, except it reads in two of the 3 bit quantities. The first represents the current player's last direction, and the second its current direction running. * 3, it only adds the player to the needing-update list, or so believed. Type 3 is not well known. '''Player list updating''' The next step in the player updating procedure is the player list updating, or where the client recieves data on every player in its local list, such as appearance and location relative to ours. The client loops through a process for each player in the updating. The client reads an 11 bit quantity from the buffer, which is the next player in the updated list to be informed about. The clietn then checks if it has a cached buffer for that player's updating, and if it does, it updates the player appearance. '''Appearance updating''' Appearance updating starts off by first reading an unsigned byte that represents the current player's gender. Then it reads another unsigned byte that represents the player's over-head icon id. This is used with prayer icons above heads. Next, a loop occurs 12 times to read equipment data. In the loop, the client reads an unsigned byte that is the equipment slot's item id high byte. If it is 0, the player's equpment slot has no item. If it is not 0, another unsigned byte is read the merged with the previous to create the equipment's item id. If the id is 65535 (written as a -1 signed short), then the player's appearance is that of an NPC. The client reads in an unsigned short representing the NPC's id and sets the player's definition to that NPC's. After the equipment loop, it loops 5 times, once for each type of coloured body part. In each loop, the client reads an unsigned short and assigns it as the color of the current loop idx (which represents the body part). Finally, after the color loop, the client reads 7 unsigned shorts representing animation indices; the animations belong to: * Standing still * Turning while standing * Walking * Turning around (backwards) * Turning a quarter-way clockwise * Turning a quarter-way counter clockwise * Running After these animation indices are read, a long representing the player's name is read, an unsigned byte representing the combat level, and an unsigned short representing the players skill level (for things where players arent ranked by levels, such as where it states '
opcode | usage | size | payload |
opcode | usage | size | payload |