2022-12-22 00:01:09 +00:00
|
|
|
|
using Account;
|
|
|
|
|
using Pal.Common;
|
|
|
|
|
using System;
|
2023-02-16 09:25:33 +00:00
|
|
|
|
using System.Collections.Generic;
|
2022-12-22 00:01:09 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Numerics;
|
2023-02-15 22:17:19 +00:00
|
|
|
|
using Dalamud.Game.Gui;
|
2023-02-16 09:25:33 +00:00
|
|
|
|
using Dalamud.Logging;
|
2023-02-16 23:54:23 +00:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2023-02-16 18:51:54 +00:00
|
|
|
|
using Pal.Client.Database;
|
2023-02-16 09:25:33 +00:00
|
|
|
|
using Pal.Client.DependencyInjection;
|
|
|
|
|
using Pal.Client.Extensions;
|
2023-02-10 19:48:14 +00:00
|
|
|
|
using Pal.Client.Properties;
|
2023-02-16 18:51:54 +00:00
|
|
|
|
using Pal.Client.Windows;
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
|
|
|
|
namespace Pal.Client.Scheduled
|
|
|
|
|
{
|
2023-02-15 22:17:19 +00:00
|
|
|
|
internal sealed class QueuedImport : IQueueOnFrameworkThread
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 09:25:33 +00:00
|
|
|
|
private ExportRoot Export { get; }
|
|
|
|
|
private Guid ExportId { get; set; }
|
|
|
|
|
private int ImportedTraps { get; set; }
|
|
|
|
|
private int ImportedHoardCoffers { get; set; }
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
|
|
|
|
public QueuedImport(string sourcePath)
|
|
|
|
|
{
|
2023-02-11 20:10:45 +00:00
|
|
|
|
using var input = File.OpenRead(sourcePath);
|
2023-02-15 22:17:19 +00:00
|
|
|
|
Export = ExportRoot.Parser.ParseFrom(input);
|
2022-12-22 00:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedImport>
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 09:25:33 +00:00
|
|
|
|
private readonly ChatGui _chatGui;
|
|
|
|
|
private readonly FloorService _floorService;
|
2023-02-16 18:51:54 +00:00
|
|
|
|
private readonly ImportService _importService;
|
|
|
|
|
private readonly ConfigWindow _configWindow;
|
|
|
|
|
|
|
|
|
|
public Handler(
|
2023-02-16 23:54:23 +00:00
|
|
|
|
ILogger<Handler> logger,
|
2023-02-16 18:51:54 +00:00
|
|
|
|
ChatGui chatGui,
|
|
|
|
|
FloorService floorService,
|
|
|
|
|
ImportService importService,
|
|
|
|
|
ConfigWindow configWindow)
|
2023-02-16 23:54:23 +00:00
|
|
|
|
: base(logger)
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 09:25:33 +00:00
|
|
|
|
_chatGui = chatGui;
|
|
|
|
|
_floorService = floorService;
|
2023-02-16 18:51:54 +00:00
|
|
|
|
_importService = importService;
|
|
|
|
|
_configWindow = configWindow;
|
2022-12-22 00:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
protected override void Run(QueuedImport import, ref bool recreateLayout, ref bool saveMarkers)
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 09:25:33 +00:00
|
|
|
|
recreateLayout = true;
|
|
|
|
|
saveMarkers = true;
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!Validate(import))
|
|
|
|
|
return;
|
2023-02-15 22:17:19 +00:00
|
|
|
|
|
2023-02-16 18:51:54 +00:00
|
|
|
|
List<Guid> oldExportIds = _importService.FindForServer(import.Export.ServerUrl)
|
|
|
|
|
.Select(x => x.Id)
|
|
|
|
|
.ToList();
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
foreach (var remoteFloor in import.Export.Floors)
|
|
|
|
|
{
|
|
|
|
|
ushort territoryType = (ushort)remoteFloor.TerritoryType;
|
|
|
|
|
var localState = _floorService.GetFloorMarkers(territoryType);
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
localState.UndoImport(oldExportIds);
|
|
|
|
|
ImportFloor(import, remoteFloor, localState);
|
|
|
|
|
|
|
|
|
|
localState.Save();
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 18:51:54 +00:00
|
|
|
|
_importService.RemoveAllByIds(oldExportIds);
|
|
|
|
|
_importService.RemoveById(import.ExportId);
|
|
|
|
|
_importService.Add(new ImportHistory
|
2023-02-16 09:25:33 +00:00
|
|
|
|
{
|
|
|
|
|
Id = import.ExportId,
|
|
|
|
|
RemoteUrl = import.Export.ServerUrl,
|
|
|
|
|
ExportedAt = import.Export.CreatedAt.ToDateTime(),
|
|
|
|
|
ImportedAt = DateTime.UtcNow,
|
|
|
|
|
});
|
2023-02-16 18:51:54 +00:00
|
|
|
|
_configWindow.UpdateLastImport();
|
2023-02-16 09:25:33 +00:00
|
|
|
|
|
2023-02-16 23:54:23 +00:00
|
|
|
|
_logger.LogInformation(
|
2023-02-16 18:51:54 +00:00
|
|
|
|
$"Imported {import.ExportId} for {import.ImportedTraps} traps, {import.ImportedHoardCoffers} hoard coffers");
|
2023-02-16 09:46:19 +00:00
|
|
|
|
_chatGui.PalMessage(string.Format(Localization.ImportCompleteStatistics, import.ImportedTraps,
|
2023-02-16 09:25:33 +00:00
|
|
|
|
import.ImportedHoardCoffers));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2023-02-16 23:54:23 +00:00
|
|
|
|
_logger.LogError(e, "Import failed");
|
2023-02-16 09:25:33 +00:00
|
|
|
|
_chatGui.PalError(string.Format(Localization.Error_ImportFailed, e));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool Validate(QueuedImport import)
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 09:25:33 +00:00
|
|
|
|
if (import.Export.ExportVersion != ExportConfig.ExportVersion)
|
2022-12-22 00:01:09 +00:00
|
|
|
|
{
|
2023-02-16 23:54:23 +00:00
|
|
|
|
_logger.LogError(
|
|
|
|
|
"Import: Different version in export file, {ExportVersion} != {ConfiguredVersion}", import.Export.ExportVersion, ExportConfig.ExportVersion);
|
2023-02-16 09:46:19 +00:00
|
|
|
|
_chatGui.PalError(Localization.Error_ImportFailed_IncompatibleVersion);
|
2023-02-16 09:25:33 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-12-22 00:01:09 +00:00
|
|
|
|
|
2023-02-16 18:51:54 +00:00
|
|
|
|
if (!Guid.TryParse(import.Export.ExportId, out Guid exportId) || exportId == Guid.Empty)
|
2023-02-16 09:25:33 +00:00
|
|
|
|
{
|
2023-02-16 23:54:23 +00:00
|
|
|
|
_logger.LogError("Import: Invalid export id '{Id}'", import.Export.ExportId);
|
2023-02-16 09:46:19 +00:00
|
|
|
|
_chatGui.PalError(Localization.Error_ImportFailed_InvalidFile);
|
2023-02-16 09:25:33 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
import.ExportId = exportId;
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(import.Export.ServerUrl))
|
|
|
|
|
{
|
|
|
|
|
// If we allow for backups as import/export, this should be removed
|
2023-02-16 23:54:23 +00:00
|
|
|
|
_logger.LogError("Import: No server URL");
|
2023-02-16 09:46:19 +00:00
|
|
|
|
_chatGui.PalError(Localization.Error_ImportFailed_InvalidFile);
|
2023-02-16 09:25:33 +00:00
|
|
|
|
return false;
|
2022-12-22 00:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 09:25:33 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 });
|
|
|
|
|
foreach (var remoteMarker in remoteMarkers)
|
|
|
|
|
{
|
|
|
|
|
Marker? localMarker = localState.Markers.SingleOrDefault(x => x == remoteMarker);
|
|
|
|
|
if (localMarker == null)
|
|
|
|
|
{
|
|
|
|
|
localState.Markers.Add(remoteMarker);
|
|
|
|
|
localMarker = remoteMarker;
|
|
|
|
|
|
|
|
|
|
if (localMarker.Type == Marker.EType.Trap)
|
|
|
|
|
import.ImportedTraps++;
|
|
|
|
|
else if (localMarker.Type == Marker.EType.Hoard)
|
|
|
|
|
import.ImportedHoardCoffers++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
remoteMarker.Imports.Add(import.ExportId);
|
|
|
|
|
}
|
2022-12-22 00:01:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|