Prevent saving and starting a map when max player count is exceeded.

This commit is contained in:
abc013
2021-07-03 12:15:39 +01:00
committed by Smittytron
parent 347a09e6cf
commit 2742985520
4 changed files with 26 additions and 4 deletions

View File

@@ -336,9 +336,6 @@ namespace OpenRA
throw new InvalidDataException($"Map format {MapFormat} is not supported.\n File: {package.Name}");
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
if (PlayerDefinitions.Count > 64)
throw new InvalidDataException($"Maps must not define more than 64 players.\n File: {package.Name}");
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
Grid = modData.Manifest.Get<MapGrid>();

View File

@@ -17,6 +17,10 @@ namespace OpenRA
{
public class MapPlayers
{
// Player masks are represented using a 64 bit integer
// The "Everyone" player for spectators is created at runtime,
// reducing the available player count for maps by 1.
public const int MaximumPlayerCount = 63;
public readonly Dictionary<string, PlayerReference> Players;
public MapPlayers()

View File

@@ -88,6 +88,12 @@ namespace OpenRA.Server
status = Session.MapStatus.Incompatible;
}
if (map.Players.Players.Count > MapPlayers.MaximumPlayerCount)
{
Log.Write("server", "Failed to load `{0}`: Player count exceeds maximum ({1}/{2}).", map.Title, map.Players.Players.Count, MapPlayers.MaximumPlayerCount);
status = Session.MapStatus.Incompatible;
}
cache[map] = status;
if ((status & Session.MapStatus.Validating) != 0)

View File

@@ -351,12 +351,27 @@ namespace OpenRA.Mods.Common.Widgets.Logic
hideMenu = true;
var editorActorLayer = world.WorldActor.Trait<EditorActorLayer>();
var actionManager = world.WorldActor.Trait<EditorActionManager>();
var playerDefinitions = editorActorLayer.Players.ToMiniYaml();
var playerCount = new MapPlayers(playerDefinitions).Players.Count;
if (playerCount > MapPlayers.MaximumPlayerCount)
{
ConfirmationDialogs.ButtonPrompt(
title: "Error: Max player count exceeded",
text: $"There are too many players defined ({playerCount}/{MapPlayers.MaximumPlayerCount}).",
onConfirm: ShowMenu,
confirmText: "Back");
return;
}
Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs()
{
{ "onSave", (Action<string>)(_ => { hideMenu = false; actionManager.Modified = false; }) },
{ "onExit", () => hideMenu = false },
{ "map", world.Map },
{ "playerDefinitions", editorActorLayer.Players.ToMiniYaml() },
{ "playerDefinitions", playerDefinitions },
{ "actorDefinitions", editorActorLayer.Save() }
});
};