/// <exception cref="ArgumentException">Thrown when the <see cref="MpqArchive"/> does not contain an <see cref="Attributes"/> file.</exception> public static bool VerifyAttributes(this MpqArchive archive) { if (!archive.TryOpenFile(Attributes.FileName, out var attributesStream)) { throw new ArgumentException($"The archive must contain an {Attributes.FileName} file.", nameof(archive)); } archive.AddFileName(Signature.FileName); using var reader = new BinaryReader(attributesStream); var attributes = reader.ReadAttributes(); var hasCrc32 = attributes.Flags.HasFlag(AttributesFlags.Crc32); var hasDateTime = attributes.Flags.HasFlag(AttributesFlags.DateTime); var hasUnk0x04 = attributes.Flags.HasFlag(AttributesFlags.Unk0x04); var count = 0; foreach (var mpqEntry in archive) { if (hasCrc32) { var actualCrc32 = attributes.Crc32s[count]; if (string.Equals(mpqEntry.FileName, Attributes.FileName, StringComparison.OrdinalIgnoreCase)) { if (actualCrc32 != 0) { return(false); } } else if (string.Equals(mpqEntry.FileName, Signature.FileName, StringComparison.OrdinalIgnoreCase)) { if (actualCrc32 != _signatureCrc32) { return(false); } } else { using var mpqEntryStream = archive.OpenFile(mpqEntry); if (actualCrc32 != new CRC32().GetCrc32(mpqEntryStream)) { return(false); } } } if (hasUnk0x04) { var unk0x04 = attributes.Unk0x04s[count]; if (unk0x04.Length != 16) { return(false); } for (var i = 0; i < 16; i++) { if (unk0x04[i] != 0) { return(false); } } } count++; } return((!hasCrc32 || attributes.Crc32s.Count == count) && (!hasDateTime || attributes.DateTimes.Count == count) && (!hasUnk0x04 || attributes.Unk0x04s.Count == count)); }
public static void DiscoverFileNames(this MpqArchive archive) { archive.AddFileName(Attributes.FileName); archive.AddFileName(ListFile.FileName); archive.AddFileName(@"(signature)"); archive.AddFileName(@"(user data)"); archive.AddFileName(MapSounds.FileName); archive.AddFileName(MapCameras.FileName); archive.AddFileName(MapEnvironment.FileName); archive.AddFileName(MapPathingMap.FileName); archive.AddFileName(MapPreviewIcons.FileName); archive.AddFileName(MapRegions.FileName); archive.AddFileName(MapShadowMap.FileName); archive.AddFileName(@"war3mapMap.blp"); archive.AddFileName(@"war3mapMap.tga"); archive.AddFileName(@"war3mapPath.tga"); archive.AddFileName(@"war3mapPreview.blp"); archive.AddFileName(@"war3mapPreview.tga"); archive.AddFileName(CampaignInfo.FileName); archive.AddFileName(MapInfo.FileName); archive.AddFileName(CampaignAbilityObjectData.FileName); archive.AddFileName(CampaignBuffObjectData.FileName); archive.AddFileName(CampaignDestructableObjectData.FileName); archive.AddFileName(CampaignDoodadObjectData.FileName); archive.AddFileName(CampaignItemObjectData.FileName); archive.AddFileName(CampaignUnitObjectData.FileName); archive.AddFileName(CampaignUpgradeObjectData.FileName); archive.AddFileName(MapAbilityObjectData.FileName); archive.AddFileName(MapBuffObjectData.FileName); archive.AddFileName(MapDestructableObjectData.FileName); archive.AddFileName(MapDoodadObjectData.FileName); archive.AddFileName(MapItemObjectData.FileName); archive.AddFileName(MapUnitObjectData.FileName); archive.AddFileName(MapUpgradeObjectData.FileName); archive.AddFileName(CampaignTriggerStrings.FileName); archive.AddFileName(MapCustomTextTriggers.FileName); archive.AddFileName(MapTriggers.FileName); archive.AddFileName(MapTriggerStrings.FileName); archive.AddFileName(@"scripts\war3map.j"); archive.AddFileName(@"war3map.j"); archive.AddFileName(@"war3map.lua"); archive.AddFileName(MapDoodads.FileName); archive.AddFileName(MapUnits.FileName); archive.AddFileName(@"conversation.json"); archive.AddFileName(@"war3mapExtra.txt"); archive.AddFileName(@"war3mapMisc.txt"); archive.AddFileName(@"war3mapSkin.txt"); archive.AddFileName(@"war3map.imp"); if (archive.IsCampaignArchive(out var campaignInfo)) { for (var i = 0; i < campaignInfo.Maps.Count; i++) { archive.AddFileName(campaignInfo.Maps[i].MapFilePath); } } }