public static int Main(string[] args) { Console.WriteLine("Exporting!"); var vpkPath = @"C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\dota\pak01_dir.vpk"; //var heroName = "npc_dota_hero_void_spirit"; var vpkLoader = BasicVpkFileLoader.FromVpk(vpkPath); var modelPaths = new List <string>(); //var heroInfos = HeroInfo.LoadFromVpk(vpkLoader); //var heroInfo = heroInfos.FirstOrDefault(h => h.LocalizedName == heroName); //modelPaths.Add(heroInfo.ModelPath); //modelPaths.AddRange(heroInfo.Cosmetics.Where(item => item.IsDefault && !item.ModelPath.Contains("persona")).Select(item => item.ModelPath)); modelPaths = new List <string> { "models/heroes/bristleback/bristleback.vmdl", "models/heroes/bristleback/bristleback_back.vmdl", "models/heroes/bristleback/bristleback_head.vmdl", "models/heroes/bristleback/bristleback_weapon.vmdl", "models/heroes/bristleback/bristleback_bracer.vmdl", "models/heroes/bristleback/bristleback_necklace.vmdl", }; var exporter = new ObjExporter(vpkLoader); exporter.ExportModelsAsObj(modelPaths.Select(path => { var resource = vpkLoader.LoadFile(path); if (resource.ResourceType != ResourceType.Model) { throw new ArgumentException("Passed in path must be a path to a model"); } return((Model)resource.DataBlock); }).ToList()); return(0); }
private void DumpVPK(Package package, string type) { if (ExtFilterList != null && !ExtFilterList.Contains(type)) { return; } if (!package.Entries.ContainsKey(type)) { Console.WriteLine("There are no files of type \"{0}\".", type); return; } var fileLoader = new BasicVpkFileLoader(package); var entries = package.Entries[type]; foreach (var file in entries) { var extension = type; var filePath = FixPathSlashes(file.GetFullPath()); if (FileFilter != null && !filePath.StartsWith(FileFilter, StringComparison.Ordinal)) { continue; } if (OutputFile != null) { if (CachedManifest && OldPakManifest.TryGetValue(filePath, out var oldCrc32) && oldCrc32 == file.CRC32) { continue; } OldPakManifest[filePath] = file.CRC32; } Console.WriteLine("\t[archive index: {0:D3}] {1}", file.ArchiveIndex, filePath); package.ReadEntry(file, out var output); if (type.EndsWith("_c", StringComparison.Ordinal) && Decompile) { using var resource = new Resource(); using var memory = new MemoryStream(output); try { resource.Read(memory); extension = FileExtract.GetExtension(resource); if (extension == null) { extension = type.Substring(0, type.Length - 2); } // TODO: Hook this up in FileExtract if (resource.ResourceType == ResourceType.Mesh || resource.ResourceType == ResourceType.Model) { var outputExtension = GltfExportFormat; var outputFile = Path.Combine(OutputFile, Path.ChangeExtension(filePath, outputExtension)); Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); var exporter = new GltfModelExporter { ExportMaterials = GltfExportMaterials, ProgressReporter = new ConsoleProgressReporter(), FileLoader = fileLoader }; if (resource.ResourceType == ResourceType.Mesh) { exporter.ExportToFile(file.GetFileName(), outputFile, new Mesh(resource)); } else if (resource.ResourceType == ResourceType.Model) { exporter.ExportToFile(file.GetFileName(), outputFile, (Model)resource.DataBlock); } continue; } output = FileExtract.Extract(resource).ToArray(); } catch (Exception e) { File.AppendAllText("exceptions.txt", $"---------------\nFile: {filePath}\nException: {e}\n\n"); lock (ConsoleWriterLock) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("\t" + e.Message + " on resource type " + type + ", extracting as-is"); Console.ResetColor(); } } } if (OutputFile != null) { if (type != extension) { filePath = Path.ChangeExtension(filePath, extension); } DumpFile(filePath, output); } } }