private static void VerifyApp(SteamClientUtils steamClient, string appManifestPath, bool deleteUnknownFiles) { Console.WriteLine($"Parsing {appManifestPath}"); var kv = KeyValue.LoadAsText(appManifestPath); var mountedDepots = kv["MountedDepots"]; var gamePath = Path.Join(Path.GetDirectoryName(appManifestPath), "common", kv["installdir"].Value); if (!Directory.Exists(gamePath)) { throw new DirectoryNotFoundException($"Game not found: {gamePath}"); } Console.WriteLine($"Scanning {gamePath}"); var allKnownDepotFiles = new Dictionary <string, ulong>(); foreach (var mountedDepot in mountedDepots.Children) { var manifestPath = Path.Join(steamClient.SteamPath, "depotcache", $"{mountedDepot.Name}_{mountedDepot.Value}.manifest"); if (!File.Exists(manifestPath)) { Console.Error.WriteLine($"Manifest does not exist: {manifestPath}"); continue; } var manifest = DepotManifest.Deserialize(File.ReadAllBytes(manifestPath)); foreach (var file in manifest.Files) { if (file.Flags.HasFlag(EDepotFileFlag.Directory)) { continue; } allKnownDepotFiles[file.FileName] = file.TotalSize; } Console.WriteLine($"{manifestPath} - {manifest.Files.Count} files"); } Console.WriteLine($"{allKnownDepotFiles.Count} files in depot manifests"); var filesOnDisk = Directory.GetFiles(gamePath, "*", SearchOption.AllDirectories).ToList(); filesOnDisk.Sort(); Console.WriteLine($"{filesOnDisk.Count} files on disk"); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Red; var filenamesOnDisk = new HashSet <string>(); foreach (var file in filesOnDisk) { var unprefixedPath = file.Substring(gamePath.Length + 1); filenamesOnDisk.Add(unprefixedPath); if (unprefixedPath == "installscript.vdf") { continue; } if (!allKnownDepotFiles.ContainsKey(unprefixedPath)) { Console.Write($"Unknown file: {unprefixedPath}"); if (deleteUnknownFiles && !InsideWhitelist(file)) { try { File.Delete(file); Console.Write(" -> [Deleted]"); } catch (Exception ex) { Console.WriteLine("Unable to delete!"); Console.WriteLine(ex); } } Console.WriteLine(); continue; } var length = new FileInfo(file).Length; if (allKnownDepotFiles[unprefixedPath] != (ulong)length) { Console.WriteLine($"Mismatching file size: {unprefixedPath} (is {length} bytes, should be {allKnownDepotFiles[unprefixedPath]})"); continue; } } foreach (var file in allKnownDepotFiles.Keys.Where(file => !filenamesOnDisk.Contains(file))) { Console.WriteLine($"Missing file: {file}"); } Console.ResetColor(); }
public List <DLC> GetInstalledDLCFiles() { List <DLC> dlcList = new List <DLC>(); if (AppManifestPath != null && File.Exists(AppManifestPath)) { KeyValue appManifest = KeyValue.LoadAsText(AppManifestPath); Dictionary <string, string> depotManifests = new Dictionary <string, string>(); foreach (KeyValue mountedDepot in appManifest["MountedDepots"].Children) { depotManifests[mountedDepot.Name] = mountedDepot.Value; } foreach (KeyValue mountedDepot in appManifest["InstalledDepots"].Children) { depotManifests[mountedDepot.Name] = mountedDepot["manifest"].Value; } foreach (KeyValuePair <string, string> depotManifest in depotManifests) { uint dlcappid = Convert.ToUInt32(depotManifest.Key); string manifestPath = Path.Combine(SteamPath, "depotcache", $"{dlcappid}_{depotManifest.Value}.manifest"); if (File.Exists(manifestPath)) { DLC dlc = new DLC(dlcappid); DepotManifest manifest = DepotManifest.Deserialize(File.ReadAllBytes(manifestPath)); foreach (DepotManifest.FileData file in manifest.Files) { if (file.Flags.HasFlag(EDepotFileFlag.Directory)) { continue; } string fileName = file.FileName.ToLower(); string extension = Path.GetExtension(fileName).ToLower(); if (fileName.Contains("assets")) { if (extension.Contains("xml") || extension.Contains("bin")) { dlc.IncludedFiles.Add(NormalizePath(GetRelativePath(Path.Combine(RWPath, "Assets"), Path.Combine(RWPath, fileName)))); } if (extension == ".ap") { string absoluteFileName = Path.Combine(RWPath, fileName); try { ZipArchive zipFile = ZipFile.OpenRead(absoluteFileName); dlc.IncludedFiles.AddRange(from x in zipFile.Entries where (x.FullName.Contains(".xml") || x.FullName.Contains(".bin")) select NormalizePath(GetRelativePath(Path.Combine(RWPath, "Assets"), Path.Combine(Path.GetDirectoryName(absoluteFileName), x.FullName)))); } catch { } } } } dlcList.Add(dlc); } } } return(dlcList); }