PDA

View Full Version : rcon extension



maxdamage99
17th July 2020, 07:02
in addition to: https://killtube.org/showthread.php?3153-callback-RCON&highlight=rcon

Added function https://github.com/damage99/libcod/commit/484ef3e4d6dee6d397eb404900afbab450c04bbe:


out_printf()


Function allows the output to be redirected to the client like "rcon status", "rcon systeminfo" etc.
Works both for remote connections (rcon tool) and for players who use the console by connecting to the server.
Now you can create your own rcon commands or modify built-in commands for yourself.




codecallback_remoteCommand(from, command, pointerMsg)
{
commandArray = strtok(command, " ");
command = commandArray[2];
sfrom = strtok(from, ":");

ip = sfrom[0];
port = sfrom[1];

if (command == "rcon_password" || command == "killserver" || command == "quit")
return;

if (command == "online")
{
out_printf(from, "Online players: " + scr\_utils::getObjArray("classname", "player", "logged", true, undefined).size);
return;
}

if (command == "uptime")
{
out_printf(from, scr\_server::getUpTimeStr(false));
return;
}

doRcon(from, pointerMsg);
}


I also found a use to create in some way API.
I used this to create a server-status on my Discord server.


Use any tool to create a bot and its commands, I'll show you how it works using .PHP example


function serverStatus()
{
$S_IP = '127.0.1.0';
$S_PORT = "28960";
$SERVER_TOKEN = 'MuCN14jiSAKJTNV4UK7p'; //access token

$errno = $errstr = null;
$server_info = "udp://" . $S_IP;
$sendpacket = "\xff\xff\xff\xffrcon " . $SERVER_TOKEN . " getplayers";

@$connectpacket = fsockopen($server_info, $S_PORT, $errno, $errstr);
if(!$connectpacket)
echo 'serverStatus(): connect error!';

socket_set_timeout ($connectpacket, 1, 0);
fwrite ($connectpacket, $sendpacket);

$S_HOSTNAME = '';
$S_MAP = '';

$P_NAME = "";
$P_SCORE = "";
$P_PING = "";

$PLAYER_COUNT = 0;
while ($ret = fread ($connectpacket, 10000))
{
$ret = mb_strimwidth($ret, 4, strlen($ret));

if ($ret[1] != " ")
continue;

$a = $ret[0];
if ($a == "h")
$S_HOSTNAME = mb_strimwidth($ret, 2, strlen($ret));
elseif ($a == "m")
$S_MAP = mb_strimwidth($ret, 2, strlen($ret));
elseif ($a == "n" )
{
$P_NAME .= mb_strimwidth($ret, 2, strlen($ret)) . "\n";
$PLAYER_COUNT++;
}
elseif ($a == "s")
$P_SCORE .= mb_strimwidth($ret, 2, strlen($ret)) . "\n";
elseif ($a == "p")
$P_PING .= mb_strimwidth($ret, 2, strlen($ret)) . "\n";
else
echo 'serverStatus(): undefined control-symbol!';
}

fclose ($connectpacket);


/* construct your discord message */

/*

$S_HOSTNAME = 'CoD2Server';
$S_MAP = 'mp_toujane';
$P_NAME = 'Unknown Soldier\nPlayer#123\nUnnamedPlayer\nZombieBot\n';
$P_SCORE = '14\n0\n1\n13\n';
$P_PING = '109\n87\n43\n14\n';

*/
}


.gsc


G_Command(c, v)
{
return getSubStr(c, 0, v.size) == v;
}

codecallback_remoteCommand(from, command, pointerMsg)
{
commandArray = strtok(command, " ");
command = commandArray[2];
sfrom = strtok(from, ":");

ip = sfrom[0];
port = sfrom[1];

DiscordToken = "MuCN14jiSAKJTNV4UK7p";

if (commandArray[1] == DiscordToken && G_Command(command, "getplayers"))
{
thread Discord_GetPlayers(from);
return;
}

doRcon(from, pointerMsg);
}

Discord_GetPlayers(from)
{
out_printf(from, "h " + removeColors(getCvar("sv_hostname")));

mapCvar = getCvar("mapname");
map = scr\_map::getMapDescription(mapCvar);
if (!isDefined(map))
map = mapCvar;

out_printf(from, "m " + map);

players = getEntArray("player", "classname");
for (i = 0; i < players.size; i++)
{
player = players[i];
if (/* filter unlogged players, bots etc.*/)
continue;

out_printf(from, "n " + player.name);
out_printf(from, "s " + player.score);
out_printf(from, "p " + player getPing());
}
}


G_Command() - to filter some garbage, I don’t know, maybe this is a completely useless operation, but I noticed some strange behavior, so I just made insurance.
Access_Token can (should :)) differ from the rcon_password.
you can also make a system of several rcon_passwords (if you implement all the necessary functions in the .gsc) and give the admins a unique rcon_password - this will help to identify all actions with reference to their performer.

There are some problems with the transmission of some characters (special characters and Cyrillic).
you can always use only integer data for send, for example:
1. CoD2: transfer the indexes (id) of rows in the database.
and, after gets already in .PHP
2. select from DB where ID = ...


Code can be added and improved forever, specifically here I brought the most exemplary and understandable.
There can be a lot of ideas for use, the whole point is only in your imagination.
I wait to any comments, recommendations, advice on the implementation of out_printf() itself in libcod or its use in .gsc

Mitch
17th July 2020, 09:58
In your first example out_printf is missing a parameter.



out_printf(address, message);
out_printf("1.2.3.4:55555", "test");

maxdamage99
20th July 2020, 05:40
In your first example out_printf is missing a parameter.



out_printf(address, message);
out_printf("1.2.3.4:55555", "test");


Yes, thank you.
Fact is that I do not use the function directly, but through an alias and the value (from) is stored in an auxiliary global variable: level.redir_addr

apparently when I wrote the code for the example, I did not see this moment :D

igstyga
25th July 2020, 21:50
@maxdamage99 Can I get some pointers about porting this to CoD 1.1? "/rcon set command" is a freakin mess.

maxdamage99
10th August 2020, 11:00
@maxdamage99 Can I get some pointers about porting this to CoD 1.1? "/rcon set command" is a freakin mess.

i am not familiar with cod1, try this: https://github.com/riicchhaarrd/CoDExtended

It seems to me that the "catching" of rcon commands is already implemented there, you can ask the developer or try yourself add a callback for processing cmd_functions() in .gsc