Пример #1
0
        public SessionInfo()
        {
            id           = 0;
            lapsTotal    = 0;
            lapsComplete = 0;
            leadChanges  = 0;
            cautions     = 0;
            cautionLaps  = 0;

            fastestlap    = 0;
            fastestdriver = new DriverInfo();
            fastestlapnum = 0;

            time = 0;
            sessiontimeremaining = 0;
            sessionlength        = 0;
            sessionstarttime     = -1;
            sessionstartpos      = 0;
            finishline           = Int32.MaxValue;

            type       = SessionTypes.none;
            state      = SessionStates.invalid;
            flag       = SessionFlags.invalid;
            startlight = SessionStartLights.off;

            standings      = new ObservableCollection <StandingsItem>();
            followedDriver = new StandingsItem();
        }
Пример #2
0
    public Singleton(
        DiContainer container,
        GameStateMachine <JamStateType> gsMachine,
        SessionFlags pSessionFlags,
        [Inject(Id = GameInstaller.GLOBAL_DISPATCHER)]
        IEventDispatcher eventDispatcher,
        GameConfig pGameConfig,
        NetworkManager pNetworkManager,
        GuiManager guiManager,
        ParticleGOD pparticleGod,
        AudioSystem pAudioSystem)
    {
        diContainer            = container;
        sessionFlags           = pSessionFlags;
        gameConfig             = pGameConfig;
        gameStateMachine       = gsMachine;
        notificationDispatcher = eventDispatcher;
        networkManager         = pNetworkManager;
        gui         = guiManager;
        particleGod = pparticleGod;
        audioSystem = pAudioSystem;

        _initialize();
        _instance = this;
    }
Пример #3
0
 internal static void HandleHTTPError(Session oSession, SessionFlags flagViolation, bool bPoisonClientConnection, bool bPoisonServerConnection, string sMessage)
 {
     if (bPoisonClientConnection)
     {
         oSession.PoisonClientPipe();
     }
     if (bPoisonServerConnection)
     {
         oSession.PoisonServerPipe();
     }
     oSession.SetBitFlag(flagViolation, true);
     if ((CONFIG.bReportHTTPErrors && !CONFIG.QuietMode) && !oSession.oFlags.ContainsKey("x-HTTPProtocol-Violation"))
     {
         oSession.oFlags.Remove("ui-hide");
         frmAlert alert = new frmAlert("HTTP Protocol Violation", "Fiddler has detected a protocol violation in session #" + oSession.id.ToString() + ".\n\n" + sMessage, "Note: You can disable this message using Tools | Fiddler Options");
         _frmMain.BeginInvoke(new alerterDelegate(_frmMain.ShowAlert), new object[] { alert });
     }
     Log.LogFormat("{0} - [#{1}] {2}", new object[] { "Fiddler.Network.ProtocolViolation", oSession.id.ToString(), sMessage });
     sMessage = "[ProtocolViolation] " + sMessage;
     if ((oSession["x-HTTPProtocol-Violation"] == null) || !oSession["x-HTTPProtocol-Violation"].Contains(sMessage))
     {
         Session session;
         (session = oSession)["x-HTTPProtocol-Violation"] = session["x-HTTPProtocol-Violation"] + sMessage;
     }
 }
Пример #4
0
 public override bool ClearSessionFlag(string flag)
 {
     lock (SessionFlags)
     {
         return(SessionFlags.Remove(flag));
     }
 }
Пример #5
0
 public override bool HasSessionFlag(string flag)
 {
     lock (SessionFlags)
     {
         return(SessionFlags.Contains(flag));
     }
 }
 public SessionSetupResponse(byte[] buffer, int offset) : base(buffer, offset)
 {
     StructureSize        = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
     SessionFlags         = (SessionFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
     SecurityBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 4);
     SecurityBufferLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
     SecurityBuffer       = ByteReader.ReadBytes(buffer, offset + SecurityBufferOffset, SecurityBufferLength);
 }
Пример #7
0
    public void Awake()
    {
        _instance = this;

        _stateFactory    = new TacoTuesdayStateFactory();
        gameStateMachine = new GameStateMachine(_stateFactory);

        sessionFlags   = new SessionFlags();
        networkManager = gameObject.AddComponent <NetworkManager>();

        Input.multiTouchEnabled = false; //This needs to go elsewere
    }
Пример #8
0
        public override bool SetSessionFlag(string flag)
        {
            if (HasSessionFlag(flag))
            {
                return(false);
            }

            lock (SessionFlags)
            {
                SessionFlags.Add(flag);
            }
            return(true);
        }
        public HelpSystem(SessionFlags session)
        {
            if (!Enum.IsDefined( typeof( SessionFlags ), session ))
            {
                throw new ArgumentException(
                    string.Format(
                        "Неправильный тип перечисления {0} - {1}",
                        session.GetType().ToString(), (int)session
                        )
                );
            }

            _sessionFlags = session;
        }
Пример #10
0
        private static Session _getSessionFromEntry(Hashtable htEntry)
        {
            Hashtable htRequest = (Hashtable)htEntry["request"];

            byte[]    array     = HTTPArchiveJSONImport._getRequestFromEntry(htRequest);
            Hashtable hashtable = (Hashtable)htEntry["response"];

            byte[] array2 = HTTPArchiveJSONImport._getResponseFromEntry(hashtable);
            if (array == null || array2 == null)
            {
                MessageBox.Show("Failed to get session from entry");
                return(null);
            }
            SessionFlags sessionFlags = 64;
            Session      session      = new Session(array, array2, sessionFlags);
            int          totalSize    = HTTPArchiveJSONImport.getTotalSize(hashtable);

            if (totalSize > 0)
            {
                session.set_Item("X-TRANSFER-SIZE", totalSize.ToString());
            }
            if (htEntry.ContainsKey("comment"))
            {
                string text = (string)htEntry["comment"];
                if (!string.IsNullOrEmpty(text))
                {
                    session.set_Item("ui-comments", text);
                }
            }
            DateTime now;

            if (!DateTime.TryParse((string)htEntry["startedDateTime"], out now))
            {
                now = DateTime.Now;
            }
            if (htEntry.ContainsKey("timings"))
            {
                Hashtable htTimers = (Hashtable)htEntry["timings"];
                session.Timers.DNSTime             = HTTPArchiveJSONImport.getMilliseconds(htTimers, "dns");
                session.Timers.TCPConnectTime      = HTTPArchiveJSONImport.getMilliseconds(htTimers, "connect");
                session.Timers.HTTPSHandshakeTime  = HTTPArchiveJSONImport.getMilliseconds(htTimers, "ssl");
                session.Timers.ClientConnected     = (session.Timers.ClientBeginRequest = (session.Timers.FiddlerGotRequestHeaders = (session.Timers.ClientDoneRequest = now)));
                session.Timers.ServerConnected     = (session.Timers.FiddlerBeginRequest = now.AddMilliseconds((double)(HTTPArchiveJSONImport.getMilliseconds(htTimers, "blocked") + session.Timers.DNSTime + session.Timers.TCPConnectTime + session.Timers.HTTPSHandshakeTime)));
                session.Timers.ServerGotRequest    = session.Timers.FiddlerBeginRequest.AddMilliseconds((double)HTTPArchiveJSONImport.getMilliseconds(htTimers, "send"));
                session.Timers.ServerBeginResponse = (session.Timers.FiddlerGotResponseHeaders = session.Timers.ServerGotRequest.AddMilliseconds((double)HTTPArchiveJSONImport.getMilliseconds(htTimers, "wait")));
                session.Timers.ServerDoneResponse  = session.Timers.ServerBeginResponse.AddMilliseconds((double)HTTPArchiveJSONImport.getMilliseconds(htTimers, "receive"));
                session.Timers.ClientBeginResponse = (session.Timers.ClientDoneResponse = session.Timers.ServerDoneResponse);
            }
            return(session);
        }
        public HelpSystem(SessionFlags session)
        {
            if (!Enum.IsDefined(typeof(SessionFlags), session))
            {
                throw new ArgumentException(
                          string.Format(
                              "Неправильный тип перечисления {0} - {1}",
                              session.GetType().ToString(), (int)session
                              )
                          );
            }

            _sessionFlags = session;
        }
Пример #12
0
        private static Session _getSessionFromEntry(Hashtable htEntry)
        {
            DateTime  now;
            Hashtable htRequest = (Hashtable)htEntry["request"];

            byte[]    arrRequest = _getRequestFromEntry(htRequest);
            Hashtable htResponse = (Hashtable)htEntry["response"];

            byte[] arrResponse = _getResponseFromEntry(htResponse);
            if ((arrRequest == null) || (arrResponse == null))
            {
                MessageBox.Show("Failed to get session from entry");
                return(null);
            }
            SessionFlags responseStreamed = SessionFlags.ResponseStreamed;
            Session      session          = new Session(arrRequest, arrResponse, responseStreamed);
            int          num = getTotalSize(htResponse);

            if (num > 0)
            {
                session["X-TRANSFER-SIZE"] = num.ToString();
            }
            if (htEntry.ContainsKey("comment"))
            {
                string str = (string)htEntry["comment"];
                if (!string.IsNullOrEmpty(str))
                {
                    session["ui-comments"] = str;
                }
            }
            if (!DateTime.TryParse((string)htEntry["startedDateTime"], out now))
            {
                now = DateTime.Now;
            }
            if (htEntry.ContainsKey("timings"))
            {
                Hashtable htTimers = (Hashtable)htEntry["timings"];
                session.Timers.DNSTime             = getMilliseconds(htTimers, "dns");
                session.Timers.TCPConnectTime      = getMilliseconds(htTimers, "connect");
                session.Timers.HTTPSHandshakeTime  = getMilliseconds(htTimers, "ssl");
                session.Timers.ClientConnected     = session.Timers.ClientBeginRequest = session.Timers.FiddlerGotRequestHeaders = session.Timers.ClientDoneRequest = now;
                session.Timers.ServerConnected     = session.Timers.FiddlerBeginRequest = now.AddMilliseconds((double)(((getMilliseconds(htTimers, "blocked") + session.Timers.DNSTime) + session.Timers.TCPConnectTime) + session.Timers.HTTPSHandshakeTime));
                session.Timers.ServerGotRequest    = session.Timers.FiddlerBeginRequest.AddMilliseconds((double)getMilliseconds(htTimers, "send"));
                session.Timers.ServerBeginResponse = session.Timers.FiddlerGotResponseHeaders = session.Timers.ServerGotRequest.AddMilliseconds((double)getMilliseconds(htTimers, "wait"));
                session.Timers.ServerDoneResponse  = session.Timers.ServerBeginResponse.AddMilliseconds((double)getMilliseconds(htTimers, "receive"));
                session.Timers.ClientBeginResponse = session.Timers.ClientDoneResponse = session.Timers.ServerDoneResponse;
            }
            return(session);
        }
Пример #13
0
    private void _initialize()
    {
        name = "(singleton)";
        DontDestroyOnLoad(gameObject);

        _stateFactory          = new NovaStateFactory();
        gameStateMachine       = new GameStateMachine(_stateFactory);
        sessionFlags           = new SessionFlags();
        notificationDispatcher = new NotificationDispatcher();

        networkManager          = gameObject.AddComponent <NetworkManager>();
        gameConfig              = Resources.Load <GameConfig>("GameConfig");
        Input.multiTouchEnabled = false; //TODO: This needs to go elsewere

        _postInit();
    }
Пример #14
0
        public static Session Import(Entry entry)
        {
            DateTime now;
            Request  htRequest = entry.request;

            byte[]   arrRequest = GetRequestFromEntry(htRequest);
            Response htResponse = entry.response;

            byte[] arrResponse = GetResponseFromEntry(htResponse);

            if ((arrRequest == null) || (arrResponse == null))
            {
                throw new Exception("Failed to get session from entry");
            }

            const SessionFlags responseStreamed = SessionFlags.ResponseStreamed;
            var session = new Session(arrRequest, arrResponse, responseStreamed);
            int num     = GetTotalSize(htResponse);

            if (num > 0)
            {
                session["X-TRANSFER-SIZE"] = num.ToString(CultureInfo.InvariantCulture);
            }

            session["ui-comments"] = entry.comment;

            if (!DateTime.TryParse(entry.startedDateTime, out now))
            {
                now = DateTime.Now;
            }

            session.Timers.DNSTime                 = entry.timings.dns;
            session.Timers.TCPConnectTime          = entry.timings.connect;
            session.Timers.HTTPSHandshakeTime      = entry.timings.ssl;
            session.Timers.ClientConnected         = session.Timers.ClientBeginRequest = session.Timers.ClientDoneRequest = now;
            session.Timers.ServerConnected         =
                session.Timers.FiddlerBeginRequest =
                    now.AddMilliseconds(((entry.timings.blocked + session.Timers.DNSTime) + session.Timers.TCPConnectTime) +
                                        session.Timers.HTTPSHandshakeTime);
            session.Timers.ServerGotRequest    = session.Timers.FiddlerBeginRequest.AddMilliseconds(entry.timings.send);
            session.Timers.ServerBeginResponse = now.AddMilliseconds(entry.timings.wait);
            session.Timers.ServerDoneResponse  =
                session.Timers.ServerBeginResponse.AddMilliseconds(entry.timings.receive);
            session.Timers.ClientBeginResponse = session.Timers.ClientDoneResponse = session.Timers.ServerDoneResponse;
            return(session);
        }
Пример #15
0
 internal static void HandleHTTPError(Session oSession, SessionFlags flagViolation, bool bPoisonClientConnection, bool bPoisonServerConnection, string sMessage)
 {
     if (bPoisonClientConnection)
     {
         oSession.PoisonClientPipe();
     }
     if (bPoisonServerConnection)
     {
         oSession.PoisonServerPipe();
     }
     oSession.SetBitFlag(flagViolation, true);
     oSession["ui-backcolor"] = "LightYellow";
     sMessage = "[ProtocolViolation] " + sMessage;
     if ((oSession["x-HTTPProtocol-Violation"] == null) || !oSession["x-HTTPProtocol-Violation"].Contains(sMessage))
     {
         Session session;
         (session = oSession)["x-HTTPProtocol-Violation"] = session["x-HTTPProtocol-Violation"] + sMessage;
     }
 }
Пример #16
0
 internal static void HandleHTTPError(Session oSession, SessionFlags flagViolation, bool bPoisonClientConnection, bool bPoisonServerConnection, string sMessage)
 {
     if (bPoisonClientConnection)
     {
         oSession.PoisonClientPipe();
     }
     if (bPoisonServerConnection)
     {
         oSession.PoisonServerPipe();
     }
     oSession.SetBitFlag(flagViolation, true);
     oSession["ui-backcolor"] = "LightYellow";
     FiddlerApplication.Log.LogFormat("{0} - [#{1}] {2}", new object[]
     {
         "Fiddler.Network.ProtocolViolation",
         oSession.Int32_0.ToString(),
         sMessage
     });
     sMessage = "[ProtocolViolation] " + sMessage;
     if (oSession["x-HTTPProtocol-Violation"] == null || !oSession["x-HTTPProtocol-Violation"].Contains(sMessage))
     {
         oSession["x-HTTPProtocol-Violation"] = oSession["x-HTTPProtocol-Violation"] + sMessage;
     }
 }
Пример #17
0
 public Session(byte[] arrRequest, byte[] arrResponse, SessionFlags oSF)
 {
     HTTPHeaderParseWarnings warnings;
     int num;
     int num2;
     int num3;
     int num4;
     this.bBufferResponse = FiddlerApplication.Prefs.GetBoolPref("fiddler.ui.rules.bufferresponses", false);
     this.Timers = new SessionTimers();
     this._bAllowClientPipeReuse = true;
     this.oFlags = new StringDictionary();
     if (Utilities.IsNullOrEmpty(arrRequest))
     {
         throw new ArgumentException("Missing request data for session");
     }
     if (Utilities.IsNullOrEmpty(arrResponse))
     {
         arrResponse = Encoding.ASCII.GetBytes("HTTP/1.1 0 FIDDLER GENERATED - RESPONSE DATA WAS MISSING\r\n\r\n");
     }
     this.state = SessionStates.Done;
     this.m_requestID = Interlocked.Increment(ref cRequests);
     this.BitFlags = oSF;
     if (!Parser.FindEntityBodyOffsetFromArray(arrRequest, out num, out num2, out warnings))
     {
         throw new InvalidDataException("Request corrupt, unable to find end of headers.");
     }
     if (!Parser.FindEntityBodyOffsetFromArray(arrResponse, out num3, out num4, out warnings))
     {
         throw new InvalidDataException("Response corrupt, unable to find end of headers.");
     }
     this.requestBodyBytes = new byte[arrRequest.Length - num2];
     this.responseBodyBytes = new byte[arrResponse.Length - num4];
     Buffer.BlockCopy(arrRequest, num2, this.requestBodyBytes, 0, this.requestBodyBytes.Length);
     Buffer.BlockCopy(arrResponse, num4, this.responseBodyBytes, 0, this.responseBodyBytes.Length);
     string sData = CONFIG.oHeaderEncoding.GetString(arrRequest, 0, num) + "\r\n\r\n";
     string sHeaders = CONFIG.oHeaderEncoding.GetString(arrResponse, 0, num3) + "\r\n\r\n";
     this.oRequest = new ClientChatter(this, sData);
     this.oResponse = new ServerChatter(this, sHeaders);
 }
Пример #18
0
 public bool isAnyFlagSet(SessionFlags flagsToTest)
 {
     return (SessionFlags.None != (this._bitFlags & flagsToTest));
 }
Пример #19
0
 public bool IsFlagSet(SessionFlags FlagsToTest)
 {
     return (FlagsToTest == (this._bitFlags & FlagsToTest));
 }
Пример #20
0
 public bool isFlagSet(SessionFlags flagsToTest)
 {
     return (flagsToTest == (this._bitFlags & flagsToTest));
 }
Пример #21
0
 internal void SetBitFlag(SessionFlags FlagsToSet, bool b)
 {
     if (b)
     {
         this.BitFlags = this._bitFlags | FlagsToSet;
     }
     else
     {
         this.BitFlags = this._bitFlags & ~FlagsToSet;
     }
 }
Пример #22
0
        public SessionInfo()
        {

            id = 0;
            lapsTotal = 0;
            lapsComplete = 0;
            leadChanges = 0;
            cautions = 0;
            cautionLaps = 0;

            fastestlap = 0;
            fastestdriver = new DriverInfo();
            fastestlapnum = 0;

            time = 0;
            sessiontimeremaining = 0;
            sessionlength = 0;
            sessionstarttime = -1;
            sessionstartpos = 0;
            finishline = Int32.MaxValue;

            type = SessionTypes.none;
            state = SessionStates.invalid;
            flag = SessionFlags.invalid;
            startlight = SessionStartLights.off;

            standings = new ObservableCollection<StandingsItem>();
            followedDriver = new StandingsItem();
        }
Пример #23
0
 internal static void HandleHTTPError(Session oSession, SessionFlags flagViolation, bool bPoisonClientConnection, bool bPoisonServerConnection, string sMessage)
 {
     if (bPoisonClientConnection)
     {
         oSession.PoisonClientPipe();
     }
     if (bPoisonServerConnection)
     {
         oSession.PoisonServerPipe();
     }
     oSession.SetBitFlag(flagViolation, true);
     oSession["ui-backcolor"] = "LightYellow";
     Log.LogFormat("{0} - [#{1}] {2}", new object[] { "Fiddler.Network.ProtocolViolation", oSession.id.ToString(), sMessage });
     sMessage = "[ProtocolViolation] " + sMessage;
     if ((oSession["x-HTTPProtocol-Violation"] == null) || !oSession["x-HTTPProtocol-Violation"].Contains(sMessage))
     {
         Session session;
         (session = oSession)["x-HTTPProtocol-Violation"] = session["x-HTTPProtocol-Violation"] + sMessage;
     }
 }
 public HelpSystem(SessionFlags session, IGeneralConfigSystem genConfig)
     : this(session)
 {
     GeneralConfig = genConfig;
 }
 public HelpSystem(SessionFlags session, IGeneralConfigSystem genConfig)
     : this( session )
 {
     GeneralConfig = genConfig;
 }
Пример #26
0
 void ClearRedirectFlag(SessionFlags flag)
 {
     m_flags &= ~flag;
 }
Пример #27
0
        private void CalculateLivePositions(iRacingData telemetry)
        {
            if (!_raceSessionInProgress)
            {
                this._carIdxToGameTimeOffTrack.Clear();
            }

            // Assume race has finished.
            this._raceSessionInProgress = false;

            // In a race that is not yet in checkered flag mode,
            // Live positions are determined from track position (total lap distance)
            // Any other conditions (race finished, P, Q, etc), positions are ordered as result positions
            SessionFlags flag = (SessionFlags)telemetry.SessionFlags;

            if (this.SessionData.SessionType == "Race" && flag.HasFlag(SessionFlags.Checkered))
            {
                // We need to check if player is the first (p1) to cross the s/f line as HasCrossedSFLine is only true for 1 tick
                if (raceEndState == RaceEndState.WAITING_TO_CROSS_LINE || _driver.Live.IsNewLap)
                {
                    if (this._driver.Live.IsNewLap)
                    {
                        Console.WriteLine("Player just crossed line to finish race");
                        raceEndState = RaceEndState.FINISHED;

                        this._driver.FinishStatus = Driver.FinishState.Finished;
                    }
                }
                else if (raceEndState == RaceEndState.NONE)
                {
                    Console.WriteLine("Starting wait for player crossing line");
                    raceEndState = RaceEndState.WAITING_TO_CROSS_LINE;
                }
            }
            else
            {
                raceEndState = RaceEndState.NONE;
            }
            if (this.SessionData.SessionType == "Race" && raceEndState != RaceEndState.FINISHED &&
                (flag.HasFlag(SessionFlags.StartGo) || flag.HasFlag(SessionFlags.StartHidden /*yellow?*/)) &&
                telemetry.PlayerCarPosition > 0)
            {
                this._raceSessionInProgress = true;

                // When driver disconnects (or in other cases I am not sure about yet), TotalLapDitance
                // gets ceiled to the nearest integer.  Because of that, for the reminder of a lap such car is
                // ahead of others by TotalLapDitance, which results incorrect positions announced.
                //
                // To mitigate that, try detecting such cases and using floor(TotalLapDitance) instead.
                //
                // Also, try detecting cars that finished and use YAML reported positions instead for those.

                if (this._gameTimeWhenWhiteFlagTriggered == -1.0 && flag.HasFlag(SessionFlags.White))
                {
                    this._gameTimeWhenWhiteFlagTriggered = telemetry.SessionTime;
                }

                // Correct the distances
                foreach (var driver in _drivers)
                {
                    if (driver.IsSpectator || driver.IsPaceCar || driver.CurrentResults.IsOut)
                    {
                        continue;
                    }

                    if (Math.Floor(driver.Live.TotalLapDistanceCorrected) > driver.Live.LiveLapsCompleted)
                    {
                        driver.Live.TotalLapDistanceCorrected = (float)driver.Live.LiveLapsCompleted;
                    }
                }

                // If leader has not finished yet, check if he just did.
                if (_leaderFinished == null && this._gameTimeWhenWhiteFlagTriggered != -1.0)
                {
                    // See if leading driver crossed s/f line after race time expired.
                    foreach (var driver in _drivers.OrderByDescending(d => d.Live.TotalLapDistanceCorrected))
                    {
                        if (driver.IsSpectator || driver.IsPaceCar || driver.CurrentResults.IsOut)
                        {
                            continue;
                        }

                        if (driver.IsCurrentDriver)
                        {
                            // It appears that player s/f crossing time is set before the actual s/f crossing.  So, for player "Finished" state
                            // rely on logic that waits for new lap crossing.
                            continue;
                        }

                        if (driver.Live.GameTimeWhenLastCrossedSFLine > this._gameTimeWhenWhiteFlagTriggered)
                        {
                            _leaderFinished = driver;
                        }

                        // Only check assumed leader by lapdist (skipping lapped vehicles, spectators etc).
                        break;
                    }
                }

                // Now, detect lapped and retired finishers.
                foreach (var driver in _drivers)
                {
                    if (_leaderFinished != null &&
                        driver.Live.GameTimeWhenLastCrossedSFLine >= _leaderFinished.Live.GameTimeWhenLastCrossedSFLine)
                    {
                        if (driver.IsCurrentDriver || driver.IsPaceCar)
                        {
                            // It appears that player s/f crossing time is set before the actual s/f crossing.  So, for player "Finished" state
                            // rely on logic that waits for new lap crossing.
                            continue;
                        }

                        // Everyone, who crosses s/f after leader finished, finishes too.
                        driver.FinishStatus = Driver.FinishState.Finished;
                    }

                    // Try detecting disconnects.  Save last time seen off world, and mark as disconnect if
                    // stays off world long enough.
                    if (driver.FinishStatus == Driver.FinishState.Unknown)  // Don't do any processing for Finished and Retired.
                    {
                        if (driver.Live.TrackSurface == TrackSurfaces.NotInWorld)
                        {
                            var timeSinceOffWorld = -1.0;
                            if (!this._carIdxToGameTimeOffTrack.TryGetValue(driver.Id, out timeSinceOffWorld))
                            {
                                this._carIdxToGameTimeOffTrack.Add(driver.Id, telemetry.SessionTime);
                            }
                            else if (telemetry.SessionTime - timeSinceOffWorld > SECONDS_OFF_WORLD_TILL_RETIRED)
                            {
                                driver.FinishStatus = Driver.FinishState.Retired;
                                Console.WriteLine("Marking driver: " + driver.Name + " as retired.");
                            }
                        }
                        else
                        {
                            this._carIdxToGameTimeOffTrack.Remove(driver.Id);
                        }
                    }

                    if (driver.FinishStatus == Driver.FinishState.Retired &&
                        driver.Live.TrackSurface != TrackSurfaces.NotInWorld)
                    {
                        driver.FinishStatus = Driver.FinishState.Unknown;
                        Console.WriteLine("Driver: " + driver.Name + " was previously marked as retired, shown up again.");
                    }
                }

                // Determine live position from lap distance.
                int pos = 1;
                foreach (var driver in _drivers.OrderByDescending(d => d.Live.TotalLapDistanceCorrected))
                {
                    if (driver.IsSpectator || driver.IsPaceCar || driver.CurrentResults.IsOut)
                    {
                        driver.Live.Position = 1001;  // Make it obvious those guys are not tracked.
                        continue;
                    }
                    if (driver.FinishStatus == Driver.FinishState.Finished &&
                        driver.Live.TrackSurface == TrackSurfaces.NotInWorld)
                    {
                        // When finished driver disconnects, use game reported position.
                        // This should not mess up order of drivers following, because all the
                        // drivers are ordered by TotalLapDistanceCorrected.
                        driver.Live.Position = driver.CurrentResults.Position;

                        if (driver.Live.Position == 0)
                        {
                            driver.Live.Position = 1000;  // Game sends nonsense again.  Mark those so that they don't interfere with sorting anywhere.
                        }
                    }
                    else
                    {
                        driver.Live.Position = pos;
                    }
                    pos++;
                }
            }
            else  // Not Race or Finished.
            {
                // Clear out cached finished leader.  Ugly data model, ugly workarounds :(
                _leaderFinished = null;
                _gameTimeWhenWhiteFlagTriggered = -1.0;

                // In P or Q, set live position from result position (== best lap according to iRacing)
                foreach (var driver in _drivers)
                {
                    if (driver.IsSpectator || driver.IsPaceCar)
                    {
                        driver.Live.Position = 1001;  // Make it obvious those guys are not tracked.
                        continue;
                    }
                    if (telemetry.CarIdxPosition[driver.Id] > 0 && raceEndState != RaceEndState.FINISHED)
                    {
                        driver.Live.Position = telemetry.CarIdxPosition[driver.Id];
                    }
                    else
                    {
                        driver.Live.Position = driver.CurrentResults.Position;
                    }

                    if (telemetry.CarIdxClassPosition[driver.Id] > 0 && raceEndState != RaceEndState.FINISHED)
                    {
                        driver.Live.ClassPosition = telemetry.CarIdxClassPosition[driver.Id];
                    }
                    else
                    {
                        driver.Live.ClassPosition = driver.CurrentResults.ClassPosition;
                    }

                    if (driver.Live.Position == 0)
                    {
                        driver.Live.Position = 1000;  // Game sends nonsense again.  Mark those so that they don't interfere with sorting anywhere.
                    }

                    if (driver.Live.ClassPosition == 0)
                    {
                        driver.Live.ClassPosition = 1000;  // Game sends nonsense again.  Mark those so that they don't interfere with sorting anywhere.
                    }
                }
            }
        }