private ChunkDescriptor ReadChunkDescriptor() { UInt32 manifestSize = this.ReadUInt32BE(); long baseOffset = this.BaseStream.Position; byte[] manifestContent = this.ReadBytes((int)manifestSize); ChunkDescriptor descriptor = new ChunkDescriptor(); using (BinaryReader memoryReader = new BinaryReader(new MemoryStream(manifestContent))) { descriptor.Magic = memoryReader.ReadBytes(4); descriptor.Offset = baseOffset - 4; if (!descriptor.Magic.SequenceEqual(new byte[] { 0x9D, 0x79, 0x8E, 0xD5 })) { throw new InvalidDataException(); } descriptor.TotalFiles = memoryReader.ReadUInt32BE(); descriptor.TotalFilesWithName = memoryReader.ReadUInt32BE(); descriptor.TotalFilesWithId = memoryReader.ReadUInt32BE(); descriptor.TotalFilesWithMetaEntries = memoryReader.ReadUInt32BE(); descriptor.OffsetFileNamesBlock = memoryReader.ReadUInt32BE(); descriptor.OffsetMetaEntriesBlock = memoryReader.ReadUInt32BE(); descriptor.MetaEntriesSize = memoryReader.ReadUInt32BE(); for (int i = 0; i < descriptor.TotalFiles; i++) { ChunkDescriptorPair pair = new ChunkDescriptorPair(); pair.Hash = memoryReader.ReadBytes(20); descriptor.Pairs.Add(pair); } List <byte[]> chunkIds = new List <byte[]>(); if (descriptor.TotalFilesWithMetaEntries == 0 && descriptor.TotalFilesWithId != 0) { for (int i = 0; i < descriptor.TotalFilesWithName; i++) { descriptor.EbxDescriptors.Add(ReadIntermediateDescriptor(baseOffset, memoryReader)); } for (int i = 0; i < descriptor.TotalFilesWithId; i++) { descriptor.DataDescriptors.Add(ReadIntermediateDescriptor(baseOffset, memoryReader)); } for (int i = 0; i < descriptor.TotalFilesWithId; i++) { var resourceId = memoryReader.ReadUInt32BE(); } for (int i = 0; i < descriptor.TotalFilesWithId; i++) { var unknown1 = memoryReader.ReadUInt64BE(); var unknown2 = memoryReader.ReadUInt64BE(); } for (int i = 0; i < descriptor.TotalFilesWithId; i++) { chunkIds.Add(memoryReader.ReadBytes(8)); } } memoryReader.BaseStream.Seek(descriptor.OffsetFileNamesBlock, SeekOrigin.Begin); int nameStartOffset = 0; for (int i = 0; i < descriptor.TotalFilesWithName; i++) { descriptor.Pairs[i].Name = memoryReader.ReadNullTerminatedString().Replace('/', '\\'); var compositeDescriptor = new CompositeResourceDescriptor(); compositeDescriptor.Name = descriptor.Pairs[i].Name; compositeDescriptor.Ebx = ConvertIntermediateResourceToFinalResource(descriptor.EbxDescriptors.FirstOrDefault(ebx => ebx.NameOffset == nameStartOffset), compositeDescriptor); compositeDescriptor.Resource = ConvertIntermediateResourceToFinalResource(descriptor.DataDescriptors.FirstOrDefault(ebx => ebx.NameOffset == nameStartOffset), compositeDescriptor); descriptor.ResourceDescriptors.Add(compositeDescriptor); nameStartOffset += compositeDescriptor.Name.Length + 1; } if (descriptor.TotalFilesWithMetaEntries == 0 && descriptor.TotalFilesWithId != 0) { for (int i = 0; i < descriptor.TotalFilesWithId; i++) { descriptor.Pairs[(int)descriptor.TotalFilesWithName + i].Name = BitConverter.ToString(chunkIds[i]).Replace("-", ""); } } } return(descriptor); }
private ResourceDescriptor ConvertIntermediateResourceToFinalResource(IntermediateResourceDescriptor intermediateResourceDescriptor, CompositeResourceDescriptor compositeDescriptor) { if (intermediateResourceDescriptor == null) { return(null); } intermediateResourceDescriptor.FinalResourceDescriptor = compositeDescriptor; return(new ResourceDescriptor() { Offset = intermediateResourceDescriptor.FileOffset, Size = intermediateResourceDescriptor.Size }); }