private bool CheckSessionStarted(Rf2FullData rfData, SimulatorDataSet dataSet) { if (_previousSessionTime.TotalSeconds - 1 > dataSet.SessionInfo.SessionTime.TotalSeconds) { Logger.Info($"New Session - Session time is less. Oldtime : {_previousSessionTime.TotalSeconds} - New Time: {dataSet.SessionInfo.SessionTime.TotalSeconds}"); return(true); } if (_rawLastSessionType != rfData.scoring.mScoringInfo.mSession || _lastSessionType != dataSet.SessionInfo.SessionType) { Logger.Info("New Session - Session type doesn't match"); _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = rfData.scoring.mScoringInfo.mSession; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } if (dataSet.SessionInfo.SessionPhase != _lastSessionPhase && _lastSessionPhase != SessionPhase.Green && dataSet.SessionInfo.SessionPhase != SessionPhase.Countdown) { Logger.Info("New Session - Session phase doesn't match"); _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = rfData.scoring.mScoringInfo.mSession; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } return(false); }
public Task SetSessionPhase(Guid sessionId, Guid currentPhaseId, SessionPhase newPhase) { DummySession foundSession = SessionMap[sessionId]; if (foundSession != null) { if (foundSession.PhaseId == currentPhaseId) { foundSession.SetupSessionPhase(newPhase); if (newPhase == SessionPhase.Victory) { foundSession.Round += 1; } return(Task.FromResult(false)); } else { throw new ConcurrencyException(); } } else { throw new InvalidOperationException("Called JoinSession with a non-existant GUID"); } }
protected override void ResetConnector() { _rawLastSessionType = int.MinValue; _lastSessionType = SessionType.Na; _lastSessionPhase = SessionPhase.Countdown; _previousSessionTime = TimeSpan.MinValue;; }
public AssettoCorsaConnector() : base(AcExecutables) { _dependencies = new DependencyChecker( new IDependency[] { new DirectoryExistsDependency(@"apps\python\SecondMonitor"), new DirectoryExistsDependency(@"apps\python\SecondMonitor\stdlib"), new DirectoryExistsDependency(@"apps\python\SecondMonitor\stdlib64"), new FileExistsAndMatchDependency( @"apps\python\SecondMonitor\SecondMonitor.py", @"Connectors\AssettoCorsa\SecondMonitor.py"), new FileExistsAndMatchDependency( @"apps\python\SecondMonitor\smshared_mem.py", @"Connectors\AssettoCorsa\smshared_mem.py"), new FileExistsAndMatchDependency( @"apps\python\SecondMonitor\stdlib\_ctypes.pyd", @"Connectors\AssettoCorsa\stdlib\_ctypes.pyd"), new FileExistsAndMatchDependency( @"apps\python\SecondMonitor\stdlib64\_ctypes.pyd", @"Connectors\AssettoCorsa\stdlib64\_ctypes.pyd"), }, () => true); _assettoCorsaStartObserver = new AssettoCorsaStartObserver(); _physicsBuffer = new MappedBuffer <SPageFilePhysics>(AssettoCorsaShared.SharedMemoryNamePhysics); _graphicsBuffer = new MappedBuffer <SPageFileGraphic>(AssettoCorsaShared.SharedMemoryNameGraphic); _staticBuffer = new MappedBuffer <SPageFileStatic>(AssettoCorsaShared.SharedMemoryNameStatic); _secondMonitorBuffer = new MappedBuffer <SPageFileSecondMonitor>(AssettoCorsaShared.SharedMemoryNameSecondMonitor); _acDataConverter = new AcDataConverter(this, _assettoCorsaStartObserver); _rawLastSessionType = AcSessionType.AC_UNKNOWN; _lastSessionType = SessionType.Na; _lastSessionPhase = SessionPhase.Countdown; _stopwatch = new Stopwatch(); }
private SessionOfExperts CreateSession(SessionPhase phase) { var session = Substitute.For <SessionOfExperts>(); session.CurrentPhase.Returns(phase); return(session); }
protected override void ResetConnector() { _stopwatch.Restart(); _rawLastSessionType = AcSessionType.AC_UNKNOWN; _lastSessionType = SessionType.Na; _lastSessionPhase = SessionPhase.Countdown; _lastDataSet = null; }
public void TestNextPhase(SessionPhase currentPhase, SessionPhase nextPhase) { var session = CreateSession() .SetProperty(nameof(SessionOfExperts.CurrentPhase), currentPhase); session.NextPhaseOrFinish(); session.CurrentPhase.Should().Be(nextPhase); }
public void UpdateSessionBasics(SessionType type, SessionPhase phase) { if (phase == SessionPhase.None) { return; } if (_session == null) { _session = CreateSession(type); Logger.Log($"{type} session started - new weekend"); SessionStarted?.Invoke(this, EventArgs.Empty); } else if (type != _session.Type) { if (IsInProgress(_session.Phase)) { EndTimedPhase(); } Logger.Log($"{_session.Type} session ended"); SessionEnded?.Invoke(this, EventArgs.Empty); var isPartOfWeekend = type > _session.Type; _session = isPartOfWeekend ? CreateSession(type, _session.WeekendId) : CreateSession(type); var message = isPartOfWeekend ? $"{type} session started - part of existing weekend" : $"{type} session started - new weekend"; Logger.Log(message, Severity.Verbose); SessionStarted?.Invoke(this, EventArgs.Empty); } // We capture this so we the nested methods can use the up-to-date session var oldPhase = _session.Phase; _session.UpdateSessionInfo(type, phase); // If we are in the same session, check if we are advancing through the timed phases if (type == _session.Type) { if (IsStarting(oldPhase) && IsInProgress(_session.Phase)) { StartTimedPhase(); } if (IsInProgress(oldPhase) && IsEnding(_session.Phase)) { EndTimedPhase(); } } }
private void IfCurrentSessionIsNotInPhaseThrow(SessionPhase phase) { IfCurrentSessionDoesNotExistThrow(); // ReSharper disable once PossibleNullReferenceException if (CurrentSession.CurrentPhase != phase) { throw new InvalidOperationException(SessionIsNotInPhase); } }
protected SessionOfExperts SetFakeCurrentSession(SessionPhase sessionPhase) { var session = Substitute.For <SessionOfExperts>(); session.CurrentPhase.Returns(sessionPhase); SetFakeCurrentSession(session); return(session); }
public void FinishPhase_SetLastCompletedPhaseAsCurrentPhaseOfSession(SessionPhase currentPhase) { var expert = CreateExpert(); SetCurrentSessionPhase(currentPhase); expert.FinishCurrentPhase(); expert.LastCompletedPhase.Should().Be(currentPhase); }
public string GetScriptCld(string dommePersonalityName, SessionPhase sessionPhase) { if (sessionPhase == SessionPhase.Modules) { return(GetPersonalityFolder(dommePersonalityName) + Path.DirectorySeparatorChar + "System" + Path.DirectorySeparatorChar + "ModuleCheckList.cld"); } else { return(GetPersonalityFolder(dommePersonalityName) + Path.DirectorySeparatorChar + "System" + Path.DirectorySeparatorChar + sessionPhase.ToString() + "CheckList.cld"); } }
public void trigger(float sessionRunningTime, SessionType sessionType, SessionPhase lastSessionPhase, int startPosition, int finishPosition, int numCars, int completedLaps, Boolean isDisqualified, Boolean isDNF, DateTime now) { if (!enableSessionEndMessages) { Console.WriteLine("Session end, position = " + finishPosition + ", session end messages are disabled"); return; } if (lastSessionEndMessagesPlayedAt.AddSeconds(10) > now) { Console.WriteLine("Skipping duplicate session end message call - last call was " + (now - lastSessionEndMessagesPlayedAt).TotalSeconds.ToString("0.00") + " seconds ago"); return; } if (sessionType == SessionType.Race) { if (sessionRunningTime >= minSessionRunTimeForEndMessages || completedLaps > 0) { if (lastSessionPhase == SessionPhase.Finished) { // only play session end message for races if we've actually finished, not restarted lastSessionEndMessagesPlayedAt = now; playFinishMessage(sessionType, startPosition, finishPosition, numCars, isDisqualified, isDNF, completedLaps); } else { Console.WriteLine("Skipping race session end message because the previous phase wasn't Finished"); } } else { Console.WriteLine("Skipping race session end message because it didn't run for a lap or " + minSessionRunTimeForEndMessages + " seconds"); } } else if (sessionType == SessionType.Practice || sessionType == SessionType.Qualify) { if (sessionRunningTime >= minSessionRunTimeForEndMessages) { if (lastSessionPhase == SessionPhase.Green || lastSessionPhase == SessionPhase.FullCourseYellow || lastSessionPhase == SessionPhase.Finished || lastSessionPhase == SessionPhase.Checkered) { lastSessionEndMessagesPlayedAt = now; playFinishMessage(sessionType, startPosition, finishPosition, numCars, false, isDNF, completedLaps); } else { Console.WriteLine("Skipping non-race session end message because the previous phase wasn't green, finished, or checkered"); } } else { Console.WriteLine("Skipping non-race session end message because the session didn't run for " + minSessionRunTimeForEndMessages + " seconds"); } } }
private SessionOfExperts SetFakeSession( SessionPhase sessionPhase = SessionPhase.MakingAssociations) { var session = Substitute.For <SessionOfExperts>(); session.CurrentPhase.Returns(sessionPhase); _fakeSessionOfExpertsRepository.GetCurrent().Returns(session); return(session); }
public void IsPhaseCompleted_CurrentSessionPhaseDoesNotEqualLastCompletedPhase_ReturnFalse( SessionPhase currentPhase, SessionPhase?lastCompletedPhase) { var expert = CreateExpert(); SetCurrentSessionPhase(currentPhase); expert.LastCompletedPhase = lastCompletedPhase; expert.IsPhaseCompleted.Should().Be(false); }
public void SelectNodePost_SessionExistsAndIsNotInRelationPhase_SaveErrorAndRedirectToCurrentSession( SessionPhase currentPhase) { var controllerUnderTest = CreateControllerUnderTest(); SetFakeCurrentSession(currentPhase); var result = (RedirectToRouteResult)controllerUnderTest.SelectNode(new NodeCandidateListViewModel()); Assert.AreEqual(NotAvailableOnThisPhaseErrorMessage, controllerUnderTest.TempData[DataConstants.Error]); Assert.AreEqual("CurrentSession", result.RouteValues["action"]); }
public void Relation_SessionExistsAndIsNotInRelationPhase_ThrowInvalidOperationException( SessionPhase currentPhase) { var serviceUnderTest = CreateServiceUnderTest(); SetFakeSession(currentPhase); Assert.Throws( Is.TypeOf <InvalidOperationException>() .And.Message.EqualTo(SessionIsNotInPhaseErrorMessage), () => serviceUnderTest.Relations(new RelationTupleDto(), "testExpert")); }
public void CreateSemanticNetworkFromNodeCandidates_SessionExistsAndIsNotInNodePhase_InvalidOperationException( SessionPhase currentPhase) { var serviceUnderTest = CreateServiceUnderTest(); SetFakeSession(currentPhase); Assert.Throws( Is.TypeOf <InvalidOperationException>() .And.Message.EqualTo(SessionIsNotInPhaseErrorMessage), () => serviceUnderTest.CreateSemanticNetworkFromNodeCandidates(new List <NodeCandidate>())); }
public void AssociationsTypes_SessionExistsAndIsNotInAssociationTypePhase_InvalidOperationException( SessionPhase currentPhase) { var serviceUnderTest = CreateServiceUnderTest(); SetFakeSession(currentPhase); Assert.Throws( Is.TypeOf <InvalidOperationException>() .And.Message.EqualTo(SessionIsNotInPhaseErrorMessage), () => serviceUnderTest.AssociationsTypes(new List <AssociationDto>(), "testExpert")); }
public void SaveRelationsAsVergesOfSemanticNetwork_SessionExistAndNotRelationPhase_InvalidOperationException( SessionPhase currentPhase) { var serviceUnderTest = CreateServiceUnderTest(); SetFakeSession(currentPhase); Assert.Throws( Is.TypeOf <InvalidOperationException>() .And.Message.EqualTo(SessionIsNotInPhaseErrorMessage), () => serviceUnderTest.SaveRelationsAsVergesOfSemanticNetwork()); }
public void GetVerges_SessionExistsAndIsNotInRelationPhase_SaveErrorAndRedirectToCurrenSession( SessionPhase currentPhase) { var controllerUnderTest = CreateControllerUnderTest(); SetFakeCurrentSession(currentPhase); var result = (RedirectToRouteResult)controllerUnderTest.SaveVerges(); Assert.AreEqual(NotAvailableOnThisPhaseErrorMessage, controllerUnderTest.TempData[DataConstants.Error]); Assert.AreEqual("CurrentSession", result.RouteValues["action"]); }
public void Relation_SessionExistsAndIsNotInRelationPhase_SaveErrorAndRedirectToExpertTest( SessionPhase currentPhase) { var cut = CreateControllerUnderTest(); SetFakeCurrentSession(currentPhase); var result = (RedirectToRouteResult)cut.Relation(new RelationViewModel()); Assert.AreEqual(NotAvailableOnThisPhaseErrorMessage, cut.TempData[DataConstants.Error]); Assert.AreEqual("ExpertTest", result.RouteValues["action"]); }
public string GetScriptDir(string dommePersonalityName, string type, SessionPhase sessionPhase) { var baseDir = GetPersonalityFolder(dommePersonalityName) + Path.DirectorySeparatorChar; if (sessionPhase == SessionPhase.Modules) { baseDir += "Modules" + Path.DirectorySeparatorChar; } else { baseDir += type + Path.DirectorySeparatorChar + sessionPhase.ToString() + Path.DirectorySeparatorChar; } return(baseDir); }
public void trigger(float sessionRunningTime, SessionType sessionType, SessionPhase lastSessionPhase, int startPosition, int finishPosition, int numCars, int completedLaps, Boolean isDisqualified) { if (!enableSessionEndMessages) { Console.WriteLine("Session end, position = " + finishPosition + ", session end messages are disabled"); return; } if (sessionType == SessionType.Race) { if (sessionRunningTime > 60 || completedLaps > 0) { if (lastSessionPhase == SessionPhase.Finished) { // only play session end message for races if we've actually finished, not restarted playFinishMessage(sessionType, startPosition, finishPosition, numCars, isDisqualified); } else { Console.WriteLine("skipping race session end message because the previous phase wasn't Finished"); } } else { Console.WriteLine("skipping race session end message because it didn't run for a lap or a minute"); } } else if (sessionType == SessionType.Practice || sessionType == SessionType.Qualify) { if (sessionRunningTime > 60) { if (lastSessionPhase == SessionPhase.Green || lastSessionPhase == SessionPhase.FullCourseYellow || lastSessionPhase == SessionPhase.Finished || lastSessionPhase == SessionPhase.Checkered) { playFinishMessage(sessionType, startPosition, finishPosition, numCars, false); } else { Console.WriteLine("skipping non-race session end message because the previous phase wasn't green, finished, or checkered"); } } else { Console.WriteLine("skipping non-race session end message because the session didn't run for a minute"); } } }
private bool CheckSessionStarted(AssettoCorsaShared acData, SimulatorDataSet dataSet) { if (_rawLastSessionType != acData.AcsGraphic.session || _lastSessionType != dataSet.SessionInfo.SessionType) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = acData.AcsGraphic.session; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; Logger.Info("Session restart cause - Session Type Change"); return(true); } if (dataSet.SessionInfo.SessionPhase != _lastSessionPhase && _lastSessionPhase != SessionPhase.Green && dataSet.SessionInfo.SessionPhase != SessionPhase.Countdown) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = acData.AcsGraphic.session; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; Logger.Info("Session restart cause - Session Phase Change"); _assettoCorsaStartObserver.ResetStartState(); return(true); } if (_lastDataSet == null) { return(false); } if (_lastDataSet.PlayerInfo?.CompletedLaps > dataSet.PlayerInfo?.CompletedLaps) { Logger.Info("Session restart cause - Less Completed Laps than previously"); _assettoCorsaStartObserver.ResetStartState(); return(true); } if (_lastDataSet.SessionInfo.SessionType == SessionType.Race && _lastDataSet.SessionInfo.LeaderCurrentLap > dataSet.SessionInfo.LeaderCurrentLap) { Logger.Info("Session restart cause - Less Leader Completed Laps than previously"); _assettoCorsaStartObserver.ResetStartState(); return(true); } return(false); }
private bool CheckSessionStarted(Rf2FullData rfData, SimulatorDataSet dataSet) { if (_rawLastSessionType != rfData.scoring.mScoringInfo.mSession || _lastSessionType != dataSet.SessionInfo.SessionType) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = rfData.scoring.mScoringInfo.mSession; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } if (dataSet.SessionInfo.SessionPhase != _lastSessionPhase && _lastSessionPhase != SessionPhase.Green && dataSet.SessionInfo.SessionPhase != SessionPhase.Countdown) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = rfData.scoring.mScoringInfo.mSession; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } return(false); }
public async Task SetSessionPhase(Guid sessionId, Guid currentPhaseId, SessionPhase newPhase) { ISessionData sessionData = await GetSession(sessionId); SessionTableEntry session = sessionData as SessionTableEntry; if (session.PhaseId == currentPhaseId) { try { session.PhaseId = Guid.NewGuid(); session.RawPhaseType = (Int32)newPhase; // Increase the round number (if required) if (newPhase == SessionPhase.Victory) { session.RawRound += 1; } // Write entry back (fails on write conflict) TableOperation insertOperation = TableOperation.Replace(session); await SessionTable.ExecuteAsync(insertOperation); } catch (StorageException exception) { if (exception.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) { throw new ConcurrencyException(); } else { throw exception; } } } else { throw new ConcurrencyException(); } }
private bool CheckSessionStarted(AssettoCorsaShared acData, SimulatorDataSet dataSet) { if (_rawLastSessionType != acData.AcsGraphic.session || _lastSessionType != dataSet.SessionInfo.SessionType) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = acData.AcsGraphic.session; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } if (dataSet.SessionInfo.SessionPhase != _lastSessionPhase && _lastSessionPhase != SessionPhase.Green && dataSet.SessionInfo.SessionPhase != SessionPhase.Countdown) { _lastSessionType = dataSet.SessionInfo.SessionType; _rawLastSessionType = acData.AcsGraphic.session; _lastSessionPhase = dataSet.SessionInfo.SessionPhase; return(true); } if (_lastDataSet == null) { return(false); } if (_lastDataSet.PlayerInfo?.CompletedLaps > dataSet.PlayerInfo?.CompletedLaps) { return(true); } if (_lastDataSet.SessionInfo.SessionType == SessionType.Race && _lastDataSet.SessionInfo.LeaderCurrentLap > dataSet.SessionInfo.LeaderCurrentLap) { return(true); } return(false); }
private SessionPhase GetNextPhase(SessionPhase phase) { switch (phase) { case SessionPhase.BeforeSession: return(SessionPhase.Start); case SessionPhase.Start: return(SessionPhase.Modules); case SessionPhase.Modules: return(SessionPhase.Link); case SessionPhase.Link: return(SessionPhase.End); case SessionPhase.End: return(SessionPhase.AfterSession); default: return(SessionPhase.End); } }
public Boolean isApplicableForCurrentSessionAndPhase(SessionType sessionType, SessionPhase sessionPhase) { return applicableSessionPhases.Contains(sessionPhase) && applicableSessionTypes.Contains(sessionType); }
private bool IsEnding(SessionPhase phase) => phase > SessionPhase.SessionOver;
/** * Gets the current session phase. If the transition is valid this is returned, otherwise the * previous phase is returned */ private SessionPhase mapToSessionPhase(SessionPhase lastSessionPhase, SessionType currentSessionType, float lastSessionRunningTime, float thisSessionRunningTime, int r3eSessionPhase, ControlType controlType, int previousLapsCompleted, int currentLapsCompleted, Boolean isCarRunning) { /* prac and qual sessions go chequered after the allotted time. They never go 'finished'. If we complete a lap * during this period we can detect the session end and trigger the finish message. Otherwise we just can't detect * this period end - hence the 'isCarRunning' hack... */ if ((int)RaceRoomConstant.SessionPhase.Checkered == r3eSessionPhase) { if (lastSessionPhase == SessionPhase.Green) { // only allow a transition to checkered if the last state was green Console.WriteLine("checkered - completed " + currentLapsCompleted + " laps, session running time = " + thisSessionRunningTime); return SessionPhase.Checkered; } else if (SessionPhase.Checkered == lastSessionPhase) { if (previousLapsCompleted != currentLapsCompleted || controlType == ControlType.AI || ((currentSessionType == SessionType.Qualify || currentSessionType == SessionType.Practice) && !isCarRunning)) { Console.WriteLine("finished - completed " + currentLapsCompleted + " laps (was " + previousLapsCompleted + "), session running time = " + thisSessionRunningTime + " control type = " + controlType); return SessionPhase.Finished; } } } else if ((int)RaceRoomConstant.SessionPhase.Countdown == r3eSessionPhase) { // don't allow a transition to Countdown if the game time has increased if (lastSessionRunningTime < thisSessionRunningTime) { return SessionPhase.Countdown; } } else if ((int)RaceRoomConstant.SessionPhase.Formation == r3eSessionPhase) { return SessionPhase.Formation; } else if ((int)RaceRoomConstant.SessionPhase.Garage == r3eSessionPhase) { return SessionPhase.Garage; } else if ((int)RaceRoomConstant.SessionPhase.Green == r3eSessionPhase) { if (controlType == ControlType.AI && thisSessionRunningTime < 30) { return SessionPhase.Formation; } else { return SessionPhase.Green; } } else if ((int)RaceRoomConstant.SessionPhase.Gridwalk == r3eSessionPhase) { return SessionPhase.Gridwalk; } else if ((int)RaceRoomConstant.SessionPhase.Terminated == r3eSessionPhase) { return SessionPhase.Finished; } return lastSessionPhase; }
public void trigger(float sessionRunningTime, SessionType sessionType, SessionPhase lastSessionPhase, int finishPosition, int numCars, int completedLaps, Boolean isDisqualified) { if (!enableSessionEndMessages) { Console.WriteLine("Session end, position = " + finishPosition + ", session end messages are disabled"); return; } if (sessionType == SessionType.Race) { if (sessionRunningTime > 60 || completedLaps > 0) { if (lastSessionPhase == SessionPhase.Finished) { // only play session end message for races if we've actually finished, not restarted playFinishMessage(sessionType, finishPosition, numCars, isDisqualified); } else { Console.WriteLine("skipping race session end message because the previous phase wasn't Finished"); } } else { Console.WriteLine("skipping race session end message because it didn't run for a lap or a minute"); } } else if (sessionType == SessionType.Practice || sessionType == SessionType.Qualify) { if (sessionRunningTime > 60) { if (lastSessionPhase == SessionPhase.Green || lastSessionPhase == SessionPhase.Finished || lastSessionPhase == SessionPhase.Checkered) { playFinishMessage(sessionType, finishPosition, numCars, false); } else { Console.WriteLine("skipping non-race session end message because the previous phase wasn't green, finished, or checkered"); } } else { Console.WriteLine("skipping non-race session end message because the session didn't run for a minute"); } } }
// TODO: this has been hacked around so much as to have become entirely bollocks. Re-write it /* * When a practice session ends (while driving around) the mSessionState goes from 2 (racing) to * 1 (race not started) to 0 (invalid) over a few seconds. It never goes to any of the finished * states */ private SessionPhase mapToSessionPhase(SessionType sessionType, uint sessionState, uint raceState, int numParticipants, Boolean leaderHasFinishedRace, SessionPhase previousSessionPhase, float sessionTimeRemaining, float sessionRunTime) { if (numParticipants < 1) { return SessionPhase.Unavailable; } if (sessionType == SessionType.Race) { if (raceState == (uint)eRaceState.RACESTATE_NOT_STARTED) { if (sessionState == (uint)eSessionState.SESSION_FORMATIONLAP) { return SessionPhase.Formation; } else { return SessionPhase.Countdown; } } else if (raceState == (uint)eRaceState.RACESTATE_RACING) { if (leaderHasFinishedRace) { return SessionPhase.Checkered; } else { return SessionPhase.Green; } } else if (raceState == (uint)eRaceState.RACESTATE_FINISHED || raceState == (uint)eRaceState.RACESTATE_DNF || raceState == (uint)eRaceState.RACESTATE_DISQUALIFIED || raceState == (uint)eRaceState.RACESTATE_RETIRED || raceState == (uint)eRaceState.RACESTATE_INVALID || raceState == (uint)eRaceState.RACESTATE_MAX) { return SessionPhase.Finished; } } else if (sessionType == SessionType.Practice || sessionType == SessionType.Qualify) { // yeah yeah.... if (sessionRunTime > 0 && sessionTimeRemaining <= 1) { return SessionPhase.Finished; } else if (raceState == (uint)eRaceState.RACESTATE_RACING) { return SessionPhase.Green; } else if (raceState == (uint)eRaceState.RACESTATE_NOT_STARTED) { // for these sessions, we'll be in 'countdown' for all of the first lap :( return SessionPhase.Countdown; } } return SessionPhase.Unavailable; }