Skip to content

Commit

Permalink
Include map.png into uid generation
Browse files Browse the repository at this point in the history
  • Loading branch information
PunkPun committed Jan 22, 2022
1 parent 3da9929 commit d3e8490
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 11 deletions.
34 changes: 28 additions & 6 deletions OpenRA.Game/Map/Map.cs
Expand Up @@ -15,6 +15,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using OpenRA.FileFormats;
using OpenRA.FileSystem;
using OpenRA.Graphics;
Expand Down Expand Up @@ -152,6 +153,7 @@ public void Serialize(Map map, List<MiniYamlNode> nodes)
public class Map : IReadOnlyFileSystem
{
public const int SupportedMapFormat = 11;
public const int CurrentMapFormat = 12;

/// <summary>Defines the order of the fields in map.yaml</summary>
static readonly MapField[] YamlFields =
Expand Down Expand Up @@ -252,7 +254,7 @@ public class Map : IReadOnlyFileSystem

internal Translation Translation;

public static string ComputeUID(IReadOnlyPackage package)
public 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" };
Expand All @@ -265,7 +267,7 @@ public static string ComputeUID(IReadOnlyPackage package)
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
Expand All @@ -285,6 +287,26 @@ public static string ComputeUID(IReadOnlyPackage package)
}
}

// PERF This is a way to get MapFormat without expensive yaml parsing
public static int GetMapFormat(IReadOnlyPackage p)
{
var result = "";
foreach (var a in p.GetStream("map.yaml").ReadAllLines())
{
var search = Regex.Match(a, "MapFormat: (.?\\d)");
if (search.Success && search.Groups.Count > 0)
{
result = search.Groups[1].Value;
break;
}
}

if (result == "")
throw new InvalidDataException($"Does not contain MapFormat");

return Convert.ToInt32(result);
}

/// <summary>
/// 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.
Expand Down Expand Up @@ -332,7 +354,7 @@ public Map(ModData modData, IReadOnlyPackage package)
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");
Expand Down Expand Up @@ -400,7 +422,7 @@ public Map(ModData modData, IReadOnlyPackage package)

PostInit();

Uid = ComputeUID(Package);
Uid = ComputeUID(Package, MapFormat);
}

void PostInit()
Expand Down Expand Up @@ -587,7 +609,7 @@ PPos[] ProjectCellInner(MPos uv)

public void Save(IReadWritePackage toPackage)
{
MapFormat = SupportedMapFormat;
MapFormat = CurrentMapFormat;

var root = new List<MiniYamlNode>();
foreach (var field in YamlFields)
Expand All @@ -612,7 +634,7 @@ public void Save(IReadWritePackage toPackage)
Package = toPackage;

// Update UID to match the newly saved data
Uid = ComputeUID(toPackage);
Uid = ComputeUID(toPackage, MapFormat);
}

public byte[] SaveBinaryData()
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Map/MapCache.cs
Expand Up @@ -101,7 +101,7 @@ public void LoadMaps()
if (mapPackage == null)
continue;

var uid = Map.ComputeUID(mapPackage);
var uid = Map.ComputeUID(mapPackage, Map.GetMapFormat(mapPackage));
previews[uid].UpdateFromMap(mapPackage, kv.Key, kv.Value, modData.Manifest.MapCompatibility, mapGrid.Type);
}
}
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Map/MapPreview.cs
Expand Up @@ -323,7 +323,7 @@ public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassi
if (yaml.TryGetValue("MapFormat", out var temp))
{
var format = FieldLoader.GetValue<int>("MapFormat", temp.Value);
if (format != Map.SupportedMapFormat)
if (format < Map.SupportedMapFormat)
throw new InvalidDataException($"Map format {format} is not supported.");
}

Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/Lint/CheckMapMetadata.cs
Expand Up @@ -29,8 +29,8 @@ void ILintServerMapPass.Run(Action<string> emitError, Action<string> emitWarning

void Run(Action<string> 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.");
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/UtilityCommands/GetMapHashCommand.cs
Expand Up @@ -27,7 +27,7 @@ bool IUtilityCommand.ValidateArguments(string[] args)
void IUtilityCommand.Run(Utility utility, string[] args)
{
using (var package = new Folder(Platform.EngineDir).OpenPackage(args[1], utility.ModData.ModFiles))
Console.WriteLine(Map.ComputeUID(package));
Console.WriteLine(Map.ComputeUID(package, Map.GetMapFormat(package)));
}
}
}

0 comments on commit d3e8490

Please sign in to comment.