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; }