04.12.2014, 12:47
(
Last edited by mrsh; 18/02/2016 at 11:36 AM.
)
SAMP Server Status PHP v1.1B
Ajax Version (High Performance Servers):
PHP Code:
<?php
$serverIP = "10.20.30.40";
$serverPort = 7777;
?>
<html oncontextmenu="return false">
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css">
<div class="wrapper" id="weapper">
<center>
<?php
function sanitize_output($buffer) {
$search = array(
'/\>[^\S ]+/s', // strip whitespaces after tags, except space
'/[^\S ]+\</s', // strip whitespaces before tags, except space
'/(\s)+/s' // shorten multiple whitespace sequences
);
$replace = array(
'>',
'<',
'\\1'
);
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
}
ob_start("sanitize_output");
class QueryServer
{
// Private variables used for the query-ing.
private $szServerIP;
private $iPort;
private $rSocketID;
private $bStatus;
// The __construct function gets called automatically
// by PHP once the class gets initialized.
function __construct( $szServerIP, $iPort )
{
$this->szServerIP = $this->VerifyAddress( $szServerIP );
$this->iPort = $iPort;
if (empty( $this->szServerIP ) || !is_numeric( $iPort )) {
throw new QueryServerException( 'Either the ip-address or the port isn\'t filled in correctly.' );
}
$this->rSocketID = @fsockopen( 'udp://' . $this->szServerIP, $iPort, $iErrorNo, $szErrorStr, 5 );
if (!$this->rSocketID) {
throw new QueryServerException( 'Cannot connect to the server: ' . $szErrorStr );
}
socket_set_timeout( $this->rSocketID, 0, 500000 );
$this->bStatus = true;
}
// The VerifyAddress function verifies the given hostname/
// IP address and returns the actual IP Address.
function VerifyAddress( $szServerIP )
{
if (ip2long( $szServerIP ) !== false &&
long2ip( ip2long( $szServerIP ) ) == $szServerIP ) {
return $szServerIP;
}
$szAddress = gethostbyname( $szServerIP );
if ($szAddress == $szServerIP) {
return "";
}
return $szAddress;
}
// The SendPacket function sends a packet to the server which
// requests information, based on the type of packet send.
function SendPacket( $cPacket )
{
$szPacket = 'SAMP';
$aIpChunks = explode( '.', $this->szServerIP );
foreach( $aIpChunks as $szChunk ) {
$szPacket .= chr( $szChunk );
}
$szPacket .= chr( $this->iPort & 0xFF );
$szPacket .= chr( $this->iPort >> 8 & 0xFF );
$szPacket .= $cPacket;
return fwrite( $this->rSocketID, $szPacket, strlen( $szPacket ) );
}
// The GetPacket() function returns a specific number of bytes
// read from the socket. This uses a special way of getting stuff.
function GetPacket( $iBytes )
{
$iResponse = fread( $this->rSocketID, $iBytes );
if ($iResponse === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$iLength = ord( $iResponse );
if ($iLength > 0)
return fread( $this->rSocketID, $iLength );
return "";
}
// After we're done, the connection needs to be closed using
// the Close() function. Otherwise stuff might go wrong.
function Close( )
{
if ($this->rSocketID !== false) {
fclose( $this->rSocketID );
}
}
// A little function that's needed to properly convert the
// four bytes we're recieving to integers to an actual PHP
// integer. ord() can't handle value's higher then 255.
function toInteger( $szData )
{
$iInteger = 0;
$iInteger += ( ord( @$szData[ 0 ] ) );
$iInteger += ( ord( @$szData[ 1 ] ) << 8 );
$iInteger += ( ord( @$szData[ 2 ] ) << 16 );
$iInteger += ( ord( @$szData[ 3 ] ) << 24 );
if( $iInteger >= 4294967294 )
$iInteger -= 4294967296;
return $iInteger;
}
// The GetInfo() function returns basic information about the
// server, like the hostname, number of players online etc.
function GetInfo( )
{
if ($this->SendPacket('i') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$szFirstData = fread( $this->rSocketID, 4 );
if (empty( $szFirstData ) || $szFirstData != 'SAMP') {
throw new QueryServerException( 'The server at ' . $this->szServerIP . ' is not an SA-MP Server.' );
}
// Pop the first seven characters returned.
fread( $this->rSocketID, 7 );
return array (
'Password' => ord( fread( $this->rSocketID, 1 ) ),
'Players' => $this->toInteger( fread( $this->rSocketID, 2 ) ),
'MaxPlayers' => $this->toInteger( fread( $this->rSocketID, 2 ) ),
'Hostname' => $this->GetPacket( 4 ),
'Gamemode' => $this->GetPacket( 4 ),
'Map' => $this->GetPacket( 4 )
);
}
// The GetRules() function returns the rules which are set
// on the server, e.g. the gravity, version etcetera.
function GetRules( )
{
if ($this->SendPacket('r') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Pop the first 11 bytes from the response;
fread( $this->rSocketID, 11 );
$iRuleCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iRuleCount; $i ++ ) {
$szRuleName = $this->GetPacket( 1 );
$aReturnArray[ $szRuleName ] = $this->GetPacket( 1 );
}
return $aReturnArray;
}
// The GetPlayers() function is pretty much simelar to the
// detailed function, but faster and contains less information.
function GetPlayers( )
{
if ($this->SendPacket('c') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Again, pop the first eleven bytes send;
fread( $this->rSocketID, 11 );
$iPlayerCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iPlayerCount; $i ++ )
{
$aReturnArray[ ] = array (
'Nickname' => $this->GetPacket( 1 ),
'Score' => $this->toInteger( fread( $this->rSocketID, 4 ) )
);
}
return $aReturnArray;
}
// The GetDetailedPlayers() function returns the player list,
// but in a detailed form inclusing the score and the ping.
function GetDetailedPlayers( )
{
if ($this->SendPacket('d') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Skip the first 11 bytes of the response;
fread( $this->rSocketID, 11 );
$iPlayerCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iPlayerCount; $i ++ ) {
$aReturnArray[ ] = array(
'PlayerID' => $this->toInteger( fread( $this->rSocketID, 1 ) ),
'Nickname' => $this->GetPacket( 1 ),
'Score' => $this->toInteger( fread( $this->rSocketID, 4 ) ),
'Ping' => $this->toInteger( fread( $this->rSocketID, 4 ) )
);
}
return $aReturnArray;
}
function RCON($rcon, $command)
{
echo 'Password '.$rcon.' with '.$command;
if ($this->SendPacket('x '.$rcon.' '.$command) === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$aReturnArray = fread( $this->rSocketID, 11 );
echo fread( $this->rSocketID, 11 );
return $aReturnArray;
}
}
class QueryServerException extends Exception
{
private $szMessage;
function __construct( $szMessage )
{
$this->szMessage = $szMessage;
}
function toString( )
{
return $this->szMessage;
}
}
try
{
$rQuery = new QueryServer( $serverIP, $serverPort );
$aInformation = $rQuery->GetInfo( );
$aServerRules = $rQuery->GetRules( );
$aBasicPlayer = $rQuery->GetPlayers( );
$aTotalPlayers = $rQuery->GetDetailedPlayers( );
$rQuery->Close( );
}
catch (QueryServerException $pError)
{
echo 'ERROR!';
}
if(isset($aInformation) && is_array($aInformation)){
?>
<title>Server Status --> <?php echo htmlentities($aInformation['Hostname']); ?></title>
<b>General Information</b>
<table class="pure-table pure-table-horizontal">
<tr>
<td>Hostname</td>
<td><?php echo htmlentities($aInformation['Hostname']); ?></td>
</tr>
<tr>
<td>Gamemode</td>
<td><?php echo htmlentities($aInformation['Gamemode']); ?></td>
</tr>
<tr>
<td>Players</td>
<td><?php echo $aInformation['Players']; ?> / <?php echo $aInformation['MaxPlayers']; ?></td>
</tr>
<tr>
<td>Map</td>
<td><?php echo htmlentities($aInformation['Map']); ?></td>
</tr>
<tr>
<td>Weather</td>
<td><?php echo $aServerRules['weather']; ?></td>
</tr>
<tr>
<td>Time</td>
<td><?php echo $aServerRules['worldtime']; ?></td>
</tr>
<tr>
<td>Version</td>
<td><?php echo $aServerRules['version']; ?></td>
</tr>
<tr>
<td>Password</td>
<td><?php echo $aInformation['Password'] ? 'Yes' : 'No'; ?></td>
</tr>
</table>
<br />
<?php
if(!is_array($aTotalPlayers) || count($aTotalPlayers) == 0){
echo '<br /><i>None / Can not give stats. (It is too high)</i>';
} else {
?>
<b>Online Players</b>
<table class="pure-table pure-table-bordered">
<tr class="pure-table-odd">
<td><b>ID</b></td>
<td><b>Nickname</b></td>
<td><b>Score</b></td>
<td><b>Ping</b></td>
</tr>
<?php
foreach($aTotalPlayers AS $id => $value){
?>
<tr>
<td><?php echo $value['PlayerID']; ?></td>
<td><?php echo htmlentities($value['Nickname']); ?></td>
<td><?php echo $value['Score']; ?></td>
<td><?php echo $value['Ping']; ?></td>
</tr>
<?php
}
echo '</table>';
}
}
?></div><script src="//code.jquery.com/jquery-1.11.0.min.js"></script><script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script> <script type="text/javascript">function Load_external_content() {$('.wrapper').load('index.php');} setInterval('Load_external_content()',1000);</script>
PHP Code:
<?php
$serverIP = "10.20.30.40";
$serverPort = 7777;
?>
<html oncontextmenu="return false">
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css">
<div class="wrapper" id="weapper">
<center>
<?php
function sanitize_output($buffer) {
$search = array(
'/\>[^\S ]+/s', // strip whitespaces after tags, except space
'/[^\S ]+\</s', // strip whitespaces before tags, except space
'/(\s)+/s' // shorten multiple whitespace sequences
);
$replace = array(
'>',
'<',
'\\1'
);
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
}
ob_start("sanitize_output");
class QueryServer
{
// Private variables used for the query-ing.
private $szServerIP;
private $iPort;
private $rSocketID;
private $bStatus;
// The __construct function gets called automatically
// by PHP once the class gets initialized.
function __construct( $szServerIP, $iPort )
{
$this->szServerIP = $this->VerifyAddress( $szServerIP );
$this->iPort = $iPort;
if (empty( $this->szServerIP ) || !is_numeric( $iPort )) {
throw new QueryServerException( 'Either the ip-address or the port isn\'t filled in correctly.' );
}
$this->rSocketID = @fsockopen( 'udp://' . $this->szServerIP, $iPort, $iErrorNo, $szErrorStr, 5 );
if (!$this->rSocketID) {
throw new QueryServerException( 'Cannot connect to the server: ' . $szErrorStr );
}
socket_set_timeout( $this->rSocketID, 0, 500000 );
$this->bStatus = true;
}
// The VerifyAddress function verifies the given hostname/
// IP address and returns the actual IP Address.
function VerifyAddress( $szServerIP )
{
if (ip2long( $szServerIP ) !== false &&
long2ip( ip2long( $szServerIP ) ) == $szServerIP ) {
return $szServerIP;
}
$szAddress = gethostbyname( $szServerIP );
if ($szAddress == $szServerIP) {
return "";
}
return $szAddress;
}
// The SendPacket function sends a packet to the server which
// requests information, based on the type of packet send.
function SendPacket( $cPacket )
{
$szPacket = 'SAMP';
$aIpChunks = explode( '.', $this->szServerIP );
foreach( $aIpChunks as $szChunk ) {
$szPacket .= chr( $szChunk );
}
$szPacket .= chr( $this->iPort & 0xFF );
$szPacket .= chr( $this->iPort >> 8 & 0xFF );
$szPacket .= $cPacket;
return fwrite( $this->rSocketID, $szPacket, strlen( $szPacket ) );
}
// The GetPacket() function returns a specific number of bytes
// read from the socket. This uses a special way of getting stuff.
function GetPacket( $iBytes )
{
$iResponse = fread( $this->rSocketID, $iBytes );
if ($iResponse === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$iLength = ord( $iResponse );
if ($iLength > 0)
return fread( $this->rSocketID, $iLength );
return "";
}
// After we're done, the connection needs to be closed using
// the Close() function. Otherwise stuff might go wrong.
function Close( )
{
if ($this->rSocketID !== false) {
fclose( $this->rSocketID );
}
}
// A little function that's needed to properly convert the
// four bytes we're recieving to integers to an actual PHP
// integer. ord() can't handle value's higher then 255.
function toInteger( $szData )
{
$iInteger = 0;
$iInteger += ( ord( @$szData[ 0 ] ) );
$iInteger += ( ord( @$szData[ 1 ] ) << 8 );
$iInteger += ( ord( @$szData[ 2 ] ) << 16 );
$iInteger += ( ord( @$szData[ 3 ] ) << 24 );
if( $iInteger >= 4294967294 )
$iInteger -= 4294967296;
return $iInteger;
}
// The GetInfo() function returns basic information about the
// server, like the hostname, number of players online etc.
function GetInfo( )
{
if ($this->SendPacket('i') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$szFirstData = fread( $this->rSocketID, 4 );
if (empty( $szFirstData ) || $szFirstData != 'SAMP') {
throw new QueryServerException( 'The server at ' . $this->szServerIP . ' is not an SA-MP Server.' );
}
// Pop the first seven characters returned.
fread( $this->rSocketID, 7 );
return array (
'Password' => ord( fread( $this->rSocketID, 1 ) ),
'Players' => $this->toInteger( fread( $this->rSocketID, 2 ) ),
'MaxPlayers' => $this->toInteger( fread( $this->rSocketID, 2 ) ),
'Hostname' => $this->GetPacket( 4 ),
'Gamemode' => $this->GetPacket( 4 ),
'Map' => $this->GetPacket( 4 )
);
}
// The GetRules() function returns the rules which are set
// on the server, e.g. the gravity, version etcetera.
function GetRules( )
{
if ($this->SendPacket('r') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Pop the first 11 bytes from the response;
fread( $this->rSocketID, 11 );
$iRuleCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iRuleCount; $i ++ ) {
$szRuleName = $this->GetPacket( 1 );
$aReturnArray[ $szRuleName ] = $this->GetPacket( 1 );
}
return $aReturnArray;
}
// The GetPlayers() function is pretty much simelar to the
// detailed function, but faster and contains less information.
function GetPlayers( )
{
if ($this->SendPacket('c') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Again, pop the first eleven bytes send;
fread( $this->rSocketID, 11 );
$iPlayerCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iPlayerCount; $i ++ )
{
$aReturnArray[ ] = array (
'Nickname' => $this->GetPacket( 1 ),
'Score' => $this->toInteger( fread( $this->rSocketID, 4 ) )
);
}
return $aReturnArray;
}
// The GetDetailedPlayers() function returns the player list,
// but in a detailed form inclusing the score and the ping.
function GetDetailedPlayers( )
{
if ($this->SendPacket('d') === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
// Skip the first 11 bytes of the response;
fread( $this->rSocketID, 11 );
$iPlayerCount = ord( fread( $this->rSocketID, 2 ) );
$aReturnArray = array( );
for( $i = 0; $i < $iPlayerCount; $i ++ ) {
$aReturnArray[ ] = array(
'PlayerID' => $this->toInteger( fread( $this->rSocketID, 1 ) ),
'Nickname' => $this->GetPacket( 1 ),
'Score' => $this->toInteger( fread( $this->rSocketID, 4 ) ),
'Ping' => $this->toInteger( fread( $this->rSocketID, 4 ) )
);
}
return $aReturnArray;
}
function RCON($rcon, $command)
{
echo 'Password '.$rcon.' with '.$command;
if ($this->SendPacket('x '.$rcon.' '.$command) === false) {
throw new QueryServerException( 'Connection to ' . $this->szServerIP . ' failed or has dropped.' );
}
$aReturnArray = fread( $this->rSocketID, 11 );
echo fread( $this->rSocketID, 11 );
return $aReturnArray;
}
}
class QueryServerException extends Exception
{
private $szMessage;
function __construct( $szMessage )
{
$this->szMessage = $szMessage;
}
function toString( )
{
return $this->szMessage;
}
}
try
{
$rQuery = new QueryServer( $serverIP, $serverPort );
$aInformation = $rQuery->GetInfo( );
$aServerRules = $rQuery->GetRules( );
$aBasicPlayer = $rQuery->GetPlayers( );
$aTotalPlayers = $rQuery->GetDetailedPlayers( );
$rQuery->Close( );
}
catch (QueryServerException $pError)
{
echo 'ERROR!';
}
if(isset($aInformation) && is_array($aInformation)){
?>
<title>Server Status --> <?php echo htmlentities($aInformation['Hostname']); ?></title>
<b>General Information</b>
<table class="pure-table pure-table-horizontal">
<tr>
<td>Hostname</td>
<td><?php echo htmlentities($aInformation['Hostname']); ?></td>
</tr>
<tr>
<td>Gamemode</td>
<td><?php echo htmlentities($aInformation['Gamemode']); ?></td>
</tr>
<tr>
<td>Players</td>
<td><?php echo $aInformation['Players']; ?> / <?php echo $aInformation['MaxPlayers']; ?></td>
</tr>
<tr>
<td>Map</td>
<td><?php echo htmlentities($aInformation['Map']); ?></td>
</tr>
<tr>
<td>Weather</td>
<td><?php echo $aServerRules['weather']; ?></td>
</tr>
<tr>
<td>Time</td>
<td><?php echo $aServerRules['worldtime']; ?></td>
</tr>
<tr>
<td>Version</td>
<td><?php echo $aServerRules['version']; ?></td>
</tr>
<tr>
<td>Password</td>
<td><?php echo $aInformation['Password'] ? 'Yes' : 'No'; ?></td>
</tr>
</table>
<br />
<?php
if(!is_array($aTotalPlayers) || count($aTotalPlayers) == 0){
echo '<br /><i>None / Can not give stats. (It is too high)</i>';
} else {
?>
<b>Online Players</b>
<table class="pure-table pure-table-bordered">
<tr class="pure-table-odd">
<td><b>ID</b></td>
<td><b>Nickname</b></td>
<td><b>Score</b></td>
<td><b>Ping</b></td>
</tr>
<?php
foreach($aTotalPlayers AS $id => $value){
?>
<tr>
<td><?php echo $value['PlayerID']; ?></td>
<td><?php echo htmlentities($value['Nickname']); ?></td>
<td><?php echo $value['Score']; ?></td>
<td><?php echo $value['Ping']; ?></td>
</tr>
<?php
}
echo '</table>';
}
}
?></div>
PHP Code:
$serverIP = "10.20.30.40";
$serverPort = 7777;
Error's Reasons:
None / Can not give stats. (It is too high) = This problem when it happens that your players is too high (like 120players) or is too low (like 0!) For Fix this problem you need high performance server.
ERROR! = This problem when it happens that your server is offline or your server blocked connections! (for big servers) For Fix this problem you need to start your server or add your stats server in your whitelist.
Examples:
For use this in your website/forum you can use this code:
PHP Code:
<?php include 'your stats file adress.php'; ?>
Code:
<iframe src="http://server.com/your stats file adress.php" width="100%" height="100%">Your browser is **** :|</iframe>
Todo:
Quote:
Creating SA-MP stats with supporting JSON. Add language support. (0.3.7 update) |
Quote:
Fixed major bugs. |