Example #1
0
        public void FlattenClasses(bool allowModifyDemo)
        {
            var tableLookup = _dtRef.Tables.ToImmutableDictionary(table => table.Name, table => table);

            FlattenedProps = new PropLookup(_dtRef.ServerClasses.Count);

            foreach (ServerClass serverClass in _dtRef.ServerClasses)
            {
                SendTable table = _dtRef.Tables[serverClass.DataTableId];
                GatherProps(tableLookup, GatherExcludes(tableLookup, table), table, serverClass, "");
                SortProps(FlattenedProps[serverClass.DataTableId].flattenedProps);
            }

            // Now that I know the order of the props, I will parse the baselines of any SvcCreateMessages that
            // appeared BEFORE the datatables (valve really do be like that). In game, the baselines are stored as an
            // array and reparsed every time they're updated during demo playback. I just parse them once and store
            // them in a more accessible format.

            if (allowModifyDemo && _demoRef.StringTablesManager.TableReadable.GetValueOrDefault(TableNames.InstanceBaseLine))
            {
                _demoRef.StringTablesManager.Tables[TableNames.InstanceBaseLine]
                .Entries
                .Select(entry => entry.EntryData)
                .Cast <InstanceBaseline>()
                .ToList()
                .ForEach(baseline => baseline.ParseStream(baseline.Reader));
            }
        }
Example #2
0
        private Event?Process(CSVCMsg_SendTable message)
        {
            client.SendTables.Add(SendTable.CreateWith(message));

            log.Debug(String.Format("CSVCMsg_SendTable: {0} with {1} props",
                                    message.net_table_name, message.props.Count));

            return(null);
        }
Example #3
0
        public Entity(WorldState ws, ServerClass sClass, SendTable table, uint index, uint serialNumber)
        {
            m_World        = ws;
            m_Class        = sClass;
            m_NetworkTable = table;
            m_Index        = index;
            m_SerialNumber = serialNumber;

            Team  = new EntityPropertyMonitor <Team?>("DT_BaseEntity.m_iTeamNum", this, o => (Team)(int)o);
            Owner = new EntityPropertyMonitor <EHandle>("DT_BaseEntity.m_hOwnerEntity", this, o => new EHandle(ws, (uint)o));
        }
Example #4
0
        private void BuildHierarchy(
            List <PropertyInfo> properties,
            SendTable send,
            Dictionary <string, SendTable> all,
            HashSet <string> excluding)
        {
            var nonDtProps = new List <PropertyInfo>();

            GatherProperties(properties, send, all, nonDtProps, excluding);

            properties.AddRange(nonDtProps);
        }
Example #5
0
 private void GatherExcludes(
     SendTable table,
     Dictionary <string, SendTable> all,
     HashSet <string> excluding)
 {
     foreach (var property in table.Properties)
     {
         if (property.Flags.HasFlag(PropertyInfo.MultiFlag.Exclude))
         {
             excluding.Add(QualifyProperty(property.DtName, property));
         }
         else if (property.Type == PropertyInfo.PropertyType.DataTable)
         {
             GatherExcludes(all[property.DtName], all, excluding);
         }
     }
 }
Example #6
0
        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);
            }
        }
Example #7
0
        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);
        }
Example #8
0
		public void ParsePacket(IBitStream bitstream)
        {
			while (true)
            {
				var type = (SVC_Messages)bitstream.ReadProtobufVarInt();
				if (type != SVC_Messages.svc_SendTable)
					throw new Exception("Expected SendTable, got " + type);

				var size = bitstream.ReadProtobufVarInt();
				bitstream.BeginChunk(size * 8);
				var sendTable = new SendTable(bitstream);
				bitstream.EndChunk();

                if (sendTable.IsEnd)
                    break;

				DataTables.Add(sendTable);
            }

			int serverClassCount = checked((int)bitstream.ReadInt(16));

            for (int i = 0; i < serverClassCount; i++)
            {
                ServerClass entry = new ServerClass();
				entry.ClassID = checked((int)bitstream.ReadInt(16));

                if (entry.ClassID > serverClassCount)
                    throw new Exception("Invalid class index");

				entry.Name = bitstream.ReadDataTableString();
				entry.DTName = bitstream.ReadDataTableString();

                entry.DataTableID = DataTables.FindIndex(a => a.Name == entry.DTName);

                ServerClasses.Add(entry);
            }

            for (int i = 0; i < serverClassCount; i++)
                FlattenDataTable(i);
        }
Example #9
0
        private void GatherProperties(
            List <PropertyInfo> properties,
            SendTable send,
            Dictionary <string, SendTable> all,
            List <PropertyInfo> nonDtProps,
            HashSet <string> excluding)
        {
            var skipOn = PropertyInfo.MultiFlag.Exclude | PropertyInfo.MultiFlag.InsideArray;

            foreach (var property in send.Properties)
            {
                if ((uint)(property.Flags & skipOn) > 0)
                {
                    continue;
                }
                if (excluding.Contains(QualifyProperty(property.Origin.NetTableName, property)))
                {
                    continue;
                }

                if (property.Type == PropertyInfo.PropertyType.DataTable)
                {
                    var pointsAt = all[property.DtName];

                    if (property.Flags.HasFlag(PropertyInfo.MultiFlag.Collapsible))
                    {
                        GatherProperties(properties, pointsAt, all, nonDtProps, excluding);
                    }
                    else
                    {
                        BuildHierarchy(properties, pointsAt, all, excluding);
                    }
                }
                else
                {
                    nonDtProps.Add(property);
                }
            }
        }
Example #10
0
 public TempEntity(WorldState ws, ServerClass sClass, SendTable table)
 {
     World        = ws;
     Class        = sClass;
     NetworkTable = table;
 }
Example #11
0
        public static Task Read(this SourceDemo demo, DataTables frame)
        {
            var buf = frame.Buffer;

            while (buf.ReadBoolean())
            {
                bool needsdecoder = buf.ReadBoolean();
                var  table        = new SendTable()
                {
                    NetTableName = buf.ReadString(),
                    NeedsDecoder = needsdecoder
                };

                var props = buf.ReadUBits(DataTable.PROPINFOBITS_NUMPROPS);
                for (int j = 0; j < props; j++)
                {
                    int fbits = (demo.Protocol == 2)
                        ? 11
                        : DataTable.PROPINFOBITS_FLAGS;

                    var prop = new SendProp
                    {
                        Type    = (SendPropType)buf.ReadUBits(DataTable.PROPINFOBITS_TYPE),
                        VarName = buf.ReadString(),
                        Flags   = (SendPropFlags)buf.ReadUBits(fbits)
                    };

                    if ((prop.Type == SendPropType.DataTable) || (prop.IsExcludeProp()))
                    {
                        prop.ExcludeDtName = buf.ReadString();
                        //if ((prop.Flags & SendPropFlags.Collapsible) != 0)
                        //{
                        //}
                    }
                    else if (prop.Type == SendPropType.Array)
                    {
                        prop.Elements = (int)buf.ReadUBits(DataTable.PROPINFOBITS_NUMELEMENTS);
                    }
                    else
                    {
                        prop.LowValue  = buf.ReadSingle();
                        prop.HighValue = buf.ReadSingle();
                        prop.Bits      = (int)buf.ReadUBits(DataTable.PROPINFOBITS_NUMBITS + 1);
                    }
                    table.Props.Add(prop);
                }

                frame.Tables.Add(table);
            }

            var classes = buf.ReadInt16();

            for (var i = 0; i < classes; i++)
            {
                frame.Classes.Add(new ServerClassInfo
                {
                    ClassId       = buf.ReadInt16(),
                    ClassName     = buf.ReadString(),
                    DataTableName = buf.ReadString()
                });
            }
            return(Task.CompletedTask);
        }
Example #12
0
 private Events?Handle(CSVCMsg_SendTable message)
 {
     state.SendTables.Add(SendTable.CreateWith(message));
     return(null);
 }
Example #13
0
		void GatherProps_IterateProps(SendTable table, int ServerClassIndex, List<FlattenedPropEntry> flattenedProps, string prefix)
        {
            for (int i = 0; i < table.Properties.Count; i++)
            {
                SendTableProperty property = table.Properties[i];

                if (property.Flags.HasFlagFast(SendPropertyFlags.InsideArray) || property.Flags.HasFlagFast(SendPropertyFlags.Exclude) || IsPropExcluded(table, property))
                    continue;

                if (property.Type == SendPropertyType.DataTable)
                {
                    SendTable subTable = GetTableByName(property.DataTableName);

                    if (property.Flags.HasFlagFast(SendPropertyFlags.Collapsible))
                    {
						//we don't prefix Collapsible stuff, since it is just derived mostly
						GatherProps_IterateProps(subTable, ServerClassIndex, flattenedProps, prefix);
                    }
                    else
                    {
						//We do however prefix everything else

						string nfix = prefix + ((property.Name.Length > 0) ? property.Name + "." : "");

						GatherProps(subTable, ServerClassIndex, nfix);
                    }
                }
                else
                {
                    if (property.Type == SendPropertyType.Array)
                    {
						flattenedProps.Add(new FlattenedPropEntry(prefix + property.Name, property, table.Properties[i - 1]));
                    }
                    else
                    {
						flattenedProps.Add(new FlattenedPropEntry(prefix + property.Name, property, null));
                    }
                }


            }
        }
Example #14
0
 bool IsPropExcluded(SendTable table, SendTableProperty prop)
 {
     return CurrentExcludes.Exists(a => table.Name == a.DTName && prop.Name == a.VarName);
 }
Example #15
0
		void GatherProps(SendTable table, int serverClassIndex, string prefix)
        {
            List<FlattenedPropEntry> tmpFlattenedProps = new List<FlattenedPropEntry>();
			GatherProps_IterateProps(table, serverClassIndex, tmpFlattenedProps, prefix);

            List<FlattenedPropEntry> flattenedProps = ServerClasses[serverClassIndex].FlattenedProps;

            flattenedProps.AddRange(tmpFlattenedProps);
        }
Example #16
0
        private ISet <(string propName, string tableName)> GatherExcludes(IReadOnlyDictionary <string, SendTable> tableLookup, SendTable table)
        {
            var excludes = new HashSet <(string, string)>();

            foreach (SendTableProp sendProp in table.SendProps)
            {
                if (sendProp.SendPropType == SendPropType.DataTable)
                {
                    excludes.UnionWith(GatherExcludes(tableLookup, tableLookup[sendProp.ExcludeDtName !]));
Example #17
0
        static SendTable ParseSendTable(BitStream stream)
        {
            SendTable table = new SendTable();

            table.Unknown1 = stream.ReadBool();

            table.NetTableName = stream.ReadCString();

            int propertyCount = (int)stream.ReadULong(PROPINFOBITS_NUMPROPS);

            SendPropDefinition arrayElementProp = null;

            for (int i = 0; i < propertyCount; i++)
            {
                SendPropDefinition prop = new SendPropDefinition(table);

                prop.Type = (SendPropType)stream.ReadULong(PROPINFOBITS_TYPE);
                Debug.Assert(Enum.GetValues(typeof(SendPropType)).Cast <SendPropType>().Contains(prop.Type));

                Debug.Assert(prop.Type == SendPropType.Datatable ? prop.Flags == 0 : true);

                prop.Name = stream.ReadCString();

                prop.Flags = (SendPropFlags)stream.ReadULong(PROPINFOBITS_FLAGS);

                if (prop.Type == SendPropType.Datatable)
                {
                    prop.ExcludeName = stream.ReadCString();
                }
                else
                {
                    if ((prop.Flags & SendPropFlags.Exclude) != 0)
                    {
                        prop.ExcludeName = stream.ReadCString();
                    }
                    else if (prop.Type == SendPropType.Array)
                    {
                        prop.ArrayElements = (int)stream.ReadULong(PROPINFOBITS_NUMELEMENTS);
                    }
                    else
                    {
                        prop.LowValue  = stream.ReadSingle();
                        prop.HighValue = stream.ReadSingle();

                        prop.BitCount = stream.ReadULong(PROPINFOBITS_NUMBITS);
                    }
                }

                if (prop.Flags.HasFlag(SendPropFlags.NoScale))
                {
                    if (prop.Type == SendPropType.Float)
                    {
                        prop.BitCount = 32;
                    }
                    else if (prop.Type == SendPropType.Vector)
                    {
                        if (!prop.Flags.HasFlag(SendPropFlags.Normal))
                        {
                            prop.BitCount = 32 * 3;
                        }
                    }
                }

                if (arrayElementProp != null)
                {
                    Debug.Assert(prop.Type == SendPropType.Array);
                    prop.ArrayProperty = arrayElementProp;
                    arrayElementProp   = null;
                }

                if (prop.Flags.HasFlag(SendPropFlags.InsideArray))
                {
                    Debug.Assert(arrayElementProp == null);
                    Debug.Assert(!prop.Flags.HasFlag(SendPropFlags.ChangesOften));
                    arrayElementProp = prop;
                }
                else
                {
                    table.Properties.Add(prop);
                }
            }

            return(table);
        }
 public SendTableProp(SourceDemo?demoRef, SendTable tableRef) : base(demoRef)
 {
     TableRef = tableRef;
 }
Example #19
0
		void GatherExcludesAndBaseclasses(SendTable sendTable, bool collectBaseClasses)
        {
            CurrentExcludes.AddRange(
                sendTable.Properties
                    .Where(a => a.Flags.HasFlagFast(SendPropertyFlags.Exclude))
                    .Select(a => new ExcludeEntry(a.Name, a.DataTableName, sendTable.Name))
                );

            foreach (var prop in sendTable.Properties.Where(a => a.Type == SendPropertyType.DataTable))
            {
				if (collectBaseClasses && prop.Name == "baseclass") {
					GatherExcludesAndBaseclasses (GetTableByName (prop.DataTableName), true);
					CurrentBaseclasses.Add (FindByDTName (prop.DataTableName));
				} else {
					GatherExcludesAndBaseclasses (GetTableByName (prop.DataTableName), false);
				}
            }
        }