SRCDS Steam group


Query a server with PHP
#1
I will provide 2 php functions which you can use to query a server and then format the query results. This is only for the AS2_INFO query. It returns the server's hostname, map, game, and gamemode.

The query function: (note: It returns the data urlencode()-ed, so that it is easier to work with the strange characters returned by the query.)
PHP Code:
/* SOURCE ENGINE QUERY FUNCTION, requires the server ip:port */
function source_query($ip)
{
$cut explode(":"$ip);
$HL2_address $cut[0];
$HL2_port $cut[1];

$HL2_command "\377\377\377\377TSource Engine Query\0";
$HL2_socket fsockopen("udp://".$HL2_address$HL2_port$errno$errstr,3);
fwrite($HL2_socket$HL2_command); $JunkHead fread($HL2_socket,4);
$CheckStatus socket_get_status($HL2_socket);

if(
$CheckStatus["unread_bytes"] == 0)
{
    return 
0;
}

$do 1;
while(
$do)
{
    
$str fread($HL2_socket,1);
    
$HL2_stats.= $str;
    
$status socket_get_status($HL2_socket);
    if(
$status["unread_bytes"] == 0)
    {
        
$do 0;
    }
}
fclose($HL2_socket);

$x 0;
while (
$x <= strlen($HL2_stats))
{
    
$x++;
    
$result.= substr($HL2_stats$x1);    
}
$result urlencode($result); // the output
return $result;



And now for the function that formats the query results: (note: it assumes the exact output of the above query function. The query info is returned into an array with the keys: hostname, map, game, gamemode )
PHP Code:
/* FORMAT SOURCE ENGINE QUERY (assumes the query's results were urlencode()'ed!) */
function format_source_query($string)
{
$string str_replace('%07','',$string);
$string str_replace("%00","|||",$string);
$sinfo urldecode($string);
$sinfo explode('|||',$sinfo);
$info['hostname'] = $sinfo[0];
$info['map'] = $sinfo[1];
$info['game'] = $sinfo[2];
if (
$info['game'] == 'garrysmod') { $info['game'] = "Garry's Mod"; }
elseif (
$info['game'] == 'cstrike') { $info['game'] = "Counter-Strike: Source"; }
elseif (
$info['game'] == 'dod') { $info['game'] = "Day of Defeat: Source"; }
$info['gamemode'] = $sinfo[3];
return 
$info;



Finally, an example of how to use all of this would be:
PHP Code:
$query source_query($ip); // $ip MUST contain IP:PORT
$q format_source_query($query);

echo 
"Hostname: ".$q['hostname'];
echo 
"Map: ".$q['map'];
echo 
"Game: ".$q['game'];
echo 
"Gamemode: ".$q['gamemode']; 

An example of similar code at work would be the following image which I have dynamically created with php:
[Image: ?a=gmod.randomresources.com:27016]


A portion of the code was not made by me (part of the query code),, however I had to spend lots of time figuring out how to dissect the query results and get the broken query code to work. You are free to use this wherever you wish with no credits, but a link to randomresources.org would be nice. I made this because a few months ago I looked for such a script and could not find one.
randomresources.org | xfire: toasty2
Reply
#2
Nice job, I'm sure a lot of people can use this for their clan website!
Join the Source Dedicated Server Support Group on Steam Community!
Source Dedicated Server (SRCDS)
Free to join, Live support! (When available)

http://forums.srcds.com/viewtopic/5114
Reply
#3
can u use this to get player count?
Reply
#4
yes you can, you'll have to add a bit of code tho, if you know how to use PHP you can see what to send to the server here:
http://developer.valvesoftware.com/wiki/Source_Server_Queries
Join the Source Dedicated Server Support Group on Steam Community!
Source Dedicated Server (SRCDS)
Free to join, Live support! (When available)

http://forums.srcds.com/viewtopic/5114
Reply
#5
I have been looking around on google now for almost 4 hours trying to find a way to query the a server I have the RCON password for to get a list of the players with SteamID. I've found examples of many things and have gotten almost all the little snippets of code I need to piece together a PHP based little admin system but I can't get the SteamID. I'm pretty sure it's possible, I had run into PsychoNuke RCON mod by the PHPNuke people that had some sort of SteamID retrieval system, however the script was a bit dated and I couldn't get it to even query the server.

Anyways if anyone could help me out here with retrieving player steamid's with the rcon, which I believe is needed, I would be greatly thankful for maybe just a link to another PHP script or something that retrieves it that I could just look through.

Thanks.

*edit*
I seem to get how to do it, you basically have to send the RCON status command however I know enough PHP to look at something and know where to cut/paste and do minor editing but I can't really seem to figure out how I can format the returning strings from the rcon status command I get with this php script I have to send RCON commands. It sends the command fine, just returns NULL and need a bit of help just getting the info returned into arrays or something.

Code:
<?php
define("SERVERDATA_EXECCOMMAND",2);
define("SERVERDATA_AUTH",3);

class RCon {
    var $Password;
    var $Host;
    var $Port = 27015;
    var $_Sock = null;
    var $_Id = 0;

    function RCon ($Host,$Port,$Password) {
    $this->Password = $Password;
    $this->Host = $Host;
    $this->Port = $Port;
    $this->_Sock = @fsockopen($this->Host,$this->Port, $errno, $errstr, 30) or
        die("Couldn't Connect: $errstr ($errno)\n");
    $this->_Set_Timeout($this->_Sock,2,500);
    }
    
    function Auth () {
    $PackID = $this->_Write(SERVERDATA_AUTH,$this->Password);
    
    $ret = $this->_PacketRead();
    if ($ret[1]['id'] == -1) {
        die("Erreur\n");
    }
    }

    function _Set_Timeout(&$res,$s,$m=0) {
    if (version_compare(phpversion(),'4.3.0','<')) {
        return socket_set_timeout($res,$s,$m);
    }
    return stream_set_timeout($res,$s,$m);
    }

    function _Write($cmd, $s1='', $s2='') {
    $id = ++$this->_Id;
    $data = pack("VV",$id,$cmd).$s1.chr(0).$s2.chr(0);
    $data = pack("V",strlen($data)).$data;
    fwrite($this->_Sock,$data,strlen($data));
    return $id;
    }

    function _PacketRead() {
    $retarray = array();
    while ($size = @fread($this->_Sock,4)) {
        $size = unpack('V1Size',$size);
        if ($size["Size"] > 4096) {
        $packet = "\x00\x00\x00\x00\x00\x00\x00\x00".fread($this->_Sock,4096);
        } else {
        $packet = fread($this->_Sock,$size["Size"]);
        }
        array_push($retarray,unpack("V1ID/V1Reponse/a*S1/a*S2",$packet));
    }
    return $retarray;
    }

    function Read() {
    $Packets = $this->_PacketRead();    
    foreach($Packets as $pack) {
        if (isset($ret[$pack['ID']])) {
        $ret[$pack['ID']]['S1'] .= $pack['S1'];
        $ret[$pack['ID']]['S2'] .= $pack['S1'];
        } else {
        $ret[$pack['ID']] = array(
                    'Reponse' => $pack['Reponse'],
                    'S1' => $pack['S1'],
                    'S2' =>    $pack['S2'],
                    );
        }
    }
    return $ret;
    }

    function sendCommand($Command) {
    $Command = '"'.trim(str_replace(' ','" "', $Command)).'"';
    $this->_Write(SERVERDATA_EXECCOMMAND,$Command,'');
    }

    function rconCommand($Command) {
    $this->sendcommand($Command);
    $ret = $this->Read();
    return $ret[0]['S1'];
    }
}
?>
Reply
#6
Ok, I went through that file putting echo statements all throughout and basically found that the entire status command sent back is in one big packet from the function _PacketRead() area under the else part of the if statement. You can also call that exact packet with all the data with "$ret[2]['S1']" in the function rconCommand at the end. It will basically send this packet as an example at you so what I guess I need to see is if there is anyway to break this stuff up:

Code:
hostname: Insomnia TF2 Server version : 1.0.0.2/9 3247 secure udp/ip : 66.150.155.81:27015 map : cp_gravelpit at: 0 x, 0 y, 0 z players : 17 (24 max) # userid name uniqueid connected ping loss state adr # 368 "pumpkinaza" STEAM_0:1:16339968 38:20 62 0 active 72.134.111.52:27005 # 352 "zhr^sm0kez" STEAM_0:0:13942862 1:22:03 58 0 active 68.116.91.92:33561 # 373 "Revant" STEAM_0:1:4151980 25:38 85 0 active 66.1.140.91:27005 # 338 "zhr^Shaun Alexander" STEAM_0:0:12899953 2:32:39 81 0 active 24.19.200.145:27005 # 378 "parnell555" STEAM_0:1:16210038 20:35 102 0 active 66.91.58.44:27005 # 377 "Rogg" STEAM_0:0:4644486 22:43 51 0 active 63.194.81.36:37135 # 366 "Choplol" STEAM_0:0:16285278 42:26 61 0 active 72.197.42.253:8331 # 360 "[unknown]" STEAM_0:0:7771895 56:36 187 0 active 211.209.247.75:27005 # 318 "Theone" STEAM_0:1:60380 3:43:25 89 0 active 98.198.106.239:43620 # 365 "Tide" STEAM_0:1:11566164 42:44 73 0 active 71.104.0.40:27005 # 381 "sollars" STEAM_0:1:3918650 14:02 215 0 active 81.153.71.199:51605 # 367 "frost" STEAM_0:0:4621907 42:04 73 0 active 66.245.38.89:61420 # 386 "zhr^dangerdoom" STEAM_0:0:4069842 05:00 70 0 active 71.103.25.201:50630 # 372 "Archangel" STEAM_0:0:6785933 28:09 116 0 active 70.178.255.75:27005 # 375 "the.g.chan" STEAM_0:0:16174051 25:25 32 0 active 169.232.117.77:27005 # 315 "iNs|Quasar" STEAM_0:1:16228721 4:00:10 88 0 active 68.147.128.133:9328 # 380 "Corporal_Tunnel" STEAM_0:0:13441685 15:56 105 0 active 69.254.162.211:60060
Reply
#7
Hi thanks for the post its quite usefull and intersting. Im also trying to get the this script to show the number of player slots and current players.

Id love to also be able to pull off player stats but reading the link you provided I can see that source servers have that info but im damned if I can see how I can fetch that data.
Reply
#8
There is something called grey cube that queries servers. I think its greycube.com .
realchamp Wrote:
Hazz Wrote:Has someone helped you on these forums? If so, help someone else
Mooga Wrote:OrangeBox is a WHORE.
Reply
#9
Its called LGSL - known about the guy (Richard Perry) years ago as the LGSL was initally released as a plugin for the popular CMS e107. But yes, the site is called GreyCube - http://www.greycube.com/site/news.php

He has a standalone version now that can query most gameservers and return pings, scores, players names (and possibly steamids - can't remember off the top of my head). You can create your own PHP page to display the query back onto another page if you want a different layout.

Only problem is if you run this off a webserver, the query ports tend to be blocked by most webhosts - and even if you ask nicely, they usually wont unblock them.
Reply
#10
Drocona Wrote:yes you can, you'll have to add a bit of code tho, if you know how to use PHP you can see what to send to the server here:
http://developer.valvesoftware.com/wiki/Source_Server_Queries

Promt please this "bit of code" that I can to see the number of players
Reply
#11
Just look at the website Drocona provided. I did, took me a second to find it.
realchamp Wrote:
Hazz Wrote:Has someone helped you on these forums? If so, help someone else
Mooga Wrote:OrangeBox is a WHORE.
Reply
#12
"\xFF\xFF\xFF\xFF\x57" ?
Reply
#13
what? Just click on the link.....
Here it is again for you http://developer.valvesoftware.com/wiki/Source_Server_Queries
realchamp Wrote:
Hazz Wrote:Has someone helped you on these forums? If so, help someone else
Mooga Wrote:OrangeBox is a WHORE.
Reply
#14
thanks for the link for Hl1 http://www.j0k3r.net/forum/classe-php-de-query-serveur-hl1-563.htm
Reply
#15
erm.... that's french...
Join the Source Dedicated Server Support Group on Steam Community!
Source Dedicated Server (SRCDS)
Free to join, Live support! (When available)

http://forums.srcds.com/viewtopic/5114
Reply


Forum Jump:


Users browsing this thread: 7 Guest(s)