WCF Extensibility part 1: background on game server protocols

Talking to game servers

There are various kinds of multiplayer games that allow you to battle against other gamers. I’ll focus on the First Person Shooters (FPS) and Real Time Strategy (RTS) games and skip the (Massive Multiplayer Online) Role Playing Games (MMORPG and RPG). Usually the FPS and RTS games will connect to a central server that is located on your LAN or out in the Internet. The game players will interact by means of the server using a special protocol. The administrators of the server are regular game players for most of the time, but have elevated privileges to control the game server. Typical things that an admin will do is change the currently played map, restart game rounds, and kick or ban misbehaving players from the server.

This type of control can be done “locally” when the admin is one of the players connected to the server, or remotely. The latter is called remote control and it uses a special protocol particular to the type of game engine. Luckily most of these protocols are reasonably well documented. There are not that many game engines out there and hence a small number of protocols. The most famous ones are:

  • Unreal (1, 2 and 3)
  • Quake (1, 2 and 3)
  • Half-Life (aka Goldsource, based on Quake engine)
  • Source
  • Doom 3

Right now, we’ll zoom in on the Source engine with its protocol for remote control of game servers based on this engine.

Issuing commands

If you have a Source-based game like Half-Life 2 or Team Fortress 2 it is pretty easy to use control from the game interface. You can simply connect to the server to control by joining a multiplayer game. Once on the server you can access a console window to send commands. A comprehensive list of commands is available. Here are some examples of common commands:

rcon_password abc123

changelevel de_dust2
kick 1:0:12345
mp_restartround 1

The first command rcon_password is needed to prevent unwanted control of a game server.

You can even use remote control by specifying the server address and password first, so you do not have to connect to the game at all.

rcon_password abc123

The game itself is needed to control the server, because the game knows the protocol specific to the engine. But other than that it is inconvenient that you would need to own and start the game just to control the server. There are a fair number of code implementations out there that capture the protocol and allow a programmer to use the API to control a server remotely. I wrote several myself, which is a nice programming exercise with an interesting theme of gaming. Well, at least it beats the common customer/order/product samples.

Understanding the protocol

The Source engine is created and maintained by Valve and their developer wiki holds a pretty good explanation of the Source remote control (rcon) protocol.

Here’s my take on the protocol:

Source uses a TCP connection from the client to the game server. After connecting the client should perform an authentication handshake. If the authentication was successful, you can start issuing commands. The protocol uses multiple message exchanges between client and server to accomplish both. Every message has the same structure:

  • packet size (int): entire message excluding packet size integer. It must be at least 10.
  • request id (int): random number used for correlating responses to requests
  • server data (int): depending on purpose of message the server data has one of the following values
    • SERVERDATA_AUTH = 3: initial authentication handshake message
    • SERVERDATA_EXECCOMMAND = 2: command message
    • SERVERDATA_RESPONSE_VALUE = 0: response from command message
    • SERVERDATA_AUTH_RESPONSE = 2: acknowledgement of authentication message
  • string1 (null-terminated string): either command to run, password or result
  • string2 (null-terminated string): reserverd, must be empty string (“”);
  • A typical rcon session will look like this:


    Let’s take a look at some of the individual packets. Let’s assume that the password is “abc123” and that the command that was issued is “changelevel de_dust2”

      Authentication Junk Acknowledgment Exec command command reply
    packet size 4 + 4 + 7 + 1 == 16 4 + 4 + 1 + 1 == 10 4 + 4 + 1 + 1 == 10 4 + 4 + 21 + 1 == 30 4 + 4 + (string1.length + 1) + 1 == 10
    request id 0x2e0e0000 0x2e0e0000 0x2e0e0000 0xd2010000 0xd2010000
    server data 3 0 2 2 0
    string 1 “abc123” “” “” “changelevel de_dust2” “” (command specific,
    varies depending of success or failure of method)
    string 2 “” “” “” “” “”

    After the exec command and corresponding reply packets you can continue issuing exec commands.

    de_train1aThe sequence of message above is the ideal picture. In reality things might be a little more difficult, because:

    1. a reply may consist of multiple reply packets.
    2. authentication might not be successful because of a wrong password.

    Eventually we will take everything into account, but for now we will pretend that multi-packet responses do not exist and that authentication is always successful.

    If that works, the exchange of raw bytes across the network should look something like this (for the 5 messages listed above):

    0000   10 00 00 00 2e 0e 00 00 03 00 00 00 61 62 63 31  ............abc1
    0010   32 33 00 00                                      23..
    0000   0a 00 00 00 2e 0e 00 00 00 00 00 00 00 00        ..............
    0000   0a 00 00 00 2e 0e 00 00 02 00 00 00 00 00        ..............
    0000   1e 00 00 00 d2 01 00 00 02 00 00 00 63 68 61 6e  ............chan
    0010   67 65 6c 65 76 65 6c 20 64 65 5f 64 75 73 74 32  gelevel de_dust2
    0020   00 00                                            ..
    0000   0a 00 00 00 d2 01 00 00 00 00 00 00 00 00        ..............

    Next steps

    Our task at hand is to learn WCF to speak this protocol, while maintaining the channel layer concepts.

    This entry was posted in Uncategorized. Bookmark the permalink.

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out /  Change )

    Google photo

    You are commenting using your Google account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s