From a6e5a0b53f127359df46ec665da8991037b9c1fe Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Sat, 29 Jun 2013 10:58:37 +1200 Subject: [PATCH] Add temp banning to servers --- OpenRA.Game/GameRules/Settings.cs | 2 +- OpenRA.Game/Network/Session.cs | 1 - OpenRA.Game/Server/Server.cs | 27 +++++----- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs | 33 +++++++++--- .../Widgets/Logic/KickClientLogic.cs | 37 +++++++++++++ OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs | 9 ++-- OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs | 9 +++- mods/cnc/chrome/dialogs.yaml | 54 ++++++++++++++++++- mods/d2k/chrome/lobby.yaml | 52 ++++++++++++++++++ mods/ra/chrome/lobby.yaml | 52 ++++++++++++++++++ 11 files changed, 247 insertions(+), 30 deletions(-) create mode 100644 OpenRA.Mods.RA/Widgets/Logic/KickClientLogic.cs diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index 77908fe1cc..625abb8a8c 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -36,7 +36,7 @@ namespace OpenRA.GameRules public bool VerboseNatDiscovery = false; // print very detailed logs for debugging public bool AllowCheats = false; public string Map = null; - public string[] Ban = null; + public string[] Ban = { }; public int TimeOut = 0; public bool Dedicated = false; public bool DedicatedLoop = true; diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 7c6a836b9a..1ba16a8da4 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -84,7 +84,6 @@ namespace OpenRA.Network { public string ServerName; public string Map; - public string[] Ban; public string[] Mods = { "ra" }; // mod names public int OrderLatency = 3; // net tick frames (x 120 = ms) public int RandomSeed = 0; diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 3532b87ec0..afc038d900 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -66,6 +66,8 @@ namespace OpenRA.Server protected set { pState = value; } } + public List TempBans = new List(); + public void Shutdown() { State = ServerState.ShuttingDown; @@ -103,7 +105,6 @@ namespace OpenRA.Server lobbyInfo.GlobalSettings.RandomSeed = randomSeed; lobbyInfo.GlobalSettings.Map = settings.Map; lobbyInfo.GlobalSettings.ServerName = settings.Name; - lobbyInfo.GlobalSettings.Ban = settings.Ban; lobbyInfo.GlobalSettings.Dedicated = settings.Dedicated; foreach (var t in ServerTraits.WithInterface()) @@ -270,18 +271,13 @@ namespace OpenRA.Server client.IpAddress = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString(); // Check if IP is banned - if (lobbyInfo.GlobalSettings.Ban != null) + var bans = Settings.Ban.Union(TempBans); + if (bans.Contains(client.IpAddress)) { - - if (lobbyInfo.GlobalSettings.Ban.Contains(client.IpAddress)) - { - Console.WriteLine("Rejected connection from "+client.Name+"("+newConn.socket.RemoteEndPoint+"); Banned."); - Log.Write("server", "Rejected connection from {0}; Banned.", - newConn.socket.RemoteEndPoint); - SendOrderTo(newConn, "ServerError", "You are banned from the server!"); - DropClient(newConn); - return; - } + Log.Write("server", "Rejected connection from {0}; Banned.", newConn.socket.RemoteEndPoint); + SendOrderTo(newConn, "ServerError", "You are {0} from the server.".F(Settings.Ban.Contains(client.IpAddress) ? "banned" : "temporarily banned")); + DropClient(newConn); + return; } // Promote connection to a valid client @@ -502,7 +498,7 @@ namespace OpenRA.Server { conns.Remove(toDrop); - var dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).FirstOrDefault(); + var dropClient = lobbyInfo.Clients.FirstOrDefault(c1 => c1.Index == toDrop.PlayerIndex); if (dropClient == null) return; @@ -531,7 +527,10 @@ namespace OpenRA.Server DispatchOrders(toDrop, toDrop.MostRecentFrame, new byte[] {0xbf}); - if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated) + if (!conns.Any()) + TempBans.Clear(); + + if (conns.Any() || lobbyInfo.GlobalSettings.Dedicated) SyncLobbyInfo(); if (!lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin) diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index afcdaf3229..421f9d8589 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -380,6 +380,7 @@ + diff --git a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs index b69ad28a3d..8b3de02d03 100644 --- a/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.RA/ServerTraits/LobbyCommands.cs @@ -413,25 +413,44 @@ namespace OpenRA.Mods.RA.Server { "kick", s => { - if (!client.IsAdmin) { server.SendOrderTo(conn, "Message", "Only the host can kick players"); return true; } - int clientID; - int.TryParse(s, out clientID); + var split = s.Split(' '); + if (split.Length < 2) + { + server.SendOrderTo(conn, "Message", "Malformed kick command"); + return true; + } - var connToKick = server.conns.SingleOrDefault( c => server.GetClient(c) != null && server.GetClient(c).Index == clientID); - if (connToKick == null) + int kickClientID; + int.TryParse(split[0], out kickClientID); + + var kickConn = server.conns.SingleOrDefault(c => server.GetClient(c) != null && server.GetClient(c).Index == kickClientID); + if (kickConn == null) { server.SendOrderTo(conn, "Message", "Noone in that slot."); return true; } - server.SendOrderTo(connToKick, "ServerError", "You have been kicked from the server"); - server.DropClient(connToKick); + var kickConnIP = server.GetClient(kickConn).IpAddress; + + Log.Write("server", "Kicking client {0} as requested", kickClientID); + server.SendOrderTo(kickConn, "ServerError", "You have been kicked from the server"); + server.DropClient(kickConn); + + bool tempBan; + bool.TryParse(split[1], out tempBan); + + if (tempBan) + { + Log.Write("server", "Temporarily banning client {0} ({1}) as requested", kickClientID, kickConnIP); + server.TempBans.Add(kickConnIP); + } + server.SyncLobbyInfo(); return true; }}, diff --git a/OpenRA.Mods.RA/Widgets/Logic/KickClientLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/KickClientLogic.cs new file mode 100644 index 0000000000..6b44eac700 --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/KickClientLogic.cs @@ -0,0 +1,37 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using OpenRA.Widgets; + +namespace OpenRA.Mods.RA.Widgets.Logic +{ + class KickClientLogic + { + [ObjectCreator.UseCtor] + public KickClientLogic(Widget widget, string clientName, Action okPressed) + { + widget.Get("TITLE").GetText = () => "Kick {0}?".F(clientName); + + var tempBan = false; + var preventRejoiningCheckbox = widget.Get("PREVENT_REJOINING_CHECKBOX"); + preventRejoiningCheckbox.IsChecked = () => tempBan; + preventRejoiningCheckbox.OnClick = () => tempBan ^= true; + + widget.Get("OK_BUTTON").OnClick = () => + { + widget.Parent.RemoveChild(widget); + okPressed(tempBan); + }; + + widget.Get("CANCEL_BUTTON").OnClick = () => widget.Parent.RemoveChild(widget); + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index 199d0e6909..8fd06044af 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -20,8 +20,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic { public class LobbyLogic { + Widget lobby; Widget EditablePlayerTemplate, NonEditablePlayerTemplate, EmptySlotTemplate, - EditableSpectatorTemplate, NonEditableSpectatorTemplate, NewSpectatorTemplate; + EditableSpectatorTemplate, NonEditableSpectatorTemplate, NewSpectatorTemplate; ScrollPanelWidget chatPanel; Widget chatTemplate; @@ -85,7 +86,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic internal LobbyLogic(Widget widget, World world, OrderManager orderManager, Action onExit, Action onStart, bool addBots) { - var lobby = widget; + lobby = widget; this.orderManager = orderManager; this.OnGameStart = () => { CloseWindow(); onStart(); }; this.onExit = onExit; @@ -425,7 +426,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic LobbyUtils.SetupClientWidget(template, slot, client, orderManager, client.Bot == null); LobbyUtils.SetupNameWidget(template, slot, client); - LobbyUtils.SetupKickWidget(template, slot, client, orderManager); + LobbyUtils.SetupKickWidget(template, slot, client, orderManager, lobby); LobbyUtils.SetupColorWidget(template, slot, client); LobbyUtils.SetupFactionWidget(template, slot, client, CountryNames); LobbyUtils.SetupTeamWidget(template, slot, client); @@ -467,7 +468,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic template = NonEditableSpectatorTemplate.Clone(); LobbyUtils.SetupNameWidget(template, null, client); - LobbyUtils.SetupKickWidget(template, null, client, orderManager); + LobbyUtils.SetupKickWidget(template, null, client, orderManager, lobby); } LobbyUtils.SetupClientWidget(template, null, c, orderManager, true); diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs index 816715c9da..87a26b9e9f 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs @@ -262,12 +262,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic slot.IsVisible = () => false; } - public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager) + public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby) { var button = parent.Get("KICK"); button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index; button.IsDisabled = () => orderManager.LocalClient.IsReady; - button.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index)); + Action okPressed = tempBan => orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); + button.OnClick = () => Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby, new WidgetArgs + { + { "clientName", c.Name }, + { "okPressed", okPressed } + }); } public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, ColorPreviewManagerWidget colorPreview) diff --git a/mods/cnc/chrome/dialogs.yaml b/mods/cnc/chrome/dialogs.yaml index 44925da0ee..6396f33257 100644 --- a/mods/cnc/chrome/dialogs.yaml +++ b/mods/cnc/chrome/dialogs.yaml @@ -131,4 +131,56 @@ Container@CONFIRM_PROMPT: Y:89 Width:140 Height:35 - Text:Confirm \ No newline at end of file + Text:Confirm + +Background@KICK_CLIENT_DIALOG: + X:15 + Y:30 + Width:503 + Height:219 + Logic:KickClientLogic + Background:panel-black + Children: + Label@TITLE: + X:0 + Y:40 + Width:PARENT_RIGHT + Height:25 + Font:Bold + Align:Center + Label@TEXTA: + X:0 + Y:67 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:You may also apply a temporary ban, preventing + Label@TEXTB: + X:0 + Y:85 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:them from joining for the remainder of this game. + Checkbox@PREVENT_REJOINING_CHECKBOX: + X:(PARENT_RIGHT - WIDTH)/2 + Y:120 + Width:150 + Height:20 + Text:Temporarily Ban + Button@OK_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 + 75 + Y:155 + Width:120 + Height:25 + Text:Kick + Font:Bold + Button@CANCEL_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 - 75 + Y:155 + Width:120 + Height:25 + Text:Cancel + Font:Bold \ No newline at end of file diff --git a/mods/d2k/chrome/lobby.yaml b/mods/d2k/chrome/lobby.yaml index 96f93f4682..5e214f4df8 100644 --- a/mods/d2k/chrome/lobby.yaml +++ b/mods/d2k/chrome/lobby.yaml @@ -486,3 +486,55 @@ Background@SERVER_LOBBY: Text:Start Game Font:Bold TooltipContainer@TOOLTIP_CONTAINER: + +Background@KICK_CLIENT_DIALOG: + X:20 + Y:67 + Width:504 + Height:235 + Logic:KickClientLogic + Background:dialog3 + Children: + Label@TITLE: + X:0 + Y:40 + Width:PARENT_RIGHT + Height:25 + Font:Bold + Align:Center + Label@TEXTA: + X:0 + Y:67 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:You may also apply a temporary ban, preventing + Label@TEXTB: + X:0 + Y:85 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:them from joining for the remainder of this game. + Checkbox@PREVENT_REJOINING_CHECKBOX: + X:(PARENT_RIGHT - WIDTH)/2 + Y:120 + Width:150 + Height:20 + Text:Temporarily Ban + Button@OK_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 + 75 + Y:155 + Width:120 + Height:25 + Text:Kick + Font:Bold + Button@CANCEL_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 - 75 + Y:155 + Width:120 + Height:25 + Text:Cancel + Font:Bold \ No newline at end of file diff --git a/mods/ra/chrome/lobby.yaml b/mods/ra/chrome/lobby.yaml index 5a2c39ddfc..55688ddc0e 100644 --- a/mods/ra/chrome/lobby.yaml +++ b/mods/ra/chrome/lobby.yaml @@ -492,3 +492,55 @@ Background@SERVER_LOBBY: Text:Start Game Font:Bold TooltipContainer@TOOLTIP_CONTAINER: + +Background@KICK_CLIENT_DIALOG: + X:20 + Y:67 + Width:504 + Height:235 + Logic:KickClientLogic + Background:dialog3 + Children: + Label@TITLE: + X:0 + Y:40 + Width:PARENT_RIGHT + Height:25 + Font:Bold + Align:Center + Label@TEXTA: + X:0 + Y:67 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:You may also apply a temporary ban, preventing + Label@TEXTB: + X:0 + Y:85 + Width:PARENT_RIGHT + Height:25 + Font:Regular + Align:Center + Text:them from joining for the remainder of this game. + Checkbox@PREVENT_REJOINING_CHECKBOX: + X:(PARENT_RIGHT - WIDTH)/2 + Y:120 + Width:150 + Height:20 + Text:Temporarily Ban + Button@OK_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 + 75 + Y:155 + Width:120 + Height:25 + Text:Kick + Font:Bold + Button@CANCEL_BUTTON: + X:(PARENT_RIGHT - WIDTH)/2 - 75 + Y:155 + Width:120 + Height:25 + Text:Cancel + Font:Bold \ No newline at end of file