private int readFromOffset(int offset, byte[] rawData) { totalPacketCount++; if (totalPacketCount == estimateRateStartPacket) { ticksAtRateEstimateStart = DateTime.Now.Ticks; } else if (totalPacketCount == estimateRateEndPacket && ticksAtRateEstimateStart > 0) { rateEstimate = (float)(TimeSpan.TicksPerSecond * (estimateRateEndPacket - estimateRateStartPacket)) / (float)(DateTime.Now.Ticks - ticksAtRateEstimateStart); } // the first 2 bytes are the version - discard it for now int frameTypeAndSequence = rawData[offset + 2]; int frameType = frameTypeAndSequence & 3; int sequence = frameTypeAndSequence >> 2; int frameLength = 0; if (frameType == 0) { telemPacketCount++; frameLength = sTelemetryData_PacketSize; Boolean sequenceCheckOK = isNextInSequence(sequence); if (strictPacketOrdering && !sequenceCheckOK) { discardedTelemCount++; } else { handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sTelemetryData telem = (sTelemetryData)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sTelemetryData)); if (sequenceCheckOK || !telemIsOutOfSequence(telem)) { //buttonsState = ConvertByteToBoolArray(telem.sDPad); lastSequenceNumberForTelemPacket = sequence; workingGameState = StructHelper.MergeWithExistingState(workingGameState, telem); newSpotterData = workingGameState.hasNewPositionData; handle.Free(); } } } else if (frameType == 1) { frameLength = sParticipantInfoStrings_PacketSize; handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sParticipantInfoStrings strings = (sParticipantInfoStrings)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sParticipantInfoStrings)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, strings); handle.Free(); } else if (frameType == 2) { frameLength = sParticipantInfoStringsAdditional_PacketSize; handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sParticipantInfoStringsAdditional additional = (sParticipantInfoStringsAdditional)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sParticipantInfoStringsAdditional)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, additional); handle.Free(); } return(frameLength + offset); }
public override Object ReadGameData() { PCarsStructWrapper structWrapper = new PCarsStructWrapper(); structWrapper.ticksWhenRead = DateTime.Now.Ticks; lock (this) { if (!initialised) { if (!InitialiseInternal()) { throw new GameDataReadException("Failed to initialise UDP client"); } } //previousGameState = StructHelper.Clone(currentGameState); currentGameState = StructHelper.Clone(workingGameState); } structWrapper.data = currentGameState; return(structWrapper); }