private Stream Decompress(FAR3Entry Entry) { m_Reader.ReadBytes(9); uint CompressedSize = m_Reader.ReadUInt32(); ushort CompressionID = m_Reader.ReadUShort(); 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 = CompressedSize; Dec.DecompressedSize = DecompressedSize; byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)CompressedSize)); MemoryStream MemStream = new MemoryStream(DecompressedData); MemStream.Seek(0, SeekOrigin.Begin); return(MemStream); } else { m_Reader.Seek(m_Reader.Position - 15); return(new MemoryStream(m_Reader.ReadBytes((int)Entry.DecompressedDataSize))); } }
/// <summary> /// Reads all the entries in the archive into memory. /// </summary> /// <param name="ThrowException">Wether or not to throw an exception if the archive was not a FAR3. If false, function will return.</param> public bool ReadArchive(bool ThrowException) { m_FinishedReading.Reset(); if (m_Reader == null) { m_Reader = new FileReader(m_Path, false); } lock (m_Reader) { ASCIIEncoding Enc = new ASCIIEncoding(); string MagicNumber = Enc.GetString(m_Reader.ReadBytes(8)); if (!MagicNumber.Equals("FAR!byAZ", StringComparison.InvariantCultureIgnoreCase)) { if (ThrowException) { throw new FAR3Exception("MagicNumber was wrong - FAR3Archive.cs!"); } else { m_Reader.Close(); return(false); } } m_Reader.ReadUInt32(); //Version. m_Reader.Seek((long)m_Reader.ReadUInt32()); uint NumFiles = m_Reader.ReadUInt32(); for (int i = 0; i < NumFiles; i++) { FAR3Entry Entry = new FAR3Entry(); Entry.DecompressedDataSize = m_Reader.ReadUInt32(); byte[] Dummy = m_Reader.ReadBytes(3); Entry.CompressedDataSize = (uint)((Dummy[0] << 0) | (Dummy[1] << 8) | (Dummy[2]) << 16); m_Reader.ReadByte(); //Unknown. Entry.DataOffset = m_Reader.ReadUInt32(); Entry.Flags = m_Reader.ReadUShort(); Entry.FileNameLength = m_Reader.ReadUShort(); Entry.TypeID = m_Reader.ReadUInt32(); Entry.FileID = m_Reader.ReadUInt32(); Entry.Filename = Enc.GetString(m_Reader.ReadBytes(Entry.FileNameLength)); UniqueFileID ID = new UniqueFileID(Entry.TypeID, Entry.FileID); if (!m_Entries.ContainsKey(ID.UniqueID)) { m_Entries.AddOrUpdate(ID.UniqueID, Entry, (Key, ExistingValue) => ExistingValue = Entry); } } } m_FinishedReading.Set(); return(true); }
/// <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(); } }
/// <summary> /// Returns an entry in this archive as a Stream instance. /// Throws a FAR3Exception if entry was not found. /// </summary> /// <param name="ID">ID of the entry to grab from archive.</param> /// <returns>The entry's data as a Stream instance.</returns> public Stream GrabEntry(ulong ID) { m_FinishedReading.WaitOne(); if (!ContainsEntry(ID)) { throw new FAR3Exception("Couldn't find entry - FAR3Archive.cs!"); } FAR3Entry Entry = m_Entries[ID]; lock (m_Reader) { m_Reader.Seek((long)Entry.DataOffset); switch (Entry.TypeID) { case 1: //BMP case 2: //TGA case 5: //SKEL case 7: //ANIM case 9: //MESH case 11: //BND case 12: //APR case 13: //OFT case 15: //PO case 16: //COL case 18: //HAG case 20: //JPG case 24: //PNG return(Decompress(Entry)); case 14: //PNG, uncompressed default: MemoryStream MemStream = new MemoryStream(m_Reader.ReadBytes((int)Entry.DecompressedDataSize)); MemStream.Seek(0, SeekOrigin.Begin); return(MemStream); } } }
private Stream Decompress(FAR3Entry Entry) { m_Reader.ReadBytes(9); uint CompressedSize = m_Reader.ReadUInt32(); ushort CompressionID = m_Reader.ReadUShort(); 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 = CompressedSize; Dec.DecompressedSize = DecompressedSize; byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)CompressedSize)); MemoryStream MemStream = new MemoryStream(DecompressedData); MemStream.Seek(0, SeekOrigin.Begin); return MemStream; } else { m_Reader.Seek(m_Reader.Position - 15); return new MemoryStream(m_Reader.ReadBytes((int)Entry.DecompressedDataSize)); } }
/// <summary> /// Reads all the entries in the archive into memory. /// </summary> /// <param name="ThrowException">Wether or not to throw an exception if the archive was not a FAR3. If false, function will return.</param> public bool ReadArchive(bool ThrowException) { m_FinishedReading.Reset(); if (m_Reader == null) m_Reader = new FileReader(m_Path, false); lock (m_Reader) { ASCIIEncoding Enc = new ASCIIEncoding(); string MagicNumber = Enc.GetString(m_Reader.ReadBytes(8)); if (!MagicNumber.Equals("FAR!byAZ", StringComparison.InvariantCultureIgnoreCase)) { if (ThrowException) throw new FAR3Exception("MagicNumber was wrong - FAR3Archive.cs!"); else { m_Reader.Close(); return false; } } m_Reader.ReadUInt32(); //Version. m_Reader.Seek((long)m_Reader.ReadUInt32()); uint NumFiles = m_Reader.ReadUInt32(); for (int i = 0; i < NumFiles; i++) { FAR3Entry Entry = new FAR3Entry(); Entry.DecompressedDataSize = m_Reader.ReadUInt32(); byte[] Dummy = m_Reader.ReadBytes(3); Entry.CompressedDataSize = (uint)((Dummy[0] << 0) | (Dummy[1] << 8) | (Dummy[2]) << 16); m_Reader.ReadByte(); //Unknown. Entry.DataOffset = m_Reader.ReadUInt32(); Entry.Flags = m_Reader.ReadUShort(); Entry.FileNameLength = m_Reader.ReadUShort(); Entry.TypeID = m_Reader.ReadUInt32(); Entry.FileID = m_Reader.ReadUInt32(); Entry.Filename = Enc.GetString(m_Reader.ReadBytes(Entry.FileNameLength)); UniqueFileID ID = new UniqueFileID(Entry.TypeID, Entry.FileID); if (!m_Entries.ContainsKey(ID.UniqueID)) m_Entries.AddOrUpdate(ID.UniqueID, Entry, (Key, ExistingValue) => ExistingValue = Entry); } } m_FinishedReading.Set(); return true; }
/// <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); Archive.ReadArchive(true); foreach (FAR3Entry Entry in Archive.GrabAllEntries()) 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); Archive.ReadArchive(false); foreach (FAR3Entry Entry in Archive.GrabAllEntries()) 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); Archive.ReadArchive(true); foreach (FAR3Entry Entry in Archive.GrabAllEntries()) 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); Archive.ReadArchive(true); foreach (FAR3Entry Entry in Archive.GrabAllEntries()) 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); } } } } } } }