DI: Split QueueHandler into multiple classes
This commit is contained in:
parent
29aefee135
commit
7d04cd7575
@ -69,7 +69,6 @@ namespace Pal.Client.DependencyInjection
|
|||||||
services.AddSingleton<FrameworkService>();
|
services.AddSingleton<FrameworkService>();
|
||||||
services.AddSingleton<ChatService>();
|
services.AddSingleton<ChatService>();
|
||||||
services.AddSingleton<FloorService>();
|
services.AddSingleton<FloorService>();
|
||||||
services.AddSingleton<QueueHandler>();
|
|
||||||
|
|
||||||
// windows & related services
|
// windows & related services
|
||||||
services.AddSingleton<AgreementWindow>();
|
services.AddSingleton<AgreementWindow>();
|
||||||
@ -82,6 +81,12 @@ namespace Pal.Client.DependencyInjection
|
|||||||
services.AddSingleton<SplatoonRenderer>();
|
services.AddSingleton<SplatoonRenderer>();
|
||||||
services.AddSingleton<RenderAdapter>();
|
services.AddSingleton<RenderAdapter>();
|
||||||
|
|
||||||
|
// queue handling
|
||||||
|
services.AddTransient<IQueueOnFrameworkThread.Handler<QueuedImport>, QueuedImport.Handler>();
|
||||||
|
services.AddTransient<IQueueOnFrameworkThread.Handler<QueuedUndoImport>, QueuedUndoImport.Handler>();
|
||||||
|
services.AddTransient<IQueueOnFrameworkThread.Handler<QueuedConfigUpdate>, QueuedConfigUpdate.Handler>();
|
||||||
|
services.AddTransient<IQueueOnFrameworkThread.Handler<QueuedSyncResponse>, QueuedSyncResponse.Handler>();
|
||||||
|
|
||||||
// set up the current UI language before creating anything
|
// set up the current UI language before creating anything
|
||||||
Localization.Culture = new CultureInfo(pluginInterface.UiLanguage);
|
Localization.Culture = new CultureInfo(pluginInterface.UiLanguage);
|
||||||
|
|
||||||
|
@ -9,7 +9,9 @@ using Dalamud.Game;
|
|||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Pal.Client.Configuration;
|
using Pal.Client.Configuration;
|
||||||
using Pal.Client.Extensions;
|
using Pal.Client.Extensions;
|
||||||
using Pal.Client.Net;
|
using Pal.Client.Net;
|
||||||
@ -20,6 +22,7 @@ namespace Pal.Client.DependencyInjection
|
|||||||
{
|
{
|
||||||
internal sealed class FrameworkService : IDisposable
|
internal sealed class FrameworkService : IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly Framework _framework;
|
private readonly Framework _framework;
|
||||||
private readonly ConfigurationManager _configurationManager;
|
private readonly ConfigurationManager _configurationManager;
|
||||||
private readonly IPalacePalConfiguration _configuration;
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
@ -28,7 +31,6 @@ namespace Pal.Client.DependencyInjection
|
|||||||
private readonly FloorService _floorService;
|
private readonly FloorService _floorService;
|
||||||
private readonly DebugState _debugState;
|
private readonly DebugState _debugState;
|
||||||
private readonly RenderAdapter _renderAdapter;
|
private readonly RenderAdapter _renderAdapter;
|
||||||
private readonly QueueHandler _queueHandler;
|
|
||||||
private readonly ObjectTable _objectTable;
|
private readonly ObjectTable _objectTable;
|
||||||
private readonly RemoteApi _remoteApi;
|
private readonly RemoteApi _remoteApi;
|
||||||
|
|
||||||
@ -36,7 +38,9 @@ namespace Pal.Client.DependencyInjection
|
|||||||
internal Queue<IQueueOnFrameworkThread> LateEventQueue { get; } = new();
|
internal Queue<IQueueOnFrameworkThread> LateEventQueue { get; } = new();
|
||||||
internal ConcurrentQueue<nint> NextUpdateObjects { get; } = new();
|
internal ConcurrentQueue<nint> NextUpdateObjects { get; } = new();
|
||||||
|
|
||||||
public FrameworkService(Framework framework,
|
public FrameworkService(
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
Framework framework,
|
||||||
ConfigurationManager configurationManager,
|
ConfigurationManager configurationManager,
|
||||||
IPalacePalConfiguration configuration,
|
IPalacePalConfiguration configuration,
|
||||||
ClientState clientState,
|
ClientState clientState,
|
||||||
@ -44,10 +48,10 @@ namespace Pal.Client.DependencyInjection
|
|||||||
FloorService floorService,
|
FloorService floorService,
|
||||||
DebugState debugState,
|
DebugState debugState,
|
||||||
RenderAdapter renderAdapter,
|
RenderAdapter renderAdapter,
|
||||||
QueueHandler queueHandler,
|
|
||||||
ObjectTable objectTable,
|
ObjectTable objectTable,
|
||||||
RemoteApi remoteApi)
|
RemoteApi remoteApi)
|
||||||
{
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
_configurationManager = configurationManager;
|
_configurationManager = configurationManager;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
@ -56,7 +60,6 @@ namespace Pal.Client.DependencyInjection
|
|||||||
_floorService = floorService;
|
_floorService = floorService;
|
||||||
_debugState = debugState;
|
_debugState = debugState;
|
||||||
_renderAdapter = renderAdapter;
|
_renderAdapter = renderAdapter;
|
||||||
_queueHandler = queueHandler;
|
|
||||||
_objectTable = objectTable;
|
_objectTable = objectTable;
|
||||||
_remoteApi = remoteApi;
|
_remoteApi = remoteApi;
|
||||||
|
|
||||||
@ -84,7 +87,7 @@ namespace Pal.Client.DependencyInjection
|
|||||||
bool saveMarkers = false;
|
bool saveMarkers = false;
|
||||||
|
|
||||||
while (EarlyEventQueue.TryDequeue(out IQueueOnFrameworkThread? queued))
|
while (EarlyEventQueue.TryDequeue(out IQueueOnFrameworkThread? queued))
|
||||||
_queueHandler.Handle(queued, ref recreateLayout, ref saveMarkers);
|
HandleQueued(queued, ref recreateLayout, ref saveMarkers);
|
||||||
|
|
||||||
if (_territoryState.LastTerritory != _clientState.TerritoryType)
|
if (_territoryState.LastTerritory != _clientState.TerritoryType)
|
||||||
{
|
{
|
||||||
@ -111,12 +114,13 @@ namespace Pal.Client.DependencyInjection
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (LateEventQueue.TryDequeue(out IQueueOnFrameworkThread? queued))
|
while (LateEventQueue.TryDequeue(out IQueueOnFrameworkThread? queued))
|
||||||
_queueHandler.Handle(queued, ref recreateLayout, ref saveMarkers);
|
HandleQueued(queued, ref recreateLayout, ref saveMarkers);
|
||||||
|
|
||||||
var currentFloor = _floorService.GetFloorMarkers(_territoryState.LastTerritory);
|
var currentFloor = _floorService.GetFloorMarkers(_territoryState.LastTerritory);
|
||||||
|
|
||||||
IList<Marker> visibleMarkers = GetRelevantGameObjects();
|
IList<Marker> visibleMarkers = GetRelevantGameObjects();
|
||||||
HandlePersistentMarkers(currentFloor, visibleMarkers.Where(x => x.IsPermanent()).ToList(), saveMarkers, recreateLayout);
|
HandlePersistentMarkers(currentFloor, visibleMarkers.Where(x => x.IsPermanent()).ToList(), saveMarkers,
|
||||||
|
recreateLayout);
|
||||||
HandleEphemeralMarkers(visibleMarkers.Where(x => !x.IsPermanent()).ToList(), recreateLayout);
|
HandleEphemeralMarkers(visibleMarkers.Where(x => !x.IsPermanent()).ToList(), recreateLayout);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -126,7 +130,9 @@ namespace Pal.Client.DependencyInjection
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Render Markers
|
#region Render Markers
|
||||||
private void HandlePersistentMarkers(LocalState currentFloor, IList<Marker> visibleMarkers, bool saveMarkers, bool recreateLayout)
|
|
||||||
|
private void HandlePersistentMarkers(LocalState currentFloor, IList<Marker> visibleMarkers, bool saveMarkers,
|
||||||
|
bool recreateLayout)
|
||||||
{
|
{
|
||||||
var currentFloorMarkers = currentFloor.Markers;
|
var currentFloorMarkers = currentFloor.Markers;
|
||||||
|
|
||||||
@ -145,7 +151,8 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
// This requires you to have seen a trap/hoard marker once per floor to synchronize this for older local states,
|
// This requires you to have seen a trap/hoard marker once per floor to synchronize this for older local states,
|
||||||
// markers discovered afterwards are automatically marked seen.
|
// markers discovered afterwards are automatically marked seen.
|
||||||
if (partialAccountId != null && knownMarker is { NetworkId: { }, RemoteSeenRequested: false } && !knownMarker.RemoteSeenOn.Contains(partialAccountId))
|
if (partialAccountId != null && knownMarker is { NetworkId: { }, RemoteSeenRequested: false } &&
|
||||||
|
!knownMarker.RemoteSeenOn.Contains(partialAccountId))
|
||||||
updateSeenMarkers = true;
|
updateSeenMarkers = true;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -156,9 +163,10 @@ namespace Pal.Client.DependencyInjection
|
|||||||
saveMarkers = true;
|
saveMarkers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recreateLayout && currentFloorMarkers.Count > 0 && (_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander || _configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander))
|
if (!recreateLayout && currentFloorMarkers.Count > 0 &&
|
||||||
|
(_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander ||
|
||||||
|
_configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander))
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (var marker in currentFloorMarkers)
|
foreach (var marker in currentFloorMarkers)
|
||||||
@ -183,7 +191,9 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
if (updateSeenMarkers && partialAccountId != null)
|
if (updateSeenMarkers && partialAccountId != null)
|
||||||
{
|
{
|
||||||
var markersToUpdate = currentFloorMarkers.Where(x => x is { Seen: true, NetworkId: { }, RemoteSeenRequested: false } && !x.RemoteSeenOn.Contains(partialAccountId)).ToList();
|
var markersToUpdate = currentFloorMarkers.Where(x =>
|
||||||
|
x is { Seen: true, NetworkId: { }, RemoteSeenRequested: false } &&
|
||||||
|
!x.RemoteSeenOn.Contains(partialAccountId)).ToList();
|
||||||
foreach (var marker in markersToUpdate)
|
foreach (var marker in markersToUpdate)
|
||||||
marker.RemoteSeenRequested = true;
|
marker.RemoteSeenRequested = true;
|
||||||
Task.Run(async () => await SyncSeenMarkersForTerritory(_territoryState.LastTerritory, markersToUpdate));
|
Task.Run(async () => await SyncSeenMarkersForTerritory(_territoryState.LastTerritory, markersToUpdate));
|
||||||
@ -195,12 +205,14 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
if (_territoryState.TerritorySyncState == SyncState.Complete)
|
if (_territoryState.TerritorySyncState == SyncState.Complete)
|
||||||
{
|
{
|
||||||
var markersToUpload = currentFloorMarkers.Where(x => x.IsPermanent() && x.NetworkId == null && !x.UploadRequested).ToList();
|
var markersToUpload = currentFloorMarkers
|
||||||
|
.Where(x => x.IsPermanent() && x.NetworkId == null && !x.UploadRequested).ToList();
|
||||||
if (markersToUpload.Count > 0)
|
if (markersToUpload.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var marker in markersToUpload)
|
foreach (var marker in markersToUpload)
|
||||||
marker.UploadRequested = true;
|
marker.UploadRequested = true;
|
||||||
Task.Run(async () => await UploadMarkersForTerritory(_territoryState.LastTerritory, markersToUpload));
|
Task.Run(async () =>
|
||||||
|
await UploadMarkersForTerritory(_territoryState.LastTerritory, markersToUpload));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,15 +224,18 @@ namespace Pal.Client.DependencyInjection
|
|||||||
List<IRenderElement> elements = new();
|
List<IRenderElement> elements = new();
|
||||||
foreach (var marker in currentFloorMarkers)
|
foreach (var marker in currentFloorMarkers)
|
||||||
{
|
{
|
||||||
if (marker.Seen || _configuration.Mode == EMode.Online || marker is { WasImported: true, Imports.Count: > 0 })
|
if (marker.Seen || _configuration.Mode == EMode.Online ||
|
||||||
|
marker is { WasImported: true, Imports.Count: > 0 })
|
||||||
{
|
{
|
||||||
if (marker.Type == Marker.EType.Trap)
|
if (marker.Type == Marker.EType.Trap)
|
||||||
{
|
{
|
||||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), _configuration.DeepDungeons.Traps);
|
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers),
|
||||||
|
_configuration.DeepDungeons.Traps);
|
||||||
}
|
}
|
||||||
else if (marker.Type == Marker.EType.Hoard)
|
else if (marker.Type == Marker.EType.Hoard)
|
||||||
{
|
{
|
||||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), _configuration.DeepDungeons.HoardCoffers);
|
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers),
|
||||||
|
_configuration.DeepDungeons.HoardCoffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,8 +249,10 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
private void HandleEphemeralMarkers(IList<Marker> visibleMarkers, bool recreateLayout)
|
private void HandleEphemeralMarkers(IList<Marker> visibleMarkers, bool recreateLayout)
|
||||||
{
|
{
|
||||||
recreateLayout |= _floorService.EphemeralMarkers.Any(existingMarker => visibleMarkers.All(x => x != existingMarker));
|
recreateLayout |=
|
||||||
recreateLayout |= visibleMarkers.Any(visibleMarker => _floorService.EphemeralMarkers.All(x => x != visibleMarker));
|
_floorService.EphemeralMarkers.Any(existingMarker => visibleMarkers.All(x => x != existingMarker));
|
||||||
|
recreateLayout |=
|
||||||
|
visibleMarkers.Any(visibleMarker => _floorService.EphemeralMarkers.All(x => x != visibleMarker));
|
||||||
|
|
||||||
if (recreateLayout)
|
if (recreateLayout)
|
||||||
{
|
{
|
||||||
@ -249,7 +266,8 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
if (marker.Type == Marker.EType.SilverCoffer && _configuration.DeepDungeons.SilverCoffers.Show)
|
if (marker.Type == Marker.EType.SilverCoffer && _configuration.DeepDungeons.SilverCoffers.Show)
|
||||||
{
|
{
|
||||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), _configuration.DeepDungeons.SilverCoffers);
|
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers),
|
||||||
|
_configuration.DeepDungeons.SilverCoffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,9 +282,13 @@ namespace Pal.Client.DependencyInjection
|
|||||||
{
|
{
|
||||||
switch (marker.Type)
|
switch (marker.Type)
|
||||||
{
|
{
|
||||||
case Marker.EType.Trap when _territoryState.PomanderOfSight == PomanderState.Inactive || !_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander || visibleMarkers.Any(x => x == marker):
|
case Marker.EType.Trap when _territoryState.PomanderOfSight == PomanderState.Inactive ||
|
||||||
|
!_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander ||
|
||||||
|
visibleMarkers.Any(x => x == marker):
|
||||||
return _configuration.DeepDungeons.Traps.Color;
|
return _configuration.DeepDungeons.Traps.Color;
|
||||||
case Marker.EType.Hoard when _territoryState.PomanderOfIntuition == PomanderState.Inactive || !_configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander || visibleMarkers.Any(x => x == marker):
|
case Marker.EType.Hoard when _territoryState.PomanderOfIntuition == PomanderState.Inactive ||
|
||||||
|
!_configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander ||
|
||||||
|
visibleMarkers.Any(x => x == marker):
|
||||||
return _configuration.DeepDungeons.HoardCoffers.Color;
|
return _configuration.DeepDungeons.HoardCoffers.Color;
|
||||||
case Marker.EType.SilverCoffer:
|
case Marker.EType.SilverCoffer:
|
||||||
return _configuration.DeepDungeons.SilverCoffers.Color;
|
return _configuration.DeepDungeons.SilverCoffers.Color;
|
||||||
@ -278,7 +300,8 @@ namespace Pal.Client.DependencyInjection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateRenderElement(Marker marker, List<IRenderElement> elements, uint color, MarkerConfiguration config)
|
private void CreateRenderElement(Marker marker, List<IRenderElement> elements, uint color,
|
||||||
|
MarkerConfiguration config)
|
||||||
{
|
{
|
||||||
if (!config.Show)
|
if (!config.Show)
|
||||||
return;
|
return;
|
||||||
@ -287,9 +310,11 @@ namespace Pal.Client.DependencyInjection
|
|||||||
marker.RenderElement = element;
|
marker.RenderElement = element;
|
||||||
elements.Add(element);
|
elements.Add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Up-/Download
|
#region Up-/Download
|
||||||
|
|
||||||
private async Task DownloadMarkersForTerritory(ushort territoryId)
|
private async Task DownloadMarkersForTerritory(ushort territoryId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -346,6 +371,7 @@ namespace Pal.Client.DependencyInjection
|
|||||||
_debugState.SetFromException(e);
|
_debugState.SetFromException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private IList<Marker> GetRelevantGameObjects()
|
private IList<Marker> GetRelevantGameObjects()
|
||||||
@ -388,5 +414,13 @@ namespace Pal.Client.DependencyInjection
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleQueued(IQueueOnFrameworkThread queued, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
Type handlerType = typeof(IQueueOnFrameworkThread.Handler<>).MakeGenericType(queued.GetType());
|
||||||
|
var handler = (IQueueOnFrameworkThread.IHandler)_serviceProvider.GetRequiredService(handlerType);
|
||||||
|
|
||||||
|
handler.RunIfCompatible(queued, ref recreateLayout, ref saveMarkers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,31 @@
|
|||||||
namespace Pal.Client.Scheduled
|
using Dalamud.Logging;
|
||||||
|
|
||||||
|
namespace Pal.Client.Scheduled
|
||||||
{
|
{
|
||||||
internal interface IQueueOnFrameworkThread
|
internal interface IQueueOnFrameworkThread
|
||||||
{
|
{
|
||||||
|
internal interface IHandler
|
||||||
|
{
|
||||||
|
void RunIfCompatible(IQueueOnFrameworkThread queued, ref bool recreateLayout, ref bool saveMarkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract class Handler<T> : IHandler
|
||||||
|
where T : IQueueOnFrameworkThread
|
||||||
|
{
|
||||||
|
protected abstract void Run(T queued, ref bool recreateLayout, ref bool saveMarkers);
|
||||||
|
|
||||||
|
public void RunIfCompatible(IQueueOnFrameworkThread queued, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
if (queued is T t)
|
||||||
|
{
|
||||||
|
PluginLog.Information($"Handling {queued.GetType()} with handler {GetType()}");
|
||||||
|
Run(t, ref recreateLayout, ref saveMarkers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PluginLog.Error($"Could not use queue handler {GetType()} with type {queued.GetType()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Dalamud.Game.Gui;
|
|
||||||
using Dalamud.Logging;
|
|
||||||
using Pal.Client.Configuration;
|
|
||||||
using Pal.Client.DependencyInjection;
|
|
||||||
using Pal.Client.Extensions;
|
|
||||||
using Pal.Client.Net;
|
|
||||||
using Pal.Client.Properties;
|
|
||||||
using Pal.Common;
|
|
||||||
|
|
||||||
namespace Pal.Client.Scheduled
|
|
||||||
{
|
|
||||||
// TODO The idea was to split this from the queue objects, should be in individual classes tho
|
|
||||||
internal sealed class QueueHandler
|
|
||||||
{
|
|
||||||
private readonly ConfigurationManager _configurationManager;
|
|
||||||
private readonly IPalacePalConfiguration _configuration;
|
|
||||||
private readonly FloorService _floorService;
|
|
||||||
private readonly TerritoryState _territoryState;
|
|
||||||
private readonly DebugState _debugState;
|
|
||||||
private readonly ChatGui _chatGui;
|
|
||||||
|
|
||||||
public QueueHandler(
|
|
||||||
ConfigurationManager configurationManager,
|
|
||||||
IPalacePalConfiguration configuration,
|
|
||||||
FloorService floorService,
|
|
||||||
TerritoryState territoryState,
|
|
||||||
DebugState debugState,
|
|
||||||
ChatGui chatGui)
|
|
||||||
{
|
|
||||||
_configurationManager = configurationManager;
|
|
||||||
_configuration = configuration;
|
|
||||||
_floorService = floorService;
|
|
||||||
_territoryState = territoryState;
|
|
||||||
_debugState = debugState;
|
|
||||||
_chatGui = chatGui;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(IQueueOnFrameworkThread queued, ref bool recreateLayout, ref bool saveMarkers)
|
|
||||||
{
|
|
||||||
if (queued is QueuedConfigUpdate)
|
|
||||||
{
|
|
||||||
ConfigUpdate(ref recreateLayout, ref saveMarkers);
|
|
||||||
}
|
|
||||||
else if (queued is QueuedSyncResponse queuedSyncResponse)
|
|
||||||
{
|
|
||||||
SyncResponse(queuedSyncResponse);
|
|
||||||
recreateLayout = true;
|
|
||||||
saveMarkers = true;
|
|
||||||
}
|
|
||||||
else if (queued is QueuedImport queuedImport)
|
|
||||||
{
|
|
||||||
Import(queuedImport);
|
|
||||||
recreateLayout = true;
|
|
||||||
saveMarkers = true;
|
|
||||||
}
|
|
||||||
else if (queued is QueuedUndoImport queuedUndoImport)
|
|
||||||
{
|
|
||||||
UndoImport(queuedUndoImport);
|
|
||||||
recreateLayout = true;
|
|
||||||
saveMarkers = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConfigUpdate(ref bool recreateLayout, ref bool saveMarkers)
|
|
||||||
{
|
|
||||||
if (_configuration.Mode == EMode.Offline)
|
|
||||||
{
|
|
||||||
LocalState.UpdateAll();
|
|
||||||
_floorService.FloorMarkers.Clear();
|
|
||||||
_floorService.EphemeralMarkers.Clear();
|
|
||||||
_territoryState.LastTerritory = 0;
|
|
||||||
|
|
||||||
recreateLayout = true;
|
|
||||||
saveMarkers = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SyncResponse(QueuedSyncResponse queued)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var remoteMarkers = queued.Markers;
|
|
||||||
var currentFloor = _floorService.GetFloorMarkers(queued.TerritoryType);
|
|
||||||
if (_configuration.Mode == EMode.Online && queued.Success && remoteMarkers.Count > 0)
|
|
||||||
{
|
|
||||||
switch (queued.Type)
|
|
||||||
{
|
|
||||||
case SyncType.Download:
|
|
||||||
case SyncType.Upload:
|
|
||||||
foreach (var remoteMarker in remoteMarkers)
|
|
||||||
{
|
|
||||||
// Both uploads and downloads return the network id to be set, but only the downloaded marker is new as in to-be-saved.
|
|
||||||
Marker? localMarker = currentFloor.Markers.SingleOrDefault(x => x == remoteMarker);
|
|
||||||
if (localMarker != null)
|
|
||||||
{
|
|
||||||
localMarker.NetworkId = remoteMarker.NetworkId;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queued.Type == SyncType.Download)
|
|
||||||
currentFloor.Markers.Add(remoteMarker);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SyncType.MarkSeen:
|
|
||||||
var partialAccountId =
|
|
||||||
_configuration.FindAccount(RemoteApi.RemoteUrl)?.AccountId.ToPartialId();
|
|
||||||
if (partialAccountId == null)
|
|
||||||
break;
|
|
||||||
foreach (var remoteMarker in remoteMarkers)
|
|
||||||
{
|
|
||||||
Marker? localMarker = currentFloor.Markers.SingleOrDefault(x => x == remoteMarker);
|
|
||||||
if (localMarker != null)
|
|
||||||
localMarker.RemoteSeenOn.Add(partialAccountId);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't modify state for outdated floors
|
|
||||||
if (_territoryState.LastTerritory != queued.TerritoryType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (queued.Type == SyncType.Download)
|
|
||||||
{
|
|
||||||
if (queued.Success)
|
|
||||||
_territoryState.TerritorySyncState = SyncState.Complete;
|
|
||||||
else
|
|
||||||
_territoryState.TerritorySyncState = SyncState.Failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_debugState.SetFromException(e);
|
|
||||||
if (queued.Type == SyncType.Download)
|
|
||||||
_territoryState.TerritorySyncState = SyncState.Failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Import(QueuedImport queued)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!queued.Validate(_chatGui))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var oldExportIds = string.IsNullOrEmpty(queued.Export.ServerUrl)
|
|
||||||
? _configuration.ImportHistory.Where(x => x.RemoteUrl == queued.Export.ServerUrl).Select(x => x.Id)
|
|
||||||
.Where(x => x != Guid.Empty).ToList()
|
|
||||||
: new List<Guid>();
|
|
||||||
|
|
||||||
foreach (var remoteFloor in queued.Export.Floors)
|
|
||||||
{
|
|
||||||
ushort territoryType = (ushort)remoteFloor.TerritoryType;
|
|
||||||
var localState = _floorService.GetFloorMarkers(territoryType);
|
|
||||||
|
|
||||||
localState.UndoImport(oldExportIds);
|
|
||||||
queued.ImportFloor(remoteFloor, localState);
|
|
||||||
|
|
||||||
localState.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
_configuration.ImportHistory.RemoveAll(hist =>
|
|
||||||
oldExportIds.Contains(hist.Id) || hist.Id == queued.ExportId);
|
|
||||||
_configuration.ImportHistory.Add(new ConfigurationV1.ImportHistoryEntry
|
|
||||||
{
|
|
||||||
Id = queued.ExportId,
|
|
||||||
RemoteUrl = queued.Export.ServerUrl,
|
|
||||||
ExportedAt = queued.Export.CreatedAt.ToDateTime(),
|
|
||||||
ImportedAt = DateTime.UtcNow,
|
|
||||||
});
|
|
||||||
_configurationManager.Save(_configuration);
|
|
||||||
|
|
||||||
_chatGui.Print(string.Format(Localization.ImportCompleteStatistics, queued.ImportedTraps,
|
|
||||||
queued.ImportedHoardCoffers));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
PluginLog.Error(e, "Import failed");
|
|
||||||
_chatGui.PalError(string.Format(Localization.Error_ImportFailed, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UndoImport(QueuedUndoImport queued)
|
|
||||||
{
|
|
||||||
foreach (ETerritoryType territoryType in typeof(ETerritoryType).GetEnumValues())
|
|
||||||
{
|
|
||||||
var localState = _floorService.GetFloorMarkers((ushort)territoryType);
|
|
||||||
localState.UndoImport(new List<Guid> { queued.ExportId });
|
|
||||||
localState.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
_configuration.ImportHistory.RemoveAll(hist => hist.Id == queued.ExportId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,37 @@
|
|||||||
namespace Pal.Client.Scheduled
|
using Pal.Client.Configuration;
|
||||||
|
using Pal.Client.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Pal.Client.Scheduled
|
||||||
{
|
{
|
||||||
internal sealed class QueuedConfigUpdate : IQueueOnFrameworkThread
|
internal sealed class QueuedConfigUpdate : IQueueOnFrameworkThread
|
||||||
{
|
{
|
||||||
|
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedConfigUpdate>
|
||||||
|
{
|
||||||
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
|
private readonly FloorService _floorService;
|
||||||
|
private readonly TerritoryState _territoryState;
|
||||||
|
|
||||||
|
public Handler(IPalacePalConfiguration configuration, FloorService floorService,
|
||||||
|
TerritoryState territoryState)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_floorService = floorService;
|
||||||
|
_territoryState = territoryState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Run(QueuedConfigUpdate queued, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
if (_configuration.Mode == EMode.Offline)
|
||||||
|
{
|
||||||
|
LocalState.UpdateAll();
|
||||||
|
_floorService.FloorMarkers.Clear();
|
||||||
|
_floorService.EphemeralMarkers.Clear();
|
||||||
|
_territoryState.LastTerritory = 0;
|
||||||
|
|
||||||
|
recreateLayout = true;
|
||||||
|
saveMarkers = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
using Account;
|
using Account;
|
||||||
using Pal.Common;
|
using Pal.Common;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
|
using Dalamud.Logging;
|
||||||
|
using Pal.Client.Configuration;
|
||||||
|
using Pal.Client.DependencyInjection;
|
||||||
|
using Pal.Client.Extensions;
|
||||||
using Pal.Client.Properties;
|
using Pal.Client.Properties;
|
||||||
|
|
||||||
namespace Pal.Client.Scheduled
|
namespace Pal.Client.Scheduled
|
||||||
{
|
{
|
||||||
internal sealed class QueuedImport : IQueueOnFrameworkThread
|
internal sealed class QueuedImport : IQueueOnFrameworkThread
|
||||||
{
|
{
|
||||||
public ExportRoot Export { get; }
|
private ExportRoot Export { get; }
|
||||||
public Guid ExportId { get; private set; }
|
private Guid ExportId { get; set; }
|
||||||
public int ImportedTraps { get; private set; }
|
private int ImportedTraps { get; set; }
|
||||||
public int ImportedHoardCoffers { get; private set; }
|
private int ImportedHoardCoffers { get; set; }
|
||||||
|
|
||||||
public QueuedImport(string sourcePath)
|
public QueuedImport(string sourcePath)
|
||||||
{
|
{
|
||||||
@ -22,35 +27,100 @@ namespace Pal.Client.Scheduled
|
|||||||
Export = ExportRoot.Parser.ParseFrom(input);
|
Export = ExportRoot.Parser.ParseFrom(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Validate(ChatGui chatGui)
|
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedImport>
|
||||||
{
|
{
|
||||||
if (Export.ExportVersion != ExportConfig.ExportVersion)
|
private readonly ChatGui _chatGui;
|
||||||
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
|
private readonly ConfigurationManager _configurationManager;
|
||||||
|
private readonly FloorService _floorService;
|
||||||
|
|
||||||
|
public Handler(ChatGui chatGui, IPalacePalConfiguration configuration,
|
||||||
|
ConfigurationManager configurationManager, FloorService floorService)
|
||||||
{
|
{
|
||||||
chatGui.PrintError(Localization.Error_ImportFailed_IncompatibleVersion);
|
_chatGui = chatGui;
|
||||||
|
_configuration = configuration;
|
||||||
|
_configurationManager = configurationManager;
|
||||||
|
_floorService = floorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Run(QueuedImport import, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
recreateLayout = true;
|
||||||
|
saveMarkers = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Validate(import))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var oldExportIds = string.IsNullOrEmpty(import.Export.ServerUrl)
|
||||||
|
? _configuration.ImportHistory.Where(x => x.RemoteUrl == import.Export.ServerUrl)
|
||||||
|
.Select(x => x.Id)
|
||||||
|
.Where(x => x != Guid.Empty).ToList()
|
||||||
|
: new List<Guid>();
|
||||||
|
|
||||||
|
foreach (var remoteFloor in import.Export.Floors)
|
||||||
|
{
|
||||||
|
ushort territoryType = (ushort)remoteFloor.TerritoryType;
|
||||||
|
var localState = _floorService.GetFloorMarkers(territoryType);
|
||||||
|
|
||||||
|
localState.UndoImport(oldExportIds);
|
||||||
|
ImportFloor(import, remoteFloor, localState);
|
||||||
|
|
||||||
|
localState.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
_configuration.ImportHistory.RemoveAll(hist =>
|
||||||
|
oldExportIds.Contains(hist.Id) || hist.Id == import.ExportId);
|
||||||
|
_configuration.ImportHistory.Add(new ConfigurationV1.ImportHistoryEntry
|
||||||
|
{
|
||||||
|
Id = import.ExportId,
|
||||||
|
RemoteUrl = import.Export.ServerUrl,
|
||||||
|
ExportedAt = import.Export.CreatedAt.ToDateTime(),
|
||||||
|
ImportedAt = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
_configurationManager.Save(_configuration);
|
||||||
|
|
||||||
|
_chatGui.Print(string.Format(Localization.ImportCompleteStatistics, import.ImportedTraps,
|
||||||
|
import.ImportedHoardCoffers));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
PluginLog.Error(e, "Import failed");
|
||||||
|
_chatGui.PalError(string.Format(Localization.Error_ImportFailed, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Validate(QueuedImport import)
|
||||||
|
{
|
||||||
|
if (import.Export.ExportVersion != ExportConfig.ExportVersion)
|
||||||
|
{
|
||||||
|
_chatGui.PrintError(Localization.Error_ImportFailed_IncompatibleVersion);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Guid.TryParse(Export.ExportId, out Guid exportId) || ExportId == Guid.Empty)
|
if (!Guid.TryParse(import.Export.ExportId, out Guid exportId) || import.ExportId == Guid.Empty)
|
||||||
{
|
{
|
||||||
chatGui.PrintError(Localization.Error_ImportFailed_InvalidFile);
|
_chatGui.PrintError(Localization.Error_ImportFailed_InvalidFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportId = exportId;
|
import.ExportId = exportId;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Export.ServerUrl))
|
if (string.IsNullOrEmpty(import.Export.ServerUrl))
|
||||||
{
|
{
|
||||||
// If we allow for backups as import/export, this should be removed
|
// If we allow for backups as import/export, this should be removed
|
||||||
chatGui.PrintError(Localization.Error_ImportFailed_InvalidFile);
|
_chatGui.PrintError(Localization.Error_ImportFailed_InvalidFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ImportFloor(ExportFloor remoteFloor, LocalState localState)
|
private void ImportFloor(QueuedImport import, ExportFloor remoteFloor, LocalState localState)
|
||||||
{
|
{
|
||||||
var remoteMarkers = remoteFloor.Objects.Select(m => new Marker((Marker.EType)m.Type, new Vector3(m.X, m.Y, m.Z)) { WasImported = true });
|
var remoteMarkers = remoteFloor.Objects.Select(m =>
|
||||||
|
new Marker((Marker.EType)m.Type, new Vector3(m.X, m.Y, m.Z)) { WasImported = true });
|
||||||
foreach (var remoteMarker in remoteMarkers)
|
foreach (var remoteMarker in remoteMarkers)
|
||||||
{
|
{
|
||||||
Marker? localMarker = localState.Markers.SingleOrDefault(x => x == remoteMarker);
|
Marker? localMarker = localState.Markers.SingleOrDefault(x => x == remoteMarker);
|
||||||
@ -60,12 +130,13 @@ namespace Pal.Client.Scheduled
|
|||||||
localMarker = remoteMarker;
|
localMarker = remoteMarker;
|
||||||
|
|
||||||
if (localMarker.Type == Marker.EType.Trap)
|
if (localMarker.Type == Marker.EType.Trap)
|
||||||
ImportedTraps++;
|
import.ImportedTraps++;
|
||||||
else if (localMarker.Type == Marker.EType.Hoard)
|
else if (localMarker.Type == Marker.EType.Hoard)
|
||||||
ImportedHoardCoffers++;
|
import.ImportedHoardCoffers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteMarker.Imports.Add(ExportId);
|
remoteMarker.Imports.Add(import.ExportId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Pal.Client.Configuration;
|
||||||
|
using Pal.Client.DependencyInjection;
|
||||||
|
using Pal.Client.Extensions;
|
||||||
|
using Pal.Client.Net;
|
||||||
|
|
||||||
namespace Pal.Client.Scheduled
|
namespace Pal.Client.Scheduled
|
||||||
{
|
{
|
||||||
@ -8,6 +14,89 @@ namespace Pal.Client.Scheduled
|
|||||||
public required ushort TerritoryType { get; init; }
|
public required ushort TerritoryType { get; init; }
|
||||||
public required bool Success { get; init; }
|
public required bool Success { get; init; }
|
||||||
public required List<Marker> Markers { get; init; }
|
public required List<Marker> Markers { get; init; }
|
||||||
|
|
||||||
|
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedSyncResponse>
|
||||||
|
{
|
||||||
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
|
private readonly FloorService _floorService;
|
||||||
|
private readonly TerritoryState _territoryState;
|
||||||
|
private readonly DebugState _debugState;
|
||||||
|
|
||||||
|
public Handler(IPalacePalConfiguration configuration, FloorService floorService, TerritoryState territoryState, DebugState debugState)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_floorService = floorService;
|
||||||
|
_territoryState = territoryState;
|
||||||
|
_debugState = debugState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Run(QueuedSyncResponse queued, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
recreateLayout = true;
|
||||||
|
saveMarkers = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var remoteMarkers = queued.Markers;
|
||||||
|
var currentFloor = _floorService.GetFloorMarkers(queued.TerritoryType);
|
||||||
|
if (_configuration.Mode == EMode.Online && queued.Success && remoteMarkers.Count > 0)
|
||||||
|
{
|
||||||
|
switch (queued.Type)
|
||||||
|
{
|
||||||
|
case SyncType.Download:
|
||||||
|
case SyncType.Upload:
|
||||||
|
foreach (var remoteMarker in remoteMarkers)
|
||||||
|
{
|
||||||
|
// Both uploads and downloads return the network id to be set, but only the downloaded marker is new as in to-be-saved.
|
||||||
|
Marker? localMarker = currentFloor.Markers.SingleOrDefault(x => x == remoteMarker);
|
||||||
|
if (localMarker != null)
|
||||||
|
{
|
||||||
|
localMarker.NetworkId = remoteMarker.NetworkId;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queued.Type == SyncType.Download)
|
||||||
|
currentFloor.Markers.Add(remoteMarker);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SyncType.MarkSeen:
|
||||||
|
var partialAccountId =
|
||||||
|
_configuration.FindAccount(RemoteApi.RemoteUrl)?.AccountId.ToPartialId();
|
||||||
|
if (partialAccountId == null)
|
||||||
|
break;
|
||||||
|
foreach (var remoteMarker in remoteMarkers)
|
||||||
|
{
|
||||||
|
Marker? localMarker = currentFloor.Markers.SingleOrDefault(x => x == remoteMarker);
|
||||||
|
if (localMarker != null)
|
||||||
|
localMarker.RemoteSeenOn.Add(partialAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't modify state for outdated floors
|
||||||
|
if (_territoryState.LastTerritory != queued.TerritoryType)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (queued.Type == SyncType.Download)
|
||||||
|
{
|
||||||
|
if (queued.Success)
|
||||||
|
_territoryState.TerritorySyncState = SyncState.Complete;
|
||||||
|
else
|
||||||
|
_territoryState.TerritorySyncState = SyncState.Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_debugState.SetFromException(e);
|
||||||
|
if (queued.Type == SyncType.Download)
|
||||||
|
_territoryState.TerritorySyncState = SyncState.Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SyncState
|
public enum SyncState
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Pal.Client.Configuration;
|
||||||
|
using Pal.Client.DependencyInjection;
|
||||||
|
using Pal.Common;
|
||||||
|
|
||||||
namespace Pal.Client.Scheduled
|
namespace Pal.Client.Scheduled
|
||||||
{
|
{
|
||||||
@ -9,6 +13,33 @@ namespace Pal.Client.Scheduled
|
|||||||
ExportId = exportId;
|
ExportId = exportId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid ExportId { get; }
|
private Guid ExportId { get; }
|
||||||
|
|
||||||
|
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedUndoImport>
|
||||||
|
{
|
||||||
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
|
private readonly FloorService _floorService;
|
||||||
|
|
||||||
|
public Handler(IPalacePalConfiguration configuration, FloorService floorService)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_floorService = floorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Run(QueuedUndoImport queued, ref bool recreateLayout, ref bool saveMarkers)
|
||||||
|
{
|
||||||
|
recreateLayout = true;
|
||||||
|
saveMarkers = true;
|
||||||
|
|
||||||
|
foreach (ETerritoryType territoryType in typeof(ETerritoryType).GetEnumValues())
|
||||||
|
{
|
||||||
|
var localState = _floorService.GetFloorMarkers((ushort)territoryType);
|
||||||
|
localState.UndoImport(new List<Guid> { queued.ExportId });
|
||||||
|
localState.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
_configuration.ImportHistory.RemoveAll(hist => hist.Id == queued.ExportId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user