public void ApplyWorldState(WorldState ws) { List <IBaseEntity> tempents = new List <IBaseEntity>(); { BitStream local = Data.Clone(); local.Cursor = 0; TempEntity e = null; for (int i = 0; i < EntryCount; i++) { double delay = 0; if (local.ReadBool()) { delay = local.ReadInt(8) / 100.0; } if (local.ReadBool()) { uint classID = local.ReadUInt(ws.ClassBits); ServerClass serverClass = ws.ServerClasses[(int)classID - 1]; SendTable sendTable = ws.SendTables.Single(st => st.NetTableName == serverClass.DatatableName); var flattened = sendTable.FlattenedProps; e = new TempEntity(ws, serverClass, sendTable); EntityCoder.ApplyEntityUpdate(e, local); tempents.Add(e); } else { Debug.Assert(e != null); EntityCoder.ApplyEntityUpdate(e, local); } } } foreach (IBaseEntity te in tempents) { ws.Listeners.TempEntityCreated.Invoke(te); } }
Entity ReadEnterPVS(WorldState ws, BitStream stream, uint entityIndex) { ServerClass serverClass = ws.ServerClasses[(int)stream.ReadUInt(ws.ClassBits)]; SendTable networkTable = ws.SendTables.Single(st => st.NetTableName == serverClass.DatatableName); uint serialNumber = stream.ReadUInt(SourceConstants.NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS); Entity e; { Entity existing = ws.Entities[entityIndex]; e = (existing == null || existing.SerialNumber != serialNumber) ? new Entity(ws, serverClass, networkTable, entityIndex, serialNumber) : existing; } var decodedBaseline = ws.InstanceBaselines[(int)Baseline.Value][entityIndex]; if (decodedBaseline != null) { var propertiesToAdd = decodedBaseline .Except(e.Properties, SendPropDefinitionComparer.Instance) .Select(sp => sp.Clone(e)); foreach (var p2a in propertiesToAdd) { e.AddProperty(p2a); } } else { BitStream baseline = ws.StaticBaselines.SingleOrDefault(bl => bl.Key == e.Class).Value; if (baseline != null) { baseline.Cursor = 0; EntityCoder.ApplyEntityUpdate(e, baseline); Debug.Assert((baseline.Length - baseline.Cursor) < 8); } } return(e); }
public void ApplyWorldState(WorldState ws) { if (ws.SignonState.State == ConnectionState.Spawn) { if (!IsDelta) { // We are done with signon sequence. ws.SignonState.State = ConnectionState.Full; } else { throw new InvalidOperationException("eceived delta packet entities while spawing!"); } } //ClientFrame newFrame = new ClientFrame(ws.Tick); //ws.Frames.Add(newFrame); //ClientFrame oldFrame = null; if (IsDelta) { if (ws.Tick == (ulong)DeltaFrom.Value) { throw new InvalidDataException("Update self-referencing"); } //oldFrame = ws.Frames.Single(f => f.ServerTick == (ulong)DeltaFrom.Value); } if (UpdateBaseline) { if (Baseline.Value == BaselineIndex.Baseline0) { ws.InstanceBaselines[(int)BaselineIndex.Baseline1] = ws.InstanceBaselines[(int)BaselineIndex.Baseline0]; ws.InstanceBaselines[(int)BaselineIndex.Baseline0] = new IList <SendProp> [SourceConstants.MAX_EDICTS]; } else if (Baseline.Value == BaselineIndex.Baseline1) { ws.InstanceBaselines[(int)BaselineIndex.Baseline0] = ws.InstanceBaselines[(int)BaselineIndex.Baseline1]; ws.InstanceBaselines[(int)BaselineIndex.Baseline1] = new IList <SendProp> [SourceConstants.MAX_EDICTS]; } else { throw new ArgumentOutOfRangeException(nameof(Baseline)); } } Data.Seek(0, SeekOrigin.Begin); int newEntity = -1; for (int i = 0; i < UpdatedEntries; i++) { newEntity += 1 + (int)EntityCoder.ReadUBitVar(Data); // Leave PVS flag if (!Data.ReadBool()) { // Enter PVS flag if (Data.ReadBool()) { Entity e = ReadEnterPVS(ws, Data, (uint)newEntity); EntityCoder.ApplyEntityUpdate(e, Data); if (ws.Entities[e.Index] != null && !ReferenceEquals(e, ws.Entities[e.Index])) { ws.Entities[e.Index].Dispose(); } ws.Entities[e.Index] = e; if (UpdateBaseline) { ws.InstanceBaselines[Baseline.Value == BaselineIndex.Baseline0 ? 1 : 0][e.Index] = new List <SendProp>(e.Properties.Select(sp => sp.Clone())); } e.InPVS = true; } else { // Preserve/update Entity e = ws.Entities[(uint)newEntity]; // ws.Entities.Single(ent => ent.Index == newEntity); EntityCoder.ApplyEntityUpdate(e, Data); } } else { bool shouldDelete = Data.ReadBool(); Entity e = ws.Entities[newEntity]; if (e != null) { e.InPVS = false; } ReadLeavePVS(ws, newEntity, shouldDelete); } } if (IsDelta) { // Read explicit deletions while (Data.ReadBool()) { uint ent = Data.ReadUInt(SourceConstants.MAX_EDICT_BITS); //Debug.Assert(ws.Entities[ent] != null); if (ws.Entities[ent] != null) { ws.Entities[ent].Dispose(); } ws.Entities[ent] = null; } } //Console.WriteLine("Parsed {0}", Description); }