Add a player list to the MP server browser.

This commit is contained in:
Paul Chote
2017-12-25 13:20:13 +00:00
committed by reaperrr
parent 3ba610b535
commit bccc0f8f17
11 changed files with 383 additions and 104 deletions

View File

@@ -18,6 +18,7 @@ using System.Text;
using BeaconLib;
using OpenRA.Network;
using OpenRA.Server;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -37,13 +38,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ModData modData;
readonly WebServices services;
readonly Probe lanGameProbe;
readonly ScrollItemWidget serverTemplate;
readonly ScrollItemWidget headerTemplate;
readonly Widget clientContainer;
readonly ScrollPanelWidget clientList;
readonly ScrollItemWidget clientTemplate, clientHeader;
readonly MapPreviewWidget mapPreview;
readonly ButtonWidget joinButton;
readonly int joinButtonY;
GameServer currentServer;
MapPreview currentMap;
ScrollItemWidget serverTemplate;
ScrollItemWidget headerTemplate;
Action onStart;
Action onExit;
@@ -85,10 +91,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
headerTemplate = serverList.Get<ScrollItemWidget>("HEADER_TEMPLATE");
serverTemplate = serverList.Get<ScrollItemWidget>("SERVER_TEMPLATE");
var join = widget.Get<ButtonWidget>("JOIN_BUTTON");
join.IsVisible = () => currentServer != null;
join.IsDisabled = () => !currentServer.IsJoinable;
join.OnClick = () => Join(currentServer);
joinButton = widget.Get<ButtonWidget>("JOIN_BUTTON");
joinButton.IsVisible = () => currentServer != null;
joinButton.IsDisabled = () => !currentServer.IsJoinable;
joinButton.OnClick = () => Join(currentServer);
joinButtonY = joinButton.Bounds.Y;
// Display the progress label over the server list
// The text is only visible when the list is empty
@@ -159,7 +166,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
refreshButton.OnClick = RefreshServerList;
}
var mapPreview = widget.GetOrNull<MapPreviewWidget>("SELECTED_MAP_PREVIEW");
mapPreview = widget.GetOrNull<MapPreviewWidget>("SELECTED_MAP_PREVIEW");
if (mapPreview != null)
mapPreview.Preview = () => currentMap;
@@ -201,10 +208,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var players = widget.GetOrNull<LabelWidget>("SELECTED_PLAYERS");
if (players != null)
{
players.IsVisible = () => currentServer != null;
players.IsVisible = () => currentServer != null && !currentServer.Clients.Any();
players.GetText = () => PlayersLabel(currentServer);
}
clientContainer = widget.Get("CLIENT_LIST_CONTAINER");
clientList = Ui.LoadWidget("MULTIPLAYER_CLIENT_LIST", clientContainer, new WidgetArgs()) as ScrollPanelWidget;
clientList.IsVisible = () => currentServer != null && currentServer.Clients.Any();
clientHeader = clientList.Get<ScrollItemWidget>("HEADER");
clientTemplate = clientList.Get<ScrollItemWidget>("TEMPLATE");
clientList.RemoveChildren();
var directConnectButton = widget.Get<ButtonWidget>("DIRECTCONNECT_BUTTON");
directConnectButton.OnClick = () =>
{
@@ -361,6 +375,86 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
currentServer = server;
currentMap = server != null ? modData.MapCache[server.Map] : null;
clientList.RemoveChildren();
if (server == null || !server.Clients.Any())
{
joinButton.Bounds.Y = joinButtonY;
return;
}
joinButton.Bounds.Y = clientContainer.Bounds.Bottom;
var players = server.Clients
.Where(c => !c.IsSpectator)
.GroupBy(p => p.Team)
.OrderBy(g => g.Key);
var teams = new Dictionary<string, IEnumerable<GameClient>>();
var noTeams = players.Count() == 1;
foreach (var p in players)
{
var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : "Team {0}".F(p.Key);
teams.Add(label, p);
}
if (server.Clients.Any(c => c.IsSpectator))
teams.Add("Spectators", server.Clients.Where(c => c.IsSpectator));
// Can only show factions if the server is running the same mod
var disableFactionDisplay = server.Mod != modData.Manifest.Id;
if (mapPreview != null)
{
var spawns = currentMap.SpawnPoints;
var occupants = server.Clients
.Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length))
.ToDictionary(c => spawns[c.SpawnPoint - 1], c => new SpawnOccupant(c, disableFactionDisplay));
mapPreview.SpawnOccupants = () => occupants;
}
var factionInfo = modData.DefaultRules.Actors["world"].TraitInfos<FactionInfo>();
foreach (var kv in teams)
{
var group = kv.Key;
if (group.Length > 0)
{
var header = ScrollItemWidget.Setup(clientHeader, () => true, () => { });
header.Get<LabelWidget>("LABEL").GetText = () => group;
clientList.AddChild(header);
}
foreach (var option in kv.Value)
{
var o = option;
var item = ScrollItemWidget.Setup(clientTemplate, () => false, () => { });
if (!o.IsSpectator && !disableFactionDisplay)
{
var label = item.Get<LabelWidget>("LABEL");
var font = Game.Renderer.Fonts[label.Font];
var name = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font);
label.GetText = () => name;
label.GetColor = () => o.Color.RGB;
var flag = item.Get<ImageWidget>("FLAG");
flag.IsVisible = () => true;
flag.GetImageCollection = () => "flags";
flag.GetImageName = () => (factionInfo != null && factionInfo.Any(f => f.InternalName == o.Faction)) ? o.Faction : "Random";
}
else
{
var label = item.Get<LabelWidget>("NOFLAG_LABEL");
var font = Game.Renderer.Fonts[label.Font];
var name = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font);
label.GetText = () => name;
label.GetColor = () => o.Color.RGB;
}
clientList.AddChild(item);
}
}
}
void RefreshServerListInner(List<GameServer> games)