private static void SendSnapshot(ServerClient client) { // send entity states var message = new BitStream(); // reliable messages for (uint i = client.ReliableAcknowledged + 1; i <= client.ReliableSequence; i++) { // header byte message.WriteByte(Server.ReliableCommandNumber); // command number message.WriteUInt32(i); // command message.WriteString(client.ReliableCommands[i & (client.ReliableCommands.Length - 1)]); } message.WriteByte(Server.SnapshotNumber); message.WriteUInt32(_serverTime); message.WriteUInt32(client.LastReceivedReliableCommand); var useDelta = true; if ((client.Channel.SequenceOut - client.LastAcknowledgedMessage) >= 28) { useDelta = false; Log.Write(LogLevel.Warning, "client {0} lagged behind more than [max stored old packets]", client.Name); } for (int i = 0; i < Entities.Length; i++) { var entity = Entities[i]; if (entity == null) { continue; } // write the entity number message.WriteInt32(i, 12); var entityBase = (useDelta) ? ((client.EntityBases[i] != null) ? client.EntityBases[i].Get() : null) : null; var deltaMessage = new DeltaBitStream(entityBase, message); // write the spawn key deltaMessage.WriteInt32(entity.SpawnKey, 20); // write the type code deltaMessage.WriteInt32(entity.TypeCode, 4); // write the actual data entity.Serialize(deltaMessage); // set the new base if (client.EntityBases[i] == null) { client.EntityBases[i] = new ServerClientEntityBase(client); } client.EntityBases[i].Set(deltaMessage.NewBase); } message.WriteInt32(4095, 12); message.WriteByte(0xFF); // send the message client.Channel.SendMessage(message); }
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; }
public void SendMessage(BitStream stream) { SendMessage(stream.Bytes); }