Disable maps with broken rules in the lobby. Fixes #4334.
This commit is contained in:
@@ -27,6 +27,9 @@ namespace OpenRA
|
||||
// Used for grouping maps in the UI
|
||||
public enum MapClassification { Unknown, System, User, Remote }
|
||||
|
||||
// Used for verifying map availability in the lobby
|
||||
public enum MapRuleStatus { Unknown, Cached, Invalid }
|
||||
|
||||
// Fields names must match the with the remote API
|
||||
public class RemoteMapData
|
||||
{
|
||||
@@ -58,6 +61,8 @@ namespace OpenRA
|
||||
public MapStatus Status { get; private set; }
|
||||
public MapClassification Class { get; private set; }
|
||||
|
||||
public MapRuleStatus RuleStatus { get; private set; }
|
||||
|
||||
Download download;
|
||||
public long DownloadBytes { get; private set; }
|
||||
public int DownloadPercentage { get; private set; }
|
||||
@@ -227,5 +232,22 @@ namespace OpenRA
|
||||
download.Cancel();
|
||||
download = null;
|
||||
}
|
||||
|
||||
public void CacheRules()
|
||||
{
|
||||
if (RuleStatus != MapRuleStatus.Unknown)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Map.PreloadRules();
|
||||
RuleStatus = MapRuleStatus.Cached;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Write("debug", "Map {0} failed validation with an exception:\n{1}", Uid, e.Message);
|
||||
RuleStatus = MapRuleStatus.Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Traits;
|
||||
@@ -170,7 +171,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (slotsButton != null)
|
||||
{
|
||||
slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
|
||||
!orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);
|
||||
Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);
|
||||
|
||||
var botNames = modRules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name);
|
||||
slotsButton.OnMouseDown = _ =>
|
||||
@@ -264,7 +265,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
optionsBin.IsVisible = () => panel == PanelType.Options;
|
||||
|
||||
var optionsButton = lobby.Get<ButtonWidget>("OPTIONS_BUTTON");
|
||||
optionsButton.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
|
||||
optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
|
||||
optionsButton.GetText = () => panel == PanelType.Options ? "Players" : "Options";
|
||||
optionsButton.OnClick = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;
|
||||
|
||||
@@ -278,7 +279,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
|
||||
if (startGameButton != null)
|
||||
{
|
||||
startGameButton.IsDisabled = () => configurationDisabled() ||
|
||||
startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
|
||||
orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
|
||||
startGameButton.OnClick = () =>
|
||||
{
|
||||
@@ -554,8 +555,20 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
return;
|
||||
|
||||
Map = Game.modData.MapCache[uid];
|
||||
|
||||
if (Map.Status == MapStatus.Available)
|
||||
{
|
||||
// Maps need to be validated and pre-loaded before they can be accessed
|
||||
new Thread(_ =>
|
||||
{
|
||||
var map = Map;
|
||||
map.CacheRules();
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
// Map may have changed in the meantime
|
||||
if (map != Map)
|
||||
return;
|
||||
|
||||
if (map.RuleStatus != MapRuleStatus.Invalid)
|
||||
{
|
||||
// Tell the server that we have the map
|
||||
orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady)));
|
||||
@@ -565,6 +578,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (!Map.Map.Options.StartingCash.HasValue && !pri.SelectableCash.Contains(orderManager.LobbyInfo.GlobalSettings.StartingCash))
|
||||
orderManager.IssueOrder(Order.Command("startingcash {0}".F(pri.DefaultCash)));
|
||||
}
|
||||
});
|
||||
}).Start();
|
||||
}
|
||||
else if (Game.Settings.Game.AllowDownloading)
|
||||
Game.modData.MapCache.QueryRemoteMapDetails(new [] { uid });
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var available = widget.GetOrNull("MAP_AVAILABLE");
|
||||
if (available != null)
|
||||
{
|
||||
available.IsVisible = () => lobby.Map.Status == MapStatus.Available;
|
||||
available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached;
|
||||
|
||||
var preview = available.Get<MapPreviewWidget>("MAP_PREVIEW");
|
||||
preview.Preview = () => lobby.Map;
|
||||
@@ -46,6 +46,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
author.GetText = () => "Created by {0}".F(lobby.Map.Author);
|
||||
}
|
||||
|
||||
var invalid = widget.GetOrNull("MAP_INVALID");
|
||||
if (invalid != null)
|
||||
{
|
||||
invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Invalid;
|
||||
|
||||
var preview = invalid.Get<MapPreviewWidget>("MAP_PREVIEW");
|
||||
preview.Preview = () => lobby.Map;
|
||||
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
||||
preview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager.LobbyInfo, lobby.Map);
|
||||
|
||||
var title = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
|
||||
if (title != null)
|
||||
title.GetText = () => lobby.Map.Title;
|
||||
|
||||
var type = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||
if (type != null)
|
||||
type.GetText = () => lobby.Map.Type;
|
||||
}
|
||||
|
||||
var download = widget.GetOrNull("MAP_DOWNLOADABLE");
|
||||
if (download != null)
|
||||
{
|
||||
@@ -76,7 +95,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var progress = widget.GetOrNull("MAP_PROGRESS");
|
||||
if (progress != null)
|
||||
{
|
||||
progress.IsVisible = () => lobby.Map.Status != MapStatus.Available && lobby.Map.Status != MapStatus.DownloadAvailable;
|
||||
progress.IsVisible = () => (lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) && lobby.Map.Status != MapStatus.DownloadAvailable;
|
||||
|
||||
var preview = progress.Get<MapPreviewWidget>("MAP_PREVIEW");
|
||||
preview.Preview = () => lobby.Map;
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var status = parent.Get<CheckboxWidget>("STATUS_CHECKBOX");
|
||||
status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null;
|
||||
status.IsVisible = () => true;
|
||||
status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available;
|
||||
status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available || map.RuleStatus != MapRuleStatus.Cached;
|
||||
|
||||
var state = orderManager.LocalClient.IsReady ? Session.ClientState.NotReady : Session.ClientState.Ready;
|
||||
status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state)));
|
||||
|
||||
@@ -38,6 +38,41 @@ Container@LOBBY_MAP_PREVIEW:
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Container@MAP_INVALID:
|
||||
Width: PARENT_RIGHT
|
||||
Height: PARENT_BOTTOM
|
||||
Children:
|
||||
Background@MAP_BG:
|
||||
Width: PARENT_RIGHT
|
||||
Height: 194
|
||||
Background: panel-gray
|
||||
Children:
|
||||
MapPreview@MAP_PREVIEW:
|
||||
X: 1
|
||||
Y: 1
|
||||
Width: PARENT_RIGHT-2
|
||||
Height: PARENT_BOTTOM-2
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
Label@MAP_TITLE:
|
||||
Y: 197
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Bold
|
||||
Align: Center
|
||||
Label@MAP_STATUS_A:
|
||||
Y: 212
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Text: This map is not compatible
|
||||
Label@MAP_STATUS_B:
|
||||
Y: 225
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Text: with this version of OpenRA
|
||||
Container@MAP_DOWNLOADABLE:
|
||||
Width: PARENT_RIGHT
|
||||
Height: PARENT_BOTTOM
|
||||
|
||||
@@ -38,6 +38,41 @@ Container@LOBBY_MAP_PREVIEW:
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Container@MAP_INVALID:
|
||||
Width: PARENT_RIGHT
|
||||
Height: PARENT_BOTTOM
|
||||
Children:
|
||||
Background@MAP_BG:
|
||||
Width: PARENT_RIGHT
|
||||
Height: 214
|
||||
Background: dialog3
|
||||
Children:
|
||||
MapPreview@MAP_PREVIEW:
|
||||
X: 1
|
||||
Y: 1
|
||||
Width: PARENT_RIGHT-2
|
||||
Height: PARENT_BOTTOM-2
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
Label@MAP_TITLE:
|
||||
Y: 215
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Bold
|
||||
Align: Center
|
||||
Label@MAP_STATUS_A:
|
||||
Y:232
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Text: This map is not compatible
|
||||
Label@MAP_STATUS_B:
|
||||
Y:245
|
||||
Width: PARENT_RIGHT
|
||||
Height: 25
|
||||
Font: Tiny
|
||||
Align: Center
|
||||
Text: with this version of OpenRA
|
||||
Container@MAP_DOWNLOADABLE:
|
||||
Width: PARENT_RIGHT
|
||||
Height: PARENT_BOTTOM
|
||||
|
||||
Reference in New Issue
Block a user