From d492c23a6df31b80f856c4e91c3988b8c4a89419 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 17:50:04 +0000 Subject: [PATCH] Store map packages in MapPreview. --- OpenRA.Game/Map/MapCache.cs | 10 +- OpenRA.Game/Map/MapPreview.cs | 4 +- OpenRA.Game/ModData.cs | 2 +- .../ServerTraits/LobbyCommands.cs | 2 +- .../UtilityCommands/CheckYaml.cs | 2 +- .../UtilityCommands/UpgradeMapCommand.cs | 7 +- .../UtilityCommands/UpgradeModCommand.cs | 16 +- .../UtilityCommands/UpgradeRules.cs | 146 +++++++++--------- .../Widgets/Logic/Editor/SaveMapLogic.cs | 2 +- .../Widgets/Logic/Lobby/LobbyLogic.cs | 5 +- .../Widgets/Logic/MapChooserLogic.cs | 2 +- .../Widgets/Logic/MissionBrowserLogic.cs | 7 +- 12 files changed, 102 insertions(+), 103 deletions(-) diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index d936a89282..03772ab193 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -60,11 +60,9 @@ namespace OpenRA { using (new Support.PerfTimer(path.Key)) { - using (var package = modData.ModFiles.OpenPackage(path.Key)) - { - var uid = Map.ComputeUID(package); - previews[uid].UpdateFromMap(package, path.Value, modData.Manifest.MapCompatibility, mapGrid.Type); - } + var package = modData.ModFiles.OpenPackage(path.Key); + var uid = Map.ComputeUID(package); + previews[uid].UpdateFromMap(package, path.Value, modData.Manifest.MapCompatibility, mapGrid.Type); } } catch (Exception e) @@ -189,7 +187,7 @@ namespace OpenRA if (bitmap == null) { createdPreview = true; - var map = new Map(p.Path); + var map = new Map(modData, p.Package); bitmap = Minimap.RenderMapPreview(modData.DefaultRules.TileSets[map.Tileset], map, modData.DefaultRules, true); } diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index e2fbd42831..df9da8e866 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -58,7 +58,7 @@ namespace OpenRA MapCache cache; public readonly string Uid; - public string Path { get; private set; } + public IReadOnlyPackage Package { get; private set; } public string Title { get; private set; } public string Type { get; private set; } @@ -126,7 +126,7 @@ namespace OpenRA yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary(); } - Path = p.Name; + Package = p; GridType = gridType; Class = classification; diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 59f57b9a61..f2f5ccb1fa 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -165,7 +165,7 @@ namespace OpenRA throw new InvalidDataException("Invalid map uid: {0}".F(uid)); // Operate on a copy of the map to avoid gameplay state leaking into the cache - var map = new Map(MapCache[uid].Path); + var map = new Map(this, MapCache[uid].Package); LoadTranslations(map); diff --git a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs index 86f9ed434b..502fbebfb4 100644 --- a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs @@ -948,7 +948,7 @@ namespace OpenRA.Mods.Common.Server static void LoadMap(S server) { - server.Map = new Map(server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Path); + server.Map = new Map(server.ModData, server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Package); server.MapPlayers = new MapPlayers(server.Map.PlayerDefinitions); server.LobbyInfo.Slots = server.MapPlayers.Players diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs index cef64043b3..4e8294d945 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.UtilityCommands modData.MapCache.LoadMaps(); maps.AddRange(modData.MapCache .Where(m => m.Status == MapStatus.Available) - .Select(m => new Map(m.Path))); + .Select(m => new Map(modData, m.Package))); } else maps.Add(new Map(args[1])); diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs index ac035fd051..c28f610be5 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs @@ -27,15 +27,16 @@ namespace OpenRA.Mods.Common.UtilityCommands // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - UpgradeRules.UpgradeMapFormat(modData, args[1]); + var package = modData.ModFiles.OpenWritablePackage(args[1]); + UpgradeRules.UpgradeMapFormat(modData, package); - var map = new Map(args[1]); + var map = new Map(modData, package); var engineDate = Exts.ParseIntegerInvariant(args[2]); UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0); UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0); UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0); UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0); - map.Save((IReadWritePackage)map.Package); + map.Save(package); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs index 2828656c87..dd3f4edcc3 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs @@ -100,21 +100,21 @@ namespace OpenRA.Mods.Common.UtilityCommands } Console.WriteLine("Processing Maps:"); - var mapPaths = modData.MapCache - .Where(m => m.Status == MapStatus.Available) - .Select(m => m.Path); + var mapPreviews = modData.MapCache + .Where(m => m.Status == MapStatus.Available); - foreach (var path in mapPaths) + foreach (var p in mapPreviews) { - Console.WriteLine("\t" + path); - UpgradeRules.UpgradeMapFormat(modData, path); + var package = (IReadWritePackage)p.Package; + Console.WriteLine("\t" + package.Name); + UpgradeRules.UpgradeMapFormat(modData, package); - var map = new Map(path); + var map = new Map(modData, package); UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0); UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0); UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0); UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0); - map.Save((IReadWritePackage)map.Package); + map.Save(package); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index d770a2755d..d9809cc2c1 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -15,6 +15,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using OpenRA.FileSystem; using OpenRA.Graphics; using OpenRA.Traits; @@ -3601,95 +3602,92 @@ namespace OpenRA.Mods.Common.UtilityCommands } } - internal static void UpgradeMapFormat(ModData modData, string path) + internal static void UpgradeMapFormat(ModData modData, IReadWritePackage package) { - using (var package = modData.ModFiles.OpenWritablePackage(path)) + if (package == null) + return; + + var yamlStream = package.GetStream("map.yaml"); + if (yamlStream == null) + return; + + var yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, package.Name)); + var nd = yaml.ToDictionary(); + var mapFormat = FieldLoader.GetValue("MapFormat", nd["MapFormat"].Value); + if (mapFormat < 6) + throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(mapFormat, package.Name)); + + // Nothing to do + if (mapFormat >= 8) + return; + + // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum + if (mapFormat < 7) { - if (package == null) - return; + MiniYaml useAsShellmap; + if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) + yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("Shellmap"))); + else if (nd["Type"].Value == "Mission" || nd["Type"].Value == "Campaign") + yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("MissionSelector"))); + } - var yamlStream = package.GetStream("map.yaml"); - if (yamlStream == null) - return; - - var yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, path)); - var nd = yaml.ToDictionary(); - var mapFormat = FieldLoader.GetValue("MapFormat", nd["MapFormat"].Value); - if (mapFormat < 6) - throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(mapFormat, path)); - - // Nothing to do - if (mapFormat >= 8) - return; - - // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum - if (mapFormat < 7) + // Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors + if (mapFormat < 8) + { + var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players"); + if (players != null) { - MiniYaml useAsShellmap; - if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) - yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("Shellmap"))); - else if (nd["Type"].Value == "Mission" || nd["Type"].Value == "Campaign") - yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("MissionSelector"))); - } - - // Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors - if (mapFormat < 8) - { - var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players"); - if (players != null) + bool noteHexColors = false; + bool noteColorRamp = false; + foreach (var player in players.Value.Nodes) { - bool noteHexColors = false; - bool noteColorRamp = false; - foreach (var player in players.Value.Nodes) + var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp"); + if (colorRampNode != null) { - var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp"); - if (colorRampNode != null) + Color dummy; + var parts = colorRampNode.Value.Value.Split(','); + if (parts.Length == 3 || parts.Length == 4) { - Color dummy; - var parts = colorRampNode.Value.Value.Split(','); - if (parts.Length == 3 || parts.Length == 4) + // Try to convert old normalized HSL value to a rgb hex color + try { - // Try to convert old normalized HSL value to a rgb hex color - try - { - HSLColor color = new HSLColor( - (byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255), - (byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255), - (byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255)); - colorRampNode.Value.Value = FieldSaver.FormatValue(color); - noteHexColors = true; - } - catch (Exception) - { - throw new InvalidDataException("Invalid ColorRamp value.\n File: " + path); - } + HSLColor color = new HSLColor( + (byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255), + (byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255), + (byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255)); + colorRampNode.Value.Value = FieldSaver.FormatValue(color); + noteHexColors = true; + } + catch (Exception) + { + throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name); } - else if (parts.Length != 1 || !HSLColor.TryParseRGB(parts[0], out dummy)) - throw new InvalidDataException("Invalid ColorRamp value.\n File: " + path); - - colorRampNode.Key = "Color"; - noteColorRamp = true; } + else if (parts.Length != 1 || !HSLColor.TryParseRGB(parts[0], out dummy)) + throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name); + + colorRampNode.Key = "Color"; + noteColorRamp = true; } - - Console.WriteLine("Converted " + path + " to MapFormat 8."); - if (noteHexColors) - Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa]."); - else if (noteColorRamp) - Console.WriteLine("ColorRamp is now called Color."); } - } - var entries = new Dictionary(); - entries.Add("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString())); - foreach (var file in package.Contents) - { - if (file == "map.yaml") - continue; - - entries.Add(file, package.GetStream(file).ReadAllBytes()); + Console.WriteLine("Converted " + package.Name + " to MapFormat 8."); + if (noteHexColors) + Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa]."); + else if (noteColorRamp) + Console.WriteLine("ColorRamp is now called Color."); } } + + var entries = new Dictionary(); + entries.Add("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString())); + foreach (var file in package.Contents) + { + if (file == "map.yaml") + continue; + + entries.Add(file, package.GetStream(file).ReadAllBytes()); + } } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs index e91ae4790e..ad34870a08 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs @@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var mapDirectories = modData.Manifest.MapFolders .ToDictionary(kv => makeMapDirectory(kv.Key), kv => Enum.Parse(kv.Value)); - var mapPath = map.Package.Name; + var mapPath = map.Package != null ? map.Package.Name : null; var directoryDropdown = widget.Get("DIRECTORY_DROPDOWN"); { Func setupItem = (option, template) => diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 24978d7f22..770b632477 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -737,14 +737,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (MapPreview.Uid == uid) return; - MapPreview = Game.ModData.MapCache[uid]; + var modData = Game.ModData; + MapPreview = modData.MapCache[uid]; Map = null; if (MapPreview.Status == MapStatus.Available) { // Maps need to be validated and pre-loaded before they can be accessed new Thread(_ => { - var currentMap = Map = new Map(MapPreview.Path); + var currentMap = Map = new Map(modData, MapPreview.Package); currentMap.PreloadRules(); Game.RunAfterTick(() => { diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index ef4fe121d6..c067db3988 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -284,7 +284,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic string DeleteMap(string map) { - var path = Game.ModData.MapCache[map].Path; + var path = Game.ModData.MapCache[map].Package.Name; try { if (File.Exists(path)) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index e15829a3ad..6559d17622 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly ScrollPanelWidget missionList; readonly ScrollItemWidget headerTemplate; readonly ScrollItemWidget template; - readonly Cache mapCache = new Cache(p => new Map(p.Path)); + readonly Cache mapCache; MapPreview selectedMapPreview; Map selectedMap; @@ -55,6 +55,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic public MissionBrowserLogic(Widget widget, World world, Action onStart, Action onExit) { modData = Game.ModData; + mapCache = new Cache(p => new Map(modData, p.Package)); this.onStart = onStart; missionList = widget.Get("MISSION_LIST"); @@ -108,8 +109,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)).ToList(); var previews = modData.MapCache - .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path))) - .OrderBy(p => missionMapPaths.IndexOf(Path.GetFullPath(p.Path))); + .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(p.Package.Name)) + .OrderBy(p => missionMapPaths.IndexOf(p.Package.Name)); CreateMissionGroup(kv.Key, previews); allPreviews.AddRange(previews);