Esempio n. 1
0
        /*
         * Reads pack header from the given reader.
         */
        public static PFHeader ReadHeader(BinaryReader reader)
        {
            PFHeader header;
            string   packIdentifier = new string (reader.ReadChars(4));

            header = new PFHeader(packIdentifier);
            int packType = reader.ReadInt32();

            header.PrecedenceByte = (byte)packType;
            // header.Type = (PackType)packType;
            header.Version = reader.ReadInt32();
            int replacedPackFilenameLength = reader.ReadInt32();

            reader.BaseStream.Seek(0x10L, SeekOrigin.Begin);
            header.FileCount = reader.ReadUInt32();
            UInt32 indexSize = reader.ReadUInt32();

            header.DataStart = header.Length + indexSize;

            if (header.PackIdentifier == "PFH4" || header.PackIdentifier == "PFH5")
            {
                header.Unknown = reader.ReadUInt32();
            }

            // go to correct position
            reader.BaseStream.Seek(header.Length, SeekOrigin.Begin);
            for (int i = 0; i < header.Version; i++)
            {
                header.ReplacedPackFileNames.Add(IOFunctions.TheadUnsafeReadZeroTerminatedAscii(reader));
            }
            header.DataStart += replacedPackFilenameLength;
            return(header);
        }
Esempio n. 2
0
        /*
         * Decode pack file at the given path.
         */
        public PackFile Open(string packFullPath)
        {
            PackFile file;
            long     sizes = 0;

            using (var reader = new BinaryReader(new FileStream(packFullPath, FileMode.Open), Encoding.ASCII))
            {
                PFHeader header = ReadHeader(reader);
                file = new PackFile(packFullPath, header);
                OnHeaderLoaded(header);

                long offset = file.Header.DataStart;
                for (int i = 0; i < file.Header.FileCount; i++)
                {
                    uint size = reader.ReadUInt32();
                    sizes += size;
                    if (file.Header.HasAdditionalInfo)
                    {
                        header.AdditionalInfo = reader.ReadUInt32();
                    }

                    if (file.Header.PackIdentifier == "PFH5")
                    {
                        reader.ReadByte();
                    }

                    string packedFileName = IOFunctions.TheadUnsafeReadZeroTerminatedAscii(reader);
                    // this is easier because we can use the Path methods
                    // under both Windows and Unix
                    packedFileName = packedFileName.Replace('\\', Path.DirectorySeparatorChar);

                    PackedFile packed = new PackedFile(file.Filepath, packedFileName, offset, size);
                    file.Add(packed);
                    packed.IsAdded = false; // Reset the flag as the file is not really added as a new file, it is loaded for the first time
                    offset        += size;
                    OnPackedFileLoaded(packed);
                }
            }
            OnFinishedLoading(file);
            file.IsModified = false;
            return(file);
        }
        /*
         * Find next file entry and return true if there is one, otherwise false.
         */
        public bool MoveNext()
        {
            currentFileIndex++;
            if (currentFileIndex > header.FileCount)
            {
                return(false);
            }
            uint size = reader.ReadUInt32();

            //FIXME this is wrong, different PFH versions have different length additionalInfo
            //TODO this is mostly duplicated with PackFileCodec.  Reducing code duplication would be wise.
            if (Header.HasAdditionalInfo)
            {
                header.AdditionalInfo = reader.ReadUInt32();
            }
            if (Header.PackIdentifier == "PFH5")
            {
                reader.ReadByte();
            }
            try {
                string packedFileName = IOFunctions.TheadUnsafeReadZeroTerminatedAscii(reader);
                // this is easier because we can use the Path methods
                // under both Windows and Unix
                packedFileName = packedFileName.Replace('\\', Path.DirectorySeparatorChar);

                currentFile = new PackedFile(filepath, packedFileName, offset, size);
                offset     += size;

                return(true);
            } catch (Exception ex) {
                Console.WriteLine("Failed enumeration of {2}/{3} file in {0}: {1}",
                                  Path.GetFileName(filepath), ex, currentFileIndex, header.FileCount);
                Console.WriteLine("Current position in file: {0}; last succesful file: {1}",
                                  reader.BaseStream.Position, Current.FullPath);
            }
            return(false);
        }