Store map packages in MapPreview.

This commit is contained in:
Paul Chote
2016-02-20 17:50:04 +00:00
parent 226081d379
commit d492c23a6d
12 changed files with 102 additions and 103 deletions

View File

@@ -60,11 +60,9 @@ namespace OpenRA
{ {
using (new Support.PerfTimer(path.Key)) using (new Support.PerfTimer(path.Key))
{ {
using (var package = modData.ModFiles.OpenPackage(path.Key)) var package = modData.ModFiles.OpenPackage(path.Key);
{ var uid = Map.ComputeUID(package);
var uid = Map.ComputeUID(package); previews[uid].UpdateFromMap(package, path.Value, modData.Manifest.MapCompatibility, mapGrid.Type);
previews[uid].UpdateFromMap(package, path.Value, modData.Manifest.MapCompatibility, mapGrid.Type);
}
} }
} }
catch (Exception e) catch (Exception e)
@@ -189,7 +187,7 @@ namespace OpenRA
if (bitmap == null) if (bitmap == null)
{ {
createdPreview = true; 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); bitmap = Minimap.RenderMapPreview(modData.DefaultRules.TileSets[map.Tileset], map, modData.DefaultRules, true);
} }

View File

@@ -58,7 +58,7 @@ namespace OpenRA
MapCache cache; MapCache cache;
public readonly string Uid; public readonly string Uid;
public string Path { get; private set; } public IReadOnlyPackage Package { get; private set; }
public string Title { get; private set; } public string Title { get; private set; }
public string Type { 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(); yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
} }
Path = p.Name; Package = p;
GridType = gridType; GridType = gridType;
Class = classification; Class = classification;

View File

@@ -165,7 +165,7 @@ namespace OpenRA
throw new InvalidDataException("Invalid map uid: {0}".F(uid)); throw new InvalidDataException("Invalid map uid: {0}".F(uid));
// Operate on a copy of the map to avoid gameplay state leaking into the cache // 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); LoadTranslations(map);

View File

@@ -948,7 +948,7 @@ namespace OpenRA.Mods.Common.Server
static void LoadMap(S 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.MapPlayers = new MapPlayers(server.Map.PlayerDefinitions);
server.LobbyInfo.Slots = server.MapPlayers.Players server.LobbyInfo.Slots = server.MapPlayers.Players

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
modData.MapCache.LoadMaps(); modData.MapCache.LoadMaps();
maps.AddRange(modData.MapCache maps.AddRange(modData.MapCache
.Where(m => m.Status == MapStatus.Available) .Where(m => m.Status == MapStatus.Available)
.Select(m => new Map(m.Path))); .Select(m => new Map(modData, m.Package)));
} }
else else
maps.Add(new Map(args[1])); maps.Add(new Map(args[1]));

View File

@@ -27,15 +27,16 @@ namespace OpenRA.Mods.Common.UtilityCommands
// HACK: The engine code assumes that Game.modData is set. // HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData; 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]); var engineDate = Exts.ParseIntegerInvariant(args[2]);
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0); UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0); UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0); UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0);
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0); UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save((IReadWritePackage)map.Package); map.Save(package);
} }
} }
} }

View File

@@ -100,21 +100,21 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
Console.WriteLine("Processing Maps:"); Console.WriteLine("Processing Maps:");
var mapPaths = modData.MapCache var mapPreviews = modData.MapCache
.Where(m => m.Status == MapStatus.Available) .Where(m => m.Status == MapStatus.Available);
.Select(m => m.Path);
foreach (var path in mapPaths) foreach (var p in mapPreviews)
{ {
Console.WriteLine("\t" + path); var package = (IReadWritePackage)p.Package;
UpgradeRules.UpgradeMapFormat(modData, path); 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.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0); UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0); UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0);
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0); UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save((IReadWritePackage)map.Package); map.Save(package);
} }
} }
} }

View File

@@ -15,6 +15,7 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using OpenRA.FileSystem;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Traits; 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<int>("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) MiniYaml useAsShellmap;
return; 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"); // Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors
if (yamlStream == null) if (mapFormat < 8)
return; {
var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players");
var yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, path)); if (players != null)
var nd = yaml.ToDictionary();
var mapFormat = FieldLoader.GetValue<int>("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)
{ {
MiniYaml useAsShellmap; bool noteHexColors = false;
if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) bool noteColorRamp = false;
yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("Shellmap"))); foreach (var player in players.Value.Nodes)
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; var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp");
bool noteColorRamp = false; if (colorRampNode != null)
foreach (var player in players.Value.Nodes)
{ {
var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp"); Color dummy;
if (colorRampNode != null) var parts = colorRampNode.Value.Value.Split(',');
if (parts.Length == 3 || parts.Length == 4)
{ {
Color dummy; // Try to convert old normalized HSL value to a rgb hex color
var parts = colorRampNode.Value.Value.Split(','); try
if (parts.Length == 3 || parts.Length == 4)
{ {
// Try to convert old normalized HSL value to a rgb hex color HSLColor color = new HSLColor(
try (byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255),
{ (byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255),
HSLColor color = new HSLColor( (byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255));
(byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255), colorRampNode.Value.Value = FieldSaver.FormatValue(color);
(byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255), noteHexColors = true;
(byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255)); }
colorRampNode.Value.Value = FieldSaver.FormatValue(color); catch (Exception)
noteHexColors = true; {
} throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name);
catch (Exception)
{
throw new InvalidDataException("Invalid ColorRamp value.\n File: " + path);
}
} }
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<string, byte[]>(); Console.WriteLine("Converted " + package.Name + " to MapFormat 8.");
entries.Add("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString())); if (noteHexColors)
foreach (var file in package.Contents) Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa].");
{ else if (noteColorRamp)
if (file == "map.yaml") Console.WriteLine("ColorRamp is now called Color.");
continue;
entries.Add(file, package.GetStream(file).ReadAllBytes());
} }
} }
var entries = new Dictionary<string, byte[]>();
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());
}
} }
} }
} }

View File

@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var mapDirectories = modData.Manifest.MapFolders var mapDirectories = modData.Manifest.MapFolders
.ToDictionary(kv => makeMapDirectory(kv.Key), kv => Enum<MapClassification>.Parse(kv.Value)); .ToDictionary(kv => makeMapDirectory(kv.Key), kv => Enum<MapClassification>.Parse(kv.Value));
var mapPath = map.Package.Name; var mapPath = map.Package != null ? map.Package.Name : null;
var directoryDropdown = widget.Get<DropDownButtonWidget>("DIRECTORY_DROPDOWN"); var directoryDropdown = widget.Get<DropDownButtonWidget>("DIRECTORY_DROPDOWN");
{ {
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>

View File

@@ -737,14 +737,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (MapPreview.Uid == uid) if (MapPreview.Uid == uid)
return; return;
MapPreview = Game.ModData.MapCache[uid]; var modData = Game.ModData;
MapPreview = modData.MapCache[uid];
Map = null; Map = null;
if (MapPreview.Status == MapStatus.Available) if (MapPreview.Status == MapStatus.Available)
{ {
// Maps need to be validated and pre-loaded before they can be accessed // Maps need to be validated and pre-loaded before they can be accessed
new Thread(_ => new Thread(_ =>
{ {
var currentMap = Map = new Map(MapPreview.Path); var currentMap = Map = new Map(modData, MapPreview.Package);
currentMap.PreloadRules(); currentMap.PreloadRules();
Game.RunAfterTick(() => Game.RunAfterTick(() =>
{ {

View File

@@ -284,7 +284,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
string DeleteMap(string map) string DeleteMap(string map)
{ {
var path = Game.ModData.MapCache[map].Path; var path = Game.ModData.MapCache[map].Package.Name;
try try
{ {
if (File.Exists(path)) if (File.Exists(path))

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ScrollPanelWidget missionList; readonly ScrollPanelWidget missionList;
readonly ScrollItemWidget headerTemplate; readonly ScrollItemWidget headerTemplate;
readonly ScrollItemWidget template; readonly ScrollItemWidget template;
readonly Cache<MapPreview, Map> mapCache = new Cache<MapPreview, Map>(p => new Map(p.Path)); readonly Cache<MapPreview, Map> mapCache;
MapPreview selectedMapPreview; MapPreview selectedMapPreview;
Map selectedMap; Map selectedMap;
@@ -55,6 +55,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public MissionBrowserLogic(Widget widget, World world, Action onStart, Action onExit) public MissionBrowserLogic(Widget widget, World world, Action onStart, Action onExit)
{ {
modData = Game.ModData; modData = Game.ModData;
mapCache = new Cache<MapPreview, Map>(p => new Map(modData, p.Package));
this.onStart = onStart; this.onStart = onStart;
missionList = widget.Get<ScrollPanelWidget>("MISSION_LIST"); missionList = widget.Get<ScrollPanelWidget>("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 missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)).ToList();
var previews = modData.MapCache var previews = modData.MapCache
.Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(Path.GetFullPath(p.Path))) .Where(p => p.Status == MapStatus.Available && missionMapPaths.Contains(p.Package.Name))
.OrderBy(p => missionMapPaths.IndexOf(Path.GetFullPath(p.Path))); .OrderBy(p => missionMapPaths.IndexOf(p.Package.Name));
CreateMissionGroup(kv.Key, previews); CreateMissionGroup(kv.Key, previews);
allPreviews.AddRange(previews); allPreviews.AddRange(previews);