Allow for SortaKinda imports
This commit is contained in:
@@ -106,6 +106,12 @@ public class AddonInventoryWindow : NativeAddon
|
||||
base.OnUpdate(addon);
|
||||
}
|
||||
|
||||
public void ManualRefresh()
|
||||
{
|
||||
InventoryState.RefreshFromGame();
|
||||
RefreshCategoriesCore(true);
|
||||
}
|
||||
|
||||
private void OnInventoryUpdate(AddonEvent type, AddonArgs args)
|
||||
{
|
||||
InventoryState.RefreshFromGame();
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Configuration.Import;
|
||||
|
||||
namespace AetherBags.Helpers.Import;
|
||||
|
||||
public static class SortaKindaImportExport
|
||||
{
|
||||
private static readonly JsonSerializerOptions ExternalJsonOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
AllowTrailingCommas = true,
|
||||
WriteIndented = true,
|
||||
IncludeFields = true
|
||||
};
|
||||
|
||||
public static bool TryImportFromClipboard(
|
||||
SystemConfiguration targetConfig,
|
||||
bool replaceExisting,
|
||||
out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
string clipboard;
|
||||
try
|
||||
{
|
||||
clipboard = Dalamud.Bindings.ImGui.ImGui.GetClipboardText();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = $"Failed to read clipboard: {ex.Message}";
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryImportFromJson(clipboard, targetConfig, replaceExisting, out error);
|
||||
}
|
||||
|
||||
public static bool TryImportFromJson(
|
||||
string input,
|
||||
SystemConfiguration targetConfig,
|
||||
bool replaceExisting,
|
||||
out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
error = "Input was empty.";
|
||||
return false;
|
||||
}
|
||||
|
||||
var external = Util.DeserializeCompressed<SortaKindaCategory[]>(input.Trim(), ExternalJsonOptions);
|
||||
|
||||
if (external is null)
|
||||
{
|
||||
error = "Failed to parse SortaKinda input.";
|
||||
return false;
|
||||
}
|
||||
|
||||
var mapped = external
|
||||
.Select(MapToUserCategory)
|
||||
.OrderBy(c => c.Order)
|
||||
.ToList();
|
||||
|
||||
var dest = targetConfig.Categories.UserCategories;
|
||||
|
||||
if (replaceExisting)
|
||||
{
|
||||
dest.Clear();
|
||||
dest.AddRange(mapped);
|
||||
}
|
||||
else
|
||||
{
|
||||
var byId = dest
|
||||
.Where(c => !string.IsNullOrWhiteSpace(c.Id))
|
||||
.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var incoming in mapped)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(incoming.Id) && byId.TryGetValue(incoming.Id, out var existing))
|
||||
{
|
||||
existing.Name = incoming.Name;
|
||||
existing.Description = incoming.Description;
|
||||
existing.Order = incoming.Order;
|
||||
existing.Priority = incoming.Priority;
|
||||
existing.Color = incoming.Color;
|
||||
existing.Rules = incoming.Rules;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.Add(incoming);
|
||||
if (!string.IsNullOrWhiteSpace(incoming.Id))
|
||||
byId[incoming.Id] = incoming;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetConfig.Categories.UserCategoriesEnabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string ExportToJson(SystemConfiguration sourceConfig)
|
||||
{
|
||||
var exported = sourceConfig.Categories.UserCategories
|
||||
.OrderBy(c => c.Order)
|
||||
.Select(MapToExternal)
|
||||
.ToArray();
|
||||
|
||||
return Util.SerializeCompressed(exported, ExternalJsonOptions);
|
||||
}
|
||||
|
||||
public static void ExportToClipboard(SystemConfiguration sourceConfig)
|
||||
=> Dalamud.Bindings.ImGui.ImGui.SetClipboardText(ExportToJson(sourceConfig));
|
||||
|
||||
private static UserCategoryDefinition MapToUserCategory(SortaKindaCategory external)
|
||||
=> new()
|
||||
{
|
||||
Id = string.IsNullOrWhiteSpace(external.Id) ? Guid.NewGuid().ToString("N") : external.Id,
|
||||
Name = external.Name,
|
||||
Description = string.Empty,
|
||||
Order = external.Index,
|
||||
Priority = 100,
|
||||
Color = external.Color,
|
||||
Rules = new CategoryRuleSet
|
||||
{
|
||||
AllowedItemIds = new List<uint>(),
|
||||
AllowedItemNamePatterns = external.AllowedItemNames?.ToList() ?? new List<string>(),
|
||||
AllowedUiCategoryIds = external.AllowedItemTypes?.ToList() ?? new List<uint>(),
|
||||
AllowedRarities = external.AllowedItemRarities?.ToList() ?? new List<int>(),
|
||||
ItemLevel = new RangeFilter<int>
|
||||
{
|
||||
Enabled = external.ItemLevelFilter?.Enable ?? false,
|
||||
Min = external.ItemLevelFilter?.MinValue ?? 0,
|
||||
Max = external.ItemLevelFilter?.MaxValue ?? 2000,
|
||||
},
|
||||
VendorPrice = new RangeFilter<uint>
|
||||
{
|
||||
Enabled = external.VendorPriceFilter?.Enable ?? false,
|
||||
Min = external.VendorPriceFilter?.MinValue ?? 0u,
|
||||
Max = external.VendorPriceFilter?.MaxValue ?? 9_999_999u,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static SortaKindaCategory MapToExternal(UserCategoryDefinition internalCat)
|
||||
=> new()
|
||||
{
|
||||
Color = internalCat.Color,
|
||||
Id = internalCat.Id,
|
||||
Name = internalCat.Name,
|
||||
Index = internalCat.Order,
|
||||
AllowedItemNames = internalCat.Rules.AllowedItemNamePatterns?.ToList() ?? new List<string>(),
|
||||
AllowedItemTypes = internalCat.Rules.AllowedUiCategoryIds?.ToList() ?? new List<uint>(),
|
||||
AllowedItemRarities = internalCat.Rules.AllowedRarities?.ToList() ?? new List<int>(),
|
||||
ItemLevelFilter = new ExternalRangeFilterDto<int>
|
||||
{
|
||||
Enable = internalCat.Rules.ItemLevel.Enabled,
|
||||
Label = "Item Level Filter",
|
||||
MinValue = internalCat.Rules.ItemLevel.Min,
|
||||
MaxValue = internalCat.Rules.ItemLevel.Max
|
||||
},
|
||||
VendorPriceFilter = new ExternalRangeFilterDto<uint>
|
||||
{
|
||||
Enable = internalCat.Rules.VendorPrice.Enabled,
|
||||
Label = "Vendor Price Filter",
|
||||
MinValue = internalCat.Rules.VendorPrice.Min,
|
||||
MaxValue = internalCat.Rules.VendorPrice.Max
|
||||
},
|
||||
Direction = 0,
|
||||
FillMode = 0,
|
||||
SortMode = 0
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Helpers.Import;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
@@ -62,4 +63,35 @@ public abstract class ImportExportResetHelper {
|
||||
);
|
||||
Services.Logger.Info("Configuration reset to default.");
|
||||
}
|
||||
|
||||
public static void TryImportSortaKindaFromClipboard(bool replaceExisting)
|
||||
{
|
||||
//if (!Services.KeyState[VirtualKey.SHIFT])
|
||||
// return;
|
||||
|
||||
var notification = new Notification { Content = "SortaKinda categories imported.", Type = NotificationType.Success };
|
||||
|
||||
if (!SortaKindaImportExport.TryImportFromClipboard(System.Config, replaceExisting, out var error))
|
||||
{
|
||||
notification.Content = error;
|
||||
notification.Type = NotificationType.Error;
|
||||
Services.Logger.Warning(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
Util.SaveConfig(System.Config);
|
||||
Services.Logger.Info("SortaKinda categories imported from clipboard.");
|
||||
}
|
||||
|
||||
Services.NotificationManager.AddNotification(notification);
|
||||
}
|
||||
|
||||
public static void TryExportSortaKindaToClipboard()
|
||||
{
|
||||
SortaKindaImportExport.ExportToClipboard(System.Config);
|
||||
Services.NotificationManager.AddNotification(
|
||||
new Notification { Content = "SortaKinda JSON exported to clipboard.", Type = NotificationType.Success }
|
||||
);
|
||||
Services.Logger.Info("SortaKinda JSON exported to clipboard.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,25 +53,31 @@ public static class Util
|
||||
}
|
||||
}
|
||||
|
||||
public static string SerializeConfig(SystemConfiguration config)
|
||||
public static string SerializeCompressed<T>(T value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(config, ConfigJsonOptions);
|
||||
var json = JsonSerializer.Serialize(value, options ?? ConfigJsonOptions);
|
||||
return CompressToBase64(json);
|
||||
}
|
||||
|
||||
public static SystemConfiguration? DeserializeConfig(string input)
|
||||
public static T? DeserializeCompressed<T>(string input, JsonSerializerOptions? options = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = DecompressFromBase64(input);
|
||||
return JsonSerializer.Deserialize<SystemConfiguration>(json, ConfigJsonOptions);
|
||||
return JsonSerializer.Deserialize<T>(json, options ?? ConfigJsonOptions);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static string SerializeConfig(SystemConfiguration config)
|
||||
=> SerializeCompressed(config, ConfigJsonOptions);
|
||||
|
||||
public static SystemConfiguration? DeserializeConfig(string input)
|
||||
=> DeserializeCompressed<SystemConfiguration>(input, ConfigJsonOptions);
|
||||
|
||||
public static void SaveConfig(SystemConfiguration config)
|
||||
{
|
||||
FileInfo file = FileHelpers.GetFileInfo(SystemConfiguration.FileName);
|
||||
|
||||
@@ -73,6 +73,12 @@ public class Plugin : IDalamudPlugin
|
||||
System.AddonInventoryWindow.Toggle();
|
||||
if(args == "config")
|
||||
System.AddonInventoryWindow.Toggle();
|
||||
if (args == "import-sk")
|
||||
{
|
||||
// Manually import from SortaKinda for testing until we have a proper config window
|
||||
ImportExportResetHelper.TryImportSortaKindaFromClipboard(true);
|
||||
System.AddonInventoryWindow.ManualRefresh();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user