Page 1 sur 1

Fsockopen et serveur de jeux ( CS )

Posté : 16 nov. 2008, 10:36
par the_grinch
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 =)

Posté : 16 nov. 2008, 11:08
par Invité
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.

Posté : 16 nov. 2008, 11:18
par the_grinch
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 ...

Posté : 16 nov. 2008, 12:27
par chrislabricole
Et si tu enlève carrément le "udp://" ?
$fp = fsockopen($ip, $port, $errno, $errstr, 5);
:-k

Posté : 16 nov. 2008, 12:33
par the_grinch
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;
	}
}
?>

Posté : 16 nov. 2008, 12:43
par chrislabricole
En effet, sur Internet il doit y avoir beaucoup beaucoup de scripts qui permettent ça, surtout pour un jeu comme CS ! :)

Posté : 16 nov. 2008, 12:44
par the_grinch
je vais essayer de comprendre ces fonctions car c'est la premiere fois que j'utilise les sockets.

Posté : 07 déc. 2008, 17:25
par the_grinch
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; 
   } 
}

Posté : 07 déc. 2008, 17:42
par Sékiltoyai
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é.

Posté : 07 déc. 2008, 20:00
par the_grinch
Oui, mais j'ai mis le bout de code général, pour tester correctement si un serveur est lancé ou pas.