FAQ  •  Register  •  Login

[PHP] How to build your own score database



Zone Bunny
Zone Bunny

Posts: 15

Joined: 22 Jan 2016, 01:06

Site Rep: International / Overseas

Post 24 Jun 2016, 19:33

[PHP] How to build your own score database

Hey guys!

I managed to parse the Myzonelaser Website and build my own score database, so i wanted to share it with you. There is a technical difficulty tho. You can only track games which you (or any member you have the login data of) have played in. For me, this is not a problem, because i play in every game of our lasertag community.

PERHAPS there is a better way to get to the scores (e.g. reading it directly from a sites server?), but i am not a site admin. I am just an Laser Tag enthusiast with decent coding skills :D

Things you need:
1. PHP knowledge
2. cookies.txt extension (Chrome / Firefox)
3. something to save the scores in

Export your myzonelaser.come Cookies into a cookies.txt and put it in the same directory as the following PHP file.

And here is the code:

*Just some * i need it in my project to run, you can leave it out
$score_file = 'public/tmp/score_overview.html';
require_once 'library/vendor/autoload.php';
require_once 'library/config.php';
//define( 'ROOT_PATH', dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR );
$autoloader = new Autoloader();

 * If the file is not modified today, i will fetch the new content of the score page
 * This will fetch the page only once per day, because f*** is the MYZONELT page slow...

if ( date ("ymd", filemtime($score_file)) != date ("ymd", time()) ) {
    // Create the target URLs
    // Don't forget to escape your user input!
    $reputationUrl = "http://myzonelaser.com/index.php?module=myzlt&page=Games";

    // Note that __DIR__ can also be used in PHP 5.3+
    $cookieJar = dirname(__FILE__) . '\cookies.txt';

    // The User-Agent string to send
    $userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5";

    // Create the cURL handle for reputation scrape
    $ch = curl_init($reputationUrl);

    // Set connection meta
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

    // Set header-related options
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieJar);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieJar);

    // Execute the request
    if (!$result = curl_exec($ch)) {
        exit("ERROR: Reputation scrape request failed: " . curl_error($ch));
    file_put_contents($score_file, $result);
else {
 $result = file_get_contents($score_file);   

//load result of the curl fetch in a DOMDocument Object
$doc = new DOMDocument();

 * Parse the Document with xpath
 * Unfortunatelly the page uses tables without <th> tags, so i have to filter them out later
 * $games gets the Div with the date of the game, so i have something to match it with the data i already have
 * the rest of the variables stores the whole column of the table in the div containing 'rap_dd'
 * which results in all the tables with scores, accuracy, aliases and teams of members logged in in the
 * games i played in
$xpath = new DOMXpath($doc);
$games = $xpath->query("//td[contains(., 'Played on')]");
$rank = $xpath->query("//div/@id[starts-with(., 'rap_dd')]/../table/tr/td[position()=1]");
$aliases = $xpath->query("//div/@id[starts-with(., 'rap_dd')]/../table/tr/td[position()=2]");
$score = $xpath->query("//div/@id[starts-with(., 'rap_dd')]/../table/tr/td[position()=3]");
$accuracy = $xpath->query("//div/@id[starts-with(., 'rap_dd')]/../table/tr/td[position()=4]");
$team = $xpath->query("//div/@id[starts-with(., 'rap_dd')]/../table/tr/td[position()=5]");

//this is the array which will contain all the information
$to_insert = array();

//i have to set my locale to english, cause im from germany and it gives me problem with date conversion if i dont do it
$loc_de = setlocale(LC_ALL,'english');

 * Loop variables
 * i starts at 0 cause arrays always starts at 0
 * j starts at 1 because, as mentioned above, the first row are headings
 * which i dont want to include in my database
$i = 0;
$j = 1;
 * I need the sitename to remove it from the string "Played on ..." on top of the games-table
 * so i just have the date in the string
$sitename = 'ActionPark';
while($i <= $games->length) {
    //filter out everything except the date and make an object out of it
    $replace = array ('Played on ',' at '.$sitename);
    $string =  str_replace($replace, '', $games->item($i)->nodeValue);
    $date = new DateTime($string);
     * Now we loop through the rows of every score table listed on the page
     * and add the values to the array
     * Every game gets it's own index and its according values underneath it
    while ($j <= $rank->length && $rank->item($j)->nodeValue != 'Rank') {
            $to_insert [$aliases->item($j)->nodeValue][$j]['date'] = $date->format('Y-m-d');       
            $to_insert [$aliases->item($j)->nodeValue][$j]['rank'] = $rank->item($j)->nodeValue;
            $to_insert [$aliases->item($j)->nodeValue][$j]['score'] = $score->item($j)->nodeValue;
            $to_insert [$aliases->item($j)->nodeValue][$j]['accuracy'] = $accuracy->item($j)->nodeValue;
            $to_insert [$aliases->item($j)->nodeValue][$j]['team'] = $team->item($j)->nodeValue;

 * from here on it is on you what you want to do with the data just fetched.
 * You could var_dump the array above to have a look at it, save it to a file
 * or write it to a database via propel, like i do
 * I will just comment the whole code out, since it probably wont work for you
 * but i leave it here as an example
 * One thing: i filter out every score below 1000 because i dont want special
 * game modes like Capture The Flag or Speedball to influence my data
echo '<pre>';
echo  '</pre>';
foreach($to_insert as $alias => $games) {
    $cur_player = models\SpielerQuery::create()->findOneByMyzoneuser($alias);
    foreach($games as $key => $game) {
        $cur_game = models\SpieleQuery::create()->findOneByDatum(array("min" => $game['date']." 00:00:00", "max" => $game['date']." 23:59:59"));
        if($cur_game != null
                && $cur_player != null
                && \models\MyzonedataQuery::create()->filterBySpielId($cur_game->getId())->filterBySpielerId($cur_player->getId())->count() == 0
                && $game['score'] >= 1000) {
            $myZoneData = new \models\Myzonedata();
            echo 'Spieler: '.$myZoneData->getSpielerId().' - Spiel: '.$myZoneData->getSpielId().' - '.$myZoneData->getScore().' - '.$myZoneData->getRank().'<br/><br />';

And now you ask yourself...what can i do with that *!?
For example, you could do something like this: http://lt-community.de/?controller=page ... eaderboard
A private league only for your player group! Nice! :D


User avatar

Zone Poster
Zone Poster

Site Admins
Site Admins

P&C Representative
P&C Representative

Posts: 254

Joined: 25 Mar 2014, 17:01

Location: Adelaide, South Australia

Site Rep: SA

Post 25 Jun 2016, 01:16

Re: [PHP] How to build your own score database

Very interesting...

Cool :)
I aim to misbehave.

"Hey... Isn't P&C in Melbourne?" - Pal, 2012 (On Subtlety)
"And I will pay $50 to get out of Jail again, because this game is a ****" - Vector, 2013 (On Monopoly)
"I do mistrust dinosaurs..." - Rep, 2014 (On Forum Policy)


User avatar

Zone Bunny
Zone Bunny

Posts: 27

Joined: 10 Dec 2015, 13:15

Site Rep: No Location Represented

Post 26 Jun 2016, 09:25

Re: [PHP] How to build your own score database

This is awesome. Looking to try to add this to our site hopefully. Facebook message me sometime so we can go over some zone coding. <Todd Rodman>

Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests