Skip to content

Commit 803f1b8

Browse files
committed
WIP add autodetection of enabled toggles
1 parent 09500f0 commit 803f1b8

6 files changed

Lines changed: 83 additions & 22 deletions

File tree

MonkeyLoader.GamePacks.ResoniteModLoader/ModConfiguration.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,4 @@ public ModConfigurationDefinition(ResoniteModBase owner, Version configVersion,
267267
AutoSave = autoSaveConfig;
268268
}
269269
}
270-
271-
/// <summary>
272-
/// Represents an <see cref="Exception"/> encountered while loading a mod's configuration file.
273-
/// </summary>
274-
public class ModConfigurationException : Exception
275-
{
276-
internal ModConfigurationException(string message) : base(message)
277-
{ }
278-
279-
internal ModConfigurationException(string message, Exception innerException) : base(message, innerException)
280-
{ }
281-
}
282270
}

MonkeyLoader.GamePacks.ResoniteModLoader/ModConfigurationDefinitionBuilder.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using MonkeyLoader.Configuration;
44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using System.Reflection;
89

@@ -13,10 +14,14 @@ namespace ResoniteModLoader
1314
/// </summary>
1415
public class ModConfigurationDefinitionBuilder
1516
{
16-
private static readonly Type _modConfigKeyType = typeof(ModConfigurationKey);
1717
private static readonly MethodInfo _addRangeComponentMethod = AccessTools.Method(typeof(ModConfigurationDefinitionBuilder), nameof(AddRangeComponent));
18+
private static readonly string[] _definitiveEnabledToggles = new[] { "enabled", "mod enabled", "mod_enabled", "is_enabled" };
19+
private static readonly string[] _indicativeEnabledToggles = new[] { "enabled" };
20+
private static readonly Type _modConfigKeyType = typeof(ModConfigurationKey);
21+
1822
private readonly HashSet<ModConfigurationKey> _keys = new();
1923
private readonly ResoniteModBase _owner;
24+
2025
private bool _autoSaveConfig = true;
2126
private Version _configVersion = new(1, 0, 0);
2227

@@ -88,6 +93,43 @@ internal void ProcessAttributes()
8893
.Do(ProcessField);
8994
}
9095

96+
internal bool TryGetEnabledToggle([NotNullWhen(true)] out DefiningConfigKey<bool>? enabledToggleKey, bool remove = true)
97+
{
98+
enabledToggleKey = null;
99+
ModConfigurationKey? enabledToggle = null;
100+
101+
var potentialKeys = _keys.OfType<ModConfigurationKey<bool>>().ToArray();
102+
103+
foreach (var definitiveEnabledToggle in _definitiveEnabledToggles)
104+
{
105+
if (potentialKeys.FirstOrDefault(key => key.Name.Equals(definitiveEnabledToggle, StringComparison.OrdinalIgnoreCase)) is ModConfigurationKey enabledKey)
106+
{
107+
enabledToggle = enabledKey;
108+
break;
109+
}
110+
}
111+
112+
if (enabledToggle is null)
113+
{
114+
potentialKeys = potentialKeys
115+
.Where(key => _indicativeEnabledToggles
116+
.Any(name => key.Name.Contains(name, StringComparison.OrdinalIgnoreCase)))
117+
.ToArray();
118+
119+
if (potentialKeys.Length != 1)
120+
return false;
121+
122+
enabledToggle = potentialKeys[0];
123+
}
124+
125+
enabledToggleKey = (DefiningConfigKey<bool>)enabledToggle.UntypedKey;
126+
127+
if (remove)
128+
_keys.Remove(enabledToggle);
129+
130+
return true;
131+
}
132+
91133
private static void AddRangeComponent<T>(DefiningConfigKey<T> key, T min, T max)
92134
{
93135
var rangeComponent = new ConfigKeyRange<T>(min, max, null);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace ResoniteModLoader
4+
{
5+
/// <summary>
6+
/// Represents an <see cref="Exception"/> encountered while loading a mod's configuration file.
7+
/// </summary>
8+
public class ModConfigurationException : Exception
9+
{
10+
internal ModConfigurationException(string message) : base(message)
11+
{ }
12+
13+
internal ModConfigurationException(string message, Exception innerException) : base(message, innerException)
14+
{ }
15+
}
16+
}

MonkeyLoader.GamePacks.ResoniteModLoader/ModLoader.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ public sealed class ModLoader : ResoniteMonkey<ModLoader>
3535
private static readonly Lazy<bool> _isHeadless = new(() => AccessTools.AllTypes().Any(type => type.Namespace == "FrooxEngine.Headless"));
3636

3737
/// <summary>
38-
/// Returns <c>true</c> if ResoniteModLoader was loaded by a headless
38+
/// Gets whether this is running on a headless client.
3939
/// </summary>
40+
/// <value><c>true</c> if ResoniteModLoader was loaded by a headless; otherwise, <c>false</c>.</value>
4041
public static bool IsHeadless => _isHeadless.Value;
4142

4243
/// <inheritdoc/>

MonkeyLoader.GamePacks.ResoniteModLoader/ResoniteMod.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MonkeyLoader;
2+
using MonkeyLoader.Configuration;
23
using MonkeyLoader.Logging;
34
using MonkeyLoader.Patching;
45
using MonkeyLoader.Resonite;
@@ -18,6 +19,11 @@ public abstract class ResoniteMod : ResoniteModBase
1819
{
1920
private readonly Lazy<ModConfiguration?> _configuration;
2021

22+
/// <summary>
23+
/// Gets the <see cref="MonkeyBase.Enabled">Enabled</see>-Toggle config item for this mod.
24+
/// </summary>
25+
internal DefiningConfigKey<bool>? EnabledToggle { get; private set; }
26+
2127
/// <inheritdoc/>
2228
protected override ModConfiguration? Configuration => _configuration.Value;
2329

@@ -26,10 +32,10 @@ protected ResoniteMod()
2632
{
2733
_configuration = new(() =>
2834
{
29-
if (BuildConfigurationDefinition() is ModConfigurationDefinition definition)
30-
return Config.LoadSection(new ModConfiguration(definition));
35+
if (BuildConfigurationDefinition() is not ModConfigurationDefinition definition)
36+
return null;
3137

32-
return null;
38+
return Config.LoadSection(new ModConfiguration(definition));
3339
});
3440
}
3541

@@ -186,6 +192,9 @@ internal static Logger GetLoggerFromStackTrace(StackTrace stackTrace)
186192

187193
DefineConfiguration(builder);
188194

195+
if (builder.TryGetEnabledToggle(out var enabledToggleKey))
196+
EnabledToggle = enabledToggleKey;
197+
189198
return builder.Build();
190199
}
191200

MonkeyLoader.GamePacks.ResoniteModLoader/RmlMod.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ namespace ResoniteModLoader
1818
{
1919
internal sealed class RmlMod : Mod
2020
{
21+
/// <summary>
22+
/// Map of Assembly to ResoniteMod, used for logging purposes
23+
/// </summary>
24+
internal static readonly Dictionary<Assembly, ResoniteMod> AssemblyLookupMap = new();
25+
2126
private static readonly Type _resoniteModType = typeof(ResoniteMod);
2227
private static readonly Uri _rmlIconUrl = new("https://avatars.githubusercontent.com/u/145755526");
2328

2429
///<inheritdoc/>
2530
public override string Description => "RML Mods don't have descriptions.";
2631

27-
/// <summary>
28-
/// Map of Assembly to ResoniteMod, used for logging purposes
29-
/// </summary>
30-
internal static readonly Dictionary<Assembly, ResoniteMod> AssemblyLookupMap = new();
31-
3232
///<inheritdoc/>
3333
public override IFileSystem FileSystem { get; }
3434

@@ -79,6 +79,11 @@ public RmlMod(MonkeyLoader.MonkeyLoader loader, string? location, bool isGamePac
7979
authors.Add(resoniteMod.Author);
8080
monkeys.Add(resoniteMod);
8181

82+
resoniteMod.GetConfiguration();
83+
84+
if (resoniteMod.EnabledToggle is not null)
85+
MonkeyToggles.A
86+
8287
// Add dependencies after refactoring MKL
8388
//foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
8489
// dependencies.Add(referencedAssembly.Name, new DependencyReference())

0 commit comments

Comments
 (0)