public void Deserialize(BitStream message, UserCommand?old) { if (old == null) { ServerTime = message.ReadUInt32(); Buttons = (ClientButtons)message.ReadInt16(); } else { var oldCommand = old.Value; // read server time if (message.ReadBool()) { // is delta time ServerTime = oldCommand.ServerTime + message.ReadByte(); } else { // is absolute time ServerTime = message.ReadUInt32(); } // read buttons Buttons = (ClientButtons)message.ReadDeltaInt16((short)oldCommand.Buttons); } }
public uint ReadUInt32() { uint value = (_baseStream == null) ? 0 : _baseStream.ReadUInt32(); if (_bitStream.ReadBool()) { value = _bitStream.ReadUInt32(); } _newBaseStream.WriteUInt32(value); return(value); }
public void WriteUInt32(uint value) { _newBaseStream.WriteUInt32(value); if (_baseStream != null && value == _baseStream.ReadUInt32()) { _bitStream.WriteBool(false); } else { _bitStream.WriteBool(true); _bitStream.WriteUInt32(value); } }
public static void ProcessPacket(NetAddress from, byte[] packet) { if (packet.Length < 4) { return; } var message = new BitStream(packet); var sequenceNum = message.ReadUInt32(); if (sequenceNum == 0xFFFFFFFF) { ProcessOutOfBand(from, packet); return; } if (from != _serverChannel.Address) { return; } if (_serverChannel.ProcessPacket(packet)) { message = new BitStream(packet); // reset the bitstream ProcessServerMessage(message); } }
private static void ProcessReliableCommand(BitStream message) { uint commandSequence = message.ReadUInt32(); string command = message.ReadString(); if (commandSequence <= _lastExecutedReliable) { return; } string[] args = Command.Tokenize(command); switch (args[0]) { case "print": if (args.Length < 2) { break; } Log.Write(LogLevel.Info, "{0}", string.Join(" ", args, 1, args.Length - 1)); break; case "disconnect": State = ClientState.Idle; Log.Write(LogLevel.Error, "Disconnected from server: {0}", (args.Length == 2) ? args[1] : "no message"); break; } _lastExecutedReliable = commandSequence; _lastReliableMessage = commandSequence; }
private static void ProcessClientReliableCommand(ServerClient client, BitStream message) { uint commandSequence = message.ReadUInt32(); string command = message.ReadString(); if (commandSequence <= client.LastExecutedReliableCommand) { return; } string[] args = Command.Tokenize(command); switch (args[0]) { case "say": if (args.Length < 2) { break; } string msg = string.Format("{0}: {1}", client.Name, string.Join(" ", args, 1, args.Length - 1)); Log.Write(LogLevel.Info, msg); SendReliableCommand(null, "print \"" + msg + "\""); break; case "disconnect": DropClient(client, "Disconnected from server"); break; } client.LastReceivedReliableCommand = commandSequence; client.LastExecutedReliableCommand = commandSequence; }
public static void ProcessPacket(NetAddress from, byte[] packet) { if (packet.Length < 4) { return; } var message = new BitStream(packet); var sequenceNum = message.ReadUInt32(); if (sequenceNum == 0xFFFFFFFF) { ProcessOutOfBand(from, packet); return; } for (int i = 0; i < _clients.Length; i++) { if (_clients[i] != null) { if (_clients[i].Channel.Address == from) { if (_clients[i].Channel.ProcessPacket(packet)) { ProcessClientMessage(_clients[i], message); } } } } }
private static void ProcessClientMessage(ServerClient client, BitStream message) { client.LastMessageReceivedAt = _serverTime; client.LastAcknowledgedMessage = message.ReadUInt32(); client.ReliableAcknowledged = message.ReadUInt32(); // check if this command is from an older initialization state var stateID = message.ReadInt32(); if (stateID != _stateID) { if (client.LastAcknowledgedMessage >= client.LastInitStateMessage) { SendInitializationState(client); } return; } byte command = 0; try { do { command = message.ReadByte(); switch (command) { case UserCommand.CommandType: ProcessClientUserCommand(client, message); break; case 2: // TODO: magic number fix ProcessClientReliableCommand(client, message); break; } } while (command != 0xFF); } catch (Exception e) { Log.Write(LogLevel.Warning, "Error while processing client message: " + e.ToString()); DropClient(client, "Error while processing client message."); } }
public bool ProcessPacket(byte[] packet) { var message = new BitStream(packet); var sequence = message.ReadUInt32(); if (sequence < SequenceIn) { Log.Write(LogLevel.Debug, "out of order packet ({0}, {1})", sequence, SequenceIn); return(false); } if (sequence > (SequenceIn + 1)) { Log.Write(LogLevel.Debug, "dropped packet ({0}, {1})", sequence, SequenceIn); } SequenceIn = sequence; return(true); }
private static void ProcessServerMessage(BitStream message) { _lastMessageReceivedAt = _clientTime; _lastServerMessage = message.ReadUInt32(); byte command = 0; #if !DEBUG try { #endif do { command = message.ReadByte(); switch (command) { case Server.SnapshotNumber: ProcessSnapshot(message); break; case Server.ReliableCommandNumber: ProcessReliableCommand(message); break; case Server.InitStateNumber: ProcessInitializationState(message); break; } } while (command != 0xFF); #if !DEBUG } catch (Exception e) { Log.Write(LogLevel.Warning, "Error while processing client message: " + e.ToString()); // TODO: disconnect client } #endif }
private static void ProcessSnapshot(BitStream message) { if (State == ClientState.Connected) { State = ClientState.Ingame; } var snapshot = new Snapshot(); snapshot.Sequence = _serverChannel.SequenceIn; snapshot.ServerTime = message.ReadUInt32(); _serverTimeDelta = (int)((int)snapshot.ServerTime - (int)_clientTime); _reliableAcknowledged = message.ReadInt32(); int entityNumber = message.ReadInt32(12); while (entityNumber != 4095) { var entityBase = (_entityBases[entityNumber] != null) ? _entityBases[entityNumber] : null; var deltaMessage = new DeltaBitStream(entityBase, message); var spawnKey = deltaMessage.ReadInt32(20); var typeCode = deltaMessage.ReadInt32(4); snapshot.Entities[entityNumber] = Entity.Create(typeCode); snapshot.Entities[entityNumber].Deserialize(deltaMessage); _entityBases[entityNumber] = deltaMessage.NewBase; entityNumber = message.ReadInt32(12); } // push snapshot history array back by one for (int i = (_snapHistory.Length - 2); i >= 0; i--) { _snapHistory[i + 1] = _snapHistory[i]; } // and set the first snapshot to the current one _snapHistory[0] = snapshot; // define current and previous snapshots int delayMsec = cl_snapDelay.GetValue <int>(); int numSnaps = 0; for (int i = 0; i < _snapHistory.Length; i++) { if (_snapHistory[i] != null) { if (_snapHistory[i].ServerTime < (_snapHistory[0].ServerTime - delayMsec)) { numSnaps = i; break; } } } int snapDelay = Math.Max(0, Math.Min(_snapHistory.Length - 2, numSnaps)); _lastSnap = _snapHistory[snapDelay + 1]; _curSnap = _snapHistory[snapDelay]; if (_curSnap == null) { _curSnap = _snapHistory[0]; } _curSnap.ClientTime = _clientTime; }