From cec60dbf6b0c45a266ab824c5117397c3e8db91c Mon Sep 17 00:00:00 2001 From: Eve <85962933+obvEve@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:22:23 +0200 Subject: [PATCH 1/3] Report issues with null settings/duplicate ids --- .../Features/UserSettings/CustomSetting.cs | 36 +++++++++++++++++-- .../Features/ReportDefinedSettingPatch.cs | 19 ++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 SecretAPI/Patches/Features/ReportDefinedSettingPatch.cs diff --git a/SecretAPI/Features/UserSettings/CustomSetting.cs b/SecretAPI/Features/UserSettings/CustomSetting.cs index 95e681b..09a1ba9 100644 --- a/SecretAPI/Features/UserSettings/CustomSetting.cs +++ b/SecretAPI/Features/UserSettings/CustomSetting.cs @@ -2,10 +2,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using global::UserSettings.ServerSpecific; using LabApi.Events.Handlers; +using LabApi.Features.Console; using LabApi.Features.Enums; using LabApi.Features.Wrappers; using Mirror; @@ -155,13 +157,22 @@ public bool IsShared /// Registers a collection of settings. /// /// The settings to register. - public static void Register(params CustomSetting[] settings) => CustomSettings.AddRange(settings); + public static void Register(params CustomSetting[] settings) + { + settings.ForEach(setting => ReportSettingIssue(setting, null)); + CustomSettings.AddRange(settings); + } /// /// Registers a collection of settings. /// /// The settings to register. - public static void Register(IEnumerable settings) => CustomSettings.AddRange(settings); + public static void Register(IEnumerable settings) + { + foreach (CustomSetting? setting in settings) + ReportSettingIssue(setting, null); + CustomSettings.AddRange(settings); + } /// /// Unregisters collection of settings. @@ -322,6 +333,27 @@ public static void SendSettingsToPlayer(Player player, int? version = null) ListPool.Shared.Return(playerSettings); } + /// + /// Reports issues with settings being registered. + /// + /// The to validate. + /// The to validate. + internal static void ReportSettingIssue(CustomSetting? setting, ServerSpecificSettingBase? settingBase) + { + if (settingBase == null && setting == null) + { + Logger.Error("[CustomSetting.TryValidateSetting] Failed to validate null setting! " + new StackTrace()); + return; + } + + int id = setting?.Id ?? settingBase!.SettingId; + if (CustomSettings.Any(s => s.Id == id) || ServerSpecificSettingsSync.DefinedSettings.Any(s => s.SettingId == id)) + { + Logger.Error($"Setting {setting?.GetType().FullName ?? settingBase?.Label ?? "UNKNOWN"} is being registered with an existing Id {id} {new StackTrace()}"); + return; + } + } + /// /// Checks whether a is equal to . /// diff --git a/SecretAPI/Patches/Features/ReportDefinedSettingPatch.cs b/SecretAPI/Patches/Features/ReportDefinedSettingPatch.cs new file mode 100644 index 0000000..cfe6581 --- /dev/null +++ b/SecretAPI/Patches/Features/ReportDefinedSettingPatch.cs @@ -0,0 +1,19 @@ +namespace SecretAPI.Patches.Features; + +using HarmonyLib; +using SecretAPI.Attributes; +using SecretAPI.Features.UserSettings; +using UserSettings.ServerSpecific; + +/// +/// Logs issues with . +/// +[HarmonyPatchCategory(nameof(CustomSetting))] +[HarmonyPatch(typeof(ServerSpecificSettingsSync), nameof(ServerSpecificSettingsSync.DefinedSettings), MethodType.Setter)] +internal static class ReportDefinedSettingPatch +{ + private static void Postfix(ref ServerSpecificSettingBase[] value) + { + value.ForEach(setting => CustomSetting.ReportSettingIssue(null, setting)); + } +} \ No newline at end of file From 3fa025625b1c790311825ba2359035e240d8ddbb Mon Sep 17 00:00:00 2001 From: Eve <85962933+obvEve@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:01:22 +0200 Subject: [PATCH 2/3] Change error message slightly --- SecretAPI/Features/UserSettings/CustomSetting.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SecretAPI/Features/UserSettings/CustomSetting.cs b/SecretAPI/Features/UserSettings/CustomSetting.cs index 09a1ba9..5dddcdb 100644 --- a/SecretAPI/Features/UserSettings/CustomSetting.cs +++ b/SecretAPI/Features/UserSettings/CustomSetting.cs @@ -349,7 +349,7 @@ internal static void ReportSettingIssue(CustomSetting? setting, ServerSpecificSe int id = setting?.Id ?? settingBase!.SettingId; if (CustomSettings.Any(s => s.Id == id) || ServerSpecificSettingsSync.DefinedSettings.Any(s => s.SettingId == id)) { - Logger.Error($"Setting {setting?.GetType().FullName ?? settingBase?.Label ?? "UNKNOWN"} is being registered with an existing Id {id} {new StackTrace()}"); + Logger.Error($"[CustomSetting.TryValidateSetting] {setting?.GetType().FullName ?? settingBase?.Label ?? "UNKNOWN"} is being registered with an existing Id {id} {new StackTrace()}"); return; } } From b1cea0808235545ec055cbdf820ee692b6aa95e8 Mon Sep 17 00:00:00 2001 From: Eve <85962933+obvEve@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:31:55 +0200 Subject: [PATCH 3/3] log the setting that is sharing the duplicate id --- SecretAPI/Features/UserSettings/CustomSetting.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SecretAPI/Features/UserSettings/CustomSetting.cs b/SecretAPI/Features/UserSettings/CustomSetting.cs index 5dddcdb..9280015 100644 --- a/SecretAPI/Features/UserSettings/CustomSetting.cs +++ b/SecretAPI/Features/UserSettings/CustomSetting.cs @@ -347,9 +347,10 @@ internal static void ReportSettingIssue(CustomSetting? setting, ServerSpecificSe } int id = setting?.Id ?? settingBase!.SettingId; - if (CustomSettings.Any(s => s.Id == id) || ServerSpecificSettingsSync.DefinedSettings.Any(s => s.SettingId == id)) + string? sharedIdInfo = CustomSettings.FirstOrDefault(s => s.Id == id)?.GetType().FullName ?? ServerSpecificSettingsSync.DefinedSettings.FirstOrDefault(s => s.SettingId == id)?.Label; + if (sharedIdInfo != null) { - Logger.Error($"[CustomSetting.TryValidateSetting] {setting?.GetType().FullName ?? settingBase?.Label ?? "UNKNOWN"} is being registered with an existing Id {id} {new StackTrace()}"); + Logger.Error($"[CustomSetting.TryValidateSetting] {setting?.GetType().FullName ?? settingBase?.Label ?? "UNKNOWN"} is being registered with a duplicate ID ({id}) shared by {sharedIdInfo} {new StackTrace()}"); return; } }