Skip to content

Commit

Permalink
credits
Browse files Browse the repository at this point in the history
  • Loading branch information
PadowYT2 authored Jan 3, 2023
1 parent 38cabdd commit 7f60f5c
Showing 1 changed file with 107 additions and 47 deletions.
154 changes: 107 additions & 47 deletions modules/RconMC/classes/Rcon.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
<?php
/**
* See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for
* more information about Source RCON Packets
*
* PHP Version 7
*
* @copyright 2013-2017 Chris Churchwell
* @author thedudeguy
* @link https://github.com/thedudeguy/PHP-Minecraft-Rcon
*/

namespace Thedudeguy;

class Rcon
{

private $host;
private $port;
private $password;
private $timeout;

private $socket;

private $authorized;
private $last_response;
private $authorized = false;
private $lastResponse = '';

const PACKET_AUTHORIZE = 5;
const PACKET_COMMAND = 6;
Expand All @@ -21,6 +32,14 @@ class Rcon
const SERVERDATA_EXECCOMMAND = 2;
const SERVERDATA_RESPONSE_VALUE = 0;

/**
* Create a new instance of the Rcon class.
*
* @param string $host
* @param integer $port
* @param string $password
* @param integer $timeout
*/
public function __construct($host, $port, $password, $timeout)
{
$this->host = $host;
Expand All @@ -29,74 +48,102 @@ public function __construct($host, $port, $password, $timeout)
$this->timeout = $timeout;
}

public function get_response()
/**
* Get the latest response from the server.
*
* @return string
*/
public function getResponse()
{
return $this->last_response;
return $this->lastResponse;
}

public function connect(): bool
/**
* Connect to a server.
*
* @return boolean
*/
public function connect()
{
$this->socket = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);

if (!$this->socket) {
$this->last_response = $errstr;
$this->lastResponse = $errstr;
return false;
}

//set timeout
stream_set_timeout($this->socket, 3, 0);

//authorize
$auth = $this->authorize();

if ($auth) {
return true;
}

return false;
// check authorization
return $this->authorize();
}

/**
* Disconnect from server.
*
* @return void
*/
public function disconnect()
{
if ($this->socket) {
fclose($this->socket);
fclose($this->socket);
}
}

public function is_connected()
/**
* True if socket is connected and authorized.
*
* @return boolean
*/
public function isConnected()
{
return $this->authorized;
}

public function send_command($command)
/**
* Send a command to the connected server.
*
* @param string $command
*
* @return boolean|mixed
*/
public function sendCommand($command)
{
if (!$this->is_connected()) {
return false;
if (!$this->isConnected()) {
return false;
}

// send command packet.
$this->write_packet(Rcon::PACKET_COMMAND, Rcon::SERVERDATA_EXECCOMMAND, $command);
// send command packet
$this->writePacket(self::PACKET_COMMAND, self::SERVERDATA_EXECCOMMAND, $command);

// get response
$response_packet = $this->readPacket();
if ($response_packet['id'] == self::PACKET_COMMAND) {
if ($response_packet['type'] == self::SERVERDATA_RESPONSE_VALUE) {
$this->lastResponse = $response_packet['body'];

// get response.
$response_packet = $this->read_packet();
if ($response_packet['id'] == Rcon::PACKET_COMMAND) {
if ($response_packet['type'] == Rcon::SERVERDATA_RESPONSE_VALUE) {
$this->last_response = $response_packet['body'];
return $response_packet['body'];
}
}

return false;
}

private function authorize(): bool
/**
* Log into the server with the given credentials.
*
* @return boolean
*/
private function authorize()
{
$this->write_packet(Rcon::PACKET_AUTHORIZE, Rcon::SERVERDATA_AUTH, $this->password);
$response_packet = $this->read_packet();
$this->writePacket(self::PACKET_AUTHORIZE, self::SERVERDATA_AUTH, $this->password);
$response_packet = $this->readPacket();

if ($response_packet['type'] == Rcon::SERVERDATA_AUTH_RESPONSE) {
if ($response_packet['id'] == Rcon::PACKET_AUTHORIZE) {
if ($response_packet['type'] == self::SERVERDATA_AUTH_RESPONSE) {
if ($response_packet['id'] == self::PACKET_AUTHORIZE) {
$this->authorized = true;

return true;
}
}
Expand All @@ -106,38 +153,49 @@ private function authorize(): bool
}

/**
* Writes a packet to the socket stream..
* Writes a packet to the socket stream.
*
* @param $packetId
* @param $packetType
* @param string $packetBody
*
* @return void
*/
private function write_packet($packet_id, $packet_type, $packet_body)
private function writePacket($packetId, $packetType, $packetBody)
{
/*
Size 32-bit little-endian Signed Integer Varies, see below.
ID 32-bit little-endian Signed Integer Varies, see below.
Type 32-bit little-endian Signed Integer Varies, see below.
Body Null-terminated ASCII String Varies, see below.
Empty String Null-terminated ASCII String 0x00
*/
Size 32-bit little-endian Signed Integer Varies, see below.
ID 32-bit little-endian Signed Integer Varies, see below.
Type 32-bit little-endian Signed Integer Varies, see below.
Body Null-terminated ASCII String Varies, see below.
Empty String Null-terminated ASCII String 0x00
*/

//create packet
$packet = pack("VV", $packet_id, $packet_type);
$packet = $packet . $packet_body . "\x00";
$packet = $packet . "\x00";
$packet = pack('VV', $packetId, $packetType);
$packet = $packet.$packetBody."\x00";
$packet = $packet."\x00";

// get packet size.
$packet_size = strlen($packet);

// attach size to packet.
$packet = pack("V", $packet_size) . $packet;
$packet = pack('V', $packet_size).$packet;

// write packet.
fwrite($this->socket, $packet, strlen($packet));
}

private function read_packet()
/**
* Read a packet from the socket stream.
*
* @return array
*/
private function readPacket()
{
//get packet size.
$size_data = fread($this->socket, 4);
$size_pack = unpack("V1size", $size_data);
$size_pack = unpack('V1size', $size_data);
$size = $size_pack['size'];

// if size is > 4096, the response will be in multiple packets.
Expand All @@ -147,6 +205,8 @@ private function read_packet()
// currently, this script does not support multi-packet responses.

$packet_data = fread($this->socket, $size);
return unpack("V1id/V1type/a*body", $packet_data);
$packet_pack = unpack('V1id/V1type/a*body', $packet_data);

return $packet_pack;
}
}

0 comments on commit 7f60f5c

Please sign in to comment.