From 9c3b967a47cbe3b3b4bf4e8e3f79d839b12819db Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 17:10:23 +0000 Subject: [PATCH 1/5] Remove dead map saving code. --- OpenRA.Game/Map/Map.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 5d08ae8913..783314a56a 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -357,12 +357,6 @@ namespace OpenRA PostInit(); - // The Uid is calculated from the data on-disk, so - // format changes must be flushed to disk. - // TODO: this isn't very nice - if (MapFormat < 8) - Save(path); - Uid = ComputeUID(Container); } From 573e26c8872bbb848a9a3d63d34dc733deab2ac9 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 17:23:49 +0000 Subject: [PATCH 2/5] Load and save maps using packages. --- OpenRA.Game/Map/Map.cs | 81 ++++++++++--------- .../UtilityCommands/ImportLegacyMapCommand.cs | 2 +- .../Widgets/Logic/Editor/NewMapLogic.cs | 2 +- .../Widgets/Logic/Editor/SaveMapLogic.cs | 2 +- .../UtilityCommands/D2kMapImporter.cs | 2 +- .../UtilityCommands/ImportTSMapCommand.cs | 2 +- 6 files changed, 48 insertions(+), 43 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 783314a56a..9fb63ac27c 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -113,12 +113,14 @@ namespace OpenRA public const int MaxTilesInCircleRange = 50; public readonly MapGrid Grid; + readonly ModData modData; [FieldLoader.Ignore] public readonly WVec[] SubCellOffsets; public readonly SubCell DefaultSubCell; public readonly SubCell LastSubCell; - [FieldLoader.Ignore] public IReadWritePackage Container; - public string Path { get; private set; } + + public IReadOnlyPackage Package { get; private set; } + public string Path { get { return Package.Name; } } // Yaml map data public string Uid { get; private set; } @@ -251,7 +253,7 @@ namespace OpenRA void AssertExists(string filename) { - using (var s = Container.GetStream(filename)) + using (var s = Package.GetStream(filename)) if (s == null) throw new InvalidOperationException("Required file {0} not present in this map".F(filename)); } @@ -260,10 +262,11 @@ namespace OpenRA /// 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. /// - public Map(TileSet tileset, int width, int height) + public Map(ModData modData, TileSet tileset, int width, int height) { + this.modData = modData; var size = new Size(width, height); - Grid = Game.ModData.Manifest.Get(); + Grid = modData.Manifest.Get(); var tileRef = new TerrainTile(tileset.Templates.First().Key, 0); Title = "Name your map here"; @@ -302,18 +305,21 @@ namespace OpenRA /// Initializes a map loaded from disk. public Map(string path) + : this(Game.ModData, Game.ModData.ModFiles.OpenPackage(path)) { } + + public Map(ModData modData, IReadOnlyPackage package) { - Path = path; - Container = Game.ModData.ModFiles.OpenWritablePackage(path); + this.modData = modData; + Package = package; AssertExists("map.yaml"); AssertExists("map.bin"); - var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetStream("map.yaml"), path)); + var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name)); FieldLoader.Load(this, yaml); if (MapFormat != SupportedMapFormat) - throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path)); + throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name)); SpawnPoints = Exts.Lazy(() => { @@ -345,19 +351,19 @@ namespace OpenRA MapResources = Exts.Lazy(LoadResourceTiles); MapHeight = Exts.Lazy(LoadMapHeight); - Grid = Game.ModData.Manifest.Get(); + Grid = modData.Manifest.Get(); SubCellOffsets = Grid.SubCellOffsets; LastSubCell = (SubCell)(SubCellOffsets.Length - 1); DefaultSubCell = (SubCell)Grid.SubCellDefaultIndex; - if (Container.Contains("map.png")) - using (var dataStream = Container.GetStream("map.png")) + if (Package.Contains("map.png")) + using (var dataStream = Package.GetStream("map.png")) CustomPreview = new Bitmap(dataStream); PostInit(); - Uid = ComputeUID(Container); + Uid = ComputeUID(Package); } void PostInit() @@ -366,7 +372,7 @@ namespace OpenRA { try { - return Game.ModData.RulesetCache.Load(this, this); + return modData.RulesetCache.Load(this, this); } catch (Exception e) { @@ -374,7 +380,7 @@ namespace OpenRA Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message); } - return Game.ModData.DefaultRules; + return modData.DefaultRules; }); cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]); @@ -489,6 +495,11 @@ namespace OpenRA } public void Save(string toPath) + { + Save(modData.ModFiles.CreatePackage(toPath, new Dictionary())); + } + + public void Save(IReadWritePackage toContainer) { MapFormat = 8; @@ -538,37 +549,31 @@ namespace OpenRA entries.Add("map.yaml", Encoding.UTF8.GetBytes(s)); // Add any custom assets - if (Container != null) + if (Package != null) { - foreach (var file in Container.Contents) + foreach (var file in Package.Contents) { if (file == "map.bin" || file == "map.yaml") continue; - entries.Add(file, Container.GetStream(file).ReadAllBytes()); + entries.Add(file, Package.GetStream(file).ReadAllBytes()); } } // Saving the map to a new location - if (toPath != Path || Container == null) - { - Path = toPath; - - // Create a new map package - Container = Game.ModData.ModFiles.CreatePackage(Path, entries); - } + Package = toContainer; // Update existing package - Container.Write(entries); + toContainer.Write(entries); // Update UID to match the newly saved data - Uid = ComputeUID(Container); + Uid = ComputeUID(toContainer); } public CellLayer LoadMapTiles() { var tiles = new CellLayer(this); - using (var s = Container.GetStream("map.bin")) + using (var s = Package.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.TilesOffset > 0) @@ -600,7 +605,7 @@ namespace OpenRA public CellLayer LoadMapHeight() { var tiles = new CellLayer(this); - using (var s = Container.GetStream("map.bin")) + using (var s = Package.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.HeightsOffset > 0) @@ -622,7 +627,7 @@ namespace OpenRA { var resources = new CellLayer(this); - using (var s = Container.GetStream("map.bin")) + using (var s = Package.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.ResourcesOffset > 0) @@ -1173,16 +1178,16 @@ namespace OpenRA public Stream Open(string filename) { // Explicit package paths never refer to a map - if (!filename.Contains("|") && Container.Contains(filename)) - return Container.GetStream(filename); + if (!filename.Contains("|") && Package.Contains(filename)) + return Package.GetStream(filename); - return Game.ModData.DefaultFileSystem.Open(filename); + return modData.DefaultFileSystem.Open(filename); } public bool TryGetPackageContaining(string path, out IReadOnlyPackage package, out string filename) { // Packages aren't supported inside maps - return Game.ModData.DefaultFileSystem.TryGetPackageContaining(path, out package, out filename); + return modData.DefaultFileSystem.TryGetPackageContaining(path, out package, out filename); } public bool TryOpen(string filename, out Stream s) @@ -1190,21 +1195,21 @@ namespace OpenRA // Explicit package paths never refer to a map if (!filename.Contains("|")) { - s = Container.GetStream(filename); + s = Package.GetStream(filename); if (s != null) return true; } - return Game.ModData.DefaultFileSystem.TryOpen(filename, out s); + return modData.DefaultFileSystem.TryOpen(filename, out s); } public bool Exists(string filename) { // Explicit package paths never refer to a map - if (!filename.Contains("|") && Container.Contains(filename)) + if (!filename.Contains("|") && Package.Contains(filename)) return true; - return Game.ModData.DefaultFileSystem.Exists(filename); + return modData.DefaultFileSystem.Exists(filename); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index bc21ec4f6a..2ddeec6947 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.UtilityCommands ValidateMapFormat(format); var tileset = GetTileset(mapSection); - Map = new Map(Rules.TileSets[tileset], MapSize, MapSize) + Map = new Map(modData, Rules.TileSets[tileset], MapSize, MapSize) { Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)), Author = "Westwood Studios" diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs index 8549b069d8..747d848155 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var tileset = modRules.TileSets[tilesetDropDown.Text]; - var map = new Map(tileset, width + 2, height + maxTerrainHeight + 2); + var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1); var br = new PPos(width, height + maxTerrainHeight); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs index d9bfda3d8a..904c7073b8 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs @@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Update the map cache so it can be loaded without restarting the game var classification = mapDirectories[directoryDropdown.Text]; - modData.MapCache[map.Uid].UpdateFromMap(map.Container, classification, null, map.Grid.Type); + modData.MapCache[map.Uid].UpdateFromMap(map.Package, classification, null, map.Grid.Type); Console.WriteLine("Saved current map at {0}", combinedPath); Ui.CloseWindow(); diff --git a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs index 59fb7dbfd4..e2b3f55b48 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs @@ -309,7 +309,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands tileSet = rules.TileSets["ARRAKIS"]; - map = new Map(tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth) + map = new Map(Game.ModData, tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth) { Title = Path.GetFileNameWithoutExtension(mapFile), Author = "Westwood Studios" diff --git a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs index 85582237a1..14c8e21038 100644 --- a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs +++ b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs @@ -221,7 +221,7 @@ namespace OpenRA.Mods.TS.UtilityCommands fullSize = new int2(iniSize[2], iniSize[3]); - var map = new Map(modData.DefaultRules.TileSets[tileset], size.Width, size.Height); + var map = new Map(Game.ModData, modData.DefaultRules.TileSets[tileset], size.Width, size.Height); map.Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)); map.Author = "Westwood Studios"; map.Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]); From 226081d3791de1d293da73edb9f35c69e58f995f Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 17:33:13 +0000 Subject: [PATCH 3/5] Remove map saving shim method. --- OpenRA.Game/FileSystem/FileSystem.cs | 3 ++- OpenRA.Game/Map/Map.cs | 6 ------ .../UtilityCommands/ImportLegacyMapCommand.cs | 6 +++--- .../UtilityCommands/ResizeMapCommand.cs | 3 ++- .../UtilityCommands/UpgradeMapCommand.cs | 4 +++- .../UtilityCommands/UpgradeModCommand.cs | 3 ++- .../Widgets/Logic/Editor/SaveMapLogic.cs | 17 +++++++++++------ .../UtilityCommands/ImportD2kMapCommand.cs | 6 +++--- .../UtilityCommands/ImportTSMapCommand.cs | 6 +++--- 9 files changed, 29 insertions(+), 25 deletions(-) diff --git a/OpenRA.Game/FileSystem/FileSystem.cs b/OpenRA.Game/FileSystem/FileSystem.cs index c59371e8c4..3591268b46 100644 --- a/OpenRA.Game/FileSystem/FileSystem.cs +++ b/OpenRA.Game/FileSystem/FileSystem.cs @@ -33,8 +33,9 @@ namespace OpenRA.FileSystem Cache> fileIndex = new Cache>(_ => new List()); - public IReadWritePackage CreatePackage(string filename, Dictionary content) + public IReadWritePackage CreatePackage(string filename) { + var content = new Dictionary(); if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) return new ZipFile(this, filename, content); if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 9fb63ac27c..76123a6974 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -120,7 +120,6 @@ namespace OpenRA public readonly SubCell LastSubCell; public IReadOnlyPackage Package { get; private set; } - public string Path { get { return Package.Name; } } // Yaml map data public string Uid { get; private set; } @@ -494,11 +493,6 @@ namespace OpenRA return rules.Value; } - public void Save(string toPath) - { - Save(modData.ModFiles.CreatePackage(toPath, new Dictionary())); - } - public void Save(IReadWritePackage toContainer) { MapFormat = 8; diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index 2ddeec6947..3049205120 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -93,9 +93,9 @@ namespace OpenRA.Mods.Common.UtilityCommands Map.FixOpenAreas(Rules); - var fileName = Path.GetFileNameWithoutExtension(args[1]); - var dest = fileName + ".oramap"; - Map.Save(dest); + var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap"; + var package = modData.ModFiles.CreatePackage(dest); + Map.Save(package); Console.WriteLine(dest + " saved."); } diff --git a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs index 96ffa3c2ef..d6039796e9 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.FileSystem; namespace OpenRA.Mods.Common.UtilityCommands { @@ -67,7 +68,7 @@ namespace OpenRA.Mods.Common.UtilityCommands foreach (var kv in forRemoval) map.ActorDefinitions.Remove(kv); - map.Save(map.Path); + map.Save((IReadWritePackage)map.Package); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs index 831e3f8538..ac035fd051 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeMapCommand.cs @@ -8,6 +8,8 @@ */ #endregion +using OpenRA.FileSystem; + namespace OpenRA.Mods.Common.UtilityCommands { class UpgradeMapCommand : IUtilityCommand @@ -33,7 +35,7 @@ namespace OpenRA.Mods.Common.UtilityCommands 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(args[1]); + map.Save((IReadWritePackage)map.Package); } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs index f03f8857b1..2828656c87 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeModCommand.cs @@ -11,6 +11,7 @@ using System; using System.IO; using System.Linq; +using OpenRA.FileSystem; namespace OpenRA.Mods.Common.UtilityCommands { @@ -113,7 +114,7 @@ namespace OpenRA.Mods.Common.UtilityCommands 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(map.Path); + map.Save((IReadWritePackage)map.Package); } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs index 904c7073b8..e91ae4790e 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs @@ -75,6 +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 directoryDropdown = widget.Get("DIRECTORY_DROPDOWN"); { Func setupItem = (option, template) => @@ -86,7 +87,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic return item; }; - var mapDirectory = map.Path != null ? Platform.UnresolvePath(Path.GetDirectoryName(map.Path)) : null; + // TODO: This won't work for maps inside oramod packages + var mapDirectory = mapPath != null ? Platform.UnresolvePath(Path.GetDirectoryName(mapPath)) : null; var initialDirectory = mapDirectories.Keys.FirstOrDefault(f => f == mapDirectory); // Prioritize MapClassification.User directories over system directories @@ -100,14 +102,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic var mapIsUnpacked = false; - if (map.Path != null) + // TODO: This won't work for maps inside oramod packages + if (mapPath != null) { - var attr = File.GetAttributes(map.Path); + var attr = File.GetAttributes(mapPath); mapIsUnpacked = attr.HasFlag(FileAttributes.Directory); } var filename = widget.Get("FILENAME"); - filename.Text = mapIsUnpacked ? Path.GetFileName(map.Path) : Path.GetFileNameWithoutExtension(map.Path); + filename.Text = mapIsUnpacked ? Path.GetFileName(mapPath) : Path.GetFileNameWithoutExtension(mapPath); var fileType = mapIsUnpacked ? MapFileType.Unpacked : MapFileType.OraMap; var fileTypes = new Dictionary() @@ -158,13 +161,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Create the map directory if required Directory.CreateDirectory(Platform.ResolvePath(directoryDropdown.Text)); + // TODO: This won't work for maps inside oramod packages var combinedPath = Platform.ResolvePath(Path.Combine(directoryDropdown.Text, filename.Text + fileTypes[fileType].Extension)); // Invalidate the old map metadata - if (map.Uid != null && combinedPath == map.Path) + if (map.Uid != null && combinedPath == mapPath) modData.MapCache[map.Uid].Invalidate(); - map.Save(combinedPath); + var package = modData.ModFiles.CreatePackage(combinedPath); + map.Save(package); // Update the map cache so it can be loaded without restarting the game var classification = mapDirectories[directoryDropdown.Text]; diff --git a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs index 7656189501..5ce82b9a77 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs @@ -35,9 +35,9 @@ namespace OpenRA.Mods.D2k.UtilityCommands if (map == null) return; - var fileName = Path.GetFileNameWithoutExtension(args[1]); - var dest = fileName + ".oramap"; - map.Save(dest); + var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap"; + var package = modData.ModFiles.CreatePackage(dest); + map.Save(package); Console.WriteLine(dest + " saved."); } } diff --git a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs index 14c8e21038..bc1be4c41f 100644 --- a/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs +++ b/OpenRA.Mods.TS/UtilityCommands/ImportTSMapCommand.cs @@ -171,9 +171,9 @@ namespace OpenRA.Mods.TS.UtilityCommands var mapPlayers = new MapPlayers(map.Rules, spawnCount); map.PlayerDefinitions = mapPlayers.ToMiniYaml(); - var fileName = Path.GetFileNameWithoutExtension(filename); - var dest = fileName + ".oramap"; - map.Save(dest); + var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap"; + var package = modData.ModFiles.CreatePackage(dest); + map.Save(package); Console.WriteLine(dest + " saved."); } From d492c23a6df31b80f856c4e91c3988b8c4a89419 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 17:50:04 +0000 Subject: [PATCH 4/5] 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); From 8a9bce45ecd9f162930fcc0fbfcdb85342f319fa Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Feb 2016 18:00:07 +0000 Subject: [PATCH 5/5] Remove map loading shim. --- OpenRA.Game/Map/Map.cs | 4 ---- OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs | 2 +- OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs | 2 +- OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 76123a6974..b030d11d65 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -302,10 +302,6 @@ namespace OpenRA PostInit(); } - /// Initializes a map loaded from disk. - public Map(string path) - : this(Game.ModData, Game.ModData.ModFiles.OpenPackage(path)) { } - public Map(ModData modData, IReadOnlyPackage package) { this.modData = modData; diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs index 4e8294d945..7cddb8fa48 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Select(m => new Map(modData, m.Package))); } else - maps.Add(new Map(args[1])); + maps.Add(new Map(modData, modData.ModFiles.OpenPackage(args[1]))); foreach (var testMap in maps) { diff --git a/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs index 4ffdfd0593..7b849ecd3c 100644 --- a/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { Game.ModData = modData; - var map = new Map(args[1]); + var map = new Map(modData, modData.ModFiles.OpenPackage(args[1])); var minimap = Minimap.RenderMapPreview(map.Rules.TileSets[map.Tileset], map, true); var dest = Path.GetFileNameWithoutExtension(args[1]) + ".png"; diff --git a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs index d6039796e9..173b29dac3 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.UtilityCommands public void Run(ModData modData, string[] args) { Game.ModData = modData; - map = new Map(args[1]); + map = new Map(modData, modData.ModFiles.OpenPackage(args[1])); Console.WriteLine("Resizing map {0} from {1} to {2},{3}", map.Title, map.MapSize, width, height); map.Resize(width, height);