Пример #1
0
        public void TestDullahanPsb()
        {
            var resPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");
            //var path = Path.Combine(resPath, "e-mote38_KRKR-pure.psb");
            //var path = Path.Combine(resPath, "HD愛子a_春服.psb");
            //var path2 = Path.Combine(resPath, "HD愛子a_春服-pure.psb");
            //var path = Path.Combine(resPath, "akira_guide.psb");
            //var path2 = Path.Combine(resPath, "akira_guide-pure.psb");
            //var path = Path.Combine(resPath, "dx_真闇_裸_impure.psb");
            //var path2 = Path.Combine(resPath, "dx_真闇_裸-pure.psb");
            //var path = Path.Combine(resPath, "emote396-win.psb");
            //var path2 = Path.Combine(resPath, "emote396-win.pure.psb");
            var path  = Path.Combine(resPath, "ca01_l_body_1.psz.psb");
            var path2 = Path.Combine(resPath, "ca01_l_body_1-pure.psb");

            var psb = PSB.DullahanLoad(new FileStream(path, FileMode.Open), 64);
            var p2  = new PsbFile(path2);

            var offset1 = psb.Header.OffsetChunkData;
            var offset2 = p2.Header.OffsetChunkData;

            Assert.AreEqual(offset1, offset2);

            var obj = psb.Objects.First();
            //if (psb.Platform == PsbSpec.krkr)
            //{
            //    psb.SwitchSpec(PsbSpec.win);
            //}
            //psb.Merge();
            //var r = psb.Resources[0].Data.Length;
            //File.WriteAllBytes("Dullahan.psb", psb.Build());
        }
Пример #2
0
        public void TestEncode()
        {
            //Debug.WriteLine(Environment.CurrentDirectory);
            uint targetKey = 504890837; //give your model key
            var  resPath   = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");

            foreach (var file in Directory.EnumerateFiles(resPath))
            {
                if (!file.ToLowerInvariant().EndsWith(".psb"))
                {
                    continue;
                }

                var fileName =
                    Path.GetFileNameWithoutExtension(file).Split(new[] { '-' }, 2); //rename your file as key-name.psb
                if (fileName.Length < 2)
                {
                    continue;
                }

                var key = UInt32.Parse(fileName[0]);
                if (key != targetKey)
                {
                    continue;
                }

                PsbFile psb = new PsbFile(file);
                psb.EncodeToFile(targetKey, file + ".pure", EncodeMode.Encrypt, EncodePosition.Auto);
            }
        }
        public GbaVcExtractor(string dumpPath, PsbFile psbFile)
        {
            string gbaDictionaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GBA_DICTIONARY_CSV_PATH);

            gbaDictionary = new RomNameDictionary(gbaDictionaryPath);

            this.psbFile = psbFile;
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GbaVcExtractor"/> class.
        /// </summary>
        /// <param name="psbFile">PSB file to parse.</param>
        /// <param name="verbose">whether to provide verbose output.</param>
        public GbaVcExtractor(PsbFile psbFile, bool verbose = false)
        {
            this.verbose = verbose;
            string gbaDictionaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GbaDictionaryCsvPath);

            this.gbaDictionary = new RomNameDictionary(gbaDictionaryPath);

            this.psbFile = psbFile;
        }
Пример #5
0
        /// <summary>
        /// Compile Json to PSB
        /// </summary>
        /// <param name="inputJson">Json text</param>
        /// <param name="inputResJson">Resource Json text</param>
        /// <param name="baseDir">If resource Json uses relative paths (usually it does), specify the base dir</param>
        /// <param name="version">PSB version</param>
        /// <param name="cryptKey">CryptKey, if you need to use it outside FreeMote</param>
        /// <param name="spec">PSB Platform</param>
        /// <returns></returns>
        public static byte[] Compile(string inputJson, string inputResJson, string baseDir = null, ushort?version = null, uint?cryptKey = null,
                                     PsbSpec?spec = null)
        {
            //Parse
            PSB psb = Parse(inputJson, version ?? 3);

            //Link
            if (!string.IsNullOrWhiteSpace(inputResJson))
            {
                if (inputResJson.Trim().StartsWith("{")) //resx.json
                {
                    PsbResourceJson resx = JsonConvert.DeserializeObject <PsbResourceJson>(inputResJson);
                    if (resx.PsbType != null)
                    {
                        psb.Type = resx.PsbType.Value;
                    }
                    if (resx.PsbVersion != null && version == null)
                    {
                        psb.Header.Version = resx.PsbVersion.Value;
                    }
                    if (resx.Platform != null && spec == null)
                    {
                        spec = resx.Platform;
                    }
                    if (resx.CryptKey != null & cryptKey == null)
                    {
                        cryptKey = resx.CryptKey;
                    }

                    if (resx.ExternalTextures)
                    {
                        Console.WriteLine("[INFO] External Texture mode ON, no resource will be compiled.");
                    }
                    else
                    {
                        psb.Link(resx, baseDir);
                    }
                }
                else
                {
                    List <string> resources = JsonConvert.DeserializeObject <List <string> >(inputResJson);
                    psb.Link(resources, baseDir);
                }
            }
            //Build
            psb.Merge();
            if (spec != null && spec != psb.Platform)
            {
                psb.SwitchSpec(spec.Value, spec.Value.DefaultPixelFormat());
                psb.Merge();
            }
            var bytes = psb.Build();

            //Convert
            return(cryptKey != null?PsbFile.EncodeToBytes(cryptKey.Value, bytes, EncodeMode.Encrypt, EncodePosition.Auto) : bytes);
        }
Пример #6
0
 static bool Convert(uint?key, string path)
 {
     if (!key.HasValue)
     {
         Console.WriteLine("Key not valid.");
         return(false);
     }
     if (!File.Exists(path))
     {
         Console.WriteLine($"File:{path} not exists.");
         return(false);
     }
     try
     {
         PsbFile psb = new PsbFile(path);
         if (psb.Version > 2)
         {
             if (psb.TestHeaderEncrypted()) //Decrypt
             {
                 psb.EncodeToFile(key.Value, path + ".decrypted", EncodeMode.Decrypt);
             }
             else
             {
                 psb.EncodeToFile(key.Value, path + ".encrypted", EncodeMode.Encrypt);
             }
         }
         else
         {
             if (psb.TestBodyEncrypted()) //Decrypt
             {
                 psb.EncodeToFile(key.Value, path + ".decrypted", EncodeMode.Decrypt);
             }
             else
             {
                 psb.EncodeToFile(key.Value, path + ".encrypted", EncodeMode.Encrypt);
             }
         }
     }
     catch (Exception e)
     {
         Console.WriteLine("Error: This file is not valid.");
         Console.WriteLine(e);
         return(false);
     }
     return(true);
 }
Пример #7
0
        /// <summary>
        /// Save as pure MDF
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] SaveAsMdf(this PSB psb, uint?key = null)
        {
            psb.Merge();
            var     bytes    = psb.Build();
            Adler32 adler    = new Adler32();
            uint    checksum = 0;

            if (key == null)
            {
                adler.Update(bytes);
                checksum = (uint)adler.Checksum;
            }

            MemoryStream ms = new MemoryStream(bytes);

            using (MemoryStream fs = new MemoryStream())
            {
                if (key != null)
                {
                    MemoryStream nms = new MemoryStream((int)ms.Length);
                    PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, ms, nms);
                    ms.Dispose();
                    ms = nms;
                    var pos = ms.Position;
                    adler.Update(ms);
                    checksum    = (uint)adler.Checksum;
                    ms.Position = pos;
                }

                BinaryWriter bw = new BinaryWriter(fs);
                bw.WriteStringZeroTrim(MdfFile.Signature);
                bw.Write((uint)ms.Length);
                //bw.Write(ZlibCompress.Compress(ms));
                ZlibCompress.CompressToBinaryWriter(bw, ms);
                bw.WriteBE(checksum);
                ms.Dispose();
                bw.Flush();
                return(fs.ToArray());
            }
        }
Пример #8
0
        /// <summary>
        /// Save PSB as MDF file
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="path"></param>
        /// <param name="key"></param>
        public static void SaveAsMdfFile(this PSB psb, string path, uint?key = null)
        {
            psb.Merge();
            var     bytes      = psb.Build();
            Adler32 checksumer = new Adler32();
            uint    checksum   = 0;

            if (key == null)
            {
                checksumer.Update(bytes);
                checksum = (uint)checksumer.Checksum;
            }
            MemoryStream ms = new MemoryStream(bytes);

            using (Stream fs = new FileStream(path, FileMode.Create))
            {
                if (key != null)
                {
                    MemoryStream nms = new MemoryStream((int)ms.Length);
                    PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, ms, nms);
                    ms.Dispose();
                    ms = nms;
                    var pos = ms.Position;
                    checksumer.Update(ms);
                    checksum    = (uint)checksumer.Checksum;
                    ms.Position = pos;
                }

                BinaryWriter bw = new BinaryWriter(fs);
                bw.WriteStringZeroTrim(MdfFile.Signature);
                bw.Write((uint)ms.Length);
                bw.Write(ZlibCompress.Compress(ms));
                bw.WriteBE(checksum);
                ms.Dispose();
                bw.Flush();
            }
        }
Пример #9
0
        /// <summary>
        /// Decompile Pure PSB as Json
        /// </summary>
        /// <param name="path"></param>
        /// <param name="psb"></param>
        /// <param name="context"></param>
        /// <param name="psbType"></param>
        /// <returns></returns>
        public static string Decompile(string path, out PSB psb, Dictionary <string, object> context = null, PsbType psbType = PsbType.PSB)
        {
            using var fs = File.OpenRead(path);
            var    ctx    = FreeMount.CreateContext(context);
            string type   = null;
            Stream stream = fs;

            using var ms = ctx.OpenFromShell(fs, ref type);
            if (ms != null)
            {
                ctx.Context[Consts.Context_PsbShellType] = type;
                fs.Dispose();
                stream = ms;
            }

            try
            {
                psb = new PSB(stream, false);
            }
            catch (PsbBadFormatException e) when(e.Reason == PsbBadFormatReason.Header ||
                                                 e.Reason == PsbBadFormatReason.Array ||
                                                 e.Reason == PsbBadFormatReason.Body)  //maybe encrypted
            {
                stream.Position = 0;
                uint?key = null;

                if (ctx.Context.ContainsKey(Consts.Context_CryptKey))
                {
                    key = ctx.Context[Consts.Context_CryptKey] as uint?;
                }
                else
                {
                    key = ctx.GetKey(stream);
                }

                stream.Position = 0;
                if (key != null) //try use key
                {
                    try
                    {
                        using (var mms = new MemoryStream((int)stream.Length))
                        {
                            PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, mms);
                            stream.Dispose();
                            psb = new PSB(mms);
                            ctx.Context[Consts.Context_CryptKey] = key;
                        }
                    }
                    catch
                    {
                        throw e;
                    }
                }
                else //key = null
                {
                    if (e.Reason == PsbBadFormatReason.Header || e.Reason == PsbBadFormatReason.Array) //now try Dullahan loading
                    {
                        psb = PSB.DullahanLoad(stream);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            if (psbType != PsbType.PSB)
            {
                psb.Type = psbType;
            }

            return(Decompile(psb));
        }
Пример #10
0
        /// <summary>
        /// Compile Json to PSB
        /// </summary>
        /// <param name="inputJson">Json text</param>
        /// <param name="inputResJson">Resource Json text</param>
        /// <param name="baseDir">If resource Json uses relative paths (usually it does), specify the base dir</param>
        /// <param name="version">PSB version</param>
        /// <param name="cryptKey">CryptKey, use null for pure PSB</param>
        /// <param name="spec">PSB Platform</param>
        /// <param name="keepShell">If true, try to compress PSB to shell type (MDF/LZ4 etc.) specified in resx.json; otherwise just output PSB</param>
        /// <returns></returns>
        public static byte[] Compile(string inputJson, string inputResJson, string baseDir = null,
                                     ushort?version = null, uint?cryptKey  = null,
                                     PsbSpec?spec   = null, bool keepShell = true)
        {
            var context = FreeMount.CreateContext();
            //Parse
            PSB psb = Parse(inputJson, version ?? 3);

            //Link
            if (!string.IsNullOrWhiteSpace(inputResJson))
            {
                if (inputResJson.Trim().StartsWith("{")) //resx.json
                {
                    PsbResourceJson resx = JsonConvert.DeserializeObject <PsbResourceJson>(inputResJson);
                    if (resx.PsbType != null)
                    {
                        psb.Type = resx.PsbType.Value;
                    }

                    if (resx.PsbVersion != null && version == null)
                    {
                        psb.Header.Version = resx.PsbVersion.Value;
                    }

                    if (resx.Platform != null && spec == null)
                    {
                        spec = resx.Platform;
                    }

                    if (resx.CryptKey != null & cryptKey == null)
                    {
                        cryptKey = resx.CryptKey;
                    }

                    context = FreeMount.CreateContext(resx.Context);

                    if (resx.HasExtraResources)
                    {
                        PsbResHelper.LinkExtraResources(psb, context, resx.ExtraResources, resx.ExtraFlattenArrays, baseDir);
                    }

                    if (resx.ExternalTextures)
                    {
#if DEBUG
                        Console.WriteLine("[INFO] External Texture mode ON, no resource will be compiled.");
#endif
                    }
                    else
                    {
                        psb.Link(resx, baseDir);
                    }
                }
                else
                {
                    List <string> resources = JsonConvert.DeserializeObject <List <string> >(inputResJson);
                    psb.Link(resources, baseDir);
                }
            }

            //Build
            psb.Merge();
            if (spec != null && spec != psb.Platform)
            {
                psb.SwitchSpec(spec.Value, spec.Value.DefaultPixelFormat());
                psb.Merge();
            }

            var bytes = psb.Build();

            //Convert
            if (cryptKey != null)
            {
                bytes = PsbFile.EncodeToBytes(cryptKey.Value, bytes, EncodeMode.Encrypt, EncodePosition.Auto);
            }

            if (context.HasShell && keepShell)
            {
                using var outStream = context.PackToShell(new MemoryStream(bytes));
                bytes = outStream.ToArray();
            }

            return(bytes);
        }
Пример #11
0
        static bool Convert(uint?key, string path)
        {
            if (!File.Exists(path))
            {
                Console.WriteLine($"File:{path} not exists.");
                return(false);
            }

            try
            {
                using (var fs = new FileStream(path, FileMode.Open))
                {
                    Stream stream   = fs;
                    string type     = null;
                    var    ms       = FreeMount.CreateContext().OpenFromShell(fs, ref type);
                    bool   hasShell = false;
                    if (ms != null)
                    {
                        Console.WriteLine($"Shell type: {type}");
                        stream   = ms;
                        hasShell = true;
                    }

                    BinaryReader br = new BinaryReader(stream, Encoding.UTF8);
                    if (!key.HasValue)
                    {
                        var k = FreeMount.CreateContext().GetKey(stream);
                        if (k != null)
                        {
                            key = k;
                            Console.WriteLine($"Using key: {key}");
                        }
                        else if (hasShell)
                        {
                            File.WriteAllBytes(Path.ChangeExtension(path, ".decompressed.psb"), ms.ToArray());
                            return(true);
                        }
                        else
                        {
                            Console.WriteLine("No Key and No Shell.");
                            return(false);
                        }
                    }

                    var header = PsbHeader.Load(br);

                    using (var outMs = new MemoryStream((int)stream.Length))
                    {
                        if (header.Version > 2)
                        {
                            if (PsbFile.TestHeaderEncrypted(stream, header)) //Decrypt
                            {
                                //psb.EncodeToFile(key.Value, path + ".decrypted", EncodeMode.Decrypt);
                                PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".pure.psb"), outMs.ToArray());
                            }
                            else
                            {
                                //psb.EncodeToFile(key.Value, path + ".encrypted", EncodeMode.Encrypt);
                                PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".encrypted.psb"), outMs.ToArray());
                            }
                        }
                        else
                        {
                            if (PsbFile.TestBodyEncrypted(br, header)) //Decrypt
                            {
                                PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".pure.psb"), outMs.ToArray());
                            }
                            else
                            {
                                PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".encrypted.psb"), outMs.ToArray());
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: This file is not valid.");
                Console.WriteLine(e);
                return(false);
            }

            return(true);
        }
Пример #12
0
        static void Main(string[] args)
        {
            Console.WriteLine("FreeMote PSB Converter");
            Console.WriteLine("by Ulysses, [email protected]");
            FreeMount.Init();
            Console.WriteLine($"{FreeMount.PluginsCount} Plugins Loaded.");
            Console.WriteLine();

            var app = new CommandLineApplication();

            app.OptionsComparison = StringComparison.OrdinalIgnoreCase;

            //help
            app.HelpOption();
            app.ExtendedHelpText = PrintHelp();

            //options
            var optKey    = app.Option <uint>("-k|--key <KEY>", "PSB key (uint, dec)", CommandOptionType.SingleValue);
            var optNewKey = app.Option <uint>("-nk|--new-key <KEY>", "New PSB key for transfer (uint, dec)",
                                              CommandOptionType.SingleValue);
            //args
            var argPath =
                app.Argument("Files", "File paths", multipleValues: true);

            //command: pack
            app.Command("pack", packCmd =>
            {
                //help
                packCmd.Description = "Pack/Unpack PSBs to/from shell (FreeMote.Plugins required)";
                packCmd.HelpOption();
                packCmd.ExtendedHelpText = @"
Example:
  EmtConvert pack -s LZ4 sample.psb 
";
                //options
                var optType = packCmd.Option("-s|--shell <SHELL>",
                                             "Set shell type. No need to specify if unpack",
                                             CommandOptionType.SingleValue);
                //args
                var argPsbPaths = packCmd.Argument("PSB", "MDF/PSB Paths", true);

                packCmd.OnExecute(() =>
                {
                    string type = optType.HasValue() ? optType.Value() : null;
                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            ShellConvert(s, type);
                        }
                    }
                });
            });

            //command: print
            app.Command("print", printCmd =>
            {
                //help
                printCmd.Description = "Print an EMT PSB (for its initial state, don't expect it working)";
                printCmd.HelpOption();
                printCmd.ExtendedHelpText = @"
Example:
  EmtConvert print -w 4096 -h 4096 sample.psb 
";
                //options
                var optWidth = printCmd.Option <int>("-w|--width <INT>",
                                                     "Set width. Default=-1 (auto)",
                                                     CommandOptionType.SingleValue);
                var optHeight = printCmd.Option <int>("-h|--height <INT>",
                                                      "Set height. Default=-1 (auto)",
                                                      CommandOptionType.SingleValue);
                //args
                var argPsbPaths = printCmd.Argument("PSB", "MDF/PSB Paths", true);

                printCmd.OnExecute(() =>
                {
                    int width  = optWidth.HasValue() ? optWidth.ParsedValue : -1;
                    int height = optHeight.HasValue() ? optHeight.ParsedValue : -1;
                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            Draw(s, width, height);
                        }
                    }
                });
            });

            //mdf
            app.Command("mdf", mdfCmd =>
            {
                //help
                mdfCmd.Description = "Pack/Unpack MT19937 encrypted MDF (FreeMote.Plugins required)";
                mdfCmd.HelpOption();
                mdfCmd.ExtendedHelpText = @"
Example:
  EmtConvert mdf -k 1234567890ab -l 131 sample.psb 
  EmtConvert mdf -s 1234567890absample.psb -l 131 sample.psb 
  Hint: To pack a normal MDF, use `EmtConvert pack -s MDF <MDF file>`
";
                //options
                //var optMdfPack = mdfCmd.Option("-p|--pack",
                //    "Pack (Encrypt) a PSB to MT19937 MDF",
                //    CommandOptionType.NoValue);
                var optMdfSeed = mdfCmd.Option("-s|--seed <SEED>",
                                               "Set complete seed (Key+FileName)",
                                               CommandOptionType.SingleValue);
                var optMdfKey = mdfCmd.Option("-k|--key <KEY>",
                                              "Set key (Infer file name from path)",
                                              CommandOptionType.SingleValue);
                var optMdfKeyLen = mdfCmd.Option <uint>("-l|--length <LEN>",
                                                        "Set key length (not required if decrypt all bytes)",
                                                        CommandOptionType.SingleValue);
                //args
                var argPsbPaths = mdfCmd.Argument("PSB", "PSB Paths", true);

                mdfCmd.OnExecute(() =>
                {
                    string key  = optMdfKey.HasValue() ? optMdfKey.Value() : null;
                    string seed = optMdfSeed.HasValue() ? optMdfSeed.Value() : null;
                    if (string.IsNullOrEmpty(key) && string.IsNullOrEmpty(seed))
                    {
                        throw new ArgumentNullException(nameof(key), "No key or seed specified.");
                    }

                    uint?keyLen = optMdfKeyLen.HasValue() ? optMdfKeyLen.ParsedValue : (uint?)null;
                    Dictionary <string, object> context = new Dictionary <string, object>();
                    if (keyLen.HasValue)
                    {
                        context["MdfKeyLength"] = keyLen;
                    }

                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            var fileName     = Path.GetFileName(s);
                            string finalSeed = seed;
                            if (key != null)
                            {
                                finalSeed = key + fileName;
                            }

                            context["MdfKey"] = finalSeed;
                            ShellConvert(s, "MDF", context);
                        }
                    }
                });
            });

            app.OnExecute(() =>
            {
                uint?key    = optKey.HasValue() ? optKey.ParsedValue : (uint?)null;
                uint?newKey = optNewKey.HasValue() ? optNewKey.ParsedValue : (uint?)null;

                foreach (var s in argPath.Values)
                {
                    if (File.Exists(s))
                    {
                        if (key != null && newKey != null) //Transfer
                        {
                            File.WriteAllBytes(Path.ChangeExtension(s, ".converted.psb"),
                                               PsbFile.Transfer(key.Value, newKey.Value, File.ReadAllBytes(s)));
                        }
                        else
                        {
                            Convert(key, s);
                        }
                    }
                }
            });

            if (args.Length == 0)
            {
                app.ShowHelp();
                Console.WriteLine("Convert all PSBs in current directory:");
                AskForKey();
                AskForNewKey();

                DirectoryInfo di    = new DirectoryInfo(Environment.CurrentDirectory);
                uint          count = 0;
                foreach (var file in di.EnumerateFiles("*.psb"))
                {
                    if (NewKey != null)
                    {
                        try
                        {
                            File.WriteAllBytes(Path.ChangeExtension(file.FullName, ".converted.psb"),
                                               PsbFile.Transfer(Key.Value, NewKey.Value, File.ReadAllBytes(file.FullName)));
                            count++;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Error: This file is not valid.");
                            Console.WriteLine(e);
                        }
                    }
                    else
                    {
                        if (Convert(Key, file.FullName))
                        {
                            count++;
                        }
                    }
                }

                Console.WriteLine($"Completed! {count} files processed in total.");
                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
                return;
            }

            app.Execute(args);

            Console.WriteLine("Done.");
        }
Пример #13
0
        static void Main(string[] args)
        {
            Console.WriteLine("FreeMote PSB Converter");
            Console.WriteLine("by Ulysses, [email protected]");
            FreeMount.Init();
            Console.WriteLine($"{FreeMount.PluginsCount} Plugins Loaded.");
            Console.WriteLine();

            var app = new CommandLineApplication();

            app.OptionsComparison = StringComparison.OrdinalIgnoreCase;

            //help
            app.HelpOption();
            app.ExtendedHelpText = PrintHelp();

            //options
            var optKey    = app.Option <uint>("-k|--key <KEY>", "PSB key (uint, dec)", CommandOptionType.SingleValue);
            var optNewKey = app.Option <uint>("-nk|--new-key <KEY>", "New PSB key for transfer (uint, dec)",
                                              CommandOptionType.SingleValue);
            //args
            var argPath =
                app.Argument("Files", "File paths", multipleValues: true);

            //command: pixel
            app.Command("pixel", pixelCmd =>
            {
                //help
                pixelCmd.Description = "Convert pixel colors of extracted images (RGBA BMP/PNG)";
                pixelCmd.HelpOption();
                pixelCmd.ExtendedHelpText = @"
Example:
  EmtConvert pixel -m Switch02 sample.png
";
                //options
                var optMethod = pixelCmd.Option <PsbImageConvertMethod>("-m|--method <METHOD>",
                                                                        "Set convert method",
                                                                        CommandOptionType.SingleValue);

                //args
                var argPaths = pixelCmd.Argument("Image", "Image Paths", true);

                pixelCmd.OnExecute(() =>
                {
                    if (!optMethod.HasValue())
                    {
                        Console.WriteLine("Convert Method is not specified!");
                        return;
                    }

                    foreach (var path in argPaths.Values)
                    {
                        if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
                        {
                            continue;
                        }

                        int width  = 0;
                        int height = 0;
                        PixelFormat pixelFormat = PixelFormat.Format32bppArgb;
                        try
                        {
                            var img     = Image.FromFile(path);
                            width       = img.Width;
                            height      = img.Height;
                            pixelFormat = img.PixelFormat;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            continue;
                        }

                        var bts = RL.GetPixelBytesFromImageFile(path);

                        switch (optMethod.ParsedValue)
                        {
                        case PsbImageConvertMethod.Switch02:
                            RL.Switch_0_2(ref bts);
                            break;

                        case PsbImageConvertMethod.ROR:
                            RL.Rgba2Argb(ref bts);
                            break;

                        case PsbImageConvertMethod.ROL:
                            RL.Rgba2Argb(ref bts, true);
                            break;

                        case PsbImageConvertMethod.RGBA428:
                            bts = RL.Rgba428(bts);
                            break;

                        case PsbImageConvertMethod.RGBA2L8Grayscale:
                            bts = RL.Rgba2L8(bts);
                            bts = RL.ReadL8(bts, height, width);
                            break;

                        case PsbImageConvertMethod.Untile:
                            bts = PostProcessing.UntileTexture(bts, width, height, pixelFormat);
                            break;

                        case PsbImageConvertMethod.Unswizzle:
                            bts = PostProcessing.UnswizzleTexture(bts, width, height, pixelFormat);
                            break;

                        case PsbImageConvertMethod.Tile:
                            bts = PostProcessing.TileTexture(bts, width, height, pixelFormat);
                            break;

                        case PsbImageConvertMethod.Swizzle:
                            bts = PostProcessing.SwizzleTexture(bts, width, height, pixelFormat);
                            break;

                        default:
                            continue;
                        }

                        RL.ConvertToImageFile(bts, Path.ChangeExtension(path, ".converted.png"), height, width, PsbImageFormat.png);
                    }
                });
            });

            //command: pack
            app.Command("pack", packCmd =>
            {
                //help
                packCmd.Description = "Pack/Unpack PSBs to/from shell (FreeMote.Plugins required)";
                packCmd.HelpOption();
                packCmd.ExtendedHelpText = @"
Example:
  EmtConvert pack -s LZ4 sample.psb 
";
                //options
                var optType = packCmd.Option("-s|--shell <SHELL>",
                                             "Set shell type. No need to specify if unpack",
                                             CommandOptionType.SingleValue);
                //args
                var argPsbPaths = packCmd.Argument("PSB", "MDF/PSB Paths", true);

                packCmd.OnExecute(() =>
                {
                    string type = optType.HasValue() ? optType.Value() : null;
                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            ShellConvert(s, type);
                        }
                    }
                });
            });

            //command: print
            app.Command("print", printCmd =>
            {
                //help
                printCmd.Description = "Print an EMT PSB (for its initial state, don't expect it working)";
                printCmd.HelpOption();
                printCmd.ExtendedHelpText = @"
Example:
  EmtConvert print -w 4096 -h 4096 sample.psb 
";
                //options
                var optWidth = printCmd.Option <int>("-w|--width <INT>",
                                                     "Set width. Default=-1 (auto)",
                                                     CommandOptionType.SingleValue);
                var optHeight = printCmd.Option <int>("-h|--height <INT>",
                                                      "Set height. Default=-1 (auto)",
                                                      CommandOptionType.SingleValue);
                //args
                var argPsbPaths = printCmd.Argument("PSB", "MDF/PSB Paths", true);

                printCmd.OnExecute(() =>
                {
                    int width  = optWidth.HasValue() ? optWidth.ParsedValue : -1;
                    int height = optHeight.HasValue() ? optHeight.ParsedValue : -1;
                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            Draw(s, width, height);
                        }
                    }
                });
            });

            //mdf
            app.Command("mdf", mdfCmd =>
            {
                //help
                mdfCmd.Description = "Pack/Unpack MT19937 encrypted MDF (FreeMote.Plugins required)";
                mdfCmd.HelpOption();
                mdfCmd.ExtendedHelpText = @"
Example:
  EmtConvert mdf -k 1234567890ab -l 131 sample.psb 
  EmtConvert mdf -s 1234567890absample.psb -l 131 sample.psb 
  Hint: To pack a pure MDF, use `EmtConvert pack -s MDF <MDF file>`
";
                //options
                //var optMdfPack = mdfCmd.Option("-p|--pack",
                //    "Pack (Encrypt) a PSB to MT19937 MDF",
                //    CommandOptionType.NoValue);
                var optMdfSeed = mdfCmd.Option("-s|--seed <SEED>",
                                               "Set complete seed (Key+FileName)",
                                               CommandOptionType.SingleValue);
                var optMdfKey = mdfCmd.Option("-k|--key <KEY>",
                                              "Set key (Infer file name from path)",
                                              CommandOptionType.SingleValue);
                var optMdfKeyLen = mdfCmd.Option <uint>("-l|--length <LEN>",
                                                        "Set key length (not required if decrypt all bytes)",
                                                        CommandOptionType.SingleValue);
                //args
                var argPsbPaths = mdfCmd.Argument("PSB", "PSB Paths", true);

                mdfCmd.OnExecute(() =>
                {
                    string key  = optMdfKey.HasValue() ? optMdfKey.Value() : null;
                    string seed = optMdfSeed.HasValue() ? optMdfSeed.Value() : null;
                    if (string.IsNullOrEmpty(key) && string.IsNullOrEmpty(seed))
                    {
                        //throw new ArgumentNullException(nameof(key), "No key or seed specified.");
                        Console.WriteLine("No key or seed specified. Packing to pure MDF.");

                        foreach (var s in argPsbPaths.Values)
                        {
                            if (File.Exists(s))
                            {
                                ShellConvert(s, "MDF");
                            }
                        }
                        return;
                    }

                    Dictionary <string, object> context = new Dictionary <string, object>();
                    uint?keyLen = optMdfKeyLen.HasValue() ? optMdfKeyLen.ParsedValue : (uint?)null;
                    if (keyLen.HasValue)
                    {
                        context[Context_MdfKeyLength] = keyLen;
                    }

                    foreach (var s in argPsbPaths.Values)
                    {
                        if (File.Exists(s))
                        {
                            var fileName     = Path.GetFileName(s);
                            string finalSeed = seed;
                            if (key != null)
                            {
                                finalSeed = key + fileName;
                            }

                            context[Context_MdfKey] = finalSeed;
                            ShellConvert(s, "MDF", context);
                        }
                    }
                });
            });

            app.OnExecute(() =>
            {
                uint?key    = optKey.HasValue() ? optKey.ParsedValue : (uint?)null;
                uint?newKey = optNewKey.HasValue() ? optNewKey.ParsedValue : (uint?)null;

                foreach (var s in argPath.Values)
                {
                    if (File.Exists(s))
                    {
                        if (key != null && newKey != null) //Transfer
                        {
                            File.WriteAllBytes(Path.ChangeExtension(s, ".converted.psb"),
                                               PsbFile.Transfer(key.Value, newKey.Value, File.ReadAllBytes(s)));
                        }
                        else
                        {
                            Convert(key, s);
                        }
                    }
                }
            });

            if (args.Length == 0)
            {
                app.ShowHelp();
                Console.WriteLine("Convert all PSBs in current directory:");
                AskForKey();
                AskForNewKey();

                DirectoryInfo di    = new DirectoryInfo(Environment.CurrentDirectory);
                uint          count = 0;
                foreach (var file in di.EnumerateFiles("*.psb"))
                {
                    if (NewKey != null)
                    {
                        try
                        {
                            File.WriteAllBytes(Path.ChangeExtension(file.FullName, ".converted.psb"),
                                               PsbFile.Transfer(Key.Value, NewKey.Value, File.ReadAllBytes(file.FullName)));
                            count++;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Error: This file is not valid.");
                            Console.WriteLine(e);
                        }
                    }
                    else
                    {
                        if (Convert(Key, file.FullName))
                        {
                            count++;
                        }
                    }
                }

                Console.WriteLine($"Completed! {count} files processed in total.");
                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
                return;
            }

            app.Execute(args);

            Console.WriteLine("Done.");
        }
Пример #14
0
        static void Main(string[] args)
        {
            Console.WriteLine("FreeMote PSB Converter");
            Console.WriteLine("by Ulysses, [email protected]");
            Console.WriteLine();
            if (args.Length >= 3)
            {
                if (!File.Exists(args[0]))
                {
                    Console.WriteLine("File not exists.");
                    return;
                }
                uint key;
                if (!uint.TryParse(args[1], out key))
                {
                    Console.WriteLine("Key is not valid.");
                    return;
                }
                Key = key;
                if (!uint.TryParse(args[2], out key))
                {
                    Console.WriteLine("New key is not valid.");
                    return;
                }
                NewKey = key;
                byte[] bytes = File.ReadAllBytes(args[0]);
                File.WriteAllBytes(args[0] + ".converted", PsbFile.Transfer(Key.Value, NewKey.Value, bytes));
            }
            else if (args.Length == 2)
            {
                if (!File.Exists(args[0]))
                {
                    Console.WriteLine("File not exists.");
                    return;
                }
                uint key;
                if (!uint.TryParse(args[1], out key))
                {
                    Console.WriteLine("Key is not valid.");
                    return;
                }
                Key = key;
                Convert(Key, args[0]);
            }
            else if (args.Length == 1)
            {
                if (!File.Exists(args[0]))
                {
                    PrintHelp();
                    return;
                }
                AskForKey();
                Convert(Key, args[0]);
            }
            else
            {
                PrintHelp();
                AskForKey();
                AskForNewKey();

                DirectoryInfo di    = new DirectoryInfo(Environment.CurrentDirectory);
                uint          count = 0;
                foreach (var file in di.EnumerateFiles("*.psb"))
                {
                    if (NewKey != null)
                    {
                        try
                        {
                            File.WriteAllBytes(file.FullName + ".converted", PsbFile.Transfer(Key.Value, NewKey.Value, File.ReadAllBytes(file.FullName)));
                            count++;
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Error: This file is not valid.");
                            Console.WriteLine(e);
                        }
                    }
                    else
                    {
                        if (Convert(Key, file.FullName))
                        {
                            count++;
                        }
                    }
                }
                Console.WriteLine($"Completed! {count} files processed in total.");
                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
            }
        }
Пример #15
0
        static void Main(string[] args)
        {
            if (args.Length == 0 || args.Length > 2)
            {
                PrintUsage();
                return;
            }

            if (args.Length == 1)
            {
                if (args[0] == "--version")
                {
                    PrintVersion();
                    return;
                }
            }

            bool verbose = false;

            if (args[0] == "-v")
            {
                verbose = true;
                Console.WriteLine("Verbose output mode is set");
            }

            string sourcePath = args[args.Length - 1];

            if (verbose)
            {
                Console.WriteLine("Source extract file is " + Path.GetFullPath(sourcePath));
            }

            if (!File.Exists(sourcePath))
            {
                Console.WriteLine("Could not find file at " + sourcePath + ". Please ensure that your filename is correct.");
                return;
            }

            Console.WriteLine("============================================================================");
            Console.WriteLine("Starting extraction of rom from " + sourcePath + "...");
            Console.WriteLine("============================================================================");

            string extractedRomPath = "";

            RpxFile rpxFile = null;
            PsbFile psbFile = null;
            PkgFile pkgFile = null;
            SrlFile srlFile = null;

            // Identifies filetype of the file argument,
            // then instantiates file with file's location and verbose
            if (RpxFile.IsRpx(sourcePath))
            {
                Console.WriteLine("RPX file detected!");
                rpxFile = new RpxFile(sourcePath, verbose);
            }
            else if (PsbFile.IsPsb(sourcePath))
            {
                Console.WriteLine("PSB file detected!");
                psbFile = new PsbFile(sourcePath, verbose);
            }
            else if (PkgFile.IsPkg(sourcePath))
            {
                pkgFile = new PkgFile(sourcePath, verbose);
            }
            else if (SrlFile.IsSrl(sourcePath))
            {
                Console.WriteLine("SRL file detected!");
                srlFile = new SrlFile(sourcePath, verbose);
            }

            // Create the list of rom extractors
            List <IRomExtractor> romExtractors = new List <IRomExtractor>();

            if (rpxFile != null)
            {
                romExtractors.Add(new NesVcExtractor(rpxFile, verbose));
                romExtractors.Add(new SnesVcExtractor(rpxFile.DecompressedPath, verbose));
                romExtractors.Add(new FdsVcExtractor(rpxFile, verbose));
            }
            else if (psbFile != null)
            {
                romExtractors.Add(new GbaVcExtractor(psbFile, verbose));
            }
            else if (pkgFile != null)
            {
                romExtractors.Add(new PceVcExtractor(pkgFile, verbose));
            }
            else if (Path.GetExtension(sourcePath) == ".sfrom")
            {
                romExtractors.Add(new SnesVcExtractor(sourcePath, verbose));
            }
            else if (srlFile != null)
            {
                romExtractors.Add(new DsVcExtractor(srlFile, verbose));
            }

            // Check with each extractor until a valid rom is found,
            // Then extract the rom with the appropriate extractor
            foreach (var romExtractor in romExtractors)
            {
                if (romExtractor.IsValidRom())
                {
                    extractedRomPath = romExtractor.ExtractRom();
                    break;
                }
            }

            if (!String.IsNullOrEmpty(extractedRomPath))
            {
                Console.WriteLine("============================================================================");
                Console.WriteLine(sourcePath + " has been extracted to " + extractedRomPath + " successfully.");
                Console.WriteLine("============================================================================");
            }
            else
            {
                Console.WriteLine("============================================================================");
                Console.WriteLine("FAILURE: Could not successfully identify the rom type for " + sourcePath);
                Console.WriteLine("============================================================================");
            }
        }
Пример #16
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                PrintUsage();
                return;
            }

            string sourcePath = args[0];

            if (!File.Exists(sourcePath))
            {
                Console.WriteLine("Could not find file at " + sourcePath + ". Please ensure that your filename is correct.");
                return;
            }

            Console.WriteLine("============================================================================");
            Console.WriteLine("Starting extraction of rom from " + sourcePath + "...");
            Console.WriteLine("============================================================================");

            string extractedRomPath = "";

            RpxFile rpxFile = null;
            PsbFile psbFile = null;

            if (RpxFile.IsRpx(sourcePath))
            {
                Console.WriteLine("RPX file detected!");
                rpxFile = new RpxFile(sourcePath);
            }
            else if (PsbFile.IsPsb(sourcePath))
            {
                Console.WriteLine("PSB file detected!");
                psbFile = new PsbFile(sourcePath);
            }


            // Create the list of rom extractors
            List <IRomExtractor> romExtractors = new List <IRomExtractor>();

            if (rpxFile != null)
            {
                romExtractors.Add(new NesVcExtractor(sourcePath, rpxFile));
                romExtractors.Add(new SnesVcExtractor(sourcePath, rpxFile));
            }
            else if (psbFile != null)
            {
                romExtractors.Add(new GbaVcExtractor(sourcePath, psbFile));
            }

            foreach (var romExtractor in romExtractors)
            {
                if (romExtractor.IsValidRom())
                {
                    extractedRomPath = romExtractor.ExtractRom();
                    break;
                }
            }

            if (!String.IsNullOrEmpty(extractedRomPath))
            {
                Console.WriteLine("============================================================================");
                Console.WriteLine(sourcePath + " has been extracted to " + extractedRomPath + " successfully.");
                Console.WriteLine("============================================================================");
            }
            else
            {
                Console.WriteLine("============================================================================");
                Console.WriteLine("FAILURE: Could not successfully identify the rom type for " + sourcePath);
                Console.WriteLine("============================================================================");
            }
        }