Ejemplo n.º 1
0
        private static void Main(string[] args)
        {
            Logger.PrintVersion("Cethleann");
            var flags = CommandLineFlags.ParseFlags <DataExporterFlags>(CommandLineFlags.PrintHelp, args);

            if (flags == null)
            {
                return;
            }

            IManagedFS?fs = default;

            if (flags.Flayn)
            {
                fs = new Flayn(flags);
                ((Flayn)fs).LoadPatterns();
                foreach (var gamedir in flags.GameDirs)
                {
                    fs.AddDataFS(gamedir);
                }
            }
            else if (flags.Leonhart)
            {
                fs = new Leonhart(flags);
                foreach (var gamedir in flags.GameDirs)
                {
                    fs.AddDataFS(gamedir);
                }
            }
            else if (flags.Mitsunari)
            {
                fs = new Mitsunari(flags);
                foreach (var gamedir in flags.GameDirs)
                {
                    fs.AddDataFS(gamedir);
                }
            }
            else if (flags.Nyotengu)
            {
                fs = new Nyotengu(flags);
                foreach (var rdb in flags.GameDirs.SelectMany(gamedir => Directory.GetFiles(gamedir, "*.rdb")))
                {
                    fs.AddDataFS(rdb);
                }

                ((Nyotengu)fs).LoadExtList();
            }
            else if (flags.Zhao) // yep it's identical, but filenames are suffixed with .hash
            // so it would try to load RDB BINs in normal installs since those are named .rdb.bin
            {
                fs = new Nyotengu(flags);
                foreach (var rdb in flags.GameDirs.SelectMany(gamedir => Directory.GetFiles(gamedir, "*.rdb.*")))
                {
                    fs.AddDataFS(rdb);
                }

                ((Nyotengu)fs).LoadExtList();
            }
            else if (flags.Reisalin)
            {
                fs = new Reisalin(flags);
                foreach (var gamedir in flags.GameDirs.SelectMany(gameDir => Directory.GetFiles(gameDir, "*.pak")))
                {
                    fs.AddDataFS(gamedir);
                }
            }
            else if (flags.Yshtola)
            {
                YshtolaSettings?settings = flags.GameId switch
                {
                    "DissidiaNT" => new YshtolaDissidiaSettings(),
                    "VenusVacation" => new YshtolaVenusVacationSettings(),
                    _ => default
                };
                if (settings == default)
                {
                    Logger.Error("Cethleann", $"No decryption settings found for {flags.GameId}!");
                    return;
                }

                fs = new Yshtola(flags, settings);
                var yshtola = (Yshtola)fs;
                yshtola.Root = flags.GameDirs.ToArray();
                foreach (var tableName in settings.TableNames)
                {
                    fs.AddDataFS(tableName);
                }
                if (!Directory.Exists(flags.OutputDirectory))
                {
                    Directory.CreateDirectory(flags.OutputDirectory);
                }
                for (var index = 0; index < yshtola.Tables.Count; index++)
                {
                    var table = yshtola.Tables[index];
                    var type  = Path.GetDirectoryName(yshtola.Settings.TableNames[index]);
                    var name  = $"manifest-{type ?? "COMMON"}.{flags.GameId.ToLower()}";
                    File.WriteAllBytes(Path.Combine(flags.OutputDirectory, name), table.Buffer.ToArray());
                }

                if (flags.YshtolaManifestOnly)
                {
                    return;
                }
            }

            if (fs == null)
            {
                Logger.Error("Cethleann", "No FS specified! Prove --flayn, --reisalin, --leonhart, --mitsunari, --nyotengu, or --yshtola!");
                return;
            }

            if (!flags.NoFilelist)
            {
                fs.LoadFileList(flags.FileList);
            }
            if (flags.NyotenguGeneratedFileList && fs is Nyotengu nyotengu)
            {
                nyotengu.SaveGeneratedFileList(flags.FileList);
                return;
            }

            for (var index = 0; index < fs.EntryCount; index++)
            {
                try
                {
                    var data     = fs.ReadEntry(index).Span;
                    var dt       = data.GetDataType();
                    var ext      = UnbundlerLogic.GetExtension(data);
                    var filepath = fs.GetFilename(index, ext, dt) ?? $"{index}.{ext}";
                    while (filepath.StartsWith("\\") || filepath.StartsWith("/"))
                    {
                        filepath = filepath.Substring(1);
                    }
                    if (flags.Reisalin && filepath.EndsWith(".gz", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (data[4] == 0x78)
                        {
                            data = StreamCompression.Decompress(data, new CompressionOptions
                            {
                                Length = -1,
                                Type   = DataCompression.Deflate
                            });
                        }
                        filepath = filepath.Substring(0, filepath.Length - 3);
                    }

                    var pathBase = $@"{flags.OutputDirectory}\{filepath}";
                    UnbundlerLogic.TryExtractBlob(pathBase, data, false, flags, false);
                }
                catch (Exception e)
                {
                    Logger.Error("Cethleann", e);
#if DEBUG
                    throw;
#endif
                }
            }

            fs.Dispose();
        }
Ejemplo n.º 2
0
 /// <summary>
 ///     Load a referenced KTID file
 /// </summary>
 /// <param name="instance"></param>
 /// <param name="nyotengu"></param>
 /// <returns></returns>
 public static Memory <byte> Dereference(this KTIDReference instance, Nyotengu nyotengu) => nyotengu.ReadEntry(instance.KTID);