EOSERV Wiki > Page: Packet

Packet

Structure

The Endless Online packet stream consists of a two byte length followed by possibly encoded data:
(Length:2) (Data:''n'') where ''n'' is the number specified by Length.
The same format is followed for both client-to-server and server-to-client communication.

The first two bytes of the (unencrypted) data are are the packet action and packet family. The remaining data is packet dependent. See Packet_List for a list of packet IDs.

(PacketAction:1) (PacketFamily:1) (Data:''n'') where ''n'' is the length, minus 2.

There is commonly a third byte included with packets sent client-to-server which is an additional security mechanism. This is discussed in the Encryption section.

Number Encoding

Numbers are not sent in plain Two's compliment, as the stream is binary safe (contains no zero bytes) and consequently they have a slightly smaller range of possible values they can represent. See EncodeNumber for an algorithm to encode/decode numbers.

Encryption

Communication between the Endless Online client and server is very lightly encrypted and fairly easy to encode/decode. It is a stateful process and not all packets are encoded.

There are three stages: Flipping, interleaving and "dickwinding". These only apply to the actual packet data (including the ID) and ''not'' the length bytes. For most client-to-server packets there is also a byte inserted immediately following the packet ID which we will refer to as the "counter".

Flipping

All of the bytes in a packet are simply have their most significant bits flipped (i.e. XOR 0x80). e.g.
0x20 -> 0xA0
  or
0x17 -> 0x97 

Interleaving

Packets are "woven" in to each-other using the following patterns.

Encoding e.g.

abcde -> aebdc
  or
abcdef -> afbecd

This is the only step that requires different code for encoding and decoding.

Decoding e.g.

abcde -> acedb
  or
abcdef -> acefdb

Dickwinding

This was named by Sausage and first implemented in the EOProxy project. There are two numbers sent from the server to the client on connect between 6 and 12 that represent a "send packet swap multiple" and a "receive packet swap multiple".

Any two bytes next to each other in the packet data that are divisible by that number are flipped.

Multiple = 5  (ASCII values: T=84, a=97, g=103, h=104, i=105, s=115, x=120) 
"This is a gay six" -> "Thsi si a gay xis"

Counter

There are 2 values sent on connect, and with every ping packet that comes from the server, that give the client a "starting counter ID". A private counter is kept on both the server and the client that increases from 0 to 9 for each packet sent before looping back to 0. If a packet is sent with the wrong counter value (should be starting + loopingcount), the server usually disconnects them (however, no private servers implement this, and only some packets do on the official servers). When the "starting counter ID" is updated by a ping packet, the counter does not reset.
EOSERV Wiki > Page: Packet