Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.61 KB | None | 0 0
  1. <?php
  2.  
  3. // P.S. Kad man nav ko darit, es rakstu datoram instrukcijas.
  4. // Čau Signe!
  5.  
  6. /**
  7. * SAMP Query Script
  8. *
  9. * @author Chris-Prime
  10. */
  11.  
  12. class Buffer {
  13.  
  14. protected $socket;
  15.  
  16. public function __construct($socket, $trimHeader = true) {
  17. $this->socket = $socket;
  18. if($trimHeader) {
  19. $this->read(11);
  20. }
  21. }
  22.  
  23. public function read($length) {
  24. return fread($this->socket, $length);
  25. }
  26.  
  27. public function readInt($bytes) {
  28. return ord($this->read($bytes));
  29. }
  30.  
  31. }
  32.  
  33. class SampQueryAPI {
  34.  
  35. const INFO = 'i';
  36. const PING = 'p';
  37. const BASIC_PLAYERS = 'c';
  38. const PLAYERS = 'd';
  39. const RULES = 'r';
  40.  
  41. protected $port, $address;
  42. protected $timeout;
  43.  
  44. protected $socket;
  45.  
  46. protected $online = false;
  47.  
  48. protected $randoms = [];
  49.  
  50. public function __construct($address, $port = 7777, $timeout = 2) {
  51. $this->address = gethostbyname($address);
  52. $this->port = $port;
  53. $this->timeout = $timeout;
  54.  
  55. $this->connect();
  56. }
  57.  
  58. public function connect($test = true) {
  59. $this->socket = @fsockopen("udp://".$this->address, $this->port, $errno, $errstr, $this->timeout);
  60. if(!$this->socket) {
  61. throw new \Exception("Couldn't open socket [$errno]: $errstr");
  62. }
  63.  
  64. socket_set_timeout($this->socket, $this->timeout);
  65.  
  66. if($test) {
  67. $packet = 'SAMP';
  68. $packet .= chr(strtok($this->address, '.'));
  69. $packet .= chr(strtok('.'));
  70. $packet .= chr(strtok('.'));
  71. $packet .= chr(strtok('.'));
  72. $packet .= chr($this->port & 0xFF);
  73. $packet .= chr($this->port >> 8 & 0xFF);
  74. $packet .= 'p4150';
  75.  
  76. fwrite($this->socket, $packet);
  77.  
  78. if(fread($this->socket, 10))
  79. {
  80. if(fread($this->socket, 5) == 'p4150')
  81. {
  82. $this->online = true;
  83. return;
  84. }
  85. }
  86.  
  87. $this->online = false;
  88. }
  89. }
  90.  
  91. public function isOnline() {
  92. return $this->online;
  93. }
  94.  
  95. public function getInfo() {
  96. $this->sendPacket($this->buildPacket(self::INFO));
  97. $buf = new Buffer($this->socket, true);
  98. $d = array();
  99. $d["Password"] = $buf->readInt(1);
  100. $d["Players"] = $buf->readInt(2);
  101. $d["MaxPlayers"] = $buf->readInt(2);
  102. $d["Hostname"] = $buf->read($buf->readInt(4));
  103. $d["Gamemode"] = $buf->read($buf->readInt(4));
  104. $d["Mapname"] = $buf->read($buf->readInt(4));
  105. return $d;
  106. }
  107.  
  108. public function getPing() {
  109. $n = microtime(true);
  110. $this->sendPacket($this->buildPacket(self::PING));
  111. $buf = new Buffer($this->socket, true);
  112. $d = ["Ping" => microtime(true) - $n];
  113. foreach ($this->randoms as $k => $r) {
  114. $rr = $buf->readInt(1);
  115. if($rr !== $r) {
  116. throw new \Exception("Ping number mismatch ($k: $r !== $rr)!");
  117. }
  118. }
  119. return $d;
  120. }
  121.  
  122. public function getRules() {
  123. $this->sendPacket($this->buildPacket(self::RULES));
  124. $d = [];
  125. $buf = new Buffer($this->socket, true);
  126. $d["Rules"] = [];
  127. $rc = $buf->readInt(2);
  128. for($i = 0; $i < $rc; $i++) {
  129. $d["Rules"][$i]["Rulename"] = $buf->read($buf->readInt(1));
  130. $d["Rules"][$i]["Value"] = $buf->read($buf->readInt(1));
  131. }
  132. return $d;
  133. }
  134.  
  135. public function getBasicPlayers() {
  136. $this->sendPacket($this->buildPacket(self::BASIC_PLAYERS));
  137. $buf = new Buffer($this->socket);
  138. $d = [];
  139. $iPlayerCount = $buf->readInt(2);
  140. if($iPlayerCount > 0)
  141. {
  142. for($iIndex = 0; $iIndex < $iPlayerCount; ++$iIndex)
  143. {
  144. $iStrlen = $buf->readInt(1);
  145. $d[] = array
  146. (
  147. "nickname" => $buf->read($iStrlen),
  148. "score" => $buf->readInt(4),
  149. );
  150. }
  151. }
  152. return $d;
  153. }
  154.  
  155. public function getPlayers() {
  156. $this->sendPacket($this->buildPacket(self::PLAYERS));
  157. $buf = new Buffer($this->socket);
  158. $d = [];
  159. $iPlayerCount = $buf->readInt(2);
  160. for ($i=0; $i < $iPlayerCount; $i++) {
  161. $d["Players"][$i]["PlayerID"] = $buf->readInt(1);
  162. $d["Players"][$i]["PlayerNick"] = $buf->read($buf->readInt(1));
  163. $d["Players"][$i]["Score"] = $buf->readInt(4);
  164. $d["Players"][$i]["Ping"] = $buf->readInt(4);
  165. }
  166. return $d;
  167. }
  168.  
  169. public function buildPacket($opcode) {
  170. $bin = "SAMP";
  171. foreach (explode(".", $this->address) as $byte) {
  172. $bin .= chr($byte);
  173. }
  174. $bin .= chr($this->port & 0xFF);
  175. $bin .= chr($this->port >> 8 & 0xFF);
  176. $bin .= $opcode;
  177. if($opcode === self::PING) { // If sending a ping packet
  178. for($i = 0; $i < 4; $i++) {
  179. $bin .= chr($this->randoms[$i] = mt_rand(0, 255));
  180. }
  181. }
  182. return $bin;
  183. }
  184.  
  185. public function sendPacket($packet) {
  186. if(!$this->isOnline()) throw new Exception("Can't send packet to offline server");
  187. fwrite($this->socket, $packet);
  188. }
  189.  
  190. public function disconnect() {
  191. @fclose($this->socket);
  192. }
  193.  
  194. }
  195.  
  196. $s = new SampQueryAPI("rp.samp.lv", 7777, 5);
  197.  
  198. echo "<pre>";
  199. if($s->isOnline()) {
  200. var_dump($s->getInfo());
  201. var_dump($s->getPing());
  202. var_dump($s->getPlayers());
  203. var_dump($s->getBasicPlayers());
  204. var_dump($s->getRules());
  205. } else {
  206. die("Can't connect");
  207. }
  208.  
  209. $s->disconnect();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement