Added a player action dropdown.

Adds options for:
 - handling kick
 - transferring admin
 - move to spectator
This commit is contained in:
teinarss
2018-07-05 22:07:30 +00:00
committed by Paul Chote
parent 0c1b11ed4f
commit 1c0aa24640
7 changed files with 212 additions and 60 deletions

View File

@@ -37,6 +37,8 @@ namespace OpenRA.Mods.Common.Server
{ "option", Option }, { "option", Option },
{ "assignteams", AssignTeams }, { "assignteams", AssignTeams },
{ "kick", Kick }, { "kick", Kick },
{ "make_admin", MakeAdmin },
{ "make_spectator", MakeSpectator },
{ "name", Name }, { "name", Name },
{ "faction", Faction }, { "faction", Faction },
{ "team", Team }, { "team", Team },
@@ -601,6 +603,65 @@ namespace OpenRA.Mods.Common.Server
return true; 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) static bool Name(S server, Connection conn, Session.Client client, string s)
{ {
var sanitizedName = Settings.SanitizedPlayerName(s); var sanitizedName = Settings.SanitizedPlayerName(s);

View File

@@ -594,18 +594,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
template = nonEditablePlayerTemplate.Clone(); template = nonEditablePlayerTemplate.Clone();
LobbyUtils.SetupClientWidget(template, client, orderManager, client.Bot == null); 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.SetupColorWidget(template, slot, client);
LobbyUtils.SetupFactionWidget(template, slot, client, factions); LobbyUtils.SetupFactionWidget(template, slot, client, factions);
if (isHost) if (isHost)
{ {
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map); LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSpawnWidget(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 else
{ {
LobbyUtils.SetupNameWidget(template, slot, client);
LobbyUtils.SetupTeamWidget(template, slot, client); LobbyUtils.SetupTeamWidget(template, slot, client);
LobbyUtils.SetupSpawnWidget(template, slot, client); LobbyUtils.SetupSpawnWidget(template, slot, client);
} }
@@ -650,9 +651,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (template == null || template.Id != nonEditableSpectatorTemplate.Id) if (template == null || template.Id != nonEditableSpectatorTemplate.Id)
template = nonEditableSpectatorTemplate.Clone(); template = nonEditableSpectatorTemplate.Clone();
LobbyUtils.SetupNameWidget(template, null, client); if (isHost)
LobbyUtils.SetupKickWidget(template, null, client, orderManager, lobby, LobbyUtils.SetupPlayerActionWidget(template, null, client, orderManager, lobby,
() => panel = PanelType.Kick, () => panel = PanelType.Players); () => panel = PanelType.Kick, () => panel = PanelType.Players);
else
LobbyUtils.SetupNameWidget(template, null, client);
if (client.IsAdmin) if (client.IsAdmin)
LobbyUtils.SetupReadyWidget(template, null, client); LobbyUtils.SetupReadyWidget(template, null, client);
@@ -708,13 +711,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Ui.CloseWindow(); Ui.CloseWindow();
onStart(); onStart();
} }
class DropDownOption
{
public string Title;
public Func<bool> IsSelected;
public Action OnClick;
}
} }
public class LobbyFaction public class LobbyFaction
@@ -724,4 +720,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public string Description; public string Description;
public string Side; public string Side;
} }
class DropDownOption
{
public string Title;
public Func<bool> IsSelected = () => false;
public Action OnClick;
}
} }

View File

@@ -73,6 +73,60 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 167, options, setupItem); 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, public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client,
OrderManager orderManager, int teamCount) OrderManager orderManager, int teamCount)
{ {
@@ -316,6 +370,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c) public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c)
{ {
var name = parent.Get<LabelWidget>("NAME"); var name = parent.Get<LabelWidget>("NAME");
name.IsVisible = () => true;
var font = Game.Renderer.Fonts[name.Font]; var font = Game.Renderer.Fonts[name.Font];
var label = WidgetUtils.TruncateText(c.Name, name.Bounds.Width, font); var label = WidgetUtils.TruncateText(c.Name, name.Bounds.Width, font);
name.GetText = () => label; name.GetText = () => label;
@@ -343,23 +398,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
HideChildWidget(parent, "SLOT_OPTIONS"); 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"); var slot = parent.Get<DropDownButtonWidget>("PLAYER_ACTION");
button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index; slot.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
button.IsDisabled = () => orderManager.LocalClient.IsReady; slot.IsDisabled = () => orderManager.LocalClient.IsReady;
Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); }; slot.GetText = () => c != null ? c.Name : string.Empty;
button.OnClick = () => slot.OnMouseDown = _ => ShowPlayerActionDropDown(slot, s, c, orderManager, lobby, before, after);
{
before();
Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs // Ensure Name selector (if present) is hidden
{ HideChildWidget(parent, "NAME");
{ "clientName", c.Name },
{ "okPressed", okPressed },
{ "cancelPressed", after }
});
};
} }
public static void SetupKickSpectatorsWidget(Widget parent, OrderManager orderManager, Widget lobby, Action before, Action after, bool skirmishMode) public static void SetupKickSpectatorsWidget(Widget parent, OrderManager orderManager, Widget lobby, Action before, Action after, bool skirmishMode)
@@ -578,4 +626,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
widget.IsVisible = () => false; 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;
}
}
} }

View File

@@ -26,6 +26,23 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
Width: PARENT_RIGHT - 20 Width: PARENT_RIGHT - 20
Height: 25 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: ScrollPanel@FACTION_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH Width: DROPDOWN_WIDTH
Background: panel-black Background: panel-black

View File

@@ -185,16 +185,13 @@ Container@LOBBY_PLAYER_BIN:
Y: 0 - 1 Y: 0 - 1
Width: 180 Width: 180
Height: 25 Height: 25
Button@KICK: DropDownButton@PLAYER_ACTION:
X: 180 X: 15
Width: 25 Width: 190
Height: 25 Height: 25
Children: Font: Regular
Image: Visible: false
ImageCollection: lobby-bits Align: Left
ImageName: kick
X: 7
Y: 7
ColorBlock@COLORBLOCK: ColorBlock@COLORBLOCK:
X: 215 X: 215
Y: 6 Y: 6
@@ -358,16 +355,13 @@ Container@LOBBY_PLAYER_BIN:
Y: 0 - 1 Y: 0 - 1
Width: 180 Width: 180
Height: 25 Height: 25
Button@KICK: DropDownButton@PLAYER_ACTION:
X: 180 X: 15
Width: 25 Width: 190
Height: 25 Height: 25
Children: Font: Regular
Image: Visible: false
ImageCollection: lobby-bits Align: Left
ImageName: kick
X: 7
Y: 7
Label@SPECTATOR: Label@SPECTATOR:
X: 210 X: 210
Width: 341 Width: 341

View File

@@ -26,6 +26,22 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
Width: PARENT_RIGHT - 20 Width: PARENT_RIGHT - 20
Height: 25 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: ScrollPanel@TEAM_DROPDOWN_TEMPLATE:
Width: DROPDOWN_WIDTH Width: DROPDOWN_WIDTH
Children: Children:

View File

@@ -181,13 +181,13 @@ Container@LOBBY_PLAYER_BIN:
Width: 165 Width: 165
Height: 25 Height: 25
Text: Name Text: Name
Button@KICK: DropDownButton@PLAYER_ACTION:
X: 155 X: 15
Y: 2 Width: 165
Width: 25 Height: 25
Height: 23 Font: Regular
Text: X Visible: false
Font: Bold Align: Left
ColorBlock@COLORBLOCK: ColorBlock@COLORBLOCK:
X: 195 X: 195
Y: 6 Y: 6
@@ -347,13 +347,13 @@ Container@LOBBY_PLAYER_BIN:
X: 20 X: 20
Y: 0 - 1 Y: 0 - 1
Text: Name Text: Name
Button@KICK: DropDownButton@PLAYER_ACTION:
X: 155 X: 15
Y: 2 Width: 165
Width: 25 Height: 25
Height: 23 Font: Regular
Text: X Visible: false
Font: Bold Align: Left
Label@SPECTATOR: Label@SPECTATOR:
X: 190 X: 190
Width: 326 Width: 326