using System.Transactions; using System.Net.Mail; using MediatR; using Sledgemapper.Api.Data; using Sledgemapper.Shared.Entities; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Handlers; using System.Linq; using Sledgemapper.Api.Models; namespace Sledgemapper.Api.Commands { public class GetMapSnapshotCommand : IRequest { public string SessionName { get; private set; } public GetMapSnapshotCommand(string sessionName) { SessionName = sessionName; } } public class GetMapSnapshotCommandHandler : IRequestHandler { private readonly MyDbContext _dbcontext; private readonly IMediator _mediator; public GetMapSnapshotCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } 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.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; } } 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; } } } 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; } } }