The online racing simulator
Just got my laptop working today (Damn charger getting lost ... ), I will look into it.
ok thx.
I think I can answer that. When you make a query to LFSW, you sometimes get NO data (e.g. when a racer has no hotlaps ...).

I suppose you use the returned $data without checking it is actually a non-initial array.

Just do this:

<?php 
if (is_array($data)){
  foreach(
$data as ....){
    ...
  }
}
?>

Ideas for Version 2.
  • Cache System;
  • Database Login;
Anything you guys would like to see added?
For non-premium access, there is always a 5 second sleep.

I think, there should only be a 5 second sleep if necessary.

For example for my tracker I need to query a lot. I don't want the 5-second sleep for the first query (since I have my own timestamp to check that delay), for all further queries the sleep is ok.

So i modified the constructor a little bit:

<?php 
    
// Constructor
    
function LFSWorldSDK($idk$ps false$initial_sleep true ) {
        
$this->ps $ps;
        
$this->idk $idk;
        
$this->compression = (function_exists('gzinflate')) ? 0;
        
$this->timestamp time( );
        if (
$initial_sleep == false// this will cause the first query to be done immediately 
            
$this->timestamp -= 5
    }
?>

And in the make_query function:

<?php 
        
if (!$this->ps){
            
$delta time( ) - $this->timestamp;
            if (
$delta 5)         // only sleep if necessary ...
                
sleep($delta);  // ... and only as long as necessary (up to 6 seconds because 5 will fail occasionally)
            
$this->timestamp time( );
        }
?>

I used 6 seconds in the sleep-command since 5 would sometimes not be enough ...

It seems to work at the moment for me but I have not tested it a lot at this early stage of the new tracker.
LFS World SDK 1.9.Beta
Many a bug fix and improvements. Most notably get_progress is fixed, and some functions will now return a false. Also errors are handled in a much different way, as to minimize the SDK allowing an error to be thrown without it being handled by the SDK in some way.

Released as beta for the next few days, to see if you guys find any bugs that I missed. Happy hunting!
Attached files
LFSWorldSDK1.9.BETA.zip - 2.7 KB - 553 views
I just took a quick look.

But since I am using the 1.8 version of your SDK in which I already found some issues, I checked these things in 1.9 and here is my first result:

Number format of lap times didn't work for me so I changed it to %05.2f

<?php 
    
function convert_lfsw_time($time) {
        return 
sprintf('%d:%05.2f'floor($time 60000), (($time 60000) / 1000));
    }
?>

Then, in the flag-conversion method, I missed some flags (SHIFTER and AUTOCLUTCH)


<?php 
    
function convert_flags_hlaps($flags_hlaps) {
        
$data = array();
        if (
$flags_hlaps 1)        $data[1] = 'LEFTHANDDRIVE';
        if (
$flags_hlaps 2)        $data[2] = 'GEARCHANGECUT';
        if (
$flags_hlaps 4)        $data[4] = 'GEARCHANGEBLIP';
        if (
$flags_hlaps 8)        $data[8] = 'AUTOGEAR';
        if (
$flags_hlaps 16)        $data[16] = 'SHIFTER';
        if (
$flags_hlaps 64)        $data[64] = 'BRAKEHELP';
        if (
$flags_hlaps 128)        $data[128] = 'AXISCLUTCH';
        if (
$flags_hlaps 512)        $data[512] = 'AUTOCLUTCH';
        if (
$flags_hlaps 1024)    $data[1024] = 'MOUSESTEER';
        if (
$flags_hlaps 2048)    $data[2048] = 'KN';
        if (
$flags_hlaps 4096)    $data[4096] = 'KS';
        if (!(
$flags_hlaps 7168))    $data[7168] = 'WHEEL';
        return 
$data;
    }
?>

Furthermore, as far as I understood it, I think some of these flags might already be obsolete. According to Victors post we have

<?php 
        1 LEFTHANDDRIVE
        8 AUTOGEAR
        16 SHIFTER
        64 BRAKEHELP
        128 AXISCLUTCH
        512 AUTOCLUTCH
        1024 MOUSESTEER 
*
        
2048 KN *
        
4096 KS *
        (*) if 
not 10242048 or 4096steering is wheel.
?>

Then I didn't like these flag-identifier too much, so I added a function exporting a simple string of letters (which are commonly used I guess):

<?php 
    
function convert_flags_hlaps_to_letters($flags_hlaps) {
        
$string "";
        if (
$flags_hlaps == "" || $flags_hlaps == 0) return;
        if (
$flags_hlaps 1024)    $string .= "M ";
        if (
$flags_hlaps 2048)    $string .= 'Kn ';
        if (
$flags_hlaps 4096)    $string .= 'Ks ';
        if (!(
$flags_hlaps 7168))    $string .= 'W ';
        if (
$flags_hlaps 1)        $string .= "L ";
            else                    
$string .= "R ";
        if (
$flags_hlaps 2)        $string .= "cc ";     // obsolete?
        
if ($flags_hlaps 4)        $string .= "cb ";     // obsolete?
        
if ($flags_hlaps 8)        $string .= "A ";     // Autogear
        
if ($flags_hlaps 16)        $string .= "S ";        // Shifter
        
if ($flags_hlaps 64)        $string .= "bh ";    
        if (
$flags_hlaps 128)        $string .= "cl ";    // Axisclutch (pedal)
        
if ($flags_hlaps 512)        $string .= "ac ";    // Autoclutch
        
return $string;
    }
?>

In your 1.8 version I introduced an optional parameter in the constructor that allows me to avoid the initial 6 second sleep for the first query (of course this should only be used when one is sure to have waited that time before).

So here is my old modification:

<?php 
    
private $timestamp ,
            
$query;
    
    
// Constructor
    
function LFSWorldSDK($idk$ps false$initial_sleep true ) {
        
$this->ps $ps;
        
$this->idk $idk;
        
$this->compression = (function_exists('gzinflate')) ? 0;
        
$this->timestamp time( );
        if (
$initial_sleep == false// this will cause the first query to be done immediately 
            
$this->timestamp -= 5
    }
    
// Core Functions.
    
function make_query($qryStr$file 'get_stat2.php') {
        if (!
$this->ps){
            
$delta time( ) - $this->timestamp;
            if (
$delta 5)         // only sleep if necessary ...
                
sleep($delta);  // ... and only as long as necessary (up to 6 seconds because 5 will fail occasionally)
            
$this->timestamp time( );
        }
        
$data = @file_get_contents("http://www.lfsworld.net/pubstat/{$file}?version=1.4&idk={$this->idk}&ps={$this->ps}{$qryStr}&c={$this->compression}&s=2");
        
$data = ($this->compression) ? gzinflate($data) : $data;
        
$data unserialize($data);
        if (
is_array($data)) return $data;
        return array();
    }
?>

I like the error handling of your new version:

<?php 
    
function make_query($qryStr) {
        if (!
$this->ps)
            
sleep(6);
        
$data file_get_contents("http://www.lfsworld.net/pubstat/get_stat2.php?version=1.4&idk={$this->idk}&ps={$this->ps}&c={$this->compression}&s=2{$qryStr}");
        if (
$this->compression)
            
$data gzinflate($data);
        if (
$this->is_lfsw_error($data))
            return 
$this->make_query($qryStr);
        
$return = @unserialize($data);
        if (
$return === FALSE)
            return 
$data;
        else
            return 
$return;
    }
    function 
is_lfsw_error($data) {
        if (
$data == 'can\'t reload this page that quickly after another')
            return 
TRUE;
        else
            return 
FALSE;
    }
?>

BUT, you really shouldn't call make_query within itself without any fallback, because you could easily end up in an endless-loop.

So I would suggest you introduce some counter or whatever to end that loop after X loops if necessary (just keep in mind that LFS-World could be down or whatever).

I will try to use the 1.9 version in my new HoT Tracker (maybe having it modified a little bit).

Great work!

HorsePower
Quote from HorsePower :Then, in the flag-conversion method, I missed some flags (SHIFTER and AUTOCLUTCH) Furthermore, as far as I understood it, I think some of these flags might already be obsolete. According to Victors post we have

Ah, crap, I'll add those, but I'm also going to keep the old ones (Just In Case, or if Vic would like to speak up about them, that would be great).

Quote from HorsePower :Then I didn't like these flag-identifier too much, so I added a function exporting a simple string of letters (which are commonly used I guess):

Ok, I feel that can be handled outside of the SDK, but I might add a function to return it like the LFS World Website.

Quote from HorsePower :In your 1.8 version I introduced an optional parameter in the constructor that allows me to avoid the initial 6 second sleep for the first query (of course this should only be used when one is sure to have waited that time before).

I think the idea is a good one, but as you said they must be sure to have waited before they attempt the next query, I trust you programmers will do that, so I'll implement it also.

Quote from HorsePower :I like the error handling of your new version:

Thank you, I worked hard on that .

Quote from HorsePower :BUT, you really shouldn't call make_query within itself without any fallback, because you could easily end up in an endless-loop. So I would suggest you introduce some counter or whatever to end that loop after X loops if necessary (just keep in mind that LFS-World could be down or whatever).

There always is a but when it comes to someone complementing me. I tested this with a failed connection to the LFS World website (I turned off my wireless card, then made the query) and felt how the SDK handled it was quite graceful. I'll leave it as is for now, but I'll retest to see if it is needed.

No, no, thank you for your hard work, and now that your helping, can I get your first name and last name so that I might add you as a co-author of the SDK.
LFSWorldSDK 1.9.0
LFSWorldSDK 1.9.0

Minor Fixes and Improvements (Oh, I fell like Apple with that kind of change log.)
Attached files
LFSWorldSDK1.9.0.zip - 2.8 KB - 555 views
-
(bunder9999) DELETED by bunder9999 : darned php.
There's a bug in the function get_teams.

Instead of

<?php 
$result
[$i]['info'] = $this->convert_team_bits($data['bits']);
?>

it has to be

<?php 
$result
[$i]['bits'] = $this->convert_team_bits($data['bits']);
?>

Regards,

HorsePower
Quote from HorsePower :There's a bug in the function get_teams.

Instead of

<?php 
$result
[$i]['info'] = $this->convert_team_bits($data['bits']);
?>

it has to be

<?php 
$result
[$i]['bits'] = $this->convert_team_bits($data['bits']);
?>

Regards,

HorsePower

Editing and Fixing now ... sorry guys thanks for look out HP .
Attached files
LFSWorldSDK1.9.1.zip - 2.8 KB - 562 views
No problem mate,

btw, the new tracker will use the 1.8 version, since for 1.9 the returning arrays have changed a bit (e.g. you already convert team bits in the SDK). Since I store the team bits on DB level in the tracker, I didn't want to change and test everything again.

Other than that I did some modifications on the SDK to better suite my purposes.

But of course I recommend to use your SDK (in what version ever).
I modified the SDK to support CURL for those of us on hosting without file_get_contents(), namely me The method will default to CURL but use file_get_contents() if it is not available.

Modify ->makeQuery() method

$data = $this->getUrl("http://www.lfsworld.net/pubstat/get_stat2.php?version=1.4&idk={$this->idk}&ps={$this->ps}&c={$this->compression}&s=2{$qryStr}");

Modify ->getProgress() method

return json_decode(array_pop(explode("\n", $this->getUrl('http://www.lfsworld.net/pubstat/hostprogress.php?host='.urlencode($host)))), TRUE);

Add new method

function getUrl($url){
if (function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
return curl_exec($ch);
} else {
return file_get_contents($url);
}
}

Becky, you might like the OOP version of the cURL lib that I made, incomplete, but I think you'll be able to finish it off if you so desire. I also have an IMAP OOP lib, that's really useful for connecting to GMail.
Attached files
cURL.zip - 913 B - 540 views
IMAP.zip - 720 B - 536 views
It's only 4 lines hun *scratches head* feel free to tidy it up if you will, actually I've noticed my personal code has been really messy lately and I thinks it's because I'm midway through adapting to new standards at work.

Cheers for the LFSWorld SDK, it saved a ton of time reinventing the wheel. Usually on my own stuff I like to use as few libraries as possible, that's sort of the point, but I really didn't fancy it and wanted to play with .js
This is what you've made possible babe, a fully sortable, searchable and far prettier LFS World host list :P I'm still working on it and adding functionality, but cool start no? I'm chuffed with it so far anyway, but lots of bells and whistles are still to come as I start putting the first useable public facing pieces of my project together.


Preview (May break during testing)
Attached images
LFSW-Sorting.jpg
That's SWEET! Becky, I would love to learn JS properly but I've not really had the time. What with everything really becoming UI driven I think I need to start learning it for real as this using can'ed code is no longer working.

(I'm thinking about a MUCH better version of phpMyAdmin that will allow you to update the database with an asynchronous query.)

Great work there. Love it!
Hi,
I want to create TOP20 of my fastest laps, but I don't know how to sort the column WR-diff

<?php 
php

    
include('lfsworldsdk.php');
    
    
$trackcode = array(
        
'000' => 'BL1',
        
'001' => 'BL1R',
        
'010' => 'BL2',
        
'011' => 'BL2R',
        
'020' => 'BL3',
        
'100' => 'SO1',
        
'101' => 'SO1R',
        
'110' => 'SO2',
        
'111' => 'SO2R',
        
'120' => 'SO3',
        
'121' => 'SO3R',
        
'130' => 'SO4',
        
'131' => 'SO4R',
        
'140' => 'SO5',
        
'141' => 'SO5R',
        
'150' => 'SO6',
        
'151' => 'SO6R',
        
'200' => 'FE1',
        
'201' => 'FE1R',
        
'210' => 'FE2',
        
'211' => 'FE2R',
        
'220' => 'FE3',
        
'221' => 'FE3R',
        
'230' => 'FE4',
        
'231' => 'FE4R',
        
'240' => 'FE5',
        
'241' => 'FE5R',
        
'250' => 'FE6',
        
'251' => 'FE6R',
        
'300' => 'AU1',
        
'310' => 'AU2',
        
'320' => 'AU3',
        
'330' => 'AU4',
        
'400' => 'KY1',
        
'401' => 'KY1R',
        
'410' => 'KY2',
        
'411' => 'KY2R',
        
'420' => 'KY3',
        
'421' => 'KY3R',
        
'500' => 'WE1',
        
'501' => 'WE1R',
        
'600' => 'AS1',
        
'601' => 'AS1R',
        
'610' => 'AS2',
        
'611' => 'AS2R',
        
'620' => 'AS3',
        
'621' => 'AS3R',
        
'630' => 'AS4',
        
'631' => 'AS4R',
        
'640' => 'AS5',
        
'641' => 'AS5R',
        
'650' => 'AS6',
        
'651' => 'AS6R',
        
'660' => 'AS7',
        
'661' => 'AS7R'
    
);
    
    function 
convert_lfsw_time($time) {
        return 
sprintf('%d:%05.2f'floor($time 60000), (($time 60000) / 1000));
    }

    
$wr $SDK->get_wr();
    
$pb $SDK->get_pb('adamshl');
    
    echo 
'<table width=\"400\" border=\"1\">';
    echo 
'<tr><td> </td><td>Track</td><td>Car</td><td>Time</td><td>WR-diff</td><td>Laps</td><td>Date</td></tr>';
    
//asort($pb);
    
$lp '1';    
    foreach (
$pb as $id) {
        if(
$id['laptime'] != '0' AND $lp <= '20') { 
            echo 
'<tr><td>' $lp++ . '.</td>'
            
'<td>' $trackcode[$id['track']] . '</td>'
            
'<td>' $id['car'] . '</td>'
            
'<td>' convert_lfsw_time($id['laptime']) . '</td>';
            foreach (
$wr as $diff) {
                if(
$diff['track'] == $id['track'] & $diff['car'] == $id['car']) { 
                    echo 
'<td>' convert_lfsw_time($id['laptime'] - $diff['laptime']) . '</td>';
                }
            }
            echo 
'<td>' $id['lapcount'] . '</td>'
            
'<td>' date("d.m.Y H:i"$id['timestamp']) . '</td></tr>';
        }
    }
    echo 
'</table>';
    

?>

Can anyone help me? I use LFSWorldSDK v1.9.1
Dygear, if you're looking at getting into JS it might be worth looking at jQuery or similar frameworks. They do save you a lot of time, and you're still writing JS at the end of the day

Quote from adamshl :Hi,
I want to create TOP20 of my fastest laps, but I don't know how to sort the column WR-diff

You need to sort the array before you start displaying it. The simplest way is to use usort and create your own function to compare the WR diffs as the callback. It's not terribly efficient, but it should be good enough to get you going
After you get your PBs you need to sort them, then display only the first 20, fastest to slowest.

I have used usort before for this purpose but have lost the code somewhere. As an alternative I think you could use array_multisort.
Quote from the_angry_angel :Dygear, if you're looking at getting into JS it might be worth looking at jQuery or similar frameworks. They do save you a lot of time, and you're still writing JS at the end of the day

In fact, I have been using jQuery for some time now. Still don't quite have the handle on JS as I would like. There is something about the DOM and jQuery that I just don't get. Everything I have been reading up to this point has been giving me a very high level overview of the DOM and it's interaction with jQuery, making very hard to do some things that should be very simple to implement.

For example, getting the column's header in a <table> '<thead> <tbody>' pair. Finding it damn near impossable to even get the child's instance (for the lack of better term). Really I need a glossary of html terms in reference to using JS. While I used instance, I think now that a better term for it would be to find one's children count, or the offspring's number, or the child node's numerical (for example when there are multiple of the same tag inside of the document tree, like more then one td.)
Hello

I am not that good in php so I have a question.
I am working on a website for a lfs team. All members of that team will have their own profile page. On that page I want to display LFSWorld stats.
No i found out about this script (LFSWorldSDK1.9.1) and uploaded it on the server.
I think it works the way it should, but how can I display it in a table? like 2 columns with left side what the data is en the right side the value of lfs world. (I only care about the pst part)

for example:

Distance driven in km | 6499559
Fuel burned | 171064

Thanks in advance,
Hoitjes

<?php 
php    
include('lfsworldsdk.php');    
<
table>
    <
thead>
        <
tr>
            <
th>Key</th>
            <
td>Val</td>
        </
tr>
    </
thead>
    <
tbody>
php    forEach ($SDK->get_pst('Dygear') as $key => $val):    
        <
tr>
            <
th>echo $key; </th>
            <
td>echo $val; </td>
        </
tr>
php    endForEach;    
    </
tbody>
</
table>
?>

I probably am stupid but does this supose to dsiplay?
Key Val 0 Array
Thanks,
Hoitjes

FGED GREDG RDFGDR GSFDG