Parse map rules and players from remote maps.

This commit is contained in:
Paul Chote
2016-03-27 13:11:37 +01:00
parent 81f22f8871
commit 65f7d46025
3 changed files with 47 additions and 12 deletions

View File

@@ -112,7 +112,7 @@ namespace OpenRA
}
}
public void QueryRemoteMapDetails(IEnumerable<string> uids)
public void QueryRemoteMapDetails(IEnumerable<string> uids, Action<MapPreview> mapDetailsReceived = null)
{
var maps = uids.Distinct()
.Select(uid => previews[uid])
@@ -144,7 +144,7 @@ namespace OpenRA
{
var yaml = MiniYaml.FromString(data);
foreach (var kv in yaml)
maps[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value);
maps[kv.Key].UpdateRemoteSearch(MapStatus.DownloadAvailable, kv.Value, mapDetailsReceived);
}
catch
{

View File

@@ -17,6 +17,7 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using OpenRA.FileSystem;
using OpenRA.Graphics;
@@ -51,6 +52,9 @@ namespace OpenRA
public readonly MapGridType map_grid_type;
public readonly string minimap;
public readonly bool downloading;
public readonly string tileset;
public readonly string rules;
public readonly string players_block;
}
public class MapPreview : IDisposable, IReadOnlyFileSystem
@@ -334,7 +338,7 @@ namespace OpenRA
return true;
}
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml)
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action<MapPreview> parseMetadata = null)
{
var newData = innerData.Clone();
newData.Status = status;
@@ -358,14 +362,31 @@ namespace OpenRA
newData.Author = r.author;
newData.PlayerCount = r.players;
newData.Bounds = r.bounds;
newData.TileSet = r.tileset;
var spawns = new CPos[r.spawnpoints.Length / 2];
for (var j = 0; j < r.spawnpoints.Length; j += 2)
spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]);
newData.SpawnPoints = spawns;
newData.GridType = r.map_grid_type;
newData.Preview = new Bitmap(new MemoryStream(Convert.FromBase64String(r.minimap)));
var playersString = Encoding.UTF8.GetString(Convert.FromBase64String(r.players_block));
newData.Players = new MapPlayers(MiniYaml.FromString(playersString));
newData.SetRulesetGenerator(modData, () =>
{
var rulesString = Encoding.UTF8.GetString(Convert.FromBase64String(r.rules));
var rulesYaml = new MiniYaml("", MiniYaml.FromString(rulesString)).ToDictionary();
var ruleDefinitions = LoadRuleSection(rulesYaml, "Rules");
var weaponDefinitions = LoadRuleSection(rulesYaml, "Weapons");
var voiceDefinitions = LoadRuleSection(rulesYaml, "Voices");
var musicDefinitions = LoadRuleSection(rulesYaml, "Music");
var notificationDefinitions = LoadRuleSection(rulesYaml, "Notifications");
var sequenceDefinitions = LoadRuleSection(rulesYaml, "Sequences");
return Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
});
}
catch (Exception) { }
@@ -374,6 +395,9 @@ namespace OpenRA
if (innerData.Preview != null)
cache.CacheMinimap(this);
if (parseMetadata != null)
parseMetadata(this);
}
// Update the status and class unconditionally

View File

@@ -326,7 +326,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
if (startGameButton != null)
{
startGameButton.IsDisabled = () => configurationDisabled() ||
startGameButton.IsDisabled = () => configurationDisabled() || Map.Status != MapStatus.Available ||
orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
(orderManager.LobbyInfo.GlobalSettings.DisableSingleplayer && orderManager.LobbyInfo.IsSinglePlayer);
@@ -464,8 +464,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
startingUnits.IsDisabled = () => configurationDisabled() || startUnitsLocked.Update(Map);
startingUnits.GetText = () => Map.Status != MapStatus.Available ||
!Map.RulesLoaded || startUnitsLocked.Update(Map) ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
startingUnits.GetText = () => !Map.RulesLoaded || startUnitsLocked.Update(Map) ?
"Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
startingUnits.OnMouseDown = _ =>
{
var classes = startUnitsInfos.Update(Map).Select(a => a.Class).Distinct();
@@ -496,8 +496,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
map => map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>());
startingCash.IsDisabled = () => configurationDisabled() || playerResources.Update(Map).DefaultCashLocked;
startingCash.GetText = () => Map.Status != MapStatus.Available ||
!Map.RulesLoaded || playerResources.Update(Map).DefaultCashLocked ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
startingCash.GetText = () => !Map.RulesLoaded || playerResources.Update(Map).DefaultCashLocked ?
"Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
startingCash.OnMouseDown = _ =>
{
var options = playerResources.Update(Map).SelectableCash.Select(c => new DropDownOption
@@ -533,8 +533,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
techLevelDescription.IsVisible = techLevel.IsVisible;
techLevel.IsDisabled = () => configurationDisabled() || mapOptions.Update(Map).TechLevelLocked;
techLevel.GetText = () => Map.Status != MapStatus.Available ||
!Map.RulesLoaded || mapOptions.Update(Map).TechLevelLocked ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
techLevel.GetText = () => !Map.RulesLoaded || mapOptions.Update(Map).TechLevelLocked ?
"Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
techLevel.OnMouseDown = _ =>
{
var options = techLevels.Update(Map).Select(c => new DropDownOption
@@ -776,6 +776,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return true;
}
void LoadMapPreviewRules(MapPreview map)
{
new Task(() =>
{
// Force map rules to be loaded on this background thread
var unused = map.Rules;
}).Start();
}
void UpdateCurrentMap()
{
var uid = orderManager.LobbyInfo.GlobalSettings.Map;
@@ -814,8 +823,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
});
}).Start();
}
else if (Map.Status == MapStatus.DownloadAvailable)
LoadMapPreviewRules(Map);
else if (Game.Settings.Game.AllowDownloading)
modData.MapCache.QueryRemoteMapDetails(new[] { uid });
modData.MapCache.QueryRemoteMapDetails(new[] { uid }, LoadMapPreviewRules);
}
void UpdatePlayerList()