public bool Run(IFile romFile, out IFileHierarchy hierarchy) { Asserts.Equal( ".iso", romFile .Extension, $"Cannot dump ROM because it is not an ISO: {romFile}"); Asserts.True( romFile.Exists, $"Cannot dump ROM because it does not exist: {romFile}"); var didChange = false; var finalDirectoryPath = romFile.FullNameWithoutExtension; var finalDirectory = new FinDirectory(finalDirectoryPath); if (!finalDirectory.Exists) { didChange = true; this.DumpRom_(romFile); Asserts.True(finalDirectory.Exists, $"Directory was not created: {finalDirectory}"); } hierarchy = new FileHierarchy(finalDirectory); return(didChange); }
public bool Extract(IFileHierarchyFile garFile) { Asserts.True(garFile.Exists, $"Could not extract GAR because it does not exist: {garFile.FullName}"); var directoryPath = StringUtil.UpTo(garFile.FullName, ".gar"); var directory = new FinDirectory(directoryPath); if (directory.Exists) { return(false); } var logger = Logging.Create <ZarExtractor>(); logger.LogInformation($"Extracting GAR {garFile.LocalPath}..."); Gar gar; { using var er = new EndianBinaryReader(garFile.Impl.OpenRead(), Endianness.LittleEndian); gar = new Gar(er); } foreach (var fileType in gar.FileTypes) { foreach (var file in fileType.Files) { var fileName = file.FileName; if (!fileName.EndsWith($".{fileType.TypeName}")) { fileName = $"{fileName}.{fileType.TypeName}"; } var filePath = Path.Join(directoryPath, fileName); Directory.CreateDirectory(Path.GetDirectoryName(filePath) !); File.WriteAllBytes(filePath, file.Bytes); } } garFile.Impl.Info.Delete(); return(true); }
public bool Extract(IFileHierarchyFile zarFile) { Asserts.True(zarFile.Exists, $"Could not extract ZAR because it does not exist: {zarFile.FullName}"); Asserts.Equal(".zar", zarFile.Extension, $"Could not extract file because it is not a ZAR: {zarFile.FullName}"); var directoryPath = zarFile.FullName.Substring(0, zarFile.FullName.Length - ".zar".Length); var directory = new FinDirectory(directoryPath); if (directory.Exists) { return(false); } var logger = Logging.Create <ZarExtractor>(); logger.LogInformation($"Extracting ZAR {zarFile.LocalPath}..."); Zar zar; { using var er = new EndianBinaryReader(zarFile.Impl.OpenRead(), Endianness.LittleEndian); zar = new Zar(er); } foreach (var fileType in zar.FileTypes) { foreach (var file in fileType.Files) { var filePath = Path.Join(directoryPath, file.FileName); Directory.CreateDirectory( Asserts.CastNonnull(Path.GetDirectoryName(filePath))); File.WriteAllBytes(filePath, file.Bytes); } } zarFile.Impl.Info.Delete(); return(true); }
private static void GetFromKando_( string name, out string outputPath, out IList <string> bmdPaths, out IList <string> bcxPaths, out IList <string> btiPaths) { outputPath = Args.GetOutputPath_(name); var kandoDir = new FinDirectory( @"R:\Documents\CSharpWorkspace\Pikmin2Utility\cli\roms\pikmin2\user\Kando"); var entryDir = kandoDir.GetSubdir(name); var modelDir = entryDir.GetSubdir(@"arc.szs 0.rarc_dir\arc"); bmdPaths = Files.GetPathsWithExtension(modelDir, ".bmd", true); bcxPaths = Arrays.Concat( Files.GetPathsWithExtension(modelDir, ".bca", true), Files.GetPathsWithExtension(modelDir, ".bck", true)); btiPaths = Files.GetPathsWithExtension(modelDir, ".bti", true); }
public void Run(string scratchDirectoryPath, string outputDirectoryPath) { string gameDirectory = null; if (OperatingSystem.IsWindows()) { gameDirectory = SteamInterop.GetGameInstallDirectory("HaloWarsDE"); Console.WriteLine( $"Found Halo Wars Definitive Edition install at {gameDirectory}"); } // Point the framework to the game install and working directories var context = new HWContext(gameDirectory, scratchDirectoryPath); // Expand all compressed/encrypted game files. This also handles the .xmb -> .xml conversion context.ExpandAllEraFiles(); var scratchDirectory = new FinDirectory(scratchDirectoryPath); var mapDirectories = scratchDirectory .GetSubdir("scenario/skirmish/design") .GetExistingSubdirs(); var outputDirectory = new FinDirectory(outputDirectoryPath); var baseDstMapDirectory = outputDirectory.GetSubdir("scenario/skirmish/design", true); foreach (var srcMapDirectory in mapDirectories) { var mapName = srcMapDirectory.Name; var dstMapDirectory = baseDstMapDirectory.GetSubdir(mapName, true); var gltfFile = new FinFile( Path.Combine(dstMapDirectory.FullName, $"{mapName}.gltf")); if (gltfFile.Exists) { continue; } var xttFile = srcMapDirectory.GetExistingFiles() .Single(file => file.Extension == ".xtt"); var xtdFile = srcMapDirectory.GetExistingFiles() .Single(file => file.Extension == ".xtd"); var xtt = HWXttResource.FromFile(context, xttFile.FullName); var xtd = HWXtdResource.FromFile(context, xtdFile.FullName); var finModel = xtd.Mesh; var xttMaterial = finModel.MaterialManager.AddStandardMaterial(); xttMaterial.DiffuseTexture = finModel.MaterialManager.CreateTexture( xtt.AlbedoTexture); xttMaterial.DiffuseTexture.Name = $"{mapName}_albedo"; xttMaterial.AmbientOcclusionTexture = finModel.MaterialManager.CreateTexture( xtd.AmbientOcclusionTexture); xttMaterial.AmbientOcclusionTexture.Name = $"{mapName}_ao"; foreach (var primitive in finModel.Skin.Meshes[0].Primitives) { primitive.SetMaterial(xttMaterial); } var exporter = new AssimpIndirectExporter { LowLevel = true }; exporter.Export(gltfFile.CloneWithExtension(".fbx"), finModel); // Cleans up any remaining .bin files. var binFiles = dstMapDirectory.GetExistingFiles() .Where(file => file.Extension == ".bin"); foreach (var binFile in binFiles) { binFile.Info.Delete(); } // Forces an immediate garbage-collection cleanup. This is required to // prevent OOM errors, since Halo Wars maps are just so huge. GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); } var artDirectory = scratchDirectory.GetSubdir("art"); var artSubdirQueue = new FinQueue <IDirectory>(artDirectory); // TODO: Switch to DFS instead, it's more intuitive as a user while (artSubdirQueue.TryDequeue(out var artSubdir)) { // TODO: Skip a file if it's already been extracted // TODO: Parse UGX files instead, as long as they specify their own animations var visFiles = artSubdir.GetExistingFiles() .Where(f => f.Extension == ".vis") .ToList(); foreach (var visFile in visFiles) { var vis = HWVisResource.FromFile(context, visFile.FullName); var finModel = vis.Model; var outFilePath = visFile.FullName.Replace(scratchDirectoryPath, outputDirectoryPath); var outFile = new FinFile(outFilePath).CloneWithExtension(".fbx"); outFile.GetParent().Create(); var exporter = new AssimpIndirectExporter(); exporter.Export(outFile, finModel); Console.WriteLine($"Processed {visFile.FullName}"); } artSubdirQueue.Enqueue(artSubdir.GetExistingSubdirs()); } /*var gls = HWGlsResource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.gls"); * Console.WriteLine($"Processed {gls}"); * * var scn = HWScnResource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.scn"); * PrintScenarioObjects(scn); * Console.WriteLine($"Processed {scn}"); * * var sc2 = HWSc2Resource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.sc2"); * PrintScenarioObjects(sc2); * Console.WriteLine($"Processed {sc2}"); * * var sc3 = HWSc3Resource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.sc3"); * PrintScenarioObjects(sc3); * Console.WriteLine($"Processed {sc3}"); * }*/ }
public bool Run( IFileHierarchyFile rarcFile, bool cleanup, IReadOnlySet <string> junkTerms) { Asserts.True( rarcFile.Impl.Exists, $"Cannot dump RARC because it does not exist: {rarcFile}"); if (!MagicTextUtil.Verify(rarcFile, "RARC")) { return(false); } var directoryPath = rarcFile.FullName + "_dir"; if (!Directory.Exists(directoryPath)) { var logger = Logging.Create <RarcDump>(); logger.LogInformation($"Dumping RARC {rarcFile.LocalPath}..."); Files.RunInDirectory( rarcFile.Impl.GetParent() !, () => { ProcessUtil.ExecuteBlockingSilently( GcnToolsConstants.RARCDUMP_EXE, $"\"{rarcFile.FullName}\""); }); Asserts.True(Directory.Exists(directoryPath), $"Directory was not created: {directoryPath}"); } // Determines final directory path from var directory = new FinDirectory(directoryPath); var subdir = directory.GetExistingSubdirs().Single(); var subdirName = subdir.Name; var isSubdirJunk = junkTerms.Contains(subdirName); var rarcName = rarcFile.NameWithoutExtension; var isRarcJunk = junkTerms.Contains(rarcName); string finalDirectoryName; // If only one is in the junk set, uses the other. if (isSubdirJunk && !isRarcJunk) { finalDirectoryName = rarcName; } else if (!isSubdirJunk && isRarcJunk) { finalDirectoryName = subdirName; } // If subdir has same name or is an abbreviation of the parent, // just collapses them with the parent name. else if ((subdirName.Length <= rarcName.Length && subdirName.ToLower() == rarcName.Substring(0, subdirName.Length).ToLower()) || (junkTerms?.Contains(subdirName) ?? false)) { finalDirectoryName = rarcName; } // If parent has same name or is an abbreviation of the subdir, // just collapses them with the subdir name. else if (subdirName.Length >= rarcName.Length && subdirName.Substring(0, rarcName.Length).ToLower() == rarcName.ToLower()) { finalDirectoryName = subdirName; } // If subdir has a different name, merges their names together and // collapses them. else { finalDirectoryName = $"{rarcName}_{subdirName}"; } var finalDirectoryPath = Path.Join(Path.GetDirectoryName(directoryPath), finalDirectoryName); Asserts.True(!Directory.Exists(finalDirectoryPath)); subdir.MoveTo(finalDirectoryPath); Directory.Delete(directoryPath); if (cleanup) { rarcFile.Impl.Info.Delete(); } return(true); }
public bool Run(IFile romFile, out IFileHierarchy hierarchy) { Asserts.Equal( ".cia", romFile.Extension, $"Cannot dump ROM because it is not a CIA: {romFile}"); Asserts.True( romFile.Exists, $"Cannot dump ROM because it does not exist: {romFile}"); var didChange = false; var finalDirectoryPath = romFile.FullName.Substring(0, romFile.FullName.Length - ".cia".Length); var finalDirectory = new FinDirectory(finalDirectoryPath); if (!finalDirectory.Exists) { didChange = true; var beforeFiles = ThreeDsToolsConstants.HACKING_TOOLKIT_9DS_DIRECTORY .GetExistingFiles() .ToHashSet(); var beforeSubdirs = ThreeDsToolsConstants.HACKING_TOOLKIT_9DS_DIRECTORY .GetExistingSubdirs() .ToHashSet(); var directoryPath = Path.Join( ThreeDsToolsConstants.HACKING_TOOLKIT_9DS_DIRECTORY.FullName, "ExtractedRomFS"); var directory = new FinDirectory(directoryPath); if (!directory.Exists) { this.DumpRom_(romFile); Asserts.True(directory.Exists, $"Failed to find expected HackingToolkit9ds directory:\n{directory}" + "\n\n" + "This is most likely due to not pre-installing " + "HackingToolkit9ds via the installer:\n" + "cli/tools/HackingToolkit9DSv12/SetupUS.exe"); } Directory.Move(directoryPath, finalDirectoryPath); Asserts.True(finalDirectory.Exists, $"Directory was not created: {finalDirectory}"); var afterFiles = ThreeDsToolsConstants.HACKING_TOOLKIT_9DS_DIRECTORY .GetExistingFiles() .ToArray(); var afterSubdirs = ThreeDsToolsConstants.HACKING_TOOLKIT_9DS_DIRECTORY .GetExistingSubdirs() .ToArray(); // Cleans up unneeded files & directories foreach (var afterFile in afterFiles) { if (!beforeFiles.Contains(afterFile)) { afterFile.Info.Delete(); } } foreach (var afterSubdir in afterSubdirs) { if (!beforeSubdirs.Contains(afterSubdir)) { afterSubdir.Info.Delete(true); } } } hierarchy = new FileHierarchy(finalDirectory); return(didChange); }