public MStepRes Handle(long playerId, MStepReq message)
        {
            var playerInputs = new List <PlayerInput>();

            foreach (var item in message.GameInput.Commands)
            {
                playerInputs.Add(new PlayerInput(item));
            }
            var input = new Msg_PlayerInput(message.GameInput.Tick, (byte)message.GameInput.ActorId, playerInputs);

#if DEBUG_SHOW_INPUT
            if (input.Commands != null && input.Commands?.Length > 0)
            {
                var cmd         = input.Commands[0];
                var playerInput = new Deserializer(cmd.content).Parse <Lockstep.Game.PlayerInput>();
                if (playerInput.inputUV != LVector2.zero)
                {
                    Debug.Log(
                        $"curTick{Tick} isOutdate{input.Tick < Tick} RecvInput actorID:{input.ActorId}  inputTick:{input.Tick}  move:{playerInput.inputUV}");
                }
            }
#endif
            var        gameId = GameClass.GetGameIdWithPlayerId(playerId);
            IGameClass game   = GameClass.GetGame(gameId);
            game.HandlePlayerInput(input);

            return(new MStepRes {
                ID = message.ID, MsgType = EResType.Pong
            });
        }
Beispiel #2
0
 private void SendInput(Msg_PlayerInput input)
 {
     //TODO 合批次 一起发送 且连同历史未确认包一起发送
     if (!_constStateService.IsClientMode)
     {
         _networkService.SendInput(input);
     }
 }
Beispiel #3
0
 public void SendInput(Msg_PlayerInput msg)
 {
     if (_noNetwork)
     {
         return;
     }
     _roomMsgMgr.SendInput(msg);
 }
        // Token: 0x060001D2 RID: 466 RVA: 0x000063B4 File Offset: 0x000045B4
        public void SendInput(Msg_PlayerInput msg)
        {
            bool noNetwork = this._noNetwork;

            if (!noNetwork)
            {
                this._roomMsgMgr.SendInput(msg);
            }
        }
Beispiel #5
0
        private void DoClientUpdate()
        {
            int maxRollbackCount = 5;

            if (_isDebugRollback && _world.Tick > maxRollbackCount && _world.Tick % maxRollbackCount == 0)
            {
                var rawTick     = _world.Tick;
                var revertCount = LRandom.Range(1, maxRollbackCount);
                for (int i = 0; i < revertCount; i++)
                {
                    var input = new Msg_PlayerInput(_world.Tick, LocalActorId, _inputService.GetDebugInputCmds());
                    var frame = new ServerFrame()
                    {
                        tick    = rawTick - i,
                        _inputs = new Msg_PlayerInput[] { input }
                    };
                    _cmdBuffer.ForcePushDebugFrame(frame);
                }
                _debugService.Trace("RollbackTo " + (_world.Tick - revertCount));
                if (!RollbackTo(_world.Tick - revertCount, _world.Tick))
                {
                    _commonStateService.IsPause = true;
                    return;
                }

                while (_world.Tick < rawTick)
                {
                    var sFrame = _cmdBuffer.GetServerFrame(_world.Tick);
                    Logging.Debug.Assert(sFrame != null && sFrame.tick == _world.Tick,
                                         $" logic error: server Frame  must exist tick {_world.Tick}");
                    _cmdBuffer.PushLocalFrame(sFrame);
                    Simulate(sFrame);
                    if (_commonStateService.IsPause)
                    {
                        return;
                    }
                }
            }

            while (_world.Tick < TargetTick)
            {
                FramePredictCount = 0;
                var input = new Msg_PlayerInput(_world.Tick, LocalActorId, _inputService.GetInputCmds());
                var frame = new ServerFrame()
                {
                    tick    = _world.Tick,
                    _inputs = new Msg_PlayerInput[] { input }
                };
                _cmdBuffer.PushLocalFrame(frame);
                _cmdBuffer.PushServerFrames(new ServerFrame[] { frame });
                Simulate(_cmdBuffer.GetFrame(_world.Tick));
                if (_commonStateService.IsPause)
                {
                    return;
                }
            }
        }
        public void SendInput(Msg_PlayerInput input)
        {
            _tick2SendTimestamp[input.Tick] = LTime.realtimeSinceStartupMS;
#if DEBUG_SHOW_INPUT
            var cmd         = input.Commands[0];
            var playerInput = new Deserializer(cmd.content).Parse <Lockstep.Game.PlayerInput>();
            if (playerInput.inputUV != LVector2.zero)
            {
                Debug.Log($"SendInput tick:{input.Tick} uv:{playerInput.inputUV}");
            }
#endif
            _networkService.SendInput(input);
        }
        private void FillInputWithLastFrame(ServerFrame frame)
        {
            int tick             = frame.tick;
            var inputs           = frame.Inputs;
            var lastServerInputs = tick == 0 ? null : _cmdBuffer.GetFrame(tick - 1)?.Inputs;
            var myInput          = inputs[LocalActorId];

            //fill inputs with last frame's input (Input predict)
            for (int i = 0; i < _actorCount; i++)
            {
                inputs[i] = new Msg_PlayerInput(tick, _allActors[i], lastServerInputs?[i]?.Commands);
            }

            inputs[LocalActorId] = myInput;
        }
Beispiel #8
0
        private void FillInputWithLastFrame(ServerFrame frame)
        {
            int tick            = frame.tick;
            var inputs          = frame.Inputs;
            var lastFrameInputs = tick == 0 ? null : cmdBuffer.GetFrame(tick - 1)?.Inputs;
            var curFrameInput   = inputs[_localActorId];

            //将所有角色 给予默认的输入
            for (int i = 0; i < _actorCount; i++)
            {
                inputs[i] = new Msg_PlayerInput(tick, _allActors[i], lastFrameInputs?[i]?.Commands?.ToList());
            }

            inputs[_localActorId] = curFrameInput;
        }
 private void DoClientUpdate()
 {
     while (_world.Tick < TargetTick)
     {
         FramePredictCount = 0;
         var input = new Msg_PlayerInput(_world.Tick, LocalActorId, _inputService.GetInputCmds());
         var frame = new ServerFrame()
         {
             tick    = _world.Tick,
             _inputs = new Msg_PlayerInput[] { input }
         };
         _cmdBuffer.PushLocalFrame(frame);
         _cmdBuffer.PushServerFrames(new ServerFrame[] { frame });
         Simulate(_cmdBuffer.GetFrame(_world.Tick));
     }
 }
        private void SendInputs(int curTick)
        {
            Msg_PlayerInput msg_PlayerInput = new Msg_PlayerInput(curTick, this.LocalActorId, this._inputService.GetInputCmds());
            ServerFrame     serverFrame     = new ServerFrame();

            Msg_PlayerInput[] array = new Msg_PlayerInput[this._actorCount];
            array[(int)this.LocalActorId] = msg_PlayerInput;
            serverFrame.Inputs            = array;
            serverFrame.Tick = curTick;
            this.FillInputWithLastFrame(serverFrame);
            this._cmdBuffer.PushLocalFrame(serverFrame);
            bool flag = curTick > this._cmdBuffer.MaxServerTickInBuffer;

            if (flag)
            {
                this._cmdBuffer.SendInput(msg_PlayerInput);
            }
        }
Beispiel #11
0
        public void HandlePlayerInput(Msg_PlayerInput input)
        {
            if (input.Tick < Tick)
            {
                return;
            }

            var frame = GetOrCreateFrame(input.Tick);

            var id = input.ActorId;

            if (!_allNeedWaitInputPlayerIds.Contains(id))
            {
                _allNeedWaitInputPlayerIds.Add(id);
            }

            frame.Inputs[id] = input;
            _CheckBorderServerFrame(false);
        }
Beispiel #12
0
        public void Add(int tick, Msg_PlayerInput msg)
        {
            if (!InputLog.ContainsKey(tick))
            {
                InputLog.Add(tick, new Dictionary <int, Dictionary <byte, List <InputCmd> > >());
            }

            if (!InputLog[tick].ContainsKey(msg.Tick))
            {
                InputLog[tick].Add(msg.Tick, new Dictionary <byte, List <InputCmd> >());
            }

            if (!InputLog[tick][msg.Tick].ContainsKey(msg.ActorId))
            {
                InputLog[tick][msg.Tick].Add(msg.ActorId, new List <InputCmd>());
            }

            if (msg.Commands != null)
            {
                InputLog[tick][msg.Tick][msg.ActorId].AddRange(msg.Commands);
            }
        }
        void SendInputs(int curTick)
        {
            var input  = new Msg_PlayerInput(curTick, LocalActorId, _inputService.GetInputCmds());
            var cFrame = new ServerFrame();
            var inputs = new Msg_PlayerInput[_actorCount];

            inputs[LocalActorId] = input;
            cFrame.Inputs        = inputs;
            cFrame.tick          = curTick;
            FillInputWithLastFrame(cFrame);
            _cmdBuffer.PushLocalFrame(cFrame);
            //if (input.Commands != null) {
            //    var playerInput = new Deserializer(input.Commands[0].content).Parse<Lockstep.Game.PlayerInput>();
            //    Debug.Log($"SendInput curTick{curTick} maxSvrTick{_cmdBuffer.MaxServerTickInBuffer} _tickSinceGameStart {_tickSinceGameStart} uv {playerInput.inputUV}");
            //}
            if (curTick > _cmdBuffer.MaxServerTickInBuffer)
            {
                //TODO combine all history inputs into one Msg
                //Debug.Log("SendInput " + curTick +" _tickSinceGameStart " + _tickSinceGameStart);
                _cmdBuffer.SendInput(input);
            }
        }
        private void FillInputWithLastFrame(ServerFrame frame)
        {
            int tick = frame.Tick;

            Msg_PlayerInput[] inputs = frame.Inputs;
            Msg_PlayerInput[] array;
            if (tick != 0)
            {
                ServerFrame frame2 = this._cmdBuffer.GetFrame(tick - 1);
                array = ((frame2 != null) ? frame2.Inputs : null);
            }
            else
            {
                array = null;
            }
            Msg_PlayerInput[] array2          = array;
            Msg_PlayerInput   msg_PlayerInput = inputs[(int)this.LocalActorId];

            for (int i = 0; i < this._actorCount; i++)
            {
                Msg_PlayerInput[] array3 = inputs;
                int        num           = i;
                int        tick2         = tick;
                byte       actorID       = this._allActors[i];
                InputCmd[] inputs2;
                if (array2 == null)
                {
                    inputs2 = null;
                }
                else
                {
                    Msg_PlayerInput msg_PlayerInput2 = array2[i];
                    inputs2 = ((msg_PlayerInput2 != null) ? msg_PlayerInput2.Commands : null);
                }
                array3[num] = new Msg_PlayerInput(tick2, actorID, inputs2);
            }
            inputs[(int)this.LocalActorId] = msg_PlayerInput;
        }
 public void SendInput(Msg_PlayerInput msg)
 {
     SendMsgRoom(EMsgCS.C2S_PlayerInput, msg);
 }
Beispiel #16
0
        private void BorderServerFrame(int deltaTime)
        {
            waitTimer += deltaTime;
            if (State != EGameState.Playing)
            {
                return;
            }
            while (true)   // 如果落后太多 就一直追帧
            {
                var iTick = (int)Tick;
                if (allHistoryFrames.Count <= iTick)
                {
                    return;
                }

                var frame = allHistoryFrames[iTick];
                if (frame == null)
                {
                    return;
                }

                var inputs = frame.Inputs;
                //超时等待 移除超时玩家
                if (waitTimer > NetworkDefine.MAX_DELAY_TIME_MS)
                {
                    waitTimer = 0;
                    //移除还没有到来的帧的Player
                    for (int i = 0; i < inputs.Length; i++)
                    {
                        if (inputs[i] == null)
                        {
                            if (Players[i] != null)
                            {
                                //Log($"Overtime wait remove localId = {i}");
                            }

                            allNeedWaitInputPlayerIds.Remove((byte)i);
                        }
                    }
                }

                //是否所有的输入  都已经等到
                foreach (var id in allNeedWaitInputPlayerIds)
                {
                    if (inputs[id] == null)
                    {
                        return;
                    }
                }

                //将所有未到的包 给予默认的输入
                for (int i = 0; i < inputs.Length; i++)
                {
                    if (inputs[i] == null)
                    {
                        inputs[i] = new Msg_PlayerInput(Tick, (byte)i, null);
                    }
                }

                //Debug.Log("Border input " + Tick);
                var msg    = new Msg_ServerFrames();
                int count  = Tick < 2 ? iTick + 1 : 3;
                var frames = new ServerFrame[count];
                for (int i = 0; i < count; i++)
                {
                    frames[count - i - 1] = allHistoryFrames[iTick - i];
                }

                msg.startTick = frames[0].tick;
                msg.frames    = frames;
                BorderUdp(EMsgSC.G2C_FrameData, msg);
                if (firstFrameTimeStamp <= 0)
                {
                    firstFrameTimeStamp = timeSinceLoaded;
                }

                Tick++;
            }
        }
Beispiel #17
0
        private void Step()
        {
            if (_constStateService.IsClientMode)
            {
                var input = new Msg_PlayerInput(_world.Tick, _localActorId, _inputService.GetInputCmds());
                var frame = new ServerFrame()
                {
                    tick    = _world.Tick,
                    _inputs = new Msg_PlayerInput[] { input }
                };
                _cmdBuffer.PushLocalFrame(frame);
                _cmdBuffer.PushServerFrames(new ServerFrame[] { frame });
                _cmdBuffer.UpdateFramesInfo();
                Simulate(_cmdBuffer.GetFrame(_world.Tick));
                return;
            }

            //cmdBuffer.Ping = _gameMsgService.Ping;
            _cmdBuffer.UpdateFramesInfo();
            var missFrameTick = _cmdBuffer.GetMissServerFrameTick();

            //客户端落后服务器太多帧 请求丢失帧
            if (_cmdBuffer.IsNeedReqMissFrame())
            {
                _networkService.SendMissFrameReq(missFrameTick);
            }

            //if (!cmdBuffer.CanExecuteNextFrame()) { //因为网络问题 需要等待服务器发送确认包 才能继续往前
            //    return;
            //}
            _frameDeadline = LTime.realtimeSinceStartup + MaxSimulationMsPerFrame;

            var minTickToBackup = missFrameTick - FrameBuffer.SnapshotFrameInterval;
            //追帧 无输入
            var isPursueServer = !PursueServer(minTickToBackup);

            if (isPursueServer)
            {
                _constStateService.IsPursueFrame = true;
                Debug.Log($"PurchaseServering curTick:" + _world.Tick);
                EventHelper.Trigger(EEvent.PursueFrameProcess, GetPursueProgress());
                return;
            }

            if (_constStateService.IsPursueFrame)
            {
                EventHelper.Trigger(EEvent.PursueFrameDone);
            }

            _constStateService.IsPursueFrame = false;

            var frameDeltaTime = (LTime.realtimeSinceStartup - _timestampOnPurcue) * 1000;
            var targetTick     = (float)System.Math.Ceiling(frameDeltaTime / NetworkDefine.UPDATE_DELTATIME) +
                                 _tickOnPursue;

            //正常跑帧
            while (_world.Tick < targetTick)
            {
                var curTick = _world.Tick;
                _cmdBuffer.UpdateFramesInfo();
                //校验服务器包  如果有预测失败 则需要进行回滚
                if (_cmdBuffer.IsNeedRollback)
                {
                    _world.RollbackTo(_cmdBuffer.nextTickToCheck, missFrameTick);
                    _world.CleanUselessSnapshot(System.Math.Min(_cmdBuffer.nextTickToCheck - 1, _world.Tick));

                    minTickToBackup = System.Math.Max(minTickToBackup, _world.Tick + 1);
                    while (_world.Tick < missFrameTick)
                    {
                        var sFrame = _cmdBuffer.GetServerFrame(_world.Tick);
                        Logging.Debug.Assert(sFrame != null && sFrame.tick == _world.Tick,
                                             $" logic error: server Frame  must exist tick {_world.Tick}");
                        //服务器超前 客户端 应该追上去 将服务器中的输入作为客户端输入
                        _cmdBuffer.PushLocalFrame(sFrame);
                        Simulate(sFrame, _world.Tick >= minTickToBackup);
                    }

                    while (_world.Tick < curTick)
                    {
                        var frame = _cmdBuffer.GetLocalFrame(_world.Tick);
                        FillInputWithLastFrame(frame); //加上输入预判 减少回滚
                        Logging.Debug.Assert(frame != null && frame.tick == _world.Tick,
                                             $" logic error: local frame must exist tick {_world.Tick}");
                        Predict(frame, _world.Tick > minTickToBackup);
                    }
                }

                {
                    if (_world.Tick == curTick)   //当前帧 没有被执行 需要执行之
                    {
                        ServerFrame cFrame = null;
                        var         sFrame = _cmdBuffer.GetServerFrame(_world.Tick);
                        if (sFrame != null)
                        {
                            cFrame = sFrame;
                        }
                        else
                        {
                            var input = new Msg_PlayerInput(curTick, _localActorId, _inputService.GetInputCmds());
                            cFrame = new ServerFrame();
                            var inputs = new Msg_PlayerInput[_actorCount];
                            inputs[_localActorId] = input;
                            cFrame.Inputs         = inputs;
                            cFrame.tick           = curTick;
                            FillInputWithLastFrame(cFrame);
                            if (curTick > _cmdBuffer.maxServerTickInBuffer)   //服务器的输入还没到 需要同步输入到服务器
                            {
                                SendInput(input);
                            }
                        }

                        _cmdBuffer.PushLocalFrame(cFrame);
                        Predict(cFrame);
                    }
                }
            } //end of while(_world.Tick < targetTick)

            CheckAndSendHashCodes();
        }
 public void SendInput(Msg_PlayerInput msg)
 {
     // SendMsgRoom(EMsgSC.C2S_PlayerInput, msg);
 }
Beispiel #19
0
        private bool _CheckBorderServerFrame(bool isForce = false)
        {
            if (State != EGameState.Playing)
            {
                return(false);
            }
            var frame  = GetOrCreateFrame(Tick);
            var inputs = frame.Inputs;

            if (!isForce)
            {
                //是否所有的输入  都已经等到
                for (int i = 0; i < inputs.Length; i++)
                {
                    if (inputs[i] == null)
                    {
                        return(false);
                    }
                }
            }

            //将所有未到的包 给予默认的输入
            for (int i = 0; i < inputs.Length; i++)
            {
                if (inputs[i] == null)
                {
                    inputs[i] = new Msg_PlayerInput(Tick, (byte)i)
                    {
                        IsMiss = true
                    };
                }
            }

            //Debug.Log($" Border input {Tick} isUpdate:{isForce} _tickSinceGameStart:{_tickSinceGameStart}");
            var msg    = new MultiFrames();
            int count  = Tick < 2 ? Tick + 1 : 3;
            var frames = new ServerFrame[count];

            for (int i = 0; i < count; i++)
            {
                frames[count - i - 1] = _allHistoryFrames[Tick - i];
            }

            msg.StartTick = frames[0].tick;
            msg.frames    = frames;
            // FIXME: set response, message should with ServerFrames or PlayerGameInputs
            borderMessageO.Notify(new BorderMessageModel()
            {
                GameId = this.GameId, Message = new MStepRes()
                {
                    MsgType = EResType.StepResponse, Frames = msg.TransformToMMultiFrames()
                }
            });
            if (_firstFrameTimeStamp <= 0)
            {
                _firstFrameTimeStamp = _timeSinceLoaded;
            }

            if (_gameStartTimestampMs < 0)
            {
                _gameStartTimestampMs =
                    LTime.realtimeSinceStartupMS + _configuration.GetValue <int>("frame_interval", 100) * _ServerTickDealy;
            }

            Tick++;
            return(true);
        }
        private void DoClientUpdate()
        {
            int  num  = 5;
            bool flag = this._isDebugRollback && this._world.Tick > num && this._world.Tick % num == 0;

            if (flag)
            {
                int tick = this._world.Tick;
                int num2 = LRandom.Range(1, num);
                for (int i = 0; i < num2; i++)
                {
                    Msg_PlayerInput msg_PlayerInput = new Msg_PlayerInput(this._world.Tick, this.LocalActorId, this._inputService.GetDebugInputCmds());
                    ServerFrame     frame           = new ServerFrame
                    {
                        Tick    = tick - i,
                        _Inputs = new Msg_PlayerInput[]
                        {
                            msg_PlayerInput
                        }
                    };
                    this._cmdBuffer.ForcePushDebugFrame(frame);
                }
                this._debugService.Trace("RollbackTo " + (this._world.Tick - num2), false, false);
                bool flag2 = !this.RollbackTo(this._world.Tick - num2, this._world.Tick, true);
                if (flag2)
                {
                    this._globalStateService.IsPause = true;
                    return;
                }
                while (this._world.Tick < tick)
                {
                    ServerFrame serverFrame = this._cmdBuffer.GetServerFrame(this._world.Tick);
                    Debug.Assert(serverFrame != null && serverFrame.Tick == this._world.Tick, string.Format(" logic error: server Frame  must exist tick {0}", this._world.Tick));
                    this._cmdBuffer.PushLocalFrame(serverFrame);
                    this.Simulate(serverFrame, true);
                    bool isPause = this._globalStateService.IsPause;
                    if (isPause)
                    {
                        return;
                    }
                }
            }
            while (this._world.Tick < this.TargetTick)
            {
                this.FramePredictCount = 0;
                Msg_PlayerInput msg_PlayerInput2 = new Msg_PlayerInput(this._world.Tick, this.LocalActorId, this._inputService.GetInputCmds());
                ServerFrame     serverFrame2     = new ServerFrame
                {
                    Tick    = this._world.Tick,
                    _Inputs = new Msg_PlayerInput[]
                    {
                        msg_PlayerInput2
                    }
                };
                this._cmdBuffer.PushLocalFrame(serverFrame2);
                this._cmdBuffer.PushServerFrames(new ServerFrame[]
                {
                    serverFrame2
                }, true);
                this.Simulate(this._cmdBuffer.GetFrame(this._world.Tick), true);
                bool isPause2 = this._globalStateService.IsPause;
                if (isPause2)
                {
                    break;
                }
            }
        }
Beispiel #21
0
 public void SendInput(Msg_PlayerInput msg)
 {
     SendUdp(EMsgSC.C2G_PlayerInput, msg);
 }
Beispiel #22
0
 private void SendInput(Msg_PlayerInput input)
 {
     //TODO 合批次 一起发送 且连同历史未确认包一起发送
     _networkService.SendInput(input);
 }
Beispiel #23
0
        public override void DoUpdate(float deltaTime)
        {
            if (!Running)
            {
                return;
            }

            if (_constStateService.IsVideoMode)
            {
                return;
            }

            cmdBuffer.Ping = _networkService.Ping;
            cmdBuffer.UpdateFramesInfo();
            var missFrameTick = cmdBuffer.GetMissServerFrameTick();

            //客户端落后服务器太多帧 请求丢失帧
            if (cmdBuffer.IsNeedReqMissFrame())
            {
                _networkService.SendMissFrameReq(missFrameTick);
            }

            //if (!cmdBuffer.CanExecuteNextFrame()) { //因为网络问题 需要等待服务器发送确认包 才能继续往前
            //    return;
            //}
            _frameDeadline = Time.realtimeSinceStartup + MaxSimulationMsPerFrame;

            var minTickToBackup = missFrameTick - FrameBuffer.SnapshotFrameInterval;

            //追帧 无输入
            _constStateService.isPursueFrame = true;
            if (!PursueServer(minTickToBackup))
            {
                _constStateService.isPursueFrame = false;
                Debug.Log($"PurchaseServering curTick:" + _world.Tick);
                return;
            }

            _constStateService.isPursueFrame = false;

            var frameDeltaTime = (Time.realtimeSinceStartup - timestampOnPurcue) * 1000;
            var targetTick     = Mathf.CeilToInt(frameDeltaTime / NetworkDefine.UPDATE_DELTATIME) + tickOnPursue;

            //正常跑帧
            while (_world.Tick < targetTick)
            {
                var curTick = _world.Tick;
                cmdBuffer.UpdateFramesInfo();
                //校验服务器包  如果有预测失败 则需要进行回滚
                if (cmdBuffer.IsNeedRevert)
                {
                    _world.RollbackTo(cmdBuffer.nextTickToCheck, missFrameTick);
                    _world.CleanUselessSnapshot(System.Math.Min(cmdBuffer.nextTickToCheck - 1, _world.Tick));

                    minTickToBackup = System.Math.Max(minTickToBackup, _world.Tick + 1);
                    while (_world.Tick < missFrameTick)
                    {
                        var sFrame = cmdBuffer.GetServerFrame(_world.Tick);
                        Logging.Debug.Assert(sFrame != null && sFrame.tick == _world.Tick,
                                             $" logic error: server Frame  must exist tick {_world.Tick}");
                        //服务器超前 客户端 应该追上去 将服务器中的输入作为客户端输入
                        cmdBuffer.PushLocalFrame(sFrame);
                        Simulate(sFrame, _world.Tick >= minTickToBackup);
                    }

                    while (_world.Tick < curTick)
                    {
                        var frame = cmdBuffer.GetLocalFrame(_world.Tick);
                        FillInputWithLastFrame(frame); //加上输入预判 减少回滚
                        Logging.Debug.Assert(frame != null && frame.tick == _world.Tick,
                                             $" logic error: local frame must exist tick {_world.Tick}");
                        Predict(frame, _world.Tick > minTickToBackup);
                    }
                }

                {
                    if (_world.Tick == curTick)   //当前帧 没有被执行 需要执行之
                    {
                        ServerFrame cFrame = null;
                        var         sFrame = cmdBuffer.GetServerFrame(_world.Tick);
                        if (sFrame != null)
                        {
                            cFrame = sFrame;
                        }
                        else
                        {
                            var input = new Msg_PlayerInput(curTick, _localActorId, _inputService.GetInputCmds());
                            cFrame = new ServerFrame();
                            var inputs = new Msg_PlayerInput[_actorCount];
                            inputs[_localActorId] = input;
                            cFrame.Inputs         = inputs;
                            cFrame.tick           = curTick;
                            FillInputWithLastFrame(cFrame);
#if DEBUG_FRAME_DELAY
                            input.timeSinceStartUp = Time.realtimeSinceStartup;
#endif
                            if (curTick > cmdBuffer.maxServerTickInBuffer)   //服务器的输入还没到 需要同步输入到服务器
                            {
                                SendInput(input);
                            }
                        }

                        cmdBuffer.PushLocalFrame(cFrame);
                        Predict(cFrame);
                    }
                }
            } //end of while(_world.Tick < targetTick)

            CheckAndSendHashCodes();
        }
Beispiel #24
0
 public void SendInput(Msg_PlayerInput input)
 {
     this._tick2SendTimestamp[input.Tick] = LTime.realtimeSinceStartupMS;
     this._networkService.SendInput(input);
 }