public void Deserialize(Stream input) { var basePosition = input.Position; var magic = input.ReadValueU32(Endian.Big); if (magic != Signature) { throw new FormatException("unsupported archive version"); } input.Position += 4; // skip version var platform = (Archive.Platform)input.ReadValueU32(Endian.Big); if (platform != Archive.Platform.PC && platform != Archive.Platform.Xbox360 && platform != Archive.Platform.PS3) { throw new FormatException("unsupported archive platform"); } var endian = platform == Archive.Platform.PC ? Endian.Little : Endian.Big; input.Position = basePosition; uint version; using (var data = input.ReadToMemoryStreamSafe(12, endian)) { data.Position += 4; // skip magic version = data.ReadValueU32(endian); data.Position += 4; // skip platform } if (version != 19) { throw new FormatException("unsupported archive version"); } Archive.FileHeader fileHeader; using (var data = input.ReadToMemoryStreamSafe(52, endian)) { fileHeader = Archive.FileHeader.Read(data, endian); } input.Position = basePosition + fileHeader.ResourceTypeTableOffset; var resourceTypeCount = input.ReadValueU32(endian); var resourceTypes = new Archive.ResourceType[resourceTypeCount]; for (uint i = 0; i < resourceTypeCount; i++) { resourceTypes[i] = Archive.ResourceType.Read(input, endian); } input.Position = basePosition + fileHeader.BlockTableOffset; var blockStream = BlockReaderStream.FromStream(input, endian); var resources = new Archive.ResourceEntry[fileHeader.ResourceCount]; for (uint i = 0; i < fileHeader.ResourceCount; i++) { Archive.ResourceHeader resourceHeader; using (var data = blockStream.ReadToMemoryStreamSafe(26, endian)) { resourceHeader = Archive.ResourceHeader.Read(data, endian); } if (resourceHeader.Size < 30) { throw new FormatException(); } resources[i] = new Archive.ResourceEntry() { TypeId = (int)resourceHeader.TypeId, Version = resourceHeader.Version, Data = blockStream.ReadBytes((int)resourceHeader.Size - 30), SlotRamRequired = resourceHeader.SlotRamRequired, SlotVramRequired = resourceHeader.SlotVramRequired, OtherRamRequired = resourceHeader.OtherRamRequired, OtherVramRequired = resourceHeader.OtherVramRequired, }; } input.Position = basePosition + fileHeader.XmlOffset; var xml = input.ReadString((int)(input.Length - input.Position), Encoding.ASCII); this._ResourceTypes.Clear(); this._ResourceEntries.Clear(); this._Endian = endian; this._Platform = platform; this._SlotRamRequired = fileHeader.SlotRamRequired; this._SlotVramRequired = fileHeader.SlotVramRequired; this._OtherRamRequired = fileHeader.OtherRamRequired; this._OtherVramRequired = fileHeader.OtherVramRequired; this._Unknown20 = (byte[])fileHeader.Unknown20.Clone(); this._ResourceTypes.AddRange(resourceTypes); this._ResourceInfoXml = xml; this._ResourceEntries.AddRange(resources); }
public void Deserialize(Stream input) { // Read Texture Names before we start. // They are from an external file, taken from MTL. ReadTextureNames(); if (IsGameType(GamesEnumerator.MafiaI_DE)) { if (!File.Exists("libs/oo2core_8_win64.dll")) { MessageBox.Show(Language.GetString("$M1DE_OODLEERROR"), "Toolkit"); return; } } var basePosition = input.Position; // Check Magic, should be SDS. var magic = input.ReadValueU32(Endian.Big); if (magic != Signature) { string FormatError = string.Format("Unsupported Archive Signature: {0}", magic); throw new FormatException(FormatError); } input.Seek(8, SeekOrigin.Begin); // Check Platform. There may be values for XboxOne and PS4, but that is unknown. var platform = (Platform)input.ReadValueU32(Endian.Big); if (platform != Platform.PC && platform != Platform.Xbox360 && platform != Platform.PS3) { string FormatError = string.Format("Unsupported Archive Platform: {0}", platform); throw new FormatException(FormatError); } var endian = platform == Archive.Platform.PC ? Endian.Little : Endian.Big; input.Seek(4, SeekOrigin.Begin); // Check Version, should be 19 (Mafia: II) or 20 (Mafia III). var version = input.ReadValueU32(endian); if (version != 19 && version != 20) { string FormatError = string.Format("Unsupported Archive Version: {0}", version); throw new FormatException(FormatError); } input.Seek(12, SeekOrigin.Begin); input.Position = basePosition; using (var data = input.ReadToMemoryStreamSafe(12, endian)) { data.Position += 4; // skip magic _Version = data.ReadValueU32(endian); data.Position += 4; // skip platform } if (_Version != 19 && _Version != 20) { throw new FormatException("unsupported archive version"); } Archive.FileHeader fileHeader; using (var data = input.ReadToMemoryStreamSafe(52, endian)) { fileHeader = Archive.FileHeader.Read(data, endian); } input.Position = basePosition + fileHeader.ResourceTypeTableOffset; var resourceTypeCount = input.ReadValueU32(endian); var resourceTypes = new Archive.ResourceType[resourceTypeCount]; for (uint i = 0; i < resourceTypeCount; i++) { resourceTypes[i] = Archive.ResourceType.Read(input, endian); } input.Position = basePosition + fileHeader.BlockTableOffset; var blockStream = BlockReaderStream.FromStream(input, endian); var resources = new Archive.ResourceEntry[fileHeader.ResourceCount]; for (uint i = 0; i < fileHeader.ResourceCount; i++) { Archive.ResourceHeader resourceHeader; var size = (_Version == 20 ? 34 : 26); using (var data = blockStream.ReadToMemoryStreamSafe(size, endian)) { resourceHeader = Archive.ResourceHeader.Read(data, endian, _Version); } if (resourceHeader.Size < 30) { throw new FormatException(); } resources[i] = new Archive.ResourceEntry() { TypeId = (int)resourceHeader.TypeId, Version = resourceHeader.Version, Data = blockStream.ReadBytes((int)resourceHeader.Size - (size + 4)), FileHash = resourceHeader.FileHash, SlotRamRequired = resourceHeader.SlotRamRequired, SlotVramRequired = resourceHeader.SlotVramRequired, OtherRamRequired = resourceHeader.OtherRamRequired, OtherVramRequired = resourceHeader.OtherVramRequired, }; } if (fileHeader.XmlOffset != 0) { input.Position = basePosition + fileHeader.XmlOffset; var xml = input.ReadString((int)(input.Length - input.Position), Encoding.ASCII); this._ResourceInfoXml = xml; } this._ResourceTypes.Clear(); this._ResourceEntries.Clear(); this._Endian = endian; this._Platform = platform; this._SlotRamRequired = fileHeader.SlotRamRequired; this._SlotVramRequired = fileHeader.SlotVramRequired; this._OtherRamRequired = fileHeader.OtherRamRequired; this._OtherVramRequired = fileHeader.OtherVramRequired; this._Unknown20 = (byte[])fileHeader.Unknown20.Clone(); this._ResourceTypes.AddRange(resourceTypes); this._ResourceEntries.AddRange(resources); }