Skip to content

Commit fcc1a09

Browse files
committed
Add support for HiddenConfig and ProtectedConfig Tags, refactor locale integration, and implement custom data feeds
1 parent 88db2a7 commit fcc1a09

10 files changed

Lines changed: 181 additions & 52 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace BepisModSettings.ConfigAttributes;
4+
5+
public class ActionConfig(Delegate action)
6+
{
7+
public Delegate Action { get; } = action ?? throw new ArgumentNullException(nameof(action));
8+
9+
public object Invoke(params object[] args) => Action.DynamicInvoke(args);
10+
}
11+
12+
public class ActionConfig<T>(Action<T> action) : ActionConfig(action)
13+
{
14+
public void Invoke(T arg) => ((Action<T>)Action)(arg);
15+
}
16+
17+
public class ActionConfig<T1, T2>(Action<T1, T2> action) : ActionConfig(action)
18+
{
19+
public void Invoke(T1 arg1, T2 arg2) => ((Action<T1, T2>)Action)(arg1, arg2);
20+
}
21+
22+
public class FuncConfig<TResult>(Func<TResult> func) : ActionConfig(func)
23+
{
24+
public TResult Invoke() => ((Func<TResult>)Action)();
25+
}
26+
27+
public class FuncConfig<T, TResult>(Func<T, TResult> func) : ActionConfig(func)
28+
{
29+
public TResult Invoke(T arg) => ((Func<T, TResult>)Action)(arg);
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using FrooxEngine;
4+
5+
namespace BepisModSettings.ConfigAttributes;
6+
7+
public delegate IAsyncEnumerable<DataFeedItem> DataFeedMethod(IReadOnlyList<string> path, IReadOnlyList<string> groupKeys);
8+
9+
public sealed class CustomDataFeed(DataFeedMethod action)
10+
{
11+
private readonly DataFeedMethod _action = action ?? throw new ArgumentNullException(nameof(action));
12+
13+
public IAsyncEnumerable<DataFeedItem> Build(IReadOnlyList<string> path, IReadOnlyList<string> groupKeys)
14+
{
15+
ArgumentNullException.ThrowIfNull(path);
16+
17+
return _action(path, groupKeys);
18+
}
19+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace BepisModSettings.ConfigAttributes;
2+
3+
public class HiddenConfig { }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace BepisModSettings.ConfigAttributes;
2+
3+
public class ProtectedConfig(string maskString)
4+
{
5+
public ProtectedConfig() : this("*") { }
6+
7+
public string MaskString { get; } = maskString;
8+
}

BepisModSettings/DataFeeds/BepisNestedCategoryPage.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ internal static async IAsyncEnumerable<DataFeedItem> Enumerate(IReadOnlyList<str
2121
}
2222
else
2323
{
24-
DataFeedLabel noConfigs = new DataFeedLabel();
25-
noConfigs.InitBase("InvalidCategory", path, null, "Settings.BepInEx.Plugins.Error".AsLocaleKey());
26-
yield return noConfigs;
24+
DataFeedLabel invalidCategory = new DataFeedLabel();
25+
invalidCategory.InitBase("InvalidCategory", path, null, "Settings.BepInEx.Plugins.Error".AsLocaleKey());
26+
yield return invalidCategory;
2727
}
2828
}
2929
}

BepisModSettings/DataFeeds/BepisPluginPage.cs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using BepInEx.NET.Common;
1010
using BepInExResoniteShim;
1111
using BepisLocaleLoader;
12+
using BepisModSettings.ConfigAttributes;
1213
using Elements.Core;
1314
using FrooxEngine;
1415
using FrooxEngine.UIX;
@@ -73,7 +74,7 @@ internal static async IAsyncEnumerable<DataFeedItem> Enumerate(IReadOnlyList<str
7374
modGroup.InitBase("Metadata", path, null, "Settings.BepInEx.Plugins.Metadata".AsLocaleKey());
7475
yield return modGroup;
7576

76-
string[] metadataGroup = new[] { "Metadata" };
77+
string[] metadataGroup = ["Metadata"];
7778

7879
DataFeedIndicator<string> idIndicator = new DataFeedIndicator<string>();
7980
idIndicator.InitBase("Id", path, metadataGroup, "Settings.BepInEx.Plugins.Guid".AsLocaleKey());
@@ -119,6 +120,8 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
119120
List<string> added = new List<string>();
120121
foreach (ConfigEntryBase config in configFile.Values)
121122
{
123+
if (!Plugin.ShowHidden.Value && config.Description.Tags.Any(x => x is HiddenConfig)) continue;
124+
122125
Type valueType = config.SettingType;
123126

124127
string section = config.Definition.Section;
@@ -147,22 +150,24 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
147150
string initKey = section + "." + config.Definition.Key;
148151
string key = added.Contains(initKey) ? initKey + added.Count : initKey;
149152

150-
// TODO: Figure out how to actually Localize config keys.
151-
// TODO: Add Key for SubCategories
153+
// TODO: Somehow support subcategories
154+
LocaleString nameKey = config.Definition.Key;
155+
LocaleString descKey = config.Description.Description;
156+
LocaleString defaultKey = $"{config.Definition.Key} : {valueType}";
157+
LocaleString valueKey = $"{config.Definition.Key} : {config.BoxedValue}";
152158

153-
string defaultKey = $"{config.Definition.Key} : {valueType}"; // "Settings.BepInEx.Plugins.Configs.Default".AsLocaleKey(("name", config.Definition.Key), ("type", valueType));
154-
string valueKey = $"{config.Definition.Key} : {config.BoxedValue}"; // "Settings.BepInEx.Plugins.Configs.Value".AsLocaleKey(("name", config.Definition.Key), ("value", config.BoxedValue));
155-
string nameKey = config.Definition.Key; // "Settings.BepInEx.Plugins.Configs.Name".AsLocaleKey(("name", config.Definition.Key));
156-
string descKey = config.Description.Description; // "Settings.BepInEx.Plugins.Configs.Description".AsLocaleKey(("description", config.Description.Description));
159+
bool hasLocale = LocaleLoader.PluginsWithLocales.Any(x => x.Metadata.GUID == metaData.ID);
160+
if (hasLocale && config.Description.Tags.FirstOrDefault(x => x is ConfigLocale) is ConfigLocale localeString)
161+
{
162+
nameKey = localeString.Name;
163+
descKey = localeString.Description;
157164

158-
// if (SettingsLocaleHelper.PluginsWithLocales.Any(x => x.Metadata.GUID == metaData.ID))
159-
// {
160-
// nameKey = config.Definition.Key.AsLocaleKey();
161-
// descKey = config.Description.Description.AsLocaleKey();
162-
//
163-
// defaultKey = $"Settings.{metaData.ID}.Configs.Default".AsLocaleKey(("name", nameKey.content), ("type", valueType));
164-
// valueKey = $"Settings.{metaData.ID}.Configs.Value".AsLocaleKey(("name", nameKey.content), ("value", config.BoxedValue));
165-
// }
165+
string formatted = localeString.Name.content.GetFormattedLocaleString();
166+
defaultKey = $"{formatted} : {valueType}";
167+
valueKey = $"{formatted} : {config.BoxedValue}";
168+
}
169+
170+
InternalLocale internalLocale = new InternalLocale(nameKey, descKey);
166171

167172
added.Add(key);
168173

@@ -172,7 +177,7 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
172177
{
173178
DataFeedItem dummyField = null;
174179

175-
if (config.Description.Tags.Contains("Action") && config.Description.Tags.FirstOrDefault(x => x is Delegate) is Delegate del)
180+
if (config.Description.Tags.FirstOrDefault(x => x is ActionConfig) is ActionConfig action)
176181
{
177182
DataFeedAction actionField = new DataFeedAction();
178183
actionField.InitBase(key, path, groupingKeys, nameKey, descKey);
@@ -181,23 +186,37 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
181186
Button btn = syncDelegate.Slot.GetComponent<Button>();
182187
if (btn == null) return;
183188

184-
btn.LocalPressed += (_, _) => del.DynamicInvoke();
189+
btn.LocalPressed += (_, _) => action.Invoke();
185190
});
186191

187192
dummyField = actionField;
188193
}
189194

190-
if (dummyField == null)
195+
bool customUi = false;
196+
if (config.Description.Tags.FirstOrDefault(x => x is CustomDataFeed) is CustomDataFeed customDataFeed)
197+
{
198+
customUi = true;
199+
IAsyncEnumerable<DataFeedItem> datafeed = customDataFeed.Build(path, groupingKeys);
200+
await foreach (DataFeedItem item in datafeed)
201+
{
202+
yield return item;
203+
}
204+
}
205+
206+
if (dummyField == null && !customUi)
191207
{
192208
dummyField = new DataFeedValueField<dummy>();
193209
dummyField.InitBase(key, path, groupingKeys, nameKey, descKey);
194210
}
195-
196-
yield return dummyField;
211+
212+
if (!customUi)
213+
{
214+
yield return dummyField;
215+
}
197216
}
198217
else if (valueType == typeof(bool))
199218
{
200-
yield return DataFeedHelpers.GenerateToggle(key, path, groupingKeys, config);
219+
yield return DataFeedHelpers.GenerateToggle(key, path, groupingKeys, internalLocale, config);
201220
}
202221
else if (valueType.IsEnum)
203222
{
@@ -215,7 +234,7 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
215234
}
216235
else
217236
{
218-
enumItem = (DataFeedItem)DataFeedHelpers.GenerateEnumItemsAsync.MakeGenericMethod(valueType).Invoke(null, [key, path, groupingKeys, config]);
237+
enumItem = (DataFeedItem)DataFeedHelpers.GenerateEnumItemsAsync.MakeGenericMethod(valueType).Invoke(null, [key, path, groupingKeys, internalLocale, config]);
219238
}
220239
}
221240
catch (Exception e)
@@ -236,7 +255,7 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
236255

237256
try
238257
{
239-
nullableEnumItems = (IAsyncEnumerable<DataFeedItem>)DataFeedHelpers.GenerateNullableEnumItemsAsync.MakeGenericMethod(nullableType).Invoke(null, [key, path, groupingKeys, config]);
258+
nullableEnumItems = (IAsyncEnumerable<DataFeedItem>)DataFeedHelpers.GenerateNullableEnumItemsAsync.MakeGenericMethod(nullableType).Invoke(null, [key, path, groupingKeys, internalLocale, config]);
240259
}
241260
catch (Exception e)
242261
{
@@ -261,11 +280,11 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
261280
{
262281
if (!config.SettingType.IsTypeInjectable() && TomlTypeConverter.CanConvert(config.SettingType))
263282
{
264-
valueItem = DataFeedHelpers.GenerateProxyField(key, path, groupingKeys, config);
283+
valueItem = DataFeedHelpers.GenerateProxyField(key, path, groupingKeys, internalLocale, config);
265284
}
266285
else
267286
{
268-
valueItem = (DataFeedItem)DataFeedHelpers.GenerateValueField.MakeGenericMethod(valueType).Invoke(null, [key, path, groupingKeys, config]);
287+
valueItem = (DataFeedItem)DataFeedHelpers.GenerateValueField.MakeGenericMethod(valueType).Invoke(null, [key, path, groupingKeys, internalLocale, config]);
269288
}
270289
}
271290
catch (Exception e)
@@ -292,7 +311,7 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigs(ConfigFile
292311
{
293312
Button btn = syncDelegate.Slot.GetComponent<Button>();
294313
if (btn == null) return;
295-
314+
296315
btn.LocalPressed += (_, _) => LoadConfigs(metaData.ID);
297316
});
298317
yield return loadAct;
@@ -348,6 +367,7 @@ private static async IAsyncEnumerable<DataFeedItem> GetDummyAsync(DataFeedItem i
348367

349368
yield return item;
350369
}
370+
351371
private static void LoadConfigs(string pluginId)
352372
{
353373
Plugin.Log.LogDebug($"Loading Configs for {pluginId}");

BepisModSettings/DataFeeds/BepisSettingsPage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ internal static async IAsyncEnumerable<DataFeedItem> Enumerate(IReadOnlyList<str
2323
pluginsGrid.InitBase("PluginsGrid", path, ["BepInExPlugins"], "Settings.BepInEx.LoadedPlugins".AsLocaleKey());
2424
yield return pluginsGrid;
2525

26-
string[] loadedPluginsGroup = new[] { "BepInExPlugins", "PluginsGrid" };
26+
string[] loadedPluginsGroup = ["BepInExPlugins", "PluginsGrid"];
2727

2828
if (NetChainloader.Instance.Plugins.Count > 0)
2929
{
@@ -65,7 +65,7 @@ internal static async IAsyncEnumerable<DataFeedItem> Enumerate(IReadOnlyList<str
6565
coreGroup.InitBase("BepInExCore", path, null, "Settings.BepInEx.Core".AsLocaleKey());
6666
yield return coreGroup;
6767

68-
string[] coreGroupParam = new[] { "BepInExCore" };
68+
string[] coreGroupParam = ["BepInExCore"];
6969

7070
DataFeedCategory bepisCategory = new DataFeedCategory();
7171
bepisCategory.InitBase("BepInEx.Core.Config", path, coreGroupParam, "Settings.BepInEx.Core.Config".AsLocaleKey());

0 commit comments

Comments
 (0)