What? RCON built into mc 1,9?

Discussion in 'Bukkit Discussion' started by zenyl, Oct 14, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    zenyl

    Dinnerbone tweeted this around 23 hours ago. I just saw it, and now my head is filled with "how"

    Anyone got any idea how this should work, or is it kept as a Bukkit secret for now?

    PS: Sorry for the weird title, i accidentially clicked the "send" button (or what it's called), before i saw, the title was wrong
     
  2. It's a feature of the vanilla server.
     
  3. The vanilla code for 1.9pr4+ Supports the RCON protocol, used by source games for remote consoles.
    I have a php class on my desktop that can auth and send commands over this. Would be very nice over needing plugins to do this.
     
  4. Offline

    zenyl

    Thx for clearing that up for me :D
     
  5. @tehbeard Mind showing your php class, or just do a tiny tutorial on how to connect via RCON?
     
  6. @r3Fuze , I make no claim of it working past the current 1.9pr4, but for experimental purposes it's quite neat.

    Code:
    <?php
    /*
    RCON remote console class, modified for minecraft compability by Tehbeard.
    
    !!!YOU MUST CONFIGURE RCON ON YOUR MINECRAFT SERVER FOR THIS TO WORK
    AT TIME OF WRITING ONLY 1.9pr4+ HAVE BUILTIN RCON SUPPORT!!!
    
    Example Code:
    ============
    include_once("rcon.class.php"); //Include this file
    $r = new rcon("127.0.0.1",25575,"foobar"); //create rcon object for server on the rcon port with a specific password
    if($r->Auth()){ //Connect and attempt to authenticate
    {
      $r->rconCommand("say Saving in 10 seconds!"); //send a command
      sleep(10);
      $r->rconCommand("save-all"); //send a command
      $r->rconCommand("say Save complete!");//send a command
      echo $r->rconCommand("list");//send a command, echo returned value
    }
    ============
    
    
    
    Based upon the following work:
    [<<<
    	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 = 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("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();
    		//var_dump($ret);
    		if ($ret[0]['ID'] == -1) {
    			return false;
    		}
    		return true;
    	}
    
    	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)).'"';
    		//$Command="stop";
    		$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[$this->_Id]['S1'];
    	}
    }
    ?>
    
    
     
    jwnordquist, ks07, cheese5505 and 2 others like this.
  7. Offline

    cheese5505

    Nice, it works on Pre5! But, it gives me errors after i submit the command. I'll try to fix it.
     
  8. Offline

    NuclearW

    I would like to note that you should be very careful about using rcon, especially what networks you use it on, such as an unencrypted wifi connection.

    Rcon has no encryption, so when you send your rcon password it is sent in the clear! Using SSH or other encrypted methods for remote console access should still be your primary method if you can use it.
     
Thread Status:
Not open for further replies.

Share This Page