public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); long offset = 8; var dir = new List <Entry>(); int i = 0; while (offset < file.MaxOffset) { uint size = file.View.ReadUInt32(offset); offset += 4; var entry = new Entry { Name = string.Format("{0}#{1:D4}", base_name, i++), Offset = offset, Size = size }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } uint signature = file.View.ReadUInt32(offset); var res = AutoEntry.DetectFileType(signature); entry.ChangeType(res); offset += size; dir.Add(entry); } return(new ArcFile(file, this, dir)); }
void DetectFileTypes(Stream file, IList <Entry> dir) { foreach (PackedEntry entry in dir) { file.Position = entry.Offset; uint signature = ReadUInt32(file); IResource res = null; if (0x584F59 == signature) // 'YOX' { if (0 != (2 & ReadUInt32(file))) { entry.IsPacked = true; entry.UnpackedSize = ReadUInt32(file); entry.Offset += 0x10; entry.Size -= 0x10; file.Position = entry.Offset; using (var input = new ZLibStream(file, CompressionMode.Decompress, true)) signature = ReadUInt32(input); res = AutoEntry.DetectFileType(signature); } } else { res = AutoEntry.DetectFileType(signature); } if (res != null) { entry.Name = Path.ChangeExtension(entry.Name, res.Extensions.FirstOrDefault()); entry.Type = res.Type; } } }
public void DetectTypes(IEnumerable <Entry> dir, Func <Entry, uint> get_signature) { foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type))) { if (entry.Name.HasAnyOfExtensions("txt", "nut")) { entry.Type = "script"; continue; } uint signature = get_signature(entry); var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.ChangeType(res); } else if (0x474E4D8A == signature) { entry.Name = Path.ChangeExtension(entry.Name, "mng"); } else if (entry.Name.StartsWith("script/")) { entry.Type = "script"; } } }
void DetectFileTypes(ArcView file, List <Entry> dir) { foreach (var entry in dir) { var offset = entry.Offset; var signature = file.View.ReadUInt32(offset); if (entry.Size > 0x10 && 0x4C495243 == signature) // 'CRIL' { uint packed_size = file.View.ReadUInt32(offset + 12); if (packed_size < entry.Size - 0x10) { signature = file.View.ReadUInt32(offset + 0x10 + packed_size); if (0x10 == signature) { signature = file.View.ReadUInt32(offset + 0x10 + packed_size + signature); } } } var res = AutoEntry.DetectFileType(signature); if (null != res) { entry.Type = res.Type; entry.Name = Path.ChangeExtension(entry.Name, res.Extensions.FirstOrDefault()); } } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } List <Entry> dir = null; foreach (var name_size in NameSizes) { uint index_size = (uint)((name_size + 8) * count); uint first_offset = file.View.ReadUInt32(4 + name_size + 4); if (first_offset == (4 + index_size) && first_offset < file.MaxOffset) { if (null == dir) { dir = new List <Entry> (count); } else { dir.Clear(); } long index_offset = 4; for (int i = 0; i < count; ++i) { string name = file.View.ReadString(index_offset, name_size); if (string.IsNullOrWhiteSpace(name)) { goto CheckNextLength; } index_offset += name_size; uint offset = file.View.ReadUInt32(index_offset + 4); var entry = new AutoEntry(name, () => { uint signature = file.View.ReadUInt32(offset); if (1 == signature) { return(s_GraFormat.Value); } return(AutoEntry.DetectFileType(signature)); }); entry.Offset = offset; entry.Size = file.View.ReadUInt32(index_offset); if (offset <= index_size || !entry.CheckPlacement(file.MaxOffset)) { goto CheckNextLength; } dir.Add(entry); index_offset += 8; } return(new ArcFile(file, this, dir)); } CheckNextLength: ; } return(null); }
static void SetEntryType(Entry entry, uint signature) { var res = AutoEntry.DetectFileType(signature); if (null != res) { entry.ChangeType(res); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat") || !Path.GetFileName(file.Name).StartsWith("arc", StringComparison.InvariantCultureIgnoreCase)) { return(null); } long current_offset = 0; var dir = new List <Entry>(); while (current_offset < file.MaxOffset) { uint size = file.View.ReadUInt32(current_offset); if (0 == size) { break; } uint name_length = file.View.ReadUInt16(current_offset + 8); if (0 == name_length || name_length > 0x100) { return(null); } var name = file.View.ReadString(current_offset + 10, name_length); if (0 == name.Length) { return(null); } current_offset += 10 + name_length; if (current_offset + size > file.MaxOffset) { return(null); } var entry = new Entry { Name = name, Offset = current_offset, Size = size, }; uint signature = file.View.ReadUInt32(current_offset); if (file.View.AsciiEqual(current_offset + 4, "GWD")) { entry.Type = "image"; entry.Name = Path.ChangeExtension(entry.Name, "gwd"); } else { var res = AutoEntry.DetectFileType(signature); entry.ChangeType(res); } dir.Add(entry); current_offset += size; } if (0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (file.View.ReadUInt32(4) != 0) { return(null); } int count = file.View.ReadInt32(0xC); if (!IsSaneCount(count)) { return(null); } uint index_offset = file.View.ReadUInt32(8); if (index_offset >= file.MaxOffset || index_offset + count * 4 > file.MaxOffset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new Entry { Name = string.Format("{0}#{1:D5}", base_name, i), Offset = file.View.ReadUInt32(index_offset) + 0x20, }; if (entry.Offset > index_offset) { return(null); } dir.Add(entry); index_offset += 4; } for (int i = 1; i < count; ++i) { dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset); } dir[count - 1].Size = (uint)(index_offset - dir[count - 1].Offset); foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); if (0x544F48 == signature) // 'HOT' { if (0x21 == (file.View.ReadByte(entry.Offset + 7) & 0x21)) { entry.Type = "image"; } } else { entry.ChangeType(AutoEntry.DetectFileType(signature)); } } return(new ArcFile(file, this, dir)); }
void DetectFileTypes(ArcView file, List <Entry> dir) { using (var input = file.CreateStream()) using (var reader = new ArcView.Reader(input)) { var buffer = new byte[0x10]; foreach (PackedEntry entry in dir) { input.Position = entry.Offset; uint packed_size = reader.ReadUInt32(); entry.UnpackedSize = reader.ReadUInt32(); entry.Offset += 8; if (0 == packed_size) { entry.Size = entry.UnpackedSize; } else { entry.IsPacked = true; entry.Size = packed_size; } if (entry.Size < 0x10) { continue; } uint signature; if (entry.IsPacked) { UnpackEntry(input, buffer); signature = LittleEndian.ToUInt32(buffer, 0); } else { signature = reader.ReadUInt32(); } IResource res; if (0x020000 == signature || 0x0A0000 == signature) { res = ImageFormat.Tga; } else { res = AutoEntry.DetectFileType(signature); } if (null != res) { entry.Type = res.Type; var ext = res.Extensions.FirstOrDefault(); if (!string.IsNullOrEmpty(ext)) { entry.Name = Path.ChangeExtension(entry.Name, ext); } } } } }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "KO ARC20")) { return(null); } int count = file.View.ReadInt32(12); if (!IsSaneCount(count)) { return(null); } uint index_size = 0x80 * (uint)count; if (index_size > file.View.Reserve(0x10, index_size)) { return(null); } var dir = new List <Entry> (count); long index_offset = 0x10; long base_offset = index_offset + index_size; for (uint i = 0; i < count; ++i) { string name = file.View.ReadString(index_offset, 0x60); var offset = base_offset + file.View.ReadUInt32(index_offset + 0x60); var entry = new PackedEntry { Name = name, Offset = offset }; entry.Size = file.View.ReadUInt32(index_offset + 0x64); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x80; } foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.Type = res.Type; } else if (file.View.AsciiEqual(entry.Offset, "BSE 1.")) { entry.Type = "image"; } else if (file.View.AsciiEqual(entry.Offset + 4, "bw ")) { entry.Type = "audio"; } } return(new ArcFile(file, this, dir)); }
static internal void DetectFileType(ArcView file, Entry entry) { uint signature = file.View.ReadUInt32(entry.Offset); var res = AutoEntry.DetectFileType(signature); if (null != res) { entry.ChangeType(res); } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if ((count & 0xFFFF) != 0) { return(null); } count = (count >> 16) - 1; if (!IsSaneCount(count)) { return(null); } uint index_offset = 0xC; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadUInt32(index_offset).ToString("D5"); var entry = new PackedEntry { Name = name, Offset = file.View.ReadUInt32(index_offset + 4) << 11, Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 12; } foreach (PackedEntry entry in dir) { uint signature; if (entry.Size > 13 && file.View.AsciiEqual(entry.Offset + 2, "ike")) { int unpacked_size = IkeReader.DecodeSize(file.View.ReadByte(entry.Offset + 10), file.View.ReadByte(entry.Offset + 11), file.View.ReadByte(entry.Offset + 12)); entry.IsPacked = true; entry.UnpackedSize = (uint)unpacked_size; signature = file.View.ReadUInt32(entry.Offset + 0xF); entry.Offset += 13; entry.Size -= 13; } else { signature = file.View.ReadUInt32(entry.Offset); } entry.ChangeType(AutoEntry.DetectFileType(signature)); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(0, "MD")) { return(null); } uint entry_length = file.View.ReadUInt16(4); int count = file.View.ReadUInt16(6); if (entry_length <= 8 || !IsSaneCount(count)) { return(null); } uint name_length = entry_length - 8; uint index_offset = 0x10; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, name_length); index_offset += name_length; uint offset = file.View.ReadUInt32(index_offset + 4); var entry = new AutoEntry(name, () => { uint signature = file.View.ReadUInt32(offset); if (0x4259 == (signature & 0xFFFF)) // 'YB' { return(PrsFormat.Value); } return(AutoEntry.DetectFileType(signature)); }); entry.Size = file.View.ReadUInt32(index_offset); entry.Offset = offset; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 8; } var base_name = Path.GetFileNameWithoutExtension(file.Name); if (base_name.EndsWith("_scr", StringComparison.OrdinalIgnoreCase) && KnownSchemes.Count > 0) { var encryption = QueryEncryption(file.Name); if (encryption != null) { return(new ScrMedArchive(file, this, dir, encryption)); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); int index_offset = 4; int index_end = 4 + 8 * count; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new PackedEntry { Offset = file.View.ReadUInt32(index_offset), Size = file.View.ReadUInt32(index_offset + 4), }; if (entry.Offset < index_end || !entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.Name = string.Format("{0}#{1:D5}", base_name, i); dir.Add(entry); index_offset += 8; } foreach (PackedEntry entry in dir) { var n = file.View.ReadInt32(entry.Offset); if (n <= 0) { return(null); } var offset = file.View.ReadUInt32(entry.Offset + 4); var size = file.View.ReadUInt32(entry.Offset + 8); entry.Offset += offset; entry.Size = size & 0x3FFFFFFF; entry.IsPacked = 2 != (size >> 30); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } var res = AutoEntry.DetectFileType(file.View.ReadUInt32(entry.Offset)); if (res != null) { entry.ChangeType(res); } } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(0); if (!IsSaneCount(count)) { return(null); } uint index_size = (uint)count * 4 + 8; if (index_size > file.View.Reserve(0, index_size)) { return(null); } uint index_offset = 4; uint offset = file.View.ReadUInt32(index_offset); if (offset != index_size) { return(null); } uint last_offset = file.View.ReadUInt32(index_size - 4); if (last_offset != file.MaxOffset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new Entry { Name = string.Format("{0}#{1:D4}", base_name, i), Offset = offset, }; offset = file.View.ReadUInt32(index_offset); entry.Size = (uint)(offset - entry.Offset); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); entry.ChangeType(AutoEntry.DetectFileType(signature)); } return(new ArcFile(file, this, dir)); }
internal void DetectFileTypes(ArcView file, IEnumerable <Entry> dir) { var buffer = new byte[4]; foreach (var entry in dir.Where(e => e.Size > 4)) { file.View.Read(entry.Offset, buffer, 0, 4); Decrypt(buffer); uint signature = buffer.ToUInt32(0); var res = AutoEntry.DetectFileType(signature); entry.ChangeType(res); } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt16(0); if (!IsSaneCount(count)) { return(null); } uint index_offset = 2; uint next_offset = file.View.ReadUInt32(index_offset); if (next_offset != count * 4 + 6) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { index_offset += 4; var entry = new Entry { Name = string.Format("{0}#{1:D4}", base_name, i), Offset = next_offset, }; next_offset = file.View.ReadUInt32(index_offset); if (next_offset < entry.Offset) { return(null); } entry.Size = (uint)(next_offset - entry.Offset); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); if ((signature & 0xFFFF) == 0x4246) // 'FB' { entry.Type = "image"; } else { entry.ChangeType(AutoEntry.DetectFileType(signature)); } } return(new ArcFile(file, this, dir)); }
void DetectFileTypes(ArcView file, List <Entry> dir) { using (var input = file.CreateStream()) { var buffer = new byte[0x10]; foreach (PackedEntry entry in dir) { input.Position = entry.Offset; uint packed_size = input.ReadUInt32(); entry.UnpackedSize = input.ReadUInt32(); entry.Offset += 8; if (0 == packed_size) { entry.Size = entry.UnpackedSize; } else { entry.IsPacked = true; entry.Size = packed_size; } if (entry.Size < 0x10) { continue; } uint signature; if (entry.IsPacked) { UnpackEntry(input, buffer); signature = LittleEndian.ToUInt32(buffer, 0); } else { signature = input.ReadUInt32(); } IResource res; if (0x020000 == signature || 0x0A0000 == signature) { res = ImageFormat.Tga; } else { res = AutoEntry.DetectFileType(signature); } if (null != res) { entry.ChangeType(res); } } } }
void FixupDir() { for (int i = 0; i < m_dir.Count; ++i) { var entry = (OdnEntry)m_dir[i]; long next_offset = i + 1 < m_dir.Count ? m_dir[i + 1].Offset : m_file.MaxOffset; entry.Size = (uint)(next_offset - entry.Offset); if (OdnOpener.Image24NameRe.IsMatch(entry.Name)) { entry.Type = "image"; } else if (OdnOpener.ScriptNameRe.IsMatch(entry.Name)) { entry.Type = "script"; entry.IsEncrypted = m_scripts_encrypted; } else if (OdnOpener.AudioNameRe.IsMatch(entry.Name)) { entry.Type = "audio"; } else if (entry.Size > 4) { var signature = m_file.View.ReadUInt32(entry.Offset); IResource res = null; if (0x5E6A6A42 == signature) { res = OggAudio.Instance; } else if (AudioFormat.Wav.Signature == signature) { res = AudioFormat.Wav; } else { res = AutoEntry.DetectFileType(signature); } if (res != null) { entry.ChangeType(res); } else if (OdnOpener.Image32NameRe.IsMatch(entry.Name)) { entry.Type = "image"; } } } }
static void SetEntryType(Entry entry, uint signature) { if (0xBA010000 == signature) { entry.Type = "video"; entry.Name = Path.ChangeExtension(entry.Name, "mpg"); } else { var res = AutoEntry.DetectFileType(signature); if (null != res) { entry.ChangeType(res); } } }
static protected void DetectFileTypes(ArcView file, List <Entry> dir) { byte[] signature_buffer = new byte[4]; foreach (PackedEntry entry in dir) { uint packed_size = file.View.ReadUInt32(entry.Offset); uint unpacked_size = file.View.ReadUInt32(entry.Offset + 4); entry.IsPacked = 0 != packed_size; if (!entry.IsPacked) { packed_size = unpacked_size; } entry.Size = packed_size; entry.UnpackedSize = unpacked_size; entry.Offset += 8; uint signature; if (entry.IsPacked) { using (var input = file.CreateStream(entry.Offset, Math.Min(packed_size, 0x20u))) using (var reader = new ShsCompression(input)) { reader.Unpack(signature_buffer); signature = LittleEndian.ToUInt32(signature_buffer, 0); } } else { signature = file.View.ReadUInt32(entry.Offset); } if (0 != signature) { IResource res; if (0x020000 == signature || 0x0A0000 == signature) { res = ImageFormat.Tga; } else { res = AutoEntry.DetectFileType(signature); } if (res != null) { entry.ChangeType(res); } } } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } uint index_offset = 8; uint first_offset = file.View.ReadUInt32(index_offset); if ((uint)count * 4 + 10 != first_offset) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new Entry { Offset = file.View.ReadUInt32(index_offset) }; dir.Add(entry); index_offset += 4; } foreach (var entry in dir) { if (!file.View.AsciiEqual(entry.Offset, "DATA")) { return(null); } uint name_length = file.View.ReadUInt16(entry.Offset + 0x18); entry.Size = file.View.ReadUInt32(entry.Offset + 0x1C); var name = file.View.ReadBytes(entry.Offset + 0x20, name_length); entry.Name = DecryptName(name); entry.Offset += 0x22 + name_length; uint signature = file.View.ReadUInt32(entry.Offset); var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.Type = res.Type; } } return(new ArcFile(file, this, dir)); }
internal static void DetectFileTypes(ArcView file, List <Entry> dir) { byte[] signature_buffer = new byte[4]; foreach (PackedEntry entry in dir) { uint signature; if (entry.IsPacked) { using (var input = file.CreateStream(entry.Offset, Math.Min(entry.Size, 0x20u))) using (var reader = new ShsCompression(input)) { reader.Unpack(signature_buffer); signature = LittleEndian.ToUInt32(signature_buffer, 0); } } else { signature = file.View.ReadUInt32(entry.Offset); } if (0x78534444 == signature) // 'DDSx' { entry.Type = "script"; entry.Name = Path.ChangeExtension(entry.Name, "hxb"); } else if (0 != signature) { IResource res; if (0x020000 == signature || 0x0A0000 == signature) { res = ImageFormat.Tga; } else { res = AutoEntry.DetectFileType(signature); } if (res != null) { entry.ChangeType(res); } } } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } uint index_offset = file.View.ReadUInt32(8); if (index_offset >= file.MaxOffset) { return(null); } var names = new HashSet <string>(); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = file.View.ReadString(index_offset, 0x10); if (names.Add(name)) { var entry = Create <Arc2Entry> (name); entry.Offset = file.View.ReadUInt32(index_offset + 0x10); entry.Size = file.View.ReadUInt32(index_offset + 0x14); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } entry.Key1 = file.View.ReadUInt32(index_offset + 0x18); entry.Key2 = file.View.ReadUInt32(index_offset + 0x1C); dir.Add(entry); } index_offset += 0x20; } foreach (Arc2Entry entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset) - (entry.Key1 + entry.Key2); entry.ChangeType(AutoEntry.DetectFileType(signature)); } return(new ArcFile(file, this, dir)); }
void DetectFileTypes(ArcView file, IEnumerable <Entry> dir) { foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); if (0x5F534C43 == signature) // 'CLS_' { if (file.View.AsciiEqual(entry.Offset + 4, "TEXFILE")) { entry.Type = "image"; } } else { var res = AutoEntry.DetectFileType(signature); if (res != null) { entry.ChangeType(res); } } } }
void DetectFileTypes(List <Entry> dir, ArcView file) { var type = new byte[3]; foreach (PackedEntry entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); if (signature != 0x34655A4C) // 'LZe4' { entry.ChangeType(AutoEntry.DetectFileType(signature)); } else if (entry.Size > 0x40) { entry.IsPacked = true; entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 8); file.View.Read(entry.Offset + 0xC, type, 0, 3); if (type.AsciiEqual("000")) { entry.Type = "audio"; // either WAV or MIDI } else { DecryptType(type); if (type.AsciiEqual("BMP")) { entry.ChangeType(ImageFormat.Bmp); } else if (type.AsciiEqual("WAV")) { entry.ChangeType(AudioFormat.Wav); } else if (type.AsciiEqual("MID")) { entry.Name = Path.ChangeExtension(entry.Name, "mid"); } } } } }
void DetectFileTypes(ArcView file, List <Entry> dir) { foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type))) { uint signature = file.View.ReadUInt32(entry.Offset); if (0x05304148 == signature) { entry.Type = "image"; continue; } else if (0x304148 == (signature & 0xFFFFFF)) { uint encryption = file.View.ReadUInt32(entry.Offset + 8); long offset = entry.Offset + 0x10 + (signature >> 24); if (0 != encryption) { if (4 == encryption) { uint bits = Binary.BigEndian(file.View.ReadUInt32(offset + 8)); if (bits > entry.Size) { continue; } if (file.View.AsciiEqual(offset + 12 + bits, "BM")) { entry.ChangeType(ImageFormat.Bmp); } else if (file.View.AsciiEqual(entry.Offset + entry.Size - 0x12, "TRUEVISION")) { entry.ChangeType(ImageFormat.Tga); } } continue; } signature = file.View.ReadUInt32(offset); } entry.ChangeType(AutoEntry.DetectFileType(signature)); } }
void DetectTypes(ArcView file, List <Entry> dir, NekoXCode dec) { byte[] buffer = new byte[8]; foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type))) { if (entry.Name.EndsWith(".txt", StringComparison.InvariantCultureIgnoreCase)) { entry.Type = "script"; continue; } uint key = file.View.ReadUInt32(entry.Offset); file.View.Read(entry.Offset + 12, buffer, 0, 8); dec.Decrypt(key, buffer, 0, 8); uint signature = LittleEndian.ToUInt32(buffer, 0); var res = AutoEntry.DetectFileType(signature); string ext = ""; if (res != null) { ext = res.Extensions.FirstOrDefault(); entry.Type = res.Type; } else if (0x474e4d8a == signature) { ext = "mng"; } else if (entry.Name.StartsWith("script/")) { entry.Type = "script"; } if (!string.IsNullOrEmpty(ext)) { entry.Name = Path.ChangeExtension(entry.Name, ext); } } }
public override ArcFile TryOpen(ArcView file) { int version; if (file.View.AsciiEqual(4, "1.00")) { version = 100; } else if (file.View.AsciiEqual(4, "1.10")) { version = 110; } else { return(null); } int count = file.View.ReadInt32(0x14); if (!IsSaneCount(count)) { return(null); } int bucket_count = file.View.ReadInt32(0x18); uint index_size = file.View.ReadUInt32(0x1C); uint arc_seed = file.View.ReadUInt32(0x20); long index_offset = version >= 110 ? 0x2C : 0x24; long base_offset = index_offset + index_size; var blowfish = new Blowfish(IndexKey); var packed_bytes = file.View.ReadBytes(index_offset, index_size); blowfish.Decipher(packed_bytes, packed_bytes.Length & ~7); using (var input = new MemoryStream(packed_bytes)) using (var unpacked = new ZLibStream(input, CompressionMode.Decompress)) using (var index = new BinaryReader(unpacked)) { var file_map = BuildFileNameMap(arc_seed); var dir_table = new List <TacBucket> (bucket_count); for (int i = 0; i < bucket_count; ++i) { var entry = new TacBucket(); entry.Hash = index.ReadUInt16(); entry.Count = index.ReadUInt16(); entry.Index = index.ReadInt32(); dir_table.Add(entry); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new TacEntry(); entry.Hash = index.ReadUInt64(); entry.IsPacked = index.ReadInt32() != 0; entry.UnpackedSize = index.ReadUInt32(); entry.Offset = base_offset + index.ReadUInt32(); entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } var buffer = new byte[8]; foreach (var bucket in dir_table) { for (int i = 0; i < bucket.Count; ++i) { var entry = dir[bucket.Index + i] as TacEntry; entry.Hash = entry.Hash << 16 | bucket.Hash; bool known_name = file_map.ContainsKey(entry.Hash); if (known_name) { entry.Name = file_map[entry.Hash]; entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); } else { entry.Name = string.Format("{0:X16}", entry.Hash); } if (entry.IsPacked) { continue; } entry.Key = Encoding.ASCII.GetBytes(string.Format("{0}_tlib_secure_", entry.Hash)); if (!known_name) { var bf = new Blowfish(entry.Key); file.View.Read(entry.Offset, buffer, 0, 8); bf.Decipher(buffer, 8); var res = AutoEntry.DetectFileType(buffer.ToUInt32(0)); if (res != null) { entry.ChangeType(res); } } if ("image" == entry.Type) { entry.EncryptedSize = Math.Min(10240, entry.Size); } else { entry.EncryptedSize = entry.Size; } } } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if ('H' != file.View.ReadByte(4)) { return(null); } uint index_offset = 0x10; uint data_offset = file.View.ReadUInt32(index_offset); var base_name = Path.GetFileNameWithoutExtension(file.Name).ToUpperInvariant(); if (0 == data_offset && "TP" == base_name) { var ext = Path.GetExtension(file.Name).TrimStart('.'); int version; if (int.TryParse(ext, out version) && version >= 55) { return(OpenTp055Arc(file)); } else { return(OpenTpArc(file)); } } if (data_offset < index_offset || data_offset >= file.MaxOffset) { return(null); } int count = (int)(data_offset - index_offset) / 4; if (!IsSaneCount(count)) { return(null); } uint next_offset = data_offset; bool is_bgm = "BGM" == base_name; bool is_pic = "PIC" == base_name; var dir = new List <Entry> (count); for (int i = 0; next_offset != file.MaxOffset && i < count; ++i) { index_offset += 4; var name = string.Format("{0}#{1:D5}", base_name, i); var offset = next_offset; next_offset = index_offset == data_offset ? 0 : file.View.ReadUInt32(index_offset); if (uint.MaxValue == next_offset || next_offset < offset) { break; } uint size = next_offset - offset; if (size < 4) { continue; } Entry entry; if (is_pic) { entry = new Entry { Name = name, Type = "image" } } ; else if (is_bgm) { entry = new Entry { Name = name + ".wav", Type = "audio" } } ; else { entry = new AutoEntry(name, () => { uint signature = file.View.ReadUInt32(offset); uint s16 = signature & 0xFFFF; if (1 == s16 || 3 == s16 || 4 == s16) { return(s_PicFormat.Value); } if (size > 0x200 && (size >> 9) == (signature >> 9)) { return(AudioFormat.Wav); } return(AutoEntry.DetectFileType(signature)); }); } entry.Offset = offset; entry.Size = size; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); }