Parse map rules and players from remote maps.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user