https://www.17buddies.rocks/index.html

17's Buddies Maps HL1 Maps HL2 Wads Plan des Maps
17 Buddies
Only for stats

Welcome Guest ( Log In | Register )

 
New
Pb De Programmation Php, Récupérer infos/players/rules d'un serveur de jeu CSS avec les s
Liangel
post 30/03/2011 - 19:26:43 |   Post #1
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Bonsoir tout le monde (IMG:http://forum.17buddies.rocks/style_emoticons/default/smile.gif)

Je suis en ce moment en train de concevoir (enfin plutôt paufiner) un gestionnaire de serveurs de jeu/rapports de wars pour ma team. Actuellement, il est stable et marche bien. Cependant, j'aimerais récupérer des informations complémentaires comme par exemple les variables d'un serveur (rules) et le score des joueurs (ainsi que des infos supplémentaires sur le serveur en lui-même comme l'OS ou l'hébergeur). La plupart des infos que je récupère vient de la commande RCon "status". Je teste aussi l'état du serveur (online ou offline) en envoyant une commande par socket avec retour en une seconde (suffisant pour savoir si oui ou non le serveur est en ligne).

Je me suis basé sur ceci : http://developer.valvesoftware.com/wiki/Server_queries

Ainsi que sur ce cours qui l'a permis de bien comprendre le principe des sockets et de la récupération des données par ce biais : http://a-pellegrini.developpez.com/tutoriels/php/cstrike/

Avec ces deux liens, j'ai réussi à récupérer les informations du serveur et le challenge number. Cependant j'ai quand même un gros doute sur ce dernier, car les deux autres requètes, à savoir les joueurs et les rules (qui demandent d'injecter dans la commande le challenge number) ne marchent pas (en faisant un echo de la réponse en brut, cela me donne une chaine ridiculement courte (6 caractères) concernant les rules).

J'ai alors essayé des solutions toutes faites : steam-condenser, GameQ, etc..., rien n'y fait, je retrouve le même problème.

Je me suis aussi intéressé au petit Gadget de Windows 7 que Chapo (je crois) a conçu pour 17's Buddies, que j'utilise d'ailleurs. Et surtout aux données JSON récupérées par le Javascript du widget. pour le moment, j'utilise avec honte ces données pour mon gestionnaire, ce qui me rend très dépendant de 17's Buddies.

Ma question est donc la suivante : y a-t-il une autre approche pour recueillir les informations que je recherche ? Et si non, qu'est-ce qui fait que cela ne marche pas de mon côté ?
Post PM
Website
Go to the top of the page
Chapo
post 31/03/2011 - 07:41:45 |   Post #2
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Citation (Liangel @ 30/03/2011 - 19:26:43) [snapback]1081289[/snapback]
pour le moment, j'utilise avec honte ces données pour mon gestionnaire, ce qui me rend très dépendant de 17's Buddies.


Tu n'as pas de honte à avoir à utiliser des outils tout faits, même si, visiblement, tu es comme moi et que tu préfères créer tes propres outils.

Ceci dit, en utilisant les infos JSON retournées par mon script tu peux être quasiment certain que ça restera opérationnel car ces données sont issues du même script php que celui renvoyant les infos serveurs du site 17b.

Pour le query php, tu dois vérifier si la réponse reçue est en un ou plusieurs paquets, et si elle est en format compressé ou pas. C'est surtout important pour les rules qui m'ont justement posé énormément de problèmes.

Pour réaliser le mien, je m'étais servi des liens que tu as indiqué, mais aussi de kquery (qui ne doit plus exister aujourd'hui). La meilleures source reste encore celle de valve que tu as citée http://developer.valvesoftware.com/wiki/Server_queries.

Par contre, pour le moment, je n'envisage malheureusement pas de mettre en ligne le code source de mon script (ceci juste au cas où tu me l'aurais demandé). (IMG:http://forum.17buddies.rocks/style_emoticons/default/wink.gif)

(IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_jap.gif)
Post PM
Website
Go to the top of the page
Liangel
post 31/03/2011 - 11:58:05 |   Post #3
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Je ne demanderai pas de code source ^^

Mais par contre, j'aimerais savoir si le problème que je rencontre vient de moi, où si c'est un pb de config. Et pour ça, faudrait tester la classe proposée à la fin du cours de a.pellegrini (premier lien que j'ai donné). Je l'ai testé de mon côté, je récupère les infos serveurs, mais pas les players ou les rules (erreur sur la fonction PHP "unpack").

Et comme je l'ai dit précédemment, TOUS les scripts que j'ai utilisés, avec WAMP en local aussi bien qu'avec mes hébergeurs mutualisés (mais bon, je ne peux pas trop me fier à eux, les paramètres PHP et extensions sont trop limités malheureusement) se heurtent au même problème. A s'en arracher les cheveux, j'vous dis ! (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_biggrin.gif)

Je veux bien par contre que tu m'éclaircisses sur ce point :

Citation
Pour le query php, tu dois vérifier si la réponse reçue est en un ou plusieurs paquets, et si elle est en format compressé ou pas. C'est surtout important pour les rules qui m'ont justement posé énormément de problèmes.


Je ne sais pas trop comment m'y prendre pour vérifier (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_decu.gif)
Post PM
Website
Go to the top of the page
Chapo
post 31/03/2011 - 12:17:27 |   Post #4
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Suffit de regarder les headers renvoyés.

Lis ici:

http://developer.valvesoftware.com/wiki/Server_queries

Chapitre "Protocol"

(IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_jap.gif)
Post PM
Website
Go to the top of the page
Liangel
post 31/03/2011 - 12:36:10 |   Post #5
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


OK, je crois avoir saisi au moins l'importance du "type". Je dois prendre les quatre premiers bytes pour savoir si c'est splitté ou en un seul morceau, ainsi que le nombre de paquets. Par contre ma connaissance assez moyenne de l'anglais ne fait perdre ma compréhension au niveau de la lecture/assemblage des paquets, avec le request ID.

J'avoue être un peu à la ramasse quand on parle de gestion des sockets. Je ne me suis jamais planché dessus jusqu'à ce que je décide de concevoir ce gestionnaire de serveurs (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_razz.gif)

EDIT : Après relecture, je commence à comprendre comment faire. J'avais en fait mal lu la ligne 'Packet Number' ^^
Par contre maintenant, c'est ceci que je ne comprends pas :

Citation
every packet should be verified by its Request ID and the Packet Number!


Pour le packet number, OK, mais le Request ID ? En gros, le Request ID le plus petit est le premier paquet, et le Request ID le plus grand est le dernier paquet ?

This post has been edited by Liangel: 31/03/2011 - 12:39:28
Post PM
Website
Go to the top of the page
Chapo
post 31/03/2011 - 17:16:08 |   Post #6
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Je ne me sers du Request ID que pour une seule chose: savoir si le paquet est compressé ou pas:

Code
$IsCompressed = (($RequestId & 0x80000000) != 0);


La comparaison entre le RequestId et le Packet number m'importe peu (même si effectivement je devrais le faire).

(IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_jap.gif)
Post PM
Website
Go to the top of the page
Liangel
post 18/04/2011 - 17:09:59 |   Post #7
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Me revoilàààà (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_biggrin.gif)

J'ai pu avoir un peu de temps pour retourner à mon souci.

Je me retrouve avec un $IsCompressed égal à 1. Cela veut-il dire qu'il est compressé ?

Voici mon code, au cas où :

Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Cstrike :: Example</title>
</head>
<body>
<?php
/**
* Return a byte and split it out of the string
* - unsigned char
*
* @param string $string String
*/
function getByte(&$string)
{
$data = substr($string, 0, 1);

$string = substr($string, 1);

$data = unpack('Cvalue', $data);

return $data['value'];
}

/**
* Return an unsigned short and split it out of the string
* - unsigned short (16 bit, big endian byte order)
*
* @param string $string String
*/
function getShortUnsigned(&$string)
{
$data = substr($string, 0, 2);

$string = substr($string, 2);

$data = unpack('nvalue', $data);

return $data['value'];
}

/**
* Return a signed short and split it out of the string
* - signed short (16 bit, machine byte order)
*
* @param string $string String
*/
function getShortSigned(&$string)
{
$data = substr($string, 0, 2);

$string = substr($string, 2);

$data = unpack('svalue', $data);

return $data['value'];
}

/**
* Return a long and split it out of the string
* - unsigned long (32 bit, little endian byte order)
*
* @param string $string String
*/
function getLong(&$string)
{
$data = substr($string, 0, 4);

$string = substr($string, 4);

$data = unpack('Vvalue', $data);

return $data['value'];
}

/**
* Return a float and split it out of the string
*
* @param string $string String
*/
function getFloat(&$string)
{
$data = substr($string, 0, 4);

$string = substr($string, 4);

$array = unpack("fvalue", $data);

return $array['value'];
}

/**
* Return a string and split it out of the string
*
* @param string $string String
*/
function getString(&$string)
{
$data = "";

$byte = substr($string, 0, 1);

$string = substr($string, 1);

while (ord($byte) != "0")
{
$data .= $byte;
$byte = substr($string, 0, 1);
$string = substr($string, 1);
}

return $data;
}

$_ip = '94.23.13.110';
$_port = '30001';

// Constantes
define('PACKET_SIZE', '1400');
define('SERVERQUERY_GETCHALLENGE', "\xFF\xFF\xFF\xFF\x57");
define ('REPLY_GETCHALLENGE', "\x41");
define('SERVERQUERY_RULES', "\xFF\xFF\xFF\xFF\x56");
define('REPLY_RULES', "\x45");

// Ouvre une connexion UDP
$socket = stream_socket_client('udp://'.$_ip.':'.$_port, $errno, $errstr, 1);

// Envoie une commande au serveur
$cmd = SERVERQUERY_GETCHALLENGE;
$length = strlen($cmd);
fwrite($socket, $cmd, $length);

// Reçoit la réponse
$response = fread($socket, PACKET_SIZE);

// Nettoie la réponse
$pattern = "#\xFF\xFF\xFF\xFF".REPLY_GETCHALLENGE."#";
$response = preg_replace($pattern, '', $response);

// RULES
// Envoie une commande au serveur
$cmd = SERVERQUERY_RULES.$response;
$length = strlen($cmd);
fwrite($socket, $cmd, $length);

// Reçoit la réponse
$response = fread($socket, PACKET_SIZE);

// Nettoie la réponse
$pattern = "#\xFF\xFF\xFF\xFF".REPLY_RULES."#";
$response = preg_replace($pattern, '', $response);

$es = getLong($response);
echo "Première info : ".$es;
echo "<br><br>";
$es2 = getLong($response);
echo "Deuxième info : ".$es2;
echo "<br><br>";
$IsCompressed = (($es2 & 0x80000000) != 0);
echo "Troisième info : ".$IsCompressed;
?>
</body>
</html>


Désolé du pavé (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_biggrin.gif)
Post PM
Website
Go to the top of the page
Chapo
post 18/04/2011 - 17:18:30 |   Post #8
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Citation (Liangel @ 18/04/2011 - 18:09:59) [snapback]1081344[/snapback]
Je me retrouve avec un $IsCompressed égal à 1. Cela veut-il dire qu'il est compressé ?


D'après toi ? (IMG:http://forum.17buddies.rocks/style_emoticons/default/gap.gif)
Post PM
Website
Go to the top of the page
Liangel
post 18/04/2011 - 17:42:05 |   Post #9
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Bah, ma logique voudrait que je réponde Oui (IMG:http://forum.17buddies.rocks/style_emoticons/default/icon_biggrin.gif)

Ensuite, dans ce cas où les données sont bien compressées, et d'après ce que dit Valve dans son wiki, il faut d'abord décompresser avec BZ2_bzBuffToBuffDecompress().

Là j'ai utilisé son équivalent PHP bzdecompress(), puis je continue à parser ce que je trouve, à commencer par l'en-tête de la réponse. Je trouve 45 au lieu de 69

Code
$es = getLong($response);
echo "Première info : ".$es;
echo "<br><br>";
$es2 = getLong($response);
echo "Deuxième info : ".$es2;
echo "<br><br>";
$IsCompressed = (($es2 & 0x80000000) != 0);
echo "Troisième info : ".$IsCompressed;
echo "<br><br>";
$response_unzip = bzdecompress($es2);
echo "cui : ".$response_unzip;
echo "<br><br>";
$es3 = getByte($response_unzip);
echo "Quatrième info : ".$es3;
echo "<br><br>";


Ce qui donne :

Citation
Première info : -1

Deuxième info : -772376767

Troisième info : 1

cui : -5

Quatrième info : 45


Déjà que je n'ai plus beaucoup de cheveux ... (IMG:http://forum.17buddies.rocks/style_emoticons/default/sad.gif)

This post has been edited by Liangel: 18/04/2011 - 17:42:36
Post PM
Website
Go to the top of the page
Chapo
post 18/04/2011 - 18:19:02 |   Post #10
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Faut tenir compte du nombre de paquets (si paquets il y a).

Lire les paquets de 1 à N => Assembler les paquets => Decompresser.
Post PM
Website
Go to the top of the page
Liangel
post 19/04/2011 - 12:27:33 |   Post #11
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Bah... maintenant je suis perdu.

J'envoie la commande suivante au serveur :

Citation
\xFF\xFF\xFF\xFF\x57


Ceci afin de pouvoir récupérer le challenge number.

Je lis la réponse, je vérifie quand même si c'est en paquets ou simple :

Citation
if(preg_match("#\xFF\xFF\xFF\xFF#", $response) != -1)


La condition passe, la réponse est donc en un seul morceau.

Je récupère l'en-tête (byte) et le challenge number (long), ce qui donne :

Citation
En-tête : 65
Challenge : 1536257285


Le challenge est mis dans une variable $challenge.

J'envoie maintenant la commande suivante au serveur :

Citation
"\xFF\xFF\xFF\xFF\x56".$challenge


Ceci afin de récupérer les rules.

Je lis la réponse, je vérifie quand même si c'est en paquets ou simple :

Citation
if(preg_match("#\xFF\xFF\xFF\xFF#", $response) != -1)


La encore, la condition passe, la réponse est donc en un seul morceau.

Je récupère l'en-tête (byte) pour vérifier, et je tombe sur ceci :

Citation
En-tête : 65


Ce qui correspond à l'en-tête du challenge number !

Moi pas comprendre...
Post PM
Website
Go to the top of the page
Chapo
post 19/04/2011 - 17:34:36 |   Post #12
+Reply

Group: 17 Buddies
Posts: 18 534
Joined: 27/12/2003

fr 

Team:
Dev. 17b


Citation (Liangel @ 19/04/2011 - 13:27:33) [snapback]1081351[/snapback]
Le challenge est mis dans une variable $challenge.

J'envoie maintenant la commande suivante au serveur :

Code
"\xFF\xFF\xFF\xFF\x56".$challenge


Essaie plutot d'envoyer ça:

Code
"ÿÿÿÿV".pack("V",$challenge).chr(0);
Post PM
Website
Go to the top of the page
Liangel
post 20/04/2011 - 09:20:54 |   Post #13
+Reply

Group: Member
Posts: 13
Joined: 22/03/2011

fr 


Malheureusement cela me donne la même chose...
Post PM
Website
Go to the top of the page
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:

New
 


RSS Lo-Fi Version
 
Skin © Chapo