First config implementation

This commit is contained in:
Zeffuro
2025-12-21 11:01:12 +01:00
parent f5044e707b
commit f8fbd4a476
9 changed files with 275 additions and 4 deletions
@@ -0,0 +1,11 @@
using System.Numerics;
using KamiToolKit.Classes;
namespace AetherBags.Configuration;
public class CurrencySettings
{
public Vector4 DefaultColor { get; set; } = ColorHelper.GetColor(8);
public Vector4 CappedColor { get; set; } = ColorHelper.GetColor(43);
public Vector4 LimitColor { get; set; } = ColorHelper.GetColor(17);
}
@@ -0,0 +1,11 @@
using System.Numerics;
using KamiToolKit.Classes;
namespace AetherBags.Configuration;
public class SystemConfiguration
{
public const string FileName = "AetherBags.json";
public CurrencySettings Currency { get; set; } = new();
}
+70
View File
@@ -0,0 +1,70 @@
using System;
using System.IO;
using System.Text.Json;
using Dalamud.Utility;
namespace AetherBags.Helpers;
public static class FileHelpers {
private static readonly JsonSerializerOptions SerializerOptions = new() {
WriteIndented = true,
IncludeFields = true,
};
public static T LoadFile<T>(string filePath) where T : new() {
var fileInfo = new FileInfo(filePath);
if (fileInfo is { Exists: true }) {
try {
var fileText = File.ReadAllText(fileInfo.FullName);
var dataObject = JsonSerializer.Deserialize<T>(fileText, SerializerOptions);
// If deserialize result is null, create a new instance instead and save it.
if (dataObject is null) {
dataObject = new T();
SaveFile(dataObject, filePath);
}
return dataObject;
}
catch (Exception e) {
// If there is any kind of error loading the file, generate a new one instead and save it.
Services.Logger.Error(e, $"Error trying to load file {filePath}, creating a new one instead.");
SaveFile(new T(), filePath);
}
}
var newFile = new T();
SaveFile(newFile, filePath);
return newFile;
}
public static void SaveFile<T>(T? file, string filePath) {
try {
if (file is null) {
Services.Logger.Error("Null file provided.");
return;
}
var fileText = JsonSerializer.Serialize(file, file.GetType(), SerializerOptions);
FilesystemUtil.WriteAllTextSafe(filePath, fileText);
}
catch (Exception e) {
Services.Logger.Error(e, $"Error trying to save file {filePath}");
}
}
public static FileInfo GetFileInfo(params string[] path) {
var directory = Services.PluginInterface.ConfigDirectory;
for (var index = 0; index < path.Length - 1; index++) {
directory = new DirectoryInfo(Path.Combine(directory.FullName, path[index]));
if (!directory.Exists) {
directory.Create();
}
}
return new FileInfo(Path.Combine(directory.FullName, path[^1]));
}
}
@@ -0,0 +1,65 @@
using System.Linq;
using AetherBags.Configuration;
using Dalamud.Bindings.ImGui;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Interface.ImGuiNotification;
namespace AetherBags.Helpers;
public abstract class ImportExportResetHelper {
public static void TryImportConfigFromClipboard(SystemConfiguration currentOverlayConfig)
{
if (!Services.KeyState[VirtualKey.SHIFT])
return;
var clipboard = ImGui.GetClipboardText();
var notification = new Notification { Content = "Configuration imported from clipboard.", Type = NotificationType.Success };
if (!string.IsNullOrWhiteSpace(clipboard))
{
var imported = Util.DeserializeConfig(clipboard);
if (imported != null)
{
System.Config = imported;
Util.SaveConfig(System.Config);
Services.Logger.Info("Configuration imported from clipboard.");
}
else
{
notification.Content = "Clipboard data was invalid or could not be imported.";
notification.Type = NotificationType.Error;
Services.Logger.Warning("Clipboard data was invalid or could not be imported.");
}
}
else
{
notification.Content = "Clipboard is empty or invalid for import.";
notification.Type = NotificationType.Warning;
Services.Logger.Warning("Clipboard is empty or invalid for import.");
}
Services.NotificationManager.AddNotification(notification);
}
public static void TryExportConfigToClipboard(
SystemConfiguration config)
{
var exportString = Util.SerializeConfig(config);
ImGui.SetClipboardText(exportString);
Services.NotificationManager.AddNotification(
new Notification { Content = "Configuration exported to clipboard.", Type = NotificationType.Success }
);
Services.Logger.Info("Configuration exported to clipboard.");
}
public static void TryResetConfig()
{
System.Config = Util.ResetConfig();
Util.SaveConfig(System.Config);
Services.NotificationManager.AddNotification(
new Notification { Content = "Configuration reset to default.", Type = NotificationType.Success }
);
Services.Logger.Info("Configuration reset to default.");
}
}
+92
View File
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using AetherBags.Configuration;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace AetherBags.Helpers;
public static class Util
{
private static readonly JsonSerializerOptions ConfigJsonOptions = new()
{
WriteIndented = true,
IncludeFields = true,
PropertyNameCaseInsensitive = true,
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
public static string SerializeUIntSet(HashSet<uint> set)
=> string.Join(",", set.OrderBy(x => x));
public static HashSet<uint> DeserializeUIntSet(string data)
=> data
.Split([','], StringSplitOptions.RemoveEmptyEntries)
.Select(s => uint.TryParse(s, out var val) ? val : (uint?)null)
.Where(v => v.HasValue)
.Select(v => v!.Value)
.ToHashSet();
private static string CompressToBase64(string str)
=> Convert.ToBase64String(Dalamud.Utility.Util.CompressString(str));
private static string DecompressFromBase64(string base64)
=> Dalamud.Utility.Util.DecompressString(Convert.FromBase64String(base64));
public static string SerializeHashSet(HashSet<uint> hashSet)
=> CompressToBase64(SerializeUIntSet(hashSet));
public static HashSet<uint> DeserializeHashSet(string input)
{
try
{
return DeserializeUIntSet(DecompressFromBase64(input));
}
catch
{
return new HashSet<uint>();
}
}
public static string SerializeConfig(SystemConfiguration config)
{
var json = JsonSerializer.Serialize(config, ConfigJsonOptions);
return CompressToBase64(json);
}
public static SystemConfiguration? DeserializeConfig(string input)
{
try
{
var json = DecompressFromBase64(input);
return JsonSerializer.Deserialize<SystemConfiguration>(json, ConfigJsonOptions);
}
catch
{
return null;
}
}
public static void SaveConfig(SystemConfiguration config)
{
FileInfo file = FileHelpers.GetFileInfo(SystemConfiguration.FileName);
FileHelpers.SaveFile(config, file.FullName);
}
private static SystemConfiguration LoadConfig()
{
FileInfo file = FileHelpers.GetFileInfo(SystemConfiguration.FileName);
return FileHelpers.LoadFile<SystemConfiguration>(file.FullName);
}
public static SystemConfiguration LoadConfigOrDefault()
=> LoadConfig() ?? new SystemConfiguration();
public static SystemConfiguration ResetConfig()
=> new SystemConfiguration();
}
+4 -3
View File
@@ -44,10 +44,11 @@ public class CurrencyNode : SimpleComponentNode
_countNode.Position = new Vector2(_iconImageNode.Bounds.Right + 2f, 0f);
// Limit > Capped > Normal
var config = System.Config.Currency;
_countNode.TextColor =
value.LimitReached ? ColorHelper.GetColor(17) :
value.IsCapped ? ColorHelper.GetColor(43) :
ColorHelper.GetColor(8);
value.LimitReached ? config.LimitColor :
value.IsCapped ? config.CappedColor :
config.DefaultColor;
}
}
}
+17 -1
View File
@@ -1,5 +1,6 @@
using System.Numerics;
using AetherBags.Addons;
using AetherBags.Configuration;
using AetherBags.Helpers;
using Dalamud.Plugin;
using Dalamud.Game.Command;
@@ -18,6 +19,8 @@ public class Plugin : IDalamudPlugin
KamiToolKitLibrary.Initialize(pluginInterface);
System.Config = Util.LoadConfigOrDefault();
System.AddonInventoryWindow = new AddonInventoryWindow
{
InternalName = "AetherBags",
@@ -38,6 +41,7 @@ public class Plugin : IDalamudPlugin
HelpMessage = HelpDescription
});
Services.ClientState.Login += OnLogin;
Services.ClientState.Logout += OnLogout;
if (Services.ClientState.IsLoggedIn) {
Services.Framework.RunOnFrameworkThread(OnLogin);
@@ -46,7 +50,10 @@ public class Plugin : IDalamudPlugin
public void Dispose()
{
Util.SaveConfig(System.Config);
Services.ClientState.Login -= OnLogin;
Services.ClientState.Logout -= OnLogout;
Services.CommandManager.RemoveHandler("/aetherbags");
Services.CommandManager.RemoveHandler("/ab");
@@ -70,9 +77,18 @@ public class Plugin : IDalamudPlugin
}
}
private void OnLogin() {
private void OnLogin()
{
System.Config = Util.LoadConfigOrDefault();
#if DEBUG
System.AddonInventoryWindow.Toggle();
#endif
}
private void OnLogout(int type, int code)
{
Util.SaveConfig(System.Config);
System.AddonInventoryWindow.Close();
}
}
+3
View File
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
@@ -12,5 +13,7 @@ public class Services
[PluginService] public static IDataManager DataManager { get; set; } = null!;
[PluginService] public static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService] public static IFramework Framework { get; private set; } = null!;
[PluginService] public static IKeyState KeyState { get; private set; } = null!;
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
[PluginService] public static INotificationManager NotificationManager { get; private set; } = null!;
}
+2
View File
@@ -1,8 +1,10 @@
using AetherBags.Addons;
using AetherBags.Configuration;
namespace AetherBags;
public static class System
{
public static AddonInventoryWindow AddonInventoryWindow { get; set; } = null!;
public static SystemConfiguration Config { get; set; } = null!;
}