Fsockopen et serveur de jeux ( CS )

Eléphant du PHP | 419 Messages

16 nov. 2008, 10:36

Bonjour,
Suite a mon panel pour contrôler les serveurs de jeux, je souhaiterais mettre une sorte de watchdog pour savoir si le serveur est lancé ou non.
Si il est lancé, ne rien faire et si il n'est pas lancé, le lancer.
Je l'ai fais en testant si il y a bien un screen du serveur mais le serveur peut planter en laissant le screen.
J'ai testé le port avec nmap mais il me met qu'il est clos alors que les joueurs peuvent aller dessus.

J'ai testé ce code :

	$fp = fsockopen("udp://".$ip, $port, $errno, $errstr, 5);
	if (!$fp)
	{
		echo "$errstr ($errno)";
	}
	else
	{
     echo '<font color="#00CC00">CONNECTE</font> !';
	}
     fclose($fp);

Mais le soucis c'est que il me met qu'il est connecté même quand le serveur n'existe pas...
Vu que c'est la première fois que j'utilise fsockopen, je découvre.

Je ne sais pu quoi faire...
Merci =)

Invité
Invité n'ayant pas de compte PHPfrance

16 nov. 2008, 11:08

bonjour,

http://fr3.php.net/fsockopen

extrait :
Avertissement

Les sockets UDP semblent quelques fois avoir été ouvertes sans erreur, même si l'hôte distant n'est pas accessible. L'erreur apparaît alors uniquement lorsque vous tentez de lire/écrire sur la socket. La raison de cela est que UDP est un protocole "connectionless", ce qui signifie que le système ne tentera pas d'établir un lien pour la socket tant qu'il ne doit pas recevoir/envoyer de données.

Eléphant du PHP | 419 Messages

16 nov. 2008, 11:18

Merci, j'avais vu mais je voulais demander si il y avait un moyen pour qu'il ne soit ouvert que si le serveur est lancé et tourne bien ...

Mammouth du PHP | 959 Messages

16 nov. 2008, 12:27

Et si tu enlève carrément le "udp://" ?
$fp = fsockopen($ip, $port, $errno, $errstr, 5);
:-k

Eléphant du PHP | 419 Messages

16 nov. 2008, 12:33

Dans ce cas, ça ne fonctionne plus :

Code : Tout sélectionner

Warning: fsockopen() [function.fsockopen]: unable to connect to 91.121.82.***:27015 (Connection refused) in /home/s***/www/test.php on line 16 Connection refused (111)
Je pensais récupérer des données...
Comment récupérer toutes les données ?

Puis ensuite voir si il y a bien une phrase dedans sinon c'est que le serveur n'est pas lancé.

J'ai trouvé a peu pres le meme style mais pour avoir toutes les données du serveur de jeux :
<?
// Recompose un nombre à partir de $oct octets
function ordoct($string, $oct)
{
	$nb = 0;
	for ($i=0 ; $i<$oct ; $i++)
	{
		$nb += ord($string[$i]) * pow(2, 8*$i);
	}
	return $nb;
}

// Lis un nombre décimal de type float dans un fichier $fp
function ffloat($fp)
{
	$buf[3] = ord(fread($fp, 1));
	$buf[2] = ord(fread($fp, 1));
	$buf[1] = ord(fread($fp, 1));
	$buf[0] = ord(fread($fp, 1));
	
	// Signe
	if (!($buf[0]&128))
	{
		$S = 1;
	}
	else
	{
		$S = -1;
	}
	
	// Exposant
	$buf[0] = ($buf[0] << 1) % 256;
	if ($buf[1] & 128)
	{
		$buf[0]++;
	}
	$E = $buf[0] - 127;
	
	// Mantisse
	$M = 0;
	$buf[1] %= 128;
	$buf = $buf[1]*65536 + $buf[2]*256 + $buf[3];
	for ($i=-1 ; $i>=-23 ; $i--)
	{
		if ($buf & pow(2, 23+$i))
		{
			$M += pow(2, $i);
		}
	}
	$M++;

	return $S * $M * pow(2, $E);
}

// Lis toute une chaîne de caractères dans un fichier $fp
function fline($fp)
{
	$buf = "";
	// Lecture octet par octet, en le comparant à "\0"
	do
	{
		$char = fread($fp, 1);
		$buf .= $char;
	}
	while (ord($char));
	return $buf;
}

// Retrouve les informations sur le serveur dont l'adresse est $ip:$port
// Si ($info%1) : On questionne le serveur sur ses informations
// Si ($info%2) : On questionne le serveur sur ses joueurs
// Si ($info%4) : On questionne le serveur sur ses règles
function cs_serveur($ip, $port, $info)
{
	set_time_limit(5);
	
	$CS_Label = Array ( 0 => 'IP', 1 => 'Name', 2 => 'Map', 3 => 'Path', 4 => 'Mod', 5 => 'Joueurs', 6 => 'JoueursMax', 7 => 'Type', 8 => 'OS', 9 => 'MDP');
	
	$fp = fsockopen("udp://".$ip, $port, $errno, $errstr, 5);
	if (!$fp)
	{
		echo "$errstr ($errno)";
	}
	else
	{
		if ($info & 1)
		{
			/****************\
			** Informations **
			\****************/
			$CS_Serveur['IP'] = $ip.":".$port;
			// Appel
			fputs($fp, "\xFF\xFF\xFF\xFFdetails\x00", 12);
		
			// Lis les premiers caractères : 4 "\xFF" et un "m"
			$tmp = fread($fp, 5); 
		
			$tmp = fline($fp); // Passe l'ip
			$CS_Serveur['Name'] = fline($fp);
			$CS_Serveur['Map'] = fline($fp);
			$CS_Serveur['Path'] = fline($fp);
			$CS_Serveur['Mod'] = fline($fp);
			$CS_Serveur['Joueurs'] = ord(fread($fp, 1));
			$CS_Serveur['JoueursMax'] = ord(fread($fp, 1));
			$buf = fread($fp, 1); // Passe la version du protocole
			$CS_Serveur['Type'] = fread($fp, 1);
			$CS_Serveur['OS'] = fread($fp, 1);
			$CS_Serveur['MDP'] = ord(fread($fp, 1));
		}
		if ($info & 2)
		{
			/***********\
			** Joueurs **
			\***********/
			// Appel
			fputs($fp, "\xFF\xFF\xFF\xFFplayers\x00", 12);
	
			// Attend les premiers caractères : 4 "\xFF" et un "D"
			$buf = "";
			do
			{
				$buf .= fread($fp, 1);
			}
			while (substr($buf, strlen($buf)-5, 5)!="\xFF\xFF\xFF\xFF\x44");
		
			// Lis le nombre de joueurs
			$nb = ord(fread($fp, 1));
			for ($i = 0 ; $i < $nb ; $i++)
			{
				$index = ord(fread($fp, 1));
				$CS_Joueur[$index]['Name'] = fline($fp);
				$CS_Joueur[$index]['Kill'] = ordoct(fread($fp, 4), 4);
				$CS_Joueur[$index]['Time'] = ffloat($fp);
			}
		}
		if ($info & 4)
		{
			/**********\
			** Règles **
			\**********/
			// Appel
			fputs($fp, "\xFF\xFF\xFF\xFFrules\x00", 10);
		
			// Attend les premiers caractères : 4 "\xFF" et un "E"
			$buf = "";
			do
			{
				$buf .= fread($fp, 1);
			}
			while (substr($buf, strlen($buf)-5, 5)!="\xFF\xFF\xFF\xFF\x45");
		
			// Lis le nombre de règles
			$nb = ordoct(fread($fp, 2), 2);
			for ($i = 0 ; $i < $nb ; $i++)
			{
				$CS_Regle[$i]['Name'] = fline($fp);
				$CS_Regle[$i]['Value'] = fline($fp);
			}
		}

		fclose($fp);
		$CS[0] = isset($CS_Serveur)?$CS_Serveur:NULL;
		$CS[1] = isset($CS_Joueur)?$CS_Joueur:NULL;
		$CS[2] = isset($CS_Regles)?$CS_Regles:NULL;
		return $CS;
	}
}
?>

Mammouth du PHP | 959 Messages

16 nov. 2008, 12:43

En effet, sur Internet il doit y avoir beaucoup beaucoup de scripts qui permettent ça, surtout pour un jeu comme CS ! :)

Eléphant du PHP | 419 Messages

16 nov. 2008, 12:44

je vais essayer de comprendre ces fonctions car c'est la premiere fois que j'utilise les sockets.

Eléphant du PHP | 419 Messages

07 déc. 2008, 17:25

C'est bon, j'ai trouvé, quelqu'un m'a dit la solution.

Voici le code :
 $fp = fsockopen("www.example.com", 80); 
if (!$fp) 
{ 
   echo "Unable to open\n"; 
} 
else { 

   fwrite($fp, "GET / HTTP/1.0\r\n\r\n"); 
   stream_set_timeout($fp, 2); 
   $res = fread($fp, 2000); 

   $info = stream_get_meta_data($fp); 
   fclose($fp); 

   if ($info['timed_out']) { 
       echo 'Connection timed out!'; 
   } else { 
       echo $res; 
   } 
}
Aucun site en création...

ViPHP
ViPHP | 5924 Messages

07 déc. 2008, 17:42

Il va tester ton port 80, cela va tester ton serveur http, pas ton serveur CS…

Il faut simplement faire un fsockopen :
$fp = fsockopen("udp://".$ip, $port, $errno, $errstr, 5);
Cela réussira à tous les coups.

Tu exécutes directement ce que tu as dans ton else, à la première erreur d'écriture (lorsques tu fais fputs), c'est que ton serveur n'est pas lancé.

Eléphant du PHP | 419 Messages

07 déc. 2008, 20:00

Oui, mais j'ai mis le bout de code général, pour tester correctement si un serveur est lancé ou pas.
Aucun site en création...