- Basic Config & Settings working (read-only, changes must be made via debug halt).

This commit is contained in:
MapleWheels
2026-02-06 14:29:25 -05:00
committed by Maplewheels
parent e75208507d
commit 771e73a798
4 changed files with 102 additions and 75 deletions
@@ -86,6 +86,7 @@ public interface ISettingRangeBase<T> : ISettingBase<T> where T : IEquatable<T>,
/// <typeparam name="T">The value type. See <see cref="ISettingBase{T}"/></typeparam> /// <typeparam name="T">The value type. See <see cref="ISettingBase{T}"/></typeparam>
public interface ISettingList<T> : ISettingBase<T> where T : IEquatable<T>, IConvertible public interface ISettingList<T> : ISettingBase<T> where T : IEquatable<T>, IConvertible
{ {
bool TrySetValueByIndex(int index);
IReadOnlyList<T> Options { get; } IReadOnlyList<T> Options { get; }
IReadOnlyList<string> StringOptions { get; } IReadOnlyList<string> StringOptions { get; }
} }
@@ -36,18 +36,11 @@ public class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyncEntity
try try
{ {
Value = (T)Convert.ChangeType(ConfigInfo.Element.GetAttributeString("Value", null), typeof(T)); Value = (T)Convert.ChangeType(ConfigInfo.Element.GetAttributeString("Value", null), typeof(T));
DefaultValue = Value;
} }
catch (Exception e) when (e is InvalidCastException or ArgumentNullException) catch (Exception e) when (e is InvalidCastException or ArgumentNullException)
{ {
Value = default(T); Value = default(T);
}
try
{
DefaultValue = (T)Convert.ChangeType(ConfigInfo.Element.GetAttributeString("Value", null), typeof(T));
}
catch (Exception e) when (e is InvalidCastException or ArgumentNullException)
{
DefaultValue = default(T); DefaultValue = default(T);
} }
} }
@@ -2,6 +2,7 @@
using System.Xml.Linq; using System.Xml.Linq;
using Barotrauma.LuaCs.Data; using Barotrauma.LuaCs.Data;
using Barotrauma.LuaCs; using Barotrauma.LuaCs;
using OneOf;
namespace Barotrauma.LuaCs.Data; namespace Barotrauma.LuaCs.Data;
@@ -21,33 +22,53 @@ public class SettingsEntryRegistrar : ISettingsRegistrationProvider
public void RegisterTypeProviders(IConfigService configService, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) public void RegisterTypeProviders(IConfigService configService, Func<OneOf<string, XElement, object>, bool> valueChangePredicate)
{ {
// TODO: Replace this with a proper IFactory lookup pattern.
// ISettingBase<T> // ISettingBase<T>
RegisterSettingEntry<bool>(configService, "bool"); RegisterSettingEntry<bool>(configService, "bool", valueChangePredicate);
RegisterSettingEntry<byte>(configService, "byte"); RegisterSettingEntry<byte>(configService, "byte", valueChangePredicate);
RegisterSettingEntry<sbyte>(configService, "sbyte"); RegisterSettingEntry<sbyte>(configService, "sbyte", valueChangePredicate);
RegisterSettingEntry<short>(configService, "short"); RegisterSettingEntry<short>(configService, "short", valueChangePredicate);
RegisterSettingEntry<ushort>(configService, "ushort"); RegisterSettingEntry<ushort>(configService, "ushort", valueChangePredicate);
RegisterSettingEntry<int>(configService, "int"); RegisterSettingEntry<int>(configService, "int", valueChangePredicate);
RegisterSettingEntry<uint>(configService, "uint"); RegisterSettingEntry<uint>(configService, "uint", valueChangePredicate);
RegisterSettingEntry<long>(configService, "long"); RegisterSettingEntry<long>(configService, "long", valueChangePredicate);
RegisterSettingEntry<ulong>(configService, "ulong"); RegisterSettingEntry<ulong>(configService, "ulong", valueChangePredicate);
RegisterSettingEntry<string>(configService, "string"); RegisterSettingEntry<string>(configService, "string", valueChangePredicate);
// ISettingRangeBase<T> // ISettingRangeBase<T>
// ISettingList 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<T>(IConfigService configService, string typeName) where T : IEquatable<T>, IConvertible private void RegisterSettingEntry<T>(IConfigService configService, string typeName, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) where T : IEquatable<T>, IConvertible
{ {
configService.RegisterSettingTypeInitializer(typeName, cfgInfo => configService.RegisterSettingTypeInitializer(typeName, cfgInfo =>
{ {
return new SettingEntry<bool>.Factory().CreateInstance(cfgInfo.Info, (val) => return new SettingEntry<T>.Factory().CreateInstance(cfgInfo.Info, (val) =>
{ IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate));
return !cfgInfo.Info.Element.GetAttributeBool("ReadOnly", false)
&& cfgInfo.Info.EditableStates.HasFlag(_infoProvider?.CurrentRunState ?? RunState.Running);
});
}); });
} }
private bool IsValueChangeAllowed(IConfigInfo info, OneOf<string, XElement, object> newValue,
Func<OneOf<string, XElement, object>, bool> valueChangePredicate)
{
return !info.Element.GetAttributeBool("ReadOnly", false)
|| !info.EditableStates.HasFlag(_infoProvider?.CurrentRunState ?? RunState.Running)
|| valueChangePredicate is null
|| valueChangePredicate.Invoke(newValue);
}
public void Dispose() public void Dispose()
{ {
if (!ModUtils.Threading.CheckIfClearAndSetBool(ref _isDisposed)) if (!ModUtils.Threading.CheckIfClearAndSetBool(ref _isDisposed))
@@ -33,28 +33,10 @@ namespace Barotrauma
{ {
// == startup // == startup
_servicesProvider = SetupServicesProvider(); _servicesProvider = SetupServicesProvider();
if (!ValidateLuaCsContent())
{
Logger.LogError($"{nameof(LuaCsSetup)}: ModConfig.xml missing. Unable to continue.");
throw new ApplicationException($"{nameof(LuaCsSetup)}: Lua's ModConfig.xml is missing. Unable to continue.");
}
_runStateMachine = SetupStateMachine(); _runStateMachine = SetupStateMachine();
SubscribeToLuaCsEvents(); SubscribeToLuaCsEvents();
} }
private bool ValidateLuaCsContent()
{
#if DEBUG
// TODO: we just wanna boot for now
return true;
#endif
// check if /Content/ModConfig.xml exists
// if not, try to copy missing files from the Local Mods folder
// if not, try to copy missing files from the Workshop Mods folder
// if that fails, throw an error and exit.
throw new NotImplementedException();
}
private void SubscribeToLuaCsEvents() private void SubscribeToLuaCsEvents()
{ {
EventService.Subscribe<IEventScreenSelected>(this); // game state hook in EventService.Subscribe<IEventScreenSelected>(this); // game state hook in
@@ -102,7 +84,7 @@ namespace Barotrauma
internal set => _isCsEnabled?.TrySetValue(value); internal set => _isCsEnabled?.TrySetValue(value);
} }
private SettingEntry<bool> _isCsEnabled; private ISettingBase<bool> _isCsEnabled;
/// <summary> /// <summary>
/// Whether the popup error GUI should be hidden/suppressed. /// Whether the popup error GUI should be hidden/suppressed.
@@ -112,7 +94,7 @@ namespace Barotrauma
get => _disableErrorGUIOverlay?.Value ?? false; get => _disableErrorGUIOverlay?.Value ?? false;
internal set => _disableErrorGUIOverlay?.TrySetValue(value); internal set => _disableErrorGUIOverlay?.TrySetValue(value);
} }
private SettingEntry<bool> _disableErrorGUIOverlay; private ISettingBase<bool> _disableErrorGUIOverlay;
/// <summary> /// <summary>
/// Whether usernames are anonymized or show in logs. /// Whether usernames are anonymized or show in logs.
@@ -122,7 +104,7 @@ namespace Barotrauma
get => _hideUserNamesInLogs?.Value ?? false; get => _hideUserNamesInLogs?.Value ?? false;
internal set => _hideUserNamesInLogs?.TrySetValue(value); internal set => _hideUserNamesInLogs?.TrySetValue(value);
} }
private SettingEntry<bool> _hideUserNamesInLogs; private ISettingBase<bool> _hideUserNamesInLogs;
/// <summary> /// <summary>
/// The SteamId of the Workshop LuaCs CPackage in use, if available. /// The SteamId of the Workshop LuaCs CPackage in use, if available.
@@ -132,7 +114,7 @@ namespace Barotrauma
get => _luaForBarotraumaSteamId?.Value ?? 0; get => _luaForBarotraumaSteamId?.Value ?? 0;
internal set => _luaForBarotraumaSteamId?.TrySetValue(value); internal set => _luaForBarotraumaSteamId?.TrySetValue(value);
} }
private SettingEntry<ulong> _luaForBarotraumaSteamId; private ISettingBase<ulong> _luaForBarotraumaSteamId;
/// <summary> /// <summary>
/// TODO: @evilfactory@users.noreply.github.com /// TODO: @evilfactory@users.noreply.github.com
@@ -142,7 +124,7 @@ namespace Barotrauma
get => _restrictMessageSize?.Value ?? false; get => _restrictMessageSize?.Value ?? false;
internal set => _restrictMessageSize?.TrySetValue(value); internal set => _restrictMessageSize?.TrySetValue(value);
} }
private SettingEntry<bool> _restrictMessageSize; private ISettingBase<bool> _restrictMessageSize;
/// <summary> /// <summary>
/// The local save path for all local data storage for mods. /// The local save path for all local data storage for mods.
@@ -152,28 +134,45 @@ namespace Barotrauma
get => _localDataSavePath?.Value ?? Path.Combine(Directory.GetCurrentDirectory(), "/Data/Mods"); get => _localDataSavePath?.Value ?? Path.Combine(Directory.GetCurrentDirectory(), "/Data/Mods");
internal set => _localDataSavePath?.TrySetValue(value); internal set => _localDataSavePath?.TrySetValue(value);
} }
private SettingEntry<string> _localDataSavePath; private ISettingBase<string> _localDataSavePath;
void LoadLuaCsConfig() void LoadLuaCsConfig()
{ {
_isCsEnabled = ConfigService.TryGetConfig<SettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "IsCsEnabled", out var val1) ? val1 var luaCsPackage = ContentPackageManager.EnabledPackages.Regular.FirstOrDefault(cp => cp.NameMatches("LuaCsForBarotrauma"), null)
: throw new NullReferenceException($"{nameof(IsCsEnabled)} cannot be loaded."); ?? ContentPackageManager.LocalPackages.FirstOrDefault(cp => cp.NameMatches("LuaCsForBarotrauma"))
_disableErrorGUIOverlay = ConfigService.TryGetConfig<SettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "DisableErrorGUIOverlay", out var val3) ? val3 ?? ContentPackageManager.WorkshopPackages.FirstOrDefault(cp => cp.NameMatches("LuaCsForBarotrauma"));
: throw new NullReferenceException($"{nameof(DisableErrorGUIOverlay)} cannot be loaded.");
_hideUserNamesInLogs = ConfigService.TryGetConfig<SettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "HideUserNamesInLogs", out var val4) ? val4 _isCsEnabled =
: throw new NullReferenceException($"{nameof(HideUserNamesInLogs)} cannot be loaded."); ConfigService.TryGetConfig<ISettingBase<bool>>(luaCsPackage, "IsCsEnabled", out var val1)
_luaForBarotraumaSteamId = ConfigService.TryGetConfig<SettingEntry<ulong>>(ContentPackageManager.VanillaCorePackage, "LuaForBarotraumaSteamId", out var val5) ? val5 ? val1
: throw new NullReferenceException($"{nameof(LuaForBarotraumaSteamId)} cannot be loaded."); : null;
_restrictMessageSize = ConfigService.TryGetConfig<SettingEntry<bool>>(ContentPackageManager.VanillaCorePackage, "RestrictMessageSize", out var val7) ? val7 _disableErrorGUIOverlay =
: throw new NullReferenceException($"{nameof(RestrictMessageSize)} cannot be loaded."); ConfigService.TryGetConfig<ISettingBase<bool>>(luaCsPackage, "DisableErrorGUIOverlay", out var val3)
_localDataSavePath = ConfigService.TryGetConfig<SettingEntry<string>>(ContentPackageManager.VanillaCorePackage, "LocalDataSavePath", out var val8) ? val8 ? val3
: throw new NullReferenceException($"{nameof(LocalDataSavePath)} cannot be loaded."); : null;
_hideUserNamesInLogs =
ConfigService.TryGetConfig<ISettingBase<bool>>(luaCsPackage, "HideUserNamesInLogs", out var val4)
? val4
: null;
_luaForBarotraumaSteamId =
ConfigService.TryGetConfig<ISettingBase<ulong>>(luaCsPackage, "LuaForBarotraumaSteamId", out var val5)
? val5
: null;
_restrictMessageSize =
ConfigService.TryGetConfig<ISettingBase<bool>>(luaCsPackage, "RestrictMessageSize", out var val7)
? val7
: null;
_localDataSavePath =
ConfigService.TryGetConfig<ISettingBase<string>>(luaCsPackage, "LocalDataSavePath", out var val8)
? val8
: null;
} }
private IServicesProvider SetupServicesProvider() private IServicesProvider SetupServicesProvider()
{ {
var servicesProvider = new ServicesProvider(); var servicesProvider = new ServicesProvider();
// Base Service
servicesProvider.RegisterServiceType<ILoggerService, LoggerService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILoggerService, LoggerService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<PerformanceCounterService, PerformanceCounterService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<PerformanceCounterService, PerformanceCounterService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IStorageService, StorageService>(ServiceLifetime.Transient); servicesProvider.RegisterServiceType<IStorageService, StorageService>(ServiceLifetime.Transient);
@@ -182,9 +181,22 @@ namespace Barotrauma
servicesProvider.RegisterServiceResolver<ILuaCsHook>(factory => factory.GetInstance<IEventService>() as ILuaCsHook); servicesProvider.RegisterServiceResolver<ILuaCsHook>(factory => factory.GetInstance<IEventService>() as ILuaCsHook);
servicesProvider.RegisterServiceType<IPackageManagementService, PackageManagementService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IPackageManagementService, PackageManagementService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IAssemblyManagementService, PluginManagementService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IAssemblyManagementService, PluginManagementService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IAssemblyLoaderService.IFactory, AssemblyLoader.Factory>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceResolver<IPluginManagementService>(factory => factory.GetInstance<IAssemblyManagementService>()); servicesProvider.RegisterServiceResolver<IPluginManagementService>(factory => factory.GetInstance<IAssemblyManagementService>());
servicesProvider.RegisterServiceType<ILuaScriptManagementService, LuaScriptManagementService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILuaScriptManagementService, LuaScriptManagementService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IConfigService, ConfigService>(ServiceLifetime.Singleton);
// TODO: INetworkingService
// Extension/Sub Services
servicesProvider.RegisterServiceType<IAssemblyLoaderService.IFactory, AssemblyLoader.Factory>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<ISettingsRegistrationProvider, SettingsEntryRegistrar>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IModConfigService, ModConfigService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
// All Lua Extras
servicesProvider.RegisterServiceType<IDefaultLuaRegistrar, DefaultLuaRegistrar>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IDefaultLuaRegistrar, DefaultLuaRegistrar>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaPatcher, LuaPatcherService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILuaPatcher, LuaPatcherService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaUserDataService, LuaUserDataService>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILuaUserDataService, LuaUserDataService>(ServiceLifetime.Singleton);
@@ -193,20 +205,13 @@ namespace Barotrauma
servicesProvider.RegisterServiceType<ILuaScriptLoader, LuaScriptLoader>(ServiceLifetime.Transient); servicesProvider.RegisterServiceType<ILuaScriptLoader, LuaScriptLoader>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<LuaGame, LuaGame>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<LuaGame, LuaGame>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaCsTimer, LuaCsTimer>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILuaCsTimer, LuaCsTimer>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ISettingsRegistrationProvider, SettingsEntryRegistrar>(ServiceLifetime.Transient);
// TODO: INetworkingService
servicesProvider.RegisterServiceType<IConfigService, ConfigService>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IModConfigService, ModConfigService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>, ModConfigFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
servicesProvider.RegisterServiceType<IParserServiceOneToManyAsync<IConfigResourceInfo, IConfigProfileInfo>, SettingsFileParserService>(ServiceLifetime.Transient);
// service config data // service config data
servicesProvider.RegisterServiceType<IStorageServiceConfig, StorageServiceConfig>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IStorageServiceConfig, StorageServiceConfig>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<ILuaScriptServicesConfig, LuaScriptServicesConfig>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<ILuaScriptServicesConfig, LuaScriptServicesConfig>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IConfigServiceConfig, ConfigServiceConfig>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IConfigServiceConfig, ConfigServiceConfig>(ServiceLifetime.Singleton);
servicesProvider.RegisterServiceType<IPackageManagementServiceConfig, PackageManagementServiceConfig>(ServiceLifetime.Singleton); servicesProvider.RegisterServiceType<IPackageManagementServiceConfig, PackageManagementServiceConfig>(ServiceLifetime.Singleton);
// gen IL // gen IL
servicesProvider.Compile(); servicesProvider.Compile();
return servicesProvider; return servicesProvider;
@@ -291,6 +296,7 @@ namespace Barotrauma
Logger.LogResults(PackageManagementService.UnloadAllPackages()); Logger.LogResults(PackageManagementService.UnloadAllPackages());
} }
ConfigService.Reset();
LuaScriptManagementService.Reset(); LuaScriptManagementService.Reset();
PackageManagementService.Reset(); PackageManagementService.Reset();
EventService.Reset(); EventService.Reset();
@@ -309,9 +315,12 @@ namespace Barotrauma
if (!PackageManagementService.IsAnyPackageLoaded()) if (!PackageManagementService.IsAnyPackageLoaded())
{ {
foreach (var registrationProvider in _servicesProvider.GetAllServices<ISettingsRegistrationProvider>())
{
registrationProvider.RegisterTypeProviders(ConfigService, null);
}
Logger.LogResults(PackageManagementService.LoadPackagesInfo(ContentPackageManager.EnabledPackages.All.ToImmutableArray())); Logger.LogResults(PackageManagementService.LoadPackagesInfo(ContentPackageManager.EnabledPackages.All.ToImmutableArray()));
// TODO: Implement full xml content necessary for this to work. LoadLuaCsConfig();
//LoadLuaCsConfig();
} }
CurrentRunState = RunState.LoadedNoExec; CurrentRunState = RunState.LoadedNoExec;
@@ -321,9 +330,12 @@ namespace Barotrauma
{ {
if (!PackageManagementService.IsAnyPackageLoaded()) if (!PackageManagementService.IsAnyPackageLoaded())
{ {
foreach (var registrationProvider in _servicesProvider.GetAllServices<ISettingsRegistrationProvider>())
{
registrationProvider.RegisterTypeProviders(ConfigService, null);
}
Logger.LogResults(PackageManagementService.LoadPackagesInfo(ContentPackageManager.EnabledPackages.All.ToImmutableArray())); Logger.LogResults(PackageManagementService.LoadPackagesInfo(ContentPackageManager.EnabledPackages.All.ToImmutableArray()));
// TODO: Enable later LoadLuaCsConfig();
//LoadLuaCsConfig();
} }
if (!PackageManagementService.IsAnyPackageRunning()) if (!PackageManagementService.IsAnyPackageRunning())