16 KiB
Xash3D 49 connectionless protocol
Connectionless protocol defines four common message sources and destinations, they can be:
Sfor ServerCfor ClientMfor MasterAfor Anything else
All connectionless packets have \xff\xff\xff\xff (32-bit integer set to all ones) in it's header. Let's go through each of possible direction in this document.
- Any
- Master and game server
- Client and game server
Any
Any to Any
A2A_PING and A2A_GOLDSRC_PING
Simple ping message.
- Request, in ASCII:
pingoriin GoldSrc format - Response is always
A2A_ACKorA2A_GOLDSRC_ACK
A2A_ACK and A2A_GOLDSRC_ACK
Simple ack message.
- Request, in ASCII:
ackorjin GoldSrc format - Response: none
Deprecated queries
These text-based Xash protocol queries are deprecated in favor of GoldSrc server queries, which Xash3D FWGS servers implement as well. New implementations must not send them. The server still responds to A2A_INFO for compatibility with older clients, A2A_NETINFO is not handled anymore.
A2A_NETINFO
Used to implement Half-Life's NetAPI.
-
Request message, in ASCII:
netinfo <version> <context> <request_id>versionmust be 49, as text.contextcan be any 32-bit signed integer value, encoded as text.request_idseecommon/net_api.h
-
Response message, in ASCII:
netinfo <context> <request_id> <response>contextsame as in request.request_idsame as in request.responseis server's response, depending on request type. Always encoded as Quake info string.
Possible requests and response formats:
- Request ID
1will make server respond with empty response string. - Request ID
2makes server respond with all server game rule cvars where the key is cvar name and the value is cvar value. One additional keyruleswith total amount of cvars is added. - Request ID
3makes server respond with players list, where:p<id>nameis set to player's namep<id>fragsis set to player's kill countp<id>timeis set to player's total play timeplayersis total player's list.- Alternatively, it can respond with
neterrorset toforbiddenif server does not wish to expose it's player list.
- Request ID
4makes server to respond with common game details:hostnameis server's namegamediris game directory namecurrentis total player countmaxis max players limitmapis server's current level
- On any other server will respond with
neterrorset toundefined - If protocol version doesn't match, server responds with
neterrorset toprotocol
A2A_INFO
Used to request server's details.
-
Request message, in ASCII:
info <version>versionmust be 49, as text
-
Response message, in ASCII:
info\n<response>responseis Quake info string, otherwise it's an error message.
-
Response info string format:
pis set to protocol version (FWGS extension)mapis server's current leveldmset to 1 if current game mode is deathmatch otherwise 0teamset to 1 if current game mode includes teamplay otherwise 0coopset to 1 if current game mode is cooperative otherwise 0numclis total player countmaxclis max players limitgamediris game directory namepasswordset to 1 if server is protected with password otherwise 0hostis server's name
Any to Client
A2C_PRINT and A2C_GOLDSRC_PRINT
Simple print message.
- Header:
\xff\xff\xff\xff - Request, in ASCII:
print <message>orl<message>in GoldSrc format. - Response: none
Any to Server and Server to Any
GoldSrc server queries
These match Source Engine Query messages used in GoldSrc and Source engine and implemented for compatibility with existing server browsers and monitoring tools. The client uses them to query GoldSrc servers in the server browser, and as text-based Xash protocol queries are deprecated, it will use them to query Xash servers as well. Read documentation for them on VDC: https://developer.valvesoftware.com/wiki/Server_queries
Unlike other connectionless messages these are binary: integers are little-endian, floats are 32-bit IEEE 754 and strings are null-terminated.
A2S_GOLDSRC_PLAYERS and A2S_GOLDSRC_RULES requests carry a 32-bit challenge, A2S_GOLDSRC_INFO may have one appended after the query string. When no challenge is known yet, \xff\xff\xff\xff is sent in it's place. The server may answer with a challenge instead of the data: byte A (0x41) followed by a 32-bit challenge value, 9 bytes total with the header. The request is then repeated with the received challenge. Don't confuse this message with textual S2C_GOLDSRC_CHALLENGE used during connection, they only share the first byte. Xash servers respond to queries immediately and never send query challenges, GoldSrc servers require them since the 2020 update.
Responses that don't fit into a single packet (usually rules) come from GoldSrc servers split into fragments. Such packets start with \xfe\xff\xff\xff instead of \xff\xff\xff\xff, followed by a 32-bit sequence number, same in all fragments of one response, and a byte with total fragment count in the lower 4 bits and this fragment's index in the upper 4 bits. Fragment payloads concatenated in index order form a normal \xff\xff\xff\xff message. Xash servers never split query responses and send them as single datagrams.
A2S_GOLDSRC_INFO
Used to request server's details.
- Request:
TSource Engine Query\0, optionally followed by a 32-bit challenge. Xash servers ignore it. - Response: byte
I(S2A_GOLDSRC_INFO), followed by:- byte: protocol version, 48 on GoldSrc, 49 on Xash3D FWGS
- string: server's name
- string: server's current level
- string: game directory name
- string: game description
- int16: Steam AppID, always 0 on Xash servers
- byte: total player count, bots included
- byte: max players limit
- byte: bot count
- byte: server type,
dfor dedicated orlfor listen server - byte: server's operating system,
wfor Windows,lfor Linux,mfor macOS - byte: set to 1 if server is protected with password otherwise 0
- byte: set to 1 if server is VAC secured, Xash servers put the
securevalue from gameinfo here - string: server's version
Same as the Source engine response format but without the extra data flag and its fields.
Legacy GoldSrc servers respond with the obsolete m format (S2A_GOLDSRC_LEGACY_INFO) instead, see VDC for its layout. Xash servers never send it but the client understands it and assumes protocol 48.
A2S_GOLDSRC_PLAYERS
Used to request server's player list.
- Request: byte
U(0x55), then a 32-bit challenge. - Response: byte
D(S2A_GOLDSRC_PLAYERS), followed by a byte with total player count, then for each player:- byte: player's index. Xash servers send sequential indexes starting from 0, GoldSrc servers always send 0 here.
- string: player's name
- int32: player's kill count
- float: time in seconds the player is connected, -1.0 for bots on Xash servers
Xash server doesn't respond at all if the player list is empty, the server is protected with password or exposing the player list is disabled with sv_expose_player_list cvar.
A2S_GOLDSRC_RULES
Used to request server's game rules.
- Request: byte
V(0x56), then a 32-bit challenge. - Response: byte
E(S2A_GOLDSRC_RULES), followed by an int16 with total rule count, then rule name and rule value strings for each.
Only server cvars (FCVAR_SERVER) are sent. Values of protected cvars (FCVAR_PROTECTED) are replaced with 1 if the value is set otherwise 0. If there are no cvars to expose, server doesn't respond at all.
Any to Master
S2M_SCAN_REQUEST
- Request:
1<region><IP:Port>\0<info>- Format of this message is loosely based on https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol
infohowever adds few additional fields:clverset to engine's versionnatset to 1 to filter only servers behind NAT and tell master to notify servers about scancommitset to engine's build commit hashbranchset to engine's build branchosset to which operating system engine has been builtarchset to which CPU architecture engine has been builtbuildnumset to engine's build numberkeyset to random 32-bit value formatted as hex, used to validate master responses
- Response:
M2A_SERVERSLIST
Master to Any
M2A_SERVERSLIST
- Request:
f\xff<key><reserved><IP:Port>...keyis random 32-bit value set inS2M_SCAN_REQUESTreservedis single reserved 8-bit byte- Following is list of IP addresses in binary form: 6-bytes for IPv4 address + port and 18-bytes for IPv6 address + port
- If port is 0, it means the end of list, otherwise it's the last IP used for pagination (not implemented in Xash3D)
- Response: client doesn't make response to master server but might request
A2S_GOLDSRC_INFOfrom servers
Master and game server
Server to Master
S2M_HEARTBEAT
Used to update game server information on the master server.
- Request:
q\xff<heartbeat challenge>heartbeat challengeis random 32-bit value, used to prevent faked/forged source IP addresses.
- Response:
M2S_CHALLENGE
S2M_SHUTDOWN
Used to notify master server about server shutdown, but due to security reasons must be ignored by any master implementation.
- Request:
\x62\x0a - Response: none
S2M_INFO
Game server info response on M2S_CHALLENGE.
- Request:
0\n<info>infois Quake info string containing server information passed to master server. It contains following fields:protocolis always 49challengeis master challengeplayersis total player count, without botsmaxis max players limitsbotsis total bot countgamediris set to game directorymapis server's current leveltypeset todfor dedicated orlfor listen serverpasswordset to1if server protected with password set otherwise0osalwayswsecurealways0lanalways0versionengine versionregionalways255productsame asgamedirnatset to1if server is behind NAT
- Response: none
Master to Server
M2S_CHALLENGE
Master's respoonse on game server's heartbeat message.
- Request:
s<master challenge><heartbeat challenge>master challengecontains 32-bit value, used in server response to prevent faked/forged source IP addresses.heartbat challengecotnains 32-bit value, used in heartbeat request to prevent faked/forged source IP addresses.
- Response:
S2M_INFO.
M2S_NAT_CONNECT
Master server's message with client IP address and port, used in NAT punching.
- Request:
c <IP:Port> - Response:
S2C_INFOto a specified client address.
Client and game server
Client to Server
C2S_BANDWIDTHTEST
Used to figure out network MTU. The message is optional and server might choose to not implement it or respond with challenge.
-
Request, in ASCII:
bandwidth <version> <max_size>versionmust be 49, as text.max_sizeis requested maximum packet size.
-
Possible responses:
S2C_BANDWIDTHTESTS2C_CHALLENGEA2A_PRINTfollowed byS2C_REJECTS2C_ERRORMSG(as FWGS extension) followed byA2A_PRINTandS2C_REJECT.
C2S_GETCHALLENGE
Used to validate client's address to prevent faked/forged source IP addresses.
-
Header:
\xff\xff\xff\xff -
Request, in ASCII:
getchallenge steamsteamargument is optional and can be ignored by the server, as it's only kept for compatibility with similar GoldSrc 48 message.
-
Possible responses:
S2C_CHALLENGE
C2S_CONNECT
Used to build a connection with the server.
- Header:
\xff\xff\xff\xff - Request, in ASCII:
connect <version> <challenge> "<protinfo>" "<userinfo>"versionmust be 49, as text.challengemust be challenge value, as text.protinfois a Quake info string, containing protocol extensions and other connection information.uuidis this client's unique ID (FWGS extension) hasheed with MD5.qportis random integer value from 1 to 65535, unique for this engine run.extis an integer value OR'ed with requested protocol extensions. Currently only extension isNET_EXT_SPLITSIZEwith the value of1, which tells server to split messages based oncl_dlmaxvalue fromuserinfo.
userinfocontains initial user info, encoded as Quake info string.
- Possible responses:
A2A_PRINTfollowed byS2C_REJECTS2C_ERRORMSG(as FWGS extension) followed byA2A_PRINTandS2C_REJECT.S2C_CONNECTION
Server to Client
S2C_BANDWIDTHTEST
- Request:
testpacket<crc><blob>crcis 32-bit CRC ofblobblobrandom data
- There is no required response to this message
Total message size doesn't exceed request max size.
S2C_CHALLENGE
- Request, in ASCII:
challenge <value>valueis challenge value that client must include in it's response
- Response:
C2S_CONNECT
S2C_CONNECTION
- Request, in ASCII:
client_connect <protinfo>protinfois an optional Quake info string, contains following optional fields:extis an integer value OR'ed with allowed protocol extension. Bit fields match requested inextfield inC2S_CONNECTcheatsset to 1 if server allows cheats otherwise 0
- Response: there is no out of band from the client but client will proceed to building netchan and switch client-server interaction to it.
S2C_ERRORMSG
Show client error message. Doesn't mean connection reject, only used for UI.
- Request, in ASCII:
errormsg <message>messagecontains error message
- Response: none
S2C_REJECT
Client has been rejected in connection.
- Request, in ASCII:
disconnect - Response: client can cope, get depressed or mentally tell server to fuck off.