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;
}
}