diff --git a/ClientCore/CnCNet5/NameValidator.cs b/ClientCore/CnCNet5/NameValidator.cs index c0dfa731f..503600411 100644 --- a/ClientCore/CnCNet5/NameValidator.cs +++ b/ClientCore/CnCNet5/NameValidator.cs @@ -60,8 +60,41 @@ public static string GetValidOfflineName(string name) if (validName.Length > ClientConfiguration.Instance.MaxNameLength) return validName.Substring(0, ClientConfiguration.Instance.MaxNameLength); - + return validName; } + + /// + /// Checks if a lobby name is valid for CnCNet. + /// + /// Game lobby name. + /// Null if the lobby name is valid, otherwise a string that tells + /// what is wrong with the name. + public static string IsLobbyNameValid(string lobbyName) + { + + if (string.IsNullOrEmpty(lobbyName)) + { + return "Please enter a lobby name.".L10N("Client:Main:GameNameMissing"); + } + + char[] disallowedCharacters = { ',', ';' }; + if (lobbyName.IndexOfAny(disallowedCharacters) != -1) + { + return "Lobby name contains disallowed characters.".L10N("Client:Main:GameNameDisallowedChars"); + } + + if (lobbyName.Length > 23) + { + return "Lobby name is too long.".L10N("Client:Main:GameNameTooLong"); + } + + if (new ProfanityFilter().IsOffensive(lobbyName)) + { + return "Please enter a less offensive game name.".L10N("Client:Main:GameNameOffensiveText"); + } + + return null; + } } } diff --git a/DXMainClient/DXGUI/Multiplayer/CnCNet/GameCreationWindow.cs b/DXMainClient/DXGUI/Multiplayer/CnCNet/GameCreationWindow.cs index 1bcc189d3..7958254ee 100644 --- a/DXMainClient/DXGUI/Multiplayer/CnCNet/GameCreationWindow.cs +++ b/DXMainClient/DXGUI/Multiplayer/CnCNet/GameCreationWindow.cs @@ -8,6 +8,7 @@ using Rampastring.XNAUI.XNAControls; using System; using System.IO; +using ClientCore.CnCNet5; namespace DTAClient.DXGUI.Multiplayer.CnCNet { @@ -239,17 +240,14 @@ private void BtnLoadMPGame_LeftClick(object sender, EventArgs e) private void BtnCreateGame_LeftClick(object sender, EventArgs e) { - string gameName = tbGameName.Text.Replace(";", string.Empty); - if (string.IsNullOrEmpty(gameName)) - { - return; - } + var lobbyName = tbGameName.Text; + var lobbyNameValid = NameValidator.IsLobbyNameValid(lobbyName); - if (new ProfanityFilter().IsOffensive(gameName)) + if (!string.IsNullOrEmpty(lobbyNameValid)) { - XNAMessageBox.Show(WindowManager, "Offensive game name".L10N("Client:Main:GameNameOffensiveTitle"), - "Please enter a less offensive game name.".L10N("Client:Main:GameNameOffensiveText")); + XNAMessageBox.Show(WindowManager, "Invalid lobby name".L10N("Client:Main:GameNameInvalid"), + lobbyNameValid); return; } @@ -259,7 +257,7 @@ private void BtnCreateGame_LeftClick(object sender, EventArgs e) } GameCreated?.Invoke(this, - new GameCreationEventArgs(gameName,int.Parse(ddMaxPlayers.SelectedItem.Text), + new GameCreationEventArgs(lobbyName, int.Parse(ddMaxPlayers.SelectedItem.Text), tbPassword.Text,tunnelHandler.Tunnels[lbTunnelList.SelectedIndex], ddSkillLevel.SelectedIndex) ); diff --git a/DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs b/DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs index 892fde5b1..237e6c7c1 100644 --- a/DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs +++ b/DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs @@ -37,6 +37,7 @@ public class CnCNetGameLobby : MultiplayerGameLobby private const string MAP_SHARING_DOWNLOAD_REQUEST = "MAPOK"; private const string MAP_SHARING_UPLOAD_REQUEST = "MAPREQ"; private const string MAP_SHARING_DISABLED_MESSAGE = "MAPSDISABLED"; + private const string LOBBY_NAME_CHANGED = "LNC"; private const string CHEAT_DETECTED_MESSAGE = "CD"; private const string DICE_ROLL_MESSAGE = "DR"; private const string CHANGE_TUNNEL_SERVER_MESSAGE = "CHTNL"; @@ -87,6 +88,7 @@ PrivateMessagingWindow pmWindow new StringCommandHandler("MM", CheaterNotification), new StringCommandHandler(DICE_ROLL_MESSAGE, HandleDiceRollResult), new NoParamCommandHandler(CHEAT_DETECTED_MESSAGE, HandleCheatDetectedMessage), + new NoParamCommandHandler(LOBBY_NAME_CHANGED, HandleLobbyNameChangeMessage), new StringCommandHandler(CHANGE_TUNNEL_SERVER_MESSAGE, HandleTunnelServerChangeMessage) }; @@ -97,6 +99,8 @@ PrivateMessagingWindow pmWindow AddChatBoxCommand(new ChatBoxCommand("TUNNELINFO", "View tunnel server information".L10N("Client:Main:TunnelInfoCommand"), false, PrintTunnelServerInformation)); + AddChatBoxCommand(new ChatBoxCommand("LOBBYNAME", + "Change a game lobby's name".L10N("Client:Main:ChangeLobbyNameCommand"), true, s => ChangeLobbyName(s))); AddChatBoxCommand(new ChatBoxCommand("CHANGETUNNEL", "Change the used CnCNet tunnel server (game host only)".L10N("Client:Main:ChangeTunnelCommand"), true, (s) => ShowTunnelSelectionWindow("Select tunnel server:".L10N("Client:Main:SelectTunnelServerCommand")))); @@ -1561,6 +1565,9 @@ protected override void BanPlayer(int playerIndex) private void HandleCheatDetectedMessage(string sender) => AddNotice(string.Format("{0} has modified game files during the client session. They are likely attempting to cheat!".L10N("Client:Main:PlayerModifyFileCheat"), sender), Color.Red); + private void HandleLobbyNameChangeMessage(string sender) => + AddNotice("The game host has changed the lobby name.".L10N("Client:Main:LobbyNameChanged")); + private void HandleTunnelServerChangeMessage(string sender, string tunnelAddressAndPort) { if (sender != hostName) @@ -1882,6 +1889,30 @@ private void DownloadMapByIdCommand(string parameters) #region Game broadcasting logic + /// + /// Handles changing the lobby UIName + /// + /// The new name for the lobby. + private void ChangeLobbyName(string lobbyName) + { + var lobbyNameValid = NameValidator.IsLobbyNameValid(lobbyName); + + if (!string.IsNullOrEmpty(lobbyNameValid)) + { + XNAMessageBox.Show(WindowManager, "Invalid lobby name".L10N("Client:Main:GameNameInvalid"), + lobbyNameValid); + return; + } + + //update the name and broadcast to everyone + channel.UIName = lobbyName; + AccelerateGameBroadcasting(); + + //inform the players in the room + channel.SendCTCPMessage(LOBBY_NAME_CHANGED, QueuedMessageType.SYSTEM_MESSAGE, priority: 9); + AddNotice(String.Format("Lobby name changed to {0}.".L10N("Client:Main:LobbyNameChanged"),lobbyName)); + } + /// /// Lowers the time until the next game broadcasting message. /// diff --git a/DXMainClient/Online/Channel.cs b/DXMainClient/Online/Channel.cs index 88b304f4f..1c08c02ab 100644 --- a/DXMainClient/Online/Channel.cs +++ b/DXMainClient/Online/Channel.cs @@ -63,7 +63,7 @@ public Channel(string uiName, string channelName, bool persistent, bool isChatCh #region Public members - public string UIName { get; } + public string UIName { get; set; } public string ChannelName { get; }