示例#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 int garcUnpack(string garcPath, string outPath, bool skipDecompression)
        {
            if (!File.Exists(garcPath))
            {
                throw new FileNotFoundException("File does not exist");
            }

            // 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";
            }

            FileCountDetermined?.Invoke(null, new FileCountDeterminedEventArgs {
                Total = fileCount
            });

            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) { throw new Exception("A compressed file could not be deleted: " + fileOut, e); }
                            }
                            catch
                            {
                                // File is really not encrypted.
                                File.Delete(decout);
                            }
                        }
                        #endregion

                        UnpackProgressed?.Invoke(null, new UnpackProgressedEventArgs {
                            Current = filectr, Total = fileCount
                        });

                        if ((vector >>= 1) == 0)
                        {
                            break;
                        }
                    }
                }
            }
            return(fileCount);
        }