Serving a payment option for my minecraft server so I don't have to pay for it all alone
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

RCon.class.php 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. /**
  3. * See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for
  4. * more information about Source RCON Packets
  5. *
  6. * PHP Version 7
  7. *
  8. * @copyright 2013-2017 Chris Churchwell
  9. * @author thedudeguy
  10. * @link https://github.com/thedudeguy/PHP-Minecraft-Rcon
  11. */
  12. class Rcon
  13. {
  14. private $host;
  15. private $port;
  16. private $password;
  17. private $timeout;
  18. private $socket;
  19. private $authorized = false;
  20. private $lastResponse = '';
  21. const PACKET_AUTHORIZE = 5;
  22. const PACKET_COMMAND = 6;
  23. const SERVERDATA_AUTH = 3;
  24. const SERVERDATA_AUTH_RESPONSE = 2;
  25. const SERVERDATA_EXECCOMMAND = 2;
  26. const SERVERDATA_RESPONSE_VALUE = 0;
  27. /**
  28. * Create a new instance of the Rcon class.
  29. *
  30. * @param string $host
  31. * @param integer $port
  32. * @param string $password
  33. * @param integer $timeout
  34. */
  35. public function __construct($host, $port, $password, $timeout)
  36. {
  37. $this->host = $host;
  38. $this->port = $port;
  39. $this->password = $password;
  40. $this->timeout = $timeout;
  41. }
  42. /**
  43. * Get the latest response from the server.
  44. *
  45. * @return string
  46. */
  47. public function getResponse()
  48. {
  49. return $this->lastResponse;
  50. }
  51. /**
  52. * Connect to a server.
  53. *
  54. * @return boolean
  55. */
  56. public function connect()
  57. {
  58. $this->socket = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
  59. if (!$this->socket) {
  60. $this->lastResponse = $errstr;
  61. return false;
  62. }
  63. //set timeout
  64. stream_set_timeout($this->socket, 3, 0);
  65. // check authorization
  66. return $this->authorize();
  67. }
  68. /**
  69. * Disconnect from server.
  70. *
  71. * @return void
  72. */
  73. public function disconnect()
  74. {
  75. if ($this->socket) {
  76. fclose($this->socket);
  77. }
  78. $this->authorized = false;
  79. }
  80. /**
  81. * True if socket is connected and authorized.
  82. *
  83. * @return boolean
  84. */
  85. public function isConnected()
  86. {
  87. return $this->authorized;
  88. }
  89. /**
  90. * Send a command to the connected server.
  91. *
  92. * @param string $command
  93. *
  94. * @return boolean|mixed
  95. */
  96. public function sendCommand($command)
  97. {
  98. if (!$this->isConnected()) {
  99. return false;
  100. }
  101. // send command packet
  102. $this->writePacket(self::PACKET_COMMAND, self::SERVERDATA_EXECCOMMAND, $command);
  103. // get response
  104. $response_packet = $this->readPacket();
  105. if ($response_packet['id'] == self::PACKET_COMMAND) {
  106. if ($response_packet['type'] == self::SERVERDATA_RESPONSE_VALUE) {
  107. $this->lastResponse = $response_packet['body'];
  108. return $response_packet['body'];
  109. }
  110. }
  111. return false;
  112. }
  113. /**
  114. * Log into the server with the given credentials.
  115. *
  116. * @return boolean
  117. */
  118. private function authorize()
  119. {
  120. $this->writePacket(self::PACKET_AUTHORIZE, self::SERVERDATA_AUTH, $this->password);
  121. $response_packet = $this->readPacket();
  122. if ($response_packet['type'] == self::SERVERDATA_AUTH_RESPONSE) {
  123. if ($response_packet['id'] == self::PACKET_AUTHORIZE) {
  124. $this->authorized = true;
  125. return true;
  126. }
  127. }
  128. $this->disconnect();
  129. return false;
  130. }
  131. /**
  132. * Writes a packet to the socket stream.
  133. *
  134. * @param $packetId
  135. * @param $packetType
  136. * @param string $packetBody
  137. *
  138. * @return void
  139. */
  140. private function writePacket($packetId, $packetType, $packetBody)
  141. {
  142. /*
  143. Size 32-bit little-endian Signed Integer Varies, see below.
  144. ID 32-bit little-endian Signed Integer Varies, see below.
  145. Type 32-bit little-endian Signed Integer Varies, see below.
  146. Body Null-terminated ASCII String Varies, see below.
  147. Empty String Null-terminated ASCII String 0x00
  148. */
  149. //create packet
  150. $packet = pack('VV', $packetId, $packetType);
  151. $packet = $packet.$packetBody."\x00";
  152. $packet = $packet."\x00";
  153. // get packet size.
  154. $packet_size = strlen($packet);
  155. // attach size to packet.
  156. $packet = pack('V', $packet_size).$packet;
  157. // write packet.
  158. fwrite($this->socket, $packet, strlen($packet));
  159. }
  160. /**
  161. * Read a packet from the socket stream.
  162. *
  163. * @return array
  164. */
  165. private function readPacket()
  166. {
  167. //get packet size.
  168. $size_data = fread($this->socket, 4);
  169. $size_pack = unpack('V1size', $size_data);
  170. $size = $size_pack['size'];
  171. // if size is > 4096, the response will be in multiple packets.
  172. // this needs to be address. get more info about multi-packet responses
  173. // from the RCON protocol specification at
  174. // https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
  175. // currently, this script does not support multi-packet responses.
  176. $packet_data = fread($this->socket, $size);
  177. $packet_pack = unpack('V1id/V1type/a*body', $packet_data);
  178. return $packet_pack;
  179. }
  180. }