Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- // P.S. Kad man nav ko darit, es rakstu datoram instrukcijas.
- // Čau Signe!
- /**
- * SAMP Query Script
- *
- * @author Chris-Prime
- */
- class Buffer {
- protected $socket;
- public function __construct($socket, $trimHeader = true) {
- $this->socket = $socket;
- if($trimHeader) {
- $this->read(11);
- }
- }
- public function read($length) {
- return fread($this->socket, $length);
- }
- public function readInt($bytes) {
- return ord($this->read($bytes));
- }
- }
- class SampQueryAPI {
- const INFO = 'i';
- const PING = 'p';
- const BASIC_PLAYERS = 'c';
- const PLAYERS = 'd';
- const RULES = 'r';
- protected $port, $address;
- protected $timeout;
- protected $socket;
- protected $online = false;
- protected $randoms = [];
- public function __construct($address, $port = 7777, $timeout = 2) {
- $this->address = gethostbyname($address);
- $this->port = $port;
- $this->timeout = $timeout;
- $this->connect();
- }
- public function connect($test = true) {
- $this->socket = @fsockopen("udp://".$this->address, $this->port, $errno, $errstr, $this->timeout);
- if(!$this->socket) {
- throw new \Exception("Couldn't open socket [$errno]: $errstr");
- }
- socket_set_timeout($this->socket, $this->timeout);
- if($test) {
- $packet = 'SAMP';
- $packet .= chr(strtok($this->address, '.'));
- $packet .= chr(strtok('.'));
- $packet .= chr(strtok('.'));
- $packet .= chr(strtok('.'));
- $packet .= chr($this->port & 0xFF);
- $packet .= chr($this->port >> 8 & 0xFF);
- $packet .= 'p4150';
- fwrite($this->socket, $packet);
- if(fread($this->socket, 10))
- {
- if(fread($this->socket, 5) == 'p4150')
- {
- $this->online = true;
- return;
- }
- }
- $this->online = false;
- }
- }
- public function isOnline() {
- return $this->online;
- }
- public function getInfo() {
- $this->sendPacket($this->buildPacket(self::INFO));
- $buf = new Buffer($this->socket, true);
- $d = array();
- $d["Password"] = $buf->readInt(1);
- $d["Players"] = $buf->readInt(2);
- $d["MaxPlayers"] = $buf->readInt(2);
- $d["Hostname"] = $buf->read($buf->readInt(4));
- $d["Gamemode"] = $buf->read($buf->readInt(4));
- $d["Mapname"] = $buf->read($buf->readInt(4));
- return $d;
- }
- public function getPing() {
- $n = microtime(true);
- $this->sendPacket($this->buildPacket(self::PING));
- $buf = new Buffer($this->socket, true);
- $d = ["Ping" => microtime(true) - $n];
- foreach ($this->randoms as $k => $r) {
- $rr = $buf->readInt(1);
- if($rr !== $r) {
- throw new \Exception("Ping number mismatch ($k: $r !== $rr)!");
- }
- }
- return $d;
- }
- public function getRules() {
- $this->sendPacket($this->buildPacket(self::RULES));
- $d = [];
- $buf = new Buffer($this->socket, true);
- $d["Rules"] = [];
- $rc = $buf->readInt(2);
- for($i = 0; $i < $rc; $i++) {
- $d["Rules"][$i]["Rulename"] = $buf->read($buf->readInt(1));
- $d["Rules"][$i]["Value"] = $buf->read($buf->readInt(1));
- }
- return $d;
- }
- public function getBasicPlayers() {
- $this->sendPacket($this->buildPacket(self::BASIC_PLAYERS));
- $buf = new Buffer($this->socket);
- $d = [];
- $iPlayerCount = $buf->readInt(2);
- if($iPlayerCount > 0)
- {
- for($iIndex = 0; $iIndex < $iPlayerCount; ++$iIndex)
- {
- $iStrlen = $buf->readInt(1);
- $d[] = array
- (
- "nickname" => $buf->read($iStrlen),
- "score" => $buf->readInt(4),
- );
- }
- }
- return $d;
- }
- public function getPlayers() {
- $this->sendPacket($this->buildPacket(self::PLAYERS));
- $buf = new Buffer($this->socket);
- $d = [];
- $iPlayerCount = $buf->readInt(2);
- for ($i=0; $i < $iPlayerCount; $i++) {
- $d["Players"][$i]["PlayerID"] = $buf->readInt(1);
- $d["Players"][$i]["PlayerNick"] = $buf->read($buf->readInt(1));
- $d["Players"][$i]["Score"] = $buf->readInt(4);
- $d["Players"][$i]["Ping"] = $buf->readInt(4);
- }
- return $d;
- }
- public function buildPacket($opcode) {
- $bin = "SAMP";
- foreach (explode(".", $this->address) as $byte) {
- $bin .= chr($byte);
- }
- $bin .= chr($this->port & 0xFF);
- $bin .= chr($this->port >> 8 & 0xFF);
- $bin .= $opcode;
- if($opcode === self::PING) { // If sending a ping packet
- for($i = 0; $i < 4; $i++) {
- $bin .= chr($this->randoms[$i] = mt_rand(0, 255));
- }
- }
- return $bin;
- }
- public function sendPacket($packet) {
- if(!$this->isOnline()) throw new Exception("Can't send packet to offline server");
- fwrite($this->socket, $packet);
- }
- public function disconnect() {
- @fclose($this->socket);
- }
- }
- $s = new SampQueryAPI("rp.samp.lv", 7777, 5);
- echo "<pre>";
- if($s->isOnline()) {
- var_dump($s->getInfo());
- var_dump($s->getPing());
- var_dump($s->getPlayers());
- var_dump($s->getBasicPlayers());
- var_dump($s->getRules());
- } else {
- die("Can't connect");
- }
- $s->disconnect();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement