Parser de log quake 3, urban terror,...

Soyez le premier à donner votre avis sur cette source.

Vue 5 413 fois - Téléchargée 155 fois

Description

Parser de fichier .log de serveur de jeux comme Quake III, Urban Terror, Open Arena, Nexuiz ! Il permet de récupérer les points totaux de chaque Joueurs qui peuvent par la suite être utiliser comme sur GameTracker pour des stats de tout les joueurs ! Voir même une possibilité par la suite de créer un espace membre sur votre serveur pour sauver les stats de ceux qui sont inscrits !!!

Source / Exemple :


<?Php
/****************************************************

  • Auteur : MEYER Thibault
  • Date : Vendredi 25 juillet 2008
  • fichier : score.php
                                                                                                        • /
?> <?Php function EstPresent($Pseudo, $Table) { for($i=0; $i < count($Table); $i++) { if($Table[$i]["Joueur"] == $Pseudo) { return true; } } return false; } function LireLog($Fichier) { $Log = ""; $hFile = fopen($Fichier, "r"); while(!feof($hFile)) { $Log .= fgets($hFile); } fclose($hFile); if(strstr($Log, "score:") == NULL) return false; $answer = array(); preg_match_all('(.*)', $Log, $answer, PREG_SET_ORDER); $Log = ""; for($i=0,$j=0; $i<count($answer); $i++) { if(strstr($answer[$i][0], "score:") != null) { $Log[$j++] = $answer[$i][0]; } } $Stats = array(); for($i=0; $i<count($Log); $i++) { if($i == 0) sscanf($Log[$i], "%d:%d score: %d ping: %d client: %d %s %s %s %s" , $NULL, $NULL, $Stats[$i]["score"], $NULL, $NULL, $Stats[$i]["Joueur"], $Stats[$i]["nom2"], $Stats[$i]["nom3"], $Stats[$i]["nom4"]); else sscanf($Log[$i], "%d:%d score: %d ping: %d client: %d %s %s %s %s" , $NULL, $NULL, $Stats[$i]["score"], $NULL, $NULL, $Stats[$i]["Joueur"], $Stats[$i]["nom2"], $Stats[$i]["nom3"], $Stats[$i]["nom4"]); } for($i=0; $i<count($Stats); $i++) { if(@$Stats[$i]["nom2"] != NULL) $Stats[$i]["Joueur"] .= " ".$Stats[$i]["nom2"]; if(@$Stats[$i]["nom3"] != NULL) $Stats[$i]["Joueur"] .= " ".$Stats[$i]["nom3"]; if(@$Stats[$i]["nom4"] != NULL) $Stats[$i]["Joueur"] .= " ".$Stats[$i]["nom4"]; } //Cration de la liste des joueurs (regroupe les noms en double) $Stats2[0]["Joueur"] = ""; for($i=0, $j=0; $i < count($Stats); $i++) { if(EstPresent($Stats[$i]["Joueur"], $Stats2) == false) { $Stats2[$j]["Joueur"] = $Stats[$i]["Joueur"]; $Stats2[$j++]["score"] = 0; } } //Rregroupement des points par Joueurs for($i=0; $i < count($Stats2); $i++) { for($j=0; $j < count($Stats); $j++) { if($Stats[$j]["Joueur"] == $Stats2[$i]["Joueur"]) $Stats2[$i]["score"] += $Stats[$j]["score"]; } } //Retourne la tableau return $Stats2; } function EffaceLog($Fichier) { if(!file_exists($Fichier)) return false; $hFile = fopen($Fichier, "w"); if(!$hFile) return false; return true; } function array_sort($array, $key) { for ($i = 0; $i < sizeof($array); $i++) { $sort_values[$i] = $array[$i][$key]; } asort ($sort_values); reset ($sort_values); while (list ($arr_key, $arr_val) = each ($sort_values)) { $sorted_arr[] = $array[$arr_key]; } return $sorted_arr; } ?> <? //EXEMPLE $mesStats = LireLog("games3.log"); $mesStats = array_sort($mesStats, "score"); if($mesStats == false) echo "AUCUNE PARTIE A TRAITER"; else{ for($i=count($mesStats)-1; $i>=0; $i--) { echo $mesStats[$i]["Joueur"]." : ".$mesStats[$i]["score"]; echo "<br>"; } } //QUAND MISE A JOUR DES JOUEURS SUR LA BASE DE DONNéES, ON VIDE LE JOURNAL echo "<br>"; //if(EffaceLog("games3.log") == true) echo "EFFACER OK"; //else echo "EFFACER ERREUR"; ?>

Conclusion :


Les éléments du tableau "nom2", "nom3"... C'est pour si jamais les gars on des pseudo du genre "Vieux Troll Des Bois" au lieu de "VieuxTrollDesBois"

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
79
Date d'inscription
lundi 23 décembre 2002
Statut
Membre
Dernière intervention
1 mars 2011

wouahouu, ca c'est de l'optimisation !!! Merci, je vais prendre note de tous ça.
Messages postés
592
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008

Bon, je suis lourd c'est vrai, mais CS a tout détruit ma belle indentation...
Voila le code plus clair: http://pastebin.org/58433

Sur ce, bonne journée à vous, et bonne nuit à moi :]
Messages postés
592
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008

bon comme j'avais rien à faire (enfin, si, je devrais dormir, il est 6hr du mat ^^) j'ai fait un mini exemple pour prouver ce que je dis (parce que je sais par expérience que se faire dire que son code est pourris par quelqu'un qui propose pas mieux c'est très insultant)

Voilà, on pase de 90 à 28 lignes et de 1.65secondes à 0.35 pour 100 lectures et tri de games3.log (sur mon pc)

function LireLog($Fichier) {
$hFile = fopen($Fichier, "r");
while(!feof($hFile)) {
fscanf($hFile, '%d:%d score: %d ping: %d client: %d %[^$]s',$h,$m,$score,$ping,$client,$nom);
if ($nom !== null && $score !== null){
$Stats[$nom] += $score;
$nom=null;
$score = null;
}
}
fclose($hFile);
//Retourne le tableau
return $Stats;
}

function array_sort($array, $key) {
switch($key) {
case 'score':
arsort($array);
break;
case 'joueur':
$array = array_flip($array);
arsort($array);
$array = array_flip($array);
break;
}
return $array;
}

PS: J'ai pris 10 minutes à faire ça, il peut encore être optimisé, mais pour moi c'est l'heure de dormir ;p

PPS: Si un admin croit que je pollue le sujet, libre à lui de supprimer mon post...
Messages postés
592
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008

"Après, je pense que c'est surtout les habitudes de codage."

Oui, mais faut comprendre qu'il y a de meilleures habitudes que d'autre. Enfin, moi, j'ai l'habitude de chercher à faire un code optimisé avant tout. D'ailleurs je passe sans doute plus de temps à comparer/bencher des façons de faire que de coder à proprement dit, tout ça dans le but de sauver quelques cycles CPU.

Il est évident que sur ton code seul on ne ressentira pas la différence, mais quelques dix millièmes de seconde par ci par là, ça finit par donner des secondes. Et puis, le but principal d'un vrai programmeur, est d'avoir un code le plus optimisé possible. C'est sans doute la différence entre l'amateur et le vrai passionné(je ne dis pas professionnel, parce que tristement professionnel veut rarement dire compétent): Un veut simplement que ça fonctionne, l'autre veux que ça fonctionne, et que ça soit bien codé :P.

Le count, comme disait STAILER, est en effet calculer à chaque itération puisque la condition est comparé à chaque itération. Ça devient vite très lourd, surtout avec de gros tableaux. Le sortir de là va donc, forcément, sauver beaucoup de temps d'exécution.

D'ailleurs ça ne rajoute pas forcément une ligne, tu peux l'inclure dans la définition de la boucle.

for($i=0, $j=0; $i < count($Stats); $i++)

devient

for($i=0, $j=0, $cntStats = count($Stats); $i < $cntStats; $i++)

D'ailleurs beaucoup d'autres choses pouraient être améliorées:
# $hFile = fopen($Fichier, "r");
# while(!feof($hFile))
# {
# $Log .= fgets($hFile);
# }
# fclose($hFile);

Pourrait utilisé file_get_contents, mais je ne comprends même pas pourquoi tu procède de cette façon, faire le traitement directement dans cette boucle serait BEAUCOUP plus rapide que de tout charger, et de le rediviser après. En fait ça permettrait de remplacer les lignes 23 à 58 par 5 ou 6 petites lignes.

Ensuite, tu sembles utiliser strstr pour savoir si une chaine est dans une autre. Si c'est le cas tu devrais utiliser strpos qui va être plus rapide pour l'usage que tu en fais.

Dans EffaceLog tu ne fermes pas le pointeur de fichier. Php le fait automatiquement à la fin du script, mais c'est une mauvaise habitude de pas fermer ses fichiers.

Voilà, garde à l'esprit que nous sommes sur codes-sources, et que tous ces commentaires ont pour but de t'aider à t'améliorer, non pas de dénigrer ton code ;p

Sinon l'idée de codefalse est intéressante, une classe serait sans doute sympatique :)
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
En fait, sortir les fonctions count et sizeof des boucles permettent d'augmenter la rapidité d'éxécution de ton script. Quand tu as juste ton code ici préent qui est lancé, ce n'est pas un gros problème, mais s'il est appelé avec plusieurs autres scripts, ca va vite devenir gênant.

Sortir le maximum de fonction des boucles et une des règles de base de l'optimisation du code, chose à ne jamais négliger.

Par rapport à ton code, je l'aurai beaucoup plus apprécié en tant que classe. En effet, vu l'usage, ca aurait été sympa un truc du genre :

$obj = new GameLogParser ('./quake3.log');
echo 'Statistiques du joueur Ilsundal" :
';
echo 'Nombre de matchs gagnés :' . $obj->getWinnedMatches ('Ilsundal').'
';
...
etc :)

Voir jouer avec les méthodes magiques __get et __set, du genre $obj->Winner; te retourne le grand gagnant, à toi de voir comment tu implémente le tout ! :)
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.