Represents an entry in a FAR3 archive.
Beispiel #1
0
        /// <summary>
        /// Creates a new FAR3Archive instance from a path.
        /// </summary>
        /// <param name="Path">The path to the archive.</param>
        public FAR3Archive(string Path)
        {
            m_ArchivePath = Path;

            if (isReadingSomething == false)
            {
                isReadingSomething = true;

                try
                {
                    m_Reader = new BinaryReader(File.Open(Path, FileMode.Open, FileAccess.Read, FileShare.Read));
                }
                catch (Exception)
                {
                    throw new FAR3Exception("Could not open the specified archive - " + Path + "! (FAR3Archive())");
                }

                string Header = Encoding.ASCII.GetString(m_Reader.ReadBytes(8));
                uint Version = m_Reader.ReadUInt32();

                if ((Header != "FAR!byAZ") || (Version != 3))
                {
                    throw new FAR3Exception("Archive wasn't a valid FAR V.3 archive! (FAR3Archive())");
                }

                uint ManifestOffset = m_Reader.ReadUInt32();
                m_ManifestOffset = ManifestOffset;

                m_Reader.BaseStream.Seek(ManifestOffset, SeekOrigin.Begin);

                uint NumFiles = m_Reader.ReadUInt32();

                for (int i = 0; i < NumFiles; i++)
                {
                    Far3Entry Entry = new Far3Entry();
                    Entry.DecompressedFileSize = m_Reader.ReadUInt32();
                    byte[] Dummy = m_Reader.ReadBytes(3);
                    Entry.CompressedFileSize = (uint)((Dummy[0] << 0) | (Dummy[1] << 8) | (Dummy[2]) << 16);
                    Entry.DataType = m_Reader.ReadByte();
                    Entry.DataOffset = m_Reader.ReadUInt32();
                    //Entry.HasFilename = m_Reader.ReadUInt16();
                    Entry.IsCompressed = m_Reader.ReadByte();
                    Entry.AccessNumber = m_Reader.ReadByte();
                    Entry.FilenameLength = m_Reader.ReadUInt16();
                    Entry.TypeID = m_Reader.ReadUInt32();
                    Entry.FileID = m_Reader.ReadUInt32();
                    Entry.Filename = Encoding.ASCII.GetString(m_Reader.ReadBytes(Entry.FilenameLength));

                    if (!m_Entries.ContainsKey(Entry.Filename))
                        m_Entries.Add(Entry.Filename, Entry);
                    m_EntriesList.Add(Entry);

                    m_EntryByID.Add(Entry.FileID, Entry); //isn't this a bad idea? i have a feeling this is a bad idea...
                }

                //Keep the stream open, it helps peformance.
                //m_Reader.Close();
                isReadingSomething = false;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets an entry's data from a Far3Entry instance.
        /// </summary>
        /// <param name="Entry">The Far3Entry instance.</param>
        /// <returns>The entry's data.</returns>
        public byte[] GetEntry(Far3Entry Entry)
        {
            lock (m_Reader)
            {
                m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

                isReadingSomething = true;

                if (Entry.IsCompressed == 0x01)
                {
                    m_Reader.ReadBytes(9);
                    uint   Filesize      = m_Reader.ReadUInt32();
                    ushort CompressionID = m_Reader.ReadUInt16();

                    if (CompressionID == 0xFB10)
                    {
                        byte[] Dummy            = m_Reader.ReadBytes(3);
                        uint   DecompressedSize = (uint)((Dummy[0] << 0x10) | (Dummy[1] << 0x08) | +Dummy[2]);

                        Decompresser Dec = new Decompresser();
                        Dec.CompressedSize   = Filesize;
                        Dec.DecompressedSize = DecompressedSize;

                        byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)Filesize));
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(DecompressedData);
                    }
                    else
                    {
                        m_Reader.BaseStream.Seek((m_Reader.BaseStream.Position - 15), SeekOrigin.Begin);

                        byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(Data);
                    }
                }
                else
                {
                    byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                    //m_Reader.Close();

                    isReadingSomething = false;

                    return(Data);
                }
            }

            throw new FAR3Exception("FAR3Entry didn't exist in archive - FAR3Archive.GetEntry()");
        }
Beispiel #3
0
        /// <summary>
        /// Gets an entry's data from a Far3Entry instance.
        /// </summary>
        /// <param name="Entry">The Far3Entry instance.</param>
        /// <returns>The entry's data.</returns>
        public byte[] GetEntry(Far3Entry Entry)
        {
            lock (m_Reader)
            {
                m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

                isReadingSomething = true;

                if (Entry.IsCompressed == 0x01)
                {
                    m_Reader.ReadBytes(9);
                    uint Filesize = m_Reader.ReadUInt32();
                    ushort CompressionID = m_Reader.ReadUInt16();

                    if (CompressionID == 0xFB10)
                    {
                        byte[] Dummy = m_Reader.ReadBytes(3);
                        uint DecompressedSize = (uint)((Dummy[0] << 0x10) | (Dummy[1] << 0x08) | +Dummy[2]);

                        Decompresser Dec = new Decompresser();
                        Dec.CompressedSize = Filesize;
                        Dec.DecompressedSize = DecompressedSize;

                        byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)Filesize));
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return DecompressedData;
                    }
                    else
                    {
                        m_Reader.BaseStream.Seek((m_Reader.BaseStream.Position - 15), SeekOrigin.Begin);

                        byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return Data;
                    }
                }
                else
                {
                    byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                    //m_Reader.Close();

                    isReadingSomething = false;

                    return Data;
                }
            }

            throw new FAR3Exception("FAR3Entry didn't exist in archive - FAR3Archive.GetEntry()");
        }
Beispiel #4
0
        /// <summary>
        /// Creates a new FAR3Archive instance from a path.
        /// </summary>
        /// <param name="Path">The path to the archive.</param>
        public FAR3Archive(string Path)
        {
            m_ArchivePath = Path;

            if (isReadingSomething == false)
            {
                isReadingSomething = true;

                try
                {
                    m_Reader = new BinaryReader(File.Open(Path, FileMode.Open, FileAccess.Read, FileShare.Read));
                }
                catch (Exception ex)
                {
                    throw new FAR3Exception("Could not open the specified archive - " + Path + "! (FAR3Archive())");
                }

                string Header  = Encoding.ASCII.GetString(m_Reader.ReadBytes(8));
                uint   Version = m_Reader.ReadUInt32();

                if ((Header != "FAR!byAZ") || (Version != 3))
                {
                    throw new FAR3Exception("Archive wasn't a valid FAR V.3 archive! (FAR3Archive())");
                }

                uint ManifestOffset = m_Reader.ReadUInt32();
                m_ManifestOffset = ManifestOffset;

                m_Reader.BaseStream.Seek(ManifestOffset, SeekOrigin.Begin);

                uint NumFiles = m_Reader.ReadUInt32();

                for (int i = 0; i < NumFiles; i++)
                {
                    var Entry = new Far3Entry();
                    Entry.DecompressedFileSize = m_Reader.ReadUInt32();
                    byte[] Dummy = m_Reader.ReadBytes(3);
                    Entry.CompressedFileSize = (uint)((Dummy[0] << 0) | (Dummy[1] << 8) | (Dummy[2]) << 16);
                    Entry.DataType           = m_Reader.ReadByte();
                    Entry.DataOffset         = m_Reader.ReadUInt32();
                    //Entry.HasFilename = m_Reader.ReadUInt16();
                    Entry.IsCompressed   = m_Reader.ReadByte();
                    Entry.AccessNumber   = m_Reader.ReadByte();
                    Entry.FilenameLength = m_Reader.ReadUInt16();
                    Entry.TypeID         = m_Reader.ReadUInt32();
                    Entry.FileID         = m_Reader.ReadUInt32();
                    Entry.Filename       = Encoding.ASCII.GetString(m_Reader.ReadBytes(Entry.FilenameLength));

                    if (!m_Entries.ContainsKey(Entry.Filename))
                    {
                        m_Entries.Add(Entry.Filename, Entry);
                    }
                    m_EntriesList.Add(Entry);

                    m_EntryByID.Add(Entry.FileID, Entry); //isn't this a bad idea? i have a feeling this is a bad idea...

                    //If file being processed is a texture.dat file continue, else skip
                    //Adds the ability to use custom skins in the TSO format.
                    if (Path.Contains("textures.dat") && File.Exists("gamedata/skins/" + Entry.Filename))
                    {
                        Entry.IsOverride   = true;
                        Entry.IsCompressed = (byte)0;
                        FileInfo fileInfo = new FileInfo("gamedata/skins/" + Entry.Filename);
                        Entry.DecompressedFileSize = (uint)fileInfo.Length;
                    }
                }

                //Keep the stream open, it helps peformance.
                //m_Reader.Close();
                isReadingSomething = false;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Gets an entry's data from a Far3Entry instance.
        /// </summary>
        /// <param name="Entry">The Far3Entry instance.</param>
        /// <returns>The entry's data.</returns>
        public byte[] GetEntry(Far3Entry Entry)
        {
            lock (m_Reader)
            {
                m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

                isReadingSomething = true;

                if (Entry.IsCompressed == 0x01)
                {
                    m_Reader.ReadBytes(9);
                    uint   Filesize      = m_Reader.ReadUInt32();
                    ushort CompressionID = m_Reader.ReadUInt16();

                    if (CompressionID == 0xFB10)
                    {
                        byte[] Dummy            = m_Reader.ReadBytes(3);
                        uint   DecompressedSize = (uint)((Dummy[0] << 0x10) | (Dummy[1] << 0x08) | +Dummy[2]);

                        var Dec = new Decompresser();
                        Dec.CompressedSize   = Filesize;
                        Dec.DecompressedSize = DecompressedSize;

                        byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)Filesize));
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(DecompressedData);
                    }
                    else
                    {
                        m_Reader.BaseStream.Seek((m_Reader.BaseStream.Position - 15), SeekOrigin.Begin);

                        byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(Data);
                    }
                }
                //if the file needs to use an override, load it from gamedata instead.
                if (Entry.IsOverride)
                {
                    BinaryReader binaryReader = new BinaryReader((Stream)File.Open("gamedata/skins/" + Entry.Filename, FileMode.Open, FileAccess.Read, FileShare.Read));
                    byte[]       Data         = binaryReader.ReadBytes((int)Entry.DecompressedFileSize);
                    binaryReader.Close();

                    //done
                    isReadingSomething             = false;
                    FAR3Archive.isReadingSomething = false;

                    return(Data);
                }
                else
                {
                    byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                    //m_Reader.Close();

                    isReadingSomething = false;

                    return(Data);
                }
            }

            throw new FAR3Exception("FAR3Entry didn't exist in archive - FAR3Archive.GetEntry()");
        }
        /// <summary>
        /// Creates a new FAR3Archive instance from a path.
        /// </summary>
        /// <param name="Path">The path to the archive.</param>
        public FAR3Archive(string Path)
        {
            m_ArchivePath = Path;

            if (isReadingSomething == false)
            {
                isReadingSomething = true;

                try
                {
                    m_Reader = new BinaryReader(File.Open(Path, FileMode.Open, FileAccess.Read, FileShare.Read));
                }
                catch (Exception)
                {
                    throw new FAR3Exception("Could not open the specified archive - " + Path + "! (FAR3Archive())");
                }

                string Header  = Encoding.ASCII.GetString(m_Reader.ReadBytes(8));
                uint   Version = m_Reader.ReadUInt32();

                if ((Header != "FAR!byAZ") || (Version != 3))
                {
                    throw new FAR3Exception("Archive wasn't a valid FAR V.3 archive! (FAR3Archive())");
                }

                uint ManifestOffset = m_Reader.ReadUInt32();
                m_ManifestOffset = ManifestOffset;

                m_Reader.BaseStream.Seek(ManifestOffset, SeekOrigin.Begin);

                uint NumFiles = m_Reader.ReadUInt32();

                for (int i = 0; i < NumFiles; i++)
                {
                    Far3Entry Entry = new Far3Entry();
                    Entry.DecompressedFileSize = m_Reader.ReadUInt32();
                    byte[] Dummy = m_Reader.ReadBytes(3);
                    Entry.CompressedFileSize = (uint)((Dummy[0] << 0) | (Dummy[1] << 8) | (Dummy[2]) << 16);
                    Entry.DataType           = m_Reader.ReadByte();
                    Entry.DataOffset         = m_Reader.ReadUInt32();
                    //Entry.HasFilename = m_Reader.ReadUInt16();
                    Entry.IsCompressed   = m_Reader.ReadByte();
                    Entry.AccessNumber   = m_Reader.ReadByte();
                    Entry.FilenameLength = m_Reader.ReadUInt16();
                    Entry.TypeID         = m_Reader.ReadUInt32();
                    Entry.FileID         = m_Reader.ReadUInt32();
                    Entry.Filename       = Encoding.ASCII.GetString(m_Reader.ReadBytes(Entry.FilenameLength));

                    if (!m_Entries.ContainsKey(Entry.Filename))
                    {
                        m_Entries.Add(Entry.Filename, Entry);
                    }
                    m_EntriesList.Add(Entry);

                    m_EntryByID.Add(Entry.FileID, Entry); //isn't this a bad idea? i have a feeling this is a bad idea...
                }

                //Keep the stream open, it helps peformance.
                //m_Reader.Close();
                isReadingSomething = false;
            }
        }