예제 #1
0
        /// <summary>
        ///     Inserts an Input Command into the simulation.
        /// </summary>
        /// <param name="session">Player session that raised the command. On client, this is always the LocalPlayer session.</param>
        /// <param name="function">Function that is being changed.</param>
        /// <param name="message">Arguments for this event.</param>
        /// <param name="replay">if true, current cmd state will not be checked or updated - use this for "replaying" an
        /// old input that was saved or buffered until further processing could be done</param>
        public bool HandleInputCommand(ICommonSession session, BoundKeyFunction function, FullInputCmdMessage message, bool replay = false)
        {
            #if DEBUG
            var funcId = _inputManager.NetworkBindMap.KeyFunctionID(function);
            DebugTools.Assert(funcId == message.InputFunctionId, "Function ID in message does not match function.");
            #endif

            if (!replay)
            {
                // set state, state change is updated regardless if it is locally bound
                if (_cmdStates.GetState(function) == message.State)
                {
                    return(false);
                }
                _cmdStates.SetState(function, message.State);
            }

            // handle local binds before sending off
            foreach (var handler in BindRegistry.GetHandlers(function))
            {
                // local handlers can block sending over the network.
                if (handler.HandleCmdMessage(session, message))
                {
                    return(true);
                }
            }

            // send it off to the server
            DispatchInputCommand(message);
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Handle a predicted input command.
        /// </summary>
        /// <param name="inputCmd">Input command to handle as predicted.</param>
        public void PredictInputCommand(FullInputCmdMessage inputCmd)
        {
            DebugTools.AssertNotNull(_playerManager.LocalPlayer);

            var keyFunc = _inputManager.NetworkBindMap.KeyFunctionName(inputCmd.InputFunctionId);

            Predicted = true;
            var session = _playerManager.LocalPlayer !.Session;

            foreach (var handler in BindRegistry.GetHandlers(keyFunc))
            {
                if (handler.HandleCmdMessage(session, inputCmd))
                {
                    break;
                }
            }
            Predicted = false;
        }
예제 #3
0
        private void InputMessageHandler(InputCmdMessage message, EntitySessionEventArgs eventArgs)
        {
            if (!(message is FullInputCmdMessage msg))
            {
                return;
            }

            //Client Sanitization: out of bounds functionID
            if (!_playerManager.KeyMap.TryGetKeyFunction(msg.InputFunctionId, out var function))
            {
                return;
            }

            //Client Sanitization: bad enum key state value
            if (!Enum.IsDefined(typeof(BoundKeyState), msg.State))
            {
                return;
            }

            var session = (IPlayerSession)eventArgs.SenderSession;

            if (_lastProcessedInputCmd[session] < msg.InputSequence)
            {
                _lastProcessedInputCmd[session] = msg.InputSequence;
            }

            // set state, only bound key functions get state changes
            var states = GetInputStates(session);

            states.SetState(function, msg.State);

            // route the cmdMessage to the proper bind
            //Client Sanitization: unbound command, just ignore
            foreach (var handler in BindRegistry.GetHandlers(function))
            {
                if (handler.HandleCmdMessage(session, msg))
                {
                    return;
                }
            }
        }