private static void SendCommandPacket() { var message = new BitStream(); UserCommand?command, lastCommand = null; // last received server message message.WriteUInt32(_lastServerMessage); // last received reliable message message.WriteUInt32(_lastReliableMessage); // current server state ID message.WriteInt32(_svStateID); // reliable messages for (int i = _reliableAcknowledged + 1; i <= _reliableSequence; i++) { // header byte message.WriteByte(2); // command number message.WriteInt32(i); // command message.WriteString(_reliableCommands[i & (_reliableCommands.Length - 1)]); } // header byte message.WriteByte(UserCommand.CommandType); // command count message.WriteByte((byte)ClientInput.NumCommands); while ((command = ClientInput.GetCommand()) != null) { // write a command command.Value.Serialize(message, lastCommand); // set the new command as base lastCommand = command; } // end of command message.WriteByte(0xFF); // now send the command to the server _serverChannel.SendMessage(message); _commandSequence++; }
public override void Handle() { if (Key == Keys.F11 && Down) { ConsoleRenderer.Active = !ConsoleRenderer.Active; return; } if (ConsoleRenderer.Active && Down) { ConsoleRenderer.HandleKey(Key); return; } //DebugCamera.HandleKey(Key, Down); ClientInput.HandleKey(Key, Down); }
public static void Process() { // update server time _clientTime += Game.FrameMsec; if (State != ClientState.Idle) { // create user command ClientInput.CreateCommand(); // check for timeout CheckForTimeout(); // check if a packet needs sending CheckCommandPacket(); CheckConnectPacket(); if (State == ClientState.Ingame) { // set the rendering snapshot SetRenderSnapshot(); // predict the local player's state PredictPlayer(); // set the camera position if (_snap != null) { if (_snap.LocalPlayer != null) { //var rotZ = MathHelper.ToRadians(_snap.LocalPlayer.Rotation.Z); Camera.MainCamera.Position = new Vector3(_snap.LocalPlayer.Position.X, _snap.LocalPlayer.Position.Y, 10f + MathHelper.Max(_snap.LocalPlayer.Position.Z, 0f)); //Camera.MainCamera.Position += (new Vector3((float)Math.Sin(-rotZ), (float)Math.Cos(-rotZ), 0f) * -5f); //Camera.MainCamera.ViewMatrix = Matrix.CreateLookAt(Camera.MainCamera.Position, new Vector3(_snap.LocalPlayer.Position.X, _snap.LocalPlayer.Position.Y, _snap.LocalPlayer.Position.Z), new Vector3(0f, 0f, 1f)); } } } } }
private static void PredictPlayer() { if (_snap == null || _snap.LocalPlayer == null) { return; } PlayerEntity originalPlayer = (PlayerEntity)_snap.LocalPlayer.Clone(); var predictSnap = _curSnap; if (predictSnap == null || predictSnap.LocalPlayer == null) { predictSnap = _lastSnap; if (predictSnap == null || predictSnap.LocalPlayer == null) { return; } } _snap.LocalPlayer = (PlayerEntity)predictSnap.LocalPlayer.Clone(); int currentCommand = ClientInput.CommandID; for (int commandNum = (currentCommand - 63); commandNum < currentCommand; commandNum++) { UserCommand?command = ClientInput.GetCommand(commandNum); if (command == null) { continue; } if (command.Value.ServerTime <= predictSnap.LocalPlayer.LastCommandTime) { continue; } /*if (originalPlayer.LastCommandTime == _snap.LocalPlayer.LastCommandTime) * { * if (originalPlayer.Position != _snap.LocalPlayer.Position) * { * Log.Write(LogLevel.Trace, "prediction error (position)"); * } * * if (originalPlayer.Rotation != _snap.LocalPlayer.Rotation) * { * Log.Write(LogLevel.Trace, "prediction error (rotation)"); * } * * Vector3 deltaPos = originalPlayer.Position - _snap.LocalPlayer.Position; * Vector3 deltaRot = originalPlayer.Rotation - _snap.LocalPlayer.Rotation; * * if (deltaPos.LengthSquared() > 0.01f) * { * Log.Write(LogLevel.Trace, "prediction miss (position, len {0})", deltaPos.Length()); * * uint t = _clientTime - _predictedErrorPosTime; * float f = (100f - t) / 100f; * * if (f < 0) * { * f = 0; * } * * _predictedErrorPos *= f; * _predictedErrorPos += deltaPos; * _predictedErrorPosTime = _oldTime; * } * }*/ PlayerMovement.Process((PlayerEntity)_snap.LocalPlayer, command.Value, Server.PhysicsWorld); } /* * // correct for errors accumulated above * { * uint t = _clientTime - _predictedErrorPosTime; * float f = (100f - t) / 100f; * * if (f > 0 && f < 1) * { * _snap.LocalPlayer.Position *= f; * _snap.LocalPlayer.Position += _predictedErrorPos; * } * else * { * _predictedErrorPosTime = 0; * } * } */ _oldTime = _clientTime; }