diff --git a/Sledgemapper.Api/Controllers/MapController.cs b/Sledgemapper.Api/Controllers/MapController.cs deleted file mode 100644 index 1db6765..0000000 --- a/Sledgemapper.Api/Controllers/MapController.cs +++ /dev/null @@ -1,23 +0,0 @@ -using MediatR; -using Microsoft.AspNetCore.Mvc; -using Sledgemapper.Api.Handlers; -using Sledgemapper.Shared.Entities; -using System.Threading.Tasks; - -namespace Sledgemapper.Api.Controllers -{ - [Route("tile")] - public class TileController : ControllerBase - { - private readonly IMediator _mediator; - - public TileController(IMediator mediator) { _mediator = mediator; } - - [HttpPost] - - public async Task Post(string sessionName, Tile tile) - { - await _mediator.Publish(new NewTileNotification(sessionName, tile)); - } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Controllers/SessionController.cs b/Sledgemapper.Api/Controllers/SessionController.cs new file mode 100644 index 0000000..bf65b70 --- /dev/null +++ b/Sledgemapper.Api/Controllers/SessionController.cs @@ -0,0 +1,28 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; +using Sledgemapper.Api.Handlers; +using Sledgemapper.Shared.Entities; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Controllers +{ + [Route("[controller]/{sessionName}")] + public class SessionController : ControllerBase + { + private readonly IMediator _mediator; + + public SessionController(IMediator mediator) { _mediator = mediator; } + + [HttpPost("tile")] + public async Task Post(string sessionName, [FromBody]Tile tile) + { + await _mediator.Publish(new NewTileNotification(sessionName, tile)); + } + + [HttpPost("session")] + public async Task Post(string sessionName, [FromBody]Overlay overlay) + { + await _mediator.Publish(new NewOverlayNotification(sessionName, overlay)); + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/NewTileHandler.cs b/Sledgemapper.Api/Handlers/NewTileHandler.cs index 2b4f670..8f841fe 100644 --- a/Sledgemapper.Api/Handlers/NewTileHandler.cs +++ b/Sledgemapper.Api/Handlers/NewTileHandler.cs @@ -14,20 +14,38 @@ using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class NewTileNotification: INotification + public abstract class BaseNotification : INotification { public double Timestamp { get; private set; } - public Tile Tile { get; private set; } public string SessionName { get; private set; } - public NewTileNotification(string sessionName, Tile tile) + public BaseNotification(string sessionName) { - Tile = tile; Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); SessionName = sessionName; } } + public class NewTileNotification : BaseNotification + { + public Tile Tile { get; private set; } + + public NewTileNotification(string sessionName, Tile tile) : base(sessionName) + { + Tile = tile; + } + } + + public class NewOverlayNotification : BaseNotification + { + public Overlay Overlay { get; private set; } + + public NewOverlayNotification(string sessionName, Overlay overlay) : base(sessionName) + { + Overlay = overlay; + } + } + public class SendNewTileMessage : INotificationHandler { private readonly IHubContext _hub; @@ -61,4 +79,39 @@ namespace Sledgemapper.Api.Handlers await _dbcontext.SaveChangesAsync(); } } + + public class SendNewOverlayMessage : INotificationHandler + { + private readonly IHubContext _hub; + + public SendNewOverlayMessage(IHubContext hub) => _hub = hub; + + public async Task Handle(NewOverlayNotification notification, CancellationToken cancellationToken) + { + await _hub.Clients.Groups(notification.SessionName).NewOverlay(notification.Overlay); + } + } + + public class SaveNewOverlay : INotificationHandler + { + private readonly MyDbContext _dbcontext; + + public SaveNewOverlay(MyDbContext dbcontext) => _dbcontext = dbcontext; + + public async Task Handle(NewOverlayNotification notification, CancellationToken cancellationToken) + { + var jsonString = JsonSerializer.Serialize(notification.Overlay); + + _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog + { + Operation = "N", + SessionName = notification.SessionName, + Type = "O", + Timestamp = notification.Timestamp, + Object = jsonString + }); + + await _dbcontext.SaveChangesAsync(); + } + } } diff --git a/Sledgemapper.Shared/Entities/SessionData.cs b/Sledgemapper.Shared/Entities/SessionData.cs index 7669d43..cf052f6 100644 --- a/Sledgemapper.Shared/Entities/SessionData.cs +++ b/Sledgemapper.Shared/Entities/SessionData.cs @@ -1,24 +1,122 @@ using System.Collections.Generic; -using System.Collections.Concurrent ; +using System.Collections.Concurrent; +using System; + namespace Sledgemapper.Shared.Entities { - public class SessionData - + public class TileAddedEventArgs : EventArgs { + public Tile Tile { get; set; } + public TileAddedEventArgs(Tile tile) => Tile = tile; + } + + public class OverlayAddedEventArgs : EventArgs + { + public Overlay Overlay { get; set; } + public OverlayAddedEventArgs(Overlay overlay) => Overlay = overlay; + } + + public class SessionData + { + public event EventHandler RaiseTileAddedEvent; + public event EventHandler RaiseOverlayAddedEvent; + public SessionData() { Map = new ConcurrentDictionary(); Overlays = new ConcurrentDictionary(); Walls = new ConcurrentDictionary(); - Players = new List< Player>(); + Players = new List(); Colors = new List(); } - + public ConcurrentDictionary Map { get; set; } public ConcurrentDictionary Walls { get; set; } public ConcurrentDictionary Overlays { get; set; } public bool IsValid { get; set; } - public List< Player> Players { get; set; } + public List Players { get; set; } public List Colors; + + public void NewTile(Tile selectedTile, string tileId) + { + var tileExist = Map.TryGetValue(selectedTile.ToString(), out var tile); + Tile newTile; + if (tileExist) + { + Map.TryRemove(tile.ToString(), out var _); + if (tile.ID == tileId) + { + newTile = new Tile { X = selectedTile.X, Y = selectedTile.Y, ID = tileId, Rotation = (tile.Rotation + 1) % 4 }; + } + else + { + newTile = new Tile { X = selectedTile.X, Y = selectedTile.Y, ID = tileId }; + } + } + else + { + newTile = new Tile { X = selectedTile.X, Y = selectedTile.Y, ID = tileId }; + } + + Map.TryAdd(newTile.ToString(), newTile); + + OnRaiseTileAddedEvent(new TileAddedEventArgs(newTile)); + } + + public void NewOverlay(Overlay selectedOverlay, string tileId) + { + var overlayExist = Overlays.TryGetValue(selectedOverlay.ToString(), out var overlay); + Overlay newOverlay; + if (overlayExist) + { + Overlays.TryRemove(overlay.ToString(), out var rrtile); + if (overlay.ID == tileId) + { + newOverlay = new Overlay { X = overlay.X, Y = overlay.Y, ID = tileId, Intersection = overlay.Intersection, Rotation = (overlay.Rotation + 1) % 4 }; + } + else + { + newOverlay = new Overlay { X = selectedOverlay.X, Y = selectedOverlay.Y, ID = tileId, Intersection = selectedOverlay.Intersection }; + } + } + else + { + newOverlay = new Overlay { X = selectedOverlay.X, Y = selectedOverlay.Y, ID = tileId, Intersection = selectedOverlay.Intersection }; + } + + Overlays.TryAdd(newOverlay.ToString(), newOverlay); + OnRaiseOverlayAddedEvent(new OverlayAddedEventArgs(newOverlay)); + + } + + protected virtual void OnRaiseTileAddedEvent(TileAddedEventArgs e) + { + // Make a temporary copy of the event to avoid possibility of + // a race condition if the last subscriber unsubscribes + // immediately after the null check and before the event is raised. + EventHandler raiseEvent = RaiseTileAddedEvent; + + // Event will be null if there are no subscribers + if (raiseEvent != null) + { + // Call to raise the event. + raiseEvent(this, e); + } + } + + protected virtual void OnRaiseOverlayAddedEvent(OverlayAddedEventArgs e) + { + // Make a temporary copy of the event to avoid possibility of + // a race condition if the last subscriber unsubscribes + // immediately after the null check and before the event is raised. + EventHandler raiseEvent = RaiseOverlayAddedEvent; + + // Event will be null if there are no subscribers + if (raiseEvent != null) + { + // Call to raise the event. + raiseEvent(this, e); + } + } } } diff --git a/Sledgemapper.sln b/Sledgemapper.sln index bc217e1..77a1b49 100644 --- a/Sledgemapper.sln +++ b/Sledgemapper.sln @@ -3,15 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30626.31 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sledgemapper", "MyGame\Sledgemapper.csproj", "{3E895B69-EBD7-4FDD-84D0-BEC18FC5D658}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sledgemapper", "Sledgemapper\Sledgemapper.csproj", "{82A56068-E643-424B-826F-E78F27346BC3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sledgemapper", "Sledgemapper\Sledgemapper.csproj", "{82A56068-E643-424B-826F-E78F27346BC3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sledgemapper.Api", "Sledgemapper.Api\Sledgemapper.Api.csproj", "{3D99872F-702C-4DF0-BA2F-2F06418C2130}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sledgemapper.Api", "Sledgemapper.Api\Sledgemapper.Api.csproj", "{3D99872F-702C-4DF0-BA2F-2F06418C2130}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sledgemapper.Shared", "Sledgemapper.Shared\Sledgemapper.Shared.csproj", "{7194CFCC-AECB-494F-AA7D-2E0E286A5F34}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sledgemapper.Shared", "Sledgemapper.Shared\Sledgemapper.Shared.csproj", "{7194CFCC-AECB-494F-AA7D-2E0E286A5F34}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApi", "Identity\WebApi.csproj", "{9479E33D-08EE-4B50-B6D0-218801A6E7AC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "Identity\WebApi.csproj", "{9479E33D-08EE-4B50-B6D0-218801A6E7AC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,10 +17,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3E895B69-EBD7-4FDD-84D0-BEC18FC5D658}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E895B69-EBD7-4FDD-84D0-BEC18FC5D658}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E895B69-EBD7-4FDD-84D0-BEC18FC5D658}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E895B69-EBD7-4FDD-84D0-BEC18FC5D658}.Release|Any CPU.Build.0 = Release|Any CPU {82A56068-E643-424B-826F-E78F27346BC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {82A56068-E643-424B-826F-E78F27346BC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {82A56068-E643-424B-826F-E78F27346BC3}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Sledgemapper/IMapApi.cs b/Sledgemapper/IMapApi.cs index a2d1dab..df106a6 100644 --- a/Sledgemapper/IMapApi.cs +++ b/Sledgemapper/IMapApi.cs @@ -10,7 +10,10 @@ namespace Sledgemapper { public interface IMapApi { - [Post("/tile")] + [Post("/session/{sessionName}/tile")] Task NewTile([Body] Tile tile, string sessionName); + + [Post("/session/{sessionName}/overlay")] + Task NewOverlay([Body] Overlay overlay, string sessionName); } } diff --git a/Sledgemapper/MyDatabase.db b/Sledgemapper/MyDatabase.db index bf3822b..4b564ba 100644 Binary files a/Sledgemapper/MyDatabase.db and b/Sledgemapper/MyDatabase.db differ diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index d0936cf..65b5cec 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -276,6 +276,8 @@ namespace Sledgemapper var session = await connection?.InvokeAsync("NewSession", textbox.Text, initialsTextbox.Text); if (session != null) { + session.RaiseTileAddedEvent += TileAddedEvent; + session.RaiseOverlayAddedEvent += OverlayAddedEvent; Players = session.Players; } @@ -400,6 +402,8 @@ namespace Sledgemapper return menu; } + + protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); @@ -930,62 +934,22 @@ namespace Sledgemapper private void SetTile(string tileId) { - var tileExist = _sessionData.Map.TryGetValue(_selectedTile.ToString(), out var rtile); - if (tileExist) - { - var get = _sessionData.Map.TryGetValue(_selectedTile.ToString(), out var tile); + _sessionData.NewTile(_selectedTile, tileId); + } - _sessionData.Map.TryRemove(tile.ToString(), out var rrtile); - if (tile.ID == tileId) - { - var newTile = new Tile { X = _selectedTile.X, Y = _selectedTile.Y, ID = tileId, Rotation = (tile.Rotation + 1) % 4 }; - _sessionData.Map.TryAdd(newTile.ToString(), newTile); - _api.NewTile(newTile, _session); - //connection?.InvokeAsync("NewTile", _session, newTile); - } - else - { - var newTile = new Tile { X = _selectedTile.X, Y = _selectedTile.Y, ID = tileId }; - _sessionData.Map.TryAdd(newTile.ToString(), newTile); - _api.NewTile(newTile, _session); - // connection?.InvokeAsync("NewTile", _session, newTile); - } - } - else - { - var newTile = new Tile { X = _selectedTile.X, Y = _selectedTile.Y, ID = tileId }; - _sessionData.Map.TryAdd(newTile.ToString(), newTile); - _api.NewTile(newTile, _session); - // connection?.InvokeAsync("NewTile", _session, newTile); - } + private void TileAddedEvent(object sender, TileAddedEventArgs e) + { + _api.NewTile(e.Tile, _session); } private void SetOverlay(string tileId) { - var overlayExist = _sessionData.Overlays.TryGetValue(_selectedOverlay.ToString(), out var tile); - if (overlayExist) - { - var exist = _sessionData.Overlays.TryGetValue(_selectedOverlay.ToString(), out var overlay); - _sessionData.Overlays.TryRemove(tile.ToString(), out var rrtile); - if (overlay.ID == tileId) - { - var newOverlay = new Overlay { X = overlay.X, Y = overlay.Y, ID = tileId, Intersection = overlay.Intersection, Rotation = (overlay.Rotation + 1) % 4 }; - _sessionData.Overlays.TryAdd(newOverlay.ToString(), newOverlay); - connection?.InvokeAsync("NewOverlay", _session, newOverlay); - } - else - { - var newOverlay = new Overlay { X = _selectedOverlay.X, Y = _selectedOverlay.Y, ID = tileId, Intersection = _selectedOverlay.Intersection }; - _sessionData.Overlays.TryAdd(newOverlay.ToString(), newOverlay); - connection?.InvokeAsync("NewOverlay", _session, newOverlay); - } - } - else - { - var newOverlay = new Overlay { X = _selectedOverlay.X, Y = _selectedOverlay.Y, ID = tileId, Intersection = _selectedOverlay.Intersection }; - _sessionData.Overlays.TryAdd(newOverlay.ToString(), newOverlay); - connection?.InvokeAsync("NewOverlay", _session, newOverlay); - } + _sessionData.NewOverlay(_selectedOverlay, tileId); + } + + private void OverlayAddedEvent(object sender, OverlayAddedEventArgs e) + { + _api.NewOverlay(e.Overlay, _session); } private void DeleteWall()