diff --git a/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs b/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs index 8ffce12..221c582 100644 --- a/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs +++ b/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs @@ -34,10 +34,10 @@ namespace Sledgemapper.Api.Commands double timestamp; Sledgemapper.Shared.Entities.Session mapSession; var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - snapshot = _dbcontext.Snapshots.FirstOrDefault(m => m.SessionId == session.SessionId); + snapshot = _dbcontext.Snapshots.OrderByDescending(s => s.Timestamp).FirstOrDefault(m => m.SessionId == session.SessionId); if (snapshot is null) { - + timestamp = 0; mapSession = new Shared.Entities.Session(); } @@ -59,11 +59,11 @@ namespace Sledgemapper.Api.Commands mapSession.NewTile(tile, tile.ID); break; case "W": - var wall = JsonSerializer.Deserialize(mapUpdate.Object); + var wall = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewWall(wall, wall.ID); break; case "O": - var overlay = JsonSerializer.Deserialize(mapUpdate.Object); + var overlay = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewOverlay(overlay, overlay.ID); break; @@ -79,24 +79,29 @@ namespace Sledgemapper.Api.Commands mapSession.DeleteTile(tile); break; case "W": - var wall = JsonSerializer.Deserialize(mapUpdate.Object); + var wall = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteWall(wall); break; case "O": - var overlay = JsonSerializer.Deserialize(mapUpdate.Object); + var overlay = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteOverlay(overlay); break; } } } -var newSnapshot = new Snapshot{ - SessionId=session.SessionId, - Timestamp=mapUpdates.Max(mapSession=>mapSession.Timestamp), - Object = JsonSerializer.Serialize(mapSession) + if (mapUpdates.Any()) + { + var newSnapshot = new Snapshot + { + SessionId = session.SessionId, + Timestamp = mapUpdates.Max(mapSession => mapSession.Timestamp), + Object = JsonSerializer.Serialize(mapSession) + }; + await _dbcontext.Snapshots.AddAsync(newSnapshot); + await _dbcontext.SaveChangesAsync(); + } + -}; -await _dbcontext.Snapshots.AddAsync(newSnapshot); -await _dbcontext.SaveChangesAsync(); return mapSession; diff --git a/Sledgemapper.Api/Controllers/SessionController.cs b/Sledgemapper.Api/Controllers/SessionController.cs index 7da714c..8895974 100644 --- a/Sledgemapper.Api/Controllers/SessionController.cs +++ b/Sledgemapper.Api/Controllers/SessionController.cs @@ -38,7 +38,7 @@ namespace Sledgemapper.Api.Controllers { var userId = int.Parse(HttpContext.User.Identity.Name); await _mediator.Send(new SaveNewSnapshotCommand(sessionName, session, userId)); - } + } [HttpPost("tile")] public async Task Post(string sessionName, [FromBody] Tile tile) diff --git a/Sledgemapper.Api/Data/MyDbContext.cs b/Sledgemapper.Api/Data/MyDbContext.cs index ea909df..c2e5dce 100644 --- a/Sledgemapper.Api/Data/MyDbContext.cs +++ b/Sledgemapper.Api/Data/MyDbContext.cs @@ -60,12 +60,16 @@ namespace Sledgemapper.Api.Data modelBuilder.Entity(entity => { entity.HasKey(e => e.UserConnectionId); + entity.HasIndex(e => e.UserId); + }); modelBuilder.Entity().ToTable("SessionUser", "dbo"); modelBuilder.Entity(entity => { entity.HasKey(e => e.SessionUserId); + entity.HasIndex(e => e.SessionId); + }); modelBuilder.Entity().ToTable("Snapshot", "dbo"); diff --git a/Sledgemapper.Api/Hubs/SledgemapperHub.cs b/Sledgemapper.Api/Hubs/SledgemapperHub.cs index b918919..8677793 100644 --- a/Sledgemapper.Api/Hubs/SledgemapperHub.cs +++ b/Sledgemapper.Api/Hubs/SledgemapperHub.cs @@ -17,11 +17,10 @@ using Sledgemapper.Helpers; namespace SignalRChat.Hubs { - - [Authorize] public class SledgemapperHub : Hub { + private static readonly ConcurrentDictionary UserColors = new ConcurrentDictionary(); private readonly MyDbContext _dbContext; private readonly DataContext _datacontext; @@ -35,14 +34,14 @@ namespace SignalRChat.Hubs // #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"}; + "#e6194B", + "#f58231", + "#3cb44b", + "#000075", + "#911eb4", + "#800000", + "#808000", + "#469990"}; public async Task NewTile(string sessionName, Tile tile) { @@ -147,37 +146,20 @@ namespace SignalRChat.Hubs 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, session.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 u = SessionUsers.FirstOrDefault(m => m.UserId == userId); - var player = new Player { UserId = userId, Initials = user.Initials, Position = new Tile { X = 0, Y = 0 }, Color = Colors[SessionUsers.IndexOf(u)] }; - await Clients.Group(sessionName).NewPlayer(player); - + var player = new Player { UserId = userId, Initials = user.Initials, Position = new Tile { X = 0, Y = 0 }, Color = UserColors[userId] }; + + await Clients.Group(session.SessionName).NewPlayer(player); + await Clients.Group(session.SessionName).RefreshPlayers(); + var newSession = new Sledgemapper.Shared.Entities.Session { - SessionName = sessionName, + SessionName = session.SessionName, SessionId = session.SessionId }; @@ -202,7 +184,7 @@ namespace SignalRChat.Hubs // } } - public async Task UpdatePosition(string sessionName,int sessionId, Tile tile) + public async Task UpdatePosition(string sessionName, int sessionId, Tile tile) { var userId = int.Parse(Context.User.Identity.Name); //var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionName == sessionName); @@ -235,6 +217,8 @@ namespace SignalRChat.Hubs var userConnection = new UserConnection { ConnectionId = Context.ConnectionId, UserId = userId }; _dbContext.UserConnections.Add(userConnection); await _dbContext.SaveChangesAsync(); + var availableColor = Colors.Where(m => !UserColors.Values.Contains(m)).First(); + UserColors.AddOrUpdate(userId, availableColor, (key, oldValue) => availableColor); await base.OnConnectedAsync(); } @@ -245,7 +229,7 @@ namespace SignalRChat.Hubs { _dbContext.UserConnections.Remove(userConnection); } - + var userSessions = _dbContext.SessionUsers.Where(m => m.UserId == userConnection.UserId).ToList(); { foreach (var userSession in userSessions) diff --git a/Sledgemapper.Api/LocalDatabase.db b/Sledgemapper.Api/LocalDatabase.db index 20954d8..89c527f 100644 Binary files a/Sledgemapper.Api/LocalDatabase.db and b/Sledgemapper.Api/LocalDatabase.db differ diff --git a/Sledgemapper.Api/Startup.cs b/Sledgemapper.Api/Startup.cs index d442c73..a86af33 100644 --- a/Sledgemapper.Api/Startup.cs +++ b/Sledgemapper.Api/Startup.cs @@ -49,7 +49,7 @@ namespace SignalRChat services.AddSignalR(); services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); services.AddMediatR(typeof(Startup)); - services.AddDbContext(options => options.UseSqlite("Data Source=sledgemapper.db")); + services.AddDbContext(options => {options.UseSqlite("Data Source=sledgemapper.db"); options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);}); // services.AddEntityFrameworkSqlite().AddDbContext(); // configure strongly typed settings objects diff --git a/Sledgemapper.Api/sledgemapper.db b/Sledgemapper.Api/sledgemapper.db index 94d5126..d2754f6 100644 Binary files a/Sledgemapper.Api/sledgemapper.db and b/Sledgemapper.Api/sledgemapper.db differ diff --git a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs index f9d56b7..bbaa8f4 100644 --- a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs +++ b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs @@ -15,5 +15,6 @@ namespace Sledgemapper.Clients Task NewPlayer(Player player); Task PlayerUpdate(Player player); Task UpdateMap(Session player); + Task RefreshPlayers(); } } diff --git a/Sledgemapper/CommunicationManager.cs b/Sledgemapper/CommunicationManager.cs index c7c89b8..2eeb646 100644 --- a/Sledgemapper/CommunicationManager.cs +++ b/Sledgemapper/CommunicationManager.cs @@ -85,36 +85,41 @@ namespace Sledgemapper SessionData.Map.TryAdd(tile.ToString(), tile); }); + Connection.On("RefreshPlayers", () => + { + Connection?.SendAsync("UpdatePosition", SessionData.SessionName, SessionData.SessionId, SessionData.Players.First(p=>p.UserId==int.Parse(_authenticateResponse.Id))); + }); + Connection.On("NewWall", (tile) => { SessionData.Walls.Remove(tile.ToString(), out var _); SessionData.Walls.TryAdd(tile.ToString(), tile); }); - Connection.On("NewOverlay", (tile) => - { - SessionData.Overlays.Remove(tile.ToString(), out var _); - SessionData.Overlays.TryAdd(tile.ToString(), tile); - }); + Connection.On("NewOverlay", (tile) => + { + SessionData.Overlays.Remove(tile.ToString(), out var _); + SessionData.Overlays.TryAdd(tile.ToString(), tile); + }); Connection.On("NewPlayer", (player) => - { - var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); - if (p is null) - { - SessionData.Players.Add(player); - } - else - { - p.Color = player.Color; - p.Position = player.Position; - } - }); + { + var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); + if (p is null) + { + SessionData.Players.Add(player); + } + else + { + p.Color = player.Color; + p.Position = player.Position; + } + }); } private Task GetToken() { - return Task.FromResult(_authenticateResponse.Token); + return Task.FromResult(_authenticateResponse.Token); } public async Task Register(RegisterModel registerModel) @@ -186,7 +191,7 @@ namespace Sledgemapper if (getToken == null) throw new ArgumentNullException(nameof(getToken)); this.getToken = getToken; - //if (myConfigurationService.VerifySslCertificate == false) + //if (myConfigurationService.VerifySslCertificate == false) //{ ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => true; diff --git a/Sledgemapper/IMapApi.cs b/Sledgemapper/IMapApi.cs index 1d90ce0..43d6365 100644 --- a/Sledgemapper/IMapApi.cs +++ b/Sledgemapper/IMapApi.cs @@ -21,7 +21,6 @@ namespace Sledgemapper [Post("/session/{sessionName}/snapshot")] Task SaveSnapshot([Body] Session session, string sessionName); - [Post("/session/{sessionName}/tile")] Task NewTile([Body] Tile tile, string sessionName); diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index 85aecc8..5bb8a9b 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -766,7 +766,10 @@ namespace Sledgemapper } using StreamReader file = File.OpenText(dialog.FilePath); JsonSerializer serializer = new JsonSerializer(); - _sessionData = (Session)serializer.Deserialize(file, typeof(Session)); + var loadData = (Session)serializer.Deserialize(file, typeof(Session)); + _sessionData.Map=loadData.Map; + _sessionData.Overlays=loadData.Overlays; + _sessionData.Walls=loadData.Walls; }; dialog.ShowModal(_desktop); diff --git a/Sledgemapper/UI/MainWidget.Generated.cs b/Sledgemapper/UI/MainWidget.Generated.cs index bb10ac2..b3bfba6 100644 --- a/Sledgemapper/UI/MainWidget.Generated.cs +++ b/Sledgemapper/UI/MainWidget.Generated.cs @@ -1,4 +1,4 @@ -/* Generated by MyraPad at 17/11/2020 15:10:52 */ +/* Generated by MyraPad at 17/11/2020 22:10:31 */ using Myra.Graphics2D; using Myra.Graphics2D.TextureAtlases; using Myra.Graphics2D.UI; @@ -174,6 +174,51 @@ namespace Sledgemapper.UI verticalSplitPane1.Widgets.Add(verticalStackPanel2); verticalSplitPane1.Widgets.Add(verticalStackPanel3); + var label1 = new Label(); + label1.Text = "Connection status:"; + + lblConnectionStatus = new Label(); + lblConnectionStatus.Text = "Disconnected"; + lblConnectionStatus.MinWidth = 100; + lblConnectionStatus.Id = "lblConnectionStatus"; + + var verticalSeparator1 = new VerticalSeparator(); + + var label2 = new Label(); + label2.Text = "Username:"; + + lblUsername = new Label(); + lblUsername.Text = "n/a"; + lblUsername.MinWidth = 100; + lblUsername.Id = "lblUsername"; + + var verticalSeparator2 = new VerticalSeparator(); + + var label3 = new Label(); + label3.Text = "Session name:"; + + lblSessionName = new Label(); + lblSessionName.Text = "n/a"; + lblSessionName.MinWidth = 100; + lblSessionName.Id = "lblSessionName"; + + var horizontalStackPanel1 = new HorizontalStackPanel(); + horizontalStackPanel1.Spacing = 10; + horizontalStackPanel1.Proportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Auto, + }); + horizontalStackPanel1.Height = 25; + horizontalStackPanel1.Background = new SolidBrush("#333333FF"); + horizontalStackPanel1.Widgets.Add(label1); + horizontalStackPanel1.Widgets.Add(lblConnectionStatus); + horizontalStackPanel1.Widgets.Add(verticalSeparator1); + horizontalStackPanel1.Widgets.Add(label2); + horizontalStackPanel1.Widgets.Add(lblUsername); + horizontalStackPanel1.Widgets.Add(verticalSeparator2); + horizontalStackPanel1.Widgets.Add(label3); + horizontalStackPanel1.Widgets.Add(lblSessionName); + Proportions.Add(new Proportion { @@ -185,6 +230,7 @@ namespace Sledgemapper.UI }); Widgets.Add(_mainMenu); Widgets.Add(verticalSplitPane1); + Widgets.Add(horizontalStackPanel1); } @@ -202,5 +248,8 @@ namespace Sledgemapper.UI public Grid GridTiles; public Grid GridWalls; public Grid GridOverlays; + public Label lblConnectionStatus; + public Label lblUsername; + public Label lblSessionName; } } \ No newline at end of file diff --git a/Sledgemapper/UI/mainwidget.xml b/Sledgemapper/UI/mainwidget.xml index af587b5..2775366 100644 --- a/Sledgemapper/UI/mainwidget.xml +++ b/Sledgemapper/UI/mainwidget.xml @@ -59,5 +59,18 @@ + + + + + \ No newline at end of file