Ejemplo n.º 1
0
        /// <summary>
        /// Returns the file data, decompressed if needed
        /// </summary>
        /// <param name="item">The grf file</param>
        /// <param name="decompress">Should the data decompressed?</param>
        /// <returns></returns>
        public byte[] GetFileData(RoGrfFileItem item, bool decompress)
        {
            byte[] buf       = null;
            bool   isUpdated = item.IsAdded || item.IsUpdated;

            if (isUpdated)
            {
                // Load data from file
                buf = File.ReadAllBytes(item.NewFilepath);
            }
            else if (item.FileData == null || item.FileData.Length != item.LengthCompressedAlign)
            {
                // Cache data
                CacheFileData(item);
                buf = item.FileData;
            }

            if (isUpdated == false && buf != null && buf.Length > 0)
            {
                // deocde, if needed
                if (item.Cycle >= 0 && Deflate.IsMagicHead(buf) == false)
                {
                    RoGrfHelper.DecryptFileData(buf, item.Cycle == 0, item.Cycle);
                }

                // Decompress data
                if (decompress)
                {
                    buf = Deflate.Decompress(buf);
                }
            }

            return(buf);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads the uncompressed body of versions equal or above 0x200.
        /// The body is ZIP (deflate) compressed.
        /// </summary>
        /// <param name="binReader"></param>
        /// <param name="fileCount"></param>
        /// <param name="skipFiles"></param>
        /// <returns></returns>
        private bool ReadFilesVersion2(BinaryReader binReader, int fileCount, bool skipFiles)
        {
            int lengthCompressed   = binReader.ReadInt32();
            int lengthUnCompressed = binReader.ReadInt32();

            mFileTableLength = (ulong)lengthUnCompressed;
            var bufCompressed = new byte[lengthCompressed];

            mFiletableUncompressed = new byte[(int)mFileTableLength];
            binReader.Read(bufCompressed, 0, lengthCompressed);

            mFiletableUncompressed = Deflate.Decompress(bufCompressed);

            /*
             * if (mFiletableUncompressed.Length != (int)mFileTableLength) {
             *      throw new Exception("Filesize missmatch! Uncompressed Body Size is not equal to Uncompressed Length!");
             * }
             */
            // Only read body?
            if (skipFiles == false)
            {
                for (int i = 0, offset = 0; i < fileCount; i++)
                {
                    var  filepath = string.Empty;
                    char c;
                    var  itemTableOffset = (uint)offset;

                    while ((c = (char)mFiletableUncompressed[offset++]) != '\0')
                    {
                        filepath += c;
                    }

                    filepath = Tools.UnifyPath(filepath);
                    var item = new RoGrfFileItem {
                        TableOffset = itemTableOffset,
                        Index       = Files.Count,
                        Filepath    = filepath,
                        Flags       = mFiletableUncompressed[offset + 12]
                    };

                    // File or directory?
                    if (item.IsFile)
                    {
                        item.LengthCompressed      = BitConverter.ToUInt32(mFiletableUncompressed, offset);
                        item.LengthCompressedAlign = BitConverter.ToUInt32(mFiletableUncompressed, offset + 4);
                        item.LengthUnCompressed    = BitConverter.ToUInt32(mFiletableUncompressed, offset + 8);
                        // Offset is base offset + grf header
                        item.DataOffset = BitConverter.ToUInt32(mFiletableUncompressed, offset + 13) + GrfHeaderLen;

                        // from eAtehna, DES encryption
                        item.Cycle = 1;
                        switch (item.Flags)
                        {
                        case 3:
                            for (var lop = 10; item.LengthCompressed >= lop; lop = lop * 10, item.Cycle++)
                            {
                            }
                            break;

                        case 5:
                            item.Cycle = 0;
                            break;

                        default:
                            item.Cycle = -1;
                            break;
                        }
                    }
                    else
                    {
                        // skip dirs
                        offset += (int)GrfFileLen;
                        continue;
                    }

                    // FIX: Some files in a tested grf are duplicated?
                    //		I cant remember grf version or something else..
                    if (GetFileByHash(item.NameHash) != null)
                    {
                        // Duplicate file, just skip it
                        offset += (int)GrfFileLen;
                        continue;
                    }
                    Files.Add(item.NameHash, item);
                    mStringlist.Add(item.NameHash);

                    mFileDataLength += item.LengthCompressedAlign;

                    offset += (int)GrfFileLen;

#if !DISABLE_GRF_EVENTS
                    OnItemAdded(item, i, fileCount);
#endif
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Writes the binary data to the stream.
        /// </summary>
        /// <param name="grf"></param>
        /// <param name="writer"></param>
        internal void WriteToBinaryTable(RoGrfFile grf, BinaryWriter writer)
        {
            // Skip deleted files
            if (IsDeleted)
            {
                return;
            }

            byte[] buf;

            // Update new offset
            DataOffset = (uint)writer.BaseStream.Position;

            // Either new or changed?
            if (IsUpdated == false && IsAdded == false)
            {
                // Auto-convert to 0x200 compression (deflate)
                if (grf.Version != 0x200)
                {
                    // #1: Decompress buf and update length
                    buf = grf.GetFileData(NameHash, true);
                    LengthUnCompressed = (uint)buf.Length;
                    // #2: Compress and update length
                    buf = Deflate.Compress(buf, true);
                    LengthCompressed      = (uint)buf.Length;
                    LengthCompressedAlign = (uint)buf.Length;
                }
                else
                {
                    // Get compressed data
                    buf = grf.GetFileData(NameHash, false);
                }
            }
            else
            {
                // Added or updated files, load data from origin filepath
                if (File.Exists(NewFilepath) == false)
                {
                    throw new Exception("WriteItems(): File of new or updated item not found: " + NewFilepath);
                }

                buf = File.ReadAllBytes(NewFilepath);
                LengthUnCompressed = (uint)buf.Length;
                buf = Deflate.Compress(buf, true);
                LengthCompressed = LengthCompressedAlign = (uint)buf.Length;
            }

            try {
                // Check if the buf is compressed
                if (buf.Length != LengthCompressed && buf.Length != LengthCompressedAlign)
                {
                    // The buf has to be compressed, so decompress it
                    byte[] bufUncompressed = Deflate.Decompress(buf);
                    // Update length, if decompression seems to be correct
                    if (bufUncompressed.Length == 0 || bufUncompressed.Length != LengthUnCompressed)
                    {
                        // Narf, corrupt file or something like that
                        // Just write it..
                        //throw new Exception("WriteItems(): Item " + Filepath + ", DataLen missmatch");
                    }
                    else
                    {
                        // Decompression was succesfull, so update size
                        LengthCompressed = (uint)Deflate.GetCompressedLength(bufUncompressed);
                    }
                }

                // Seems like a valid buf, write it
                writer.Write(buf);
            } catch (Exception e) {
                System.Diagnostics.Debug.WriteLine(e);
            }
        }