Difference between revisions of "Query"

From wiki.vg
Jump to navigation Jump to search
(→‎Example implementations: Dinnerbone wrote an implementation!)
 
(mention the Server List Ping packet as an alternative to the query protocol)
Line 1: Line 1:
 
Query is a UDP protocol introduced in 1.9pre4 for the purpose of querying server properties. It looks a lot like the UT3 (or GameSpot) Query Protocol [http://wiki.unrealadmin.org/UT3_query_protocol]
 
Query is a UDP protocol introduced in 1.9pre4 for the purpose of querying server properties. It looks a lot like the UT3 (or GameSpot) Query Protocol [http://wiki.unrealadmin.org/UT3_query_protocol]
 +
 +
A slightly simpler alternative to the query protocol involves connecting to the main minecraft TCP port and sending a [[Protocol#Server_List_Ping_.280xFE.29|Server List Ping]] packet, which returns motd, number of users and number of slots. More details on the [[Protocol#Server_List_Ping_.280xFE.29|main protocol page]].
  
 
All data types are big-endian, with the exception of <code>short</code>
 
All data types are big-endian, with the exception of <code>short</code>

Revision as of 06:50, 13 June 2012

Query is a UDP protocol introduced in 1.9pre4 for the purpose of querying server properties. It looks a lot like the UT3 (or GameSpot) Query Protocol [1]

A slightly simpler alternative to the query protocol involves connecting to the main minecraft TCP port and sending a Server List Ping packet, which returns motd, number of users and number of slots. More details on the main protocol page.

All data types are big-endian, with the exception of short

Server Config

   enable-query=true
   #query.port=25565

Client to Server Packet Format

Field name Field Type Notes
Magic byte, byte Always 0xFE 0xFD
Type byte 9 to handshake, 0 to stat
Session ID int32
Payload Varies See below

Server to Client Packet Format

Field name Field Type Notes
Type byte 9 for handshake, 0 for stat
Session ID int32
Payload Varies See below

Operations

Handshake

First, generate a session ID. It can be whatever you want.

Request

Send a request with an empty payload.

 FE FD 09 00 00 00 01

Response

The response payload will be a session token (note: different to a session id) encoded as a null-terminated string. You should convert it to an int32 and store it.

 09 00 00 00 01 39 35 31 33 33 30 37 00 | .....9513307.         

Basic stat

Request

Your payload should be your session token, packed as an int32.

 FE FD 00 00 00 00 01 00 3A 0D 5F

Response

Five null-terminated strings make up the beginning of the payload. They correspond to (motd, gametype, map, numplayers, maxplayers)

After these strings, a 2-byte, big-endian short, giving the hostport

At the end is a final null-terminated string, giving the hostname

 00 00 00 00 01 41 20 4D 69 6E 65 63 72 61 66 74 | .....A Minecraft
 20 53 65 72 76 65 72 00 53 4D 50 00 77 6F 72 6C |  Server.SMP.worl
 64 00 32 00 32 30 00 DD 63 31 32 37 2E 30 2E 30 | d.2.20.##127.0.0
 2E 31 00                                        | .1.

Full stat

Request

The request is the same as in a basic stat, except the payload must be padded to 8 bytes. Sending 0x00 0x00 0x00 0x00 at the end works.

 FE FD 00 00 00 00 01 00 3A 0D 5F 00 00 00 00

Response

You should ignore the first 11 bytes of the payload - they're garbage

The response is in two parts. You should split the response around the token \x00\x01player_\x00\x00

The first part is a list of null-terminated strings, representing (key1, value1, key2, value2 ...)

The second part is another list of null-terminated strings, each representing a player.

At the very end there's an extra null byte.

 00 00 00 00 01 73 70 6C 69 74 6E 75 6D 00 80 00 | .....splitnum...
 68 6F 73 74 6E 61 6D 65 00 41 20 4D 69 6E 65 63 | hostname.A minec
 72 61 66 74 20 53 65 72 76 65 72 00 67 61 6D 65 | raft Server.game
 74 79 70 65 00 53 4D 50 00 67 61 6D 65 5F 69 64 | type.SMP.game_id
 00 4D 49 4E 45 43 52 41 46 54 00 76 65 72 73 69 | .MINECRAFT.versi
 6F 6E 00 42 65 74 61 20 31 2E 39 20 50 72 65 72 | on.Beta 1.9 Prer
 65 6C 65 61 73 65 20 34 00 70 6C 75 67 69 6E 73 | elease 4.plugins
 00 00 6D 61 70 00 77 6F 72 6C 64 00 6E 75 6D 70 | ..map.world.nump
 6C 61 79 65 72 73 00 32 00 6D 61 78 70 6C 61 79 | layers.2.maxplay
 65 72 73 00 32 30 00 68 6F 73 74 70 6F 72 74 00 | ers.20.hostport.
 32 35 35 36 35 00 68 6F 73 74 6E 61 6D 65 00 31 | 25565.hostname.1
 32 37 2E 30 2E 30 2E 31 00 00 01 70 6C 61 79 65 | 27.0.0.1...playe
 72 5F 00 00 62 61 72 6E 65 79 67 61 6C 65 00 56 | r_..barneygale.V
 69 76 61 6C 61 68 65 6C 76 69 67 00 00          | ivalahelvig..

Payload format for V1.0

Same as above described somewhat differently.

Field Name Field Type Notes
(splitnum) string Always splitnum
(key_val_start) short/uint_16 Allways 0x80 After this there will be a number of key+value pairs
key string Keyname for the following value. Is repeated
value string A value that goes with the previous key. Is repeated
(key_val_end) short/uint_16 Allways 0x100 When you reach this there is no more key+value pairs
player_ string Allways player_ Star of a list of null terminated strings with online players
N/A byte Allways 0x00
playername string Repeat until you get a empty string

The keys that I have found querying a 1.0 server are...

Name Example Description
hostname 'A Minecraft Server' MOTD for the current server
gametype 'SMP' hardcoded to SMP
game_id 'MINECRAFT' hardcoded to MINECRAFT
version '1.0.0' Server version
plugins ' ' List of plugins, not yet used
map 'world' Name of the current map
numplayers '1' Number of online players. The string could be parsed to a number.
maxplayers '20' Max number of players on the server. The string could be parsed to a number
hostport '25565' Server port. The string could be parsed to a number
hostip '127.0.0.1' The IP the server is listening / was contacted on

Example implementations