I know for a fact that it isn't my server not being on or responding to queries because I use others on the internet and they work just fine. I am using the free webhosting, but as far as I am aware it only restricts inbound requests to the webserver, not the webserver outbound.
I am using fsockopen(), and here is the page I get.
http://www.sentinelsigma.xyz/minecraft/
It says it can open the socket, it just fails to receive the status. Any insight?
here i my code:
(from the page I posted)
Code: Select all
<?php
use xPaw\MinecraftQuery;
use xPaw\MinecraftQueryException;
require($_SERVER['DOCUMENT_ROOT'].'/_config/_vars.php');
// Edit this ->
define( 'MQ_SERVER_ADDR', $mc_ip );
define( 'MQ_SERVER_PORT', $mc_port );
define( 'MQ_TIMEOUT', 1 );
// Edit this <-
// Display everything in browser, because some people can't look in logs for errors
Error_Reporting( E_ALL | E_STRICT );
Ini_Set( 'display_errors', true );
require $_SERVER['DOCUMENT_ROOT'].'/_assets/query/MinecraftQuery.php';
require $_SERVER['DOCUMENT_ROOT'].'/_assets/query/MinecraftQueryException.php';
$Timer = MicroTime( true );
$Query = new MinecraftQuery( );
try
{
$Query->Connect( MQ_SERVER_ADDR, MQ_SERVER_PORT, MQ_TIMEOUT );
}
catch( MinecraftQueryException $e )
{
$Exception = $e;
}
$Timer = Number_Format( MicroTime( true ) - $Timer, 4, '.', '' );
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SentinelSigma Minecraft</title>
<? include($_SERVER['DOCUMENT_ROOT'].'/_config/_header.php');?>
<style type="text/css">
.table thead th {
background-color: #D9230F;
border-color: #D9230F !important;
color: #FFF;
}
body{
background-color: #F5F5F5;
}
</style>
<script>
function refresh() {
var img = document.getElementById("refresh");
img.setAttribute("class", "fa fa-refresh fa-spin");
}
</script>
</head>
<body>
<div name="top"></div>
<?php include($_SERVER['DOCUMENT_ROOT'].'/_config/_nav.php');?>
<div class="container" style="padding-top: 30px;">
<?php if( isset( $Exception ) ): ?>
<!-- <div class="panel panel-danger">
<div class="panel-heading"><i style="padding-left:8px;" class="fa fa-exclamation-triangle fa-2x" aria-hidden="true"></i><strong style="font-size:20px;"> Oh no!</strong><?php //echo htmlspecialchars( $Exception->getMessage( ) ); ?></div>
<p><?php //echo nl2br( $e->getTraceAsString(), false ); ?></p>
<div style="padding-left:8px; padding-bottom:12px;">
<h2>Something went wrong...</h2>
<p>The server could be off, or could be experiencing some technical difficulties. Try refreshing!</p>
<a style="text-align:right;" onclick="refresh()" href="javascript:history.go(0)" class="btn btn-default"><i class="fa fa-refresh" id="refresh" aria-hidden="true"></i> Refresh</a>
</div>
</div>
-->
<div class="panel panel-primary">
<div class="panel-heading"><?php echo htmlspecialchars( $Exception->getMessage( ) ); ?></div>
<p><?php echo nl2br( $e->getTraceAsString(), false ); ?></p>
</div>
<?php else: ?>
<div class="row">
<div class="col-sm-6">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th colspan="2"><i class="fa fa-dashboard" aria-hidden="true"></i> Server Info <em>(queried in <?php echo $Timer; ?>s)</em></th>
</tr>
</thead>
<tbody>
<?php if( ( $Info = $Query->GetInfo( ) ) !== false ): ?>
<?php foreach( $Info as $InfoKey => $InfoValue ): ?>
<tr class="warning">
<td><?php echo htmlspecialchars( $InfoKey ); ?></td>
<td>
<?php
if( Is_Array( $InfoValue ) )
{
echo "<pre>".implode("\n",$InfoValue)."</pre>";
}
else
{
echo htmlspecialchars( $InfoValue );
}
?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="2">No information received.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="col-sm-6">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th><i class="fa fa-users" aria-hidden="true"></i> Players</th>
</tr>
</thead>
<tbody>
<?php if( ( $Players = $Query->GetPlayers( ) ) !== false ): ?>
<?php foreach( $Players as $Player ): ?>
<tr class="warning">
<td>
<?php
echo "<img style='padding-right:12px;' src='https://minotar.net/helm/$Player/40.png'></img>";
echo "<b>";echo htmlspecialchars( $Player ); echo"</b>";
?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr class="danger">
<td>No players are connected.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<p style="text-align:center;"><a href="#join" class="btn btn-primary btn-block" role="button" data-toggle="modal" data-target="#serverInfo">Join now!</a></p>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="serverInfo" tabindex="-1" role="dialog" aria-labelledby="serverInfoLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="serverInfoLabel">Server Address</h4>
</div>
<div class="modal-body">
<h2 style="text-align:center;">Copy and paste the address to your game!</h2>
<div class="well">
<h3 style="text-align:center;"><?php echo $mc_ipSRV;?></h1>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<?php include($_SERVER['DOCUMENT_ROOT'].'/_config/_footer.php'); ?>
</div>
<?php endif; ?>
<?php include($_SERVER['DOCUMENT_ROOT'].'/_config/_lastload.php');?>
</body>
</html>
Code: Select all
<?php
namespace xPaw;
class MinecraftQuery
{
/*
* Class written by xPaw
*
* Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Minecraft-Query
*/
const STATISTIC = 0x00;
const HANDSHAKE = 0x09;
private $Socket;
private $Players;
private $Info;
public function Connect( $Ip, $Port = 25565, $Timeout = 3 )
{
if( !is_int( $Timeout ) || $Timeout < 0 )
{
throw new \InvalidArgumentException( 'Timeout must be an integer.' );
}
$this->Socket = @FSockOpen( 'udp://' . $Ip, (int)$Port, $ErrNo, $ErrStr, $Timeout );
if( $ErrNo || $this->Socket === false )
{
throw new MinecraftQueryException( 'Could not create socket: ' . $ErrStr );
}
Stream_Set_Timeout( $this->Socket, $Timeout );
Stream_Set_Blocking( $this->Socket, true );
try
{
$Challenge = $this->GetChallenge( );
$this->GetStatus( $Challenge );
}
// We catch this because we want to close the socket, not very elegant
catch( MinecraftQueryException $e )
{
FClose( $this->Socket );
throw new MinecraftQueryException( $e->getMessage( ) );
}
FClose( $this->Socket );
}
public function GetInfo( )
{
return isset( $this->Info ) ? $this->Info : false;
}
public function GetPlayers( )
{
return isset( $this->Players ) ? $this->Players : false;
}
private function GetChallenge( )
{
$Data = $this->WriteData( self :: HANDSHAKE );
if( $Data === false )
{
throw new MinecraftQueryException( 'Failed to receive challenge.' );
}
return Pack( 'N', $Data );
}
private function GetStatus( $Challenge )
{
$Data = $this->WriteData( self :: STATISTIC, $Challenge . Pack( 'c*', 0x00, 0x00, 0x00, 0x00 ) );
if( !$Data )
{
throw new MinecraftQueryException( 'Failed to receive status.' );
}
$Last = '';
$Info = Array( );
$Data = SubStr( $Data, 11 ); // splitnum + 2 int
$Data = Explode( "\x00\x00\x01player_\x00\x00", $Data );
if( Count( $Data ) !== 2 )
{
throw new MinecraftQueryException( 'Failed to parse server\'s response.' );
}
$Players = SubStr( $Data[ 1 ], 0, -2 );
$Data = Explode( "\x00", $Data[ 0 ] );
// Array with known keys in order to validate the result
// It can happen that server sends custom strings containing bad things (who can know!)
$Keys = Array(
'hostname' => 'HostName',
'gametype' => 'GameType',
'version' => 'Version',
'plugins' => 'Plugins',
'map' => 'Map',
'numplayers' => 'Players',
'maxplayers' => 'MaxPlayers',
'hostport' => 'HostPort',
'hostip' => 'HostIp',
'game_id' => 'GameName'
);
foreach( $Data as $Key => $Value )
{
if( ~$Key & 1 )
{
if( !Array_Key_Exists( $Value, $Keys ) )
{
$Last = false;
continue;
}
$Last = $Keys[ $Value ];
$Info[ $Last ] = '';
}
else if( $Last != false )
{
$Info[ $Last ] = mb_convert_encoding( $Value, 'UTF-8' );
}
}
// Ints
$Info[ 'Players' ] = IntVal( $Info[ 'Players' ] );
$Info[ 'MaxPlayers' ] = IntVal( $Info[ 'MaxPlayers' ] );
$Info[ 'HostPort' ] = IntVal( $Info[ 'HostPort' ] );
// Parse "plugins", if any
if( $Info[ 'Plugins' ] )
{
$Data = Explode( ": ", $Info[ 'Plugins' ], 2 );
$Info[ 'RawPlugins' ] = $Info[ 'Plugins' ];
$Info[ 'Software' ] = $Data[ 0 ];
if( Count( $Data ) == 2 )
{
$Info[ 'Plugins' ] = Explode( "; ", $Data[ 1 ] );
}
}
else
{
$Info[ 'Software' ] = 'Vanilla';
}
$this->Info = $Info;
if( empty( $Players ) )
{
$this->Players = null;
}
else
{
$this->Players = Explode( "\x00", $Players );
}
}
private function WriteData( $Command, $Append = "" )
{
$Command = Pack( 'c*', 0xFE, 0xFD, $Command, 0x01, 0x02, 0x03, 0x04 ) . $Append;
$Length = StrLen( $Command );
if( $Length !== FWrite( $this->Socket, $Command, $Length ) )
{
throw new MinecraftQueryException( "Failed to write on socket." );
}
$Data = FRead( $this->Socket, 4096 );
if( $Data === false )
{
throw new MinecraftQueryException( "Failed to read from socket." );
}
if( StrLen( $Data ) < 5 || $Data[ 0 ] != $Command[ 2 ] )
{
return false;
}
return SubStr( $Data, 5 );
}
}