using MediatR; using Sledgemapper.Api.Data; using Sledgemapper.Shared.Entities; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Linq; using Sledgemapper.Api.Models; namespace Sledgemapper.Api.Commands { public class GetMapSnapshotCommandHandler : IRequestHandler { private readonly MyDbContext _dbcontext; public GetMapSnapshotCommandHandler(MyDbContext dbcontext) { _dbcontext = dbcontext; } public async Task Handle(GetMapSnapshotCommand notification, CancellationToken cancellationToken) { Snapshot snapshot; double timestamp; Sledgemapper.Shared.Entities.Session mapSession; var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); snapshot = _dbcontext.Snapshots.OrderByDescending(s => s.Timestamp).FirstOrDefault(m => m.SessionId == session.SessionId); if (snapshot is null) { timestamp = 0; mapSession = new Shared.Entities.Session(); } else { mapSession = JsonSerializer.Deserialize(snapshot.Object); timestamp = snapshot.Timestamp; } var mapUpdates = _dbcontext.MapLogs.Where(m => m.SessionId == session.SessionId && m.Timestamp > timestamp).OrderBy(m => m.Timestamp).ToList(); foreach (var mapUpdate in mapUpdates) { if (mapUpdate.Operation == "N") { switch (mapUpdate.Type) { case "T": var tile = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewTile(tile, tile.ID); break; case "W": var wall = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewWall(wall, wall.ID); break; case "O": var overlay = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewOverlay(overlay, overlay.ID); break; case "N": var note = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewNote(note); break; case "L": var line = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewLine(line); break; case "R": var room = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewRoom(room); break; } } else if (mapUpdate.Operation == "D") { switch (mapUpdate.Type) { case "T": var tile = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteTile(tile); break; case "W": var wall = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteWall(wall); break; case "O": var overlay = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteOverlay(overlay); break; case "N": var note = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.DeleteNote(note); break; } } } 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(); } return mapSession; } } }