예제 #1
0
                public GARCEntry(byte[] data)
                {
                    Data     = data;
                    Accessed = true;

                    if (data.Length == 0)
                    {
                        return;
                    }

                    if (data[0] != 0x11)
                    {
                        return;
                    }

                    try
                    {
                        using (MemoryStream newMS = new MemoryStream())
                        {
                            LZSS.Decompress(new MemoryStream(data), data.Length, newMS);
                            Data = newMS.ToArray();
                        }
                        WasCompressed = true;
                    }
                    catch { }
                }
예제 #2
0
        public static bool garcUnpack(string garcPath, string outPath, bool skipDecompression, ProgressBar pBar1 = null, Label label = null, bool supress = false, bool bypassExt = false)
        {
            if (!File.Exists(garcPath) && !supress)
            {
                Util.Alert("File does not exist"); return(false);
            }

            // Unpack the GARC
            GARCFile     garc      = unpackGARC(garcPath);
            const string ext       = "bin"; // Default Extension Name
            int          fileCount = garc.fatb.FileCount;
            string       format    = "D" + Math.Ceiling(Math.Log10(fileCount));

            if (outPath == "gametext")
            {
                format = "D3";
            }

            #region Display
            // Initialize ProgressBar
            if (pBar1 == null)
            {
                pBar1 = new ProgressBar();
            }
            if (pBar1.InvokeRequired)
            {
                pBar1.Invoke((MethodInvoker) delegate { pBar1.Minimum = 0; pBar1.Step = 1; pBar1.Value = 0; pBar1.Maximum = fileCount; });
            }
            else
            {
                pBar1.Minimum = 0; pBar1.Step = 1; pBar1.Value = 0; pBar1.Maximum = garc.fatb.FileCount;
            }

            if (label == null)
            {
                label = new Label();
            }
            if (label.InvokeRequired)
            {
                label.Invoke((MethodInvoker) delegate { label.Visible = true; });
            }
            #endregion

            using (BinaryReader br = new BinaryReader(File.OpenRead(garcPath)))
            {
                // Create Extraction folder if it does not exist.
                if (!Directory.Exists(outPath))
                {
                    Directory.CreateDirectory(outPath);
                }

                int filectr = 0;
                // Pull out all the files
                for (int o = 0; o < garc.fato.EntryCount; o++)
                {
                    var Entry = garc.fatb.Entries[o];
                    // Set Entry File Name
                    string fileName = o.ToString(format);

                    #region OutDirectory Determination
                    string parentFolder = Entry.IsFolder ? Path.Combine(outPath, fileName) : outPath;
                    if (Entry.IsFolder) // Process Folder
                    {
                        Directory.CreateDirectory(parentFolder);
                    }
                    #endregion

                    uint vector = Entry.Vector;
                    for (int i = 0; i < 32; i++) // For each bit in vector
                    {
                        var SubEntry = Entry.SubEntries[i];
                        if (!SubEntry.Exists)
                        {
                            continue;
                        }

                        // Seek to Offset
                        br.BaseStream.Position = SubEntry.Start + garc.DataOffset;

                        // Check if Compressed
                        bool compressed = false;
                        if (!skipDecompression)
                        {
                            try { compressed = (byte)br.PeekChar() == 0x11; }
                            catch { }
                        }

                        // Write File
                        string fileOut = Path.Combine(parentFolder, (Entry.IsFolder ? i.ToString("00") : fileName) + "." + ext);
                        using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(fileOut)))
                        {
                            // Write out the data for the file
                            br.BaseStream.Position = SubEntry.Start + garc.DataOffset;
                            bw.Write(br.ReadBytes(SubEntry.Length));
                            filectr++;
                        }
                        if (compressed)
                        #region Decompression
                        {
                            string decout = Path.Combine(Path.GetDirectoryName(fileOut), "dec_" + Path.GetFileName(fileOut));
                            try
                            {
                                LZSS.Decompress(fileOut, decout);
                                try { File.Delete(fileOut); }
                                catch (Exception e) { Util.Error("A compressed file could not be deleted.", fileOut, e.ToString()); }
                            }
                            catch
                            {
                                // File is really not encrypted.
                                try { File.Delete(decout); }
                                catch (Exception e) { Util.Error("This shouldn't happen", e.ToString()); }
                            }
                        }
                        #endregion

                        #region Step
                        if (pBar1.InvokeRequired)
                        {
                            pBar1.Invoke((MethodInvoker)(() => pBar1.PerformStep()));
                        }
                        else
                        {
                            pBar1.PerformStep();
                        }

                        string update = $"{filectr/fileCount:P2} - {filectr}/{fileCount}";
                        if (label.InvokeRequired)
                        {
                            label.Invoke((MethodInvoker) delegate { label.Text = update; });
                        }
                        else
                        {
                            label.Text = update;
                        }
                        #endregion

                        if ((vector >>= 1) == 0)
                        {
                            break;
                        }
                    }
                }
            }
            #region Updates
            if (label.InvokeRequired)
            {
                label.Invoke((MethodInvoker) delegate { label.Visible = false; });
            }
            else
            {
                label.Visible = false;
            }
            SystemSounds.Exclamation.Play();
            if (!supress)
            {
                Util.Alert("Unpack Successful!", fileCount + " files unpacked from the GARC!");
            }
            #endregion
            return(true);
        }