using System.Security.AccessControl; using Microsoft.AspNetCore.SignalR; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections.Concurrent; using Sledgemapper.Shared.Entities; using Sledgemapper.Clients; using MediatR; using System; using Sledgemapper.Api.Data; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.AspNetCore.Authorization; using Sledgemapper.Api.Models; using Sledgemapper.Helpers; namespace SignalRChat.Hubs { [Authorize] public class SledgemapperHub : Hub { private readonly MyDbContext _dbContext; private readonly DataContext _datacontext; public SledgemapperHub(MyDbContext dbContext, DataContext datacontext) { _dbContext = dbContext; _datacontext = datacontext; } // other colors // #cca300, #20f200, #004011, #00e6d6, #005c73, #0057d9, #d900ca, #660029, #d9003a // private static Dictionary _sessions = new Dictionary(); public List Colors = new List{ "#CC0000", "#20f200", "#FFCC00", "#006666", "#660029", "#0000CC", "#663399", "#CC0099"}; public async Task NewTile(string sessionName, Tile tile) { // var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // var existingTile = _sessions[sessionName].Map.TryGetValue(tile.ToString(), out var t); // if (existingTile) // { // _sessions[sessionName].Map.TryRemove(t.ToString(), out var rtile); // } // _sessions[sessionName].Map.TryAdd(tile.ToString(), tile); // var jsonString = JsonSerializer.Serialize(tile); // _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog // { // Operation = "N", // SessionName = sessionName, // Type = "T", // Timestamp = timestamp, // Object = jsonString // }); // await _dbcontext.SaveChangesAsync(); await Clients.Group(sessionName).NewTile(tile); } public async Task NewWall(string sessionName, Wall tile) { // var existingTile = _sessions[sessionName].Walls.TryGetValue(tile.ToString(), out var t); // if (existingTile) // { // _sessions[sessionName].Walls.TryRemove(t.ToString(), out var rtile); // } // _sessions[sessionName].Walls.TryAdd(tile.ToString(), tile); await Clients.Group(sessionName).NewWall(tile); } public async Task NewOverlay(string sessionName, Overlay tile) { // var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // var existingTile = _sessions[sessionName].Overlays.TryGetValue(tile.ToString(), out var t); // if (existingTile) // { // _sessions[sessionName].Overlays.TryRemove(t.ToString(), out var rtile); // } // _sessions[sessionName].Overlays.TryAdd(tile.ToString(), tile); // var jsonString = JsonSerializer.Serialize(tile); // _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog // { // Operation = "N", // SessionName = sessionName, // Type = "O", // Timestamp = timestamp, // Object = jsonString // }); // await _dbcontext.SaveChangesAsync(); await Clients.Group(sessionName).NewOverlay(tile); } public async Task DeleteTile(string sessionName, Tile tile) { // _sessions[sessionName].Map.TryRemove(tile.ToString(), out var rtile); await Clients.Group(sessionName).DeleteTile(tile); } public async Task DeleteWall(string sessionName, Wall tile) { //_sessions[sessionName].Walls.TryRemove(tile.ToString(), out var rtile); await Clients.Group(sessionName).DeleteWall(tile); } public async Task DeleteOverlay(string sessionName, Overlay tile) { //_sessions[sessionName].Overlays.TryRemove(tile.ToString(), out var rtile); await Clients.Group(sessionName).DeleteOverlay(tile); } // public async Task NewSession(string sessionName, string initials) // { // var userId = int.Parse(Context.User.Identity.Name); // // var user = this.Context.GetHttpContext().; // var session = new Session(); // session.Colors = new List(Colors); // session.Colors.Shuffle(); // var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[0], Initials = initials }; // session.Players.Add(player); // _sessions.Add(sessionName, session); // await Groups.AddToGroupAsync(Context.ConnectionId, sessionName); // return session; // } public async Task JoinSession(string sessionName) { var session = _dbContext.Sessions.FirstOrDefault(s => s.SessionName == sessionName); var userId = int.Parse(Context.User.Identity.Name); if (session != null) { // var newSession = new Session(); var userSession = new SessionUser { SessionId = session.SessionId, UserId = userId }; _dbContext.SessionUsers.Add(userSession); await _dbContext.SaveChangesAsync(); var usersSession = _dbContext.SessionUsers.Where(m => m.SessionId == session.SessionId).Select(m => m.UserId).ToList(); // var players = _datacontext. // Users. // Where(m => usersSession.Contains(m.Id)).ToList(). // //Select((r, index) => new { Place = index, Name = r }) // Select((p, index) => new Player // { // Initials = p.Initials, // UserId = userId, // Color = Colors[index], // Position = new Tile { X = 0, Y = 0 } // }).ToList(); await _dbContext.SaveChangesAsync(); await Groups.AddToGroupAsync(Context.ConnectionId, sessionName); var user = _datacontext.Users.First(u => u.Id == userId); var SessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == session.SessionId).OrderBy(m => m.UserId).ToList(); var player = new Player { UserId = userId, Initials = user.Initials, Position = new Tile { X = 0, Y = 0 }, Color = Colors[SessionUsers.IndexOf(SessionUsers.FirstOrDefault(m => m.UserId == userId))] }; await Clients.Group(sessionName).NewPlayer(player); var newSession = new Sledgemapper.Shared.Entities.Session { SessionName = sessionName }; return newSession; } else { return null; } // if (_sessions.ContainsKey(sessionName)) // { // var session = _sessions[sessionName]; // var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[session.Players.Count], Initials = initials }; // session.Players.Add(player); // await Clients.Group(sessionName).NewPlayer(player); // return session; // } // else // { // return null; // } } public async Task UpdatePosition(string sessionName, Tile tile) { var userId = int.Parse(Context.User.Identity.Name); var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionName == sessionName); var SessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == session.SessionId).OrderBy(m => m.UserId).ToList(); var user = _datacontext.Users.First(u => u.Id == userId); var player = new Player { UserId = userId, Initials = user.Initials, Position = tile, Color = Colors[SessionUsers.IndexOf(SessionUsers.FirstOrDefault(m => m.UserId == userId))] }; await Clients.Group(sessionName).PlayerUpdate(player); } // public async Task Refresh(string sessionName) // { // return _sessions[sessionName]; // } // public async Task Sync(string sessionName, Session map) // { // _sessions[sessionName].Map = map.Map; // _sessions[sessionName].Overlays = map.Overlays; // _sessions[sessionName].Walls = map.Walls; // await Clients.Group(sessionName).UpdateMap(_sessions[sessionName]); // } public override async Task OnConnectedAsync() { var userId = int.Parse(Context.User.Identity.Name); //var result = _connectedPlayers.AddOrUpdate(Context.ConnectionId, userId,(key, oldValue) => userId); var userConnection = new UserConnection { ConnectionId = Context.ConnectionId, UserId = userId }; _dbContext.UserConnections.Add(userConnection); await _dbContext.SaveChangesAsync(); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception exception) { var userConnection = _dbContext.UserConnections.FirstOrDefault(m => m.ConnectionId == Context.ConnectionId); if (userConnection != null) { _dbContext.UserConnections.Remove(userConnection); } var userSessions = _dbContext.SessionUsers.Where(m => m.UserId == userConnection.UserId).ToList(); { foreach (var userSession in userSessions) { var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionId == userSession.SessionId); await Clients.Group(session.SessionName).PlayerUpdate(null); //send remove player _dbContext.SessionUsers.Remove(userSession); } } await _dbContext.SaveChangesAsync(); await base.OnDisconnectedAsync(exception); } } }