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 e)
                {
                    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.Compressed = 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);
                }

                //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()");
        }
        /// <summary>
        /// Returns a FileID for a rogue file (file that isn't archived).
        /// </summary>
        /// <param name="Entry">The entry generated for the file.</param>
        /// <returns>A FileID (see RogueFileIDs enum in Database.cs)</returns>
        public static uint GetFileID(Far3Entry Entry)
        {
            try
            {
                string Filename = Path.GetFileName(Entry.Filename);
                Filename = Filename.Replace("-", "_");
                Filename = Filename.Substring(0, Filename.IndexOf("."));

                return (uint)Enum.Parse(typeof(RogueFileIDs), Filename);
            }
            catch (ArgumentException)
            {
                return (uint)Entry.GetHashCode();
            }
        }
        /// <summary>
        /// Returns a FileID for a rogue file (file that isn't archived).
        /// </summary>
        /// <param name="Entry">The entry generated for the file.</param>
        /// <returns>A FileID (see RogueFileIDs enum in Database.cs)</returns>
        public static uint GetFileID(Far3Entry Entry)
        {
            try
            {
                string[] Dirs = Path.GetDirectoryName(Entry.Filename).Split("\\".ToCharArray());
                string Filename = Dirs[1] + "_" + Path.GetFileName(Entry.Filename);
                Filename = Filename.Replace("-", "_");
                Filename = Filename.Substring(0, Filename.IndexOf("."));

                return (uint)Enum.Parse(typeof(RogueFileIDs), Filename);
            }
            catch (ArgumentException)
            {
                return (uint)Entry.GetHashCode();
            }
        }
        private byte[] GetEntry(Far3Entry Entry)
        {
            lock (m_Reader)
            {
                //m_Reader = new BinaryReader(File.Open(m_ArchivePath, FileMode.Open, FileAccess.Read));
                m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

                isReadingSomething = true;

                if (Entry.Compressed == 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 #6
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;
            }
        }
        /// <summary>
        /// Adds files from a specified directory to a dictionary of entries.
        /// </summary>
        /// <param name="EntryDir">The directory to scan for entries.</param>
        /// <param name="Filetype">A fully qualified lowercase filetype to scan for (can be empty).</param>
        /// <param name="Entries">The Dictionary to add entries to.</param>
        private static void AddFilesFromDir(string EntryDir, string Filetype, ref Dictionary<Far3Entry, string> Entries)
        {
            string[] Dirs = Directory.GetDirectories(EntryDir);

            foreach(string Dir in Dirs)
            {
                if (Filetype != "")
                {
                    if (Dir.Contains(Filetype))
                    {
                        string[] Files = Directory.GetFiles(Dir);
                        string[] SubDirs = Directory.GetDirectories(Dir);
                        foreach (string Fle in Files)
                        {
                            if (Fle.Contains(".dat"))
                            {
                                FAR3Archive Archive = new FAR3Archive(Fle);

                                foreach (Far3Entry Entry in Archive.GetAllFAR3Entries())
                                    Entries.Add(Entry, Fle.Replace(GlobalSettings.Default.StartupPath, ""));
                            }
                            else
                            {
                                Far3Entry Entry = new Far3Entry();
                                Entry.Filename = Fle.Replace(GlobalSettings.Default.StartupPath, "");
                                Entry.FileID = HelperFuncs.GetFileID(Entry);
                                Entry.TypeID = HelperFuncs.GetTypeID(Path.GetExtension(Fle));

                                HelperFuncs.CheckCollision(Entry.FileID, Entries);

                                //Ignore fonts to minimize the risk of ID collisions.
                                if (!Entry.Filename.Contains(".ttf"))
                                {
                                    if (!Entry.Filename.Contains(".ffn"))
                                        Entries.Add(Entry, Entry.Filename);
                                }
                            }
                        }

                        foreach (string SubDir in SubDirs)
                        {
                            Files = Directory.GetFiles(SubDir);
                            foreach (string SubFle in Files)
                            {
                                if (SubFle.Contains(".dat"))
                                {
                                    FAR3Archive Archive = new FAR3Archive(SubFle);

                                    foreach (Far3Entry Entry in Archive.GetAllFAR3Entries())
                                        Entries.Add(Entry, SubFle.Replace(GlobalSettings.Default.StartupPath, ""));
                                }
                                else
                                {
                                    Far3Entry Entry = new Far3Entry();
                                    Entry.Filename = SubFle.Replace(GlobalSettings.Default.StartupPath, "");
                                    Entry.FileID = HelperFuncs.GetFileID(Entry);
                                    Entry.TypeID = HelperFuncs.GetTypeID(Path.GetExtension(SubFle));

                                    HelperFuncs.CheckCollision(Entry.FileID, Entries);

                                    //Ignore fonts to minimize the risk of ID collisions.
                                    if (!Entry.Filename.Contains(".ttf"))
                                    {
                                        if (!Entry.Filename.Contains(".ffn"))
                                            Entries.Add(Entry, Entry.Filename);
                                    }
                                }
                            }
                        }
                    }
                }
                else //Filetype was empty, so just add all filetypes found...
                {
                    string[] Files = Directory.GetFiles(Dir);
                    string[] SubDirs = Directory.GetDirectories(Dir);
                    foreach (string Fle in Files)
                    {
                        if (Fle.Contains(".dat"))
                        {
                            FAR3Archive Archive = new FAR3Archive(Fle);

                            foreach (Far3Entry Entry in Archive.GetAllFAR3Entries())
                                Entries.Add(Entry, Fle.Replace(GlobalSettings.Default.StartupPath, ""));
                        }
                        else
                        {
                            Far3Entry Entry = new Far3Entry();
                            Entry.Filename = Fle.Replace(GlobalSettings.Default.StartupPath, "");
                            Entry.FileID = HelperFuncs.GetFileID(Entry);
                            Entry.TypeID = HelperFuncs.GetTypeID(Path.GetExtension(Fle));

                            HelperFuncs.CheckCollision((ulong)(((ulong)Entry.FileID) << 32 | ((ulong)(Entry.TypeID >> 32))), Entries);

                            //Ignore fonts to minimize the risk of ID collisions.
                            if (!Entry.Filename.Contains(".ttf"))
                            {
                                if(!Entry.Filename.Contains(".ffn"))
                                    Entries.Add(Entry, Entry.Filename);
                            }
                        }
                    }

                    foreach (string SubDir in SubDirs)
                    {
                        Files = Directory.GetFiles(SubDir);
                        foreach (string SubFle in Files)
                        {
                            if (SubFle.Contains(".dat"))
                            {
                                FAR3Archive Archive = new FAR3Archive(SubFle);

                                foreach (Far3Entry Entry in Archive.GetAllFAR3Entries())
                                    Entries.Add(Entry, SubFle.Replace(GlobalSettings.Default.StartupPath, ""));
                            }
                            else
                            {
                                Far3Entry Entry = new Far3Entry();
                                Entry.Filename = SubFle.Replace(GlobalSettings.Default.StartupPath, "");
                                Entry.FileID = HelperFuncs.GetFileID(Entry);
                                Entry.TypeID = HelperFuncs.GetTypeID(Path.GetExtension(SubFle));

                                HelperFuncs.CheckCollision((ulong)(((ulong)Entry.FileID) << 32 | ((ulong)(Entry.TypeID >> 32))), Entries);

                                //Ignore fonts to minimize the risk of ID collisions.
                                if (!Entry.Filename.Contains(".ttf"))
                                {
                                    if (!Entry.Filename.Contains(".ffn"))
                                        Entries.Add(Entry, Entry.Filename);
                                }
                            }
                        }
                    }
                }
            }
        }
        private byte[] GetEntry(Far3Entry Entry)
        {
            m_Reader = new BinaryReader(File.Open(m_ArchivePath, FileMode.Open));
            m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

            if (Entry.Compressed == 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();

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

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

                return Data;
            }
            throw new FAR3Exception("FileID didn't match any in the archive! (FAR3Archive.GetItemByID())");
        }
        public byte[] GetItemByID(uint FileID)
        {
            Far3Entry[] entries = new Far3Entry[m_Entries.Count];
            m_Entries.Values.CopyTo(entries, 0);
            Far3Entry Entry = Array.Find(entries, delegate(Far3Entry entry) { return entry.FileID == FileID; });

            return GetEntry(Entry);
        }