Example #1
0
        private void Open(string path)
        {
            if (Directory.Exists(path))
            {
                foreach (string p in (new DirectoryInfo(path)).GetFiles().Select(f => f.FullName))
                {
                    Open(p);
                }
                foreach (string p in (new DirectoryInfo(path)).GetDirectories().Select(f => f.FullName))
                {
                    Open(p);
                }
            }
            else if (File.Exists(path))
            {
                string ext = Path.GetExtension(path).ToLower();
                if (ext == ".lz")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    string decpath  = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path);
                    if (filedata[0] == 0x13 && filedata[4] == 0x11) // "LZ13"
                    {
                        filedata = filedata.Skip(4).ToArray();
                    }
                    else if (filedata[0] == 0x17 && filedata[4] == 0x11) // Fire Emblem Heroes "LZ17"
                    {
                        var xorkey = BitConverter.ToUInt32(filedata, 0) >> 8;
                        xorkey *= 0x8083;
                        for (var i = 8; i < filedata.Length; i += 0x4)
                        {
                            BitConverter.GetBytes(BitConverter.ToUInt32(filedata, i) ^ xorkey).CopyTo(filedata, i);
                            xorkey ^= BitConverter.ToUInt32(filedata, i);
                        }
                        filedata = filedata.Skip(4).ToArray();
                    }
                    else if (filedata[0] == 0x4 && (BitConverter.ToUInt32(filedata, 0) >> 8) == filedata.Length - 4)
                    {
                        var xorkey = BitConverter.ToUInt32(filedata, 0) >> 8;
                        xorkey *= 0x8083;
                        for (var i = 4; i < filedata.Length; i += 0x4)
                        {
                            BitConverter.GetBytes(BitConverter.ToUInt32(filedata, i) ^ xorkey).CopyTo(filedata, i);
                            xorkey ^= BitConverter.ToUInt32(filedata, i);
                        }
                        filedata = filedata.Skip(4).ToArray();
                        if (BitConverter.ToUInt32(filedata, 0) == filedata.Length)
                        {
                            File.WriteAllBytes(decpath, filedata);
                            AddLine(RTB_Output, string.Format("Successfully decompressed {0}.", Path.GetFileName(decpath)));
                            if (File.Exists(decpath))
                            {
                                Open(decpath);
                            }
                        }
                        else
                        {
                            AddLine(RTB_Output, string.Format("Unable to automatically decompress {0}.", Path.GetFileName(path)));
                        }
                        return;
                    }
                    try
                    {
                        File.WriteAllBytes(decpath, LZ11Decompress(filedata));
                        AddLine(RTB_Output, string.Format("Successfully decompressed {0}.", Path.GetFileName(decpath)));
                    }
                    catch (Exception ex)
                    {
                        AddLine(RTB_Output, string.Format("Unable to automatically decompress {0}.", Path.GetFileName(path)));
                        Console.WriteLine(ex.Message);
                    }
                    if (File.Exists(decpath))
                    {
                        Open(decpath);
                    }
                }
                else if (ext == ".bin")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    var    outname  = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + ".txt";
                    if (BitConverter.ToUInt32(filedata, 0) == filedata.Length &&
                        new string(filedata.Skip(0x20).Take(0xC).Select(c => (char)c).ToArray()) == "MESS_ARCHIVE")
                    {
                        string archive_name = ExtractFireEmblemMessageArchive(outname, filedata);
                        AddLine(RTB_Output, string.Format("Successfully Extracted {0} ({1}).", archive_name, Path.GetFileName(path)));
                    }
                    else if (TryExtractFireEmblemHeroesMessageArchive(outname, filedata))
                    {
                        AddLine(RTB_Output, string.Format("Successfully extracted Heroes Message Archive {0}", Path.GetFileName(path)));
                    }
                }
                else if (ext == ".arc")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    if (BitConverter.ToUInt32(filedata, 0) == filedata.Length || BitConverter.ToUInt32(filedata, filedata.Length - 4) == 0x43524654)
                    {
                        ExtractFireEmblemArchive(Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + Path.DirectorySeparatorChar, filedata);
                    }
                }
                else if (ext == ".ctpk")
                {
                    AddText(RTB_Output, string.Format("Extracting images from {0}...", Path.GetFileName(path)));
                    Ctpk.Read(path);
                    AddLine(RTB_Output, "Complete!");
                }
                else if (ext == ".bch")
                {
                    AddText(RTB_Output, string.Format("Extracting textures from {0}...", Path.GetFileName(path)));
                    AddLine(RTB_Output, BCHTool.parseBCH(path) ? "Complete!" : "Failure!");
                }
                else if (ext == ".txt")
                {
                    string[] textfile = File.ReadAllLines(path);
                    if (textfile.Length > 6 && textfile[0].StartsWith("MESS_ARCHIVE") && textfile[3] == "Message Name: Message" && textfile.Skip(6).All(s => s.Contains(": ")))
                    {
                        AddText(RTB_Output, string.Format("Rebuilding Message Archive from {0}...", Path.GetFileName(path)));
                        string outname = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + ".bin";
                        byte[] arch    = MakeFireEmblemMessageArchive(textfile);
                        File.WriteAllBytes(outname, arch);
                        AddLine(RTB_Output, "Complete!");
                        byte[] cmp  = LZ11Compress(arch);
                        byte[] cmp2 = new byte[cmp.Length + 4];

                        cmp2[0] = 0x13;
                        Array.Copy(cmp, 0, cmp2, 4, cmp.Length);
                        Array.Copy(cmp, 1, cmp2, 1, 3);
                        File.WriteAllBytes(outname + ".lz", cmp2);
                    }
                }
            }
        }
Example #2
0
        private void Open(string path)
        {
            if (Directory.Exists(path))
            {
                foreach (string p in (new DirectoryInfo(path)).GetFiles().Select(f => f.FullName))
                {
                    Open(p);
                }
                foreach (string p in (new DirectoryInfo(path)).GetDirectories().Select(f => f.FullName))
                {
                    Open(p);
                }
            }
            else if (File.Exists(path))
            {
                string ext  = Path.GetExtension(path).ToLower();
                var    yaz0 = false;
                using (var fs = File.OpenRead(path))
                {
                    if (fs.Length > 4 && fs.ReadByte() == 'Y' && fs.ReadByte() == 'a' && fs.ReadByte() == 'z' && fs.ReadByte() == '0')
                    {
                        yaz0 = true;
                    }
                }
                if ((ModifierKeys == Keys.Control) && (MessageBox.Show("Compress " + path + "?", "Prompt", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes))
                {
                    var    cmp  = LZ11Compress(File.ReadAllBytes(path));
                    byte[] cmp2 = new byte[cmp.Length + 4];

                    cmp2[0] = 0x13;
                    Array.Copy(cmp, 0, cmp2, 4, cmp.Length);
                    Array.Copy(cmp, 1, cmp2, 1, 3);
                    File.WriteAllBytes(path + ".lz", cmp2);
                    AddLine(RTB_Output, string.Format("LZ13 compressed {0} to {1}", path, path + ".lz"));
                }
                else if (yaz0)
                {
                    var cmp = File.ReadAllBytes(path);
                    File.WriteAllBytes(path + ".dec", Decompress(cmp));
                    AddLine(RTB_Output, string.Format("Yaz0 decompressed {0}.", path));
                }
                else if (ext == ".lz")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    string decpath  = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path);
                    if (filedata[0] == 0x13 && filedata[4] == 0x11) // "LZ13"
                    {
                        filedata = filedata.Skip(4).ToArray();
                    }
                    else if (filedata[0] == 0x17 && filedata[4] == 0x11) // Fire Emblem Heroes "LZ17"
                    {
                        byte[] first4 = filedata.Take(4).ToArray();
                        var    xorkey = BitConverter.ToUInt32(filedata, 0) >> 8;
                        xorkey *= 0x8083;
                        for (var i = 8; i < filedata.Length; i += 0x4)
                        {
                            BitConverter.GetBytes(BitConverter.ToUInt32(filedata, i) ^ xorkey).CopyTo(filedata, i);
                            xorkey ^= BitConverter.ToUInt32(filedata, i);
                        }
                        filedata = filedata.Skip(4).ToArray();

                        byte[] output  = LZ11Decompress(filedata);
                        byte[] output2 = new byte[4 + output.Length];
                        first4.CopyTo(output2, 0);
                        output.CopyTo(output2, 4);
                        File.WriteAllBytes(decpath, output2);
                        AddLine(RTB_Output, string.Format("Successfully decompressed {0}.", Path.GetFileName(decpath)));
                        return;
                    }
                    else if (filedata[0] == 0x4 && (BitConverter.ToUInt32(filedata, 0) >> 8) == filedata.Length - 4)
                    {
                        var xorkey = BitConverter.ToUInt32(filedata, 0) >> 8;
                        xorkey *= 0x8083;
                        for (var i = 4; i < filedata.Length; i += 0x4)
                        {
                            BitConverter.GetBytes(BitConverter.ToUInt32(filedata, i) ^ xorkey).CopyTo(filedata, i);
                            xorkey ^= BitConverter.ToUInt32(filedata, i);
                        }
                        filedata = filedata.Skip(4).ToArray();
                        if (BitConverter.ToUInt32(filedata, 0) == filedata.Length)
                        {
                            File.WriteAllBytes(decpath, filedata);
                            AddLine(RTB_Output, string.Format("Successfully decompressed {0}.", Path.GetFileName(decpath)));
                            if (File.Exists(decpath))
                            {
                                Open(decpath);
                            }
                        }
                        else
                        {
                            AddLine(RTB_Output, string.Format("Unable to automatically decompress {0}.", Path.GetFileName(path)));
                        }
                        return;
                    }
                    try
                    {
                        File.WriteAllBytes(decpath, LZ11Decompress(filedata));
                        AddLine(RTB_Output, string.Format("Successfully decompressed {0}.", Path.GetFileName(decpath)));
                    }
                    catch (Exception ex)
                    {
                        AddLine(RTB_Output, string.Format("Unable to automatically decompress {0}.", Path.GetFileName(path)));
                        Console.WriteLine(ex.Message);
                    }
                    if (File.Exists(decpath))
                    {
                        Open(decpath);
                    }
                }
                else if (ext == ".bin")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    var    xorkey   = BitConverter.ToUInt32(filedata, 0) >> 8;
                    xorkey *= 0x8083;
                    var lz = filedata.Skip(4).ToArray();
                    lz = LZ11Compress(lz);
                    var output = new byte[4 + lz.Length + (lz.Length % 4 == 0?0:4 - lz.Length % 4)];
                    filedata.Take(4).ToArray().CopyTo(output, 0);
                    lz.CopyTo(output, 4);
                    for (var i = 8; i < output.Length; i += 0x4)
                    {
                        BitConverter.GetBytes(BitConverter.ToUInt32(output, i) ^ xorkey).CopyTo(output, i);
                        xorkey = BitConverter.ToUInt32(output, i);
                    }
                    File.WriteAllBytes(Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + ".bin.lz", output);
                    AddLine(RTB_Output, string.Format("Successfully Compressed {0}.", Path.GetFileName(path)));

                    /*var outname = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + ".txt";
                     * if (BitConverter.ToUInt32(filedata, 0) == filedata.Length &&
                     *  new string(filedata.Skip(0x20).Take(0xC).Select(c => (char)c).ToArray()) == "MESS_ARCHIVE")
                     * {
                     *  string archive_name = ExtractFireEmblemMessageArchive(outname, filedata);
                     *  AddLine(RTB_Output, string.Format("Successfully Extracted {0} ({1}).", archive_name, Path.GetFileName(path)));
                     * }
                     * else if (TryExtractFireEmblemHeroesMessageArchive(outname, filedata))
                     * {
                     *  AddLine(RTB_Output, string.Format("Successfully extracted Heroes Message Archive {0}", Path.GetFileName(path)));
                     * }
                     */
                }
                else if (ext == ".arc")
                {
                    byte[] filedata = File.ReadAllBytes(path);
                    if (BitConverter.ToUInt32(filedata, 0) == filedata.Length || BitConverter.ToUInt32(filedata, filedata.Length - 4) == 0x43524654)
                    {
                        ExtractFireEmblemArchive(Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + Path.DirectorySeparatorChar, filedata);
                    }
                }
                else if (ext == ".ctpk")
                {
                    AddText(RTB_Output, string.Format("Extracting images from {0}...", Path.GetFileName(path)));
                    Ctpk.Read(path);
                    AddLine(RTB_Output, "Complete!");
                }
                else if (ext == ".bch")
                {
                    AddText(RTB_Output, string.Format("Extracting textures from {0}...", Path.GetFileName(path)));
                    AddLine(RTB_Output, BCHTool.parseBCH(path) ? "Complete!" : "Failure!");
                }
                else if (ext == ".bfnt")
                {
                    AddText(RTB_Output, string.Format("Extracting font textures from {0}...", Path.GetFileName(path)));
                    var bfnt = File.ReadAllBytes(path);
                    if (BitConverter.ToUInt16(bfnt, 0x20) != 0x30)
                    {
                        AddLine(RTB_Output, "Failure!");
                    }
                    else
                    {
                        var w       = BitConverter.ToUInt16(bfnt, 0x10);
                        var h       = BitConverter.ToUInt16(bfnt, 0x12);
                        var texsize = BitConverter.ToUInt32(bfnt, 0x14);
                        var texofs  = BitConverter.ToUInt32(bfnt, 0x24);
                        if (texsize != (w * h) / 2)
                        {
                            AddLine(RTB_Output, "Failure!");
                        }
                        else
                        {
                            var num_textures = BitConverter.ToUInt16(bfnt, 0x1A);
                            for (var i = 0; i < num_textures; i++)
                            {
                                var dat = new byte[texsize];
                                Array.Copy(bfnt, texofs + texsize * i, dat, 0, texsize);
                                var outname = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + "_" + i + ".png";;
                                using (var bmp = CTR.TextureUtil.DecodeByteArray(dat, w, h, CTR.TextureFormat.L4))
                                    bmp.Save(outname, ImageFormat.Png);
                            }
                            AddLine(RTB_Output, "Complete!");
                        }
                    }
                }
                else if (ext == ".txt")
                {
                    string[] textfile = File.ReadAllLines(path);
                    if (textfile.Length > 6 && textfile[0].StartsWith("MESS_ARCHIVE") && textfile[3] == "Message Name: Message" && textfile.Skip(6).All(s => s.Contains(": ")))
                    {
                        AddText(RTB_Output, string.Format("Rebuilding Message Archive from {0}...", Path.GetFileName(path)));
                        string outname = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path) + ".bin";
                        byte[] arch    = MakeFireEmblemMessageArchive(textfile);
                        File.WriteAllBytes(outname, arch);
                        AddLine(RTB_Output, "Complete!");
                        byte[] cmp  = LZ11Compress(arch);
                        byte[] cmp2 = new byte[cmp.Length + 4];

                        cmp2[0] = 0x13;
                        Array.Copy(cmp, 0, cmp2, 4, cmp.Length);
                        Array.Copy(cmp, 1, cmp2, 1, 3);
                        File.WriteAllBytes(outname + ".lz", cmp2);
                    }
                }
            }
        }