diff --git a/.vscode/launch.json b/.vscode/launch.json index cce2780..89a6521 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,7 +2,7 @@ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", + "version": "0.2.0", "configurations": [ { "name": "Docker .NET Core Attach (Preview)", @@ -18,7 +18,18 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build sledgemapper", - "program": "${workspaceFolder}/Sledgemapper/bin/Debug/netcoreapp3.1/sledgemapper.dll", + "program": "${workspaceFolder}/Sledgemapper/bin/Debug/net5.0/sledgemapper.dll", + "args": [], + "cwd": "${workspaceFolder}/Sledgemapper", + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": "Sledgemapper.API", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build sledgemapper.api", + "program": "${workspaceFolder}/Sledgemapper.Api/bin/Debug/net5.0/sledgemapper.api.dll", "args": [], "cwd": "${workspaceFolder}/Sledgemapper", "console": "internalConsole", diff --git a/Sledgemapper.Api/.vscode/launch.json b/Sledgemapper.Api/.vscode/launch.json new file mode 100644 index 0000000..53d95e4 --- /dev/null +++ b/Sledgemapper.Api/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/bin/Debug/net5.0/Sledgemapper.Api.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/Sledgemapper.Api/.vscode/tasks.json b/Sledgemapper.Api/.vscode/tasks.json new file mode 100644 index 0000000..81fe924 --- /dev/null +++ b/Sledgemapper.Api/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Sledgemapper.Api.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Sledgemapper.Api.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/Sledgemapper.Api.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Sledgemapper.Api/Data/MyDbContext.cs b/Sledgemapper.Api/Data/MyDbContext.cs new file mode 100644 index 0000000..a01d2ba --- /dev/null +++ b/Sledgemapper.Api/Data/MyDbContext.cs @@ -0,0 +1,51 @@ +using System; +using System.Security.AccessControl; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Models; +using System.Reflection; +namespace Sledgemapper.Api.Data +{ + public static class DbInitializer + { + public static void Initialize(MyDbContext context) + { + context.Database.EnsureCreated(); + } + } + + + + + public class MyDbContext : DbContext + { + public DbSet MapLogs { get; set; } + + public MyDbContext(DbContextOptions options):base(options) + {} + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + // optionsBuilder. + // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); + // optionsBuilder.UseSqlite("Filename=SledgemapperDatabase.db", options => + // { + // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); + // }); + optionsBuilder.UseSqlite("Filename=MyDatabase.db"); + + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + // Map table names + modelBuilder.Entity().ToTable("MapLog", "dbo"); + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.MapLogId); + //entity.HasIndex(e => {e.SessionName, e.Timestamp}); + }); + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Hubs/SledgemapperHub.cs b/Sledgemapper.Api/Hubs/SledgemapperHub.cs index 5a1dfd5..a0b3ffa 100644 --- a/Sledgemapper.Api/Hubs/SledgemapperHub.cs +++ b/Sledgemapper.Api/Hubs/SledgemapperHub.cs @@ -1,3 +1,4 @@ +using System.Security.AccessControl; using Microsoft.AspNetCore.SignalR; using System.Collections.Generic; using System.Linq; @@ -6,14 +7,19 @@ 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 IMediator _mediator; + private readonly MyDbContext _dbcontext; - public SledgemapperHub(IMediator mediator) => _mediator = mediator; + // 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", @@ -27,12 +33,23 @@ private readonly IMediator _mediator; 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); } @@ -49,12 +66,19 @@ private readonly IMediator _mediator; 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); } @@ -85,6 +109,7 @@ private readonly IMediator _mediator; session.Players.Add(player); _sessions.Add(sessionName, session); + await Groups.AddToGroupAsync(Context.ConnectionId, sessionName); return session; } @@ -123,8 +148,8 @@ private readonly IMediator _mediator; _sessions[sessionName].Map = map.Map; _sessions[sessionName].Overlays = map.Overlays; _sessions[sessionName].Walls = map.Walls; - - await Clients.Group(sessionName).UpdateMap( _sessions[sessionName]); + + await Clients.Group(sessionName).UpdateMap(_sessions[sessionName]); } } } \ No newline at end of file diff --git a/Sledgemapper.Api/Models/MapLog.cs b/Sledgemapper.Api/Models/MapLog.cs new file mode 100644 index 0000000..d743479 --- /dev/null +++ b/Sledgemapper.Api/Models/MapLog.cs @@ -0,0 +1,30 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Sledgemapper.Api.Models +{ + + public class MapLog + { + [Key] + public int MapLogId { get; set; } + + [Required] + public string SessionName { get; set; } + + [Required] + [MaxLength(1)] + public string Operation { get; set; } + + [Required] + [MaxLength(256)] + public string Type { get; set; } + + [Required] + [MaxLength(256)] + public string Object { get; set; } + + [Required] + public double Timestamp { get; set; } + } +} diff --git a/Sledgemapper.Api/Models/Snapshot.cs b/Sledgemapper.Api/Models/Snapshot.cs new file mode 100644 index 0000000..0b83e97 --- /dev/null +++ b/Sledgemapper.Api/Models/Snapshot.cs @@ -0,0 +1,18 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Sledgemapper.Api.Models +{ + + public class Snapshot + { + [Key] + public int SnapshotId { get; set; } + + [Required] + public string Object { get; set; } + + [Required] + public double Timestamp { get; set; } + } +} diff --git a/Sledgemapper.Api/MyDatabase.db b/Sledgemapper.Api/MyDatabase.db new file mode 100644 index 0000000..06b37ec Binary files /dev/null and b/Sledgemapper.Api/MyDatabase.db differ diff --git a/Sledgemapper.Api/MyDatabase.db-shm b/Sledgemapper.Api/MyDatabase.db-shm new file mode 100644 index 0000000..17fbfc1 Binary files /dev/null and b/Sledgemapper.Api/MyDatabase.db-shm differ diff --git a/Sledgemapper.Api/MyDatabase.db-wal b/Sledgemapper.Api/MyDatabase.db-wal new file mode 100644 index 0000000..301b54e Binary files /dev/null and b/Sledgemapper.Api/MyDatabase.db-wal differ diff --git a/Sledgemapper.Api/Program.cs b/Sledgemapper.Api/Program.cs index 58d16e6..a9f9ce2 100644 --- a/Sledgemapper.Api/Program.cs +++ b/Sledgemapper.Api/Program.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Sledgemapper.Api.Data; namespace SignalRChat { @@ -13,7 +15,9 @@ namespace SignalRChat { public static void Main(string[] args) { - CreateHostBuilder(args).Build().Run(); + var host = CreateHostBuilder(args).Build(); + CreateDbIfNotExists(host); +host.Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => @@ -22,5 +26,23 @@ namespace SignalRChat { webBuilder.UseStartup(); }); + + private static void CreateDbIfNotExists(IHost host) + { + using (var scope = host.Services.CreateScope()) + { + var services = scope.ServiceProvider; + try + { + var context = services.GetRequiredService(); + DbInitializer.Initialize(context); + } + catch (Exception ex) + { + var logger = services.GetRequiredService>(); + logger.LogError(ex, "An error occurred creating the DB."); + } + } + } } } diff --git a/Sledgemapper.Api/Sledgemapper.Api.csproj b/Sledgemapper.Api/Sledgemapper.Api.csproj index 1f3ab63..fb38178 100644 --- a/Sledgemapper.Api/Sledgemapper.Api.csproj +++ b/Sledgemapper.Api/Sledgemapper.Api.csproj @@ -6,6 +6,12 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/Sledgemapper.Api/Startup.cs b/Sledgemapper.Api/Startup.cs index 278683d..866ad10 100644 --- a/Sledgemapper.Api/Startup.cs +++ b/Sledgemapper.Api/Startup.cs @@ -10,6 +10,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using SignalRChat.Hubs; using MediatR.Pipeline; +using Sledgemapper.Api.Data; +using Microsoft.EntityFrameworkCore; + namespace SignalRChat { public class Startup @@ -17,6 +20,7 @@ namespace SignalRChat public Startup(IConfiguration configuration) { Configuration = configuration; + } public IConfiguration Configuration { get; } @@ -27,6 +31,10 @@ namespace SignalRChat services.AddRazorPages(); services.AddSignalR(); // services.AddMediatR(typeof(Startup)); + services.AddDbContext(options => options.UseSqlite("Data Source=sledgemapper.db")); + // services.AddEntityFrameworkSqlite().AddDbContext(); + + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/Sledgemapper.Api/sledgemapper.db b/Sledgemapper.Api/sledgemapper.db new file mode 100644 index 0000000..f0e9dd6 Binary files /dev/null and b/Sledgemapper.Api/sledgemapper.db differ diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index 1bd415d..3c958a8 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -13,7 +13,7 @@ using System.IO; using System.Linq; using System; using System.Collections.Concurrent; -using Sledgemapper.Entities; +using Sledgemapper.Shared.Entities; namespace Sledgemapper { @@ -58,13 +58,12 @@ namespace Sledgemapper Window.AllowUserResizing = true; Players = new List(); connection = new HubConnectionBuilder() - .WithAutomaticReconnect() -#if DEBUG - .WithUrl("http://localhost:5000/ChatHub") -#else - .WithUrl("http://hub.michelescandura.com:5000/ChatHub") -#endif - .Build(); + // .WithAutomaticReconnect() + + .WithUrl("http://localhost:5000/SledgemapperHub") + + // .WithUrl("http://hub.michelescandura.com:5000/SledgemapperHub") + .Build(); connection.On("UpdateMap", (map) => { @@ -262,7 +261,11 @@ namespace Sledgemapper } successful = session != null; } - catch { } + catch (Exception ex) + + { + + } if (successful) { _session = textbox.Text; @@ -276,8 +279,8 @@ namespace Sledgemapper window.Closed += (s, a) => { - // Called when window is closed - }; + // Called when window is closed + }; window.ShowModal(_desktop); }; @@ -297,8 +300,8 @@ namespace Sledgemapper RowSpacing = 3, }; - // Set partitioning configuration - grid.ColumnsProportions.Add(new Proportion(ProportionType.Auto)); + // Set partitioning configuration + grid.ColumnsProportions.Add(new Proportion(ProportionType.Auto)); grid.ColumnsProportions.Add(new Proportion(ProportionType.Fill)); grid.RowsProportions.Add(new Proportion(ProportionType.Auto)); grid.RowsProportions.Add(new Proportion(ProportionType.Auto)); @@ -318,15 +321,15 @@ namespace Sledgemapper content.Widgets.Add(grid); - // var content = new VerticalStackPanel(); - // var textbox = new TextBox(); - // TextButton button = new TextButton - // { - // Text = "Start", - // HorizontalAlignment = HorizontalAlignment.Center - // }; - button.Click += async (s, e) => - { + // var content = new VerticalStackPanel(); + // var textbox = new TextBox(); + // TextButton button = new TextButton + // { + // Text = "Start", + // HorizontalAlignment = HorizontalAlignment.Center + // }; + button.Click += async (s, e) => + { if (string.IsNullOrWhiteSpace(textbox.Text)) { return; @@ -353,14 +356,14 @@ namespace Sledgemapper window.Close(); } }; - //content.Widgets.Add(textbox); - content.Widgets.Add(button); + //content.Widgets.Add(textbox); + content.Widgets.Add(button); window.Content = content; window.Closed += (s, a) => { - // Called when window is closed - }; + // Called when window is closed + }; window.ShowModal(_desktop); };