From dcf557ca46411351d4de9d81dbfd28487e9a8218 Mon Sep 17 00:00:00 2001 From: XtraCube <72575280+XtraCube@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:57:10 -0500 Subject: [PATCH 1/3] optimize plugin loading --- MiraAPI/PluginLoading/MiraPluginManager.cs | 157 ++++++++++----------- 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index acb6ebe..8dc0f17 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -38,17 +38,26 @@ internal void Initialize() } var info = new MiraPluginInfo(miraPlugin, pluginInfo); + var roles = new List(); - RegisterModifierAttribute(assembly); - RegisterAllOptions(assembly, info); + foreach (var type in assembly.GetTypes()) + { + RegisterModifierAttribute(type); + RegisterOptions(type, info); - RegisterRoleAttribute(assembly, info); - RegisterButtonAttribute(assembly, info); + if (RegisterRoleAttribute(type, info, out var role)) + { + roles.Add(role!); + } - RegisterColorClasses(assembly); + RegisterButtonAttribute(type, info); + RegisterColorClasses(type); + } - _registeredPlugins.Add(assembly, info); + info.OptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority)); + CustomRoleManager.RegisterRoleTypes(roles, info); + _registeredPlugins.Add(assembly, info); Logger.Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API."); }; IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors; @@ -65,121 +74,107 @@ public static MiraPluginInfo GetPluginByGuid(string guid) return Instance._registeredPlugins.Values.First(plugin => plugin.PluginId == guid); } - private static void RegisterAllOptions(Assembly assembly, MiraPluginInfo pluginInfo) + private static void RegisterOptions(Type type, MiraPluginInfo pluginInfo) { - var filteredTypes = assembly.GetTypes().Where(type => type.IsAssignableTo(typeof(AbstractOptionGroup))); + if (!type.IsAssignableTo(typeof(AbstractOptionGroup))) + { + return; + } + + if (!ModdedOptionsManager.RegisterGroup(type, pluginInfo)) + { + return; + } - foreach (var type in filteredTypes) + foreach (var property in type.GetProperties()) { - if (!ModdedOptionsManager.RegisterGroup(type, pluginInfo)) + if (property.PropertyType.IsAssignableTo(typeof(IModdedOption))) { + ModdedOptionsManager.RegisterPropertyOption(type, property, pluginInfo); continue; } - foreach (var property in type.GetProperties()) + var attribute = property.GetCustomAttribute(); + if (attribute == null) { - if (property.PropertyType.IsAssignableTo(typeof(IModdedOption))) - { - ModdedOptionsManager.RegisterPropertyOption(type, property, pluginInfo); - continue; - } - - var attribute = property.GetCustomAttribute(); - if (attribute == null) - { - continue; - } - - ModdedOptionsManager.RegisterAttributeOption(type, attribute, property, pluginInfo); + continue; } - } - pluginInfo.OptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority)); + ModdedOptionsManager.RegisterAttributeOption(type, attribute, property, pluginInfo); + } } - private static void RegisterRoleAttribute(Assembly assembly, MiraPluginInfo pluginInfo) + private static bool RegisterRoleAttribute(Type type, MiraPluginInfo pluginInfo, out Type? role) { - List roles = []; - foreach (var type in assembly.GetTypes()) - { - var attribute = type.GetCustomAttribute(); - if (attribute == null) - { - continue; - } + role = null; - if (!(typeof(RoleBehaviour).IsAssignableFrom(type) && typeof(ICustomRole).IsAssignableFrom(type))) - { - Logger.Error($"{type.Name} does not inherit from RoleBehaviour or ICustomRole."); - continue; - } + var attribute = type.GetCustomAttribute(); + if (attribute == null) + { + return false; + } - if (!ModList.GetById(pluginInfo.PluginId).IsRequiredOnAllClients) - { - Logger.Error("Custom roles are only supported on all clients."); - return; - } + if (!(typeof(RoleBehaviour).IsAssignableFrom(type) && typeof(ICustomRole).IsAssignableFrom(type))) + { + Logger.Error($"{type.Name} does not inherit from RoleBehaviour or ICustomRole."); + return false; + } - roles.Add(type); + if (!ModList.GetById(pluginInfo.PluginId).IsRequiredOnAllClients) + { + Logger.Error("Custom roles are only supported on all clients."); + return false; } - CustomRoleManager.RegisterRoleTypes(roles, pluginInfo); + role = type; + return true; } - private static void RegisterColorClasses(Assembly assembly) + private static void RegisterColorClasses(Type type) { - foreach (var type in assembly.GetTypes()) + if (type.GetCustomAttribute() == null) { - if (type.GetCustomAttribute() == null) + return; + } + + if (!type.IsStatic()) + { + Logger.Error($"Color class {type.Name} must be static."); + return; + } + + foreach (var property in type.GetProperties()) + { + if (property.PropertyType != typeof(CustomColor)) { continue; } - if (!type.IsStatic()) + if (property.GetValue(null) is not CustomColor color) { - Logger.Error($"Color class {type.Name} must be static."); + Logger.Error($"Color property {property.Name} in {type.Name} is not a CustomColor."); continue; } - foreach (var property in type.GetProperties()) - { - if (property.PropertyType != typeof(CustomColor)) - { - continue; - } - - if (property.GetValue(null) is not CustomColor color) - { - Logger.Error($"Color property {property.Name} in {type.Name} is not a CustomColor."); - continue; - } - - PaletteManager.CustomColors.Add(color); - } + PaletteManager.CustomColors.Add(color); } } - private static void RegisterModifierAttribute(Assembly assembly) + private static void RegisterModifierAttribute(Type type) { - foreach (var type in assembly.GetTypes()) + var attribute = type.GetCustomAttribute(); + if (attribute != null) { - var attribute = type.GetCustomAttribute(); - if (attribute != null) - { - ModifierManager.RegisterModifier(type); - } + ModifierManager.RegisterModifier(type); } } - private static void RegisterButtonAttribute(Assembly assembly, MiraPluginInfo pluginInfo) + private static void RegisterButtonAttribute(Type type, MiraPluginInfo pluginInfo) { - foreach (var type in assembly.GetTypes()) + var attribute = type.GetCustomAttribute(); + if (attribute != null) { - var attribute = type.GetCustomAttribute(); - if (attribute != null) - { - CustomButtonManager.RegisterButton(type, pluginInfo); - } + CustomButtonManager.RegisterButton(type, pluginInfo); } } } From 145ae304ebb890f456b73d0a2317b656088ffdb7 Mon Sep 17 00:00:00 2001 From: XtraCube <72575280+XtraCube@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:59:44 -0500 Subject: [PATCH 2/3] remove extra thingy --- MiraAPI/Utilities/Extensions.cs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/MiraAPI/Utilities/Extensions.cs b/MiraAPI/Utilities/Extensions.cs index 636601b..da51eec 100644 --- a/MiraAPI/Utilities/Extensions.cs +++ b/MiraAPI/Utilities/Extensions.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using UnityEngine; namespace MiraAPI.Utilities; @@ -18,22 +17,6 @@ namespace MiraAPI.Utilities; /// public static class Extensions { - public static IEnumerable GetTypesSafe(this Assembly assembly) - { - try - { - return assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - return ex.Types.Where(t => t != null); - } - catch - { - return Enumerable.Empty(); - } - } - internal static NetData GetNetData(this ICustomRole role) { var count = role.GetCount(); From e569c270103bfcf1c64af0df4fd1362dd1f97bbf Mon Sep 17 00:00:00 2001 From: XtraCube <72575280+XtraCube@users.noreply.github.com> Date: Mon, 3 Feb 2025 21:58:57 -0500 Subject: [PATCH 3/3] replace most attributes and add MiraDisableAttribute.cs --- .../Buttons/Freezer/FreezeButton.cs | 1 - MiraAPI.Example/Buttons/MeetingButton.cs | 1 - .../Buttons/Teleporter/TeleportButton.cs | 1 - MiraAPI.Example/Modifiers/CaptainModifier.cs | 1 - .../Modifiers/Freezer/FreezeModifier.cs | 1 - .../Modifiers/HighPriorityModifier.cs | 1 - MiraAPI.Example/Roles/ChameleonRole.cs | 1 - MiraAPI.Example/Roles/FreezerRole.cs | 1 - MiraAPI.Example/Roles/NeutralKillerRole.cs | 1 - MiraAPI.Example/Roles/TeleporterRole.cs | 1 - MiraAPI/GameModes/DefaultMode.cs | 1 - .../GameModes/RegisterGameModeAttribute.cs | 28 ------------------- MiraAPI/Hud/RegisterButtonAttribute.cs | 9 ------ .../Modifiers/RegisterModifierAttribute.cs | 9 ------ MiraAPI/PluginLoading/MiraDisableAttribute.cs | 9 ++++++ MiraAPI/PluginLoading/MiraPluginManager.cs | 21 ++++++-------- MiraAPI/Roles/RegisterCustomRoleAttribute.cs | 6 ---- 17 files changed, 18 insertions(+), 75 deletions(-) delete mode 100644 MiraAPI/GameModes/RegisterGameModeAttribute.cs delete mode 100644 MiraAPI/Hud/RegisterButtonAttribute.cs delete mode 100644 MiraAPI/Modifiers/RegisterModifierAttribute.cs create mode 100644 MiraAPI/PluginLoading/MiraDisableAttribute.cs delete mode 100644 MiraAPI/Roles/RegisterCustomRoleAttribute.cs diff --git a/MiraAPI.Example/Buttons/Freezer/FreezeButton.cs b/MiraAPI.Example/Buttons/Freezer/FreezeButton.cs index 8db98c7..e26405e 100644 --- a/MiraAPI.Example/Buttons/Freezer/FreezeButton.cs +++ b/MiraAPI.Example/Buttons/Freezer/FreezeButton.cs @@ -9,7 +9,6 @@ namespace MiraAPI.Example.Buttons.Freezer; -[RegisterButton] public class FreezeButton : CustomActionButton { public override string Name => "Freeze"; diff --git a/MiraAPI.Example/Buttons/MeetingButton.cs b/MiraAPI.Example/Buttons/MeetingButton.cs index 85b8ff1..fed4e1f 100644 --- a/MiraAPI.Example/Buttons/MeetingButton.cs +++ b/MiraAPI.Example/Buttons/MeetingButton.cs @@ -6,7 +6,6 @@ namespace MiraAPI.Example.Buttons; -[RegisterButton] public class MeetingButton : CustomActionButton { public override string Name => "Call Meeting"; diff --git a/MiraAPI.Example/Buttons/Teleporter/TeleportButton.cs b/MiraAPI.Example/Buttons/Teleporter/TeleportButton.cs index 564b738..9341596 100644 --- a/MiraAPI.Example/Buttons/Teleporter/TeleportButton.cs +++ b/MiraAPI.Example/Buttons/Teleporter/TeleportButton.cs @@ -9,7 +9,6 @@ namespace MiraAPI.Example.Buttons.Teleporter; -[RegisterButton] public class TeleportButton : CustomActionButton { public override string Name => "Teleport"; diff --git a/MiraAPI.Example/Modifiers/CaptainModifier.cs b/MiraAPI.Example/Modifiers/CaptainModifier.cs index 09c733c..60691a8 100644 --- a/MiraAPI.Example/Modifiers/CaptainModifier.cs +++ b/MiraAPI.Example/Modifiers/CaptainModifier.cs @@ -3,7 +3,6 @@ namespace MiraAPI.Example.Modifiers; -[RegisterModifier] public class CaptainModifier : GameModifier { public override string ModifierName => "Captain"; diff --git a/MiraAPI.Example/Modifiers/Freezer/FreezeModifier.cs b/MiraAPI.Example/Modifiers/Freezer/FreezeModifier.cs index 12a87ec..642e941 100644 --- a/MiraAPI.Example/Modifiers/Freezer/FreezeModifier.cs +++ b/MiraAPI.Example/Modifiers/Freezer/FreezeModifier.cs @@ -6,7 +6,6 @@ namespace MiraAPI.Example.Modifiers.Freezer; -[RegisterModifier] public class FreezeModifier : TimedModifier { public override string ModifierName => "Freezed"; diff --git a/MiraAPI.Example/Modifiers/HighPriorityModifier.cs b/MiraAPI.Example/Modifiers/HighPriorityModifier.cs index c96507a..b94c4d0 100644 --- a/MiraAPI.Example/Modifiers/HighPriorityModifier.cs +++ b/MiraAPI.Example/Modifiers/HighPriorityModifier.cs @@ -3,7 +3,6 @@ namespace MiraAPI.Example.Modifiers; -[RegisterModifier] public class HighPriorityModifier : GameModifier { public override string ModifierName => "High Priority"; diff --git a/MiraAPI.Example/Roles/ChameleonRole.cs b/MiraAPI.Example/Roles/ChameleonRole.cs index e3eb6c4..1f2f61f 100644 --- a/MiraAPI.Example/Roles/ChameleonRole.cs +++ b/MiraAPI.Example/Roles/ChameleonRole.cs @@ -4,7 +4,6 @@ namespace MiraAPI.Example.Roles; -[RegisterCustomRole] public class ChameloenRole : CrewmateRole, ICustomRole { public string RoleName => "Chamelon"; diff --git a/MiraAPI.Example/Roles/FreezerRole.cs b/MiraAPI.Example/Roles/FreezerRole.cs index 4f07124..bef24d2 100644 --- a/MiraAPI.Example/Roles/FreezerRole.cs +++ b/MiraAPI.Example/Roles/FreezerRole.cs @@ -3,7 +3,6 @@ namespace MiraAPI.Example.Roles; -[RegisterCustomRole] public class FreezerRole : ImpostorRole, ICustomRole { public string RoleName => "Freezer"; diff --git a/MiraAPI.Example/Roles/NeutralKillerRole.cs b/MiraAPI.Example/Roles/NeutralKillerRole.cs index 0eb60af..50a8810 100644 --- a/MiraAPI.Example/Roles/NeutralKillerRole.cs +++ b/MiraAPI.Example/Roles/NeutralKillerRole.cs @@ -3,7 +3,6 @@ namespace MiraAPI.Example.Roles; -[RegisterCustomRole] public class NeutralKillerRole : ImpostorRole, ICustomRole { public string RoleName => "Neutral Killer"; diff --git a/MiraAPI.Example/Roles/TeleporterRole.cs b/MiraAPI.Example/Roles/TeleporterRole.cs index 447e185..9877f84 100644 --- a/MiraAPI.Example/Roles/TeleporterRole.cs +++ b/MiraAPI.Example/Roles/TeleporterRole.cs @@ -3,7 +3,6 @@ namespace MiraAPI.Example.Roles; -[RegisterCustomRole] public class TeleporterRole : CrewmateRole, ICustomRole { public string RoleName => "Teleporter"; diff --git a/MiraAPI/GameModes/DefaultMode.cs b/MiraAPI/GameModes/DefaultMode.cs index 73c4ca8..83c11ba 100644 --- a/MiraAPI/GameModes/DefaultMode.cs +++ b/MiraAPI/GameModes/DefaultMode.cs @@ -1,6 +1,5 @@ namespace MiraAPI.GameModes; -[RegisterGameMode] public class DefaultMode : CustomGameMode { public override string Name => "Default"; diff --git a/MiraAPI/GameModes/RegisterGameModeAttribute.cs b/MiraAPI/GameModes/RegisterGameModeAttribute.cs deleted file mode 100644 index 4c66c35..0000000 --- a/MiraAPI/GameModes/RegisterGameModeAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace MiraAPI.GameModes; - -[AttributeUsage(AttributeTargets.Class)] -public class RegisterGameModeAttribute : Attribute -{ - private static readonly HashSet RegisteredAssemblies = []; - - internal static void Register(Assembly assembly) - { - if (!RegisteredAssemblies.Add(assembly)) - { - return; - } - - foreach (var type in assembly.GetTypes()) - { - var attribute = type.GetCustomAttribute(); - if (attribute != null) - { - CustomGameModeManager.RegisterGameMode(type); - } - } - } -} diff --git a/MiraAPI/Hud/RegisterButtonAttribute.cs b/MiraAPI/Hud/RegisterButtonAttribute.cs deleted file mode 100644 index 82e0ca5..0000000 --- a/MiraAPI/Hud/RegisterButtonAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace MiraAPI.Hud; - -/// -/// Attribute to register a button in the HUD. Necessary for the button to be recognized by Mira. -/// -[AttributeUsage(AttributeTargets.Class)] -public class RegisterButtonAttribute : Attribute; diff --git a/MiraAPI/Modifiers/RegisterModifierAttribute.cs b/MiraAPI/Modifiers/RegisterModifierAttribute.cs deleted file mode 100644 index 4858b96..0000000 --- a/MiraAPI/Modifiers/RegisterModifierAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace MiraAPI.Modifiers; - -/// -/// Marks a class as a modifier that can be registered with the . -/// -[AttributeUsage(AttributeTargets.Class)] -public class RegisterModifierAttribute : Attribute; diff --git a/MiraAPI/PluginLoading/MiraDisableAttribute.cs b/MiraAPI/PluginLoading/MiraDisableAttribute.cs new file mode 100644 index 0000000..23c1e28 --- /dev/null +++ b/MiraAPI/PluginLoading/MiraDisableAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace MiraAPI.PluginLoading; + +/// +/// Skip an element during plugin loading. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] +public class MiraDisableAttribute : Attribute; diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index 8dc0f17..5c8e573 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -42,7 +42,12 @@ internal void Initialize() foreach (var type in assembly.GetTypes()) { - RegisterModifierAttribute(type); + if (type.GetCustomAttribute() != null) + { + continue; + } + + RegisterModifier(type); RegisterOptions(type, info); if (RegisterRoleAttribute(type, info, out var role)) @@ -108,12 +113,6 @@ private static bool RegisterRoleAttribute(Type type, MiraPluginInfo pluginInfo, { role = null; - var attribute = type.GetCustomAttribute(); - if (attribute == null) - { - return false; - } - if (!(typeof(RoleBehaviour).IsAssignableFrom(type) && typeof(ICustomRole).IsAssignableFrom(type))) { Logger.Error($"{type.Name} does not inherit from RoleBehaviour or ICustomRole."); @@ -160,10 +159,9 @@ private static void RegisterColorClasses(Type type) } } - private static void RegisterModifierAttribute(Type type) + private static void RegisterModifier(Type type) { - var attribute = type.GetCustomAttribute(); - if (attribute != null) + if (type.IsAssignableTo(typeof(BaseModifier))) { ModifierManager.RegisterModifier(type); } @@ -171,8 +169,7 @@ private static void RegisterModifierAttribute(Type type) private static void RegisterButtonAttribute(Type type, MiraPluginInfo pluginInfo) { - var attribute = type.GetCustomAttribute(); - if (attribute != null) + if (type.IsAssignableTo(typeof(CustomActionButton)) || type.IsAssignableTo(typeof(CustomActionButton<>))) { CustomButtonManager.RegisterButton(type, pluginInfo); } diff --git a/MiraAPI/Roles/RegisterCustomRoleAttribute.cs b/MiraAPI/Roles/RegisterCustomRoleAttribute.cs deleted file mode 100644 index a6352f1..0000000 --- a/MiraAPI/Roles/RegisterCustomRoleAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System; - -namespace MiraAPI.Roles; - -[AttributeUsage(AttributeTargets.Class)] -public class RegisterCustomRoleAttribute : Attribute;