public override Object ReadGameData(Boolean forSpotter) { CrewChiefV4.PCars2.PCars2SharedMemoryReader.PCars2StructWrapper structWrapper = new CrewChiefV4.PCars2.PCars2SharedMemoryReader.PCars2StructWrapper(); structWrapper.ticksWhenRead = DateTime.UtcNow.Ticks; lock (this) { if (!initialised) { if (!InitialiseInternal()) { throw new GameDataReadException("Failed to initialise UDP client"); } } previousGameState = StructHelper.Clone(currentGameState); currentGameState = StructHelper.Clone(workingGameState); if (forSpotter) { newSpotterData = false; } } structWrapper.data = currentGameState; if (!forSpotter && dumpToFile && dataToDump != null && currentGameState.mTrackLocation != null && currentGameState.mTrackLocation.Length > 0) { dataToDump.Add(structWrapper); } return(structWrapper); }
private int readRawData(byte[] rawData) { // unpack the packet header manually before attempting to load into a struct uint packetNumber = BitConverter.ToUInt32(rawData, 0); uint categoryPacketNumber = BitConverter.ToUInt32(rawData, 4); int partialPacketIndexBytes = rawData[8]; int partialPacketNumber = rawData[9]; EUDPStreamerPacketHandlerType packetType = (EUDPStreamerPacketHandlerType)rawData[10]; int packetVersion = rawData[11]; int frameLength = 0; switch (packetType) { case EUDPStreamerPacketHandlerType.eCarPhysics: telemPacketCount++; if (telemPacketCount > packetCountAtStartOfNextRateCheck) { lastPacketRateEstimate = (int)((float)TimeSpan.TicksPerSecond * (float)(telemPacketCount - packetCountAtStartOfCurrentRateCheck) / (float)(DateTime.UtcNow.Ticks - ticksAtStartOfCurrentPacketRateCheck)); Console.WriteLine("Packet rate = " + lastPacketRateEstimate + "Hz, totals:" + "\rtelem = " + telemPacketCount + "\rraceDefinition = " + raceDefinitionPacketCount + "\rparticipants = " + participantsPacketCount + "\rtimings = " + timingsPacketCount + "\rgameState = " + gameStatePacketCount + "\rweather = " + weatherStatePacketCount + "\rvehicleNames = " + vehicleNamesPacketCount + "\rtimeStats = " + timeStatsPacketCount + "\rparticipantVehicleNames = " + participantVehicleNamesPacketCount + "\rin sequence = " + inSequenceTelemCount + " oos accepted = " + acceptedOutOfSequenceTelemCount + " oos rejected = " + discardedTelemCount); packetCountAtStartOfCurrentRateCheck = telemPacketCount; packetCountAtStartOfNextRateCheck = packetCountAtStartOfCurrentRateCheck + packetRateCheckInterval; ticksAtStartOfCurrentPacketRateCheck = DateTime.UtcNow.Ticks; } frameLength = UDPPacketSizes.telemetryPacketSize; Boolean sequenceCheckOK = isNextInSequence(packetNumber); if (sequenceCheckOK) { inSequenceTelemCount++; } if (strictPacketOrdering && !sequenceCheckOK) { discardedTelemCount++; } else { GCHandle telemHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sTelemetryData telem = (sTelemetryData)Marshal.PtrToStructure(telemHandle.AddrOfPinnedObject(), typeof(sTelemetryData)); if (sequenceCheckOK || !telemIsOutOfSequence(telem)) { buttonsState = ConvertBytesToBoolArray(telem.sDPad, telem.sJoyPad1, telem.sJoyPad2); lastSequenceNumberForTelemPacket = (int)packetNumber; workingGameState = StructHelper.MergeWithExistingState(workingGameState, telem); newSpotterData = true; } } finally { telemHandle.Free(); } } break; case EUDPStreamerPacketHandlerType.eRaceDefinition: raceDefinitionPacketCount++; frameLength = UDPPacketSizes.raceDataPacketSize; GCHandle raceDefHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sRaceData raceDefinition = (sRaceData)Marshal.PtrToStructure(raceDefHandle.AddrOfPinnedObject(), typeof(sRaceData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, raceDefinition); } finally { raceDefHandle.Free(); } break; case EUDPStreamerPacketHandlerType.eParticipants: participantsPacketCount++; frameLength = UDPPacketSizes.participantsDataPacketSize; GCHandle participantsHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sParticipantsData participants = (sParticipantsData)Marshal.PtrToStructure(participantsHandle.AddrOfPinnedObject(), typeof(sParticipantsData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, participants); } finally { participantsHandle.Free(); } break; case EUDPStreamerPacketHandlerType.eTimings: timingsPacketCount++; frameLength = UDPPacketSizes.timingsDataPacketSize; GCHandle timingsHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sTimingsData timings = (sTimingsData)Marshal.PtrToStructure(timingsHandle.AddrOfPinnedObject(), typeof(sTimingsData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, timings); } finally { timingsHandle.Free(); } break; case EUDPStreamerPacketHandlerType.eGameState: gameStatePacketCount++; frameLength = UDPPacketSizes.gameStateDataPacketSize; GCHandle gameStateHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sGameStateData gameState = (sGameStateData)Marshal.PtrToStructure(gameStateHandle.AddrOfPinnedObject(), typeof(sGameStateData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, gameState); } finally { gameStateHandle.Free(); } break; case EUDPStreamerPacketHandlerType.eWeatherState: weatherStatePacketCount++; Console.WriteLine("Got an undocumented and unsupported weather packet"); break; case EUDPStreamerPacketHandlerType.eVehicleNames: weatherStatePacketCount++; Console.WriteLine("Got an undocumented and unsupported vehicle names packet"); break; case EUDPStreamerPacketHandlerType.eTimeStats: participantsPacketCount++; frameLength = UDPPacketSizes.timeStatsPacketSize; GCHandle timeStatsHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sTimeStatsData timeStatsData = (sTimeStatsData)Marshal.PtrToStructure(timeStatsHandle.AddrOfPinnedObject(), typeof(sTimeStatsData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, timeStatsData); } finally { timeStatsHandle.Free(); } break; case EUDPStreamerPacketHandlerType.eParticipantVehicleNames: participantsPacketCount++; frameLength = UDPPacketSizes.participantVehicleNamesPacketSize; GCHandle vehNamesHandle = GCHandle.Alloc(rawData.Take(frameLength).ToArray(), GCHandleType.Pinned); try { sParticipantVehicleNamesData participantVehicleNames = (sParticipantVehicleNamesData)Marshal.PtrToStructure(vehNamesHandle.AddrOfPinnedObject(), typeof(sParticipantVehicleNamesData)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, participantVehicleNames); } finally { vehNamesHandle.Free(); } break; } return(frameLength); }
public override string ToString() { return("num participants " + mNumParticipants + " viewed index " + mViewedParticipantIndex + " driver name " + StructHelper.getNameFromBytes(mParticipantData[mViewedParticipantIndex].mName) + " LF tyre " + StructHelper.getNameFromBytes(mLFTyreCompoundName)); }
public int mCurrentSector; // [ enum (Type#4) Current Sector ] public override string ToString() { return("position " + mRacePosition + " name " + StructHelper.getNameFromBytes(mName).ToLower() + " lapsCompleted " + mLapsCompleted + " lapDist " + mCurrentLapDistance); }