The online racing simulator
PHP4/5 - LFSWorldSDK, class for stats retrieval
(288 posts, started )
In the next version of this (comming soon I might add) we are going to compress the querys for a few good reasons. One, if you have premium stats, it saves you money. Two, if you get uncompressed data then you know it's an error and as such the file could throw a warning out to you via the trigger_error function. As ever, it will be up to the user of the SDK to catch these errors.
Got quite a few bits n peices done with this SDK, one which is almost finished but just needs some touching up, but mostly just little bits n peices but i wouldnt have been able to do any of it without the SDK


One thing thats just been pointed out to me:
When pulling the WR holders list, XRT @ 000 is 'Svemirko Joca' however only 'Svemirko' is given. Im not sure if this would be possible to fix... just tried what i thought might work, and it seems okay

addition to LFSWorldSDK.php function get_wr()

<?php 
                
$result
[] = array(
                    
'id_wr' => $fragment[0],
                    
'track' => $fragment[1],
                    
'car' => $fragment[2],
                    
'time' => $fragment[3],
                    
'flags_hlaps' => $fragment[4],
                    
'racername' => $fragment[5],
                    
'racername2' => $fragment[6]
?>

and then

<?php 
$racername 
$data['racername']." ".$data['racername2'];
?>

Works a treat, wasnt sure if it'd throw a wobbler looking for a 6th peice of info when 99.9% of them dont have one.

<?php 
$result
[] = array(
    
'id_wr' => $fragment[0],
    
'track' => $fragment[1],
    
'car' => $fragment[2],
    
'time' => $fragment[3],
    
'flags_hlaps' => $fragment[4],
    
'racername' => preg_replace('/(.+\s){5}/U'''implode(' '$fragment))
);
?>

Should work for any number of spaces in usernames.
filur, you rock dude! Oh and nice they put a spell check in the new version of firefox!
Just a quick heads up for you all, version 1.3 is going to be uploaded to you all very soon so that you can use it. It fixes some bugs found in the last version, such as the error message 'LFSWorld Error : $str' now it will return that error string for you to deal with. Might change that behaviour in the future.

Big fix on the get_wr, hotlap_chart functions. They should now return the correct name for racername. Also I've modded the get_hl, and get_pb functions to make use of the same function set as the other two. Keeps the code nice and homogeneous.
Updated the link at the top of page.
There will be an update for this VERY soon that will have proper 1.3 support. I had a working version, but ... as I just reformatted my hard drive, I neglected to backup that one file. Sorry for the delay.
Due to CVS issues, here is the code ... I'll attempt to upload the code to the CVS when I get back from work.

<?php
class LFSWorldSDK {
var $ps;
var $idkey;
var $version;
var $lasthit;
var $action;
var $racer;
var $track;
var $car;
var $control;
var $log_filter;
var $lines;
var $starttime;
var $format;
var $c;
function LFSWorldSDK($IdKey, $Premium = false, $Version = '1.3') {
$this->ps = $Premium;
$this->idkey = $IdKey;
$this->version= $Version;
$this->lasthit= 0;
$this->query = null;
}
function make_query_string() {
$vars = array();
foreach ($this->get_option_set() as $key => $item) {
$vars[$key] = "{$key}={$item}";
}
foreach ($this->get_request_vars() as $key => $item) {
$vars[$key] = "{$key}={$item}";
}
return 'http://www.lfsworld.net/pubstat/get_stat2.php?' . implode('&', $vars);
}
function get_option_set() {
return array(
'version' => $this->version,
'idk' => $this->idkey,
'ps' => $this->ps,
);
}
function get_request_vars() {
return array(
'action' => $this->action,
'racer' => urlencode($this->racer),
'car' => $this->car,
'track' => $this->track,
'control' => $this->control,
'log_filter' => $this->log_filter,
'lines' => $this->lines,
'starttime' => $this->starttime,
'format' => $this->format,
'c' => $this->c,
);
}
function get_query_results() {
if ($this->ps == TRUE || time() - $this->lasthit > 5) {
$this->lasthit = time();
if ($str = file_get_contents($this->make_query_string())) {
if ($this->c == 1) {
$tmpfile = tmpfile();
if (file_put_contents($tmpfile, $str)) {
$gz = gzopen($tmpfile, "rb");
$str = gzpassthru($gz);
gzclose($tmpfile);
return preg_replace("/\n$/", "", $str);
}
}
elseif ($this->c == 2)
return preg_replace("/\n$/", "", gzuncompress($str));
elseif ($this->c == 3)
return preg_replace("/\n$/", "", gzinflate($str));
else {
if (count(explode("\n", $str)) == 1)
return preg_replace("/\n$/", "", $str); // Don't Ask Don't Tell.
else
return preg_replace("/\n$/", "", $str);
}
}
}
else {
sleep(1);
return $this->get_query_results();
}
}
function get_hl($racer, $track = NULL, $car = NULL) {
$this->action = 'hl';
$this->racer = $racer;
foreach (explode("\n", $this->get_query_results()) as $line => $data) {
preg_match_all('/(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+)/U', $data, $fragment);
$iteration = array(
'id_hl' => $fragment[1][0],
'track' => $fragment[2][0],
'car' => $fragment[3][0],
'split1' => $fragment[4][0],
'split2' => $fragment[5][0],
'split3' => $fragment[6][0],
'time' => $fragment[7][0],
'flags_hlaps' => $fragment[8][0]
);
if ($track != NULL || $car != NULL) {
if ($iteration['track'] == $track && $car == NULL)
$result[] = $iteration;
if ($iteration['car'] == $car && $track == NULL)
$result[] = $iteration;
if ($iteration['track'] == $track && $iteration['car'] == $car)
return $iteration;
}
else
$result[] = $iteration;
}
return $result;
}
function get_pb($racer, $track = NULL, $car = NULL) {
$this->action = 'pb';
$this->racer = $racer;
foreach (explode("\n", $this->get_query_results()) as $line => $data) {
preg_match_all('/(.+)\s(.+)\s(.+)\s(.+)/U', $data, $fragment);
$iteration = array(
'track' => $fragment[1][0],
'car' => $fragment[2][0],
'time' => $fragment[3][0],
'lapcount' => $fragment[4][0]
);
if ($track != NULL || $car != NULL) {
if ($iteration['track'] == $track && $car == NULL)
$result[] = $iteration;
if ($iteration['car'] == $car && $track == NULL)
$result[] = $iteration;
if ($iteration['track'] == $track && $iteration['car'] == $car)
return $iteration;
}
else
$result[] = $iteration;
}
return $result;
}
function get_stats($racer) {
$this->action = 'pst';
$this->racer = $racer;
$data = explode("\n", $this->get_query_results());
$result = array(
'distance' => $data[0],
'fuel' => $data[1],
'laps' => $data[2],
'hosts' => $data[3],
'wins' => $data[4],
'second' => $data[5],
'third' => $data[6],
'finished' => $data[7],
'quals' => $data[8],
'pole' => $data[9],
'credits' => $data[10],
'drags' => $data[11],
'dragwins' => $data[12],
'online' => $data[13],
'hostname' => $data[14],
'time' => $data[15],
'track' => $data[16],
'car' => $data[17],

);
return $result;
}
function hotlap_chart($track, $car, $control = NULL) {
$this->action = 'ch';
$this->track = $track;
$this->car = $car;
if ($control != NULL)
$this->control = $control;
foreach (explode("\n", $this->get_query_results()) as $line => $data) {
preg_match_all('/(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+?)/U', $data, $fragment);
$result[] = array(
'split1' => $fragment[1][0],
'split2' => $fragment[2][0],
'split3' => $fragment[3][0],
'time' => $fragment[4][0],
'flags_hlaps' => $fragment[5][0],
'racername' => $fragment[6][0]
);
}
return $result;
}
function get_wr() {
$this->action = 'wr';
foreach (explode("\n", $this->get_query_results()) as $line => $data) {
preg_match_all('/(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+)\s(.+?)/U', $data, $fragment);
$result[] = array(
'id_wr' => $fragment[1][0],
'track' => $fragment[2][0],
'car' => $fragment[3][0],
'split1' => $fragment[4][0],
'split2' => $fragment[5][0],
'split3' => $fragment[6][0],
'time' => $fragment[7][0],
'flags_hlaps' => $fragment[8][0],
'racername' => $fragment[9][0]
);
}
return $result;
}
function get_hosts() {
$this->action = 'hosts';
$string = $this->get_query_results();
$result = array();
for ($pointer = 0, $i = 0; $pointer <= strlen($string); $i++) {
$NumberOfRacers = @unpack("c", substr($string, $pointer + 52, 1));
$NumberOfRacers = $NumberOfRacers[1];
$NumberOfRacersLen = $NumberOfRacers * 24;
$PointerPast = $NumberOfRacersLen + 53;
$result[$i] = array();
if (($result[$i] = @unpack("a32hostname/A4tmlt/A4tcrm/icars/irules/claps/cqual/cspare1/cspare2/cnrofracers/a{$NumberOfRacersLen}racernames", substr($string, $pointer, $PointerPast)))) {
$result[$i]['racernames'] = preg_split("/\\0/", $result[$i]['racernames'], -1, PREG_SPLIT_NO_EMPTY);
$result[$i]['tmlt'] = unpack("ctype/cmain/a1letter/ctestId", $result[$i]['tmlt']);
$result[$i]['tcrm'] = unpack("ctrack/cconfig/creversed/cmax", $result[$i]['tcrm']);
}
else
unset($result[$i]);
$pointer += $PointerPast;
}
return $result;
}
function get_teams() {
$this->action = 'teams';
$string = $this->get_query_results();
$result = array();
for ($pointer = 0, $i = 0; $pointer <= strlen($string); $i++) {
$infoLen = @unpack("S", substr($string, $pointer + 298, 2));
$infoLen = $infoLen[1];
$nrMembers = @unpack("S", substr($string, $pointer + 300 + $infoLen, 2));
$nrMembers = $nrMembers[1] * 24;
$PointerPast = 302 + $infoLen + $nrMembers;
$result[$i] = array();
if (($result[$i] = @unpack("a128team/a6tag/a32country/a128url/Ibits/Sinfo_len/a{$infoLen}info/Snr_members/a{$nrMembers}members", substr($string, $pointer, $PointerPast)))) {
$result[$i]['members'] = preg_split("/\\0/", $result[$i]['members'], -1, PREG_SPLIT_NO_EMPTY);
$result[$i]['info'] = urldecode($result[$i]['info']);
}
else
unset($result[$i]);
$pointer += $PointerPast;
}
return $result;
}
function get_hlog($log_filter = NULL, $lines = NULL, $control = NULL, $starttime = NULL) {
$this->action = 'hl_log';
$this->format = 3;
if ($log_filter != NULL)
$this->log_filter = $log_filter;
if ($lines != NULL && $lines >= 1 && $lines <= 150)
$this->lines = $lines;
if ($control != NULL)
$this->control = $control;
if ($starttime != NULL)
$this->starttime = $starttime;
$string = $this->get_query_results();
$result = array();
for ($pointer = 0, $i = 0; $pointer <= strlen($string); $i++) {
$result[$i] = array();
if (($result[$i] = @unpack("itime/a24racer/a32country/A4tcrc/i4split/Spos/Sflags/iid_hl", substr($string, $pointer, 88)))) {
$result[$i]['tcrc'] = unpack("ctrack/cconfig/creversed/ccar", $result[$i]['tcrc']);
}
else
unset($result[$i]);
$pointer += 88;
}
return $result;
}
}
?>

Issues, feedback, comments or anything?
I see nobody is replying...well i dl'ed the sdk and the updated code and will give it a go when i get back from work. Thanks dygear
Hm i'm no programer so i would appreciate if you could help me around this...When i try to get my pb's it just says "Laps: 0" and if i try get my hotlaps it says "Array ( [id_hl] => [track] => [car] => [split1] => [split2] => [split3] => [time] => [flags_hlaps] => )"
And since 1.3 you must use your pubstats id...where do i put it?
Quote from SkyNet :since 1.3 you must use your pubstats id...where do i put it?

The id key is passed to the object at creation, it is actually required.
$object = new LFSWorldSDK('id key goes here');

Quote from SkyNet :if i try get my hotlaps it says "Array ( [id_hl] => [track] => [car] => ...

Arrays can be seen as collections of variable<->value pairs, to access the value of a variable, you use:
$the_array['variable_name'];

A simple way to iterate thru the entire array:
$hotlaps = get_hl('filur');
foreach ($hotlaps as $lap) {
echo $lap['track'].' in '.$lap['car'].': '.$lap['time'].'<br />';
}

More info on arrays in PHP:
http://php.net/manual/en/language.types.array.php
http://php.net/manual/en/ref.array.php
I don't think we've updated the examples part of it as of 1.0. I'm going to have to do that later .
Just a little question: Someone had this gzuncompress-error with an older version of LFSWorldSDK.


[B]Warning[/B]: gzuncompress(): data error in ...

ATM, I'm also programming a little script, and I also get this message from the 3rd time on I query LFSW (10 sec between queries).

I use this code (for example for WR's):

<?php 
gzuncompress
(file_get_contents("http://lfsworld.net/pubstat/get_stat2.php?version=1.3&action=wr&c=2&idk=".$this->id_key));
?>

How can I fix it? Any help appreciated! Thanks in advance!
Hey thanks i got it working.
All the tracks are in three digit numbers, how do i know which is which? I only know that 000 is blackwood.
And then how do i rename them their real names, so that it would show me "Blackwood GP" instead of "000".
Quote from HorsePower :

[B]Warning[/B]: gzuncompress(): data error in ...

ATM, I'm also programming a little script, and I also get this message from the 3rd time on I query LFSW (10 sec between queries).

I use this code (for example for WR's):

<?php 
gzuncompress
(file_get_contents("http://lfsworld.net/pubstat/get_stat2.php?version=1.3&action=wr&c=2&idk=".$this->id_key));
?>

How can I fix it? Any help appreciated! Thanks in advance!


<?php 
if ($gzstr file_get_contents(' ... ')) {
    if (
$str = @gzuncompress($gzstr))
        
/* it's all good. */
    
else
        
/* it's most likely an error message in plain text ($gzstr). */
}
else
    
/* can't get output. */
?>

Thanks very much! Will test that soon.
Ok, implemented it. The error message I get is

"can't reload this page that quickly after another"

Is this a PHP problem, or a Apache problem (I'm using XAMPP at my localhost to test my work).

I mean, as far as I understood, I can use pubstat every 5 seconds. But also if I wait 10 seconds between queries I get this message every single time from the 2rd query in a row on.

EDIT: In fact, I get this error from the 2nd query on.

EDIT: And even with 120 seconds between queries. Must be a PHP/Apache problem, right?
Quote from HorsePower :... as far as I understood, I can use pubstat every 5 seconds. But also if I wait 10 seconds between queries I get this message every single time from the 3rd query ...

Make sure you're not running something else that's querying pubstats, as it's limited per IP. Can't see how it could technically be caused by Apache or PHP.

Edit: maybe it's also limited by id-key, if you're using the same key from separate locations. (?)
I found this post, http://www.lfsforum.net/showthread.php?p=68428#post68428

He can solve his problem by using the 5-second interval. Strange. 120 seconds don't work for me.

And I have no other processes grabbing LFSW. We have a homepage, which will query LFSW at maximum every 60 seconds, but only if someones klicking on it. And that are only up to 30 people per day. And this page uses a different ID-Key.

Anyway, thanks for you comments. This is off-topic here. If I can't solve the problem, I maybe post elsewhere.

EDIT: Yet a last note here: It works for uncompressed LFSW-output. Now I'm really confused.
Quote from HorsePower :I found this post [...] He can solve his problem by using the 5-second interval. Strange. 120 seconds don't work for me [...] EDIT: Yet a last note here: It works for uncompressed LFSW-output. Now I'm really confused.

I run alot of pubstat stuff, everything compressed (gzcompress), everything on 5s. tarpit. Tried running the script from command line?
Nope. How? And what's different there?

The only change I have to make is to remove the &c=2 and the gzuncompress stuff.

PHP4/5 - LFSWorldSDK, class for stats retrieval
(288 posts, started )
FGED GREDG RDFGDR GSFDG