Esempio 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);
        }
Esempio n. 2
0
        /// <summary>
        /// Reads the uncompressed body of versions between 0x100 and 0x103.
        /// No compression of the body but a mess on filenames.
        /// </summary>
        /// <param name="binReader"></param>
        /// <param name="fileCount"></param>
        /// <param name="skipFiles"></param>
        /// <returns></returns>
        private bool ReadFilesVersion1(BinaryReader binReader, int fileCount, bool skipFiles)
        {
            mFileTableLength       = (ulong)(binReader.BaseStream.Length - binReader.BaseStream.Position);
            mFiletableUncompressed = binReader.ReadBytes((int)mFileTableLength);

            // Read only body?
            if (skipFiles == false)
            {
                for (int i = 0, offset = 0; i < fileCount; i++)
                {
                    var itemTableOffset = (uint)offset;
                    var entryType       = mFiletableUncompressed[offset + 12];
                    var offset2         = offset + BitConverter.ToInt32(mFiletableUncompressed, offset) + 4;

                    if (entryType == 0)
                    {
                        offset = offset2 + 17;
                        continue;
                    }

                    var nameLen = mFiletableUncompressed[offset] - 6;

                    // These are client limits
                    if (nameLen >= GrfMaxFilenameLength)
                    {
                        throw new Exception("Filename on index " + i + " is " + nameLen + " bytes long, max length is " + GrfMaxFilenameLength + ".");
                    }

                    var nameBuf = new byte[nameLen];
                    Buffer.BlockCopy(mFiletableUncompressed, offset + 6, nameBuf, 0, nameLen);

                    var name = RoGrfHelper.DecodeFileName(nameBuf);

                    // Check and fix the filename
                    if (name.Contains('\0'))
                    {
                        name = name.Substring(0, name.IndexOf('\0'));
                    }

                    var compressedLenAligned = (uint)(BitConverter.ToInt32(mFiletableUncompressed, offset2 + 4) - 37579);
                    var realLen = (uint)BitConverter.ToInt32(mFiletableUncompressed, offset2 + 8);
                    var pos     = (uint)BitConverter.ToInt32(mFiletableUncompressed, offset2 + 13);

                    var cycle         = 0;
                    var compressedLen = 0;

                    if (name.Contains("."))
                    {
                        var ext = "." + name.Split('.').Last().ToLower();
                        compressedLen = BitConverter.ToInt32(mFiletableUncompressed, offset2) - BitConverter.ToInt32(mFiletableUncompressed, offset2 + 8) - 715;

                        if (ext != ".gnd" && ext != ".gat" && ext != ".act" && ext != ".str")
                        {
                            cycle = 1;
                            for (int j = 10; compressedLen >= j; j *= 10)
                            {
                                cycle++;
                            }
                        }
                    }

                    name = Tools.UnifyPath(name);
                    var item = new RoGrfFileItem {
                        TableOffset           = itemTableOffset,
                        Index                 = Files.Count,
                        Filepath              = name,
                        LengthCompressed      = (uint)compressedLen,
                        LengthCompressedAlign = compressedLenAligned,
                        LengthUnCompressed    = realLen,
                        Flags                 = entryType,
                        // base offset + header length
                        DataOffset = pos + GrfHeaderLen
                    };

                    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);
        }