Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }