Example #1
0
        public void TestPsbV4()
        {
            var resPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");
            var path    = Path.Combine(resPath, "dx_ふかみ_駅員服.psb");

            Consts.PsbObjectOrderByKey = false;
            Consts.FastMode            = false;
            //var path = Path.Combine(resPath, "東北ずん子e-mote_ver39(max2048).psb");
            PSB psb = new PSB(path);

            psb.BuildToFile("regenerated.psb");
        }
Example #2
0
        public void TestWin2Krkr2Win()
        {
            var resPath  = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");
            var pathGood = Path.Combine(resPath, "goodstr.freemote.psb");
            var psb      = new PSB(pathGood);

            psb.SwitchSpec(PsbSpec.krkr, PsbSpec.krkr.DefaultPixelFormat());
            psb.Merge();
            psb.SwitchSpec(PsbSpec.win, PsbSpec.win.DefaultPixelFormat());
            psb.Merge();
            psb.BuildToFile("convert2.psb");
        }
Example #3
0
        public void TestGraft2()
        {
            var resPath  = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");
            var pathGood = Path.Combine(resPath, "goodstr.freemote.psb");
            var pathBad  = Path.Combine(resPath, "goodStr.psb");

            var psbGood = new PSB(pathGood);
            var psbBad  = new PSB(pathBad);

            dynamic texGood = (PsbDictionary)psbGood.Objects["source"].Children("tex");
            dynamic texBad  = (PsbDictionary)psbBad.Objects["source"].Children("tex#000");
            var     badIcon = texBad["icon"];

            PsbDictionary newIcon = new PsbDictionary();

            foreach (var part in texGood["icon"])
            {
                var content = part.Value;
                var bi      = ((PsbDictionary)badIcon).FirstOrDefault(i =>
                                                                      ((PsbNumber)i.Value.Children("width")).AsInt == content["width"].AsInt &&
                                                                      ((PsbNumber)i.Value.Children("height")).AsInt == content["height"].AsInt &&
                                                                      ((PsbNumber)i.Value.Children("originX")).AsFloat == content["originX"].AsFloat &&
                                                                      ((PsbNumber)i.Value.Children("originY")).AsFloat == content["originY"].AsFloat);

                if (bi.Key != null)
                {
                    newIcon[bi.Key] = content;
                }
            }

            texGood["icon"] = newIcon;

            dynamic badSource = psbBad.Objects["source"];

            badSource["tex#000"] = texGood;

            psbBad.Merge();
            psbBad.BuildToFile("graft.psb");
        }
Example #4
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.Argb2Rgba(ref bts);
                            break;

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

                        case PsbImageConvertMethod.LeARGB_4To8:
                            bts = RL.Argb428(bts);
                            break;

                        case PsbImageConvertMethod.LeARGB_TO_L8Grayscale:
                            bts = RL.Argb2L8(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);
                        }
                    }
                });
            });

            //command: fix
            app.Command("fix", fixCmd =>
            {
                //help
                fixCmd.Description = "Some mysterious fixes for PSB";
                fixCmd.HelpOption();
                fixCmd.ExtendedHelpText = @"
Example:
  EmtConvert fix -m MetadataBase sample.psb 
";
                //options
                var optMethod = fixCmd.Option <PsbFixMethod>("-m|--method <METHOD>",
                                                             "Set fix method.", CommandOptionType.SingleValue);

                //args
                var argPsbPaths = fixCmd.Argument("PSB", "PSB Paths", true);

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

                    var method = optMethod.ParsedValue;
                    foreach (var s in argPsbPaths.Values)
                    {
                        if (!File.Exists(s))
                        {
                            continue;
                        }

                        switch (method)
                        {
                        case PsbFixMethod.MetadataBase:

                            {
                                Console.Write($"Using {method} to fix {s} ...");
                                PSB psb = new PSB(s);
                                if (psb.FixMotionMetadata())
                                {
                                    psb.BuildToFile(Path.ChangeExtension(s, ".fixed.psb"));
                                    Console.WriteLine("Fixed!");
                                }
                                else
                                {
                                    Console.WriteLine("not fixed.");
                                }
                            }
                            break;

                        default:
                            Console.WriteLine($"Not implemented method: {method}");
                            break;
                        }
                    }
                });
            });

            //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). Usually use 131.",
                                                        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.");
        }