Ok, here is a list of suggestions I've compiled while working on a Live for Stats replacement.
o IS_TOC needs more information about the player that is taking over. As it stands now, after the IS_TOC gets sent a IS_PFL packet is sent, but we are still missing some of the information (i.e. Plate[8], PType). It'd be nice, instead of the IS_PFL being sent, that a IS_NPL is sent instead. Or the IS_TOC to include the PType, Flags, PName, Plate information fromt he IS_NPL. The latter would probably be preferrable as shown below As it stands in order to get the Plate and PType, we'd have to request, via the IS_NPL, all of the player info packets to be sent which seems a bit in-efficient if we're only interested in one player.
Relavent forum posting is http://www.lfsforum.net/showthread.php?t=27991.
struct IS_TOC // Take Over Car
{
byte Size; // 44
byte Type; // ISP_TOC
byte ReqI; // 0
byte PLID; // player's unique id
byte OldUCID; // old connection's unique id
byte NewUCID; // new connection's unique id
byte PType; // bit 0 : female / bit 1 : AI / bit 2 : remote
word Flags; // player flags
char PName[24]; // nickname
char Plate[8]; // number plate - NO ZERO AT END!
byte Sp2;
};
o Especially in replays running at greater than x2 speeds, we are not able to reliably receive every IS_NLP node packet, so this makes pulling statistically information that is not provided in the IS_LAP and IS_SPX packets. Specifically the information missing is the race position of the player and the current speed. From the IS_SPX packet, the lap number is also missing. Sure it can be inferred, but its better to be certain in the case of out of order packets with UDP. Adding these would give the following packets:
struct IS_LAP // LAP time
{
byte Size; // 28
byte Type; // ISP_LAP
byte ReqI; // 0
byte PLID; // player's unique id
unsigned LTime; // lap time (ms)
unsigned ETime; // total time (ms)
word LapsDone; // laps completed
word Flags; // player flags
byte Sp0;
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
byte Position; // current race position : 0 = unknown, 1 = leader, etc...
word Speed; // speed (32768 = 100 m/s)
byte Sp4;
byte Sp5;
byte Sp6;
};
struct IS_SPX // SPlit X time
{
byte Size; // 28
byte Type; // ISP_SPX
byte ReqI; // 0
byte PLID; // player's unique id
unsigned STime; // split time (ms)
unsigned ETime; // total time (ms)
byte Split; // split number 1, 2, 3
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
byte Position; // current race position : 0 = unknown, 1 = leader, etc...
word Speed; // speed (32768 = 100 m/s)
word LapsDone; // laps completed
byte Sp4;
byte Sp5;
byte Sp6;
};
Alternatively, it would be nice to have a CompCar packet available in the IS_LAP and IS_SPX.
struct IS_LAP // LAP time
{
byte Size; // 48
byte Type; // ISP_LAP
byte ReqI; // 0
byte PLID; // player's unique id
unsigned LTime; // lap time (ms)
unsigned ETime; // total time (ms)
word LapsDone; // laps completed
word Flags; // player flags
byte Sp0;
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
CompCar Info; // car info for the player
};
struct IS_SPX // SPlit X time
{
byte Size; // 48
byte Type; // ISP_SPX
byte ReqI; // 0
byte PLID; // player's unique id
unsigned STime; // split time (ms)
unsigned ETime; // total time (ms)
byte Split; // split number 1, 2, 3
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
word LapsDone; // laps completed
CompCar Info; // car info for the player
};
In either case, although I'd prefer the second, effeciency is increased because we aren't having to collect repeatedly collect the IS_MCI at a 100ms interval (for realtime and x1 replay speeds) or 50ms interval (for x2 replay speeds) in an attempt to collect information. This is especially true if we don't really need the position, etc. of the car at every node.
Relavent forum postings are http://www.lfsforum.net/showthread.php?t=27714 and http://www.lfsforum.net/showthread.php?p=482370#post482370.
o Add the connection Id to the IS_PFL packet as shown below. The player flags are really more connection based than they are player based. In terms of "taking control", the new connection that takes over the player object may have different player flags so when we track this information for statistical purposes we'll have a player information object that contains one to many connection information objects, which stores things related to the connection. This way we know what flags each "connection" used during the race.
struct IS_PFL // Player FLags (help flags changed)
{
byte Size; // 12
byte Type; // ISP_PFL
byte ReqI; // 0
byte UCID; // connection's unique id
byte PLID; // player's unique id
word Flags; // player flags (see below)
byte sp0;
byte sp1;
byte sp2;
};
o It'd be nice to have an SMALL_NPL that has a SMALL_NPL enum and the UVal would be the playerId. This SMALL_NPL packet would send a single IS_NPL packet for the requested playerId.
Relavent forum posting is http://www.lfsforum.net/showthread.php?t=27991.
o IS_TOC needs more information about the player that is taking over. As it stands now, after the IS_TOC gets sent a IS_PFL packet is sent, but we are still missing some of the information (i.e. Plate[8], PType). It'd be nice, instead of the IS_PFL being sent, that a IS_NPL is sent instead. Or the IS_TOC to include the PType, Flags, PName, Plate information fromt he IS_NPL. The latter would probably be preferrable as shown below As it stands in order to get the Plate and PType, we'd have to request, via the IS_NPL, all of the player info packets to be sent which seems a bit in-efficient if we're only interested in one player.
Relavent forum posting is http://www.lfsforum.net/showthread.php?t=27991.
struct IS_TOC // Take Over Car
{
byte Size; // 44
byte Type; // ISP_TOC
byte ReqI; // 0
byte PLID; // player's unique id
byte OldUCID; // old connection's unique id
byte NewUCID; // new connection's unique id
byte PType; // bit 0 : female / bit 1 : AI / bit 2 : remote
word Flags; // player flags
char PName[24]; // nickname
char Plate[8]; // number plate - NO ZERO AT END!
byte Sp2;
};
o Especially in replays running at greater than x2 speeds, we are not able to reliably receive every IS_NLP node packet, so this makes pulling statistically information that is not provided in the IS_LAP and IS_SPX packets. Specifically the information missing is the race position of the player and the current speed. From the IS_SPX packet, the lap number is also missing. Sure it can be inferred, but its better to be certain in the case of out of order packets with UDP. Adding these would give the following packets:
struct IS_LAP // LAP time
{
byte Size; // 28
byte Type; // ISP_LAP
byte ReqI; // 0
byte PLID; // player's unique id
unsigned LTime; // lap time (ms)
unsigned ETime; // total time (ms)
word LapsDone; // laps completed
word Flags; // player flags
byte Sp0;
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
byte Position; // current race position : 0 = unknown, 1 = leader, etc...
word Speed; // speed (32768 = 100 m/s)
byte Sp4;
byte Sp5;
byte Sp6;
};
struct IS_SPX // SPlit X time
{
byte Size; // 28
byte Type; // ISP_SPX
byte ReqI; // 0
byte PLID; // player's unique id
unsigned STime; // split time (ms)
unsigned ETime; // total time (ms)
byte Split; // split number 1, 2, 3
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
byte Position; // current race position : 0 = unknown, 1 = leader, etc...
word Speed; // speed (32768 = 100 m/s)
word LapsDone; // laps completed
byte Sp4;
byte Sp5;
byte Sp6;
};
Alternatively, it would be nice to have a CompCar packet available in the IS_LAP and IS_SPX.
struct IS_LAP // LAP time
{
byte Size; // 48
byte Type; // ISP_LAP
byte ReqI; // 0
byte PLID; // player's unique id
unsigned LTime; // lap time (ms)
unsigned ETime; // total time (ms)
word LapsDone; // laps completed
word Flags; // player flags
byte Sp0;
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
CompCar Info; // car info for the player
};
struct IS_SPX // SPlit X time
{
byte Size; // 48
byte Type; // ISP_SPX
byte ReqI; // 0
byte PLID; // player's unique id
unsigned STime; // split time (ms)
unsigned ETime; // total time (ms)
byte Split; // split number 1, 2, 3
byte Penalty; // current penalty value (see below)
byte NumStops; // number of pit stops
byte Sp3;
word LapsDone; // laps completed
CompCar Info; // car info for the player
};
In either case, although I'd prefer the second, effeciency is increased because we aren't having to collect repeatedly collect the IS_MCI at a 100ms interval (for realtime and x1 replay speeds) or 50ms interval (for x2 replay speeds) in an attempt to collect information. This is especially true if we don't really need the position, etc. of the car at every node.
Relavent forum postings are http://www.lfsforum.net/showthread.php?t=27714 and http://www.lfsforum.net/showthread.php?p=482370#post482370.
o Add the connection Id to the IS_PFL packet as shown below. The player flags are really more connection based than they are player based. In terms of "taking control", the new connection that takes over the player object may have different player flags so when we track this information for statistical purposes we'll have a player information object that contains one to many connection information objects, which stores things related to the connection. This way we know what flags each "connection" used during the race.
struct IS_PFL // Player FLags (help flags changed)
{
byte Size; // 12
byte Type; // ISP_PFL
byte ReqI; // 0
byte UCID; // connection's unique id
byte PLID; // player's unique id
word Flags; // player flags (see below)
byte sp0;
byte sp1;
byte sp2;
};
o It'd be nice to have an SMALL_NPL that has a SMALL_NPL enum and the UVal would be the playerId. This SMALL_NPL packet would send a single IS_NPL packet for the requested playerId.
Relavent forum posting is http://www.lfsforum.net/showthread.php?t=27991.