mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
c
This commit is contained in:
1 parent
a0b3b78830
commit
2edd5e8a7a
12 files changed
+106
-110
No files matched your search
@@ -15,8 +15,8 @@ namespace MiraAPI.Example;
|
|||||||
public partial class ExamplePlugin : BasePlugin, IMiraConfig
|
public partial class ExamplePlugin : BasePlugin, IMiraConfig
|
||||||
{
|
{
|
||||||
public Harmony Harmony { get; } = new(Id);
|
public Harmony Harmony { get; } = new(Id);
|
||||||
|
public static ExamplePlugin Instance { get; private set; }
|
||||||
public ModdedOptionTabSettings TabSettings => new()
|
public ModdedOptionTabSettings TabSettings => new ModdedOptionTabSettings()
|
||||||
{
|
{
|
||||||
Title = "MiraAPI Example Mod",
|
Title = "MiraAPI Example Mod",
|
||||||
TabIcon = MiraAssets.Empty
|
TabIcon = MiraAssets.Empty
|
||||||
@@ -24,6 +24,7 @@ public partial class ExamplePlugin : BasePlugin, IMiraConfig
|
|||||||
|
|
||||||
public override void Load()
|
public override void Load()
|
||||||
{
|
{
|
||||||
|
Instance = this;
|
||||||
Harmony.PatchAll();
|
Harmony.PatchAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace MiraAPI.GameModes;
|
|
||||||
|
|
||||||
public struct ActiveMode
|
|
||||||
{
|
|
||||||
public string PluginId { get; set; }
|
|
||||||
public int ModeId { get; set; }
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,6 @@
|
|||||||
public class DefaultMode : CustomGameMode
|
public class DefaultMode : CustomGameMode
|
||||||
{
|
{
|
||||||
public override string Name => "Default";
|
public override string Name => "Default";
|
||||||
public override string Description => "Default Among Us Game Mode";
|
public override string Description => "Default Among Us GameMode";
|
||||||
public override int Id => 0;
|
public override int Id => 0;
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace MiraAPI.GameOptions.Attributes
|
|||||||
{
|
{
|
||||||
foreach (var type in assembly.GetTypes())
|
foreach (var type in assembly.GetTypes())
|
||||||
{
|
{
|
||||||
foreach (var property in type.GetProperties())
|
foreach (PropertyInfo property in type.GetProperties())
|
||||||
{
|
{
|
||||||
foreach (var attribute in property.GetCustomAttributes())
|
foreach (var attribute in property.GetCustomAttributes())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,21 @@ namespace MiraAPI.GameOptions
|
|||||||
private static Dictionary<Type, ModdedOptionGroup> OriginalTypes = new();
|
private static Dictionary<Type, ModdedOptionGroup> OriginalTypes = new();
|
||||||
public static Dictionary<Assembly, IMiraConfig> RegisteredMods = new();
|
public static Dictionary<Assembly, IMiraConfig> RegisteredMods = new();
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, plugin) =>
|
||||||
|
{
|
||||||
|
if (plugin.GetType().GetInterfaces().Contains(typeof(IMiraConfig)))
|
||||||
|
{
|
||||||
|
IMiraConfig config = (IMiraConfig)Activator.CreateInstance(plugin.GetType());
|
||||||
|
RegisteredMods.Add(assembly, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterOptionGroups(assembly);
|
||||||
|
|
||||||
|
ModdedOptionAttribute.Register(assembly);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterOptionGroups(Assembly assembly)
|
private static void RegisterOptionGroups(Assembly assembly)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities;
|
||||||
|
using MiraAPI.Utilities.Assets;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MiraAPI
|
namespace MiraAPI
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using MiraAPI.GameModes;
|
|
||||||
using MiraAPI.GameOptions;
|
|
||||||
using MiraAPI.Roles;
|
|
||||||
|
|
||||||
namespace MiraAPI;
|
|
||||||
|
|
||||||
public class MiraPluginInfo
|
|
||||||
{
|
|
||||||
public string PluginId { get; set; }
|
|
||||||
public IMiraConfig Config { get; set; }
|
|
||||||
|
|
||||||
public readonly List<IModdedOptionGroup> OptionGroups = [];
|
|
||||||
public readonly List<IModdedOption> Options = [];
|
|
||||||
|
|
||||||
public readonly Dictionary<ushort, ICustomRole> CustomRoles = [];
|
|
||||||
public readonly Dictionary<int, CustomGameMode> GameModes = [];
|
|
||||||
|
|
||||||
public MiraPluginInfo(string id, IMiraConfig config)
|
|
||||||
{
|
|
||||||
PluginId = id;
|
|
||||||
Config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using BepInEx;
|
|
||||||
using BepInEx.Unity.IL2CPP;
|
|
||||||
using MiraAPI.GameOptions.Attributes;
|
|
||||||
using MiraAPI.Roles;
|
|
||||||
using MiraAPI.Utilities;
|
|
||||||
|
|
||||||
namespace MiraAPI;
|
|
||||||
|
|
||||||
public class MiraPluginManager
|
|
||||||
{
|
|
||||||
public Dictionary<Assembly, MiraPluginInfo> RegisteredPlugins = [];
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, plugin) =>
|
|
||||||
{
|
|
||||||
if (!plugin.GetType().GetInterfaces().Contains(typeof(IMiraConfig))) return;
|
|
||||||
|
|
||||||
var id = MetadataHelper.GetMetadata(plugin.GetType()).GUID;
|
|
||||||
var info = new MiraPluginInfo(id, plugin as IMiraConfig);
|
|
||||||
|
|
||||||
RegisterRoleAttribute(assembly, info);
|
|
||||||
|
|
||||||
ModdedOptionAttribute.Register(assembly);
|
|
||||||
|
|
||||||
RegisteredPlugins.Add(assembly, info);
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterRoleAttribute(Assembly assembly, MiraPluginInfo pluginInfo)
|
|
||||||
{
|
|
||||||
foreach (var type in assembly.GetTypes())
|
|
||||||
{
|
|
||||||
var attribute = type.GetCustomAttribute<RegisterCustomRoleAttribute>();
|
|
||||||
if (attribute == null) continue;
|
|
||||||
|
|
||||||
Helpers.RegisterIl2CppType(type);
|
|
||||||
var role = CustomRoleManager.RegisterRole(type, attribute.RoleId);
|
|
||||||
|
|
||||||
pluginInfo.CustomRoles.Add((ushort)role.Role, role as ICustomRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ using MiraAPI.Patches.Options;
|
|||||||
using MiraAPI.Roles;
|
using MiraAPI.Roles;
|
||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
|
||||||
|
|
||||||
namespace MiraAPI.Patches
|
namespace MiraAPI.Patches
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Reactor.Utilities;
|
|||||||
using Reactor.Utilities.Extensions;
|
using Reactor.Utilities.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using MiraAPI.Networking;
|
using MiraAPI.Networking;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -17,35 +18,46 @@ namespace MiraAPI.Roles;
|
|||||||
|
|
||||||
public static class CustomRoleManager
|
public static class CustomRoleManager
|
||||||
{
|
{
|
||||||
public static Dictionary<ushort, ICustomRole> CustomRoles = new();
|
public static readonly Dictionary<ushort, RoleBehaviour> CustomRoles = [];
|
||||||
|
public static readonly Dictionary<PluginInfo, List<RoleBehaviour>> ModRoles = [];
|
||||||
|
|
||||||
public static int GetNextRoleId(ushort requestedId)
|
public static void RegisterInRoleManager()
|
||||||
{
|
{
|
||||||
while (CustomRoles.ContainsKey(requestedId))
|
RoleManager.Instance.AllRoles = RoleManager.Instance.AllRoles.Concat(CustomRoles.Values).ToArray();
|
||||||
{
|
|
||||||
requestedId++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestedId;
|
internal static void RegisterRole(Type roleType, ushort roleId, string modId)
|
||||||
|
{
|
||||||
|
if (!IL2CPPChainloader.Instance.Plugins.TryGetValue(modId, out PluginInfo info))
|
||||||
|
{
|
||||||
|
Debug.LogError($"{modId} is not a valid mod!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static RoleBehaviour RegisterRole(Type roleType, ushort roleId)
|
|
||||||
{
|
|
||||||
if (!(typeof(RoleBehaviour).IsAssignableFrom(roleType) && typeof(ICustomRole).IsAssignableFrom(roleType)))
|
if (!(typeof(RoleBehaviour).IsAssignableFrom(roleType) && typeof(ICustomRole).IsAssignableFrom(roleType)))
|
||||||
{
|
{
|
||||||
Debug.LogError($"{roleType?.Name} does not inherit from RoleBehaviour or ICustomRole.");
|
return;
|
||||||
return null;
|
}
|
||||||
|
|
||||||
|
if (CustomRoles.Any(behaviour => behaviour.GetType() == roleType))
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var roleBehaviour = (RoleBehaviour)new GameObject(roleType.Name).DontDestroy().AddComponent(Il2CppType.From(roleType));
|
var roleBehaviour = (RoleBehaviour)new GameObject(roleType.Name).DontDestroy().AddComponent(Il2CppType.From(roleType));
|
||||||
|
|
||||||
if (roleBehaviour is not ICustomRole customRole)
|
if (roleBehaviour is not ICustomRole customRole)
|
||||||
{
|
{
|
||||||
roleBehaviour.gameObject.Destroy();
|
return;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roleBehaviour.Role = (RoleTypes)GetNextRoleId(roleId);
|
if (CustomRoles.ContainsKey(roleId))
|
||||||
|
{
|
||||||
|
Debug.LogError($"Role ID conflict for {customRole.RoleName}. Use a different ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
roleBehaviour.Role = (RoleTypes)roleId;
|
||||||
roleBehaviour.TeamType = customRole.Team == ModdedRoleTeams.Neutral ? RoleTeamTypes.Crewmate : (RoleTeamTypes)customRole.Team;
|
roleBehaviour.TeamType = customRole.Team == ModdedRoleTeams.Neutral ? RoleTeamTypes.Crewmate : (RoleTeamTypes)customRole.Team;
|
||||||
roleBehaviour.NameColor = customRole.RoleColor;
|
roleBehaviour.NameColor = customRole.RoleColor;
|
||||||
roleBehaviour.StringName = CustomStringName.CreateAndRegister(customRole.RoleName);
|
roleBehaviour.StringName = CustomStringName.CreateAndRegister(customRole.RoleName);
|
||||||
@@ -64,26 +76,47 @@ public static class CustomRoleManager
|
|||||||
RoleManager.GhostRoles.Add(roleBehaviour.Role);
|
RoleManager.GhostRoles.Add(roleBehaviour.Role);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomRoles.Add(roleId, customRole);
|
if (ModRoles.TryGetValue(info, out List<RoleBehaviour> roles))
|
||||||
|
{
|
||||||
|
roles.Add(roleBehaviour);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModRoles.TryAdd(info, [roleBehaviour]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRoles.Add(roleId, roleBehaviour);
|
||||||
|
|
||||||
if (customRole.HideSettings)
|
if (customRole.HideSettings)
|
||||||
{
|
{
|
||||||
return roleBehaviour;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = PluginSingleton<MiraAPIPlugin>.Instance.Config;
|
var config = PluginSingleton<MiraAPIPlugin>.Instance.Config;
|
||||||
config.Bind(customRole.NumConfigDefinition, 1);
|
config.Bind(customRole.NumConfigDefinition, 1);
|
||||||
config.Bind(customRole.ChanceConfigDefinition, 100);
|
config.Bind(customRole.ChanceConfigDefinition, 100);
|
||||||
|
|
||||||
return roleBehaviour;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<RoleBehaviour> GetRolesRegistered(string modId)
|
||||||
|
{
|
||||||
|
PluginInfo info = ModRoles.Keys.First(key => key.Metadata.GUID == modId);
|
||||||
|
if (ModRoles.TryGetValue(info, out List<RoleBehaviour> roles))
|
||||||
|
{
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"{modId} has no roles registered.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
public static bool GetCustomRoleBehaviour(RoleTypes roleType, out ICustomRole result)
|
public static bool GetCustomRoleBehaviour(RoleTypes roleType, out ICustomRole result)
|
||||||
{
|
{
|
||||||
CustomRoles.TryGetValue((ushort)roleType, out var temp);
|
CustomRoles.TryGetValue((ushort)roleType, out var temp);
|
||||||
if (temp != null)
|
if (temp is ICustomRole role)
|
||||||
{
|
{
|
||||||
result = temp;
|
result = role;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,40 @@ using System.Reflection;
|
|||||||
namespace MiraAPI.Roles;
|
namespace MiraAPI.Roles;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class RegisterCustomRoleAttribute(ushort roleId) : Attribute
|
public class RegisterCustomRoleAttribute : Attribute
|
||||||
{
|
{
|
||||||
public ushort RoleId { get; } = roleId;
|
private static readonly HashSet<Assembly> RegisteredAssemblies = [];
|
||||||
|
public ushort RoleId { get; }
|
||||||
|
public string ModId { get; }
|
||||||
|
|
||||||
public RegisterCustomRoleAttribute() : this((ushort)(20 + CustomRoleManager.CustomRoles.Count))
|
public RegisterCustomRoleAttribute(string modId)
|
||||||
{
|
{
|
||||||
|
ModId = modId;
|
||||||
|
RoleId = (ushort)(20 + CustomRoleManager.CustomRoles.Count);
|
||||||
|
}
|
||||||
|
public RegisterCustomRoleAttribute(string modId, ushort roleId)
|
||||||
|
{
|
||||||
|
ModId = modId;
|
||||||
|
RoleId = roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, plugin) => Register(assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Register(Assembly assembly)
|
||||||
|
{
|
||||||
|
if (!RegisteredAssemblies.Add(assembly)) return;
|
||||||
|
|
||||||
|
foreach (var type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
var attribute = type.GetCustomAttribute<RegisterCustomRoleAttribute>();
|
||||||
|
if (attribute != null)
|
||||||
|
{
|
||||||
|
Helpers.RegisterType(type);
|
||||||
|
CustomRoleManager.RegisterRole(type, attribute.RoleId, attribute.ModId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace MiraAPI.Utilities
|
|||||||
return ShipStatus.Instance.AllRooms.ToList().Find(room => room.roomArea.OverlapPoint(pos));
|
return ShipStatus.Instance.AllRooms.ToList().Find(room => room.roomArea.OverlapPoint(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RegisterIl2CppType(Type type)
|
public static void RegisterType(Type type)
|
||||||
{
|
{
|
||||||
if (ClassInjector.IsTypeRegisteredInIl2Cpp(type))
|
if (ClassInjector.IsTypeRegisteredInIl2Cpp(type))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user