diff --git a/Directory.Build.props b/Directory.Build.props
index 24401c1..52706c7 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,7 +1,7 @@
enable
- 3.4.0
+ 3.5.0-beta1
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 38f22b4..d961ed5 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -19,4 +19,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SecretAPI.Examples/ExampleEntry.cs b/SecretAPI.Examples/ExampleEntry.cs
index 1839237..8c0afc1 100644
--- a/SecretAPI.Examples/ExampleEntry.cs
+++ b/SecretAPI.Examples/ExampleEntry.cs
@@ -2,10 +2,12 @@
using System;
using HarmonyLib;
+using LabApi.Features.Console;
using LabApi.Loader.Features.Plugins;
using SecretAPI.Examples.Settings;
using SecretAPI.Extensions;
using SecretAPI.Features.UserSettings;
+using UserSettings.ServerSpecific;
///
/// Defines the entry for the plugin.
diff --git a/SecretAPI/Features/DecalHelpers.cs b/SecretAPI/Features/DecalHelpers.cs
index ce5f76e..acd9fac 100644
--- a/SecretAPI/Features/DecalHelpers.cs
+++ b/SecretAPI/Features/DecalHelpers.cs
@@ -1,10 +1,12 @@
namespace SecretAPI.Features;
using System;
+using CommandSystem.Commands.RemoteAdmin.Cleanup;
using Decals;
using InventorySystem.Items;
using InventorySystem.Items.Autosync;
using InventorySystem.Items.Firearms.Modules;
+using LabApi.Features.Wrappers;
using Mirror;
using RelativePositioning;
using UnityEngine;
@@ -86,6 +88,21 @@ public static void SpawnDecalFromDirection(Vector3 position, Vector3 direction,
public static void SpawnDecalFromDirection(Vector3 position, Quaternion direction, DecalPoolType type = DecalPoolType.Blood)
=> GetDecalMessage(position, position - (direction * Vector3.forward), type).SendToAuthenticated();
+ ///
+ /// Cleans up decals for all players.
+ ///
+ /// The to cleanup.
+ /// The amount of that decal to cleanup.
+ public static void CleanupDecals(DecalPoolType decalType, int amount = int.MaxValue) => new DecalCleanupMessage(decalType, amount).SendToAuthenticated();
+
+ ///
+ /// Cleans up decals for a specific player.
+ ///
+ /// The player to clean up decals for.
+ /// The to cleanup.
+ /// The amount of that decal to cleanup.
+ public static void CleanUpDecals(this Player player, DecalPoolType decalType, int amount = int.MaxValue) => new DecalCleanupMessage(decalType, amount).SendToHubsConditionally(hub => hub == player.ReferenceHub);
+
private static AutoSyncData GetAutoSyncData()
{
if (autoSyncData != null)
diff --git a/SecretAPI/Features/Effects/CustomPlayerEffect.cs b/SecretAPI/Features/Effects/CustomPlayerEffect.cs
index 13699b4..394d3a3 100644
--- a/SecretAPI/Features/Effects/CustomPlayerEffect.cs
+++ b/SecretAPI/Features/Effects/CustomPlayerEffect.cs
@@ -55,6 +55,12 @@ public static void Register(Type type)
}
#pragma warning disable CS0618 // Type or member is obsolete
+ if (EffectsToRegister.Contains(type))
+ {
+ Logger.Error("[CustomPlayerEffect.Register] {type} is already registered!");
+ return;
+ }
+
EffectsToRegister.Add(type);
}
diff --git a/SecretAPI/Features/IPriority.cs b/SecretAPI/Features/IPriority.cs
index 6f0666b..24214c6 100644
--- a/SecretAPI/Features/IPriority.cs
+++ b/SecretAPI/Features/IPriority.cs
@@ -1,7 +1,7 @@
namespace SecretAPI.Features;
///
-/// Handles IPriority.
+/// Handles priority on certain things.
///
public interface IPriority
{
diff --git a/SecretAPI/Features/IRegister.cs b/SecretAPI/Features/IRegister.cs
index 91bb494..a5a5bab 100644
--- a/SecretAPI/Features/IRegister.cs
+++ b/SecretAPI/Features/IRegister.cs
@@ -2,11 +2,13 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
///
/// Interface used to define a type that should auto register.
///
+/// This supports , will default to 0 if not implemented.
// TODO: Source generate this
public interface IRegister
{
@@ -25,7 +27,7 @@ public interface IRegister
///
public void TryUnregister()
{
- // default empty to prevent breaking change
+ // default to empty
}
///
@@ -38,6 +40,7 @@ public static void RegisterAll(Assembly? assembly = null)
registerables.TryAdd(assembly, new());
+ List registers = new();
foreach (Type type in assembly.GetTypes())
{
if (type.IsAbstract || type.IsInterface)
@@ -46,10 +49,14 @@ public static void RegisterAll(Assembly? assembly = null)
if (!typeof(IRegister).IsAssignableFrom(type))
continue;
- object obj = Activator.CreateInstance(type);
- if (obj is not IRegister register)
+ if (Activator.CreateInstance(type) is not IRegister register)
continue;
+ registers.Add(register);
+ }
+
+ foreach (IRegister register in registers.OrderBy(x => x is IPriority priority ? priority.Priority : 0))
+ {
registerables[assembly].Add(register);
register.TryRegister();
}
diff --git a/SecretAPI/Features/Registry.cs b/SecretAPI/Features/Registry.cs
index 2aae151..8103a70 100644
--- a/SecretAPI/Features/Registry.cs
+++ b/SecretAPI/Features/Registry.cs
@@ -1,11 +1,13 @@
namespace SecretAPI.Features;
+using System;
using System.Collections.Generic;
///
/// Handles the registration of objects and ids.
///
/// The type of the registry.
+[Obsolete("This will be removed in 4.0")]
public static class Registry
{
///
diff --git a/SecretAPI/Features/UserSettings/CustomButtonSetting.cs b/SecretAPI/Features/UserSettings/CustomButtonSetting.cs
index df65faa..b79dc4e 100644
--- a/SecretAPI/Features/UserSettings/CustomButtonSetting.cs
+++ b/SecretAPI/Features/UserSettings/CustomButtonSetting.cs
@@ -56,6 +56,11 @@ protected CustomButtonSetting(int? id, string label, string buttonText, float? h
///
public bool EverPressed => LastPressWatch.IsRunning;
+ ///
+ /// Gets the amount of times the button has been pressed.
+ ///
+ public uint TimesPressed { get; private set; }
+
///
/// Gets or sets the text of the button.
///
@@ -82,6 +87,13 @@ public float RequiredHoldTime
}
}
+ ///
+ protected override void HandleBeforeSettingUpdate()
+ {
+ base.HandleBeforeSettingUpdate();
+ TimesPressed++;
+ }
+
///
/// Sends an update to that or has updated.
///
diff --git a/SecretAPI/Features/UserSettings/CustomSetting.cs b/SecretAPI/Features/UserSettings/CustomSetting.cs
index 5715e44..2e51bc7 100644
--- a/SecretAPI/Features/UserSettings/CustomSetting.cs
+++ b/SecretAPI/Features/UserSettings/CustomSetting.cs
@@ -164,7 +164,7 @@ public static void Register(IEnumerable settings)
{
foreach (CustomSetting setting in settings)
{
- if (ValidateSettingInternal(setting, null))
+ if (ValidateSettingInternal(setting, null, null))
CustomSettings.Add(setting);
}
}
@@ -346,9 +346,12 @@ public static void SendSettingsToPlayer(Player player, int? version = null)
///
/// The to validate.
/// The to validate.
+ /// The current .
/// Whether the setting is validated and considered fine.
- internal static bool ValidateSettingInternal(CustomSetting? setting, ServerSpecificSettingBase? settingBase)
+ internal static bool ValidateSettingInternal(CustomSetting? setting, ServerSpecificSettingBase? settingBase, ServerSpecificSettingBase[]? definedSettings)
{
+ definedSettings ??= ServerSpecificSettingsSync.DefinedSettings;
+
if (settingBase == null && setting == null)
{
Logger.Error("[CustomSetting.TryValidateSetting] Failed to validate null setting! " + new StackTrace(1));
@@ -362,7 +365,7 @@ internal static bool ValidateSettingInternal(CustomSetting? setting, ServerSpeci
string validateSettingName = setting?.GetType().FullName ?? settingBase?.Label ?? "[Unknown]";
int? id = setting?.Id ?? settingBase?.SettingId;
- string? sharedIdInfo = CustomSettings.FirstOrDefault(s => s.Id == id)?.GetType().FullName ?? ServerSpecificSettingsSync.DefinedSettings.FirstOrDefault(s => s.SettingId == id && s is not SSGroupHeader)?.Label;
+ string? sharedIdInfo = CustomSettings.FirstOrDefault(s => s.Id == id && setting != s)?.GetType().FullName ?? definedSettings.FirstOrDefault(s => s.SettingId == id && s != settingBase && s is not SSGroupHeader)?.Label;
if (sharedIdInfo != null)
{
Logger.Error($"[CustomSetting.TryValidateSetting] {validateSettingName} is being registered with a duplicate ID ({id}) shared by {sharedIdInfo} {new StackTrace(1)}");
diff --git a/SecretAPI/Patches/Features/Settings/ReportDefinedSettingPatch.cs b/SecretAPI/Patches/Features/Settings/ReportDefinedSettingPatch.cs
index 30ec0c5..acfd1b5 100644
--- a/SecretAPI/Patches/Features/Settings/ReportDefinedSettingPatch.cs
+++ b/SecretAPI/Patches/Features/Settings/ReportDefinedSettingPatch.cs
@@ -8,22 +8,22 @@
using UserSettings.ServerSpecific;
///
-/// Logs issues with .
+/// Logs issues with and prevents them being registered.
///
[HarmonyPatchCategory(nameof(CustomSetting))]
[HarmonyPatch(typeof(ServerSpecificSettingsSync), nameof(ServerSpecificSettingsSync.DefinedSettings), MethodType.Setter)]
internal static class ReportDefinedSettingPatch
{
- private static void Postfix(ref ServerSpecificSettingBase[] value)
+ private static void Prefix(ref ServerSpecificSettingBase[] value)
{
- // OLD : value.ForEach(setting => CustomSetting.ValidateSettingInternal(null, setting));
List settings = ListPool.Shared.Rent();
foreach (ServerSpecificSettingBase setting in value)
{
- if (CustomSetting.ValidateSettingInternal(null, setting))
+ if (CustomSetting.ValidateSettingInternal(null, setting, value))
settings.Add(setting);
}
value = settings.ToArray();
+ ListPool.Shared.Return(settings);
}
}
\ No newline at end of file