Added username validation
Auto hide enter/leave room Username starts as UNNAMED now Show roomnumber for connected room
This commit is contained in:
@ -21,7 +21,6 @@ public class PongHub : Hub<IPongClient> {
|
||||
public override Task OnConnectedAsync() {
|
||||
Player = Lobby.CreatePlayer();
|
||||
Player.Client = Clients.Client(Context.ConnectionId);
|
||||
Player.Username = "Anon";
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@ -42,10 +41,10 @@ public class PongHub : Hub<IPongClient> {
|
||||
return Task.FromResult(room.ID);
|
||||
}
|
||||
|
||||
public Task<string> JoinRoom(string roomId) {
|
||||
public async Task<string> JoinRoom(string roomId) {
|
||||
AssertNotInRoom();
|
||||
var room = Lobby.JoinRoom(Player, roomId);
|
||||
return Task.FromResult(room.ID);
|
||||
var room = await Lobby.JoinRoom(Player, roomId);
|
||||
return room.ID;
|
||||
}
|
||||
|
||||
public Task MovePaddle(int dir) {
|
||||
@ -53,21 +52,14 @@ public class PongHub : Hub<IPongClient> {
|
||||
var direction = (PongPaddleDirection)dir;
|
||||
if (!Enum.IsDefined(direction))
|
||||
throw new HubException($"Invalid direction: {dir}!");
|
||||
room.MovePaddle(Player, direction);
|
||||
return Task.CompletedTask;
|
||||
return room.MovePaddle(Player, direction);
|
||||
}
|
||||
|
||||
public Task LeaveRoom() {
|
||||
Lobby.LeaveRoom(Player);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
public Task LeaveRoom()
|
||||
=> Lobby.LeaveRoom(Player);
|
||||
|
||||
public Task RequestUsernameChange(string username) {
|
||||
// TOOD: check this
|
||||
Logger.LogInformation("Player {Player} requested username change to [{username}]", Player, username);
|
||||
Player.Username = username;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
public Task RequestUsernameChange(string username)
|
||||
=> Lobby.ChangeUsername(Player, username);
|
||||
|
||||
public override Task OnDisconnectedAsync(Exception? exception) {
|
||||
Lobby.RemovePlayer(Player);
|
||||
|
@ -1,4 +1,6 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace PongGame.Hubs;
|
||||
|
||||
@ -35,19 +37,24 @@ public class PongLobby {
|
||||
return room;
|
||||
}
|
||||
|
||||
public PongRoom JoinRoom(PongPlayer player, string roomId) {
|
||||
public Task<PongRoom> JoinRoom(PongPlayer player, string roomId) {
|
||||
PongRoom? room;
|
||||
lock (PongRooms) {
|
||||
room = PongRooms.GetValueOrDefault(roomId);
|
||||
}
|
||||
if (room is null) throw new HubException($"Room [{roomId}] not found!");
|
||||
room.Join(player);
|
||||
return room;
|
||||
return Task.FromResult(room);
|
||||
}
|
||||
|
||||
public void LeaveRoom(PongPlayer player) {
|
||||
if (player.ConnectedRoom is PongRoom room)
|
||||
public Task LeaveRoom(PongPlayer player) {
|
||||
if (player.ConnectedRoom is PongRoom room) {
|
||||
room.Leave(player);
|
||||
if (room.IsEmpty)
|
||||
lock (PongRooms)
|
||||
_ = PongRooms.Remove(room.ID);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private readonly Random random = new();
|
||||
@ -61,4 +68,28 @@ public class PongLobby {
|
||||
} while (PongRooms.ContainsKey(id));
|
||||
return id;
|
||||
}
|
||||
|
||||
public async Task ChangeUsername(PongPlayer player, string username) {
|
||||
username = ValidateUsername(username);
|
||||
if (player.Username == username) {
|
||||
await player.Client.UsernameChanged(username);
|
||||
return;
|
||||
}
|
||||
lock (connectedPlayers) {
|
||||
// TODO: separate hashset for usernames
|
||||
if (connectedPlayers.Select(i => i.Username).Contains(username))
|
||||
throw new HubException($"Username {username} is already taken!");
|
||||
}
|
||||
Logger.LogInformation("Player {Player} requested username change to [{username}]", player, username);
|
||||
player.Username = username;
|
||||
}
|
||||
|
||||
private static readonly Regex UsernameRegex = new(@"^(?!.*[._ -]{2})[\w._ -]{3,20}$", RegexOptions.Compiled, TimeSpan.FromMilliseconds(200));
|
||||
|
||||
private static string ValidateUsername(string username) {
|
||||
username = username.Trim();
|
||||
if (!UsernameRegex.IsMatch(username))
|
||||
throw new HubException($"At most 20 characters, no two consecutive symbols");
|
||||
return username;
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ namespace PongGame.Hubs;
|
||||
|
||||
[DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")]
|
||||
public class PongPlayer {
|
||||
private string username = default!;
|
||||
private string username = "UNNAMED";
|
||||
|
||||
public PongRoom? ConnectedRoom { get; internal set; }
|
||||
public string Username {
|
||||
|
@ -18,6 +18,8 @@ public class PongRoom {
|
||||
|
||||
public PongPlayer? Player1 { get; private set; }
|
||||
public PongPlayer? Player2 { get; private set; }
|
||||
public bool IsEmpty => Player1 is null && Player2 is null;
|
||||
|
||||
private PongGameState State = PongGameState.Initial;
|
||||
|
||||
public void Join(PongPlayer player) {
|
||||
@ -67,7 +69,7 @@ public class PongRoom {
|
||||
if (Player1 is PongPlayer player1 && Player2 is PongPlayer player2) {
|
||||
Logger.LogInformation("[{ID}] Pong game started: {player1} vs. {player2}", ID, player1, player2);
|
||||
ResumeGame();
|
||||
} else if (Player1 is null && Player2 is null) {
|
||||
} else if (IsEmpty) {
|
||||
CloseRoom();
|
||||
} else
|
||||
PauseGame();
|
||||
@ -84,16 +86,15 @@ public class PongRoom {
|
||||
|
||||
public override string ToString() => $"[{ID}]";
|
||||
|
||||
public void MovePaddle(PongPlayer player, PongPaddleDirection direction) {
|
||||
public Task MovePaddle(PongPlayer player, PongPaddleDirection direction) {
|
||||
if (Player1 == player) {
|
||||
State.Paddle1.Direction = direction;
|
||||
Logger.LogDebug(DIRECTION_LOG_TEMPLATE, ID, 1, player, direction);
|
||||
return;
|
||||
} else if (Player2 == player) {
|
||||
State.Paddle2.Direction = direction;
|
||||
Logger.LogDebug(DIRECTION_LOG_TEMPLATE, ID, 2, player, direction);
|
||||
return;
|
||||
}
|
||||
throw new InvalidOperationException("Player is not in this room, but moved! Assumably players room wasn't deleted.");
|
||||
} else
|
||||
throw new InvalidOperationException("Player is not in this room, but moved! Assumably players room wasn't deleted.");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user