The online racing simulator
The code has once again been updated.

1) Fixed an error in the Host Name Colour conversion that caused text following the table to be the incorrect colour. Thanks to Tristancliffe for spotting that one.

2) Added second array to contain the In Game Name or name you wish to show in the table in the letter case you type, but must be in the same sequence as the Team Members array. Thanks to Tristancliffe for that idea.

3) Added a link to refresh the screen if hosts file not found. Thanks to Tristancliffe for the code

Dean


<?php 

//******************************************
// Add Team Member names to$TeamMembers
// LFS User Name and in lowercase
// Lowercase used to reduce typos
// in the username
//
// Also add the team Members In Game
// Name in $InGameName (any case will do)
// MUST be in the same order as $TeamMembers
//******************************************
$TeamMembers = array("lfs name","lfs name","lfs name","lfs name","lfs name");
$InGameName = array("lfs name","lfs name","lfs name","lfs name","lfs name");
//**********************************
 
// function to safely trim null-terminated strings
// could just use trim () in this example though
function trim_c_string ($string) {
    
$new "";
    
$len strlen ($string);
    for (
$x=0$x<$len$x++) {
        if (
$string[$x] != "\0"$new .= $string[$x];
        else break;
    }
    return 
$new;
}
 
// Function to remove the colour code data from a string
function remove_colour_codes($String){
$ColCodes = array("^0","^1","^2","^3","^4","^5","^6","^7","^8","^9");
$NewString str_replace($ColCodes"",$String);
return 
$NewString;
}
 
// Function used by format_host_colours function to display correct colour value in html format
function get_colour($ColourNum){
switch (
$ColourNum) {
case 
"0";
     
$ColourName "#000000"//Black
     
break;
case 
"1";
     
$ColourName "#FF0000"//Red
     
break;
case 
"2";
     
$ColourName "#00FF00"//Pastel Green
     
break;
case 
"3";
     
$ColourName "#FFFF00"//Yellow
     
break;
case 
"4";
     
$ColourName "#0000FF"//Light Blue
     
break;
case 
"5";
     
$ColourName "#FF0080"//Light Purple
     
break;
case 
"6";
     
$ColourName "#00FFFF"//Turquoise
     
break;
case 
"7";
     
// Remove comment marks on next line if not a white background
     //$ColourName = "#FFFFFF";    //White
     // Add Comment marks to next line if not a white background
     
$ColourName "#808080";    //Dark Grey
     
break;
case 
"8";
     
$ColourName "#00FF00"//Pastel Green
     
break;
}
return 
$ColourName;
}
 
// Function to replace the ^x codes in the Host name to show correct colours on the screen
function format_host_colours($HostName){
for(
$i 0$i strlen($HostName); $i++){
    if(
substr($HostName$i1) == "^"){
     
$CharPos strpos($HostName"^"$i);
     
$ColNum substr($HostNamestrpos($HostName"^"$i) + 1,1);
     
$ColourString get_colour(substr($HostNamestrpos($HostName"^"$i) + 1,1));
     if(
$i == "0"){
        
// If ^ found at the start of the host string remove the ^[num]
        
$TmpString substr($HostName,$i+2);
        
// Add the html font code to the start of the string and append the
        // variable $TmpString with the ^[num] removed
        
$HostName "<font color='$ColourString'>".$TmpString;
     }
     else{
        
// Get the left part of the string to the next ^[num]
        
$LTmpString substr($HostName,0,$i);
        
// Get the right part of the string after the ^[num]
        
$RTmpString substr($HostName,$i+2);
        
// Add the html close font and add the new html colour to the end of the
        // Left part of the string then add the right part of the string
        
$HostName $LTmpString."</font><font color='$ColourString'>".$RTmpString;
     }
    }
}
// Close any html font tag left open in the above
$HostName $HostName."</font>";
Return 
$HostName;
}
 
// Function to display Team Members online in a dynamic table
function display_expandable_table($TeamMembers$LfsUsers$InGameName){
// Set the variable to count the members online
$MembersOnline 0;
// Count the number of members
$TotalMembers count($TeamMembers);
// Create Header row for the table
echo "<tr bgcolor='#CCCCCC' align='center'><th>Team Racer</th><th>On Server</th></tr>";
// search through the file for Team Members and add a row to the
// table showing the name and server they are on
foreach ($LfsUsers as $LfsUser => $LfsHost) {
    for(
$i 0$i $TotalMembers$i++){
     if(
strtolower($LfsUser) == $TeamMembers[$i]){
        
$LfsUser remove_colour_codes($LfsUser);
        
$LfsHost format_host_colours($LfsHost);
        echo 
"<tr bgcolor='#FFFFFF'>";
        echo 
"<td>$InGameName[$i]</td>";
        echo
"<td>$LfsHost</td></tr>";
        
$MembersOnline =+ 1;
     }
    }
}
// Display this row only if no members are online
if($MembersOnline == 0){
    echo 
"<tr bgcolor='#FFFFFF' align='center'><td>No Members</td><td>Are Online</td></tr>";
}
}
 
// Function to display all Team Member Status
function display_fixed_table($TeamMembers$LfsUsers$InGameName){
/// Count the number of members
$TotalMembers count($TeamMembers);
// Create Header row for the table
echo "<tr bgcolor='#CCCCCC' align='center'><th>Team Racer</th><th>Status</th><th>On Server</th></tr>";
for(
$i 0$i $TotalMembers$i++){
    echo 
"<tr bgcolor='#FFFFFF'>";
    foreach (
$LfsUsers as $LfsUser => $LfsHost) {
     if(
strtolower($LfsUser) == $TeamMembers[$i]){
        
$LfsHost format_host_colours($LfsHost);
        echo 
"<td>$InGameName[$i]</td>";
        echo 
"<td>Online</td>";
        echo
"<td>$LfsHost</td></tr>";
        
$Found "True";
        break;
     }
     else{
        
$Found "False";
     }
    }
     if(
$Found == "False"){
        echo 
"<td>$InGameName[$i]</td>";
        echo 
"<td>Offline</td>";
        echo
"<td>&nbsp</td></tr>";
     }
}
}
 
// init some vars
$LfsUsers = array ();
$x 0;
$LfsHostList "";
// get the hostlist
$LfsHostList file_get_contents ("http://lfsworld.net/pubstat/get_stat2.php?action=hosts");
$len strlen ($LfsHostList);
// Thanks to Tristiancliffe for this line. It is a refresh link
if ($len 52) exit ("<a href='javascript:document.location.reload();'>Couldn't get hostlist. Click to retry...</a>");
 
// parse the data
while ($x $len) {
    
$LfsHostName "";
    
$nr_racers 0;
    for (
$y=0$y<32$y++) $LfsHostName .= $LfsHostList[$x++];
    
$LfsHostName trim_c_string ($LfsHostName);
    
$x += 20// skip some host-data
    
$nr_racers ord ($LfsHostList[$x++]);
    for (
$w=0$w<$nr_racers$w++) {
        
$LfsUserName "";
        for (
$y=0$y<24$y++) $LfsUserName .= $LfsHostList[$x++];
        
$LfsUsers[trim_c_string ($LfsUserName)] = $LfsHostName;
    }
}
 
// Create table to hold data
echo "<center><br>";
echo 
"<table border='1' bordercolor='C0C0C0' cellpadding='4' cellspacing='0' style='border-collapse: collapse' style='font-family: Verdana; font-size: 10pt'>";
 
//*************************************************
// Comment and Uncomment the type of table you want
//*************************************************
display_expandable_table($TeamMembers$LfsUsers$InGameName);
display_fixed_table($TeamMembers$LfsUsers$InGameName);
/* Close the table */
echo "</table></center><br>";

?>

Note : 4/11/05 18:18GMT For those who have already downloaded this code today there was a small error inside one of the functions, you may need to download it again. Inside one of the functions [$i] was missing from $InGameName when writing the data into the table. Corrected in the above code. Sorry
I can't code, but I'm not short of crazy ideas (most of which don't work anyway)...

Cheers D34NO
This Script is great.
But i have a lil Problem with it.
I only wanna use the upper part of it, cause the lower part is too wide for our Page.
How can i remove the lower part?

greez S.Menkhoff
Quote from Sven Menkhoff :This Script is great.
But i have a lil Problem with it.
I only wanna use the upper part of it, cause the lower part is too wide for our Page.
How can i remove the lower part?

greez S.Menkhoff

Please explain what you mean by upper an lower parts..
The script just creates a table so there is no upper and lower part.. There are 2 options at the bottom to display either a expandable or fixed table? (as listed below), to comment out either of the rows as described in the comments place // at the start of the line you do not want

//*************************************************
// Comment and Uncomment the type of table you want
//*************************************************
display_expandable_table($TeamMembers, $LfsUsers, $InGameName);
display_fixed_table($TeamMembers, $LfsUsers, $InGameName);

Regards
Dean
Thank you very much.
This was want i wanted to get off:
display_fixed_table($TeamMembers, $LfsUsers, $InGameName);

Now it works like i want to have it
oops I did it again...
Hi!
A small and perhaps dumb question...
I have used the function ch (chart) and recived this (and more).
What character is used after the name, I tried to search for ' ' but strpos() miss. I think it should be something like "\\n" but that don't work either. I hope there is something else than ' ' or how do you solve names with a space 'Nisse Hult"?

135260 517 biggie
135370 513 Flotch
135590 517 RMachucaA
135670 517 fab
...

Would be glad for a answer
/Tooby the noob
The name *should* be terminated with a \0 (thats how it comes directly from LFSWorld).

But I've not looked over the rest of this thread to see if its being stripped.
the _text_ results (which is everything except the hosts and teams-query) just have basic Linux line-endings "\n" and don't contain any null-strings

From the first post:
-------------------------------------------------------------------------------------
Legend: (all output is in plain text, except the hosts and teams output, which have binary data)
-------------------------------------------------------------------------------------
oops, just to read then. I did not manage to get it to work but after some more tries it did.

Thanx
/Tooby
is there a way to resolve a LFS username to the Player name used inside the game ? (when i ask for the server list i get the usernames .. but i would like to display the player names) .. any ideas ?
not via lfsworld - i just don't have player names stored, so i can't display them.
whoops. my mistake :s Sorry tooby

/me bows down to Victor
Quote from the_angry_angel :whoops. my mistake :s Sorry tooby

/me bows down to Victor

No problems. Your "mistake" showed me the way

/Tooby
LFS Statistics problem
Hi Victor,

I come here to make a small suggestion in connection with the statistics from the LFS statistics server. I am currently under development of a small code PHP to generate me a .jpg signature (in end of this post) including my principal statistics (statute on LFS, distance, fuel, laps, victories, points). The problem is as follows :
- No problem to obtain distance, fuel, laps, victories and points, by using "http://www.lfsworld.net/pubstat/get_stat2.php?action=pst"

- No problem either with the statute of the pilot thanks to a script which will see whether the pilot is on line among the results of the statistics for hosts : "http://www.lfsworld.net/pubstat/get_stat2.php?action=hosts"

The problem is when i want to mix both of them. The statistics server do not accept two requests one just after the other. I then obtain result only for the first of those. This is why I think that it would be very interesting to obtain the statute of the pilot with the other statistics of the concern pilot, by call of this the page : "http://www.lfsworld.net/pubstat/get_stat2.php?action=pst" by adding for example this statute in first line which would take "1" as value if the pilot is online and "0" if this one is offline. This is only one proposition that I hope you will soon consider. I wait your response impatiently.


P.S. : My current signature which not show my correct status in LFS (always offline = "Hors Ligne" here). It's in french because i'm.




I apologize for my poor english but i'm only a young french of 16 years old which always is on school system. I hope you this will be undertandable...
well there is a problem with just adding a value. I think a lot of parse scripts will then fail to work, so that's not a good idea.

If you have a php install at home, or if you have access to cron or other scheduling software on your current provider, then I'd suggest you make a script that gets the PST-info and your online status and then saves that data to a file. Then the script that generates your signature image can simply read the needed data from that file.
Then schedule that script via cron (or whatever scheduler) to update that data file, say every 2 minutes.

This way you will always have the data available instantly for your signature image and it will always be quite up to date and it doesn't have to access LFS World every time you need to generate your signature image.

Caching is lovely
Not a bad idea ! I will have a look at this. But are sure that it can't be possible to add the statuts of a pilot at the end of his statistics. I think it will be much easy to use for everyone. The script i use to get my personnal LFS status wasn't written by me because i've a very limited level in PHP. I successed to get my stats from the stats page by myself and it's already a little victory for me. So you can imagine that i havn't idea for the schedule's question. I will see what it is with my Host, but after i don't know to manipulate it.

Even if it's not the answer i expected, i want to thank you for your interest . I think we will talk about it again.
ohyea hmm, PST displays only one racer's information at a time, so a 0 or 1 on a new line at the end of the results might not disrupt people's stats-processing. Let me think about it
Thank's a lot ! It will help me a lot if you could do that ! And many people at the same time i think ! And as you sayed, at the end, it might not disrupt people's stats because it's at the the end, so it's an additional ID...
Quote from Victor :ohyea hmm, PST displays only one racer's information at a time, so a 0 or 1 on a new line at the end of the results might not disrupt people's stats-processing. Let me think about it

this would be really helpful...
great idea Eldarion
Quote from Victor :ohyea hmm, PST displays only one racer's information at a time, so a 0 or 1 on a new line at the end of the results might not disrupt people's stats-processing. Let me think about it

An optional 'version' arg on the URL would solve any expansion issues. Say you post Version 1 of PST (the current version), this would be the default version in case no version is specified.
Then a minor addition like the online/offline status could be made version 1.1, and unless version >= 1.1 then don't echo the extra data.

Then as revisions & bugfixes are made, you don't have to worry about busting existing code.
Which is fine, until you get to the stage where it will take a weeks to even understand whats going on, because of a huge amount of if, or switch, statements in a script; instantly becoming unmanagable.

But at least it would work
Quote from the_angry_angel :Which is fine, until you get to the stage where it will take a weeks to even understand whats going on, because of a huge amount of if, or switch, statements in a script; instantly becoming unmanagable.

But at least it would work

Depends on how you architecture it.
If get_stat.php was just a facade with a switch block....

<?php 
switch($version)
{
    case 
1.1:
        include(
'get_stat/1.1.php');
        break;
    case 
1.0:
    default:
        include(
'get_stat/1.0.php');
}
?>

It would probably be more elegant using an OO abstract factory approach, i.e.


<?php 
$statGen 
AbstractStatGen::factory($action$version);
?>

But from what I gather, Vic has a more procedural approach
I'm gradually going off object orientated approaches, in PHP. I've found a lot of OOP code (tested under 5.0.5) is about 10% slower in general. Much nicer to code and alter though, I must agree. But I suppose thats the main reason we're getting updated OOP and PDO in 5.1.
for small scripts, I just use a very straight forward approach. I have the feeling that if you'd setup classes and what not, then by the time php has parsed the classes, it could already have processed the request, had a straight forward approach been used
But for the bigger programs / scripts, classes are great to keep things organised.

Anyway, about that new feature, I do think I'll use version numbers. I'm just thinking about how to keep things organised and simple (from both programming and documentation pov).
Same here; unless there is a good reason to create a class (i.e. a unified API like LFSWPPF)

To keep docs organised, I'd suggest only keeping the current version info in the first post, and attaching older version docs as text documents.
That way new developers coming to lfs will be using the latest version, which is usually what you'd want.

Programatically, I'd suggest a directory structure similar to

*action*/*version*.php

Then you simply include the appropriate file after parsing action and version. (I'd recommend a whitelist of values for action, and a (float) force type for version to ensure system security)
You may want to keep an include that defines the versions that exist for each action, so that you don't have to keep polling the file system to make sure the files exist too.
If the version is not specified, fall back to version 1.0... if an incorrect version is specified, fall back to current version.

The idea being that you want maximum backward compatibility, but encouraging developers to use the latest version.

All of this could be totally impractical depending on how you currently have the stat generation structured, but this is how I would do it.

FGED GREDG RDFGDR GSFDG