From dbacd044ebf90e654064f45316b88c4578a9c7f2 Mon Sep 17 00:00:00 2001 From: AlchlcDvl <56699741+AlchlcDvl@users.noreply.github.com> Date: Sat, 7 Dec 2024 10:46:26 -0500 Subject: [PATCH] game mode stuff, missing implementation of 4 methods coming soon:tm: --- AmongUs.props | 2 +- ...{CustomGameMode.cs => AbstractGameMode.cs} | 12 ++- MiraAPI/GameModes/CustomGameModeManager.cs | 100 +++++++++++------- MiraAPI/GameModes/DefaultMode.cs | 10 +- MiraAPI/GameModes/GameModeOption.cs | 18 ++++ .../GameModes/RegisterGameModeAttribute.cs | 27 +---- MiraAPI/MiraApiPlugin.cs | 12 ++- MiraAPI/Patches/GameModes/ConsolePatches.cs | 18 ++-- MiraAPI/Patches/GameModes/DeadBodyPatch.cs | 11 +- MiraAPI/Patches/GameModes/GameLogicPatches.cs | 6 +- MiraAPI/Patches/GameModes/HudPatches.cs | 12 +++ .../Patches/GameModes/ImpostorTargetPatch.cs | 11 +- .../Patches/GameModes/MapBehaviourPatch.cs | 9 +- MiraAPI/Patches/GameModes/OnDeathPatch.cs | 9 +- MiraAPI/Patches/GameModes/VentPatches.cs | 47 -------- MiraAPI/Patches/HudManagerPatches.cs | 11 -- MiraAPI/PluginLoading/MiraPluginInfo.cs | 15 ++- MiraAPI/PluginLoading/MiraPluginManager.cs | 51 ++++++++- 18 files changed, 216 insertions(+), 165 deletions(-) rename MiraAPI/GameModes/{CustomGameMode.cs => AbstractGameMode.cs} (95%) create mode 100644 MiraAPI/GameModes/GameModeOption.cs create mode 100644 MiraAPI/Patches/GameModes/HudPatches.cs delete mode 100644 MiraAPI/Patches/GameModes/VentPatches.cs diff --git a/AmongUs.props b/AmongUs.props index 33c571f..b83c764 100644 --- a/AmongUs.props +++ b/AmongUs.props @@ -2,7 +2,7 @@ - + diff --git a/MiraAPI/GameModes/CustomGameMode.cs b/MiraAPI/GameModes/AbstractGameMode.cs similarity index 95% rename from MiraAPI/GameModes/CustomGameMode.cs rename to MiraAPI/GameModes/AbstractGameMode.cs index c7cf639..466c282 100644 --- a/MiraAPI/GameModes/CustomGameMode.cs +++ b/MiraAPI/GameModes/AbstractGameMode.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; +using UnityEngine; namespace MiraAPI.GameModes; /// /// Base class for custom gamemodes. /// -public abstract class CustomGameMode +public abstract class AbstractGameMode { /// /// Gets the game mode name. @@ -18,9 +19,14 @@ public abstract class CustomGameMode public abstract string Description { get; } /// - /// Gets the game mode ID. + /// Gets the game mode description. /// - public abstract int Id { get; } + public virtual Color Color { get; } = Color.white; + + /// + /// Gets or sets the game mode id. + /// + public uint ID { get; set; } /// /// Called when Intro Cutscene is destroyed. diff --git a/MiraAPI/GameModes/CustomGameModeManager.cs b/MiraAPI/GameModes/CustomGameModeManager.cs index 388eb5d..62d27e2 100644 --- a/MiraAPI/GameModes/CustomGameModeManager.cs +++ b/MiraAPI/GameModes/CustomGameModeManager.cs @@ -1,7 +1,9 @@ -using Reactor.Utilities; -using System; +using System; using System.Collections.Generic; -using System.Linq; +using Il2CppSystem.Threading.Tasks; +using MiraAPI.GameOptions; +using MiraAPI.PluginLoading; +using Reactor.Utilities; namespace MiraAPI.GameModes; @@ -10,62 +12,84 @@ namespace MiraAPI.GameModes; /// public static class CustomGameModeManager { - /// - /// List of registered gamemodes. - /// - internal static readonly Dictionary GameModes = []; + private static readonly Dictionary IdToModeMap = []; - public static bool IsDefault() + private static uint _nextId; + + private static uint GetNextId() { - return ActiveMode?.Id == 0; + _nextId++; + return _nextId; } - /// - /// Current gamemode. - /// - public static CustomGameMode? ActiveMode { get; internal set; } = new DefaultMode(); - - /// - /// Set current gamemode. - /// - /// gamemode ID. - public static void SetGameMode(int id) - { - if (GameModes.TryGetValue(id, out var gameMode)) - { - ActiveMode = gameMode; - return; - } - - Logger.Error($"No gamemode with id {id} found!"); - } + internal static uint LastId => _nextId; /// /// Register gamemode from type. /// - /// Type of gamemode class, should inherit from . - internal static void RegisterGameMode(Type gameModeType) + /// Type of gamemode class, should inherit from . + /// The custom plugin info of the mod. + internal static void RegisterGameMode(Type gameModeType, MiraPluginInfo pluginInfo) { - if (!typeof(CustomGameMode).IsAssignableFrom(gameModeType)) + if (!typeof(AbstractGameMode).IsAssignableFrom(gameModeType)) { - Logger.Warning($"{gameModeType.Name} does not inherit CustomGameMode!"); return; } - var modeObj = Activator.CreateInstance(gameModeType); + var instance = Activator.CreateInstance(gameModeType); - if (modeObj is not CustomGameMode gameMode) + if (instance is not AbstractGameMode mode) { - Logger.Error($"Failed to create instance of {gameModeType.Name}"); return; } - if (GameModes.Any(x => x.Key == gameMode.Id)) + IdToModeMap.Add(GetNextId(), mode); + pluginInfo.GameModes.Add(_nextId, mode); + + mode.ID = _nextId; + } + + /// + /// Checks to see if the default game mode is on. + /// + /// True if the default mode is one. + public static bool IsDefault() => (uint)OptionGroupSingleton.Instance.CurrentMode.Value == 0; + + /// + /// Gets the current gamemode. + /// + public static AbstractGameMode? ActiveMode { get; internal set; } + + internal static void RegisterDefaultMode() + { + var defaultMode = new DefaultMode(); + IdToModeMap.Add(0, defaultMode); + defaultMode.ID = 0; + } + + internal static void SetGameMode(uint id) + { + if (IdToModeMap.TryGetValue(id, out var mode)) { - Logger.Error($"ID for gamemode {gameMode.Name} already exists!"); + ActiveMode = mode; return; } - GameModes.Add(gameMode.Id, gameMode); + ActiveMode = IdToModeMap[0]; + Logger.Warning($"Unable to find game mode of id {id}!"); + } + + internal static void GetAndSetGameMode() + { + var id = (uint)OptionGroupSingleton.Instance.CurrentMode.Value; + + if (IdToModeMap.TryGetValue(id, out var mode)) + { + ActiveMode = mode; + return; + } + + ActiveMode = IdToModeMap[0]; + Logger.Warning($"Unable to find game mode of id {id}!"); } } diff --git a/MiraAPI/GameModes/DefaultMode.cs b/MiraAPI/GameModes/DefaultMode.cs index 73c4ca8..99f64df 100644 --- a/MiraAPI/GameModes/DefaultMode.cs +++ b/MiraAPI/GameModes/DefaultMode.cs @@ -1,9 +1,13 @@ namespace MiraAPI.GameModes; -[RegisterGameMode] -public class DefaultMode : CustomGameMode +/// +/// The default game mode. +/// +public class DefaultMode : AbstractGameMode { + /// public override string Name => "Default"; + + /// public override string Description => "Default Among Us GameMode"; - public override int Id => 0; } diff --git a/MiraAPI/GameModes/GameModeOption.cs b/MiraAPI/GameModes/GameModeOption.cs new file mode 100644 index 0000000..729cdc3 --- /dev/null +++ b/MiraAPI/GameModes/GameModeOption.cs @@ -0,0 +1,18 @@ +using MiraAPI.GameOptions; +using MiraAPI.GameOptions.OptionTypes; + +namespace MiraAPI.GameModes; + +/// +/// The game mode option. +/// +public class GameModeOption : AbstractOptionGroup +{ + /// + public override string GroupName => "Game Mode"; + + public ModdedNumberOption CurrentMode { get; set; } = new("Current Game Mode", 0, 0, CustomGameModeManager.LastId, 1, Utilities.MiraNumberSuffixes.None) + { + ChangedEvent = x => CustomGameModeManager.SetGameMode((uint)x), + }; +} diff --git a/MiraAPI/GameModes/RegisterGameModeAttribute.cs b/MiraAPI/GameModes/RegisterGameModeAttribute.cs index 4c66c35..68ab348 100644 --- a/MiraAPI/GameModes/RegisterGameModeAttribute.cs +++ b/MiraAPI/GameModes/RegisterGameModeAttribute.cs @@ -1,28 +1,9 @@ using System; -using System.Collections.Generic; -using System.Reflection; namespace MiraAPI.GameModes; +/// +/// Registers a game mode to MiraAPI. +/// [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); - } - } - } -} +public class RegisterGameModeAttribute : Attribute; diff --git a/MiraAPI/MiraApiPlugin.cs b/MiraAPI/MiraApiPlugin.cs index cfe314d..6efca17 100644 --- a/MiraAPI/MiraApiPlugin.cs +++ b/MiraAPI/MiraApiPlugin.cs @@ -1,4 +1,5 @@ using BepInEx; +using BepInEx.Configuration; using BepInEx.Unity.IL2CPP; using HarmonyLib; using MiraAPI.PluginLoading; @@ -14,15 +15,22 @@ namespace MiraAPI; [BepInProcess("Among Us.exe")] [BepInDependency(ReactorPlugin.Id)] [ReactorModFlags(ModFlags.RequireOnAllClients)] -public partial class MiraApiPlugin : BasePlugin +public partial class MiraApiPlugin : BasePlugin, IMiraPlugin { private static MiraPluginManager? PluginManager { get; set; } public Harmony Harmony { get; } = new(Id); + public static Color MiraColor { get; } = new Color32(238, 154, 112, 255); + public static MiraApiPlugin Instance { get; private set; } + + public string OptionsTitleText => "Mira API"; + public override void Load() { + Instance = this; + Harmony.PatchAll(); ReactorCredits.Register("Mira API", Version, true, ReactorCredits.AlwaysShow); @@ -30,4 +38,6 @@ public partial class MiraApiPlugin : BasePlugin PluginManager = new MiraPluginManager(); PluginManager.Initialize(); } + + public ConfigFile GetConfigFile() => Config; } diff --git a/MiraAPI/Patches/GameModes/ConsolePatches.cs b/MiraAPI/Patches/GameModes/ConsolePatches.cs index e2f24b2..09fbe17 100644 --- a/MiraAPI/Patches/GameModes/ConsolePatches.cs +++ b/MiraAPI/Patches/GameModes/ConsolePatches.cs @@ -1,14 +1,16 @@ -/* +using HarmonyLib; +using InnerNet; +using MiraAPI.GameModes; + [HarmonyPatch] public static class ConsolePatches { - [HarmonyPrefix] - [HarmonyPatch(typeof(Console), nameof(Console.CanUse))] + [HarmonyPrefix, HarmonyPatch(typeof(Console), nameof(Console.CanUse))] public static bool CanUsePatch(Console __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) { if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance) { - if (CustomGameModeManager.ActiveMode != null && CustomGameModeManager.ActiveMode.CanUseConsole(__instance)) + if (CustomGameModeManager.ActiveMode != null && CustomGameModeManager.ActiveMode.CanUseTasks(__instance)) { var task = __instance.FindTask(pc.Object); @@ -31,8 +33,7 @@ public static class ConsolePatches return true; } - [HarmonyPrefix] - [HarmonyPatch(typeof(SystemConsole), nameof(SystemConsole.CanUse))] + [HarmonyPrefix, HarmonyPatch(typeof(SystemConsole), nameof(SystemConsole.CanUse))] public static bool SystemCanUsePatch(SystemConsole __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) { if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance) @@ -50,8 +51,7 @@ public static class ConsolePatches return true; } - [HarmonyPrefix] - [HarmonyPatch(typeof(MapConsole), nameof(MapConsole.CanUse))] + [HarmonyPrefix, HarmonyPatch(typeof(MapConsole), nameof(MapConsole.CanUse))] public static bool MapCanUsePatch(MapConsole __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) { if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance) @@ -68,4 +68,4 @@ public static class ConsolePatches canUse = couldUse = true; return true; } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/DeadBodyPatch.cs b/MiraAPI/Patches/GameModes/DeadBodyPatch.cs index 07a2899..1070336 100644 --- a/MiraAPI/Patches/GameModes/DeadBodyPatch.cs +++ b/MiraAPI/Patches/GameModes/DeadBodyPatch.cs @@ -1,11 +1,12 @@ -/* +using HarmonyLib; +using MiraAPI.GameModes; + [HarmonyPatch(typeof(DeadBody))] public static class DeadBodyPatch { - [HarmonyPrefix] - [HarmonyPatch(nameof(DeadBody.OnClick))] + [HarmonyPrefix, HarmonyPatch(nameof(DeadBody.OnClick))] public static bool OnClickPatch(DeadBody __instance) { - return CustomGameModeManager.ActiveMode == null || CustomGameModeManager.ActiveMode.CanReport(__instance); + return CustomGameModeManager.ActiveMode?.CanReport(__instance) == true; } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/GameLogicPatches.cs b/MiraAPI/Patches/GameModes/GameLogicPatches.cs index a62be83..75d4ed9 100644 --- a/MiraAPI/Patches/GameModes/GameLogicPatches.cs +++ b/MiraAPI/Patches/GameModes/GameLogicPatches.cs @@ -1,4 +1,6 @@ -/* +using HarmonyLib; +using MiraAPI.GameModes; + [HarmonyPatch] public static class GameLogicPatches { @@ -17,4 +19,4 @@ public static class GameLogicPatches CustomGameModeManager.ActiveMode?.AssignRoles(out runOriginal, __instance); return runOriginal; } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/HudPatches.cs b/MiraAPI/Patches/GameModes/HudPatches.cs new file mode 100644 index 0000000..50871b9 --- /dev/null +++ b/MiraAPI/Patches/GameModes/HudPatches.cs @@ -0,0 +1,12 @@ +using HarmonyLib; +using MiraAPI.GameModes; + +[HarmonyPatch] +public static class HudPatches +{ + [HarmonyPostfix, HarmonyPatch(typeof(HudManager), nameof(HudManager.Start))] + public static void HudStartPatch(HudManager __instance) => CustomGameModeManager.ActiveMode?.HudStart(__instance); + + [HarmonyPostfix, HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] + public static void HudUpdatePatch(HudManager __instance) => CustomGameModeManager.ActiveMode?.HudUpdate(__instance); +} diff --git a/MiraAPI/Patches/GameModes/ImpostorTargetPatch.cs b/MiraAPI/Patches/GameModes/ImpostorTargetPatch.cs index ad0d9e0..08e39f9 100644 --- a/MiraAPI/Patches/GameModes/ImpostorTargetPatch.cs +++ b/MiraAPI/Patches/GameModes/ImpostorTargetPatch.cs @@ -1,4 +1,6 @@ -/* +using HarmonyLib; +using MiraAPI.GameModes; + /// /// Allow Impostors to kill each other if can kill is enabled in gamemode or friendly fire is toggled on /// @@ -16,9 +18,8 @@ public static class ImpostorTargetPatch } __result = target is { Disconnected: false, IsDead: false } && - target.PlayerId != __instance.Player.PlayerId && !(target.Role == null) && - !(target.Object == null) && !target.Object.inVent && !target.Object.inMovingPlat; + target.PlayerId != __instance.Player.PlayerId && target.Role != null && + target.Object != null && !target.Object.inVent && !target.Object.inMovingPlat; return false; - } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/MapBehaviourPatch.cs b/MiraAPI/Patches/GameModes/MapBehaviourPatch.cs index 9a4bd8b..b6c48fc 100644 --- a/MiraAPI/Patches/GameModes/MapBehaviourPatch.cs +++ b/MiraAPI/Patches/GameModes/MapBehaviourPatch.cs @@ -1,9 +1,10 @@ -/* +using HarmonyLib; +using MiraAPI.GameModes; + [HarmonyPatch(typeof(MapBehaviour))] public static class MapBehaviourPatch { - [HarmonyPrefix] - [HarmonyPatch(nameof(MapBehaviour.ShowSabotageMap))] + [HarmonyPrefix, HarmonyPatch(nameof(MapBehaviour.ShowSabotageMap))] public static bool ShowSabotagePatch(MapBehaviour __instance) { var shouldShow = CustomGameModeManager.ActiveMode?.ShouldShowSabotageMap(__instance); @@ -15,4 +16,4 @@ public static class MapBehaviourPatch return true; } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/OnDeathPatch.cs b/MiraAPI/Patches/GameModes/OnDeathPatch.cs index 99f9211..dcedbab 100644 --- a/MiraAPI/Patches/GameModes/OnDeathPatch.cs +++ b/MiraAPI/Patches/GameModes/OnDeathPatch.cs @@ -1,11 +1,12 @@ -/* +using HarmonyLib; +using MiraAPI.GameModes; + [HarmonyPatch(typeof(KillAnimation))] public static class OnDeathPatch { - [HarmonyPostfix] - [HarmonyPatch(nameof(KillAnimation.CoPerformKill))] + [HarmonyPostfix, HarmonyPatch(nameof(KillAnimation.CoPerformKill))] public static void OnDeathPostfix([HarmonyArgument(0)] PlayerControl source, [HarmonyArgument(1)] PlayerControl target) { CustomGameModeManager.ActiveMode?.OnDeath(target); } -}*/ +} diff --git a/MiraAPI/Patches/GameModes/VentPatches.cs b/MiraAPI/Patches/GameModes/VentPatches.cs deleted file mode 100644 index 597c40a..0000000 --- a/MiraAPI/Patches/GameModes/VentPatches.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* -[HarmonyPatch(typeof(Vent))] -public static class VentPatches -{ - [HarmonyPrefix] - [HarmonyPatch(nameof(Vent.CanUse))] - public static bool CanUseVentPatch(Vent __instance, ref float __result, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] ref bool canUse, [HarmonyArgument(2)] ref bool couldUse) - { - if (CustomGameModeManager.ActiveMode?.CanVent(__instance, pc) == false) - { - return couldUse = canUse = false; - } - - if (pc.Role is not ICustomRole role) - { - return couldUse = canUse = true; - } - - var num = float.MaxValue; - var @object = pc.Object; - var customRoleUsable = role.CanUseVent; - - canUse = couldUse = customRoleUsable && !pc.IsDead && (@object.CanMove || @object.inVent); - if (canUse) - { - var center = @object.Collider.bounds.center; - var position = __instance.transform.position; - num = Vector2.Distance(center, position); - canUse &= num <= __instance.UsableDistance && !PhysicsHelpers.AnythingBetween(@object.Collider, center, position, Constants.ShipOnlyMask, false); - } - __result = num; - return false; - } - - [HarmonyPrefix] - [HarmonyPatch(nameof(Vent.SetOutline))] - public static bool SetOutlinePatch(Vent __instance, [HarmonyArgument(0)] bool on, [HarmonyArgument(1)] bool mainTarget) - { - var color = PlayerControl.LocalPlayer.Data.Role is ICustomRole role - ? role.RoleColor : PlayerControl.LocalPlayer.Data.Role.IsImpostor ? Palette.ImpostorRed : Palette.CrewmateBlue; - __instance.myRend.material.SetFloat(ShaderID.Outline, on ? 1 : 0); - __instance.myRend.material.SetColor(ShaderID.OutlineColor, color); - __instance.myRend.material.SetColor(ShaderID.AddColor, mainTarget ? color : Color.clear); - - return false; - } -}*/ diff --git a/MiraAPI/Patches/HudManagerPatches.cs b/MiraAPI/Patches/HudManagerPatches.cs index af7057d..3dbb7c8 100644 --- a/MiraAPI/Patches/HudManagerPatches.cs +++ b/MiraAPI/Patches/HudManagerPatches.cs @@ -16,17 +16,6 @@ public static class HudManagerPatches // Custom buttons parent. private static GameObject? _bottomLeft; - /* - /// - /// Trigger hudstart on current custom gamemode - /// - [HarmonyPostfix] - [HarmonyPatch(nameof(HudManager.OnGameStart))] - public static void GameStartPatch(HudManager __instance) - { - CustomGameModeManager.ActiveMode?.HudStart(__instance); - }*/ - /// /// Create custom buttons and arrange them on the hud. /// diff --git a/MiraAPI/PluginLoading/MiraPluginInfo.cs b/MiraAPI/PluginLoading/MiraPluginInfo.cs index ecdfa5e..905342c 100644 --- a/MiraAPI/PluginLoading/MiraPluginInfo.cs +++ b/MiraAPI/PluginLoading/MiraPluginInfo.cs @@ -3,12 +3,8 @@ using BepInEx.Configuration; using MiraAPI.GameModes; using MiraAPI.GameOptions; using System.Collections.Generic; -using System.Collections.Immutable; using System.Collections.ObjectModel; -using System.Linq; -using MiraAPI.GameOptions.OptionTypes; using MiraAPI.Hud; -using MiraAPI.Roles; namespace MiraAPI.PluginLoading; @@ -52,6 +48,15 @@ public class MiraPluginInfo return new ReadOnlyDictionary(CustomRoles); } + /// + /// Gets a read only dictionary of Game Mode IDs and the AbstractGameMode object they are associated with. + /// + /// Read only dictionary of IDs and Game Modes. + public ReadOnlyDictionary GetModes() + { + return new ReadOnlyDictionary(GameModes); + } + /// /// Gets a read only collection of this plugin's custom buttons. /// @@ -67,7 +72,7 @@ public class MiraPluginInfo internal Dictionary CustomRoles { get; } = []; - internal Dictionary GameModes { get; } = []; + internal Dictionary GameModes { get; } = []; internal List Buttons { get; } = []; diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index feeba48..1615049 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using BepInEx.Unity.IL2CPP; using MiraAPI.Colors; +using MiraAPI.GameModes; using MiraAPI.GameOptions; using MiraAPI.GameOptions.Attributes; using MiraAPI.Hud; @@ -29,6 +30,7 @@ public sealed class MiraPluginManager internal void Initialize() { Instance = this; + IL2CPPChainloader.Instance.PluginLoad += (pluginInfo, assembly, plugin) => { if (plugin is not IMiraPlugin miraPlugin) @@ -46,21 +48,49 @@ public sealed class MiraPluginManager RegisterColorClasses(assembly); + RegisterGameModeAttribute(assembly, info); + _registeredPlugins.Add(assembly, info); Logger.Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API."); }; - IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors; + IL2CPPChainloader.Instance.Finished += FinishInitialisation; + } + + private void FinishInitialisation() + { + var plugin = IL2CPPChainloader.Instance.Plugins["mira.api"]; + var info = new MiraPluginInfo(MiraApiPlugin.Instance, plugin); + var assembly = typeof(MiraPluginManager).Assembly; + + RegisterModifierAttribute(assembly); + RegisterAllOptions(assembly, info); + + RegisterRoleAttribute(assembly, info); + RegisterButtonAttribute(assembly, info); + + RegisterColorClasses(assembly); + + RegisterGameModeAttribute(assembly, info); + + _registeredPlugins.Add(assembly, info); + + PaletteManager.RegisterAllColors(); + CustomGameModeManager.RegisterDefaultMode(); + + CustomGameModeManager.GetAndSetGameMode(); + + Logger.Info("Initialised mira stuff"); } /// /// Get a mira plugin by its GUID. /// - /// The plugin GUID. + /// The plugin GUID. /// A MiraPluginInfo. - public static MiraPluginInfo GetPluginByGuid(string guid) + public static MiraPluginInfo GetPluginByGuid(string pluginGUID) { - return Instance._registeredPlugins.Values.First(plugin => plugin.PluginId == guid); + return Instance._registeredPlugins.Values.First(plugin => plugin.PluginId == pluginGUID); } private static void RegisterAllOptions(Assembly assembly, MiraPluginInfo pluginInfo) @@ -180,4 +210,17 @@ public sealed class MiraPluginManager } } } + + private static void RegisterGameModeAttribute(Assembly assembly, MiraPluginInfo pluginInfo) + { + foreach (var type in assembly.GetTypes()) + { + var attribute = type.GetCustomAttribute(); + + if (attribute != null) + { + CustomGameModeManager.RegisterGameMode(type, pluginInfo); + } + } + } }