public static Dictionary <int, AppInfo> LoadFromFile(string path) { using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (var reader = new BinaryReader(file)) { var apps = new Dictionary <int, AppInfo>(); var version = reader.ReadInt32(); var universe = reader.ReadInt32(); while (true) { var appId = reader.ReadInt32(); if (appId == 0) { break; } var appInfo = new AppInfo(); apps.Add(appId, appInfo); var appHeader = new AppInfo.AppState() { Size = reader.ReadInt32(), State = reader.ReadInt32(), LastUpdate = reader.ReadInt32(), AccessToken = reader.ReadUInt64(), Checksum = reader.ReadBytes(20), ChangeNumber = reader.ReadInt32() }; appInfo.Header = appHeader; var appSections = new DataFieldList(); while (true) { var sectionId = reader.ReadByte(); if (sectionId == 0) { break; } // Skip the 0x00 byte before section name. reader.ReadByte(); var sectionName = reader.BaseStream.ReadNullTermString(Encoding.UTF8); appSections.Add(new DataField(sectionName, parseAppSection(reader, true))); } appInfo.Sections = appSections; } return(apps); } } }
public DataField(string name, DataFieldList data) { Name = name; ListData = data; }
static DataFieldList parseAppSection(BinaryReader reader, bool root) { var data = new DataFieldList(); while (true) { var valueType = (ValueType)reader.ReadByte(); if (valueType == ValueType.End) { // There's one additional 0x08 byte at the end of the root subsection. if (root) { reader.ReadByte(); } break; } var key = reader.BaseStream.ReadNullTermString(Encoding.UTF8); var section = new DataField(key); switch (valueType) { case ValueType.None: { section.ListData = parseAppSection(reader, false); break; } case ValueType.String: { section.StringData = reader.BaseStream.ReadNullTermString(Encoding.UTF8); break; } case ValueType.WideString: { throw new Exception("Failed to read steam data, WideString found."); } case ValueType.Int32: { section.IntData = reader.ReadInt32(); break; } case ValueType.Color: { section.IntData = reader.ReadInt32(); break; } case ValueType.Pointer: { section.IntData = reader.ReadInt32(); break; } case ValueType.UInt64: { section.UlongData = reader.ReadUInt64(); break; } case ValueType.Float32: { var buff = new byte[8]; reader.Read(buff, 0, 4); section.FloatData = BitConverter.ToSingle(buff, 0); break; } } data.Add(section); } return(data); }