PHP Classes

File: SAMP_Socket.class.php

Recommend this page to a friend!
  Classes of José Roberto de Araújo Júnior   SAMP Socket   SAMP_Socket.class.php   Download  
File: SAMP_Socket.class.php
Role: Class source
Content type: text/plain
Description: PHP >= 5
Class: SAMP Socket
Get details about a GTA San Andreas game server
Author: By
Last change: Bug fixed:
* Now times out if the server don't answer
* Simplified the private function erro()
Date: 17 years ago
Size: 7,953 bytes
 

Contents

Class file image Download
<?php
//This class connects PHP with SA:MP Servers (v0.1)
//Original file: http://team.sa-mp.com/sampqry.php.txt
class 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>"
*/
?>