Skip to content

Instantly share code, notes, and snippets.

@leobrines
Created June 14, 2019 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leobrines/be0b5cee1b478dc30e76242c860aa582 to your computer and use it in GitHub Desktop.
Save leobrines/be0b5cee1b478dc30e76242c860aa582 to your computer and use it in GitHub Desktop.
AMXX CS 1.6 Include - This enable to query a server for it's information like hostname, map or players count with sockets
#include <amxmodx>
#include <sockets>
#define MAX_INFO_LEN 1400
#define MAX_INFO_FORMAT 100
// A2S_INFO definitions for source according to http://developer.valvesoftware.com/wiki/Server_Queries#Source_servers_2
#define A2S_INFO "^xFF^xFF^xFF^xFF^x54Source Engine Query^x00"
#define A2S_INFO_LEN 25
#define A2S_INFO_SOURCE_REPLY_FORMAT "411ssss21111111s" // there are some extra flags after this but we don't care
enum {
A2S_INFO_SOURCE_IDX_HEADER=0, // Should be FF FF FF FF
A2S_INFO_SOURCE_IDX_TYPE, // Should be equal to 'I' (0x49)
A2S_INFO_SOURCE_IDX_VERSION, // Network version. 0x07 is the current Steam version.
A2S_INFO_SOURCE_IDX_SERVERNAME, // The Source server's name
A2S_INFO_SOURCE_IDX_MAP, // The current map being played "
A2S_INFO_SOURCE_IDX_GAMEDIR, // Game files folder, eg: "cstrike"
A2S_INFO_SOURCE_IDX_GAMEDESC, // Game type, eg: "Counter-Strike"
A2S_INFO_SOURCE_IDX_APPID, // Steam Application ID, see http://developer.valvesoftware.com/wiki/Steam_Application_IDs
A2S_INFO_SOURCE_IDX_NUMPLAYERS, // Currently players on the server
A2S_INFO_SOURCE_IDX_MAXPLAYERS, // Max players for the server
A2S_INFO_SOURCE_IDX_NUMBOTS, // Number of bot players on the server
A2S_INFO_SOURCE_IDX_DEDICATED, // 'l' listen, 'd' dedicated, 'p' SourceTV
A2S_INFO_SOURCE_IDX_OS, // Host OS. 'l' for Linux, 'w' for Windows
A2S_INFO_SOURCE_IDX_PASSWORD, // If set to 0x01, a password is required to join this server
A2S_INFO_SOURCE_IDX_SECURE, // if set to 0x01, this server is VAC secured
A2S_INFO_SOURCE_IDX_GAMEVERSION // The version of the game, eg: "1.0.0.22"
}
#define QUERY_TIMEOUT 0.1
#define TASK_SOCKET 145
static socket_id;
// Dinamic Array to fix
static functions[100][32];
static funcid = 0;
enum {
SOCKET=0,
INFO,
ID,
FUNC
}
stock socket_info_servername (host[], port, const cb[])
socket_info_request(host, port, cb, A2S_INFO_SOURCE_IDX_SERVERNAME);
stock socket_info_map (host[], port, const cb[])
socket_info_request(host, port, cb, A2S_INFO_SOURCE_IDX_MAP);
stock socket_info_numplayers (host[], port, const cb[])
socket_info_request(host, port, cb, A2S_INFO_SOURCE_IDX_NUMPLAYERS);
stock socket_info_maxplayers (host[], port, const cb[])
socket_info_request(host, port, cb, A2S_INFO_SOURCE_IDX_MAXPLAYERS);
static socket_info_request (host[], port, const cb[], info) {
static args[4];
args[SOCKET] = socket_create(host, port);
args[INFO] = info;
args[ID] = TASK_SOCKET + socket_id;
formatex(functions[funcid], charsmax(functions[]), "%s", cb);
args[FUNC] = funcid;
if (funcid == charsmax(functions))
funcid = 0;
else
funcid++;
socket_send2(args[SOCKET], A2S_INFO, A2S_INFO_LEN);
set_task(QUERY_TIMEOUT, "socket_check", args[ID], args, sizeof(args), "b");
}
static socket_create (host[], port) {
static socket, error;
socket = socket_open(host, port, SOCKET_UDP, error);
socket_id++;
if(socket < 0 || error)
return 0;
return socket;
}
public socket_check (args[]) {
static socket, info, id;
static data[MAX_INFO_LEN], len, indexes[MAX_INFO_FORMAT];
socket = args[SOCKET];
info = args[INFO];
id = args[ID];
if (!socket_change(socket, 100))
return;
remove_task(id);
len = socket_recv(socket, data, charsmax(data));
index_create(data, len, A2S_INFO_SOURCE_REPLY_FORMAT, indexes);
new strval[32], numval;
numval = -1;
switch (info) {
case A2S_INFO_SOURCE_IDX_SERVERNAME:
copyc(strval, charsmax(strval), data[indexes[info]], 0);
case A2S_INFO_SOURCE_IDX_MAP:
copyc(strval, charsmax(strval), data[indexes[info]], 0);
case A2S_INFO_SOURCE_IDX_NUMPLAYERS:
numval = index_get_byte(data, indexes[info]);
case A2S_INFO_SOURCE_IDX_MAXPLAYERS:
numval = index_get_byte(data, indexes[info]);
}
new func[32];
format(func, charsmax(func), "%s", functions[args[FUNC]]);
server_print("Getting Function: %s Index: %i", func, args[FUNC]);
if (numval != -1)
set_task(0.1, func, numval, _, _, "a", 1);
else if (!equali(strval, ""))
set_task(0.1, func, _, strval, sizeof(strval), "a", 1);
socket_close(socket);
}
stock index_get_byte (data[MAX_INFO_LEN], index)
return data[index];
stock index_create(data[MAX_INFO_LEN], len, formatStr[100], indexes[MAX_INFO_FORMAT]) {
new nFormatPos = 0 // current position within the format array
new nIndexPos = 0 // current position within the data array
new nDataIndex = 0 // current chracter index within the data stream
new nFormatPosMax = strlen(formatStr)
while ((nIndexPos < nFormatPosMax) && (nDataIndex <= len)) {
switch (formatStr[nFormatPos]) {
case '1': { // "byte"
indexes[nIndexPos] = nDataIndex
nDataIndex++
nIndexPos++
}
case '2': { // "short"
indexes[nIndexPos] = nDataIndex
nDataIndex += 2
nIndexPos++
}
case '4': { // "long"
indexes[nIndexPos] = nDataIndex
nDataIndex += 4
nIndexPos++
}
case 's': { // string
indexes[nIndexPos] = nDataIndex
do { nDataIndex++; }
while ((data[nDataIndex] != 0) && (nDataIndex < len)) // find the end of the string by searching a 0 character
nDataIndex++
nIndexPos++
}
case '[': { // byte switch and start of optional formats
if (data[nDataIndex] != 1) { // skip options
do { nFormatPos++; }
while ((formatStr[nFormatPos] != ']') && (nFormatPos < nFormatPosMax))
} else {
nDataIndex++
nIndexPos++
}
}
case ']': { // end of optional formats
nDataIndex++
}
default: {
nDataIndex++
}
}
nFormatPos++
}
return nIndexPos;
}
#include <amxmodx>
#include <sockets_svq>
#define PLUGIN "Server Query Example"
#define VERSION "1.0"
#define AUTHOR "Leopoldo Brines"
new ip[] = "XXX.XXX.XXX.XXX";
new port = 27015;
public plugin_init () {
register_plugin(PLUGIN, VERSION, AUTHOR);
register_concmd(".map", "cmd_map", ADMIN_ALL);
register_concmd(".maxplayers", "cmd_maxplayers", ADMIN_ALL);
register_concmd(".numplayers", "cmd_numplayers", ADMIN_ALL);
register_concmd(".servername", "cmd_servername", ADMIN_ALL);
}
public cmd_map ()
socket_info_map(ip, port, "cb_map");
public cb_map (map[])
client_print(0, print_chat, "map: %s", map);
public cmd_maxplayers ()
socket_info_maxplayers(ip, port, "cb_maxplayers");
public cb_maxplayers (num)
client_print(0, print_chat, "maxplayers: %i", num);
public cmd_numplayers ()
socket_info_numplayers(ip, port, "cb_numplayers");
public cb_numplayers (num)
client_print(0, print_chat, "numplayers: %i", num);
public cmd_servername ()
socket_info_servername(ip, port, "cb_servername");
public cb_servername (name[])
client_print(0, print_chat, "servername: %s", name);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment