public SeraphArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, ArchPacScheme scheme) : base(arc, impl, dir) { EventDir = scheme.EventDir; EventMap = scheme.EventMap; }
// 3 @ ScnPac.Dat : FF 18 05 XX XX XX XX // FF 16 05 XX XX XX XX List <Entry> ReadIndex(ArcView file, ArchPacScheme scheme) { long index_offset = scheme.IndexOffset; int base_count = file.View.ReadInt32(index_offset); int file_count = file.View.ReadInt32(index_offset + 4); index_offset += 8; if (base_count <= 0 || base_count > 0x100 || !IsSaneCount(file_count)) { return(null); } var base_offsets = new List <Tuple <uint, int> > (base_count); int total_count = 0; for (int i = 0; i < base_count; ++i) { uint offset = file.View.ReadUInt32(index_offset); int count = file.View.ReadInt32(index_offset + 4); if (count <= 0 || count > file_count || offset > file.MaxOffset) { return(null); } total_count += count; if (total_count > file_count) { return(null); } base_offsets.Add(Tuple.Create(offset, count)); index_offset += 8; } if (total_count != file_count) { return(null); } var dir = new List <Entry> (file_count); for (int j = base_count - 1; j >= 0; --j) { uint next_offset = file.View.ReadUInt32(index_offset); index_offset += 4; for (int i = 0; i < base_offsets[j].Item2; ++i) { var entry = new ArchEntry { Name = FormatEntryName(j, i), Type = "image", DirIndex = (short)j, FileIndex = (short)i, Offset = next_offset, }; next_offset = file.View.ReadUInt32(index_offset); index_offset += 4; if (next_offset < entry.Offset) { return(null); } entry.Size = (uint)(next_offset - entry.Offset); entry.Offset += base_offsets[j].Item1; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } if (entry.Size > 0) { dir.Add(entry); } } } if (0 == dir.Count) { return(null); } return(dir); }