# Half-Life RCON Script



## aciddesigns_de (1. Juni 2006)

Hi,
ich bin auf der Suche nach einen Half-Life 1 RCON Script um meinen Server zuadministrieren.

Ich habe dies gefunden: http://www.pberndt.com/Projekte.Codesnipplets.Snipplets.HL+Rcon+Klasse.html

Informationen wie Servername , current Map etc. werden angezeigt nur weiss ich nicht wie ich jetzt Befehle zum Server sende. Ich hoffe mir kann einer weiter helfen 

Greetz


----------



## Dennis Wronka (1. Juni 2006)

Da steht doch alles bei. Erst wird die Klasse gezeigt und gleich darunter ist findest Du ein Beispiel.


----------



## aciddesigns_de (1. Juni 2006)

Wie soll ich denn einen RCON Befehl senden wenn ich nirgendwo mein RCON Password eingeben muss


----------



## Dennis Wronka (1. Juni 2006)

Auch diese Info kannst Du dort finden.


> // WICHTIG:
> // Vor Rcon Befehlen immer den Text "rcon " senden
> // Also z.B. ('rcon rcon_password 123'), sonst kommt ein
> // Fehler!!


----------



## aciddesigns_de (1. Juni 2006)

Hat immernoch nichts mit meinem Problem zutun 
Ich kann keine Befehle an meinen Server schicken weil ich nicht weiss wo ich das RCON Password eingeben muss.


----------



## Suchfunktion (1. Juni 2006)

Ich verstehe schon was du genau meinst.

Er will wissen, wie er Nachrichten an den Server senden kann (und vermutlich auch wie er Nachrichten vom Server empfangen kann).


----------



## aciddesigns_de (1. Juni 2006)

ne 

ich weiss wie ich Nachrichten sende, aber nicht wie ich das RCON Password definiere.

Also folgendes:
Mit dieser Class kann ich die Informationen des Servers ausgeben da ich kein RCON Password brauche um dies zutun.
Was ich möchte, ist RCON Befehle an den Server senden um zB den Server namen zu ändern. Dazu muss ich allerdings das RCON Password setzen.


----------



## Dennis Wronka (1. Juni 2006)

Du kannst das Passwort mit der gleichen Funktion senden wie die Befehle.
Lies Dir das doch mal richtig durch. 

Das ist die Funktion: executeCommand($command)


----------



## aciddesigns_de (1. Juni 2006)

nein so kann man das nicht senden.


----------



## Dennis Wronka (1. Juni 2006)

Steht doch so da. Hast Du es mal probiert?
Ansonsten empfehle ich Ethereal


----------



## aciddesigns_de (1. Juni 2006)

Ja, ich hab es probiert sonst wüde ich nicht sagen das es nicht funktioniert ^^.


----------



## Dennis Wronka (1. Juni 2006)

Dann wirst Du Dir dafuer wohl eine Funktion schreiben muessen. Dafuer wirst Du dann wohl diese CommandID benoetigen. Diese zu bekommen duerfte mit Ethereal kein Problem sein.


----------



## aciddesigns_de (1. Juni 2006)

also Ethereal ist für mich auf Spanisch  
versteh ich nicht.


----------



## MArc (1. Juni 2006)

Du musst das rcon passwort setzen

Das geht so:

```
rcon_password xyz
```
und schon kannst du mittels

```
rcon say "hallo Ihr"
```
Befehle an den Server senden


----------



## aciddesigns_de (1. Juni 2006)

funkitoniert auch nicht


----------



## MArc (1. Juni 2006)

Achso, sorry das hab ich missverstanden.

Wenn du zb. über HLSW oder dem Spiel direkt befehle auf dem Server ausführe lassen willst.
Dann musst du ja erst das Passwort setzen, damit du Rechte bekommst, um diese auszuführen.

Soviel ich weiß, wird jedesmal wenn man ein Befehl über rcon ausführen will, das Passwort mitgesendet. Das müsstest du wahrscheinlch hinbekommen.

Gruss,
MArc


----------



## aciddesigns_de (1. Juni 2006)

kann das nicht jemamd mal selbst ausprobieren ?


----------



## aciddesigns_de (1. Juni 2006)

Folgendes habe ich Herausgefunden:

wenn ich nur 

```
if($myacid->executeCommand('bla'))
```
sende kommt das beim server an.
wenn ich aber

```
if($myacid->executeCommand('bla bla'))
```
sende kommt es nicht an. 
kann das an

```
function executeCommand($command)
        {
            $cmdIdentifier = "\xFF\xFF\xFF\xFF";
            
            fwrite($this->sockId, $cmdIdentifier.$command);
            
            $retVal = fread($this->sockId, 5);
            if(substr($retVal, 0, 4) != $cmdIdentifier)
                return false;
            
            return substr($retVal, 4);
        }
```
liegen ?
das da vielleicht was geändert werden muss da man scheinbar nur 1 Wort senden kann.


----------



## MArc (1. Juni 2006)

Also ich habs wahrscheinlich.

Du musst "server_password definieren.
Das script was du hast, ist wohl für Server die kein rcon passwort gesetzt haben (?)(falls das geht)

Füge einfach vor

```
$this->sockId = fsockopen('udp://'.$server, $port, &$errno, &$errstr, 15);
```

ein


```
$this->server_password = 'meinpasswort';
```
ein.
Hoffe das Hilft.

Nachtrag: Ähm, ich glaube es gibt befehle die kein rcon erfordern, (info zb.) und andere die eins benötigen. Da bin ich mir aber nicht ganz sicher.

Gruss,
MArc


----------



## aciddesigns_de (1. Juni 2006)

kommt das selbe bei raus


----------



## MArc (1. Juni 2006)

Ok, dann weiß ich es nicht.

Lade doch einfach das hier herunter und passe es an.

Gruss,
MArc


----------



## aciddesigns_de (1. Juni 2006)

Habe folgendes gefunden:
das soll funktionieren , tut es zwar nicht aber vielleicht kann daraus Jemand etwas ableiten.


```
<?php
/*
	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 Failure\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='') {
	// 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 = "\x00\x00\x00\x00\x00\x00\x00\x00".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'];
    }
}

$r = new rcon("xxx.xxx.xxx.xxx",27500,"rconpw");
$r->Auth();

echo "Authenticated\n";

//Send a request
var_dump($r->rconCommand("cvarlist"));

?>
```

die Funktion "Auth" sended das RCON Password.


----------



## Dennis Wronka (1. Juni 2006)

Und was genau funktioniert nicht? Kommt vielleicht ein Fehler vom Server zurueck? Oder gibt PHP Dir einen Fehler?


----------



## aciddesigns_de (1. Juni 2006)

mit diesem Script kann der erst garnicht Connecten.
mit dem anderen Script kann er Connecten und es kommen ja auch Informationen vom Server.


----------



## Dennis Wronka (1. Juni 2006)

Nimm mal das @ vor fsockopen() raus und guck ob es eine Fehlermeldung gibt.


----------



## aciddesigns_de (1. Juni 2006)

Warning: fsockopen() [function.fsockopen]: php_hostconnect: connect failed in /home/www/htdocs/myacid.de/cs/rcon.class.php on line 27

Warning: fsockopen() [function.fsockopen]: unable to connect to 193.192.58.59:27500 in /home/www/htdocs/myacid.de/cs/rcon.class.php on line 27
Unable to open socket: Connection refused (111) 

und wenn das @ da ist kommt nur:

Unable to open socket: Connection refused (111) 

liegt vielleicht daran das das 2te Script für Half-Life 2 ist.


----------



## MArc (1. Juni 2006)

Vielleicht wurde dieses "Feature" in PHP deaktiviert?:-(
Nachtrag: Oder ne, sonst würde ja eine andere Meldung kommen.

Vielleicht ist die IP oder Port ja falsch


----------



## Dennis Wronka (1. Juni 2006)

fsockopen() an sich scheint ja zu funktionieren. Nur kann halt keine Verbindung hergestellt werden. Sind sowohl IP als auch Port richtig angegeben? Laeuft die Verbindung vielleicht ueber UDP und nicht ueber TCP?


----------



## aciddesigns_de (1. Juni 2006)

welches Feature ?


----------



## MArc (1. Juni 2006)

Wie gesagt: Installier doch mal das Script dass ich weiter oben gepostet habe.
Wenn das Funktioniert weißt du das es nicht an dem Server liegt sondern an deinem eigenen Script

Gruss,
MArc


----------



## aciddesigns_de (1. Juni 2006)

ich weiss das es an meinem liegt da alle anderen Funktioniren.

kann sich vielleicht mal Jemand dieses Script runterladen und angucken:
http://sourceforge.net/project/showfiles.php?group_id=66007

und das mit meinem vergleichen. Evt. kommt einer auf einen Fehler.
Mein Problem : Ich brauch eine Funktion in der ich das RCON Password definiere.
Hier nochmal das Script:


```
<?php

    /*
        RCON Halflife Admin Klasse

        Aktion: PHP Scripte für die armen dieser Welt
        Der Erlös geht für mein Pausenbrot drauf 

        Copyright (c) 2004 by Phillip 'Firebird' Berndt
    */
    
    class hlAdmin
    {
        var $sockId;
        
        function hlAdmin($server, $port)
        {
            $this->sockId = fsockopen('udp://'.$server, $port, &$errno, &$errstr, 15);
            
            if(!$this->sockId)
                die("<br /><br />Error($errno): $errstr<br />");
        }
        
        function executeCommand($command)
        {
            $cmdIdentifier = "\xFF\xFF\xFF\xFF";
            
            fwrite($this->sockId, $cmdIdentifier.$command);
            
            $retVal = fread($this->sockId, 5);
            if(substr($retVal, 0, 4) != $cmdIdentifier)
                return false;
            
            return substr($retVal, 4);
        }
        
        function getString()
        {
            while(ord($mChar = fgetc($this->sockId)) != 0)
            {
                $retVal .= $mChar;
            }
            return $retVal;
        }
        
        function readBytes($count)
        {
            return fread($this->sockId, $count);
        }
        
    }

    // Testscript
    $myacid = new hlAdmin('193.192.58.59', 27500);
    
    // Server informationen
    if($myacid->executeCommand('info') == 'C')
    {
        echo("<table width='365' border='0' align='center' cellpadding='0' cellspacing='0'>
  					<tr>
    						<td width='110'> IP : </td>
    						<td width='255'>".$myacid->getString()."</td>
  					</tr>
  					<tr>
    						<td>Hostname :</td>
    						<td>".$myacid->getString()."</td>
  					</tr>
  					<tr>
    						<td>Map :</td>
    						<td>".$myacid->getString()."</td>
  					</tr>
  					<tr>
    						<td>Mod : </td>
    						<td>".$myacid->getString()."</td>
  					</tr>
  					<tr>
    						<td>Description : </td>
    						<td>".$myacid->getString()."</td>
  					</tr>
				</table>");

        $myacid->readBytes(3);
        echo('<br />
        ');
    }
    else 
    {
        echo('Verbindung fehlgeschlagen');
    }
    
    // WICHTIG:
    // Vor Rcon Befehlen immer den Text "rcon " senden
    // Also z.B. ('rcon rcon_password 123'), sonst kommt ein
    // Fehler!!

    // Irgendwas zum Beweisen, dass auch andere Befehle gehen :D
    // Müsste kommen, dass ich keine rcon Rechte hab ;)
    if($myacid->executeCommand('rcon mp_foobar 1'))
        echo($myacid->getString());
?>
```


----------



## k0riz0n (12. Juni 2006)

hi

biste denn jetz weiter gekommen?

also mit dem "Basic CS:S Rcon class by Freman.  (V1.00)" was auf der seite vorher gepostet wurde konnte ich bisher alle befehle an den server sende.. auch solche die eine authentification brauchen, z.b. ein PW setzen.

EDIT:
ich hab da mal was zusammengezimmert..
einfach ip, port, rcon passwort und evtl. nen befehl eingeben (kann auch leer bleiben, dann wird "status" benutzt.
http://www.korizon.de/


----------

