Query Mechanism

From SA-MP Wiki

Jump to: navigation, search

Contents

Introduction

This is still a work in progress, sorry. Also, this article is useful for people who want to know how the query works, it isn't going to make one for you. For example implementations, see example implementations.

I was once confused with the SA-MP query mechanism, but now I'm not. What the SA-MP query mechnanism is, is a UDP based packet system where you can get information about servers - their players, the server's ping, and also the rules. The best thing about this is that the RCON packet can be used for what ever you want, it can even return messages, which is great. RCON can be the worst one to get working though, due to what is needed. But if your server/PC/phone/whatever has any method of communicating with a server. This guide works with all versions of SA-MP currently, from 0.1 through 0.3.

SA-MP Packets in the real world

Image:Sa-mp-packet-description.png

The packets were (in versions 0.2.X and below) also used ingame, just press 'TAB' when playing ingame - that notification is powered by the 'd' packet.

Opcodes

Limitations

There are quite a few limitations that are in the query protocol. There is a limit of thirty queries per second (this applies overall), but the most intrusive limit is the anti-flood measure that disables the player listings.

The packet table

Packet 'opcode' Description Compatibility with 0.3 releases
i This stands for information. This gets the amount of players in the server, the map name, and all the stuff like that. It's really useful for describing your server without changing anything. Although this opcode has supported two-byte player counts, there not has been any need for it before.
r This stands for rules. 'Rules' when it comes to SA:MP includes the instagib, the gravity, weather, the website URL, and so on. No changes needed.
c It stands for client list, this sends back to the server the players' name, and then the players' score. Just imagine it as a basic overview of all the players. Throttled to 100, but can theoretically support 65536 different IDs.
d This stands for detailed player information. With this, you can get everything from the ping to the player, the player ID (useful for admin scripts), the score again, and also the username. Throttled to 100 This does not support two-byte player IDs, thus will reset to zero if more than 256 players are reached. (This happened when 'd' was not throttled.)
x This is an RCON command, and it's completely different from all of the other packets. No changes needed.
p Four psuedo-random characters are sent to the server, and the same characters are returned. You can use the time between sending and receiving to work out the servers' ping/latency. No changes needed.

The backbone of packets

Byte ASCII Using PHP Hexadecimal Description
0-3 SAMP "SAMP" 53 41 4D 50 This denotes that this packet is indeed a SA-MP packet.
4 À chr('192'); C0 This is the first byte in the server's IP address - for instance, 'À' is the ASCII character of 192 - from 192.168.200.103.
5 ¨ chr('168'); A8 This is the second byte in the server's IP address - for instance, '¨' (umlaut) is the ASCII character of 168 - from 192.168.200.103.
6 È chr('200'); C8 This is the third byte in the server's IP address - for instance, 'È' is the ASCII character of 200 - from 192.168.200.103.
7 g chr('103'); 67 This is the third byte in the server's IP address - for instance, 'g' is the ASCII character of 103 - from 192.168.200.103.
8 a chr('7777' & 0xFF); 61 First byte of the port.
9 chr('7777' >> 8 & 0xFF); 1E Second byte of the port.
10 i "i" 69 The opcode that you would like to query. Look above for the opcodes.

Real world usage

If this is confusing you, then no more dispair. If you understand a programming language such as PHP, then the packet that you will need to send would end up something like this.

/**
 *    Let's generate the string needed for the packet.
 */
$sIPAddr = "127.0.0.1";                                                         // IP address of the server
$iPort = 7777;                                                                  // Server port.
$sPacket = "";                                                                  // Blank string for packet.
 
$aIPAddr = explode('.', $sIPAddr);                                              // Exploding the IP addr.
 
$sPacket .= "SAMP";                                                             // Telling the server it is a SA-MP packet.
 
$sPacket .= chr($aIPAddr[0]);                                                   //
$sPacket .= chr($aIPAddr[1]);                                                   //
$sPacket .= chr($aIPAddr[2]);                                                   //
$sPacket .= chr($aIPAddr[3]);                                                   // Sending off the server IP, 
 
$sPacket .= chr($iPort & 0xFF);                                                 //
$sPacket .= chr($iPort >> 8 & 0xFF);                                            // Sending off the server port.
 
$sPacket .= 'i';                                                                // The opcode that you want to send.
                                                                                // You can now send this to the server.
 
/**
 *    Let's connect now to the server.
 */
$rSocket = fsockopen('udp://'.$sIPAddr, $iPort, $iError, $sError, 2);           // Create an active socket.
fwrite($rSocket, $sPacket);                                                     // Send the packet to the server.
 
echo fread($rSocket, 2048);							// Get the output from the server
 
fclose($rSocket);                                                               // Close the connection

RCON Packets

This table is using as the example RCON password changeme, and using varlist as a command, thus meaning that the packet offset will be porportional to that of those strings. Please note that due to the changes in the length of the RCON password and the RCON command, the bytes will be different from 13 onwards. The opcode used is 'x'.

Byte ASCII Using PHP Hexadecimal Description
11 chr(strlen("changeme") & 0xFF); 38 First byte of the length of the RCON password.
12 chr(strlen("changeme") >> 8 & 0xFF); 30 Second byte of the length of the RCON password.
13-20 changeme "changeme" 63 68 61 6e 67 65 6d 65 The RCON password.
21 chr(strlen("varlist") & 0xFF); 37 First byte of the length of the RCON command.
22 chr(strlen("varlist") >> 8 & 0xFF); 30 Second byte of the length of the RCON command.
23+ varlist "varlist" 76 61 72 6c 69 73 74 The actual RCON command.

Recieving the packets

When you recieve a packet, there are 11 bytes of a packet you can remove right away. These eleven bytes are what we call the header. These eleven bytes equals your query that you have sent.

Response from i

Byte Key Byte width Description
11 Password 1 Either 0 or 1, depending whether if the password has been set.
12-13 Players 2 Current amount of players online on the server.
14-15 MaxPlayers 2 Maximum amount of players that can join the server.
15-18 (strlen) 4 Length of the server hostname.
19 + strlen Hostname (strlen) Hostname of the server.
20-23 (strlen) 4 Length of the server's gamemode.
24 + strlen Gamemode (strlen) Gamemode of the server.
25-28 (strlen) 4 Length of the server's language.
29 + strlen Language (strlen) Language of the server.

Response from r

Byte Key Byte width Description
11-12 RuleCount 2 Amount of rules that the server provides.
Repeat below the amount of RuleCount, to get all the rules and values.
13 (strlen) 1 Length of the rulename.
14 + strlen Rulename (strlen) The rulename.
15 (strlen) 1 Length of the value.
16 + strlen RuleCount (strlen) That rulename's value.

Response from c

Byte Key Byte width Description
11-12 PlayerCount 2 Amount of rules that the server provides.
Repeat below the amount of PlayerCount, to get all the rules and values.
13 (strlen) 1 Length of the player's moniker.
14 + strlen PlayerNick (strlen) Player's nickname
15 Score 4 Player's score

Response from d

Byte Key Byte width Description
11-12 PlayerCount 2 Amount of rules that the server provides.
Repeat below the amount of PlayerCount, to get all the rules and values.
13 PlayerID 1 Player's ID (only 0-255 possible)
14 (strlen) 1 Length of the player's moniker.
15 + strlen PlayerNick (strlen) Player's nickname
16-19 Score 4 Player's score
20-23 Ping 4 Player's ping to the server

Response from p

Byte Key Byte width Description
11 number 1 1 The first number of the pseudo-random numbers the client sends
12 number 2 1 The second number of the pseudo-random numbers the client sends
13 number 3 1 The third number of the pseudo-random numbers the client sends
14 number 4 1 The fourth number of the pseudo-randoms number the client sends

Example Implementations

Here are a few implementations of how to send and recieve packets to and from SA-MP servers (v 0.3):

C#

Example class

C++

See here.

PHP

See here.

Personal tools