Login   Register  
PHP Classes
elePHPant
Icontem

File: clsRcon.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Geert Broekmans  >  srcds rcon  >  clsRcon.php  >  Download  
File: clsRcon.php
Role: Class source
Content type: text/plain
Description: The main class, also includes an example
Class: srcds rcon
Send RCON commands to a Source based game server
Author: By
Last change:
Date: 5 years ago
Size: 6,780 bytes
 

Contents

Class file image Download
<?php
/**
 * clsRcon
 * Connects with a Source dedicated server and allows you to execute rcon commands
 *
 * @author Geert Broekmans <php [at] madclog [dot] nl>
 * @copyright 2008 Geert Broekmans
 * @license GNU GPL
 * @version 1.0
 * ========================================================================
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * ========================================================================
 */
class clsRcon {
    
/**
     * Address of the server
     *
     * @var string
     */
    
protected $m_sAddress;
    
/**
     * Port number of the server
     *
     * @var int
     */
    
protected $m_iPort;
    
/**
     * rcon password
     *
     * @var string
     */
    
protected $m_sPassword;
    
/**
     * TCP socket for communication
     *
     * @var object
     */
    
protected $m_oSocket false;
    
/**
     * rcon request id
     *
     * @var int
     */
    
protected $m_iRequestId 0;
    
/**
     * timeout in usec
     *
     * @var int
     */
    
protected $m_iReadTimeout 150000;

    const 
SERVERDATA_EXECCOMMAND 2;
    const 
SERVERDATA_AUTH 3;
    const 
SERVERDATA_RESPONSE_VALUE 0;
    const 
SERVERDATA_AUTH_RESPONSE 2;

    
/**
     * __construct
     * Set the variables used to connect
     *
     * @access public
     * @param string $p_sAddress
     * @param int $p_iPort
     * @param string $p_sPassword
     * @return clsRcon
     */
    
public function __construct($p_sAddress$p_iPort$p_sPassword) {
        
$this->m_sAddress $p_sAddress;
        
$this->m_iPort $p_iPort;
        
$this->m_sPassword $p_sPassword;
    }

    
/**
     * __destruct
     * closes the socket
     *
     * @access public
     * @return void
     */
    
public function __destruct() {
        if (
$this->m_oSocket !== false) {
            
socket_close($this->m_oSocket);
            
$this->m_oSocket false;
        }
    }

    
/**
     * connect
     * Connects the socket and authenticates with the server
     *
     * @access public
     * @return boolean
     */
    
public function connect() {
        
// create a socket
        
if (($this->m_oSocket socket_create(AF_INET,SOCK_STREAMSOL_TCP)) === false) {
            return 
false;
        }
        
// connect it
        
if (socket_connect($this->m_oSocket$this->m_sAddress$this->m_iPort) === false) {
            
$this->m_oSocket false;
            return 
false;
        }
        
// send authentication request
        
$this->rawPacketSend($this->m_sPasswordnullself::SERVERDATA_AUTH);
        
// read the response
        
$aResult $this->rawPacketRead();
        
// check if we authenticated succesfully
        
if ($aResult[0]['CommandResponse'] != self::SERVERDATA_AUTH_RESPONSE) {
            
$this->__destruct();
            return 
false;
        } else {
            return 
true;
        }
    }

    
/**
     * rcon
     * execute an rcon command
     *
     * @access public
     * @param string $p_sCommand
     * @return array
     */
    
public function rcon($p_sCommand) {
        
// check connection
        
if($this->m_oSocket === false) {
            return 
false;
        }
        
$this->rawPacketSend($p_sCommand);

        return 
$this->rawPacketRead();
    }

    
/**
     * rawPacketSend
     * Builds up a packet and sends it to the server
     *
     * @access protected
     * @param string $p_sString1
     * @param string $p_sString2
     * @param int $p_iCommand
     * @return void
     */
    
protected function rawPacketSend($p_sString1$p_sString2 NULL$p_iCommand self::SERVERDATA_EXECCOMMAND) {
        
// build the packet backwards
        
$sPacket $p_sString1 "\x00" $p_sString2 "\x00";
        
// build the Request ID and Command into the Packet
        
$sPacket pack('VV',++$this->m_iRequestID$p_iCommand) . $sPacket;
        
// add the length
        
$sPacket pack('V',strlen($sPacket)) . $sPacket;
        
// send the packet.
        
socket_send($this->m_oSocket$sPacketstrlen($sPacket), 0x00);
    }

    
/**
     * rawPacketRead
     * reads and parses the rcon response
     *
     * @access protected
     * @return array
     */
    
protected function rawPacketRead() {
        
// the packets
        
$aPackets = array();
        
// our reading socket
        
$aRead = array($this->m_oSocket);
        
// we need to use a buffer cause sometimes a packet is send over more then 1 'read request'
        
$sBuffer '';
        while (
socket_select($aRead$aWrite NULL$aExcept NULL0$this->m_iReadTimeout)) {
            
// get the packet length
            
if (strlen($sBuffer) == 0) {
                
$aPacketLength unpack('V1PacketLength'socket_read($aRead[0], 4));
            }

            
// read some data
            
$sBuffer .= socket_read($aRead[0], $aPacketLength['PacketLength'] - strlen($sBuffer));
            
// if the package is complete parse it
            
if (strlen($sBuffer) == $aPacketLength['PacketLength']) {
                
// read the actuall packet
                
$aPacket unpack('V1RequestID/V1CommandResponse/a*String1/a*String2'$sBuffer);
                
$sBuffer '';

                if (isset(
$aPackets[$aPacket['RequestID']]) && $aPacket['CommandResponse'] != self::SERVERDATA_AUTH_RESPONSE) {
                    
// existing reply, append the data
                    
$aPackets[$aPacket['RequestID']]['String1'] .= $aPacket['String1'];
                    
$aPackets[$aPacket['RequestID']]['String2'] .= $aPacket['String2'];
                } else {
                    
// new reply
                    
$aPackets[$aPacket['RequestID']] = $aPacket;
                }
            }
        }
        return 
array_values($aPackets);
    }
}

/**
 * test case below
 */
//$oTest = new clsRcon('1.2.3.4', 27015, 'mypass');
//$oTest->connect();
//$aResponse = $oTest->rcon('cvarlist');
//var_dump($aResponse[0]['String1']);

?>