Beispiel #1
0
        /// <summary>
        ///     This method is called every tick and checks if the waitTargetTime has already been reached.
        /// </summary>
        public static void ChangePauseStateIfNeeded()
        {
            if (_state == SpeedPauseState.WaitingForPause && GetCurrentTime() > _waitTargetTime)
            {
                SimulationManager.instance.SimulationPaused = true;
                _state = SpeedPauseState.PausedWaiting;
                SendReached();

                // Clear queued drop frames because we decided on an exact pause time, so the games are already in sync
                SlowdownHelper.ClearDropFrames();
            }
            else if (_state == SpeedPauseState.WaitingForSpeedChange && GetCurrentTime() > _waitTargetTime)
            {
                SimulationManager.instance.SelectedSimulationSpeed = _speed;
                _state = SpeedPauseState.PlayingWaiting;
                SendReached();

                // Don't clear dropped frames here because the game still continues.
                // Even if the current amount is not correct anymore because the dropped frames were
                // recorded while using a different speed, it's still an acceptable approximation.
            }
            else if (_state == SpeedPauseState.WaitingForPlay && DateTime.Now >= _waitTargetTime)
            {
                SimulationManager.instance.SimulationPaused        = false;
                SimulationManager.instance.SelectedSimulationSpeed = _speed;
                _state = SpeedPauseState.Playing;

                // Clear queued drop frames because those that arrived during paused state can be ignored
                SlowdownHelper.ClearDropFrames();
            }
        }
Beispiel #2
0
 /// <summary>
 ///     Called when a SpeedPauseRequest command was received.
 /// </summary>
 /// <param name="pause"></param>
 /// <param name="speed"></param>
 /// <param name="requestId"></param>
 public static void PlayPauseRequest(bool pause, int speed, int requestId)
 {
     if (requestId == -1) // Play requested
     {
         if (!pause &&
             (_state == SpeedPauseState.Paused ||
              _state == SpeedPauseState.WaitingForPlay))
         {
             Play(speed);
             _logger.Debug($"[SpeedPauseHelper] State {SpeedPauseState.Playing} requested remotely.");
         }
     }
     else if (pause) // Pause requested
     {
         SendSpeedPauseResponse(requestId);
         if (_state == SpeedPauseState.Playing)
         {
             _state = SpeedPauseState.PauseRequested;
             _logger.Debug($"[SpeedPauseHelper] State {SpeedPauseState.Paused} requested remotely.");
         }
     }
     else // Speed change requested
     {
         SendSpeedPauseResponse(requestId);
         if (_state == SpeedPauseState.Playing)
         {
             _state = SpeedPauseState.SpeedChangeRequested;
             _speed = speed;
             _logger.Debug("[SpeedPauseHelper] Speed change requested remotely.");
         }
     }
 }
Beispiel #3
0
        /// <summary>
        ///     Called when all responses to a pause or speed change request have been received.
        /// </summary>
        /// <param name="highestGameTime">The highest game time of all responses.</param>
        /// <param name="highestLatency">The highest latency of all responses.</param>
        public static void SpeedPauseResponseReceived(long highestGameTime, long highestLatency)
        {
            // Pause time is computed by taking the highest game time plus 4 times the maximum latency because this
            // is the worst case roundtrip time from client1 -> server -> client2 -> server -> client1 which means
            // that this amount of time may have already passed since the highest game time was determined.
            DateTime pauseTime = new DateTime(highestGameTime) + MillisecondsToInGameTime(highestLatency * 4);

            if (_state == SpeedPauseState.PauseRequested)
            {
                _state          = SpeedPauseState.WaitingForPause;
                _waitTargetTime = pauseTime;
            }
            else if (_state == SpeedPauseState.SpeedChangeRequested)
            {
                _state          = SpeedPauseState.WaitingForSpeedChange;
                _waitTargetTime = pauseTime;
            }
            else if (_state == SpeedPauseState.PlayRequested)
            {
                _state = SpeedPauseState.WaitingForPlay;

                // TODO: Maybe find a way to start the games simultaneously
                _waitTargetTime = DateTime.Now;
            }
        }
Beispiel #4
0
 /// <summary>
 ///     Called when a SpeedPauseRequest command was received.
 /// </summary>
 /// <param name="pause"></param>
 /// <param name="speed"></param>
 /// <param name="requestId"></param>
 public static void PlayPauseRequest(bool pause, int speed, int requestId)
 {
     if (pause) // Pause requested
     {
         if (_state == SpeedPauseState.Playing)
         {
             _state = SpeedPauseState.PauseRequested;
             Log.Debug($"[SpeedPauseHelper] State {SpeedPauseState.Paused} requested remotely.");
         }
         SendSpeedPauseResponse(requestId);
     }
     else // Speed change or play requested
     {
         if (_state == SpeedPauseState.Playing)
         {
             _state = SpeedPauseState.SpeedChangeRequested;
             _speed = speed;
             Log.Debug("[SpeedPauseHelper] Speed change requested remotely.");
         }
         else if (_state == SpeedPauseState.Paused)
         {
             _state = SpeedPauseState.PlayRequested;
             _speed = speed;
             Log.Debug($"[SpeedPauseHelper] State {SpeedPauseState.Playing} requested remotely.");
         }
         SendSpeedPauseResponse(requestId);
     }
 }
Beispiel #5
0
        /// <summary>
        ///     Schedule state to change to Playing after the minimal network latency time has passed.
        ///     Sets state to WaitingForPlay.
        ///     Sends a SpeedPauseRequest.
        /// </summary>
        /// <param name="speed">The speed to start with.</param>
        private static void WaitForPlay(int speed)
        {
            _state          = SpeedPauseState.WaitingForPlay;
            _speed          = speed;
            _waitTargetTime = DateTime.Now.AddMilliseconds(GetMinimumLatency());

            Command.SendToAll(new SpeedPauseRequestCommand()
            {
                RequestId               = -1,
                SimulationPaused        = false,
                SelectedSimulationSpeed = speed
            });
        }
Beispiel #6
0
        /// <summary>
        ///     Called when all SpeedPauseReached commands to a request have been received.
        ///     This will allow the player to press the buttons again.
        /// </summary>
        public static void StateReached()
        {
            if (_state == SpeedPauseState.PlayingWaiting)
            {
                _state = SpeedPauseState.Playing;
            }
            else if (_state == SpeedPauseState.PausedWaiting)
            {
                _state = SpeedPauseState.Paused;
            }

            _logger.Debug($"[SpeedPauseHelper] State {_state} reached!");
        }
Beispiel #7
0
        /// <summary>
        ///     Request the pause state.
        ///     Sets state to PauseRequested.
        ///     Sends a SpeedPauseRequest and -Response with a randomly generated request id.
        /// </summary>
        private static void RequestPause()
        {
            _state = SpeedPauseState.PauseRequested;

            InitRand();

            int requestId = _rand.Next();

            Command.SendToAll(new SpeedPauseRequestCommand()
            {
                RequestId        = requestId,
                SimulationPaused = true
            });
            SendSpeedPauseResponse(requestId);
        }
Beispiel #8
0
        /// <summary>
        ///     Request a speed change (while playing).
        ///     Sets state to SpeedChangeRequested.
        ///     Sends a SpeedPauseRequest and -Response with a randomly generated request id.
        /// </summary>
        /// <param name="speed">The target speed to request.</param>
        private static void RequestSpeedChange(int speed)
        {
            _state = SpeedPauseState.SpeedChangeRequested;

            InitRand();

            int requestId = _rand.Next();

            Command.SendToAll(new SpeedPauseRequestCommand()
            {
                RequestId               = requestId,
                SimulationPaused        = false,
                SelectedSimulationSpeed = speed
            });

            _speed = speed;
            SendSpeedPauseResponse(requestId);
        }
Beispiel #9
0
        /// <summary>
        ///     Called when all SpeedPauseReached commands to a request have been received.
        ///     This will allow the player to press the buttons again.
        /// </summary>
        public static void StateReached()
        {
            if (_state == SpeedPauseState.PlayingWaiting)
            {
                _state = SpeedPauseState.Playing;
            }
            else if (_state == SpeedPauseState.PausedWaiting)
            {
                _state = SpeedPauseState.Paused;

                // If a connection request is pending, we complete it here, since now all games are paused.
                if (ConnectionRequestHandler.WorldLoadingPlayer != null)
                {
                    ConnectionRequestHandler.AllGamesBlocked();
                }
            }

            Log.Debug($"[SpeedPauseHelper] State {_state} reached!");
        }
Beispiel #10
0
 /// <summary>
 ///     Initialize current speed and pause states.
 /// </summary>
 /// <param name="paused">If the game is currently paused.</param>
 /// <param name="speed">Current game speed from 0 to 3.</param>
 public static void Initialize(bool paused, int speed)
 {
     _state = paused ? SpeedPauseState.Paused : SpeedPauseState.Playing;
     _speed = speed;
 }
Beispiel #11
0
 /// <summary>
 ///     Start playing with given speed now.
 ///     Sets state to WaitingForPlay with a target time of now.
 /// </summary>
 /// <param name="speed">The speed to start with.</param>
 private static void Play(int speed)
 {
     _state          = SpeedPauseState.WaitingForPlay;
     _speed          = speed;
     _waitTargetTime = DateTime.Now;
 }