public static void WritePropertyArray(BinaryWriter writer, BVPropertyCollection data) { data.Properties.ForEach(dr => { WriteProperty(writer, dr); }); }
public static SteamPackageInfoDataFile Read(string steamShortcutFilePath) { using (FileStream stream = File.OpenRead(steamShortcutFilePath)) using (BinaryReader reader = new BinaryReader(stream)) { List <SteamPackageInfoDataFileChunk> Chunks = new List <SteamPackageInfoDataFileChunk>(); byte Version1 = reader.ReadByte(); UInt16 Type = reader.ReadUInt16(); byte Version2 = reader.ReadByte(); UInt32 Version3 = reader.ReadUInt32(); //while(reader.BaseStream.Position < reader.BaseStream.Length) for (;;) { UInt32 PackageID = reader.ReadUInt32(); if (PackageID == 0xffffffff) { break; } byte[] Checksum = reader.ReadBytes(20); UInt32 LastChangeNumber = reader.ReadUInt32(); BVPropertyCollection Data = BVdfFile.ReadPropertyArray(reader); SteamPackageInfoDataFileChunk Chunk = new SteamPackageInfoDataFileChunk(PackageID, Checksum, LastChangeNumber, Data); Chunks.Add(Chunk); } return(new SteamPackageInfoDataFile(Version1, Type, Version2, Version3, Chunks)); } }
public SteamPackageInfoDataFileChunk(UInt32 PackageID, byte[] Checksum, UInt32 LastChangeNumber, BVPropertyCollection data) { this.PackageID = PackageID; this.Checksum = Checksum; this.LastChangeNumber = LastChangeNumber; this.data = data; }
public static void Write(string steamShortcutFilePath, BVPropertyCollection data) { using (FileStream stream = File.OpenWrite(steamShortcutFilePath)) using (BinaryWriter writer = new BinaryWriter(stream)) { BVdfFile.WritePropertyArray(writer, data); writer.Write((byte)0x08); } }
// TODO use a better AppID source, the AppInfo.vtf file only holds data the client has actually seen public List <SteamLaunchableApp> GetOwnedApps() { //UInt32[] appIDs = GetClientAppIds(); List <SteamLaunchableApp> apps = new List <SteamLaunchableApp>(); //SteamAppInfoDataFile dataFile = SteamAppInfoDataFile.Read(GetAppCacheAppInfoFile()); SteamAppInfoDataFile dataFile = SteamAppInfoDataFile.GetSteamAppInfoDataFile(); /*dataFile.chunks * .Where(chunk => chunk.data != null && chunk.data.Properties != null && chunk.data.Properties.Count > 0) * //.Select(chunk => ((BVStringToken)((BVPropertyCollection)((BVPropertyCollection)chunk.data?["appinfo"])?["common"])?["type"])?.Value?.ToLowerInvariant()) * .Select(chunk => ((BVStringToken)((BVPropertyCollection)((BVPropertyCollection)chunk.data?["appinfo"])?["common"])?["releasestate"])?.Value?.ToLowerInvariant()) * .Distinct() * .OrderBy(dr => dr) * .ToList() * .ForEach(dr => * { * Console.WriteLine(dr); * });*/ dataFile.chunks .ForEach(chunk => { if (chunk.data != null && chunk.data.Properties != null && chunk.data.Properties.Count > 0) { BVPropertyCollection appinfo = ((BVPropertyCollection)chunk.data?["appinfo"]); BVPropertyCollection common = ((BVPropertyCollection)appinfo?["common"]); BVPropertyCollection extended = ((BVPropertyCollection)appinfo?["extended"]); string type = common?["type"]?.GetValue <string>()?.ToLowerInvariant(); //if (type == "demo" || type == "game") if (!string.IsNullOrWhiteSpace(type) && type != "config") { bool isInstalled = SteamApps.BIsAppInstalled(chunk.AppID); bool isSubscribed = SteamApps.BIsSubscribedApp(chunk.AppID); string name = common?["name"]?.GetValue <string>(); string clienticon = common?["clienticon"]?.GetValue <string>(); if (isSubscribed && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(type)) { apps.Add(new SteamLaunchableApp(chunk.AppID) { Name = name?.TrimEnd(), appIcon = string.IsNullOrWhiteSpace(clienticon) ? null : Path.Combine(SteamProcessInfo.SteamInstallPath, "steam", "games", clienticon + ".ico"), appType = type, });; } } } }); return(apps); }
public SteamAppInfoDataFileChunk(UInt32 AppID, UInt32 State, UInt32 LastUpdate, UInt64 AccessToken, byte[] Checksum, UInt32 LastChangeNumber, BVPropertyCollection data) { this.AppID = AppID; this.State = State; this.LastUpdate = LastUpdate; this.AccessToken = AccessToken; this.Checksum = Checksum; this.LastChangeNumber = LastChangeNumber; this.data = data; }
public SteamPackageInfoDataFileChunk(UInt32 SubID, /*UInt32 State, UInt32 LastUpdate, UInt64 AccessToken,*/ byte[] Checksum, UInt32 LastChangeNumber, BVPropertyCollection data) { this.SubID = SubID; //this.State = State; //this.LastUpdate = LastUpdate; //this.AccessToken = AccessToken; this.Checksum = Checksum; this.LastChangeNumber = LastChangeNumber; this.data = data; }
public static BVPropertyCollection ReadPropertyArray(BinaryReader reader) { BVPropertyCollection Values = new BVPropertyCollection(); byte ReadByte = 0x00; while ((ReadByte = reader.ReadByte()) != 0x08) { //Values.Add(ReadProperty(reader)); Values.Add(ReadProperty(ReadByte, reader)); } //reader.ReadByte(); return(Values); }
public static SteamAppInfoDataFile Read(string steamShortcutFilePath) { using (FileStream stream = File.OpenRead(steamShortcutFilePath)) using (BinaryReader reader = new BinaryReader(stream)) { List <SteamAppInfoDataFileChunk> Chunks = new List <SteamAppInfoDataFileChunk>(); byte Version1 = reader.ReadByte(); UInt16 Type = reader.ReadUInt16(); byte Version2 = reader.ReadByte(); UInt32 Version3 = reader.ReadUInt32(); //while(reader.BaseStream.Position < reader.BaseStream.Length) for (; ;) { UInt32 AppID = reader.ReadUInt32(); if (AppID == 0) { break; } UInt32 DataSize = reader.ReadUInt32(); long startPos = reader.BaseStream.Position; //Console.WriteLine($"Expected End Position: {(startPos + DataSize):X8}"); UInt32 State = reader.ReadUInt32(); UInt32 LastUpdate = reader.ReadUInt32(); UInt64 AccessToken = reader.ReadUInt64(); byte[] Checksum = reader.ReadBytes(20); UInt32 LastChangeNumber = reader.ReadUInt32(); BVPropertyCollection Data = BVdfFile.ReadPropertyArray(reader); //long endPos = reader.BaseStream.Position; if (reader.BaseStream.Position != (startPos + DataSize)) { Console.WriteLine("appinfo.vdf chunk data size wrong, adjusting stream position"); reader.BaseStream.Seek(startPos + DataSize, SeekOrigin.Begin); } //Console.WriteLine($"*Expected End Position: {(startPos + DataSize):X8}"); //Console.WriteLine($"End Position: {(endPos):X8}"); SteamAppInfoDataFileChunk Chunk = new SteamAppInfoDataFileChunk(AppID, State, LastUpdate, AccessToken, Checksum, LastChangeNumber, Data); Chunks.Add(Chunk); } return(new SteamAppInfoDataFile(Version1, Type, Version2, Version3, Chunks)); } }
public static SteamPackageInfoDataFile Read(string steamShortcutFilePath) { using (FileStream stream = File.OpenRead(steamShortcutFilePath)) using (BinaryReader reader = new BinaryReader(stream)) { List <SteamPackageInfoDataFileChunk> Chunks = new List <SteamPackageInfoDataFileChunk>(); byte Version1 = reader.ReadByte(); UInt16 Type = reader.ReadUInt16(); byte Version2 = reader.ReadByte(); UInt32 Version3 = reader.ReadUInt32(); //while(reader.BaseStream.Position < reader.BaseStream.Length) for (; ;) { UInt32 SubID = reader.ReadUInt32(); if (SubID == 0xffffffff) { break; } //UInt32 DataSize = reader.ReadUInt32(); long startPos = reader.BaseStream.Position; //Console.WriteLine($"Expected End Position: {(startPos + DataSize):X8}"); //UInt32 State = reader.ReadUInt32(); //UInt32 LastUpdate = reader.ReadUInt32(); //UInt64 AccessToken = reader.ReadUInt64(); byte[] Checksum = reader.ReadBytes(20); UInt32 LastChangeNumber = reader.ReadUInt32(); BVPropertyCollection Data = BVdfFile.ReadPropertyArray(reader); //long endPos = reader.BaseStream.Position; //if (reader.BaseStream.Position != (startPos + DataSize)) //{ // Console.WriteLine("appinfo.vdf chunk data size wrong, adjusting stream position"); // reader.BaseStream.Seek(startPos + DataSize, SeekOrigin.Begin); //} //Console.WriteLine($"*Expected End Position: {(startPos + DataSize):X8}"); //Console.WriteLine($"End Position: {(endPos):X8}"); Data.ForceObjectWhenUnsure = true; Data.Children()?.ForEach(node => { BVPropertyCollection appids = ((node.Value as BVPropertyCollection)?["appids"] as BVPropertyCollection); if (appids != null) { appids.ForceNumericWhenUnsure = true; } BVPropertyCollection depotids = ((node.Value as BVPropertyCollection)?["depotids"] as BVPropertyCollection); if (depotids != null) { depotids.ForceNumericWhenUnsure = true; } BVPropertyCollection appitems = ((node.Value as BVPropertyCollection)?["appitems"] as BVPropertyCollection); if (appitems != null) { appitems.ForceNumericWhenUnsure = true; } }); SteamPackageInfoDataFileChunk Chunk = new SteamPackageInfoDataFileChunk(SubID, /*State, LastUpdate, AccessToken,*/ Checksum, LastChangeNumber, Data); Chunks.Add(Chunk); } return(new SteamPackageInfoDataFile(Version1, Type, Version2, Version3, Chunks)); } }
public List <SteamLaunchableApp> GetAppsWithMetadata(UInt64[] AppIDs = null) { //UInt32[] appIDs = GetClientAppIds(); List <SteamLaunchableApp> apps = new List <SteamLaunchableApp>(); //SteamAppInfoDataFile dataFile = SteamAppInfoDataFile.Read(GetAppCacheAppInfoFile()); SteamAppInfoDataFile dataFile = SteamAppInfoDataFile.GetSteamAppInfoDataFile(); /*dataFile.chunks * .Where(chunk => chunk.data != null && chunk.data.Properties != null && chunk.data.Properties.Count > 0) * //.Select(chunk => ((BVStringToken)((BVPropertyCollection)((BVPropertyCollection)chunk.data?["appinfo"])?["common"])?["type"])?.Value?.ToLowerInvariant()) * .Select(chunk => ((BVStringToken)((BVPropertyCollection)((BVPropertyCollection)chunk.data?["appinfo"])?["common"])?["releasestate"])?.Value?.ToLowerInvariant()) * .Distinct() * .OrderBy(dr => dr) * .ToList() * .ForEach(dr => * { * Console.WriteLine(dr); * });*/ dataFile.chunks .ForEach(chunk => { if (chunk.data != null && chunk.data.Properties != null && chunk.data.Properties.Count > 0 && ((AppIDs?.Length ?? 0) == 0 || AppIDs.Contains(chunk.AppID))) { BVPropertyCollection appinfo = ((BVPropertyCollection)chunk.data?["appinfo"]); BVPropertyCollection common = ((BVPropertyCollection)appinfo?["common"]); BVPropertyCollection extended = ((BVPropertyCollection)appinfo?["extended"]); string type = common?["type"]?.GetValue <string>()?.ToLowerInvariant(); //if (type == "demo" || type == "game") if (!string.IsNullOrWhiteSpace(type) && type != "config") { bool isInstalled = SteamApps.BIsAppInstalled(chunk.AppID); bool isSubscribed = SteamApps.BIsSubscribedApp(chunk.AppID); string name = common?["name"]?.GetValue <string>(); //string oslist = common?["oslist"]?.GetValue<string>(); //string icon = common?["icon"]?.GetValue<string>(); //string clienttga = common?["clienttga"]?.GetValue<string>(); string clienticon = common?["clienticon"]?.GetValue <string>(); //string logo = common?["logo"]?.GetValue<string>(); //string logo_small = common?["logo_small"]?.GetValue<string>(); //string releasestate = common?["releasestate"]?.GetValue<string>(); //string linuxclienticon = common?["linuxclienticon"]?.GetValue<string>(); //string controller_support = common?["controller_support"]?.GetValue<string>(); //string clienticns = common?["clienticns"]?.GetValue<string>(); //int metacritic_score = ((BVInt32Token)common?["metacritic_score"])?.Value ?? -1; //string metacritic_name = common?["metacritic_name"]?.GetValue<string>(); //BVPropertyCollection small_capsule = ((BVPropertyCollection)common?["small_capsule"]); //BVPropertyCollection header_image = ((BVPropertyCollection)common?["header_image"]); //BVPropertyCollection languages = ((BVPropertyCollection)common?["languages"]); //bool community_visible_stats = common?["community_visible_stats"]?.GetValue<string>() == "1"; //bool community_hub_visible = common?["community_hub_visible"]?.GetValue<string>() == "1"; //bool workshop_visible = common?["workshop_visible"]?.GetValue<string>() == "1"; //bool exfgls = common?["exfgls"]?.GetValue<string>() == "1"; //string gamedir = extended?["gamedir"]?.GetValue<string>(); List <string> developer = new List <string>(); List <string> publisher = new List <string>(); //string homepage = extended?["homepage"]?.GetValue<string>(); //string gamemanualurl = extended?["gamemanualurl"]?.GetValue<string>(); //bool showcdkeyonlaunch = extended?["showcdkeyonlaunch"]?.GetValue<string>() == "1"; //bool dlcavailableonstore = extended?["dlcavailableonstore"]?.GetValue<string>() == "1"; { List <BVProperty> props = (common?["associations"] as BVPropertyCollection)?.Properties; if (props != null) { foreach (BVProperty element in props) { string elemType = (element.Value as BVPropertyCollection)?["type"].GetValue <string>(); string elemVal = (element.Value as BVPropertyCollection)?["name"].GetValue <string>(); if (string.IsNullOrWhiteSpace(elemVal)) { continue; } if (elemType == "developer") // && string.IsNullOrWhiteSpace(developer)) { developer.Add(elemVal); } if (elemType == "publisher") // && string.IsNullOrWhiteSpace(publisher)) { publisher.Add(elemVal); } } } string extended_dev = extended?["developer"]?.GetValue <string>(); if (developer.Count == 0 && !string.IsNullOrWhiteSpace(extended_dev)) { developer.Add(extended_dev); } string extended_pub = extended?["publisher"]?.GetValue <string>(); if (publisher.Count == 0 && !string.IsNullOrWhiteSpace(extended_pub)) { publisher.Add(extended_pub); } } long?_original_release_date = common?["original_release_date"]?.GetValue <long>(); long?_steam_release_date = common?["steam_release_date"]?.GetValue <long>(); DateTime?original_release_date = _original_release_date.HasValue ? DateTimeOffset.FromUnixTimeSeconds(_original_release_date.Value).UtcDateTime : (DateTime?)null; DateTime?steam_release_date = _steam_release_date.HasValue ? DateTimeOffset.FromUnixTimeSeconds(_steam_release_date.Value).UtcDateTime : (DateTime?)null; BVPropertyCollection library_assets = ((BVPropertyCollection)common?["library_assets"]); bool has_library_capsule = !string.IsNullOrWhiteSpace(library_assets?["library_capsule"]?.GetValue <string>()); bool has_library_hero = !string.IsNullOrWhiteSpace(library_assets?["library_hero"]?.GetValue <string>()); bool has_library_logo = !string.IsNullOrWhiteSpace(library_assets?["library_logo"]?.GetValue <string>()); //Console.WriteLine($"{chunk.AppID}\t{(type ?? string.Empty).PadRight(4)} {(isInstalled ? 1 : 0)} {(isSubscribed ? 1 : 0)} {(releasestate ?? string.Empty).PadRight(11)} {(name ?? string.Empty).PadRight(90)} {(developer ?? string.Empty).PadRight(40)} {(publisher ?? string.Empty)}"); //File.AppendAllText("SteamDump.txt",$"{chunk.appID}\t{(type ?? string.Empty).PadRight(4)} {(isInstalled ? 1 : 0)} {(isSubscribed ? 1 : 0)} {(releasestate ?? string.Empty).PadRight(11)} {(name ?? string.Empty).PadRight(90)} {(developer ?? string.Empty).PadRight(40)} {(publisher ?? string.Empty).PadRight(40)}\r\n"); if (isSubscribed && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(type)) { apps.Add(new SteamLaunchableApp(chunk.AppID) { Name = name?.TrimEnd(), appIcon = string.IsNullOrWhiteSpace(clienticon) ? null : Path.Combine(SteamProcessInfo.SteamInstallPath, "steam", "games", clienticon + ".ico"), appType = type, extra_developer = developer.ToArray(), extra_publisher = publisher.ToArray(), extra_has_library_capsule = has_library_capsule, extra_has_library_hero = has_library_hero, extra_has_library_logo = has_library_logo, extra_original_release_date = original_release_date, extra_steam_release_date = steam_release_date, });; } } } }); return(apps); }