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 }); }
private void SendInput(Msg_PlayerInput input) { //TODO 合批次 一起发送 且连同历史未确认包一起发送 if (!_constStateService.IsClientMode) { _networkService.SendInput(input); } }
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); } }
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; }
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); } }
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); }
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); }
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++; } }
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); }
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; } } }
public void SendInput(Msg_PlayerInput msg) { SendUdp(EMsgSC.C2G_PlayerInput, msg); }
private void SendInput(Msg_PlayerInput input) { //TODO 合批次 一起发送 且连同历史未确认包一起发送 _networkService.SendInput(input); }
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(); }
public void SendInput(Msg_PlayerInput input) { this._tick2SendTimestamp[input.Tick] = LTime.realtimeSinceStartupMS; this._networkService.SendInput(input); }