Packet Types
There are five basic types of packets involved when the CheckValve Chat Relay communicates with clients:- Identity string (server-to-client)
- Connection request (client-to-server)
- Connection response (server-to-client)
- Chat message (server-to-client)
- Heartbeat (server-to-client)
Data Types
The following data types are used in the subsequent packet definitions:
Data Type | Description |
Byte | A single byte |
Short | A 16-bit (2-byte) integer in little-endian format |
Integer | A 32-bit (4-byte) integer in little-endian format |
Long | A 64-bit (8-byte) integer in little-endian format |
String | A variable-length UTF-8 encoded string terminated by a null byte (0x00) |
Packet Formats
Header and Type (all packets)
The data portion of each packet begins with a 4-byte header followed by a byte which identifies the packet type.Therefore, each packet begins with the following two fields:
Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | <packet type> | Single byte which identifies the packet type |
Value | Packet type |
0x00 | Server identity string |
0x01 | Heartbeat |
0x02 | Connection request |
0x03 | Connection response (failure) |
0x04 | Connection response (success) |
0x05 | Chat message |
Content Length (most packets)
With the exception of heartbeats, all packets include a 2-byte short integer field which indicates the content length. This is the number of bytes remaining in the packet. Since many socket implementations handle TCP data as a continuous stream, it's often necessary to know how many bytes are remaining when attempting to read data from the socket. The value of this field must be positive, and no larger than 1024.Identity String
The identity string is the first thing the server sends to the client after a connection is initiated. Currently, this packet can be safely ignored by clients. The main purpose of the identity string is to identify the listener if someone were to telnet to its port, for example. After the identity string is sent to the client, the server expects to receive a valid connection request. If a packet is not received from the client within 2 seconds, or if the next packet is not a valid connection request, then the server will close the socket.The format of the identity packet is as follows:
Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | 0x00 | Single byte which identifies the packet type |
Content Length | Short | <content length> | The length (in bytes) of the remaining packet data |
Identity String | String | <identity string> | The Chat Relay identity string |
Connection Request
The connection request is a TCP packet sent from the client to the server. The format of the connection request is as follows:Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | 0x02 | Single byte which identifies the packet type |
Content Length | Short | <content length> | The length (in bytes) of the remaining packet data |
Password | String | P <password> | An uppercase P followed by a space and then the Chat Relay password |
Game server IP | String | <IP address> | The IP address of the game server from which this client wants to receive chat messages |
Game server Port | String | <port> | The port of the game server from which this client wants to receive messages |
- The password field must be present, even if no password is specified. If no password is specified, then the password field will just be an uppercase P followed by a space. The password in the packet is ignored if the server does not require a password for client connections.
- The game server IP can be either an IPv4 or IPv6 address. If this field does not contain a valid IPv4 or IPv6 address, the server will return an error and close the connection.
- The game server port field must be a valid port number in the range {1..65535}. If this field does not contain a valid port number, the server will return an error and close the connection
Sample packet data:
ff ff ff ff 02 19 00 50 20 61 62 63 64 31 32 33 .......P abcd123
34 00 31 2e 32 2e 33 2e 34 00 32 37 30 31 35 00 4.1.2.3.4.27015.
In the above example, the client is sending the following information to the server:
- Password: abcd1234
- Game server IP: 1.2.3.4
- Game server port: 27015
Connection Response
The connection response is a TCP packet sent from the server to the client. The format of the connection response is as follows:Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | 0x03 or 0x04 | Single byte which identifies the packet type |
Content Length | Short | <content length> | The length (in bytes) of the remaining packet data |
Response | String | <response string> | The connection request response from the server |
Error Message | Description |
Empty packet | The packet received by the server contained no data |
Invalid packet | The packet received by the server was not a valid connection request |
Invalid content length | The connection request contained an invalid content length value |
Bad password | The connection request contained an incorrect password |
Bad IP address | The connection request contained an invalid game server IP address |
Bad port number | The connection request contained an invalid game server port number |
Too many connections | The server has reached its limit for concurrent client connections |
- If auto-bans are enabled on the server, each of the first six errors in the table above will cause the client IP's "bad attempts" counter to be incremented, and may result in the client IP being banned.
- A connection which is rejected with a Too many connections error is not considered a bad connection attempt by the server.
- The server's limit for simultaneous client connections can be changed by setting the maxClients option in the Chat Relay properties file (see Using the Chat Relay). Adjusting the maxClients and/or clientCheckInterval options may reduce the chances of the client receiving a Too many connections error.
Sample packet data (successful connection):
ff ff ff ff 04 02 00 4f 4b 00 .......OK.
Sample packet data (bad password rejection):
ff ff ff ff 03 0e 00 45 20 42 61 64 20 70 61 73 .......E Bad pas
73 77 6f 72 64 00 sword.
Chat Message
Each chat message is sent in a TCP packet from the client to the server. The format of the chat message is as follows:Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | 0x05 | Single byte which identifies the packet type |
Content Length | Short | <content length> | The length (in bytes) of the remaining packet data |
Protocol Version | Byte | 0x01 | Identifies the protocol version (packet format) which this packet conforms to, currently there's only version 1. |
Server Timestamp | Int | <timestamp> | Timestamp added by the Chat Relay server in Unix epoch format |
say_team | Byte | 0x00 or 0x01 | 0x00 = not say_team, 0x01 = say_team |
From IP | String | <IP address> | The IP address of the game server from which this chat message originated |
From Port | String | <port> | The port of the game server from which this chat message originated |
Message Timestamp | String | <timestamp> | The timestamp from the chat message |
Player Name | String | <name> | Name of the player who sent the chat message |
Player Team | String | <team> | Team of the player who sent the chat message |
Message | String | <message> | Text of the chat message |
Sample packet data:
ff ff ff ff 05 4f 00 01 10 42 81 52 00 31 32 37 .....O...B.R.127
2e 30 2e 30 2e 31 00 32 33 34 35 00 20 31 31 2f .0.0.1.2345. 11/
31 31 2f 32 30 31 33 20 2d 20 31 35 3a 34 35 3a 11/2020 - 15:45:
30 30 00 53 6f 6d 65 50 6c 61 79 65 72 00 53 75 00.SomePlayer.Su
72 76 69 76 6f 72 00 54 68 69 73 20 69 73 20 61 rvivor.This is a
20 74 65 73 74 21 00 test!.
In the above example, the field values are as follows:
- Content Length: 79
- Protocol Version: 1
- Server Timestamp: 1384202768
- say_team: 0
- From IP: 127.0.0.1
- From Port: 2345
- Message Timestamp: 11/11/2020 - 15:45:00
- Player Name: SomePlayer
- Player Team: Survivor
- Message: This is a test!
Heartbeat
The heartbeat allows the server to know which clients are still connected. The format of the heartbeat is as follows:Field | Type | Value | Description |
Header | Int | 0xFFFFFFFF | 4-byte header for all packets |
Type | Byte | 0x01 | Single byte which identifies the packet type |
Note: This is the only packet type which does not include the content length field.
Sample packet data:
ff ff ff ff 01 .....
Control Packets
The CheckValve Chat Relay implements a control listener which accepts control requests from the Chat Relay Control program (chatrelayctl.jar) on the loopback address. Control requests can be used to start, stop, or get status information from the Chat Relay.All control packets use a common format:
Field | Type | Value | Description |
Header | Int | 0xFFFFFFFE | 4-byte header for all packets |
Protocol Version | Byte | 0x01 | Identifies the protocol version (packet format) which this packet conforms to, currently there's only version 1. |
Timestamp | Long | <timestamp> | Timestamp of this request in Unix epoch format (milliseconds) |
Request Type | Byte | <type> | A single byte which represents the type of control request |
Value | Request type |
0x06 | Status request |
0x07 | Status response |
0x08 | Shutdown request |
0x09 | Shutdown response |