/* Receives packets and raises events continuously on a thread */ private void ThreadRoutine() { /* Sets up UDP connection objects */ UdpClient client = new UdpClient(port); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port); client.Client.ReceiveTimeout = timeout; /* Loops until broken by the isRunning flag */ while (true) { /* Break if isRunning is false */ flagMtx.WaitOne(); if (!isRunning) { flagMtx.ReleaseMutex(); break; } else { flagMtx.ReleaseMutex(); } byte[] data; /* Try to get data from the socket and restart the loop on timeout */ try { data = client.Receive(ref ep); } catch (SocketException e) { continue; } /* Get the packet type id */ int idInt = GetValidPacketID(ref data); if (idInt == -1) { continue; } PacketID id = (PacketID)idInt; /* Create arguments object for triggering event */ F118ReceivedEventArgs args; /* Parse identified packet and construct PacketReceivedEventArgs object */ switch (id) { case PacketID.MOTION: args = new F118ReceivedEventArgs(ParsePacket <PacketMotionData>(ref data), id); break; case PacketID.SESSION: args = new F118ReceivedEventArgs(ParsePacket <PacketSessionData>(ref data), id); break; case PacketID.LAPDATA: args = new F118ReceivedEventArgs(ParsePacket <PacketLapData>(ref data), id); break; case PacketID.EVENT: args = new F118ReceivedEventArgs(ParsePacket <PacketEventData>(ref data), id); break; case PacketID.PARTICIPANTS: args = new F118ReceivedEventArgs(ParsePacket <PacketParticipantsData>(ref data), id); break; case PacketID.SETUPS: args = new F118ReceivedEventArgs(ParsePacket <PacketCarSetupData>(ref data), id); break; case PacketID.TELEMETRY: args = new F118ReceivedEventArgs(ParsePacket <PacketCarTelemetryData>(ref data), id); break; case PacketID.STATUS: args = new F118ReceivedEventArgs(ParsePacket <PacketCarStatusData>(ref data), id); break; default: continue; } /* Raise event */ RaisePacketReceived(args); } client.Close(); }
/* Runs when triggered by an F118Reader object */ private void OnPacketReceived(object sender, F118ReceivedEventArgs args) { PacketID id = args.id; int carIndex = 0; switch (id) { case PacketID.MOTION: PacketMotionData motion = (PacketMotionData)args.packet; carIndex = motion.m_header.m_playerCarIndex; PositionEventArgs newPos = new PositionEventArgs(); newPos.x = motion.m_carMotionData[carIndex].m_worldPositionX; newPos.y = motion.m_carMotionData[carIndex].m_worldPositionY; newPos.z = motion.m_carMotionData[carIndex].m_worldPositionZ; GForceEventArgs newGs = new GForceEventArgs(); newGs.lat = motion.m_carMotionData[carIndex].m_gForceLateral; newGs.lon = motion.m_carMotionData[carIndex].m_gForceLongitudinal; RaisePositionReceived(newPos); RaiseGForceReceived(newGs); break; case PacketID.TELEMETRY: PacketCarTelemetryData telemetry = (PacketCarTelemetryData)args.packet; carIndex = telemetry.m_header.m_playerCarIndex; PowertrainEventArgs newPow = new PowertrainEventArgs(); sbyte gearByte = telemetry.m_carTelemetryData[carIndex].m_gear; if (gearByte == -1) { newPow.gear = 'R'; } else if (gearByte == 0) { newPow.gear = 'N'; } else { newPow.gear = (char)('0' + gearByte); } newPow.rpm = telemetry.m_carTelemetryData[carIndex].m_engineRPM; newPow.kmh = telemetry.m_carTelemetryData[carIndex].m_speed; newPow.mph = telemetry.m_carTelemetryData[carIndex].m_speed * 0.621371f; AxesEventArgs newAxes = new AxesEventArgs(); newAxes.throttle = telemetry.m_carTelemetryData[carIndex].m_throttle / 100.0f; newAxes.brake = telemetry.m_carTelemetryData[carIndex].m_brake / 100.0f; newAxes.clutch = telemetry.m_carTelemetryData[carIndex].m_clutch / 100.0f; newAxes.steering = telemetry.m_carTelemetryData[carIndex].m_steer / 100.0f; RaisePowertrainReceived(newPow); RaiseAxesReceived(newAxes); break; case PacketID.STATUS: PacketCarStatusData status = (PacketCarStatusData)args.packet; dataMtx.WaitOne(); maxRpm = status.m_carStatusData[carIndex].m_maxRPM; dataMtx.ReleaseMutex(); break; default: return; } }
/* Raises a PacketReceivedEvent if someone has subscibed to it */ private void RaisePacketReceived(F118ReceivedEventArgs args) { PacketReceivedEvent?.Invoke(this, args); }