/** * Triggered when a client change his name. * @param header Infos about the header. * @param connection Infos about the server's connection. * @param message A PlayerRename class. */ public void PlayerRename(PacketHeader header, Connection connection, string message) { App.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, new Action(delegate() { PlayerRename player = JsonConvert.DeserializeObject <PlayerRename>(message); List <ClientUser> users = GameInfos.Instance.UsersList; for (int i = 0; i < users.Count; i++) { if (player.Id == users[i].Id) { users[i].Username = player.NewName; break; } } if (GameWindow.Instance != null) { if (GameWindow.Instance.GameLogger.Text != "") { GameWindow.Instance.GameLogger.Text += "\n\n"; } GameWindow.Instance.GameLogger.Text += "[" + DateTime.Now.ToLongTimeString().ToString() + "] " + player.OldName + " has renamed into " + player.NewName; GameWindow.Instance.GameLoggerScroller.ScrollToBottom(); GameWindow.Instance.DrawCanvas(); } })); }
/// <summary> /// Handles renaming each player based on the recommendation from the server /// </summary> /// /// <param name="renames">Object containing list of player rename actions to be taken</param> private void HandlePlayerRename(PlayerRename renames) { foreach (PlayerRenameItem rename in renames.PlayerRenames) { Player foundPlayer = localPlayers.FirstOrDefault(p => p.PlayerId == rename.PlayerId); if (foundPlayer == null) { AddRemoteStatusMessage($"No player with ID = {rename.PlayerId}, Name = {rename.OriginalName} found in local list"); continue; } AddRemoteStatusMessage($"Renaming {rename.OriginalName} to {rename.NewName} due to duplicate on remote server"); foundPlayer.Name = rename.NewName; PlayerNameChanged?.Invoke(rename.PlayerId, rename.NewName); } }
/// <summary> /// Handles the player list response data /// </summary> /// /// <param name="message">The player list response message</param> /// <param name="connection">The connection the message came from</param> private void HandlePlayerListResponse(PlayerList message, Connection connection) { List <Player> newPlayers = message?.Players; if (newPlayers == null) { RemoteStatusBox.Items.Add($"ERROR: Received invalid player list from {GetEndPointId(connection.Socket.RemoteEndPoint as IPEndPoint)}, disconnecting"); connection.Close(); return; } // Negotiate player limits int playerCount = remotePlayers.Count + Players.Count; if (playerCount + newPlayers.Count > Game.MAX_PLAYERS) { string tooManyMessage = $"The {newPlayers.Count} added to the {playerCount} existing exceeds the maximum of {Game.MAX_PLAYERS}"; RemoteStatusBox.Items.Add($"Received too many players from {GetEndPointId(connection.Socket.RemoteEndPoint as IPEndPoint)}, disconnecting. {tooManyMessage}"); // Send rejection message SendMessage(connection, MessageType.Disconnect, new Disconnect { Message = tooManyMessage }); connection.Close(); return; } // Negotiate player names List <string> playerNames = remotePlayers.Values.SelectMany(p => p.Select(rp => rp.Name)).Concat(Players.Select(p => p.Name)).ToList(); List <Player> duplicateNames = newPlayers.Where(p => playerNames.Any(rpn => rpn.Equals(p.Name, StringComparison.OrdinalIgnoreCase))).ToList(); if (duplicateNames.Any()) { PlayerRename renames = new PlayerRename(); // Generate list of names that need to be replaced foreach (Player player in duplicateNames) { string newName = Utilities.GetUniqueName(player.Name, playerNames); playerNames.Add(newName); renames.PlayerRenames.Add(new PlayerRenameItem { PlayerId = player.PlayerId, OriginalName = player.Name, NewName = newName }); } SendMessage(connection, MessageType.PlayerRename, renames); return; } // Save the players list remotePlayers[GetEndPointId(connection.Socket.RemoteEndPoint as IPEndPoint)] = newPlayers; // Broadcast full players list to every connected client foreach (Connection clientConnection in hostServer.Connections) { SendMessage(clientConnection, MessageType.PlayerListResponse, new PlayerList { Players = GetAdjustedPlayersList(clientConnection) }); } }