From c40675cfba610ad91c85b14f27cb3b5c5c1b5361 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+Punsho@users.noreply.github.com> Date: Fri, 21 Jan 2022 00:03:43 +0200 Subject: [PATCH] Include map.png into uid generation --- OpenRA.Game/Map/Map.cs | 30 +++++++++++++++++---- OpenRA.Game/Map/MapPreview.cs | 2 +- OpenRA.Mods.Common/Lint/CheckMapMetadata.cs | 4 +-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 8d91489854..366f2b57a9 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -15,6 +15,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using OpenRA.FileFormats; using OpenRA.FileSystem; using OpenRA.Graphics; @@ -151,6 +152,7 @@ namespace OpenRA public class Map : IReadOnlyFileSystem { public const int SupportedMapFormat = 11; + public const int CurrentMapFormat = 12; const short InvalidCachedTerrainIndex = -1; /// Defines the order of the fields in map.yaml @@ -253,6 +255,11 @@ namespace OpenRA internal Translation Translation; public static string ComputeUID(IReadOnlyPackage package) + { + return ComputeUID(package, GetMapFormat(package)); + } + + static string ComputeUID(IReadOnlyPackage package, int format) { // UID is calculated by taking an SHA1 of the yaml and binary data var requiredFiles = new[] { "map.yaml", "map.bin" }; @@ -265,7 +272,7 @@ namespace OpenRA try { foreach (var filename in contents) - if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua")) + if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua") || (format >= 12 && filename == "map.png")) streams.Add(package.GetStream(filename)); // Take the SHA1 @@ -285,6 +292,19 @@ namespace OpenRA } } + static int GetMapFormat(IReadOnlyPackage p) + { + foreach (var line in p.GetStream("map.yaml").ReadAllLines()) + { + // PERF This is a way to get MapFormat without expensive yaml parsing + var search = Regex.Match(line, "^MapFormat:\\s*(\\d*)\\s*$"); + if (search.Success && search.Groups.Count > 0) + return FieldLoader.GetValue("MapFormat", search.Groups[1].Value); + } + + throw new InvalidDataException($"MapFormat is not definedt\n File: {p.Name}"); + } + /// /// Initializes a new map created by the editor or importer. /// The map will not receive a valid UID until after it has been saved and reloaded. @@ -332,7 +352,7 @@ namespace OpenRA foreach (var field in YamlFields) field.Deserialize(this, yaml.Nodes); - if (MapFormat != SupportedMapFormat) + if (MapFormat < SupportedMapFormat) throw new InvalidDataException($"Map format {MapFormat} is not supported.\n File: {package.Name}"); PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players"); @@ -400,7 +420,7 @@ namespace OpenRA PostInit(); - Uid = ComputeUID(Package); + Uid = ComputeUID(Package, MapFormat); } void PostInit() @@ -600,7 +620,7 @@ namespace OpenRA public void Save(IReadWritePackage toPackage) { - MapFormat = SupportedMapFormat; + MapFormat = CurrentMapFormat; var root = new List(); foreach (var field in YamlFields) @@ -625,7 +645,7 @@ namespace OpenRA Package = toPackage; // Update UID to match the newly saved data - Uid = ComputeUID(toPackage); + Uid = ComputeUID(toPackage, MapFormat); } public byte[] SaveBinaryData() diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 7dc47f0ca1..22f7197a14 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -320,7 +320,7 @@ namespace OpenRA if (yaml.TryGetValue("MapFormat", out var temp)) { var format = FieldLoader.GetValue("MapFormat", temp.Value); - if (format != Map.SupportedMapFormat) + if (format < Map.SupportedMapFormat) throw new InvalidDataException($"Map format {format} is not supported."); } diff --git a/OpenRA.Mods.Common/Lint/CheckMapMetadata.cs b/OpenRA.Mods.Common/Lint/CheckMapMetadata.cs index 49119e97a2..869d9613f6 100644 --- a/OpenRA.Mods.Common/Lint/CheckMapMetadata.cs +++ b/OpenRA.Mods.Common/Lint/CheckMapMetadata.cs @@ -28,8 +28,8 @@ namespace OpenRA.Mods.Common.Lint void Run(Action emitError, int mapFormat, string author, string title, string[] categories) { - if (mapFormat != Map.SupportedMapFormat) - emitError($"Map format {mapFormat} does not match the supported version {Map.SupportedMapFormat}."); + if (mapFormat < Map.SupportedMapFormat) + emitError($"Map format {mapFormat} does not match the supported version {Map.CurrentMapFormat}."); if (author == null) emitError("Map does not define a valid author.");