208 lines
6.6 KiB
C#
208 lines
6.6 KiB
C#
using System;
|
||
using System.IO;
|
||
using YamlDotNet.Serialization;
|
||
using YamlDotNet.Serialization.NamingConventions;
|
||
using Decal.Adapter;
|
||
|
||
namespace MosswartMassacre
|
||
{
|
||
public class PluginSettings
|
||
{
|
||
private static PluginSettings _instance;
|
||
private static string _filePath;
|
||
private static readonly object _sync = new object();
|
||
|
||
// backing fields
|
||
private bool _remoteCommandsEnabled = false;
|
||
private bool _rareMetaEnabled = true;
|
||
private bool _httpServerEnabled = false;
|
||
private bool _telemetryEnabled = false;
|
||
private bool _webSocketEnabled = false;
|
||
private bool _inventorylog = true;
|
||
private string _charTag = "default";
|
||
private int _mainWindowX = 100;
|
||
private int _mainWindowY = 100;
|
||
private bool _useTabbedInterface = true;
|
||
private string _vtankProfilesPath = "";
|
||
private bool _verboseLogging = false;
|
||
|
||
public static PluginSettings Instance => _instance
|
||
?? throw new InvalidOperationException("PluginSettings not initialized");
|
||
|
||
public static void Initialize()
|
||
{
|
||
// determine plugin folder and character-specific folder
|
||
string characterName = CoreManager.Current.CharacterFilter.Name;
|
||
|
||
// For hot reload scenarios, use the AssemblyDirectory set by the Loader
|
||
// For normal loading, fall back to the executing assembly location
|
||
string pluginFolder;
|
||
if (!string.IsNullOrEmpty(PluginCore.AssemblyDirectory))
|
||
{
|
||
pluginFolder = PluginCore.AssemblyDirectory;
|
||
}
|
||
else
|
||
{
|
||
pluginFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
||
}
|
||
|
||
// Path for character-specific folder
|
||
string characterFolder = Path.Combine(pluginFolder, characterName);
|
||
|
||
// Create the character folder if it doesn't exist
|
||
if (!Directory.Exists(characterFolder))
|
||
{
|
||
try
|
||
{
|
||
Directory.CreateDirectory(characterFolder);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
PluginCore.DispatchChatToBoxWithPluginIntercept($"[Settings] Failed to create character folder: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// YAML file is now in the character-specific folder
|
||
_filePath = Path.Combine(characterFolder, $"{characterName}.yaml");
|
||
|
||
// build serializer/deserializer once
|
||
var builder = new DeserializerBuilder()
|
||
.WithNamingConvention(UnderscoredNamingConvention.Instance);
|
||
var deserializer = builder.Build();
|
||
|
||
PluginSettings loaded = null;
|
||
|
||
if (File.Exists(_filePath))
|
||
{
|
||
try
|
||
{
|
||
string yaml = File.ReadAllText(_filePath);
|
||
loaded = deserializer.Deserialize<PluginSettings>(yaml);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
PluginCore.DispatchChatToBoxWithPluginIntercept(
|
||
$"[MosswartMassacre] Error reading settings, using defaults: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
if (loaded == null)
|
||
{
|
||
// either file didn't exist, was empty, or deserialized as null
|
||
_instance = new PluginSettings();
|
||
Save(); // write out default skeleton
|
||
}
|
||
else
|
||
{
|
||
_instance = loaded;
|
||
Save();
|
||
}
|
||
}
|
||
|
||
public static void Save()
|
||
{
|
||
lock (_sync)
|
||
{
|
||
try
|
||
{
|
||
// serialize to YAML
|
||
var serializer = new SerializerBuilder()
|
||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||
.Build();
|
||
var yaml = serializer.Serialize(_instance);
|
||
|
||
// write temp file
|
||
var temp = _filePath + ".tmp";
|
||
File.WriteAllText(temp, yaml);
|
||
|
||
// if the settings file already exists, do an atomic Replace
|
||
if (File.Exists(_filePath))
|
||
{
|
||
File.Replace(temp, _filePath, null);
|
||
}
|
||
else
|
||
{
|
||
// first‐time save: just move the temp into place
|
||
File.Move(temp, _filePath);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// log to chat so you can see what went wrong
|
||
CoreManager.Current.Actions.AddChatText(
|
||
$"[MosswartMassacre] Error saving settings: {ex.Message}", 5);
|
||
}
|
||
}
|
||
}
|
||
|
||
// public properties
|
||
public bool RemoteCommandsEnabled
|
||
{
|
||
get => _remoteCommandsEnabled;
|
||
set { _remoteCommandsEnabled = value; Save(); }
|
||
}
|
||
|
||
public bool RareMetaEnabled
|
||
{
|
||
get => _rareMetaEnabled;
|
||
set { _rareMetaEnabled = value; Save(); }
|
||
}
|
||
|
||
public bool HttpServerEnabled
|
||
{
|
||
get => _httpServerEnabled;
|
||
set { _httpServerEnabled = value; Save(); }
|
||
}
|
||
|
||
public bool TelemetryEnabled
|
||
{
|
||
get => _telemetryEnabled;
|
||
set { _telemetryEnabled = value; Save(); }
|
||
}
|
||
public bool WebSocketEnabled
|
||
{
|
||
get => _webSocketEnabled;
|
||
set { _webSocketEnabled = value; Save(); }
|
||
}
|
||
public string CharTag
|
||
{
|
||
get => _charTag;
|
||
set { _charTag = value; Save(); }
|
||
}
|
||
public bool InventoryLog
|
||
{
|
||
get => _inventorylog;
|
||
set { _inventorylog = value; Save(); }
|
||
}
|
||
|
||
public int MainWindowX
|
||
{
|
||
get => _mainWindowX;
|
||
set { _mainWindowX = value; Save(); }
|
||
}
|
||
|
||
public int MainWindowY
|
||
{
|
||
get => _mainWindowY;
|
||
set { _mainWindowY = value; Save(); }
|
||
}
|
||
|
||
public bool UseTabbedInterface
|
||
{
|
||
get => _useTabbedInterface;
|
||
set { _useTabbedInterface = value; Save(); }
|
||
}
|
||
|
||
public string VTankProfilesPath
|
||
{
|
||
get => _vtankProfilesPath;
|
||
set { _vtankProfilesPath = value; Save(); }
|
||
}
|
||
|
||
public bool VerboseLogging
|
||
{
|
||
get => _verboseLogging;
|
||
set { _verboseLogging = value; Save(); }
|
||
}
|
||
}
|
||
}
|