Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rcon.class.php 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. /*
  3. Basic CS:S Rcon class by Freman. (V1.00)
  4. ----------------------------------------------
  5. Ok, it's a completely working class now with with multi-packet responses
  6. 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")
  7. Behaviour I've noticed:
  8. rcon is not returning the packet id.
  9. */
  10. define("SERVERDATA_EXECCOMMAND",2);
  11. define("SERVERDATA_AUTH",3);
  12. class RCon {
  13. var $Password;
  14. var $Host;
  15. var $Port = 27015;
  16. var $_Sock = null;
  17. var $_Id = 0;
  18. function RCon ($Host,$Port,$Password) {
  19. $this->Password = $Password;
  20. $this->Host = $Host;
  21. $this->Port = $Port;
  22. $this->_Sock = @fsockopen($this->Host,$this->Port, $errno, $errstr, 30) or
  23. die("Unable to open socket: $errstr ($errno)\n");
  24. $this->_Set_Timeout($this->_Sock,2,500);
  25. }
  26. function Auth () {
  27. $PackID = $this->_Write(SERVERDATA_AUTH,$this->Password);
  28. // Real response (id: -1 = failure)
  29. $ret = $this->_PacketRead();
  30. if ($ret[1]['id'] == -1) {
  31. die("Authentication Failure\n");
  32. }
  33. }
  34. function _Set_Timeout(&$res,$s,$m=0) {
  35. if (version_compare(phpversion(),'4.3.0','<')) {
  36. return socket_set_timeout($res,$s,$m);
  37. }
  38. return stream_set_timeout($res,$s,$m);
  39. }
  40. function _Write($cmd, $s1='', $s2='') {
  41. // Get and increment the packet id
  42. $id = ++$this->_Id;
  43. // Put our packet together
  44. $data = pack("VV",$id,$cmd).$s1.chr(0).$s2.chr(0);
  45. // Prefix the packet size
  46. $data = pack("V",strlen($data)).$data;
  47. // Send packet
  48. fwrite($this->_Sock,$data,strlen($data));
  49. // In case we want it later we'll return the packet id
  50. return $id;
  51. }
  52. function _PacketRead() {
  53. //Declare the return array
  54. $retarray = array();
  55. //Fetch the packet size
  56. while ($size = @fread($this->_Sock,4)) {
  57. $size = unpack('V1Size',$size);
  58. //Work around valve breaking the protocol
  59. if ($size["Size"] > 4096) {
  60. //pad with 8 nulls
  61. $packet = "\x00\x00\x00\x00\x00\x00\x00\x00".fread($this->_Sock,4096);
  62. } else {
  63. //Read the packet back
  64. $packet = fread($this->_Sock,$size["Size"]);
  65. }
  66. array_push($retarray,unpack("V1ID/V1Response/a*S1/a*S2",$packet));
  67. }
  68. return $retarray;
  69. }
  70. function Read() {
  71. $Packets = $this->_PacketRead();
  72. foreach($Packets as $pack) {
  73. if (isset($ret[$pack['ID']])) {
  74. $ret[$pack['ID']]['S1'] .= $pack['S1'];
  75. $ret[$pack['ID']]['S2'] .= $pack['S1'];
  76. } else {
  77. $ret[$pack['ID']] = array(
  78. 'Response' => $pack['Response'],
  79. 'S1' => $pack['S1'],
  80. 'S2' => $pack['S2'],
  81. );
  82. }
  83. }
  84. return $ret;
  85. }
  86. function sendCommand($Command) {
  87. $Command = '"'.trim(str_replace(' ','" "', $Command)).'"';
  88. $this->_Write(SERVERDATA_EXECCOMMAND,$Command,'');
  89. }
  90. function rconCommand($Command) {
  91. $this->sendcommand($Command);
  92. $ret = $this->Read();
  93. //ATM: Source servers don't return the request id, but if they fix this the code below should read as
  94. // return $ret[$this->_Id]['S1'];
  95. return $ret[0]['S1'];
  96. }
  97. }
  98. ?>