public override ArcFile TryOpen(ArcView file) { if ((file.View.ReadInt32(0) | file.View.ReadInt32(4) | file.View.ReadInt32(8)) != 0) { return(null); } int key = file.View.ReadInt32(0x10); int count = file.View.ReadInt32(0x14); if (!IsSaneCount(count)) { return(null); } uint index_offset = 0x18; var index = new Dictionary <int, Entry> (count); for (int i = 0; i < count; ++i) { int id = file.View.ReadInt32(index_offset); var entry = new Entry { Offset = file.View.ReadUInt32(index_offset + 4), Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } index[id] = entry; index_offset += 12; } var names_entry = index[0]; var names = file.View.ReadBytes(names_entry.Offset, names_entry.Size); if (key != 0) { DecryptData(names, key); } using (var input = new BinMemoryStream(names)) { while (input.PeekByte() != -1) { int id = input.ReadInt32(); var name = input.ReadCString(); if (!string.IsNullOrEmpty(name)) { var entry = index[id]; entry.Name = name; entry.Type = FormatCatalog.Instance.GetTypeFromName(name); } } } var dir = index.Values.Where(e => !string.IsNullOrEmpty(e.Name)).ToList(); return(new YkArchive(file, this, dir, key)); }
public override ArcFile TryOpen(ArcView file) { if (file.MaxOffset <= 12 || file.MaxOffset > uint.MaxValue) { return(null); } uint packed_size = file.View.ReadUInt32(file.MaxOffset - 12) ^ 0xF0F0F0F0; uint unpacked_size = file.View.ReadUInt32(file.MaxOffset - 8) ^ 0xF0F0F0F0; const uint entry_record_size = 0x50; int count = (int)(unpacked_size / entry_record_size); if (unpacked_size % entry_record_size != 0 || packed_size >= file.MaxOffset || !IsSaneCount(count)) { return(null); } var unpacked = new byte[unpacked_size]; using (var packed = file.CreateStream(file.MaxOffset - 12 - packed_size, packed_size)) LzUnpack(packed, unpacked); using (var index = new BinMemoryStream(unpacked)) { var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int flags = index.ReadInt32(); var name = index.ReadCString(0x40); var entry = FormatCatalog.Instance.Create <PmDatEntry> (name); entry.Offset = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } if (entry.Name.HasAnyOfExtensions("CRGB", "CHAR", "rol", "edg")) { entry.Type = "image"; } entry.IsPacked = (flags & 0xFF0000) != 0; entry.StoredSize = (flags & 0x2000000) != 0; dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "ARC\0")) { return(null); } uint data_offset = file.View.ReadUInt32(8); uint unpacked_size = file.View.ReadUInt32(0xC); uint packed_size = file.View.ReadUInt32(0x10); byte[] unpacked = new byte[unpacked_size]; using (var packed = file.CreateStream(0x14, packed_size)) using (var input = new XoredStream(packed, 0xFF)) { LzssUnpack(input, unpacked); } using (var index = new BinMemoryStream(unpacked)) { var key = index.ReadBytes(256); int count = index.ReadInt32(); if (!IsSaneCount(count)) { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); var name = index.ReadCString(name_length); var entry = FormatCatalog.Instance.Create <GmlEntry> (name); entry.Offset = index.ReadUInt32() + data_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); entry.Header = index.ReadBytes(4); } return(new GmlArchive(file, this, dir, key)); } }
public override ArcFile TryOpen(ArcView file) { if (!VFS.IsPathEqualsToFileName(file.Name, "AVGDatas.pck")) { return(null); } int seed = Binary.BigEndian(file.View.ReadInt32(file.MaxOffset - 104)); var header = file.View.ReadBytes(file.MaxOffset - 100, 100); var rnd = new RandomGenerator(); rnd.Init(seed); rnd.Decrypt(header, 0, header.Length); uint checksum = (uint)(header[1] | header[2] << 8 | header[0] << 16 | header[3] << 24) ^ 0xDEFD32D3; uint length = BigEndian.ToUInt32(header, 24); if (checksum != length) { return(null); } uint idx_pos = BigEndian.ToUInt32(header, 28); uint idx_size = Binary.BigEndian(file.View.ReadUInt32(idx_pos)); uint index_size; var index = ReadChunk(file, 8, idx_pos + 4, out index_size); if (index_size >= 0x80000000) { index_size &= 0x7FFFFFFF; var unpacked = new byte[idx_size]; LzssUnpack(index, index.Length, unpacked); index = unpacked; } using (var input = new BinMemoryStream(index)) { var dir = new List <Entry>(); int dir_count = 0; while (input.PeekByte() != -1) { input.ReadInt32(); input.ReadInt32(); input.ReadInt32(); int count = Binary.BigEndian(input.ReadInt32()); var dir_name = dir_count.ToString("X4"); for (int i = 0; i < count; ++i) { var name = input.ReadCString(0x28); name = Path.Combine(dir_name, name); var entry = Create <PckEntry> (name); entry.Offset = Binary.BigEndian(input.ReadUInt32()); entry.Size = Binary.BigEndian(input.ReadUInt32()); entry.IsEncrypted = input.ReadInt32() != 0; entry.UnpackedSize = input.ReadUInt32(); entry.IsPacked = entry.Size != entry.UnpackedSize; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } ++dir_count; } return(new ArcFile(file, this, dir)); } }