PHP Classes

File: clsRcon.php

Recommend this page to a friend!
  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: 15 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_STREAM, SOL_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_sPassword, null, self::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, $sPacket, strlen($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 = NULL, 0, $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']);

?>