Example #1
0
        /// <summary>
        /// Writes the grf to the given Filename
        /// </summary>
        /// <param name="destinationPath"></param>
        /// <param name="repack"> </param>
        /// <returns></returns>
        public bool WriteGrf(string destinationPath, bool repack)
        {
            // Write to temp file
            string tmpDestinationPath = destinationPath + "tmp";

            using (FileStream fs = File.OpenWrite(tmpDestinationPath)) {
                using (mWriter = new BinaryWriter(fs)) {
                    int    iLengthUnCompressed;
                    byte[] fileTableDataCompressed;

                    using (var fileTableStream = new MemoryStream()) {
                        mWriter.Seek((int)GrfHeaderLen, SeekOrigin.Begin);

                        // Write file binary data & temporary write file table
                        int filesWritten;
                        if (repack || AlwaysRepack)
                        {
                            filesWritten = WriteFileData(fileTableStream);
                        }
                        else
                        {
                            filesWritten = WriteFileDataDirty(fileTableStream);
                        }

                        // Save the offset after writing binary data
                        var thisPos = (int)mWriter.BaseStream.Position;
                        // Write grf header
                        mWriter.Seek(0, SeekOrigin.Begin);
                        foreach (var c in MagicHeader)
                        {
                            mWriter.Write((byte)c);                             // header (15)
                        }
                        foreach (var c in AllowEncrypt)
                        {
                            mWriter.Write((byte)c);                                  // encrypt (15)
                        }
                        mWriter.Write((uint)(thisPos - GrfHeaderLen));               // tableOffset
                        mWriter.Write(mFilecountNumber1);
                        mWriter.Write((uint)(filesWritten + mFilecountNumber1 + 7)); // number2
                        // Always default version
                        Version = GrfDefaultVersion;
                        mWriter.Write(Version);                         // GRF Version
                        mWriter.Seek(thisPos, SeekOrigin.Begin);

                        // Compress file table data
                        iLengthUnCompressed     = (int)fileTableStream.Length;
                        fileTableDataCompressed = Deflate.Compress(fileTableStream.ToArray(), true);
                    }

                    // Write length and data
                    mWriter.Write(fileTableDataCompressed.Length);                             // compressed
                    mWriter.Write(iLengthUnCompressed);                                        // uncompressed
                    mWriter.Write(fileTableDataCompressed, 0, fileTableDataCompressed.Length); // data itself
                }
            }

            // If we want to overwrite the previous opened GRF, close it first
            if (mFilepath == destinationPath)
            {
                Flush();
            }

            // Ensure nothing blocks the move
            File.Delete(destinationPath);
            // Move it finally
            File.Move(destinationPath + "tmp", destinationPath);

            // Fore clean up
            GC.Collect();

            return(true);
        }
Example #2
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);
            }
        }