diff --git a/BepisModSettings/ConfigAttributes/ActionConfig.cs b/BepisModSettings/ConfigAttributes/ActionConfig.cs new file mode 100644 index 0000000..ab5a6e5 --- /dev/null +++ b/BepisModSettings/ConfigAttributes/ActionConfig.cs @@ -0,0 +1,30 @@ +using System; + +namespace BepisModSettings.ConfigAttributes; + +public class ActionConfig(Delegate action) +{ + public Delegate Action { get; } = action ?? throw new ArgumentNullException(nameof(action)); + + public object Invoke(params object[] args) => Action.DynamicInvoke(args); +} + +public class ActionConfig(Action action) : ActionConfig(action) +{ + public void Invoke(T arg) => ((Action)Action)(arg); +} + +public class ActionConfig(Action action) : ActionConfig(action) +{ + public void Invoke(T1 arg1, T2 arg2) => ((Action)Action)(arg1, arg2); +} + +public class FuncConfig(Func func) : ActionConfig(func) +{ + public TResult Invoke() => ((Func)Action)(); +} + +public class FuncConfig(Func func) : ActionConfig(func) +{ + public TResult Invoke(T arg) => ((Func)Action)(arg); +} \ No newline at end of file diff --git a/BepisModSettings/ConfigAttributes/CustomDataFeed.cs b/BepisModSettings/ConfigAttributes/CustomDataFeed.cs new file mode 100644 index 0000000..b5dff62 --- /dev/null +++ b/BepisModSettings/ConfigAttributes/CustomDataFeed.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using FrooxEngine; + +namespace BepisModSettings.ConfigAttributes; + +public delegate IAsyncEnumerable DataFeedMethod(IReadOnlyList path, IReadOnlyList groupKeys); + +public sealed class CustomDataFeed(DataFeedMethod action) +{ + private readonly DataFeedMethod _action = action ?? throw new ArgumentNullException(nameof(action)); + + public IAsyncEnumerable Build(IReadOnlyList path, IReadOnlyList groupKeys) + { + ArgumentNullException.ThrowIfNull(path); + + return _action(path, groupKeys); + } +} \ No newline at end of file diff --git a/BepisModSettings/ConfigAttributes/HiddenConfig.cs b/BepisModSettings/ConfigAttributes/HiddenConfig.cs new file mode 100644 index 0000000..7c351b4 --- /dev/null +++ b/BepisModSettings/ConfigAttributes/HiddenConfig.cs @@ -0,0 +1,3 @@ +namespace BepisModSettings.ConfigAttributes; + +public class HiddenConfig { } \ No newline at end of file diff --git a/BepisModSettings/ConfigAttributes/ProtectedConfig.cs b/BepisModSettings/ConfigAttributes/ProtectedConfig.cs new file mode 100644 index 0000000..74ce550 --- /dev/null +++ b/BepisModSettings/ConfigAttributes/ProtectedConfig.cs @@ -0,0 +1,8 @@ +namespace BepisModSettings.ConfigAttributes; + +public class ProtectedConfig(string maskString) +{ + public ProtectedConfig() : this("*") { } + + public string MaskString { get; } = maskString; +} \ No newline at end of file diff --git a/BepisModSettings/DataFeeds/BepisNestedCategoryPage.cs b/BepisModSettings/DataFeeds/BepisNestedCategoryPage.cs index 4afbc17..f6a8287 100644 --- a/BepisModSettings/DataFeeds/BepisNestedCategoryPage.cs +++ b/BepisModSettings/DataFeeds/BepisNestedCategoryPage.cs @@ -21,9 +21,9 @@ internal static async IAsyncEnumerable Enumerate(IReadOnlyList Enumerate(IReadOnlyList idIndicator = new DataFeedIndicator(); idIndicator.InitBase("Id", path, metadataGroup, "Settings.BepInEx.Plugins.Guid".AsLocaleKey()); @@ -119,6 +120,8 @@ private static async IAsyncEnumerable EnumerateConfigs(ConfigFile List added = new List(); foreach (ConfigEntryBase config in configFile.Values) { + if (!Plugin.ShowHidden.Value && config.Description.Tags.Any(x => x is HiddenConfig)) continue; + Type valueType = config.SettingType; string section = config.Definition.Section; @@ -147,22 +150,24 @@ private static async IAsyncEnumerable EnumerateConfigs(ConfigFile string initKey = section + "." + config.Definition.Key; string key = added.Contains(initKey) ? initKey + added.Count : initKey; - // TODO: Figure out how to actually Localize config keys. - // TODO: Add Key for SubCategories + // TODO: Somehow support subcategories + LocaleString nameKey = config.Definition.Key; + LocaleString descKey = config.Description.Description; + LocaleString defaultKey = $"{config.Definition.Key} : {valueType}"; + LocaleString valueKey = $"{config.Definition.Key} : {config.BoxedValue}"; - string defaultKey = $"{config.Definition.Key} : {valueType}"; // "Settings.BepInEx.Plugins.Configs.Default".AsLocaleKey(("name", config.Definition.Key), ("type", valueType)); - string valueKey = $"{config.Definition.Key} : {config.BoxedValue}"; // "Settings.BepInEx.Plugins.Configs.Value".AsLocaleKey(("name", config.Definition.Key), ("value", config.BoxedValue)); - string nameKey = config.Definition.Key; // "Settings.BepInEx.Plugins.Configs.Name".AsLocaleKey(("name", config.Definition.Key)); - string descKey = config.Description.Description; // "Settings.BepInEx.Plugins.Configs.Description".AsLocaleKey(("description", config.Description.Description)); + bool hasLocale = LocaleLoader.PluginsWithLocales.Any(x => x.Metadata.GUID == metaData.ID); + if (hasLocale && config.Description.Tags.FirstOrDefault(x => x is ConfigLocale) is ConfigLocale localeString) + { + nameKey = localeString.Name; + descKey = localeString.Description; - // if (SettingsLocaleHelper.PluginsWithLocales.Any(x => x.Metadata.GUID == metaData.ID)) - // { - // nameKey = config.Definition.Key.AsLocaleKey(); - // descKey = config.Description.Description.AsLocaleKey(); - // - // defaultKey = $"Settings.{metaData.ID}.Configs.Default".AsLocaleKey(("name", nameKey.content), ("type", valueType)); - // valueKey = $"Settings.{metaData.ID}.Configs.Value".AsLocaleKey(("name", nameKey.content), ("value", config.BoxedValue)); - // } + string formatted = localeString.Name.content.GetFormattedLocaleString(); + defaultKey = $"{formatted} : {valueType}"; + valueKey = $"{formatted} : {config.BoxedValue}"; + } + + InternalLocale internalLocale = new InternalLocale(nameKey, descKey); added.Add(key); @@ -172,7 +177,7 @@ private static async IAsyncEnumerable EnumerateConfigs(ConfigFile { DataFeedItem dummyField = null; - if (config.Description.Tags.Contains("Action") && config.Description.Tags.FirstOrDefault(x => x is Delegate) is Delegate del) + if (config.Description.Tags.FirstOrDefault(x => x is ActionConfig) is ActionConfig action) { DataFeedAction actionField = new DataFeedAction(); actionField.InitBase(key, path, groupingKeys, nameKey, descKey); @@ -181,23 +186,37 @@ private static async IAsyncEnumerable EnumerateConfigs(ConfigFile Button btn = syncDelegate.Slot.GetComponent