<?php//This class connects PHP with SA:MP Servers (v0.1)//Original file: http://team.sa-mp.com/sampqry.php.txt//PHP >= 5class SAMP_Socket{ //By jose.rob.jr //Set the address to connect, can be IP or Host var $addr=""; //Set The port to connect var $port=0; //Generate or not XML Document var $xml=false; //Give the last result var $last=array(); //Try to get the IP/Host (may be slow) var $getHost=false; //Private variables private $give=1; private $fp; private $ini=""; private $Txml=false; //Read an address, you can call without parameters if you have set $addr has the exemple in the bottom function read($addr=null,$port=null,$xml=null){ //This function sets a time limit to complete the page //the connection will never ends if the server is down without this. //This function changes the Content-Type header to application/xml if xml is set to true //If you don't want it, you can print anything (a blank space for exemple) before calling read() //or setting returnXml instead and reading the array from $last //This function won't show PHP Erros when xml is set to true set_time_limit(20); $last=&$this->last; $fp=&$this->fp; $this->Txml=&$xml; if(!$addr&&!$this->addr) $this->erro("Called ".__CLASS__."::open() without setting an address.",true); if(!$addr&&$this->addr) $addr=$this->addr; elseif($addr&&!$this->addr) $this->addr=$addr; if(preg_match('/^.*\:[0-9]+$/',$addr)){ $port=substr(strrchr($addr,":"),1); $this->port=$port; $addr=preg_replace('/^(.*):[0-9]+$/','\1',$addr); $this->addr=$addr; } elseif(!$port&&$this->port) $port=$this->port; elseif($port&&!$this->port) $this->port=$port; else{ $port=7777; $this->port=$port; } if(preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$addr)){ if($this->getHost){ $host=getHostByAddr($addr); if($host==getHostByName($host)) $host=$addr; } else{ $host="ignored"; } $ip=$addr; } else{ if($this->getHost) $ip=getHostByName($addr); else $ip=$addr; $host=$addr; } if($xml===null) $xml=$this->xml; if($xml){ @header("Content-Type: application/xml"); $this->ini=@ini_get('display_errors'); @ini_set('display_errors','0'); } if($this->give==2){ ob_start(); if($xml===true) $xml=2; else $xml=1; } if($xml) echo "<"."?xml version='1.0' encoding='iso-8859-1'?"."><server>"; $fp = @fsockopen('udp://' . $ip, $port, $errno, $errstr,3) or $this->erro($errstr,__LINE__,__FILE__,$errno); if($fp){ $packet = 'SAMP'; $packet .= chr(strtok($ip, '.')); $packet .= chr(strtok('.')); $packet .= chr(strtok('.')); $packet .= chr(strtok('.')); $packet .= chr($port & 0xFF); $packet .= chr($port >> 8 & 0xFF); fwrite($fp, $packet.'i'); stream_set_timeout($fp,10); fread($fp, 11); $conInfo=stream_get_meta_data($fp); if($conInfo['timed_out']){ $this->erro("Connection timed out!"); } else{ $is_passworded = ord(fread($fp, 1)); $plr_count = ord(fread($fp, 2)); $max_plrs = ord(fread($fp, 2)); $strlen = ord(fread($fp, 4)); $hostname = fread($fp, $strlen); $strlen = ord(fread($fp, 4)); $gamemode = fread($fp, $strlen); $strlen = ord(fread($fp, 4)); $mapname = fread($fp, $strlen); $last['server']['ip']=$ip; $last['server']['host']=$host; $last['server']['hostname']=$hostname; $last['server']['mode']=$gamemode; $last['server']['mapa']=$mapname; $last['server']['passworded']=(bool)$is_passworded; $last['server']['players']['atual']=$plr_count; $last['server']['players']['maximo']=$max_plrs; if(!preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$ip)) $ip="ignored"; if($xml){ echo '<hostname>' . htmlentities($hostname) . '</hostname>'; echo '<ip>' . $ip.($ip!='ignored'?":$port":'') . "</ip>"; echo '<host>'. $host.($host!='ignored'?":$port":'') . '</host>'; echo '<mode>' . htmlentities($gamemode) . '</mode>'; echo '<mapa>' . htmlentities($mapname) . '</mapa>'; echo '<passworded>'; if ($is_passworded){ echo 'yes'; } else { echo 'no'; } echo '</passworded>'; echo '<players><atual>' . htmlentities($plr_count) . '</atual><max>' . htmlentities($max_plrs) . '</max>'; } fwrite($fp, $packet.'c'); fread($fp, 11); $plr_count = ord(fread($fp, 2)); if($xml) echo '<lista>'; if ($plr_count > 0) { for ($i=0; $i<$plr_count; $i++) { $strlen = ord(fread($fp, 1)); $plrname = fread($fp, $strlen); $score = $this->samp_getLong(fread($fp, 4)); $last['server']['players']['lista'][$i]['nick']=$plrname; $last['server']['players']['lista'][$i]['score']=$score; if($xml) echo '<player><nick>' . htmlentities($plrname) . '</nick><score>' . htmlentities($score) . '</score></player>'; } } if($xml) echo '</lista></players>'; } fclose($fp); } if($xml) echo "</server>"; if($xml){ @ini_set("display_errors",$this->ini); $this->ini=""; } if($xml===1){ $ret=ob_get_contents(); ob_end_clean(); $this->Txml=false; return $ret; } elseif($xml===2){ $ret=ob_get_contents(); ob_end_flush(); $this->Txml=false; return $ret; } $this->Txml=false; return $last; } //This function does the read function print an XML File when called function xml(){ $this->xml=true; } //This does the inverse of xml() function notXml(){ $this->xml=false; } //This function does the read function return an array function returnArray(){ $this->give=1; } //This function does the read function return an XML File function returnXml(){ $this->give=2; } //This function does the read function trys to get IP/Host address (may be slow) function getHost(){ $this->getHost=true; } //This function does the read function just get the information without trying to get the IP/Host Address function notGetHost(){ $this->getHost=false; } //Private functions private function erro($string,$line=null,$file=null,$number=null,$die=false){ if($line===true){ $line=null; $die=true; } if($this->Txml) echo "<erros><fatal>Socket Error: ".htmlentities($string).($number!==null?" (#".htmlentities($number).")":'').($file?" in $file":'').($line?" on line $line":'')."</fatal></erros>"; else echo "<br/>\r\n<b>Socket Error:</b> ".htmlentities($string).($number!==null?" (#".htmlentities($number).")":'').($file?" in <b>$file</b>":'').($line?" on line <b>$line</b>":'')."<br/>\r\n"; if($die) die(); } private function samp_getLong($dat) { $num=0; if((ord(substr($dat,3,1)) & 128) > 0) { for ($i=0; $i<strlen($dat); $i++) { $num-=((255-ord(substr($dat,$i,1))) << 8*$i); } $num--; } else { for ($i=0; $i<strlen($dat); $i++) { $num+=(ord(substr($dat,$i,1)) << 8*$i); } } return $num; }}//Exemples:/*$samp=new SAMP_Socket;$info=$samp->read("66.197.126.19:7777");@header("Content-Type: text/plain");print_r($info);*/ /*$samp=new SAMP_Socket;$info=$samp->read("66.197.126.19",7777,true);*/ /*$samp=new SAMP_Socket;$samp->xml();$samp->read("66.197.126.19",7777);*/ /*$samp=new SAMP_Socket;$samp->xml();$samp->getHost();$samp->read("66.197.126.19");*/ /*$samp=new SAMP_Socket;$samp->addr="66.197.126.19";$samp->port=7777;$samp->xml();$samp->read();*/ /* $samp=new SAMP_Socket;$samp->returnXml();$xml=$samp->read("66.197.126.19:7777");echo"<html><head><title>Exemple -- SAMP Socket</title></head><body style='text-align: center;'><form><textarea rows='10' cols='100'>$xml</textarea></form></body></html>"*/?>