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; namespace SignalRChat.Hubs { public class SledgemapperHub : Hub { private readonly IMediator _mediator; private readonly MyDbContext _dbcontext; // public SledgemapperHub(IMediator mediator) => _mediator = mediator; public SledgemapperHub(MyDbContext dbcontext, IMediator mediator) { _dbcontext = dbcontext; _mediator=mediator;} private static Dictionary _sessions = new Dictionary(); public List Colors = new List{"CC0000", "CC3300", "FFCC00", "009900", "006666", "0066FF", "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 session = new SessionData(); 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, string initials) { 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); await Groups.AddToGroupAsync(Context.ConnectionId, sessionName); return session; } else { return null; } } public async Task UpdatePosition(string sessionName, Tile tile) { var player = _sessions[sessionName].Players.First(m => m.ConnectionId == Context.ConnectionId); player.Position = tile; await Clients.Group(sessionName).PlayerUpdate(player); } public async Task Refresh(string sessionName) { return _sessions[sessionName]; } public async Task Sync(string sessionName, SessionData map) { _sessions[sessionName].Map = map.Map; _sessions[sessionName].Overlays = map.Overlays; _sessions[sessionName].Walls = map.Walls; await Clients.Group(sessionName).UpdateMap(_sessions[sessionName]); } } }