Example #1
0
        public Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                           PsbExtractOption extractOption = PsbExtractOption.Original)
        {
            var resources = psb.CollectResources <AudioMetadata>();
            Dictionary <string, string> resDictionary = new Dictionary <string, string>();

            if (extractOption == PsbExtractOption.Original)
            {
                for (int i = 0; i < psb.Resources.Count; i++)
                {
                    var relativePath = psb.Resources[i].Index == null ? $"#{i}.raw" : $"{psb.Resources[i].Index}.raw";

                    File.WriteAllBytes(
                        Path.Combine(dirPath, relativePath),
                        psb.Resources[i].Data);
                    resDictionary.Add(Path.GetFileNameWithoutExtension(relativePath), $"{name}/{relativePath}");
                }
            }
            else
            {
                foreach (var resource in resources)
                {
                    if (resource.ChannelList.Count == 1)
                    {
                        var bts          = resource.ChannelList[0].TryToWave(context);
                        var relativePath = resource.GetFileName(resource.ChannelList[0].WaveExtension); //WaveExtension may change after ToWave
                        if (bts != null)
                        {
                            File.WriteAllBytes(Path.Combine(dirPath, relativePath), bts);
                            resDictionary.Add(resource.Name, $"{name}/{relativePath}");
                        }
                    }
                    else if (resource.ChannelList.Count > 1)
                    {
                        for (var j = 0; j < resource.ChannelList.Count; j++)
                        {
                            var waveChannel  = resource.ChannelList[j];
                            var bts          = waveChannel.TryToWave(context);
                            var relativePath = resource.GetFileName($"-{j}{waveChannel.WaveExtension}");
                            if (bts != null)
                            {
                                File.WriteAllBytes(Path.Combine(dirPath, relativePath), bts);
                                resDictionary.Add(resource.Name, $"{name}/{relativePath}");
                            }
                        }
                    }
                }
            }

            return(resDictionary);
        }
Example #2
0
        /// <summary>
        /// Decompile to files
        /// </summary>
        /// <param name="inputPath">PSB file path</param>
        /// <param name="extractOption">whether to extract image to common format</param>
        /// <param name="extractFormat">if extract, what format do you want</param>
        /// <param name="useResx">if false, use array-based resource json (legacy)</param>
        /// <param name="key">PSB CryptKey</param>
        /// <param name="type">Specify PSB type, if not set, infer type automatically</param>
        public static void DecompileToFile(string inputPath, PsbExtractOption extractOption = PsbExtractOption.Original,
                                           PsbImageFormat extractFormat = PsbImageFormat.png, bool useResx = true, uint?key = null, PsbType type = PsbType.PSB)
        {
            var context = FreeMount.CreateContext();

            if (key != null)
            {
                context.Context[Consts.Context_CryptKey] = key;
            }

            File.WriteAllText(ChangeExtensionForOutputJson(inputPath, ".json"), Decompile(inputPath, out var psb, context.Context));

            OutputResources(psb, context, inputPath, extractOption, extractFormat, useResx);
        }
Example #3
0
        public override Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                                    PsbExtractOption extractOption = PsbExtractOption.Original)
        {
            //Extra Extract
            if (extractOption == PsbExtractOption.Extract)
            {
                if (psb.Type == PsbType.Tachie)
                {
                    var bitmaps = TextureCombiner.CombineTachie(psb);
                    foreach (var kv in bitmaps)
                    {
                        kv.Value.Save(Path.Combine(dirPath, $"{kv.Key}{context.ImageFormat.DefaultExtension()}"), context.ImageFormat.ToImageFormat());
                    }
                }
            }

            return(base.OutputResources(psb, context, name, dirPath, extractOption));
        }
Example #4
0
        public static Dictionary <string, string> OutputExtraResources(PSB psb, FreeMountContext context, string name,
                                                                       string dirPath, out Dictionary <string, float[]> flattenArrays, PsbExtractOption extractOption = PsbExtractOption.Original)
        {
            Dictionary <string, string> extraResDictionary = new Dictionary <string, string>();

            flattenArrays = null;

            if (!context.UseFlattenArray() && !Consts.FlattenArrayByDefault)
            {
                extractOption = PsbExtractOption.Original;
            }

            if (extractOption == PsbExtractOption.Original)
            {
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }

                for (int i = 0; i < psb.ExtraResources.Count; i++)
                {
                    var relativePath = psb.ExtraResources[i].Index == null ? $"#{Consts.ExtraResourceIdentifierChar}{i}.bin" : $"{Consts.ExtraResourceIdentifierChar}{psb.ExtraResources[i].Index}.bin";

                    File.WriteAllBytes(
                        Path.Combine(dirPath, relativePath),
                        psb.ExtraResources[i].Data);
                    extraResDictionary.Add(Path.GetFileNameWithoutExtension(relativePath), $"{name}/{Consts.ExtraResourceFolderName}/{relativePath}");
                }
            }
            else //Extract
            {
                flattenArrays = new Dictionary <string, float[]>();
                //context.Context[Consts.Context_FlattenArray] = flattenArrays;
                for (int i = 0; i < psb.ExtraResources.Count; i++)
                {
                    var relativePath = psb.ExtraResources[i].Index == null ? $"#{Consts.ExtraResourceIdentifierChar}{i}.bin" : $"{Consts.ExtraResourceIdentifierChar}{psb.ExtraResources[i].Index}.bin";
                    var data         = psb.ExtraResources[i].Data;
                    var resName      = Path.GetFileNameWithoutExtension(relativePath);
                    if (data.Length % 4 == 0)
                    {
                        var floats = MemoryMarshal.Cast <byte, float>(data.AsSpan());
                        flattenArrays.Add(resName, floats.ToArray());
                        //extraResDictionary.Add(resName, "");
                    }
                    else
                    {
                        if (!Directory.Exists(dirPath))
                        {
                            Directory.CreateDirectory(dirPath);
                        }

                        File.WriteAllBytes(
                            Path.Combine(dirPath, relativePath),
                            psb.ExtraResources[i].Data);
                        extraResDictionary.Add(resName, $"{name}/{Consts.ExtraResourceFolderName}/{relativePath}");
                    }
                }
            }

            return(extraResDictionary);
        }
Example #5
0
        public static Dictionary <string, string> OutputImageResources(PSB psb, FreeMountContext context, string name,
                                                                       string dirPath,
                                                                       PsbExtractOption extractOption = PsbExtractOption.Original,
                                                                       PsbImageFormat extractFormat   = PsbImageFormat.png)
        {
            var resources = psb.CollectResources <ImageMetadata>();

            Dictionary <string, string> resDictionary = new Dictionary <string, string>();

            ImageFormat pixelFormat;

            switch (extractFormat)
            {
            case PsbImageFormat.png:
                pixelFormat = ImageFormat.Png;
                break;

            default:
                pixelFormat = ImageFormat.Bmp;
                break;
            }

            if (extractOption == PsbExtractOption.Original)
            {
                for (int i = 0; i < psb.Resources.Count; i++)
                {
                    var relativePath = psb.Resources[i].Index == null ? $"#{Consts.ResourceIdentifierChar}{i}.bin" : $"{psb.Resources[i].Index}.bin";

                    File.WriteAllBytes(
                        Path.Combine(dirPath, relativePath),
                        psb.Resources[i].Data);
                    resDictionary.Add(Path.GetFileNameWithoutExtension(relativePath), $"{name}/{relativePath}");
                }
            }
            else
            {
                for (int i = 0; i < resources.Count; i++)
                {
                    var resource = resources[i];
                    //Generate Friendly Name
                    var    friendlyName = resource.GetFriendlyName(psb.Type);
                    string relativePath = friendlyName;
                    if (string.IsNullOrWhiteSpace(friendlyName))
                    {
                        relativePath = resource.Resource.Index?.ToString() ?? $"({i})";
                        friendlyName = i.ToString();
                    }

                    var currentExtractOption = extractOption;
                    if (resource.Compress != PsbCompressType.Tlg && resource.Compress != PsbCompressType.ByName && (resource.Width <= 0 || resource.Height <= 0)) //impossible to extract, just keep raw
                    {
                        if (currentExtractOption == PsbExtractOption.Extract)
                        {
                            currentExtractOption = PsbExtractOption.Original;
                        }
                    }

                    switch (currentExtractOption)
                    {
                    case PsbExtractOption.Extract:
                        switch (extractFormat)
                        {
                        case PsbImageFormat.png:
                            relativePath += ".png";
                            break;

                        default:
                            relativePath += ".bmp";
                            break;
                        }

                        relativePath = CheckPath(relativePath, i);
                        if (resource.Compress == PsbCompressType.RL)
                        {
                            RL.DecompressToImageFile(resource.Data, Path.Combine(dirPath, relativePath),
                                                     resource.Height, resource.Width, extractFormat, resource.PixelFormat);
                        }
                        else if (resource.Compress == PsbCompressType.Tlg ||
                                 resource.Compress == PsbCompressType.ByName)
                        {
                            var bmp = context.ResourceToBitmap(resource.Compress == PsbCompressType.Tlg
                                    ? ".tlg"
                                    : Path.GetExtension(resource.Name), resource.Data);
                            if (bmp == null)
                            {
                                if (resource.Compress == PsbCompressType.Tlg)     //Fallback to managed TLG decoder
                                {
                                    using var ms = new MemoryStream(resource.Data);
                                    using var br = new BinaryReader(ms);
                                    bmp          = new TlgImageConverter().Read(br);
                                    bmp.Save(Path.Combine(dirPath, relativePath), pixelFormat);
                                    bmp.Dispose();
                                }

                                relativePath = Path.ChangeExtension(relativePath, Path.GetExtension(resource.Name));
                                File.WriteAllBytes(Path.Combine(dirPath, relativePath), resource.Data);
                            }
                            else
                            {
                                bmp.Save(Path.Combine(dirPath, relativePath), pixelFormat);
                                bmp.Dispose();
                            }
                        }
                        //else if (resource.Compress == PsbCompressType.ByName)
                        //{
                        //    relativePath = Path.ChangeExtension(relativePath, Path.GetExtension(resource.Name));
                        //    File.WriteAllBytes(Path.Combine(dirPath, relativePath), resource.Data);
                        //}
                        else
                        {
                            RL.ConvertToImageFile(resource.Data, Path.Combine(dirPath, relativePath),
                                                  resource.Height, resource.Width, extractFormat, resource.PixelFormat, resource.PalData,
                                                  resource.PalettePixelFormat);
                        }

                        break;

                    case PsbExtractOption.Original:
                        if (resources[i].Compress == PsbCompressType.RL)
                        {
                            relativePath += ".rl";
                            relativePath  = CheckPath(relativePath, i);
                            File.WriteAllBytes(Path.Combine(dirPath, relativePath), resource.Data);
                        }
                        else if (resource.Compress == PsbCompressType.Tlg)
                        {
                            relativePath += ".tlg";
                            relativePath  = CheckPath(relativePath, i);
                            File.WriteAllBytes(Path.Combine(dirPath, relativePath), resource.Data);
                        }
                        else
                        {
                            relativePath += ".raw";
                            relativePath  = CheckPath(relativePath, i);
                            File.WriteAllBytes(Path.Combine(dirPath, relativePath), resource.Data);
                        }

                        break;

                    //case PsbExtractOption.Decompress:
                    //    relativePath += ".raw";
                    //    relativePath = CheckPath(relativePath, i);
                    //    File.WriteAllBytes(Path.Combine(dirPath, relativePath),
                    //        resources[i].Compress == PsbCompressType.RL
                    //            ? RL.Decompress(resource.Data)
                    //            : resource.Data);
                    //    break;
                    //case PsbExtractOption.Compress:
                    //    relativePath += ".rl";
                    //    relativePath = CheckPath(relativePath, i);
                    //    File.WriteAllBytes(Path.Combine(dirPath, relativePath),
                    //        resources[i].Compress != PsbCompressType.RL
                    //            ? RL.Compress(resource.Data)
                    //            : resource.Data);
                    //    break;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(currentExtractOption), currentExtractOption, null);
                    }

                    //Determine save name
                    try
                    {
                        bool indexConflict   = false;
                        uint conflictedIndex = 0;
                        if (resource.Resource.Index != null)                          //try index as name first
                        {
                            if (resDictionary.ContainsKey(resource.Index.ToString())) //index is used before
                            {
                                Console.WriteLine(
                                    $"[WARN] Resource Index {resource.Index} conflict. May be resource sharing, but may also be something wrong.");
                                //continue;
                                indexConflict           = true;
                                conflictedIndex         = resource.Resource.Index.Value;
                                resource.Resource.Index = null; //have another try on friendly name
                            }
                        }
                        if (resource.Resource.Index == null)
                        {
                            if (resDictionary.ContainsKey(friendlyName)) // friendly name is also used (most likely its the same res reused), no name can be used to save
                            {
                                Console.WriteLine(
                                    $"[WARN] Resource Name {friendlyName} conflict. May be resource sharing, but may also be something wrong.");
                                continue; //just skip
                            }

                            if (indexConflict) //index is used but friendly name is not (maybe they are different?), save using friendly name
                            {
                                Console.WriteLine($"[FIXED] Resource {friendlyName} is sharing same data with Index {conflictedIndex}");
                            }
                        }

                        resDictionary.Add(resource.Resource.Index == null ? friendlyName : resource.Index.ToString(),
                                          $"{name}/{relativePath}");
                    }
                    catch (ArgumentException e)
                    {
                        throw new PsbBadFormatException(PsbBadFormatReason.Resources,
                                                        "Resource Export Error: Name conflict, or Index is not specified. Try Raw export mode.", e);
                    }
                }
            }

            string CheckPath(string rPath, int id)
            {
                var k = Path.GetFileNameWithoutExtension(rPath);

                if (resDictionary.ContainsKey(k))
                {
                    return($"{id}{Path.GetExtension(rPath)}");
                }

                return(rPath);
            }

            return(resDictionary);
        }
Example #6
0
 public virtual Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                            PsbExtractOption extractOption = PsbExtractOption.Original)
 {
     return(PsbResHelper.OutputImageResources(psb, context, name, dirPath, extractOption));
 }
Example #7
0
        /// <summary>
        /// Decompile to files
        /// </summary>
        /// <param name="psb">PSB</param>
        /// <param name="outputPath">Output json file name, should end with .json</param>
        /// <param name="additionalContext">additional context used in decompilation</param>
        /// <param name="extractOption">whether to extract image to common format</param>
        /// <param name="extractFormat">if extract, what format do you want</param>
        /// <param name="useResx">if false, use array-based resource json (legacy)</param>
        /// <param name="key">PSB CryptKey</param>
        public static void DecompileToFile(PSB psb, string outputPath, Dictionary <string, object> additionalContext = null, PsbExtractOption extractOption = PsbExtractOption.Original,
                                           PsbImageFormat extractFormat = PsbImageFormat.png, bool useResx = true, uint?key = null)
        {
            var context = FreeMount.CreateContext(additionalContext);

            if (key != null)
            {
                context.Context[Consts.Context_CryptKey] = key;
            }

            File.WriteAllText(outputPath, Decompile(psb)); //MARK: breaking change for json path

            OutputResources(psb, context, outputPath, extractOption, extractFormat, useResx);
        }
Example #8
0
        internal static void OutputResources(PSB psb, FreeMountContext context, string filePath, PsbExtractOption extractOption = PsbExtractOption.Original,
                                             PsbImageFormat extractFormat = PsbImageFormat.png, bool useResx = true)
        {
            var             name    = Path.GetFileNameWithoutExtension(filePath);
            var             dirPath = Path.Combine(Path.GetDirectoryName(filePath), name);
            PsbResourceJson resx    = new PsbResourceJson(psb, context.Context);

            if (File.Exists(dirPath))
            {
                name    += "-resources";
                dirPath += "-resources";
            }

            var extraDir = Path.Combine(dirPath, Consts.ExtraResourceFolderName);

            if (!Directory.Exists(dirPath)) //ensure there is no file with same name!
            {
                if (psb.Resources.Count != 0)
                {
                    Directory.CreateDirectory(dirPath);
                }
            }

            if (psb.ExtraResources.Count > 0)
            {
                var extraDic = PsbResHelper.OutputExtraResources(psb, context, name, extraDir, out var flattenArrays, extractOption);
                resx.ExtraResources = extraDic;
                if (flattenArrays != null && flattenArrays.Count > 0)
                {
                    resx.ExtraFlattenArrays = flattenArrays;
                }
            }

            var resDictionary = psb.TypeHandler.OutputResources(psb, context, name, dirPath, extractOption);

            //MARK: We use `.resx.json` to distinguish from psbtools' `.res.json`
            if (useResx)
            {
                resx.Resources = resDictionary;
                resx.Context   = context.Context;
                string json;
                if (Consts.JsonArrayCollapse)
                {
                    json = ArrayCollapseJsonTextWriter.SerializeObject(resx);
                }
                else
                {
                    json = JsonConvert.SerializeObject(resx, Formatting.Indented);
                }
                File.WriteAllText(ChangeExtensionForOutputJson(filePath, ".resx.json"), json);
            }
            else
            {
                if (psb.ExtraResources.Count > 0)
                {
                    throw new NotSupportedException("PSBv4 cannot use legacy res.json format.");
                }
                File.WriteAllText(ChangeExtensionForOutputJson(filePath, ".res.json"),
                                  JsonConvert.SerializeObject(resDictionary.Values.ToList(), Formatting.Indented));
            }
        }
Example #9
0
        /// <summary>
        /// Split textures into parts and save to files
        /// </summary>
        /// <param name="psb">PSB</param>
        /// <param name="path">Save directory</param>
        /// <param name="option">Save option</param>
        /// <param name="imageFormat">Save format</param>
        /// <param name="pixelFormat">When save to PSB special formats, specific pixel format to use</param>
        public static void SplitTextureToFiles(this PSB psb, string path, PsbExtractOption option = PsbExtractOption.Extract,
                                               PsbImageFormat imageFormat = PsbImageFormat.png, PsbPixelFormat pixelFormat = PsbPixelFormat.None)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            var source = (PsbDictionary)psb.Objects["source"];

            foreach (var texPair in source)
            {
                if (!(texPair.Value is PsbDictionary tex))
                {
                    continue;
                }

                var name = texPair.Key;
                if (!Directory.Exists(Path.Combine(path, name)))
                {
                    Directory.CreateDirectory(Path.Combine(path, name));
                }

                var icon    = (PsbDictionary)tex["icon"];
                var texture = (PsbDictionary)tex["texture"];

                //var mipmap = (PsbDictionary)texture["mipMap"]; //TODO: Mipmap?

                var pixel = texture[Consts.ResourceKey];
                if (pixel == null || !(pixel is PsbResource pixelRes))
                {
                    throw new PsbBadFormatException(PsbBadFormatReason.Resources,
                                                    "External Texture PSB is not supported. Please Link textures into PSB.");
                    return;
                }

                var md = PsbResHelper.GenerateImageMetadata(texture, pixelRes);
                md.Spec = psb.Platform; //Important
                Bitmap bmp = md.ToImage();

                foreach (var iconPair in icon)
                {
                    var    savePath = Path.Combine(path, name, iconPair.Key);
                    var    info     = (PsbDictionary)iconPair.Value;
                    var    width    = (int)(PsbNumber)info["width"];
                    var    height   = (int)(PsbNumber)info["height"];
                    var    top      = (int)(PsbNumber)info["top"];
                    var    left     = (int)(PsbNumber)info["left"];
                    var    attr     = (int)(PsbNumber)info["attr"];
                    Bitmap b        = new Bitmap(width, height, PixelFormat.Format32bppArgb);
#if USE_FASTBITMAP
                    using (FastBitmap f = b.FastLock())
                    {
                        f.CopyRegion(bmp, new Rectangle(left, top, width, height), new Rectangle(0, 0, b.Width, b.Height));
                    }
#else
                    Graphics g = Graphics.FromImage(b);
                    //g.InterpolationMode = InterpolationMode.NearestNeighbor;
                    //g.PixelOffsetMode = PixelOffsetMode.Half;
                    g.DrawImage(bmp, new Rectangle(0, 0, b.Width, b.Height), new Rectangle(left, top, width, height),
                                GraphicsUnit.Pixel);
                    g.Dispose();
#endif

                    switch (option)
                    {
                    case PsbExtractOption.Decompress:
                        File.WriteAllBytes(savePath + ".raw", RL.GetPixelBytesFromImage(b, pixelFormat));
                        break;

                    case PsbExtractOption.Compress:
                        File.WriteAllBytes(savePath + ".rl", RL.CompressImage(b, pixelFormat));
                        break;

                    case PsbExtractOption.Original:
                    case PsbExtractOption.Extract:
                    default:
                        switch (imageFormat)
                        {
                        case PsbImageFormat.bmp:
                            b.Save(savePath + ".bmp", ImageFormat.Bmp);
                            break;

                        case PsbImageFormat.png:
                        default:
                            b.Save(savePath + ".png", ImageFormat.Png);
                            //b.Save(savePath + $"_{attr}.png", ImageFormat.png);
                            break;
                        }

                        break;
                    }
                }

                bmp.Dispose();
            }
        }
Example #10
0
        public Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                           PsbExtractOption extractOption = PsbExtractOption.Original)
        {
            var resources = psb.CollectResources <AudioMetadata>();
            Dictionary <string, string> resDictionary = new Dictionary <string, string>();

            if (extractOption == PsbExtractOption.Original)
            {
                for (int i = 0; i < psb.Resources.Count; i++)
                {
                    var relativePath = psb.Resources[i].Index == null ? $"#{i}.raw" : $"{psb.Resources[i].Index}.raw";

                    File.WriteAllBytes(
                        Path.Combine(dirPath, relativePath),
                        psb.Resources[i].Data);
                    resDictionary.Add(Path.GetFileNameWithoutExtension(relativePath), $"{name}/{relativePath}");
                }
            }
            else
            {
                foreach (var resource in resources)
                {
                    if (resource.ChannelList.Count == 1)
                    {
                        var bts          = resource.ChannelList[0].TryToWave(context);
                        var relativePath = resource.GetFileName(resource.ChannelList[0].Extension + resource.ChannelList[0].WaveExtension); //WaveExtension may change after ToWave
                        if (bts != null)
                        {
                            File.WriteAllBytes(Path.Combine(dirPath, relativePath), bts);
                            resDictionary.Add(resource.Name, $"{name}/{relativePath}");
                        }
                    }
                    else if (resource.ChannelList.Count > 1)
                    {
                        if (resource.Pan == PsbAudioPan.LeftRight) //load audio.vag.l.wav & audio.vag.r.wav
                        {
                            var left          = resource.GetLeftChannel();
                            var relativePathL = resource.GetFileName($"{left.Extension}.l{left.WaveExtension}");
                            var btsL          = left.TryToWave(context);
                            if (btsL != null)
                            {
                                File.WriteAllBytes(Path.Combine(dirPath, relativePathL), btsL);
                            }
                            else
                            {
                                relativePathL = resource.GetFileName($"{left.Extension}.l{left.Extension}");
                                File.WriteAllBytes(Path.Combine(dirPath, relativePathL), left.Data.Data);
                                resDictionary.Add(resource.Name, $"{name}/{relativePathL}");
                            }

                            var right         = resource.GetRightChannel();
                            var relativePathR = resource.GetFileName($"{right.Extension}.r{right.WaveExtension}");
                            var btsR          = right.TryToWave(context);
                            if (btsR != null)
                            {
                                File.WriteAllBytes(Path.Combine(dirPath, relativePathR), btsR);
                            }
                            else
                            {
                                relativePathR = resource.GetFileName($"{right.Extension}.r{right.Extension}");
                                File.WriteAllBytes(Path.Combine(dirPath, relativePathR), right.Data.Data);
                                resDictionary.Add(resource.Name, $"{name}/{relativePathR}");
                            }

                            if (btsL != null && btsR != null)
                            {
                                var relativePath = resource.GetFileName($"{left.Extension}{left.WaveExtension}");
                                resDictionary.Add(resource.Name, $"{name}/{relativePath}"); //a virtual file path
                            }
                        }
                        else //not LeftRight
                        {
                            for (var j = 0; j < resource.ChannelList.Count; j++) //load audio.vag.1.wav etc.
                            {
                                var waveChannel = resource.ChannelList[j];
                                if (waveChannel.Data.Index == null)
                                {
                                    Console.WriteLine($"[WARN] Channel {j} is not linked with a Resource.");
                                    continue;
                                }
                                var bts          = waveChannel.TryToWave(context);
                                var noStr        = waveChannel.Data.Index == null ? $".@{j}" : $".#{waveChannel.Data.Index.Value}"; //TODO: handle @ - channel internal No.
                                var relativePath = resource.GetFileName($"{waveChannel.Extension}{noStr}{waveChannel.WaveExtension}");
                                if (bts != null)
                                {
                                    File.WriteAllBytes(Path.Combine(dirPath, relativePath), bts);
                                    resDictionary.Add(resource.Name, $"{name}/{relativePath}");
                                }
                            }
                        }
                    }
                }
            }

            return(resDictionary);
        }
Example #11
0
        internal static void OutputResources(PSB psb, FreeMountContext context, string filePath, PsbExtractOption extractOption = PsbExtractOption.Original,
                                             PsbImageFormat extractFormat = PsbImageFormat.png, bool useResx = true)
        {
            var             name    = Path.GetFileNameWithoutExtension(filePath);
            var             dirPath = Path.Combine(Path.GetDirectoryName(filePath), name);
            PsbResourceJson resx    = new PsbResourceJson(psb, context.Context);

            if (File.Exists(dirPath))
            {
                name    += "-resources";
                dirPath += "-resources";
            }

            if (!Directory.Exists(dirPath)) //ensure there is no file with same name!
            {
                if (psb.Resources.Count != 0)
                {
                    Directory.CreateDirectory(dirPath);
                }
            }

            var resDictionary = psb.TypeHandler.OutputResources(psb, context, name, dirPath, extractOption);

            //MARK: We use `.resx.json` to distinguish from psbtools' `.res.json`
            if (useResx)
            {
                resx.Resources = resDictionary;
                resx.Context   = context.Context;
                File.WriteAllText(Path.ChangeExtension(filePath, ".resx.json"),
                                  JsonConvert.SerializeObject(resx, Formatting.Indented));
            }
            else
            {
                File.WriteAllText(Path.ChangeExtension(filePath, ".res.json"),
                                  JsonConvert.SerializeObject(resDictionary.Values.ToList(), Formatting.Indented));
            }
        }
Example #12
0
 public Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                    PsbExtractOption extractOption = PsbExtractOption.Original)
 {
     return(null);
 }
Example #13
0
 public override Dictionary <string, string> OutputResources(PSB psb, FreeMountContext context, string name, string dirPath,
                                                             PsbExtractOption extractOption = PsbExtractOption.Original)
 {
     return(base.OutputResources(psb, context, name, dirPath, extractOption));
 }