Gameserver RCON Befehle ausführen per PHP

Bash, Shell, PHP, Python, Perl, CGI
twisterchen
Anbieter
Posts: 233
Joined: 2005-07-14 14:13

Gameserver RCON Befehle ausführen per PHP

Post by twisterchen » 2006-12-04 15:43

Hallo

Ich habe mir hier mal einen Connect zusammengebastelt um RCON Befehle an einen CS Server zu schicken.

Code: Select all

<?php 
if (!isset($_GET['command'])) {
	$_GET['command'] = "stats";
}

set_time_limit(1);
$cs_server["ip"] = "192.168.100.22"; 
$cs_server["port"] = "27017"; 
$cs_server["rcon"] = "peppi01"; 

$server_connect =  fsockopen("udp://".$cs_server[ip], $cs_server[port]); // zum server verbinden 

if(!$server_connect) { 
    echo "Fehler beim verbinden!";
}
else {
	echo "Verbindung steht!:";;
	// rcon id holen
	fwrite($server_connect, "xFFxFFxFFxFFchallenge rconx00"); 
	
	$read_id = fread($server_connect, 1); 
	$sockets = socket_get_status($server_connect); 
	$read_id = $read_id . fread($server_connect,$sockets['unread_bytes']); 

	$rcon_pw = explode(" ", $read_id); 
	$cs_server[rcon_id] = $rcon_pw[2];
	$cs_server[rcon_id] = str_replace("n","",$cs_server[rcon_id]); 
	// rcon ID ausgeben
	echo $cs_server[rcon_id]."<br>"; 
	// Ersten befehl senden
  // ...
  $command = sprintf("rcon %s "%s" %s", $cs_server['rcon_id'], $cs_server['rcon'], $_GET['command']);
  // Debug:
  print "DEBUG: command = $command<br />n";
  $tosend = sprintf("%c%c%c%c%s%c", 0xFF, 0xFF, 0xFF, 0xFF, $command, 0x00);
  // ...
	#$tosend = sprintf("%c%c%c%c%s%c",0xFF,0xFF,0xFF,0xFF,"rcon ".$cs_server[rcon_id]." \"".$cs_server[rcon]."\" ".$_GET[command],0x00);
	fwrite($server_connect,$tosend);
	?>
	<pre><? echo $tosend; ?></pre>
	<?
	$read_cmd = fread($server_connect, 1); 
	$sockets = socket_get_status($server_connect); 
	$read_cmd = $read_cmd . fread($server_connect,$sockets['unread_bytes']); 
	fclose($server_connect);
	echo $read_cmd; 
}

?>
folgende Ausgabe bekomme ich

Code: Select all

Verbindung steht!:1464595332
DEBUG: command = rcon 1464595332

ÿÿÿÿrcon 1464595332

ÿÿÿÿlBad rcon_password.
er sagt mir hier immer Bad rcon_password. aber ich bin mir sicher, dass das RCON PW stimmt was mache ich denn hier nur falsch vielleicht könnten mir die Durchsteiger einen Tip geben.


Vielen Dank
Gruss
Gerhard

twisterchen
Anbieter
Posts: 233
Joined: 2005-07-14 14:13

Re: Gameserver RCON Befehle ausführen per PHP

Post by twisterchen » 2006-12-05 11:41

Ich komm nicht auf den fehler wo ich irgendwo vielleicht ein String falsch übergebe oder bekomme

http://developer.valvesoftware.com/wiki/Server_Queries

Das hilft mir nicht wirklich weiter habt ihr nicht doch eine Idee dazu

Gruss
Gerhard

User avatar
Joe User
Project Manager
Project Manager
Posts: 11602
Joined: 2003-02-27 01:00
Location: Hamburg

Re: Gameserver RCON Befehle ausführen per PHP

Post by Joe User » 2006-12-05 12:45

Bin ich blind, oder hast Du den markierten Teil überlesen und deshalb nicht bedacht?
http://developer.valvesoftware.com/wiki/Server_Queries wrote:Server rules usually exceed the 1400 bytes. Because UDP packets can arrive in different order or delayed, every packet should be verified by its Request ID and the Packet Number! Every request or response with or without this header is continued with an integer -1 (0xFFFFFFFF) and the user data.
So by reading the first 4 bytes you can decide whether the data is split (-2) or in one packet (-1).
Zudem wird Dein $_GET['command'] nicht ausreichend geprüft und das set_time_limit würde ich etwas erhöhen...
PayPal.Me/JoeUserFreeBSD Remote Installation
Wings for LifeWings for Life World Run

„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.

twisterchen
Anbieter
Posts: 233
Joined: 2005-07-14 14:13

Re: Gameserver RCON Befehle ausführen per PHP

Post by twisterchen » 2006-12-05 13:54

Hallo
Zudem wird Dein $_GET['command'] nicht ausreichend geprüft und das set_time_limit würde ich etwas erhöhen...
Das ist nur zum testen das kommt bestimmt nicht so zum einsatz.

Ich habe das hier auch noch gefunden nur immo kann ich das nicht umsetzten zudem ist mein English nicht grade das allerbeste

http://developer.valvesoftware.com/wiki ... N_Protocol

Das hier geht schon so tief in die Materie das mir das auf den ersten blick einfach zu schwer ist zu verstehen.

Das Problem noch dabei ist, dass die Server Querys und das Source RCON Protocol in Beziehung auf CSS Server und 1.6 bzw CZ unterschiedlich sind.

Mir fehlt einfach der ansatz das umzusetzten, hier kommt schon wieder der Punkt nacht 5 Tagen wo ich alles hinschmeissen würde.

twisterchen
Anbieter
Posts: 233
Joined: 2005-07-14 14:13

Re: Gameserver RCON Befehle ausführen per PHP

Post by twisterchen » 2006-12-05 14:27

So hab hier mal ein für Source Server Rcon Script gefunden

Code: Select all

/*
    Basic CS:S Rcon class by Freman.  (V1.00)
    ----------------------------------------------
    Ok, it's a completely working class now with with multi-packet responses

    Contact: printf("%s%s%s%s%s%s%s%s%s%d%s%s%s","rc","on",chr(46),"cl","ass",chr(64),"pri","ya",chr(46),2,"y",chr(46),"net")

    Behaviour I've noticed:
    rcon is not returning the packet id.
*/

define("SERVERDATA_EXECCOMMAND",2);
define("SERVERDATA_AUTH",3);

class RCon {
    var $Password;
    var $Host;
    var $Port = 27500;
    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("Unable to open socket: $errstr ($errno)n");
    $this->_Set_Timeout($this->_Sock,2,500);
    }
    
    function Auth () {
    $PackID = $this->_Write(SERVERDATA_AUTH,$this->Password);
    
    // Real response (id: -1 = failure)
    $ret = $this->_PacketRead();
    if ($ret[1]['id'] == -1) {
        die("Authentication Failuren");
    }
    }

    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='') {
    // Get and increment the packet id
    $id = ++$this->_Id;

    // Put our packet together
    $data = pack("VV",$id,$cmd).$s1.chr(0).$s2.chr(0);

    // Prefix the packet size
    $data = pack("V",strlen($data)).$data;

    // Send packet
    fwrite($this->_Sock,$data,strlen($data));

    // In case we want it later we'll return the packet id
    return $id;
    }

    function _PacketRead() {
    //Declare the return array
    $retarray = array();
    //Fetch the packet size
    while ($size = @fread($this->_Sock,4)) {
        $size = unpack('V1Size',$size);
        //Work around valve breaking the protocol
        if ($size["Size"] > 4096) {
        //pad with 8 nulls
        $packet = "x00x00x00x00x00x00x00x00".fread($this->_Sock,4096);
        } else {
        //Read the packet back
        $packet = fread($this->_Sock,$size["Size"]);
        }
        array_push($retarray,unpack("V1ID/V1Response/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(
                    'Response' => $pack['Response'],
                    '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();

    //ATM: Source servers don't return the request id, but if they fix this the code below should read as
    // return $ret[$this->_Id]['S1'];return $ret[0]['S1'];
   return $ret[$this->_Id]['S1'];
    }
}

$r = new rcon("192.168.100.22",27015,"rconpasswort");
$r->Auth();

echo "Authenticatedn<br><pre>";
var_dump($r->rconCommand("stats"));
echo "</pre><br>";
?>
Hier bekomme ich das was ich will allerdings nur für Source Server jetzt versteh ich den unterschied nicht was ich ändern müsste um das auch für 1.6 bzw CZ Server zu bekommen.

Ich reiss mir heute noch den Kopf ab. :!:

twisterchen
Anbieter
Posts: 233
Joined: 2005-07-14 14:13

Re: Gameserver RCON Befehle ausführen per PHP

Post by twisterchen » 2006-12-05 17:27

Server rules usually exceed the 1400 bytes. Because UDP packets can arrive in different order or delayed, every packet should be verified by its Request ID and the Packet Number! Every request or response with or without this header is continued with an integer -1 (0xFFFFFFFF) and the user data.
So by reading the first 4 bytes you can decide whether the data is split (-2) or in one packet (-1).
Ich versteh leider nicht warum ich nach den ersten 4 Bytes entscheiden muss ob es getrennt werden muss oder nicht.

Ich grig das nicht in den PHP Code gepacken vorallendingen bei zwei verschiedenen anfragen an die jeweils unterschiedlichen server CSS oder 1.6 bzw CZ

Anonymous

RCON für CSS

Post by Anonymous » 2007-01-06 13:22

Hello
ich bin grade am selben problem... jaja dieses css
für nahezu alle anderen gameserver ist es kinderleicht ein webinterface zu erstellen... NICHT FÜR CSS

aber ich denke du sendest die falschen pakete am anfang. die sind für css.
wie die pakete für rcon cs aussehen, dahinter bin ich auch noch nicht gekommen

aber probiers mal mit diesem ansatz im $paket
xFFxFFxFFxFFchallenge rconx00

wenn du schon mehr weisst, gib bescheid

bennyprodo
Posts: 5
Joined: 2008-06-11 21:18

Re: Gameserver RCON Befehle ausführen per PHP

Post by bennyprodo » 2008-11-15 23:30

hat sich bereits erledigt^^