Config/Db: Move V1 json layouts to legacy folders

This commit is contained in:
Liza 2023-02-17 16:30:20 +01:00
parent 870f29f0c6
commit 57a5be7938
6 changed files with 209 additions and 17 deletions

View File

@ -9,6 +9,7 @@ using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Configuration.Legacy;
using Pal.Client.Database; using Pal.Client.Database;
using NJson = Newtonsoft.Json; using NJson = Newtonsoft.Json;

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration
{ {
@ -17,10 +16,6 @@ namespace Pal.Client.Configuration
public RendererConfiguration Renderer { get; set; } = new(); public RendererConfiguration Renderer { get; set; } = new();
public List<AccountConfigurationV7> Accounts { get; set; } = new(); public List<AccountConfigurationV7> Accounts { get; set; } = new();
[JsonIgnore]
[Obsolete]
public List<ConfigurationV1.ImportHistoryEntry> ImportHistory { get; set; } = new();
public IAccountConfiguration CreateAccount(string server, Guid accountId) public IAccountConfiguration CreateAccount(string server, Guid accountId)
{ {
var account = new AccountConfigurationV7(server, accountId); var account = new AccountConfigurationV7(server, accountId);

View File

@ -1,6 +1,4 @@
using Dalamud.Logging; using System;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -8,8 +6,9 @@ using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Plugin; using Dalamud.Plugin;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration.Legacy
{ {
[Obsolete] [Obsolete]
public sealed class ConfigurationV1 public sealed class ConfigurationV1
@ -90,7 +89,7 @@ namespace Pal.Client.Configuration
// 2.2 had a bug that would mark chests as traps, there's no easy way to detect this -- or clean this up. // 2.2 had a bug that would mark chests as traps, there's no easy way to detect this -- or clean this up.
// Not a problem for online players, but offline players might be fucked. // Not a problem for online players, but offline players might be fucked.
//bool changedAnyFile = false; //bool changedAnyFile = false;
LocalState.ForEach(s => JsonFloorState.ForEach(s =>
{ {
foreach (var marker in s.Markers) foreach (var marker in s.Markers)
marker.SinceVersion = "0.0"; marker.SinceVersion = "0.0";
@ -100,7 +99,7 @@ namespace Pal.Client.Configuration
{ {
s.Backup(suffix: "bak"); s.Backup(suffix: "bak");
s.Markers = new ConcurrentBag<Marker>(s.Markers.Where(m => m.SinceVersion != "0.0" || m.Type == Marker.EType.Hoard || m.WasImported)); s.Markers = new ConcurrentBag<JsonMarker>(s.Markers.Where(m => m.SinceVersion != "0.0" || m.Type == JsonMarker.EType.Hoard || m.WasImported));
s.Save(); s.Save();
//changedAnyFile = true; //changedAnyFile = true;
@ -131,7 +130,7 @@ namespace Pal.Client.Configuration
if (Version == 5) if (Version == 5)
{ {
LocalState.UpdateAll(); JsonFloorState.UpdateAll();
Version = 6; Version = 6;
Save(pluginInterface); Save(pluginInterface);

View File

@ -0,0 +1,164 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using Pal.Client.Extensions;
using Pal.Common;
namespace Pal.Client.Configuration.Legacy
{
/// <summary>
/// Legacy JSON file for marker locations.
/// </summary>
[Obsolete]
public sealed class JsonFloorState
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new() { IncludeFields = true };
private const int CurrentVersion = 4;
private static string _pluginConfigDirectory;
private static EMode _mode = EMode.Online; // might not be true, but this is 'less strict filtering' for migrations
internal static void SetContextProperties(string pluginConfigDirectory)
{
_pluginConfigDirectory = pluginConfigDirectory;
}
public uint TerritoryType { get; set; }
public ConcurrentBag<JsonMarker> Markers { get; set; } = new();
public JsonFloorState(uint territoryType)
{
TerritoryType = territoryType;
}
private void ApplyFilters()
{
if (_mode == EMode.Offline)
Markers = new ConcurrentBag<JsonMarker>(Markers.Where(x => x.Seen || (x.WasImported && x.Imports.Count > 0)));
else
// ensure old import markers are removed if they are no longer part of a "current" import
// this MAY remove markers the server sent you (and that you haven't seen), but this should be fixed the next time you enter the zone
Markers = new ConcurrentBag<JsonMarker>(Markers.Where(x => x.Seen || !x.WasImported || x.Imports.Count > 0));
}
public static JsonFloorState? Load(uint territoryType)
{
string path = GetSaveLocation(territoryType);
if (!File.Exists(path))
return null;
string content = File.ReadAllText(path);
if (content.Length == 0)
return null;
JsonFloorState localState;
int version = 1;
if (content[0] == '[')
{
// v1 only had a list of markers, not a JSON object as root
localState = new JsonFloorState(territoryType)
{
Markers = new ConcurrentBag<JsonMarker>(JsonSerializer.Deserialize<HashSet<JsonMarker>>(content, JsonSerializerOptions) ?? new()),
};
}
else
{
var save = JsonSerializer.Deserialize<SaveFile>(content, JsonSerializerOptions);
if (save == null)
return null;
localState = new JsonFloorState(territoryType)
{
Markers = new ConcurrentBag<JsonMarker>(save.Markers.Where(o => o.Type == JsonMarker.EType.Trap || o.Type == JsonMarker.EType.Hoard)),
};
version = save.Version;
}
localState.ApplyFilters();
if (version <= 3)
{
foreach (var marker in localState.Markers)
marker.RemoteSeenOn = marker.RemoteSeenOn.Select(x => x.ToPartialId()).ToList();
}
if (version < CurrentVersion)
localState.Save();
return localState;
}
public void Save()
{
string path = GetSaveLocation(TerritoryType);
ApplyFilters();
SaveImpl(path);
}
public void Backup(string suffix)
{
string path = $"{GetSaveLocation(TerritoryType)}.{suffix}";
if (!File.Exists(path))
{
SaveImpl(path);
}
}
private void SaveImpl(string path)
{
foreach (var marker in Markers)
{
if (string.IsNullOrEmpty(marker.SinceVersion))
marker.SinceVersion = typeof(Plugin).Assembly.GetName().Version!.ToString(2);
}
if (Markers.Count == 0)
File.Delete(path);
else
{
File.WriteAllText(path, JsonSerializer.Serialize(new SaveFile
{
Version = CurrentVersion,
Markers = new HashSet<JsonMarker>(Markers)
}, JsonSerializerOptions));
}
}
public string GetSaveLocation() => GetSaveLocation(TerritoryType);
private static string GetSaveLocation(uint territoryType) => Path.Join(_pluginConfigDirectory, $"{territoryType}.json");
public static void ForEach(Action<JsonFloorState> action)
{
foreach (ETerritoryType territory in typeof(ETerritoryType).GetEnumValues())
{
JsonFloorState? localState = Load((ushort)territory);
if (localState != null)
action(localState);
}
}
public static void UpdateAll()
{
ForEach(s => s.Save());
}
public void UndoImport(List<Guid> importIds)
{
// When saving a floor state, any markers not seen, not remote seen, and not having an import id are removed;
// so it is possible to remove "wrong" markers by not having them be in the current import.
foreach (var marker in Markers)
marker.Imports.RemoveAll(importIds.Contains);
}
public sealed class SaveFile
{
public int Version { get; set; }
public HashSet<JsonMarker> Markers { get; set; } = new();
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Pal.Client.Configuration.Legacy
{
[Obsolete]
public class JsonMarker
{
public EType Type { get; set; } = EType.Unknown;
public Vector3 Position { get; set; }
public bool Seen { get; set; }
public List<string> RemoteSeenOn { get; set; } = new();
public List<Guid> Imports { get; set; } = new();
public bool WasImported { get; set; }
public string? SinceVersion { get; set; }
public enum EType
{
Unknown = 0,
Trap = 1,
Hoard = 2,
Debug = 3,
}
}
}

View File

@ -19,6 +19,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Commands; using Pal.Client.Commands;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Configuration.Legacy;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.DependencyInjection.Logging; using Pal.Client.DependencyInjection.Logging;
@ -39,7 +40,11 @@ namespace Pal.Client
{ {
public static DalamudLoggerProvider LoggerProvider { get; } = new(); public static DalamudLoggerProvider LoggerProvider { get; } = new();
/// <summary>
/// Initialized as temporary logger, will be overriden once context is ready with a logger that supports scopes.
/// </summary>
private readonly ILogger _logger = LoggerProvider.CreateLogger<DependencyInjectionContext>(); private readonly ILogger _logger = LoggerProvider.CreateLogger<DependencyInjectionContext>();
private readonly string _sqliteConnectionString; private readonly string _sqliteConnectionString;
private readonly CancellationTokenSource _initCts = new(); private readonly CancellationTokenSource _initCts = new();
private ServiceProvider? _serviceProvider; private ServiceProvider? _serviceProvider;
@ -56,9 +61,14 @@ namespace Pal.Client
CommandManager commandManager, CommandManager commandManager,
DataManager dataManager) DataManager dataManager)
{ {
// Temporary logger, will be overriden later
_logger.LogInformation("Building service container"); _logger.LogInformation("Building service container");
// set up legacy services
#pragma warning disable CS0612
JsonFloorState.SetContextProperties(pluginInterface.GetPluginConfigDirectory());
#pragma warning restore CS0612
// set up logging
CancellationToken token = _initCts.Token; CancellationToken token = _initCts.Token;
IServiceCollection services = new ServiceCollection(); IServiceCollection services = new ServiceCollection();
services.AddLogging(builder => services.AddLogging(builder =>
@ -67,6 +77,7 @@ namespace Pal.Client
.AddFilter("Grpc", LogLevel.Debug) .AddFilter("Grpc", LogLevel.Debug)
.ClearProviders() .ClearProviders()
.AddProvider(LoggerProvider)); .AddProvider(LoggerProvider));
// dalamud // dalamud
services.AddSingleton<IDalamudPlugin>(this); services.AddSingleton<IDalamudPlugin>(this);
services.AddSingleton(pluginInterface); services.AddSingleton(pluginInterface);
@ -171,10 +182,6 @@ namespace Pal.Client
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
// set up legacy services
LocalState.PluginConfigDirectory = pluginInterface.GetPluginConfigDirectory();
LocalState.Mode = _serviceProvider.GetRequiredService<IPalacePalConfiguration>().Mode;
// windows that have logic to open on startup // windows that have logic to open on startup
_serviceProvider.GetRequiredService<AgreementWindow>(); _serviceProvider.GetRequiredService<AgreementWindow>();