using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.Json; using System.Threading.Tasks; using IW4MAdmin.Application.Configuration; using Jint; using Jint.Native; using Jint.Native.Json; using SharedLibraryCore.Interfaces; namespace IW4MAdmin.Application.Plugin.Script; public class ScriptPluginConfigurationWrapper { public event Action ConfigurationUpdated; private readonly ScriptPluginConfiguration _config; private readonly IConfigurationHandlerV2 _configHandler; private readonly Engine _scriptEngine; private readonly JsonParser _engineParser; private readonly List<(string, Delegate)> _updateCallbackActions = new(); private string _pluginName; public ScriptPluginConfigurationWrapper(string pluginName, Engine scriptEngine, IConfigurationHandlerV2 configHandler) { _pluginName = pluginName; _scriptEngine = scriptEngine; _configHandler = configHandler; _configHandler.Updated += OnConfigurationUpdated; _config = configHandler.Get("ScriptPluginSettings", new ScriptPluginConfiguration()).GetAwaiter().GetResult(); _engineParser = new JsonParser(_scriptEngine); } ~ScriptPluginConfigurationWrapper() { _configHandler.Updated -= OnConfigurationUpdated; } public void SetName(string name) { _pluginName = name; } public async Task SetValue(string key, object value) { var castValue = value; if (value is double doubleValue) { castValue = AsInteger(doubleValue) ?? value; } if (value is object[] array && array.All(item => item is double d && AsInteger(d) != null)) { castValue = array.Select(item => AsInteger((double)item)).ToArray(); } if (!_config.ContainsKey(_pluginName)) { _config.Add(_pluginName, new Dictionary()); } var plugin = _config[_pluginName]; if (plugin.ContainsKey(key)) { plugin[key] = castValue; } else { plugin.Add(key, castValue); } await _configHandler.Set(_config); } public JsValue GetValue(string key) => GetValue(key, null); public JsValue GetValue(string key, Delegate updateCallback) { if (!_config.ContainsKey(_pluginName)) { return JsValue.Undefined; } if (!_config[_pluginName].ContainsKey(key)) { return JsValue.Undefined; } var item = _config[_pluginName][key]; if (item is JsonElement { ValueKind: JsonValueKind.Array } jElem) { item = jElem.Deserialize>(); } if (updateCallback is not null) { _updateCallbackActions.Add((key, updateCallback)); } try { return _engineParser.Parse(item!.ToString()!); } catch { // ignored } return JsValue.FromObject(_scriptEngine, item); } private static int? AsInteger(double value) { return int.TryParse(value.ToString(CultureInfo.InvariantCulture), out var parsed) ? parsed : null; } private void OnConfigurationUpdated(ScriptPluginConfiguration config) { foreach (var callback in _updateCallbackActions) { ConfigurationUpdated?.Invoke(GetValue(callback.Item1), callback.Item2); } } }