// Öppna en "file-socket" som använder sig av protokollet UDP,
// vänta på svar i 5.0 sekunder (timouten verkar inte fungera
// om webservern kör ett win32 OS, inte heller freeBSD?)
$fp = fsockopen("udp://$ip", $port, $errno, $errstr, 5.0);
Tydligen så funkar inte timeouten mot FreeBSD servrar. Går det att på något annat sätt att få scriptet att skriva ut ett felmeddelande efter ett litet tag istället för att det ska köra i en "evighet"..?
<?php
// FUNCTIONS
///////////////////////////////////////////////
// Skapar en tid med mha. microtime
function GetMicroTime()
{
list($msec, $sec) = explode(" ", microtime());
return ($sec + $msec);
}
// Hämtar 2st bytes och gör om dem till en Int16
function getInt16($fp)
{
$data = unpack("Sshort", fread($fp, 2));
return $data['short'];
}
// Hämtar 4st byte och gör om dem till en Int32
function getInt32($fp)
{
$data = unpack("Lint", fread($fp, 4));
return $data['int'];
}
// Hämtar 4st byte och gör om dem till en Float32
function getFloat32($fp)
{
$data = unpack("ffloat", fread($fp, 4));
return $data['float'];
}
// Hämtar ett tecken och returnerar dess ASCII värde
function getByte($fp)
{
return ord(fread($fp, 1));
}
// Hämtar ett tecken och returnerar det
function getChar($fp)
{
return fread($fp, 1);
}
// Hämtar tecken för tecken tills ett NULL-tecken hittas,
// då returnerar den de hämtade teckena i form av en sträng
function getString($fp)
{
while(1) {
$rchar = fread($fp, 1);
$r_string.= $rchar;
if(ord($rchar) == 0)
break;
}
return $r_string;
}
// Hämtar tecken för tecken tills ett \ tecken hittas (eller ett nulltecken),
// då returnerar den de hämtade teckena i form av en sträng
function getSlashString($fp)
{
while(1) {
$rchar = fread($fp, 1);
$r_string.= $rchar;
if($rchar == "\\" || $rchar == "\0") {
// Ta bort slashet (ersätt det med NULL)
$r_string = str_replace("\\", "\0", $r_string);
break;
}
}
return $r_string;
}
// Skickar 4 st ÿ som motsvarar en int32 med värded -1
// följt av kommandot avslutat med ett NULL-tecken
function sendCommand($fp, $Cmd)
{
fputs($fp,"ÿÿÿÿ".$Cmd."\0");
}
// HTML START
/////////////////////////////////////////////////
?>
<html>
<head>
<title>CS - Server Info</title>
</head>
<body>
<font face="Courier">
<?php
// MAIN CODE
////////////////////////////////////////////////
// Kolla om vi har en ip och port variabel
$ip = "212.73.160.51";
$port = "27015";
if(isset($ip) && isset($port)) {
// Öppna en "file-socket" som använder sig av protokollet UDP,
// vänta på svar i 5.0 sekunder (timouten verkar inte fungera
// om webservern kör ett win32 OS, inte heller freeBSD?)
$fp = fsockopen("udp://$ip", $port, $errno, $errstr, 5.0);
if (!$fp) {
// Nått gick snett, printa ut vad som gick snett
echo "ERROR: $errno - $errstr<br>\n";
} else {
// Vi är nu connectade, kör våra kommandon
////////////////////////////////////////////
// P I N G
////////////////////////////////////////////
echo "<h3>Ping</h3>";
// Hämta tid
$s_time = GetMicroTime();
// Skicka pingkommando
sendCommand($fp, "ping");
// Ta emot svar
getInt32($fp); // Alltid -1
getChar($fp); // Alltid 'j'
getByte($fp); // NULL ???
// Mät hur lång tid det tog och skriv ut det i millisekunder
echo "Ping: <b>".round((GetMicroTime() - $s_time) * 1000)."</b><br>";
////////////////////////////////////////////
// I N F O
////////////////////////////////////////////
echo "<h3>Info</h3>";
// Skicka info kommando
sendCommand($fp, "info");
// Ta emot svar
getInt32($fp); // Alltid -1
getChar($fp); // Alltid 'C'
echo "Net address of server: <b>".getString($fp)."</b><br>";
echo "Name of the host / server: <b>".getString($fp)."</b><br>";
echo "Name of the map: <b>".getString($fp)."</b><br>";
echo "Game directory: <b>".getString($fp)."</b><br>";
echo "Game description: <b>".getString($fp)."</b><br>";
echo "Active client count: <b>".getByte($fp)."</b><br>";
echo "Maximum clients allowed: <b>".getByte($fp)."</b><br>";
echo "Protocol version: <b>".getByte($fp)."</b><br><br>";
////////////////////////////////////////////
// P L A Y E R S
////////////////////////////////////////////
echo "<h3>Players</h3>";
// Skicka players kommando
sendCommand($fp, "players");
// Ta emot svar
getInt32($fp); // Alltid -1
getChar($fp); // Alltid 'D'
$clients = getByte($fp); // Antal spelare
// Skriv ut info om våra spelare
for($i = 0; $i < $clients; $i++) {
echo "Client number / index: <b>".getByte($fp)."</b><br>";
echo "Player name: <b>".getString($fp)."</b><br>";
echo "Client's frag total: <b>".getInt32($fp)."</b><br>";
echo "Client's total time in-game: <b>".round(getFloat32($fp))."s</b><br><hr width=100%>";
}
if($clients == 0) { // Om inga spelare var activa, skriv det
echo "No active players<br>";
}
echo "<br>";
////////////////////////////////////////////
// R U L E S
////////////////////////////////////////////
echo "<h3>Rules</h3>";
// Skicka rules kommando
sendCommand($fp, "rules");
// Ta emot svar
getInt32($fp); // Alltid -1
getChar($fp); // Alltid 'E'
$rules = getInt16($fp); // Antal regler
// Hämta alla våra regler och skriv ut dem (regelnamn : värde)
for($i = 0; $i < $rules; $i++) {
echo getString($fp)." : <b>".getString($fp)."</b><br>";
}
echo "<br>";
////////////////////////////////////////////
// D E T A I L S
////////////////////////////////////////////
echo "<h3>Details</h3>";
// Skicka details kommando
sendCommand($fp, "details");
// Ta emot svar
getInt32($fp); // Alltid -1
getChar($fp); // Alltid 'm'
echo "Net address of server: <b>".getString($fp)."</b><br>";
echo "Name of the host / server: <b>".getString($fp)."</b><br>";
echo "Name of the map: <b>".getString($fp)."</b><br>";
echo "Game directory: <b>".getString($fp)."</b><br>";
echo "Game description: <b>".getString($fp)."</b><br>";
echo "Active client count: <b>".getByte($fp)."</b><br>";
echo "Maximum clients allowed: <b>".getByte($fp)."</b><br>";
echo "Protocol version: <b>".getByte($fp)."</b><br>";
echo "Type of server: <b>".(getChar($fp)=='d'?"dedicated":"listen")."</b><br>";
echo "OS of server: <b>".(getChar($fp)=='l'?"linux":"win32")."</b><br>";
echo "Password on server: <b>".(getByte($fp)?"Yes":"No")."</b><br>";
$mod = getByte($fp); // Kör servern en mod?
echo "Is server running a mod?: <b>".($mod?"Yes":"No")."</b><br>";
// Om servern kör en mod, hämta info om modden.
if($mod) {
echo "- URL for mod's \"info\" website: <b>".getString($fp)."</b><br>";
echo "- URL for mod's download ftp server: <b>".getString($fp)."</b><br>";
echo "- Unknown variable (byte): <b>".getByte($fp)."</b><br>";
echo "- Mod version #: <b>".getInt32($fp)." (Correct?)</b><br>";
echo "- Mod download size ( in bytes, approx. ): <b>".getInt32($fp)." (Correct?)</b><br>";
echo "- Is the mod a server side only mod?: <b>".(getByte($fp)?"Yes":"No")."</b><br>";
echo "- Does this server require you to have a custom client side .dll ( client.dll )?: <b>".(getByte($fp)?"Yes":"No")."</b><br>";
}
////////////////////////////////////////////
// I N F O S T R I N G
////////////////////////////////////////////
echo "<h3>Infostring</h3>";
// Skicka details kommando
sendCommand($fp, "infostring");
// Ta emot svar
getInt32($fp); // Alltid -1
echo getSlashString($fp)."<br>"; // Ska alltid vara "infostringresponse"
getByte($fp); // NULL-tecken
// Nu tar vi emot 15*2 st Slashterminerade strängar
for($i = 0; $i < 15; $i++) {
echo ($i+1).": ".getSlashString($fp)." : <b>".getSlashString($fp)."</b><br>";
}
// Då var vi klara så...
// Stäng våran "file-socket"
fclose($fp);
}
} else {
// Skriv ut ett fint formular för att skriva in ett IP och en port
echo "<form action=\"hl-stats.php\" method=\"post\">\n";
echo "IP <input type=\"text\" name=\"ip\" value=\"127.0.0.1\"><br>\n";
echo "Port <input type=\"text\" name=\"port\" value=\"27015\"><br>\n";
echo " <input type=\"submit\" value=\"Visa server info\">\n";
echo "</form>\n";
}
?>
</font>
</body>
</html>
Hittade följande på http://www.php.net/manual/en/function.fsockopen.php "The error will only become apparent when you read or write data to/from the socket. The reason for this is because UDP is a "connectionless" protocol, which means that the operating system does not try to establish a link for the socket until it actually needs to send or receive data. "
Vilket borde betyda att kommandot ska vara efter pingen. Jag ber om ursäkt. Angående exemplet på länken jag gav tidigare så gällde det väl skickning av datan "GET / HTTP/1.0\n\n".
Annat att notera är: "Note: The timeout parameter was introduced in PHP 3.0.9 and UDP support was added in PHP 4. "
<?php
$fp = fsockopen("udp://$ip", $port, $errno, $errstr, 5.0);
if (!$fp) {
// Nått gick snett, printa ut vad som gick snett
echo "ERROR: $errno - $errstr<br>\n";
} else {
// Vi är nu connectade, kör våra kommandon
sendCommand($fp, "infostring");
$str = fread($fp, 220);
if (!$str) {
echo "Couldn't connect.";
exit;
}
else {
////////////////////////////////////////////
// P I N G
////////////////////////////////////////////
?>
Glöm inte bort en extra } i slutet av skriptet..
268 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849