internal LapRecording AddLapData(PacketHeader context, LapData lapData) { LapRecording completedLap = null; // uint8 m_resultStatus; // Result status - 0 = invalid, 1 = inactive, 2 = active // 3 = finished, 4 = disqualified, 5 = not classified // 6 = retired // Status of driver - 0 = in garage, 1 = flying lap // 2 = in lap, 3 = out lap, 4 = on track) if (lapData.driverStatus == 0 || lapData.driverStatus == 3 || lapData.driverStatus == 2) { // In garage return(null); } LapRecording activeLap = GetLap(lapData.currentLapNum); if (lapData.resultStatus == 3) { if (activeLap.lapTime > 0 && activeLap.lapMotion.Count > 100) { activeLap.valid = true; activeLap.complete = true; completedLap = activeLap; } else { return(null); } } if (currentLapIndex != lapData.currentLapNum) { // New lap? Starting Lap? Something else? if (currentLapIndex > lapData.currentLapNum) { currentLapIndex = lapData.currentLapNum; } else if (currentLapIndex > 0) { var previousLap = GetLap(currentLapIndex); var lastLap = previousLap.lapTimings; if (lastLap.currentLapInvalid == 0) { // Sanity check. Packages with ResultStatus 3 are missing, so calculate if it is a valid lap // by checking sinsible sector and lap times. previousLap.complete = previousLap.started && lastLap.sector1TimeInMS > 0 && lastLap.sector2TimeInMS > 0 && (lastLap.currentLapTimeInMS) > (lastLap.sector1TimeInMS + lastLap.sector2TimeInMS); if (previousLap.complete) { previousLap.lapTimeInMs = lapData.lastLapTimeInMS; completedLap = previousLap; } } else { previousLap.valid = false; } } currentLapIndex = lapData.currentLapNum; } if (!activeLap.started) { activeLap.FirstTiming = lapData; if (lapData.lapDistance < 10) { activeLap.started = true; } } activeLap.lapTimings = lapData; activeLap.lapData.Add(new LapDataInContext() { context = context, lapData = lapData }); // GetLap(lapData.currentLapNum).started |= (lapData.sector == 0); return(completedLap); }