using System; using System.Xml.Linq; using Barotrauma.LuaCs.Data; using Barotrauma.LuaCs; using OneOf; namespace Barotrauma.LuaCs.Data; public interface ISettingsRegistrationProvider : IService { void RegisterTypeProviders(IConfigService configService, Func, bool> valueChangePredicate); } public class SettingsEntryRegistrar : ISettingsRegistrationProvider { private ILuaCsInfoProvider _infoProvider; public SettingsEntryRegistrar(ILuaCsInfoProvider infoProvider) { _infoProvider = infoProvider; } public void RegisterTypeProviders(IConfigService configService, Func, bool> valueChangePredicate) { // TODO: Replace this with a proper IFactory lookup pattern. // ISettingBase RegisterSettingEntry(configService, "bool", valueChangePredicate); RegisterSettingEntry(configService, "byte", valueChangePredicate); RegisterSettingEntry(configService, "sbyte", valueChangePredicate); RegisterSettingEntry(configService, "short", valueChangePredicate); RegisterSettingEntry(configService, "ushort", valueChangePredicate); RegisterSettingEntry(configService, "int", valueChangePredicate); RegisterSettingEntry(configService, "uint", valueChangePredicate); RegisterSettingEntry(configService, "long", valueChangePredicate); RegisterSettingEntry(configService, "ulong", valueChangePredicate); RegisterSettingEntry(configService, "string", valueChangePredicate); // ISettingRangeBase configService.RegisterSettingTypeInitializer("rangeInt", cfgInfo => { return new SettingRangeInt.RangeFactory().CreateInstance(cfgInfo.Info, (val) => IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate)); }); configService.RegisterSettingTypeInitializer("rangeFloat", cfgInfo => { return new SettingRangeFloat.RangeFactory().CreateInstance(cfgInfo.Info, (val) => IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate)); }); // ISettingList : Not Implemented yet } private void RegisterSettingEntry(IConfigService configService, string typeName, Func, bool> valueChangePredicate) where T : IEquatable, IConvertible { configService.RegisterSettingTypeInitializer(typeName, cfgInfo => { return new SettingEntry.Factory().CreateInstance(cfgInfo.Info, (val) => IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate)); }); } private bool IsValueChangeAllowed(IConfigInfo info, OneOf newValue, Func, bool> valueChangePredicate) { #if CLIENT return !info.Element.GetAttributeBool("ReadOnly", false) || info.EditableStates < _infoProvider.CurrentRunState || valueChangePredicate is null || valueChangePredicate.Invoke(newValue); #else // Server has absolute authority. return true; #endif } public void Dispose() { if (!ModUtils.Threading.CheckIfClearAndSetBool(ref _isDisposed)) { return; } _infoProvider.Dispose(); _infoProvider = null; } private int _isDisposed; public bool IsDisposed { get => ModUtils.Threading.GetBool(ref _isDisposed); private set => ModUtils.Threading.SetBool(ref _isDisposed, value); } }