Skip to content
This repository was archived by the owner on Apr 6, 2020. It is now read-only.

Networking

Kevin Evans edited this page Jul 13, 2016 · 1 revision

The client opens a TCP socket with the server, then sends a four byte seed packet. Pretty sure this is just a pseudorandom number and I'm actually not entirely sure what it's used for.

Note that uojs uses Websockify to proxy the websocket (a tcp socket with additional headers and encapsulation) to a raw TCP socket. This layer is transparent.

After the connection, the client sends additional data that authenticates and describes the client. This is done through the 0x80 packet. Once the client sends that, the server responds either that the client is OK and sends the server list, or it can error (i.e. authentication failed).

When the server sends the serverlist (0xA8), it contains a list of names of servers and corresponding IDs.

The client tells the server which server it wants to connect to by sending the server's ID from the serverlist (it's usually a zero-based index). The server then responds with a server relay packet, which contains the IP address of the server, the port, and a key.

The client then closes the connection, then reestablishes a new TCP connection with the new server. The client also sends a 4-byte key that it received in the server relay, and reauthenticates.

After this mini handshake, the server sends back compressed data. It is generally huffman coded and the decompression tree is constant and known (see network/constants.js). This layer is done seamlessly and if you're contributing to the codebase, you won't have to worry about this. However my implementation is really quite shitty and might break with certain edge cases.

From here, the client and server exchange packets as normal. For example, the server might send some packet that contains a list of items nearby. All we have to do now is convert this buffer of data to a javascript object that our client can interpret and display.

The packets usually have a single byte command, like a number that tells you what the packet is describing. The packets can either be a fixed size (as in, we know that a certain packet will be exactly 5 bytes or something), or it can be variable sized (like the second and third byte describes how big the packet will be).

Our client stores a map of packet commands and maps them to a function, where we can decode the packet.

Luckily, there is a TON of resources on these packets. Thank you to the people that have spent time writing these resources!

Here's a small list:

You can also use tools like Wireshark to help understand what the original client is sending to the server.

Clone this wiki locally