Exemplo n.º 1
0
        private void OnRealtimeCarUpdate(string sender, RealtimeCarUpdate carInfo)
        {
            try {
                CarData car = Cars.FirstOrDefault(x => x.CarIndex == carInfo.CarIndex);

                if (car != null)
                {
                    car.Update(carInfo);
                }
            }
            catch (Exception ex) {
                Debug.WriteLine(ex.Message);
            }
        }
        internal void ProcessMessage(BinaryReader br)
        {
            // Any message starts with an 1-byte command type
            var messageType = (InboundMessageTypes)br.ReadByte();

            switch (messageType)
            {
            case InboundMessageTypes.REGISTRATION_RESULT:
            {
                ConnectionId = br.ReadInt32();
                var connectionSuccess = br.ReadByte() > 0;
                var isReadonly        = br.ReadByte() == 0;
                var errMsg            = ReadString(br);

                OnConnectionStateChanged?.Invoke(ConnectionId, connectionSuccess, isReadonly, errMsg);

                // In case this was successful, we will request the initial data
                RequestEntryList();
                RequestTrackData();
            }
            break;

            case InboundMessageTypes.ENTRY_LIST:
            {
                _entryListCars.Clear();

                var connectionId  = br.ReadInt32();
                var carEntryCount = br.ReadUInt16();
                for (int i = 0; i < carEntryCount; i++)
                {
                    _entryListCars.Add(new CarInfo(br.ReadUInt16()));
                }
            }
            break;

            case InboundMessageTypes.ENTRY_LIST_CAR:
            {
                var carId = br.ReadUInt16();

                var carInfo = _entryListCars.SingleOrDefault(x => x.CarIndex == carId);
                if (carInfo == null)
                {
                    System.Diagnostics.Debug.WriteLine($"Entry list update for unknown carIndex {carId}");
                    break;
                }

                carInfo.CarModelType       = br.ReadByte();   // Byte sized car model
                carInfo.TeamName           = ReadString(br);
                carInfo.RaceNumber         = br.ReadInt32();
                carInfo.CupCategory        = br.ReadByte();  // Cup: Overall/Pro = 0, ProAm = 1, Am = 2, Silver = 3, National = 4
                carInfo.CurrentDriverIndex = br.ReadByte();
                carInfo.Nationality        = (NationalityEnum)br.ReadUInt16();

                // Now the drivers on this car:
                var driversOnCarCount = br.ReadByte();
                for (int di = 0; di < driversOnCarCount; di++)
                {
                    var driverInfo = new DriverInfo();

                    driverInfo.FirstName = ReadString(br);
                    driverInfo.LastName  = ReadString(br);
                    driverInfo.ShortName = ReadString(br);
                    driverInfo.Category  = (DriverCategory)br.ReadByte();        // Platinum = 3, Gold = 2, Silver = 1, Bronze = 0

                    // new in 1.13.11:
                    driverInfo.Nationality = (NationalityEnum)br.ReadUInt16();

                    carInfo.AddDriver(driverInfo);
                }

                OnEntrylistUpdate?.Invoke(ConnectionIdentifier, carInfo);
            }
            break;

            case InboundMessageTypes.REALTIME_UPDATE:
            {
                RealtimeUpdate update = new RealtimeUpdate();
                update.EventIndex   = (int)br.ReadUInt16();
                update.SessionIndex = (int)br.ReadUInt16();
                update.SessionType  = (RaceSessionType)br.ReadByte();
                update.Phase        = (SessionPhase)br.ReadByte();
                var sessionTime = br.ReadSingle();
                update.SessionTime = TimeSpan.FromMilliseconds(sessionTime);
                var sessionEndTime = br.ReadSingle();
                update.SessionEndTime = TimeSpan.FromMilliseconds(sessionEndTime);

                update.FocusedCarIndex = br.ReadInt32();
                update.ActiveCameraSet = ReadString(br);
                update.ActiveCamera    = ReadString(br);
                update.CurrentHudPage  = ReadString(br);

                update.IsReplayPlaying = br.ReadByte() > 0;
                if (update.IsReplayPlaying)
                {
                    update.ReplaySessionTime   = br.ReadSingle();
                    update.ReplayRemainingTime = br.ReadSingle();
                }

                update.TimeOfDay   = TimeSpan.FromMilliseconds(br.ReadSingle());
                update.AmbientTemp = br.ReadByte();
                update.TrackTemp   = br.ReadByte();
                update.Clouds      = br.ReadByte() / 10.0f;
                update.RainLevel   = br.ReadByte() / 10.0f;
                update.Wetness     = br.ReadByte() / 10.0f;

                update.BestSessionLap = ReadLap(br);

                OnRealtimeUpdate?.Invoke(ConnectionIdentifier, update);
            }
            break;

            case InboundMessageTypes.REALTIME_CAR_UPDATE:
            {
                RealtimeCarUpdate carUpdate = new RealtimeCarUpdate();

                carUpdate.CarIndex       = br.ReadUInt16();
                carUpdate.DriverIndex    = br.ReadUInt16();   // Driver swap will make this change
                carUpdate.DriverCount    = br.ReadByte();
                carUpdate.Gear           = br.ReadByte() - 2; // -2 makes the R -1, N 0 and the rest as-is
                carUpdate.WorldPosX      = br.ReadSingle();
                carUpdate.WorldPosY      = br.ReadSingle();
                carUpdate.Yaw            = br.ReadSingle();
                carUpdate.CarLocation    = (CarLocationEnum)br.ReadByte(); // - , Track, Pitlane, PitEntry, PitExit = 4
                carUpdate.Kmh            = br.ReadUInt16();
                carUpdate.Position       = br.ReadUInt16();                // official P/Q/R position (1 based)
                carUpdate.CupPosition    = br.ReadUInt16();                // official P/Q/R position (1 based)
                carUpdate.TrackPosition  = br.ReadUInt16();                // position on track (1 based)
                carUpdate.SplinePosition = br.ReadSingle();                // track position between 0.0 and 1.0
                carUpdate.Laps           = br.ReadUInt16();

                carUpdate.Delta          = br.ReadInt32(); // Realtime delta to best session lap
                carUpdate.BestSessionLap = ReadLap(br);
                carUpdate.LastLap        = ReadLap(br);
                carUpdate.CurrentLap     = ReadLap(br);

                // the concept is: "don't know a car or driver? ask for an entry list update"
                var carEntry = _entryListCars.FirstOrDefault(x => x.CarIndex == carUpdate.CarIndex);
                if (carEntry == null || carEntry.Drivers.Count != carUpdate.DriverCount)
                {
                    if ((DateTime.Now - lastEntrylistRequest).TotalSeconds > 1)
                    {
                        lastEntrylistRequest = DateTime.Now;
                        RequestEntryList();
                        System.Diagnostics.Debug.WriteLine($"CarUpdate {carUpdate.CarIndex}|{carUpdate.DriverIndex} not know, will ask for new EntryList");
                    }
                }
                else
                {
                    OnRealtimeCarUpdate?.Invoke(ConnectionIdentifier, carUpdate);
                }
            }
            break;

            case InboundMessageTypes.TRACK_DATA:
            {
                var connectionId = br.ReadInt32();
                var trackData    = new TrackData();

                trackData.TrackName   = ReadString(br);
                trackData.TrackId     = br.ReadInt32();
                trackData.TrackMeters = br.ReadInt32();
                TrackMeters           = trackData.TrackMeters > 0 ? trackData.TrackMeters : -1;

                trackData.CameraSets = new Dictionary <string, List <string> >();

                var cameraSetCount = br.ReadByte();
                for (int camSet = 0; camSet < cameraSetCount; camSet++)
                {
                    var camSetName = ReadString(br);
                    trackData.CameraSets.Add(camSetName, new List <string>());

                    var cameraCount = br.ReadByte();
                    for (int cam = 0; cam < cameraCount; cam++)
                    {
                        var cameraName = ReadString(br);
                        trackData.CameraSets[camSetName].Add(cameraName);
                    }
                }

                var hudPages      = new List <string>();
                var hudPagesCount = br.ReadByte();
                for (int i = 0; i < hudPagesCount; i++)
                {
                    hudPages.Add(ReadString(br));
                }
                trackData.HUDPages = hudPages;

                OnTrackDataUpdate?.Invoke(ConnectionIdentifier, trackData);
            }
            break;

            case InboundMessageTypes.BROADCASTING_EVENT:
            {
                BroadcastingEvent evt = new BroadcastingEvent()
                {
                    Type   = (BroadcastingCarEventType)br.ReadByte(),
                    Msg    = ReadString(br),
                    TimeMs = br.ReadInt32(),
                    CarId  = br.ReadInt32(),
                };

                evt.CarData = _entryListCars.FirstOrDefault(x => x.CarIndex == evt.CarId);
                OnBroadcastingEvent?.Invoke(ConnectionIdentifier, evt);
            }
            break;

            default:
                break;
            }
        }