Skip to content

Commit

Permalink
Added a player action dropdown.
Browse files Browse the repository at this point in the history
Adds options for:
 - handling kick
 - transferring admin
 - move to spectator
  • Loading branch information
teinarss authored and pchote committed Jul 5, 2018
1 parent 0c1b11e commit 1c0aa24
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 60 deletions.
61 changes: 61 additions & 0 deletions OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class LobbyCommands : ServerTrait, IInterpretCommand, INotifyServerStart,
{ "option", Option },
{ "assignteams", AssignTeams },
{ "kick", Kick },
{ "make_admin", MakeAdmin },
{ "make_spectator", MakeSpectator },
{ "name", Name },
{ "faction", Faction },
{ "team", Team },
Expand Down Expand Up @@ -601,6 +603,65 @@ static bool Kick(S server, Connection conn, Session.Client client, string s)
return true;
}

static bool MakeAdmin(S server, Connection conn, Session.Client client, string s)
{
if (!client.IsAdmin)
{
server.SendOrderTo(conn, "Message", "Only admins can transfer admin to another player.");
return true;
}

int newAdminId;
Exts.TryParseIntegerInvariant(s, out newAdminId);
var newAdminConn = server.Conns.SingleOrDefault(c => server.GetClient(c) != null && server.GetClient(c).Index == newAdminId);

if (newAdminConn == null)
{
server.SendOrderTo(conn, "Message", "No-one in that slot.");
return true;
}

var newAdminClient = server.GetClient(newAdminConn);
client.IsAdmin = false;
newAdminClient.IsAdmin = true;
server.SendMessage("{0} is now the admin.".F(newAdminClient.Name));
Log.Write("server", "{0} is now the admin.".F(newAdminClient.Name));
server.SyncLobbyClients();

return true;
}

static bool MakeSpectator(S server, Connection conn, Session.Client client, string s)
{
if (!client.IsAdmin)
{
server.SendOrderTo(conn, "Message", "Only the host can move players to spectators.");
return true;
}

int targetId;
Exts.TryParseIntegerInvariant(s, out targetId);
var targetConn = server.Conns.SingleOrDefault(c => server.GetClient(c) != null && server.GetClient(c).Index == targetId);

if (targetConn == null)
{
server.SendOrderTo(conn, "Message", "No-one in that slot.");
return true;
}

var targetClient = server.GetClient(targetConn);
targetClient.Slot = null;
targetClient.SpawnPoint = 0;
targetClient.Team = 0;
targetClient.Color = HSLColor.FromRGB(255, 255, 255);
server.SendMessage("{0} moved {1} to spectators.".F(client.Name, targetClient.Name));
Log.Write("server", "{0} moved {1} to spectators.".F(client.Name, targetClient.Name));
server.SyncLobbyClients();
CheckAutoStart(server);

return true;
}

static bool Name(S server, Connection conn, Session.Client client, string s)
{
var sanitizedName = Settings.SanitizedPlayerName(s);
Expand Down
29 changes: 16 additions & 13 deletions OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -594,18 +594,19 @@ void UpdatePlayerList()
template = nonEditablePlayerTemplate.Clone();

LobbyUtils.SetupClientWidget(template, client, orderManager, client.Bot == null);
LobbyUtils.SetupNameWidget(template, slot, client);
LobbyUtils.SetupKickWidget(template, slot, client, orderManager, lobby,
() => panel = PanelType.Kick, () => panel = PanelType.Players);
LobbyUtils.SetupColorWidget(template, slot, client);
LobbyUtils.SetupFactionWidget(template, slot, client, factions);

if (isHost)
{
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupPlayerActionWidget(template, slot, client, orderManager, lobby,
() => panel = PanelType.Kick, () => panel = PanelType.Players);
}
else
{
LobbyUtils.SetupNameWidget(template, slot, client);
LobbyUtils.SetupTeamWidget(template, slot, client);
LobbyUtils.SetupSpawnWidget(template, slot, client);
}
Expand Down Expand Up @@ -650,9 +651,11 @@ void UpdatePlayerList()
if (template == null || template.Id != nonEditableSpectatorTemplate.Id)
template = nonEditableSpectatorTemplate.Clone();

LobbyUtils.SetupNameWidget(template, null, client);
LobbyUtils.SetupKickWidget(template, null, client, orderManager, lobby,
() => panel = PanelType.Kick, () => panel = PanelType.Players);
if (isHost)
LobbyUtils.SetupPlayerActionWidget(template, null, client, orderManager, lobby,
() => panel = PanelType.Kick, () => panel = PanelType.Players);
else
LobbyUtils.SetupNameWidget(template, null, client);

if (client.IsAdmin)
LobbyUtils.SetupReadyWidget(template, null, client);
Expand Down Expand Up @@ -708,13 +711,6 @@ void OnGameStart()
Ui.CloseWindow();
onStart();
}

class DropDownOption
{
public string Title;
public Func<bool> IsSelected;
public Action OnClick;
}
}

public class LobbyFaction
Expand All @@ -724,4 +720,11 @@ public class LobbyFaction
public string Description;
public string Side;
}

class DropDownOption
{
public string Title;
public Func<bool> IsSelected = () => false;
public Action OnClick;
}
}
91 changes: 76 additions & 15 deletions OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,60 @@ public static void ShowSlotDropDown(DropDownButtonWidget dropdown, Session.Slot
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 167, options, setupItem);
}

public static void ShowPlayerActionDropDown(DropDownButtonWidget dropdown, Session.Slot slot,
Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
{
Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); };
var onClick = new Action(() =>
{
before();
Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
{
{ "clientName", c.Name },
{ "okPressed", okPressed },
{ "cancelPressed", after }
});
});

var options = new List<DropDownOption>
{
new DropDownOption
{
Title = "Kick",
OnClick = onClick
},
};

if (orderManager.LobbyInfo.GlobalSettings.Dedicated)
{
options.Add(new DropDownOption
{
Title = "Transfer Admin",
OnClick = () => orderManager.IssueOrder(Order.Command("make_admin {0}".F(c.Index)))
});
}

if (!c.IsObserver && orderManager.LobbyInfo.GlobalSettings.AllowSpectators)
{
options.Add(new DropDownOption
{
Title = "Move to Spectator",
OnClick = () => orderManager.IssueOrder(Order.Command("make_spectator {0}".F(c.Index)))
});
}

Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
{
var item = ScrollItemWidget.Setup(itemTemplate, o.IsSelected, o.OnClick);
var labelWidget = item.Get<LabelWidget>("LABEL");
labelWidget.GetText = () => o.Title;
return item;
};

dropdown.ShowDropDown("PLAYERACTION_DROPDOWN_TEMPLATE", 167, options, setupItem);
}

public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client,
OrderManager orderManager, int teamCount)
{
Expand Down Expand Up @@ -316,6 +370,7 @@ public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Sessio
public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c)
{
var name = parent.Get<LabelWidget>("NAME");
name.IsVisible = () => true;
var font = Game.Renderer.Fonts[name.Font];
var label = WidgetUtils.TruncateText(c.Name, name.Bounds.Width, font);
name.GetText = () => label;
Expand Down Expand Up @@ -343,23 +398,16 @@ public static void SetupSlotWidget(Widget parent, Session.Slot s, Session.Client
HideChildWidget(parent, "SLOT_OPTIONS");
}

public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
public static void SetupPlayerActionWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
{
var button = parent.Get<ButtonWidget>("KICK");
button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
button.IsDisabled = () => orderManager.LocalClient.IsReady;
Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); };
button.OnClick = () =>
{
before();
var slot = parent.Get<DropDownButtonWidget>("PLAYER_ACTION");
slot.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
slot.IsDisabled = () => orderManager.LocalClient.IsReady;
slot.GetText = () => c != null ? c.Name : string.Empty;
slot.OnMouseDown = _ => ShowPlayerActionDropDown(slot, s, c, orderManager, lobby, before, after);

Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
{
{ "clientName", c.Name },
{ "okPressed", okPressed },
{ "cancelPressed", after }
});
};
// Ensure Name selector (if present) is hidden
HideChildWidget(parent, "NAME");
}

public static void SetupKickSpectatorsWidget(Widget parent, OrderManager orderManager, Widget lobby, Action before, Action after, bool skirmishMode)
Expand Down Expand Up @@ -578,4 +626,17 @@ static void HideChildWidget(Widget parent, string widgetId)
widget.IsVisible = () => false;
}
}

class ShowPlayerActionDropDownOption
{
public Action Click { get; set; }
public string Title;
public Func<bool> Selected = () => false;

public ShowPlayerActionDropDownOption(string title, Action click)
{
Click = click;
Title = title;
}
}
}
17 changes: 17 additions & 0 deletions mods/cnc/chrome/dialogs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
Width: PARENT_RIGHT - 20
Height: 25

ScrollPanel@PLAYERACTION_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH
Background: panel-black
Children:
ScrollItem@TEMPLATE:
Width: PARENT_RIGHT - 27
Height: 25
X: 2
Y: 0
Visible: false
Children:
Label@LABEL:
X: 10
Width: PARENT_RIGHT - 20
Height: 25
Align: Left

ScrollPanel@FACTION_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH
Background: panel-black
Expand Down
30 changes: 12 additions & 18 deletions mods/cnc/chrome/lobby-players.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,13 @@ Container@LOBBY_PLAYER_BIN:
Y: 0 - 1
Width: 180
Height: 25
Button@KICK:
X: 180
Width: 25
DropDownButton@PLAYER_ACTION:
X: 15
Width: 190
Height: 25
Children:
Image:
ImageCollection: lobby-bits
ImageName: kick
X: 7
Y: 7
Font: Regular
Visible: false
Align: Left
ColorBlock@COLORBLOCK:
X: 215
Y: 6
Expand Down Expand Up @@ -358,16 +355,13 @@ Container@LOBBY_PLAYER_BIN:
Y: 0 - 1
Width: 180
Height: 25
Button@KICK:
X: 180
Width: 25
DropDownButton@PLAYER_ACTION:
X: 15
Width: 190
Height: 25
Children:
Image:
ImageCollection: lobby-bits
ImageName: kick
X: 7
Y: 7
Font: Regular
Visible: false
Align: Left
Label@SPECTATOR:
X: 210
Width: 341
Expand Down
16 changes: 16 additions & 0 deletions mods/common/chrome/dropdowns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
Width: PARENT_RIGHT - 20
Height: 25

ScrollPanel@PLAYERACTION_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH
Children:
ScrollItem@TEMPLATE:
Width: PARENT_RIGHT - 27
Height: 25
X: 2
Y: 0
Visible: false
Children:
Label@LABEL:
X: 10
Width: PARENT_RIGHT - 20
Height: 25
Align: Left

ScrollPanel@TEAM_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH
Children:
Expand Down
28 changes: 14 additions & 14 deletions mods/common/chrome/lobby-players.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,13 @@ Container@LOBBY_PLAYER_BIN:
Width: 165
Height: 25
Text: Name
Button@KICK:
X: 155
Y: 2
Width: 25
Height: 23
Text: X
Font: Bold
DropDownButton@PLAYER_ACTION:
X: 15
Width: 165
Height: 25
Font: Regular
Visible: false
Align: Left
ColorBlock@COLORBLOCK:
X: 195
Y: 6
Expand Down Expand Up @@ -347,13 +347,13 @@ Container@LOBBY_PLAYER_BIN:
X: 20
Y: 0 - 1
Text: Name
Button@KICK:
X: 155
Y: 2
Width: 25
Height: 23
Text: X
Font: Bold
DropDownButton@PLAYER_ACTION:
X: 15
Width: 165
Height: 25
Font: Regular
Visible: false
Align: Left
Label@SPECTATOR:
X: 190
Width: 326
Expand Down

0 comments on commit 1c0aa24

Please sign in to comment.