The online racing simulator
GET / SET Database (what/where/when) Use?
Hi

I've been trying for few days now to 'set' items into a database, so that I can 'get' them out later to put in a TopUser table.

I've tried

<?php 
    SetCurrentPlayerVar 
("average_speed_kmh"$average_speed_kmh);
?>


<?php 
    SetCurrentPlayerVar
"average_speed_kmh"ToNumGetCurrentPlayerVar"average_speed_kmh" );
?>


<?php 
    SetCurrentPlayerVar
"average_speed_kmh",GetStoredValue$userName "average_speed_kmh" ) );
?>


<?php 
    SetStoredValue
$userName "average_speed_kmh"GetCurrentPlayerVar"average_speed_kmh" ) );
?>


<?php 
    setUserStoredValue
( ("average_speed_kmh"$average_speed_kmh);
?>

Although the item descriptions appear in the database (I suspect its due to my OnConnectClose sub), there's no value there.

Can anyone let me know which of these I should be using, and where/when?

I've included my dskill lapper file as text file to make it easier to open.
Attached images
empty storedvalue dskill keys.png
Attached files
dskill_v0 3.txt - 9.8 KB - 466 views
#2 - Krayy
At first glance, there are syntax errors in your SetUserStoredValue statements (extra opening parentheses) and the GetStoredValue statements should be GetUserStoredValue:

<?php 
...
SetCurrentPlayerVar"lap_time_time",GetUserStoredValue"lap_time_time" ) );
SetCurrentPlayerVar"lap_time_number",GetUserStoredValue"lap_time_number" ) );
SetCurrentPlayerVar"drift_score",GetUserStoredValue"drift_score" ) );
SetCurrentPlayerVar"drift_skill",GetUserStoredValue"drift_skill" ) );
SetCurrentPlayerVar"average_speed_kmh",GetUserStoredValue"average_speed_kmh" ) );
SetCurrentPlayerVar"average_speed_mph",GetUserStoredValue"average_speed_mph" ) );
...
    
SetUserStoredValue"lap_time_time"$lap_time_time);
    
SetUserStoredValue"lap_time_number"$lap_time_number);
    
SetUserStoredValue"drift_score"$drift_score);
    
SetUserStoredValue"drift_skill"$drift_skill);
    
SetUserStoredValue"average_speed_kmh"$average_speed_kmh);
    
SetUserStoredValue(  "average_speed_mph"$average_speed_mph);
...
?>

Then you should see the values in the fi_user_value table, not fi_stored.
Quote from Krayy :At first glance, there are syntax errors in your SetUserStoredValue statements (extra opening parentheses) and the GetStoredValue statements should be GetUserStoredValue
....
then you should see the values in the fi_user_value table, not fi_stored.

Thanks for that - too gung ho on the copy/paste and trying all the 'get' statements.

I can now see the variable results saved in the table.

Next query: how do I stop all the previous results being overwritten if the main result I'm interested in is lower than previous?

Bit like !top where you may do a faster time sector, but you need to do faster lap time before old results are overwritten.

Just that the storedvalue.dbs seems to be in different format to the database used for !top.

I can (sort of) understand how the storedvalue.dbs is great for things like saving placements of buttons to how user prefers them, or how to use for a reward system, like everytime you finish a race you are given another reward point, and after gaining enough reward points then you can cash them in for something, like use of different car, admin privilages, etc.

But I'm clueless on how the storedvalue.dbs can be used for saving your best of something (e.g topspeed) so you can save topspeed based on car or track, etc., which can then be outputed into a topUser table, and not just overwritten next time you do a run in a different car/track.
#4 - Krayy
Databases 101
I find it best to think about the database like a special type of variable storage rather than as a separate entity. Database functions can be global (not tied to a user) or user specific. Here are the functions:

Global var functions (fi_stored):
SetStoredValue("varname", $value) - sets a variable
GetStoredValue("varname") - returns variable as a string
GetStoredNum("varname") - returns variable as a numeric (or as -1 if it's not a number), so you don't need to do a ToNum($var) conversion if you're doing numeric comparisons

User var functions (fi_user_value):
SetUserStoredValue($username, "varname", $value) - Sets a variable
GetUserStoredValue($username, "varname") - returns variable as a string
GetUserStoredNum($username, "varname") - returns variable as a numeric
*Note -
The $username var in the user functions is optional. If it's omitted, then it will retrieve values for the current user.

So, now we know which are global and user, so where do we store data? Easy...if the data pertains to a user, store it using the user functions, if it's not, use the global ones, i.e. DefaultTopCar = global, MyBestLap = user

A lot of internal Lapper data have hard coded internal functions to mash data and then store it such as the fastest lap times that you see in !top. The way it retrieves that data is also hard coded. Doing it inside Lapper would be inefficient, adn this is where you need to be a bit creative.

If you want to compare values before storing the largest in the databse, you will need to do a Get, Compare, then Set. So I'd do this:


<?php 
IF ( $TopSpeed GetUserStoredNum("TopSpeed"))
THEN
SetUserStoredValue
("TopSpeed"$TopSpeed);
ENDIF
?>

If haven't tested that but it should work as the GetUserStoredNum returns a numeric so can be used in a numeric comparision without doing a ToNum conversion.
Many thanks for that Krayy - makes bit more sense now - and it works!

EDIT

But discovered problem.

If I do a lap on AS1 in a UF1, and get a TopSpeed, this is written to the database.

If I then do lap in other car, and get faster TopSpeed, then this overwrites what's in database (if slower, then original database entry stays).

Even if I went to different track and did faster TopSpeed with UF1, then again the database entry gets overwritten.

Any other information I'm collecting along with TopSpeed (like car, track, etc) is also overwritten.

Or to make it easier to see, if I try different cars at different tracks, and get following results
RUN 1 = UF1, AS1, 60mph
RUN 2 = BF1, AS1, 189mph
RUN 3 = XFG, KY1, 86mph
RUN 4 = MRT, FE1, 106mph

Then database will only store and output up to RUN 2, until next time I improve on this.
BF1, AS1, 189mph

If I want to do something based on this TopSpeed, then buttons, sub-routines, etc, will only work correctly on the track in the right car with the fastest TopSpeed.

Otherwise, I have to start writing track specific variables.

For instance


<?php 
  
IF ( getLapperVar"ShortTrackName" ) == "BL1")
    
THEN
        SetUserStoredValue
("BL1_TopSpeed"$BL1_TopSpeed);
  ENDIF

  IF ( 
getLapperVar"ShortTrackName" ) == "BL1R")
    
THEN
        SetUserStoredValue
("BL1R_TopSpeed"$BL1R_TopSpeed);
  ENDIF

?>

Then if I want to compare and store in database


<?php 
  
IF ( BL1_$TopSpeed GetUserStoredNum("BL1_TopSpeed"))
    
THEN
        SetUserStoredValue
("BL1_TopSpeed"$BL1_TopSpeed);
  ENDIF

  IF ( 
BL1R_$TopSpeed GetUserStoredNum("BL1R_TopSpeed"))
    
THEN
        SetUserStoredValue
("BL1R_TopSpeed"$BL1R_TopSpeed);
  ENDIF
?>

Then if I want to output, say in a button, then I would likely need something like


<?php 
  
IF ( getLapperVar"ShortTrackName" ) == "BL1")
    
THEN
        openPrivButton
"ts_button",$origL,$origT,$Width,$Height,$spacing,$time,0,langEngine("%{main_ts}%"$BL1_TopSpeed));
    ELSE
  IF ( 
getLapperVar"ShortTrackName" ) == "BL1R")
    
THEN
        openPrivButton
"ts_button",$origL,$origT,$Width,$Height,$spacing,$time,0,langEngine("%{main_ts}%"$BL1R_TopSpeed));
ENDIF
ENDIF
?>

But I'd have to do a TopSpeed Set/Get/Output variable for the 50 or so track combinations.

And if I wanted to collect and output other info, like the car and trackname, then I have to start


<?php 
  
IF ( getLapperVar"ShortTrackName" ) == "BL1")
    
THEN
        SetUserStoredValue
("BL1_TopSpeed"$BL1_TopSpeed);
        
SetUserStoredValue("BL1_Car"$BL1_Car);
        
SetUserStoredValue("BL1_Track"$BL1_Track);
  ENDIF
?>


<?php 
  
IF ( getLapperVar"ShortTrackName" ) == "BL1")
    
THEN
        openPrivButton
"ts_button",$origL,$origT,$Width,$Height,$spacing,$time,0,langEngine("%{main_ts}%"$BL1_TopSpeed,$BL1_Car,$BL1_Track ));
ENDIF
?>

So, to me, it looks like the storedvalue.dbs is ok for storing standard variables that you can use anywhere (like Yisc's Pitboard button locations), or for adding to existing total to make new total (like Tim's points system), but not so good for storing a single variable that could differ depending on car, track, etc.

Although, even if you had

User var functions (fi_user_value):
SetUserStoredValue($track, $car, $username, "varname", $value) - Sets a variable ("varname") based on current track and car

where $track, $car and $username vars in the user functions are optional. If omitted, then it will retrieve values for the current user on current track in current car.

This would make it easier to collect data, but still going to be issues when trying to output when output relies on specific track and/or car.
#6 - Krayy
Quote from sinanju :...
User var functions (fi_user_value):
SetUserStoredValue($track, $car, $username, "varname", $value) - Sets a variable ("varname") based on current track and car

where $track, $car and $username vars in the user functions are optional. If omitted, then it will retrieve values for the current user on current track in current car.

This would make it easier to collect data, but still going to be issues when trying to output when output relies on specific track and/or car.

You couldn't do that as vars are stored as a single value using a single name. One solution would be to do this:

<?php 
SetStoredValue
("varname_" $track "_" $car "_" $username$value);
?>

Then you could use the split function to break it up when doing a Get:

<?php 
$fields 
SplitToArray(GetStoredValue("varname_AS1_BL1_Krayy"));
$Track $fields[1];
$Car $fields[2];
etc
?>


Sorry, but this is way beyond me now - unfortunately I'm not programming savvy enough for this

For instance, in previous post, I was to use SetUserStoredValue rather than SetStoredValue (user as against global variables), but now to use global variables again.

And I have no idea how you'd now do a compare like

[COLOR=#000000][COLOR=#007700]IF ( [/COLOR][COLOR=#0000bb]$TopSpeed [/COLOR][COLOR=#007700]> [/COLOR][COLOR=#0000bb]GetStoredNum[/COLOR][COLOR=#007700]([/COLOR][COLOR=#dd0000]"TopSpeed"[/COLOR][COLOR=#007700]))
[/COLOR][COLOR=#0000bb]THEN
SetStoredValue[/COLOR][COLOR=#007700]([/COLOR][COLOR=#dd0000]"TopSpeed"[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]$TopSpeed[/COLOR][COLOR=#007700]);
ENDIF[/COLOR][/COLOR]



from something like


<?php 
 
SetStoredValue
("TopSpeed_" $track "_" $car "_" $username$TopSpeed);
?>



Apologies Krayy - this is no criticism of you; just my non existent understanding of programming - some people can program htlm in text

<table border=0 width=100%>
<tr>
<center>
<br>
<br> <br>
<hr><br>
<table border=5 cellpadding=10 width=600>
<td>
<font color=red><center><b>
.... whereas some of us have to use Dreamweaver instead.
</center></b>
</table>
<br>


And the books in my local library are all sort of applications ... (like Word, Excel, Powerpoint, Access, Windows) ...for dummies rather than this type of thing (I have looked!).
#8 - Krayy
I should have clarified the difference...

There's a rule of thumb that we need to consider here...you can only retrieve data from the User database (using GetUserStoredValue) if you know the users name. In most circumstances, this limits you to the users who are online.

So if you are want to store data that can refernce a user that is not online, then you will need to use the global Store and Get functions e.g. you want to display the # of races that users had run and include offline users, you would most likely need to use the global db, but then you need to store the data like this:

$varname = "topspeed_" . $track . "_" . $car; # Like topspeed_AS1_BL1
SetStoredValue($varname, "sinanju:160,krayy:155,tim_nl:90,etc);

$times = SplitToArray($varname, ",");
FOR( $i = 0; $i < 10; $i = $i + 1)
privMsg("Racer number ". $i . " is " . $times[$i]):
ENDFOR
Sorry Krayy, but still way over my head!

However. After a number of hours, I think I've got the set and get part working now.

<?php 
SetStoredValue
$userName "_LapTime_" $track "_" $car$LapTime);
?>

and to make sure that the fastest stays in the database and is not overwritten with slower laptime, I have

<?php 
 
IF ( $LapTime GetStoredValue($userName "_LapTime_" $track "_" $car))
 
THEN
 SetStoredValue
$userName "_LapTime_" $track "_" $car$LapTime);
 ENDIF
?>

I need to do bit more testing to make sure it does what I expect.

My next problem is getting this to appear in a topusers table (like !top).

Tried

<?php 
CatchEvent etc
.....

SWITCH( 
$command )
!
laptime
topUser
"^3Fastest Lap Table",$LapTime,"DESC",argv );
BREAK;
ENDSWITCH

EndCatchEvent etc
?>


But this wouldn't work.

Neither would

<?php 
topUser
"^3Fastest Lap Table",GetStoredValue($userName "_LapTime_" $track "_" $car)),"DESC",argv );
?>

Then tried


<?php 
...
SWITCH( 
$command )
!
laptime
DoTopUser
$argv,TRUE,TRUE,TRUE );
BREAK;
ENDSWITCH
....
##

Sub DoTopUser$argv,$track,$car,$LapTime )
      
$list GetListTop$argv,$track,$car,$LapTime );
      
DumpVar$list );
EndSub
?>


But that wouldn't work either.

Is it possible to do !top type command with this kind of value?
Quote from sinanju :...
Is it possible to do !top type command with this kind of value?

In a word, no. The GetListTop function is hard coded to accept only 3 parameters, which are a list of car names (with + signs between for multiple cars), a boolean value (TRUE or FALSE) for if it's Qaulifying times, and a boolean value for times that are near your pb i.e.

<?php 
 GetListTop
$argv,$flagQual,$flagNear );
?>

You can't use it to store fastest times.....yet ;-)
It's obviouse that people want to be able to store the best values of something so that they can use it to do stats like top, and I don't see why I can't modify the code to support virtually any kind of data, as long as it is numerically comparable like speeds, times, points etc.

So that being said, let's get a list together of what values people want to store and I'll see if I can modify the code to support it.

Note that this would be a code modification away from the standard LFS versions, but I'd submit it to Gai to see if he could incorporate it into the codebase.
Thanks for that Krayy - saves me spending heaps of time trying things that won't ever work.

Quote from Krayy :...let's get a list together of what values people want to store...

A lot of the standard player variables like;

UserName . . . . . . . . . . . . .# User Name or LFS Name
NickName . . . . . . . . . . . . .# nickName of the player
Car . . . . . . . . . . . . . . . . . # Current car for the player
Track . . . . . . . . . . . . . . . .# Current track for the player
Dist . . . . . . . . . . . . . . . . . # dist for the player in km on this server
Laps . . . . . . . . . . . . . . . . .# Total number of laps done on the current track and with the current car
P_Mass . . . . . . . . . . . . . . .# Current player Mass
P_Tres . . . . . . . . . . . . . . . # Current Player Restriction
BestSectorSplit1 . . . . . . . . .# Best Split duration for the sector 1
BestSectorSplit2 . . . . . . . . .# Best Split duration for the sector 2
BestSectorSplit3 . . . . . . . . .# Best Split duration for the sector 3
BestSectorSplitLast . . . . . . .# BestSplit duration for the last sector
LapTime . . . . . . . . . . . . . . # Current Lap Time, erased when doing New LapTime
AvgSpeed . . . . . . . . . . . . . # Avg Speed on last Lap Time
BestSpeed . . . . . . . . . . . . .# Best Speed done on this combo by player
AccelerationTime . . . . . . . . .# Acceleration time achieved from start to end speed
FinishedPos . . . . . . . . . . . . .# finish or qualify pos (1 = win / 256 = not added to table)
RaceTotalTimev . . . . . . . . . .# race time (ms) the use of NumToMsh is needed
RacePBTime . . . . . . . . . . . . # race personnal best time in ms the use of NumToMsh is needed
DriftScore . . . . . . . . . . . . . .# last Drift score
LastDriftScore . . . . . . . . . . .# Last full lap drift score

Additional user variables, like;

points . . . . . . . . . . . . . . . . # any user defined points system (e.g. race points, time points, skill points, etc)
score . . . . . . . . . . . . . . . . .# any user defined scoring system
. . . . . . . . . . . . . . . . . . . . . (maybe not needed as just different way of saying points system)
uservardecimal . . . . . . . . . . .# any user defined points,scoring, award, cash collecting, etc.,
. . . . . . . . . . . . . . . . . . . . . . system that relies on decimal places
I meant data that could be grouped from a high to low value like !Top e.g. Speed at a track node, split times, points, total wins, wins at a track, wins in a car.

Basically what I'm thinking is a database that stores a key/value where the value is a numeric that can be sorted from high to low (or vice versa). Then you could write Lapper scripts to use it like:

GetVarList("cruise_points");
GetVarList("race_points");

or similar to return a list of the top cruise or race points, or any other user defined var name.
Quote from Krayy :I meant data that could be grouped from a high to low value ....

So was I.

Good way of showing various server/track stats.
Attached images
Potential Top Tables.PNG

FGED GREDG RDFGDR GSFDG