public static AFSFile fromStream(Stream data) { // Reading AFS file header var br = new BinaryReader(data); var nf = new AFSFile() { header = br.ReadInt32(), sectionCount = br.ReadInt32(), }; if (nf.header != magic) { throw new InvalidDataException("Data is not an AFS file"); } nf.sections = new AFSSection[nf.sectionCount]; for (int i = 0; i < nf.sectionCount; i++) { nf.sections[i] = new AFSSection() { offset = br.ReadInt32(), length = br.ReadInt32() }; } var w = nf.sections[0].offset; br.BaseStream.Position = w - 0x8; // hacks var filetableOffset = br.ReadInt32(); var filetableLength = br.ReadInt32(); var filetableCount = filetableLength / 0x30; // The AFSFileDescriptor structure is 48 bytes long. if (filetableOffset > 0 & filetableLength > 0) { cbug.write($"Filetable is at {filetableOffset:X} with {filetableCount:X} entries."); nf.files = new AFSFileDescriptor[filetableCount]; br.BaseStream.Position = filetableOffset; for (int i = 0; i < filetableCount; i++) { nf.files[i] = new AFSFileDescriptor() { name = br.ReadBytes(16), un0 = br.ReadInt64(), un1 = br.ReadInt64(), un2 = br.ReadInt32(), un3 = br.ReadInt16(), un4 = br.ReadInt16(), un5 = br.ReadInt32(), length = br.ReadInt32() }; } } return(nf); }
static void Main(string[] args) { Console.WriteLine("jgrex"); var w = File.OpenRead("DEMO30.afs"); var afs = AFSFile.fromStream(w); for (int i = 0; i < afs.sections.Length; i++) { cbug.write($"Entry {i} is at 0x{afs.sections[i].offset:X} of length {afs.sections[i].length:X}"); } for (int i = 0; i < afs.files.Length; i++) { var fileName = Encoding.ASCII.GetString(afs.files[i].name); cbug.write($"FileEntry {i}({fileName}) is length {afs.files[i].length:X}"); } }