View Full Version : PHP5 - Simple MPR parser
xergio
18th June 2009, 22:55
Hi all!
It's simple, this script allow to you to read the MPR files and extract the headers and the results of the race (if someone finish the race)
This is a frustrating try to read all the race. All I obtain was the documented info at www.lfs.net/?page=MPR (http://www.lfs.net/?page=MPR) .... and all the car/head skins used by the participants... but It isn't implemented. As I've said... I finished frustrated :(
You can use my script with something like this:
<?
require_once('phpmpr.php');
// parse the file
$o = new PHPMPR('some-mpr-file.mpr');
// see the content
var_dump($o);
?>The $o object has two principal properties: $o->headers with all the header info, and $o->players with an array with all the results.
See the code and the dump for more info :) Demo: http://mch.lfsteam.es/forum/mpr.php
P.D.: Sorry for my english... I know PHP, not english :shy:
Edit1: updated file to avoid a file requirement
jason_lfs
25th June 2009, 18:45
works great. Thanks. Gracias.
Dominic123
27th January 2010, 16:25
I parsed an mpr with the script and most values are right just the output for best laptime and racetime is always strange. I know all the times are in milliseconds, but sometimes i recieve negative numbers. And it's not just a single replay which doesnt work well. Here's an example (not formatted just the default output):
["Dominic123"]=>
object(PHPMPR_Player)#10 (15) {
["pname"]=>
string(13) "07 - D. Klein"
["numplate"]=>
string(6) "Bla <3"
["scarname"]=>
string(3) "FZR"
["lfsuname"]=>
string(10) "Dominic123"
["laps"]=>
int(6144)
["pflags"]=>
int(290)
["cflags"]=>
int(2)
["pits"]=>
int(1)
["penalsecs"]=>
int(0)
["racetime"]=>
int(1780820480)
["bestlaptime"]=>
int(-1766653696)
["zero"]=>
int(0)
["startpos"]=>
int(16)
["handicapmass"]=>
int(10)
["intakeres"]=>
int(15)
}
Does someone know a solution or an idea what's the source of this problem?
bdshan
27th January 2010, 16:42
I'll have to check my replay parsing code, but I think those negative numbers come from an incorrect parameter while unpacking.
Yup, I use "i" instead of "I" to unpack the int.
Dominic123
27th January 2010, 17:18
So it has to be like this?
i1racetime/i1bestlaptime
Edit: Doesn't work aswell :/
bdshan
27th January 2010, 18:15
That looks right.
Dominic123
27th January 2010, 18:16
Same result unfortunately
bdshan
28th January 2010, 00:30
It took a re-read of the MPR format, but I think your issue is because the size of the int is 4 bytes not 1.
try:
i4racetime/i4bestlaptime
avetere
28th January 2010, 14:13
actually i (or I) don't require a size-value (nor are they supported, if I'm not wrong).
My guess is: Your machine does not(!) interpret i as an 32bit integer (4byte), as the parameter i (or I) is machine-depentent in it's size.
I'd recommend the use of "L" instead, as this one is always 32bit ... or "l" for a signed integer which is useless here of course ;)
edit:
btw: "i" is for signed integers, so use of "I" was - out of those two - the right choice ;)
bdshan
28th January 2010, 14:35
In that case how do you account for the different sizes of integers in the MPR format?
TYPES :
=======
char : 1-byte ascii character
byte : 1-byte integer
word : 2-byte integer
int : 4-byte integer, lowest byte first
avetere
28th January 2010, 14:58
Here "integer" standy for exactly that: an integer value, in difference to a floating number. There is no direct correspondence with what "character-type" the pack (or unpack) function assumes.
Actually, you would like to use:
char: a
byte: C (c for signed ones)
word: S (s for signed ones)
int: L (l for signed ones)
Dominic123
28th January 2010, 16:16
It took a re-read of the MPR format, but I think your issue is because the size of the int is 4 bytes not 1.
try:
i4racetime/i4bestlaptime
But if i paste this code there's an error message becuase the sum of all bytes isn't 80 bytes, what it should be.
morpha
28th January 2010, 16:31
But if i paste this code there's an error message becuase the sum of all bytes isn't 80 bytes, what it should be.
That's because i4 = 4 integers = 16 bytes, you only need one int per value.
A byte is unsigned (as opposed to char, which is signed), as is a word (as opposed to short, which is signed) and while an int is usually signed, I really don't think it's meant to be in this case since you can't really achieve a negative laptime, so let's assume that was meant to be unsigned.
Use C for the byte, that's an unsigned 8bit integer.
Use v for the word, that's an unsigned 16bit integer guaranteed to be little-endian.
Use V for the int, that's an unsigned 32bit integer guaranteed to be little-endian.
bdshan
28th January 2010, 16:58
put it back to 1, then post the mpr and describe which values are incorrect.
Dominic123
28th January 2010, 17:27
Ok, so here's my problem. I uploaded any replay, and parsed it, thats the array dump for a driver (Me in that case :P):
array(7) {
["Dominic123"]=>
object(PHPMPR_Player)#3 (15) {
["pname"]=>
string(10) "per.Domi K"
["numplate"]=>
string(0) ""
["scarname"]=>
string(3) "FZR"
["lfsuname"]=>
string(10) "Dominic123"
["laps"]=>
int(1536)
["pflags"]=>
int(290)
["cflags"]=>
int(2)
["pits"]=>
int(1)
["penalsecs"]=>
int(0)
["racetime"]=>
int(-1932654336) // Negative Number
["bestlaptime"]=>
int(1854931200) // Way too high
["zero"]=>
int(0)
["startpos"]=>
int(4)
["handicapmass"]=>
int(0)
["intakeres"]=>
int(0)
}
As you can see these two values i mentioned before are incorrect.
bdshan
28th January 2010, 17:45
I ran your replay thru the parser, and the output is correct, at least on my machine.
array(7) {
["Dominic123"]=> object(PHPMPR_Player)#3 (15) {
["pname"]=> string(10) "per.Domi K"
["numplate"]=> string(0) ""
["scarname"]=> string(3) "FZR"
["lfsuname"]=> string(10) "Dominic123"
["laps"]=> int(6)
["pflags"]=> int(8705)
["cflags"]=> int(2)
["pits"]=> int(1)
["penalsecs"]=> int(0)
["racetime"]=> int(642700)
["bestlaptime"]=> int(102510)
["zero"]=> int(0)
["startpos"]=> int(4)
["handicapmass"]=> int(0)
["intakeres"]=> int(0) }
I also ran it thru my parser and got the same results. Must be something on your side.
morpha
28th January 2010, 18:00
Follow my suggestion, enforce little-endian :rolleyes:
avetere
28th January 2010, 18:02
I'm afraid not only those are wrong, but laps too (and i assume even pflags ...)
Here's my own readout of the replay:
[1] => Array
(
[nick] => per.Domi K
[numberplate] =>
[car] => FZR
[lfsw] => Dominic123
[lapsdone] => 6
[flags] => 8705
[confirm] => 2
[numstops] => 1
[penalty] => 0
[totaltime] => 642700
[bestlap] => 102510
[null] => 0
[startpos] => 4
[handicap] => 0
[restrictor] => 0
)
flags is your pflags ... my values result in: CustomView, AutoClutch, LeftHand and Wheel ...
done with this unpack:
unpack("@0/a24nick/a8numberplate/a4car/a24lfsw/Slapsdone/Sflags/Cconfirm/Cnumstops/Spenalty/Ltotaltime/Lbestlap/Cnull/Cstartpos/Chandicap/Crestrictor",$string);
Edit:
1: too slow ;)
2: just doublechecked: little-endian enforcment is the key ... so do what morpha said ... you seem to have a "big-endian-machine" :)
Dygear
28th January 2010, 18:29
Byte order for the lose.
Dominic123
28th January 2010, 19:06
Just tested it on an other server - and it works perfect so thanks for the advice and for trying it on your machines :)
@avetere: laps and flags may be wrong, too but i didn't notice it, cause i didn't care about them :P
@morpha: how can i enforce it?
avetere
28th January 2010, 19:38
@avetere: laps and flags may be wrong, too but i didn't notice it, cause i didn't care about them :P
@morpha: how can i enforce it?
The error there is the same: byte order ...
to enforce it, use "V" (upper case) instead of "i" or "I" ... and for those 2-byte things (words: laps, pflags, penalties) use "v" (lower case)
Dygear
28th January 2010, 21:31
The error there is the same: byte order ...
to enforce it, use "V" (upper case) instead of "i" or "I" ... and for those 2-byte things (words: laps, pflags, penalties) use "v" (lower case)
Nicely done sir!
morpha
28th January 2010, 21:32
Am I getting completely ignored here? I wrote that a couple of posts up :really:
Or is it a forum bug and my post simply doesn't show? Cause that's what it feels like :razz:
avetere
28th January 2010, 21:41
I wrote that a couple of posts up :really:
Yeah, he didn't seem to realize that ... :shrug:
morpha
28th January 2010, 21:46
Yeah, he didn't seem to realize that ... :shrug:
Well it's not that I care much, but with the forum bugs increasing rapidly lately (incorrect UIDs, polls getting mixed up, thread ratings breaking, ...) I just wondered if there might be a more serious issue :tilt:
avetere
28th January 2010, 21:50
Not at this end of the line :snail:
Dygear
29th January 2010, 08:39
That's because i4 = 4 integers = 16 bytes, you only need one int per value.
I skipped over your message because i4 = 4 integers = 64 bytes, because each 'i' or int is 16 bytes long, there for telling the unpack function to do i4 is telling it to read 4 sixteen byte segments giving you the total of 64 bytes read. Although I did read the answer part, and it just did not compute as the right answer because of the first part.
Well it's not that I care much, but with the forum bugs increasing rapidly lately (incorrect UIDs, polls getting mixed up, thread ratings breaking, ...) I just wondered if there might be a more serious issue.
vB 4.0.1 is out, 4.0.2 should be out in a fortnight, and we are using the latest 3.8.4 branch, just behind by a few patch levels.
morpha
29th January 2010, 13:42
I skipped over your message because i4 = 4 integers = 64 bytes, because each 'i' or int is 16 bytes long, there for telling the unpack function to do i4 is telling it to read 4 sixteen byte segments giving you the total of 64 bytes read. Although I did read the answer part, and it just did not compute as the right answer because of the first part.
An int is 32bits = 4 byte, 4 ints are 16 byte ;)
Even a 64 bit int would still only be 8 byte, so I really don't know what you're talking about.
Dygear
29th January 2010, 13:59
An int is 32bits = 4 byte, 4 ints are 16 byte ;)
Even a 64 bit int would still only be 8 byte, so I really don't know what you're talking about.
Me, failing at basic understanding of bit lengths.
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.