193 lines
7.7 KiB
C#
193 lines
7.7 KiB
C#
using System.Text.Json;
|
|
|
|
namespace qtc_api.Hubs
|
|
{
|
|
[Authorize]
|
|
public class ChatHub : Hub
|
|
{
|
|
private IUserService _userService;
|
|
private ILogger<ChatHub> _logger;
|
|
private static List<UserConnectionDto> ConnectedUsers = new();
|
|
private static List<User> OnlineUsers = new();
|
|
|
|
private static Dictionary<string, List<User>> GroupUsers = new();
|
|
|
|
public ChatHub(IUserService userService, ILogger<ChatHub> logger)
|
|
{
|
|
_userService = userService;
|
|
_logger = logger;
|
|
}
|
|
|
|
public override async Task OnDisconnectedAsync(Exception? ex)
|
|
{
|
|
Log("Client Disconnected From Hub");
|
|
|
|
var connection = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
|
|
|
|
if (connection != null)
|
|
{
|
|
var user = OnlineUsers.FirstOrDefault(x => x.Id == connection.ConnectedUser!.Id);
|
|
|
|
if (user != null)
|
|
{
|
|
ConnectedUsers.Remove(connection);
|
|
OnlineUsers.Remove(user);
|
|
await LogoutAsync(user);
|
|
}
|
|
}
|
|
|
|
await base.OnDisconnectedAsync(ex);
|
|
}
|
|
|
|
public async override Task OnConnectedAsync()
|
|
{
|
|
Log("Client Connected To Hub");
|
|
|
|
var uid = Context.UserIdentifier;
|
|
if (uid != null)
|
|
{
|
|
var user = await _userService.GetUserById(uid);
|
|
if (user != null && user.Success && user.Data != null)
|
|
{
|
|
// log them in
|
|
ConnectedUsers.Add(new UserConnectionDto() { ConnectedUser = user.Data, ConnectionId = Context.ConnectionId });
|
|
OnlineUsers.Add(user.Data);
|
|
await LoginAsync(user.Data);
|
|
}
|
|
}
|
|
|
|
await base.OnConnectedAsync();
|
|
}
|
|
|
|
[HubMethodName("UpdateStatus")]
|
|
public async Task UpdateStatusAsync(User user, int status)
|
|
{
|
|
var statusDto = new UserStatusDto { Id = user.Id, Status = status };
|
|
|
|
Log($"Updating Status\n{JsonSerializer.Serialize(statusDto)}");
|
|
|
|
await _userService.UpdateStatus(statusDto);
|
|
|
|
await Clients.All.SendAsync("RefreshUserLists");
|
|
}
|
|
|
|
[HubMethodName("JoinLobby")]
|
|
public async Task JoinLobbyAsync(User user)
|
|
{
|
|
await Groups.AddToGroupAsync(Context.ConnectionId, "LOBBY");
|
|
|
|
await Clients.Group("LOBBY").SendAsync("RoomMessage", $"[SERVER] User {user.Username} Has Joined The Lobby");
|
|
|
|
if (!GroupUsers.TryGetValue("LOBBY", out _)) { GroupUsers.Add("LOBBY", new List<User>()); }
|
|
GroupUsers["LOBBY"].Add(user);
|
|
|
|
await Clients.Groups("LOBBY").SendAsync("RoomUserList", GroupUsers["LOBBY"]);
|
|
Log($"User {user.Username} Has Joined The Lobby");
|
|
}
|
|
|
|
[HubMethodName("LeaveLobby")]
|
|
public async Task LeaveLobbyAsync(User user)
|
|
{
|
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "LOBBY");
|
|
|
|
await Clients.Group("LOBBY").SendAsync("RoomMessage", $"[SERVER] User {user.Username} Has Left The Lobby");
|
|
|
|
if (GroupUsers.TryGetValue("LOBBY", out _)) GroupUsers["LOBBY"].Remove(GroupUsers["LOBBY"].FirstOrDefault(e => e.Id == user.Id)!);
|
|
|
|
await Clients.Client("LOBBY").SendAsync("RoomUserList", GroupUsers["LOBBY"]);
|
|
Log($"User {user.Username} Has Left The Lobby");
|
|
}
|
|
|
|
[HubMethodName("JoinRoom")]
|
|
public async Task JoinRoomAsync(User user, Room room)
|
|
{
|
|
await Groups.AddToGroupAsync(Context.ConnectionId, room.Id);
|
|
|
|
await Clients.Group(room.Id).SendAsync("RoomMessage", $"[SERVER] User {user.Username} Has Joined {room.Name}");
|
|
|
|
if (!GroupUsers.TryGetValue(room.Id, out _)) { GroupUsers.Add(room.Id, new List<User>()); }
|
|
GroupUsers[room.Id].Add(user);
|
|
|
|
await Clients.Group(room.Id).SendAsync("RoomUserList", GroupUsers[room.Id]);
|
|
Log($"User {user.Username} Has Joined {room.Name}");
|
|
}
|
|
|
|
[HubMethodName("LeaveRoom")]
|
|
public async Task LeaveRoomAsync(User user, Room room)
|
|
{
|
|
await Groups.RemoveFromGroupAsync(Context.ConnectionId, room.Id);
|
|
|
|
await Clients.Group(room.Id).SendAsync("RoomMessage", $"[SERVER] User {user.Username} Has Left {room.Name}");
|
|
|
|
if (GroupUsers.TryGetValue(room.Id, out _)) GroupUsers[room.Id].Remove(GroupUsers[room.Id].FirstOrDefault(e => e.Id == user.Id)!);
|
|
|
|
await Clients.Group(room.Id).SendAsync("RoomUserList", GroupUsers[room.Id]);
|
|
Log($"User {user.Username} Has Left {room.Name}");
|
|
}
|
|
|
|
[HubMethodName("HandleDeletedRoom")]
|
|
public async Task HandleDeletedRoomAsync(Room room)
|
|
{
|
|
await Clients.Group(room.Id).SendAsync("RoomMessage", $"[SERVER] This Room Has Been Deleted By An Administrator.");
|
|
await Clients.Group(room.Id).SendAsync("cf", "rtl");
|
|
|
|
await Clients.All.SendAsync("RefreshRoomList");
|
|
}
|
|
|
|
[HubMethodName("RefreshContactsListOnUser")]
|
|
public async Task RefreshContactsListForUser(UserInformationDto user, User execUser)
|
|
{
|
|
var connection = ConnectedUsers.FirstOrDefault(e => e.ConnectedUser.Id == user.Id);
|
|
var connection2 = ConnectedUsers.FirstOrDefault(e => e.ConnectedUser.Id == execUser.Id);
|
|
if (connection != null && connection2 != null)
|
|
{
|
|
await Clients.Client(connection.ConnectionId).SendAsync("RefreshContactsList");
|
|
await Clients.Client(connection2.ConnectionId).SendAsync("RefreshContactsList");
|
|
return;
|
|
}
|
|
}
|
|
|
|
[HubMethodName("SendMessage")]
|
|
public async Task SendMessageAsync(User user, Message message, bool IsLobbyMsg, Room room = null!)
|
|
{
|
|
if(IsLobbyMsg == true) { await Clients.Group("LOBBY").SendAsync("RoomMessage", $"[{user.Username}] {message.Content}"); return; }
|
|
await Clients.Group(room.Id).SendAsync("RoomMessage", $"[{user.Username}] {message.Content}");
|
|
}
|
|
|
|
[HubMethodName("SendDirectMessage")]
|
|
public async Task SendDirectMessageAsync(User user, UserInformationDto userToMsg, Message message)
|
|
{
|
|
// send direct message directly to connected user
|
|
var connection = ConnectedUsers.FirstOrDefault(e => e.ConnectedUser.Id == userToMsg.Id);
|
|
if (connection != null)
|
|
{
|
|
UserInformationDto userInformationDto = new UserInformationDto { Id = user.Id, Username = user.Username, Bio = user.Bio, Role = user.Role, Status = user.Status, CreatedAt = user.CreatedAt, DateOfBirth = user.DateOfBirth, ProfilePicture = user.ProfilePicture };
|
|
await Clients.Client(connection.ConnectionId).SendAsync("ReceiveDirectMessage", message, userInformationDto);
|
|
return;
|
|
}
|
|
}
|
|
|
|
private async Task LoginAsync(User user)
|
|
{
|
|
await UpdateStatusAsync(user, 1);
|
|
|
|
ServerConfig serverConfig = JsonDocument.Parse(File.ReadAllText("./ServerConfig.json")).Deserialize<ServerConfig>();
|
|
|
|
await Clients.Client(Context.ConnectionId).SendAsync("ReceiveServerConfig", serverConfig);
|
|
await Clients.All.SendAsync("RefreshUserLists");
|
|
|
|
Log($"User {user.Username} Has Logged In");
|
|
}
|
|
|
|
private async Task LogoutAsync(User user)
|
|
{
|
|
await UpdateStatusAsync(user, 0);
|
|
await Clients.All.SendAsync("RefreshUserLists");
|
|
|
|
Log($"User {user.Username} Has Logged Out");
|
|
}
|
|
|
|
private void Log(string message) => _logger.LogInformation(message);
|
|
}
|
|
}
|