// Ö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"..?
PeddaMedlem sedan juni 20006 032 inlägg Hur ser koden ut efter den raden? Kör du fclose?
Allt i filen... :)
<?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>
stevenetMedlem sedan juni 20001 251 inlägg http://www.php.net/manual/en/function.stream-set-timeout.php
Prövat? "This is a must for use with fsockopen and Half-Life Servers"
Så stream_set_timeout($fp, 2); ska placeras ungefär vid // Vi är nu connectade, kör våra kommandon?
stevenetMedlem sedan juni 20001 251 inlägg Direkt efter:
$fp = fsockopen("udp://$ip", $port, $errno, $errstr, 5.0);
Så är det ju inte på php.net sidan...
stevenetMedlem sedan juni 20001 251 inlägg Men om du placerar den vid:
// Vi är nu connectade, kör våra kommandon?
så är du ju redan ansluten. Varför ska du då ha timeouten?
Kolla på php.net så ser du att de först kollar om det har upprättats en anslutning...
stevenetMedlem sedan juni 20001 251 inlägg 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. "
stevenetMedlem sedan juni 20001 251 inlägg Exempel:
<?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..