I love the smell of UnrealEd crashing in the morning. – tarquin

Legacy:El Muerte/GQP

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

GQP stands for Gameserver Query Protocol (working title)

Purpose[edit]

This document serves as a working draft for a RFC to be written later.

At the moment, there's only one protocol that can be considered a standard: the GameSpy protocol. But this protocol is not well defined and has some design flaws.

Hopefully, game developers and server query programs (like qstat or ASE) will adopt this specification once it's complete.

Authors[edit]

If you are going to work on the design of this protocol, please add your name here for later reference.

  • Michiel Hendriks <elmuerte@drunksnipers.com>
  • Guillaume Cocatre-Zilgien, a.k.a. "skamp" - http://www.skamp.net/

Design features[edit]

  • the protocol should be as basic and serve as many purposes as possible, so it can be implemented in every game;
  • authentication, possibility to protect data (through encryption/encoding?);
  • easily extensible with new query commands;

...

Grammar[edit]

Client request

   QUERY           ::= ( ENCODED )? COMMAND ( GS COMMAND )* EOT
   ENCODED         ::= SOH STRING ACK
   COMMAND         ::= STRING ( RS ARGUMENT-LIST )? 
   ARGUMENT-LIST   ::= STRING ( US STRING )* 

Server response

   RESPONSE        ::= ( ENCODED )? COMMAND-REPLY ( GS COMMAND-REPLY )* EOT
   COMMAND-REPLY   ::= STATUS-CODE COMMAND-NAME RS DATA
   COMMAND-NAME    ::= STRING
   STATUS-CODE     ::= DIGIT DIGIT
   DATA            ::= ACK
                     | RECORD ( RS RECORD )*
   RECORD          ::= DC1 STRING                // a simple string
                     | DC2 STRING US STRING      // name = value
                     | DC3 STRING ( US STRING )* // array
                     | DC4 STRING ( US STRING )* // labeled array (first element is the label)
                                           
   SOH             ::= <SOH>
   EOT             ::= <EOT>
   GS              ::= <GS>
   RS              ::= <RS>
   US              ::= <US>
   STRING          ::= ( <printable> )*
   DIGIT           ::= '0' ... '9'
   ACK             ::= <ACK>
   DC1             ::= <DC1>
   DC2             ::= <DC2>
   DC3             ::= <DC3>
   DC4             ::= <DC4>

Server reponse data[edit]

The server respons data (the rules DATA and RECORD) can be one of the following format:

empty reply 
only an <ACK>
text 
just a single string as reply
 "single item"
name/value 
both a name and value
 "label" => "single item"
array 
an array of value
 Array ("item one", "item two", "item three")
labeled array 
an array with a label
 "label" => Array ("item one", "item two", "item three")
   

<DLE>, <EOT>, <ETB>, <GS>, <RS>, <US>, <ACK>, <SOH>, <STX> and <ETX> are ASCII control codes (the first 32 symbols in the ASCII table).

<printable> is every non-control code in the ASCII table.

Skamp: When needed, transmissions shall be split into blocks ending with <ETB>, <EOT> indicating overall completion.

El Muerte TDS: you don't need to split transmission into blocks, UDP is pretty much a constant stream of data so just start with reading until you get an <EOT>

Skamp: Mmm-kay.

Encoding[edit]

When a Query or Command starts with <SOH>, the data is encoded up to <EOT>.

The <SOH> control character is followed by a string containing encoding information terminated by <ACK>. The choice of encoding is up to the implementor.

Skamp: I believe that <DLE> is more suitable for type definition; besides, one might want to specify more than one kind of encoding: for instance, "bzip2" + "UTF-8"...

El Muerte TDS: the string is just a identification string, so if you want "bzip2" + "utf-8" you can just use "bzip2+utf-8" as string, or even "MySpecialEncoding". It really doesn't matter.

Skamp: I'm just affraid of implementations to use different syntaxes. One would use standard notations, and another one would use "zip/english" because it's just more convenient. You're right, it doesn't really matter, as long as we specify a standard - or use an existing - ASCII notation.

El Muerte TDS: we could say use a mime string, application/gzip for example, or application/x-gamespy ;)

Status Codes[edit]

Returned codes per command:

Code Meaning
10 OK The command returned succesfully
20 Unknown command
21 Unsupported feature The requested feature is not supported, can be returned in case of encoding or authentication
22 Incorrect number of arguments Command requires more or fewer arguments; in the latter case, this status code may be ignored
23 Invalid argument One ore more arguments aren't correctly formated
30 Disabled This command has been disabled by the admin
31 Temporarily unavailable This service or command is temporarily unavailable
32 Unauthorised Not authorised to use this command or invalid credentials
40 Unsupported encoding The used encoding isn't supported
41 Decode error An error occured while decoding

Required commands[edit]

The following commands should be supported by every implementation:

identify 
return game identification info
input: none
output: gamename = tag; gamever = version; netver = minimal net version
echo 
return the argument
input: any number of arguments
output: return each input argument
auth 
return challenge info to be used with the challenge command in order to access protected commands, or to be supplied with encoded data.
input: login; password;
output: challenge string
challenge 
validate the client after an authentication
input: challenge string
output: none
extensions 
return the list of accepted extensions to the protocol
input: none
output: list

...

Example queries[edit]

Note: in the following examples, data sent to or received from the server is not real, but has been adapted to a more readable format.

Query 
 "identify" <EOT>
Response 
 10 "identify" <RS> "gamename" <US> "ut" <RS> "gamever" <US> "432" <RS> "netver" <US> "432" <EOT>
Query 
 "unknown command" <EOT>
Response 
 20 "unknown command" <RS> <STX> "error: unknown command" <EOT> 

or

 20 <RS> <ACK> <EOT>
Query 
 "echo" <RS> "this text" <GS> "echo" <RS> "more text" <EOT>
Response 
 10 "echo" <RS> <STX> "this text" <GS> 
 10 "echo" <RS> <STX> "more text" <EOT>

A test page: http://unreal.elmuerte.com/GQP/

Reference[edit]

ASCII Table[edit]

Notation Meaning Hex. code Dec. code
<SOH> Start Of Header 01 1
<STX> Start of TeXt 02 2
<ETX> End of TeXt 03 3
<EOT> End Of Transmission 04 4
<ACK> Acknowledge 06 6
<DLE> Data Link Escape 10 16
<DC1> Device Control 1 11 17
<DC2> Device Control 2 12 18
<DC3> Device Control 3 13 19
<DC4> Device Control 4 14 20
<ETB> End of Transmission Block 23 17
<GS> Group Separator 1d 29
<RS> Record Separator 1e 30
<US> Unit Separator 1f 31

Sources:

Discussion[edit]

El Muerte TDS: Everything on this page is subject for changing, this my initial concept.

Skamp: Good start! I think that in the future, technical specifications won't be enough: we will also need implementation guidelines.

Skamp: I've made some spelling and phrasing corrections, I hope you don't mind.

Skamp: Added some suggestions; I'm going to bed now :-)


Skamp:

About TYPE:

The added TYPE would allow the specification of the item's type (hexadecimal, decimal, 16 bits or 32 bits integer, signed / unsigned, etc...). I think it is important to include such information; besides, as a single char it wouldn't take much space.

The default type would apply by default to every item in the list, if not specified otherwise on a case by case basis (specific type).

El Muerte TDS: I think it's best to simple use plain 8bit ASCII for everything. And if the data is transmitted in UNICODE you would just add <SOH> "UNICODE" <ACK> in front of your transmission. I want to prevent binary data as much as possible. (unless you use an encoding)

Skamp: I didn't realize that. You should specify it somewhere, although I'm not sure to agree with that. Binary mixes quite well with ASCII, while being very suitable for numbers, and lightweight. Type enforcement is a big concern to me, since existing implementations of the GameSpy protocol have shown to be very inconsistent. I believe we need a stricter protocol.

On another subject: your redefined RECORD is much simpler and clearer than mine, sometimes I probably should go to bed earlier :-) By the way, EBNF standard notation for comments encloses them in (* *); although it doesn't matter now that you used C-like notation, it will matter when writing the RFC.

El Muerte TDS: The problem with binary data is that it will introduce endian problems (sure it's a single line in the definition that everything is big endian), But i just want to make sure we don't have to deal with 0x00.

EBNF has a format for comments ?! Didn't know that.