mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-22 07:35:55 +00:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
575f7a78a1 | ||
|
|
bf7edb30ab | ||
|
|
b4527014b7 | ||
|
|
277391ef1c | ||
|
|
6b3038f397 | ||
|
|
4e1db039a0 | ||
|
|
62bee24789 | ||
|
|
2156c80467 | ||
|
|
0ff60071c2 | ||
|
|
de2f3f0d95 |
No files matched your search
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using BepInEx;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using HarmonyLib;
|
||||
using MiraAPI.PluginLoading;
|
||||
using Reactor;
|
||||
using Reactor.Networking;
|
||||
using Reactor.Networking.Attributes;
|
||||
|
||||
namespace MiraAPI.Example.Extension;
|
||||
|
||||
[BepInAutoPlugin("mira.example.extension", "MiraExampleExtensionMod")]
|
||||
[BepInProcess("Among Us.exe")]
|
||||
[BepInDependency(ReactorPlugin.Id)]
|
||||
[BepInDependency(MiraApiPlugin.Id)]
|
||||
[BepInDependency(ExamplePlugin.Id)]
|
||||
[ReactorModFlags(ModFlags.RequireOnAllClients)]
|
||||
public partial class ExampleExtensionPlugin : BasePlugin, IMiraExtension
|
||||
{
|
||||
public Harmony Harmony { get; } = new(Id);
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
Harmony.PatchAll();
|
||||
}
|
||||
|
||||
public Type GetBasePluginType()
|
||||
{
|
||||
return typeof(ExamplePlugin);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Version>1.0.0</Version>
|
||||
<Description>Example extension for Mira API</Description>
|
||||
<Authors>Angxl, XtraCube</Authors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MiraAPI\MiraAPI.csproj" />
|
||||
<ProjectReference Include="..\MiraAPI.Example\MiraAPI.Example.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\AmongUs.props" />
|
||||
</Project>
|
||||
@@ -1,16 +0,0 @@
|
||||
using MiraAPI.Example.Extension.Options;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Modifiers;
|
||||
|
||||
public class ExtensionModifier : GameModifier
|
||||
{
|
||||
public override string ModifierName => "Extension Modifier";
|
||||
|
||||
public override string GetDescription() => "This is from the extension mod!";
|
||||
|
||||
public override int GetAssignmentChance() => (int)OptionGroupSingleton<ExtensionModifierOptions>.Instance.ModifierChance;
|
||||
|
||||
public override int GetAmountPerGame() => (int)OptionGroupSingleton<ExtensionModifierOptions>.Instance.ModifierLimit;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using MiraAPI.Example.Roles;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.GameOptions.Attributes;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Options;
|
||||
|
||||
public class ExtendedFreezerOptions : AbstractOptionGroup<FreezerRole>
|
||||
{
|
||||
public override string GroupName => "Extended Freezer Role Options";
|
||||
|
||||
[ModdedNumberOption("Freeze Uses", 1, 5)]
|
||||
public float FreezeUses { get; set; } = 1;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using MiraAPI.Example.Extension.Modifiers;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.GameOptions.Attributes;
|
||||
using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Options;
|
||||
|
||||
public class ExtensionModifierOptions : AbstractOptionGroup<ExtensionModifier>
|
||||
{
|
||||
public override string GroupName => "Extension Modifier Options";
|
||||
|
||||
[ModdedNumberOption("Modifier Chance", 0, 100, 10, MiraNumberSuffixes.Percent)]
|
||||
public float ModifierChance { get; set; } = 100f;
|
||||
|
||||
[ModdedNumberOption("Modifier Limit", 0, 10)]
|
||||
public float ModifierLimit { get; set; } = 0;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using HarmonyLib;
|
||||
using MiraAPI.Example.Buttons.Freezer;
|
||||
using MiraAPI.Example.Extension.Options;
|
||||
using MiraAPI.GameOptions;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Patches;
|
||||
|
||||
[HarmonyPatch(typeof(FreezeButton), nameof(FreezeButton.MaxUses), MethodType.Getter)]
|
||||
public static class FreezeButtonPatch
|
||||
{
|
||||
public static void Postfix(ref int __result)
|
||||
{
|
||||
__result = (int)OptionGroupSingleton<ExtendedFreezerOptions>.Instance.FreezeUses;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public class FreezeButton : CustomActionButton<PlayerControl>
|
||||
|
||||
public override float Cooldown => OptionGroupSingleton<FreezerRoleSettings>.Instance.FreezeDuration;
|
||||
|
||||
public override int MaxUses => 1;
|
||||
public override int MaxUses => (int)OptionGroupSingleton<FreezerRoleSettings>.Instance.FreezeUses;
|
||||
|
||||
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
|
||||
|
||||
|
||||
+3
-6
@@ -1,20 +1,17 @@
|
||||
using MiraAPI.Example.Extension.GameOver;
|
||||
using MiraAPI.Example.Extension.Roles;
|
||||
using MiraAPI.Example.GameOver;
|
||||
using MiraAPI.Example.Roles;
|
||||
using MiraAPI.GameEnd;
|
||||
using MiraAPI.Hud;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Buttons;
|
||||
namespace MiraAPI.Example.Buttons;
|
||||
|
||||
public class NeutralKillerButton : CustomActionButton
|
||||
{
|
||||
public override string Name => "Win Game";
|
||||
|
||||
public override float Cooldown => 0f;
|
||||
|
||||
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
CustomGameOver.Trigger<NeutralKillerGameOver>([PlayerControl.LocalPlayer.Data]);
|
||||
@@ -51,7 +51,7 @@ public static class ExampleEventHandlers
|
||||
[RegisterEvent(15)]
|
||||
public static void HandleVoteEvent(HandleVoteEvent @event)
|
||||
{
|
||||
if (@event.VoteData.Owner.Data.Role is not FreezerRole) return;
|
||||
if (@event.VoteData.Owner.Data.Role is not NeutralKillerRole) return;
|
||||
|
||||
@event.VoteData.SetRemainingVotes(0);
|
||||
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
using MiraAPI.Example.Extension.Roles;
|
||||
using MiraAPI.Example.Roles;
|
||||
using MiraAPI.GameEnd;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example.Extension.GameOver;
|
||||
namespace MiraAPI.Example.GameOver;
|
||||
|
||||
public class NeutralKillerGameOver : CustomGameOver
|
||||
{
|
||||
@@ -11,4 +11,7 @@ public class FreezerRoleSettings : AbstractOptionGroup<FreezerRole>
|
||||
|
||||
[ModdedNumberOption("Freeze Duration", 1, 15, 1, MiraNumberSuffixes.Seconds)]
|
||||
public float FreezeDuration { get; set; } = 5;
|
||||
|
||||
[ModdedNumberOption("Freeze Uses", 1, 5)]
|
||||
public float FreezeUses { get; set; } = 1;
|
||||
}
|
||||
+3
-7
@@ -1,20 +1,16 @@
|
||||
using MiraAPI.Example.Extension.GameOver;
|
||||
using MiraAPI.Example.GameOver;
|
||||
using MiraAPI.GameEnd;
|
||||
using MiraAPI.Roles;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Example.Extension.Roles;
|
||||
namespace MiraAPI.Example.Roles;
|
||||
|
||||
public class NeutralKillerRole : ImpostorRole, ICustomRole
|
||||
{
|
||||
public string RoleName => "Outcast Killer";
|
||||
|
||||
public string RoleDescription => "Outcast who can kill.";
|
||||
|
||||
public string RoleLongDescription => this.RoleDescription;
|
||||
|
||||
public string RoleLongDescription => RoleDescription;
|
||||
public Color RoleColor => Color.magenta;
|
||||
|
||||
public ModdedRoleTeams Team => ModdedRoleTeams.Custom;
|
||||
|
||||
public CustomRoleConfiguration Configuration => new(this)
|
||||
@@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiraAPI", "MiraAPI\MiraAPI.
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiraAPI.Example", "MiraAPI.Example\MiraAPI.Example.csproj", "{19B76855-16CC-43CC-A0A6-5A7FFB43F077}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiraAPI.Example.Extension", "MiraAPI.Example.Extension\MiraAPI.Example.Extension.csproj", "{526FF017-80E1-4094-804D-741AF35AA226}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -23,10 +21,6 @@ Global
|
||||
{19B76855-16CC-43CC-A0A6-5A7FFB43F077}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19B76855-16CC-43CC-A0A6-5A7FFB43F077}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19B76855-16CC-43CC-A0A6-5A7FFB43F077}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{526FF017-80E1-4094-804D-741AF35AA226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{526FF017-80E1-4094-804D-741AF35AA226}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{526FF017-80E1-4094-804D-741AF35AA226}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{526FF017-80E1-4094-804D-741AF35AA226}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace MiraAPI.Game;
|
||||
|
||||
public enum PlayerContext
|
||||
{
|
||||
|
||||
}
|
||||
@@ -64,6 +64,11 @@ public abstract class BaseModifier : IOptionable
|
||||
/// </summary>
|
||||
public virtual bool ShowInFreeplay => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating the color that should be used for the modifier within freeplay.
|
||||
/// </summary>
|
||||
public virtual Color FreeplayFileColor => Color.gray;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the modifier is unique. If true, the player can only have one instance of this modifier.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace MiraAPI.Modifiers;
|
||||
|
||||
public enum ModifierContext
|
||||
{
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Runtime.Serialization;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities;
|
||||
using Reactor.Utilities;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using Random = System.Random;
|
||||
@@ -125,6 +126,7 @@ public static class ModifierManager
|
||||
.Select(x => Activator.CreateInstance(x.Value) as GameModifier)
|
||||
.OfType<GameModifier>()
|
||||
.Where(x => x.GetAmountPerGame() > 0 && x.GetAssignmentChance() > 0)
|
||||
.Shuffle()
|
||||
.OrderByDescending(x => x.Priority())
|
||||
.ToArray();
|
||||
|
||||
|
||||
@@ -3,10 +3,12 @@ using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Patches;
|
||||
|
||||
#pragma warning disable SA1629
|
||||
/// <summary>
|
||||
/// Allows players to paste text into chat.
|
||||
/// Source: https://github.com/CallOfCreator/NewMod/blob/main/NewMod/Patches/ClipboardPatch.cs
|
||||
/// </summary>
|
||||
#pragma warning restore SA1629
|
||||
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))]
|
||||
public static class ChatControllerPatch
|
||||
{
|
||||
|
||||
@@ -12,14 +12,16 @@ public static class CanUsePatches
|
||||
public static IEnumerable<MethodBase> TargetMethods()
|
||||
{
|
||||
yield return AccessTools.Method(typeof(Console), nameof(Console.CanUse));
|
||||
yield return AccessTools.Method(typeof(MapConsole), nameof(MapConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(SystemConsole), nameof(SystemConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(Ladder), nameof(Ladder.CanUse));
|
||||
yield return AccessTools.Method(typeof(PlatformConsole), nameof(PlatformConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(OpenDoorConsole), nameof(OpenDoorConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(DeconControl), nameof(DeconControl.CanUse));
|
||||
yield return AccessTools.Method(typeof(DoorConsole), nameof(DoorConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(Ladder), nameof(Ladder.CanUse));
|
||||
yield return AccessTools.Method(typeof(MapConsole), nameof(MapConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(OpenDoorConsole), nameof(OpenDoorConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(OptionsConsole), nameof(OptionsConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(PlatformConsole), nameof(PlatformConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(SystemConsole), nameof(SystemConsole.CanUse));
|
||||
yield return AccessTools.Method(typeof(ZiplineConsole), nameof(ZiplineConsole.CanUse));
|
||||
// vent is not necessary as it has its own patch
|
||||
}
|
||||
|
||||
[HarmonyPriority(Priority.Last)]
|
||||
|
||||
@@ -22,15 +22,4 @@ internal static class TaskAddButtonPatches
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(TaskAddButton.Role), MethodType.Setter)]
|
||||
public static void RoleGetterPatch(TaskAddButton __instance)
|
||||
{
|
||||
if (__instance.role is ICustomRole { Team: ModdedRoleTeams.Custom } customRole)
|
||||
{
|
||||
__instance.FileImage.color = customRole.IntroConfiguration?.IntroTeamColor ?? Color.gray;
|
||||
}
|
||||
__instance.RolloverHandler.OutColor = __instance.FileImage.color;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using MiraAPI.Utilities;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
@@ -19,7 +20,6 @@ namespace MiraAPI.Patches.Freeplay;
|
||||
internal static class TaskAdderPatches
|
||||
{
|
||||
private static Scroller _scroller = null!;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
||||
public static void AddRolesFolder(TaskAdderGame __instance)
|
||||
@@ -32,6 +32,11 @@ internal static class TaskAdderPatches
|
||||
_scroller.allowY = true;
|
||||
_scroller.Inner = inner.transform;
|
||||
|
||||
var scrollerHelper = __instance.TaskParent.gameObject.AddComponent<ManualScrollHelper>();
|
||||
scrollerHelper.scroller = _scroller;
|
||||
scrollerHelper.verticalAxis = RewiredConstsEnum.Action.TaskRVertical;
|
||||
scrollerHelper.scrollSpeed = 10f;
|
||||
|
||||
GameObject hitbox = new("Hitbox")
|
||||
{
|
||||
layer = 5,
|
||||
@@ -295,7 +300,7 @@ internal static class TaskAdderPatches
|
||||
|
||||
if (_scroller)
|
||||
{
|
||||
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 5, 1.4f);
|
||||
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 4.5f, 1.65f);
|
||||
_scroller.SetYBoundsMin(0.0f);
|
||||
_scroller.ScrollToTop();
|
||||
}
|
||||
@@ -332,7 +337,8 @@ internal static class TaskAdderPatches
|
||||
taskAddButton.SafePositionWorld = instance.SafePositionWorld;
|
||||
taskAddButton.Text.text = modifier.ModifierName;
|
||||
taskAddButton.Text.EnableMasking();
|
||||
|
||||
taskAddButton.FileImage.color = modifier.FreeplayFileColor;
|
||||
taskAddButton.RolloverHandler.OutColor = modifier.FreeplayFileColor;
|
||||
taskAddButton.Button.OnClick = new Button.ButtonClickedEvent();
|
||||
taskAddButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
|
||||
{
|
||||
@@ -384,6 +390,20 @@ internal static class TaskAdderPatches
|
||||
|
||||
instance.AddFileAsChildCustom(taskAddButton2, ref num, ref num2, ref num3);
|
||||
taskAddButton2.Role = roleBehaviour;
|
||||
if (roleBehaviour is ICustomRole custom)
|
||||
{
|
||||
var customColor = custom.IntroConfiguration?.IntroTeamColor ?? Color.gray;
|
||||
if (custom.Team is ModdedRoleTeams.Crewmate)
|
||||
{
|
||||
customColor = Palette.CrewmateBlue;
|
||||
}
|
||||
else if (custom.Team is ModdedRoleTeams.Impostor)
|
||||
{
|
||||
customColor = Palette.ImpostorRed;
|
||||
}
|
||||
taskAddButton2.FileImage.color = customColor;
|
||||
taskAddButton2.RolloverHandler.OutColor = customColor;
|
||||
}
|
||||
if (taskAddButton2.Button == null)
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -84,7 +84,7 @@ public static class HatsTabPatches
|
||||
text.gameObject.transform.localScale = Vector3.one;
|
||||
text.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
text.EnableStencilMasking();
|
||||
text.text = $"{groupName}\nPress Ctrl or Tab to cycle pages";
|
||||
text.text = $"{groupName} ({currentPage + 1}/{sortedHats.Count})\nPress Ctrl or Tab to cycle pages";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
text.fontSize = 3f;
|
||||
text.fontSizeMax = 3f;
|
||||
|
||||
@@ -73,7 +73,7 @@ public static class NameplatesTabPatches
|
||||
text.gameObject.transform.localScale = Vector3.one;
|
||||
text.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
text.EnableStencilMasking();
|
||||
text.text = $"{groupName}\nPress Ctrl or Tab to cycle pages";
|
||||
text.text = $"{groupName} ({currentPage + 1}/{SortedNameplates.Count})\nPress Ctrl or Tab to cycle pages";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
text.fontSize = 3f;
|
||||
text.fontSizeMax = 3f;
|
||||
|
||||
@@ -76,7 +76,7 @@ public static class SkinsTabPatches
|
||||
text.gameObject.transform.localScale = Vector3.one;
|
||||
text.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
text.EnableStencilMasking();
|
||||
text.text = $"{groupName}\nPress Ctrl or Tab to cycle pages";
|
||||
text.text = $"{groupName} ({currentPage + 1}/{sortedSkins.Count})\nPress Ctrl or Tab to cycle pages";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
text.fontSize = 3f;
|
||||
text.fontSizeMax = 3f;
|
||||
|
||||
@@ -72,7 +72,7 @@ public static class VisorsTabPatches
|
||||
text.gameObject.transform.localScale = Vector3.one;
|
||||
text.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
text.EnableStencilMasking();
|
||||
text.text = $"{groupName}\nPress Ctrl or Tab to cycle pages";
|
||||
text.text = $"{groupName} ({currentPage + 1}/{SortedVisors.Count})\nPress Ctrl or Tab to cycle pages";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
text.fontSize = 3f;
|
||||
text.fontSizeMax = 3f;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace MiraAPI.Patches;
|
||||
|
||||
@@ -14,6 +15,8 @@ public static class ServerDropdownPatch
|
||||
|
||||
foreach (var regionInfo in DestroyableSingleton<ServerManager>.Instance.AvailableRegions)
|
||||
{
|
||||
var findingGame = SceneManager.GetActiveScene().name is "FindAGame";
|
||||
|
||||
if (DestroyableSingleton<ServerManager>.Instance.CurrentRegion.Equals(regionInfo))
|
||||
{
|
||||
__instance.defaultButtonSelected = __instance.firstOption;
|
||||
@@ -27,6 +30,10 @@ public static class ServerDropdownPatch
|
||||
var region = regionInfo;
|
||||
var serverListButton = __instance.ButtonPool.Get<ServerListButton>();
|
||||
var x = num % 2 == 0 ? -2 : 2;
|
||||
if (findingGame)
|
||||
{
|
||||
x += 2;
|
||||
}
|
||||
var y = -0.55f * (num / 2);
|
||||
serverListButton.transform.localPosition = new Vector3(x, __instance.y_posButton + y, -1f);
|
||||
serverListButton.transform.localScale = Vector3.one;
|
||||
@@ -39,7 +46,7 @@ public static class ServerDropdownPatch
|
||||
serverListButton.Button.OnClick.AddListener((UnityAction)(() => { __instance.ChooseOption(region); }));
|
||||
__instance.controllerSelectable.Add(serverListButton.Button);
|
||||
__instance.background.transform.localPosition = new Vector3(
|
||||
0f,
|
||||
findingGame ? 2f : 0f,
|
||||
__instance.initialYPos + (-0.3f * (num / 2)),
|
||||
0f);
|
||||
__instance.background.size = new Vector2(__instance.background.size.x, 1.2f + (0.6f * (num / 2)));
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace MiraAPI.PluginLoading;
|
||||
|
||||
public interface IMiraExtension
|
||||
{
|
||||
public Type GetBasePluginType();
|
||||
}
|
||||
@@ -37,30 +37,100 @@ public sealed class MiraPluginManager
|
||||
Instance = this;
|
||||
IL2CPPChainloader.Instance.PluginLoad += (pluginInfo, assembly, plugin) =>
|
||||
{
|
||||
if (plugin is IMiraPlugin miraPlugin)
|
||||
if (plugin is not IMiraPlugin miraPlugin)
|
||||
{
|
||||
var miraInfo = new MiraPluginInfo(miraPlugin, pluginInfo);
|
||||
RegisterPlugin(miraInfo, assembly);
|
||||
_registeredPlugins.Add(assembly, miraInfo);
|
||||
return;
|
||||
}
|
||||
else if (plugin is IMiraExtension miraExtension)
|
||||
|
||||
var info = new MiraPluginInfo(miraPlugin, pluginInfo);
|
||||
var roles = new List<Type>();
|
||||
|
||||
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
|
||||
info.PluginConfig.SaveOnConfigSet = false;
|
||||
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
var basePlugin = miraExtension.GetBasePluginType();
|
||||
var basePluginInfo = _registeredPlugins.Values.FirstOrDefault(x => x.MiraPlugin.GetType() == basePlugin);
|
||||
if (basePluginInfo == null)
|
||||
if (type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Base plugin {basePlugin.Name} not found for extension {pluginInfo.Metadata.GUID}.");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
RegisterPlugin(basePluginInfo, assembly);
|
||||
foreach (var method in type.GetMethods())
|
||||
{
|
||||
var eventAttribute = method.GetCustomAttribute<RegisterEventAttribute>();
|
||||
if (eventAttribute == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!method.IsStatic)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Event method {method.Name} in {type.Name} must be static.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var parameters = method.GetParameters();
|
||||
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Invalid event registration method {method.Name} in {type.Name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var paramType = parameters[0].ParameterType;
|
||||
MiraEventManager.RegisterEventHandler(paramType, method, eventAttribute.Priority);
|
||||
}
|
||||
|
||||
if (RegisterModifier(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterOptions(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterRole(type, info, out var role))
|
||||
{
|
||||
roles.Add(role);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterButton(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterGameOver(type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RegisterColorClasses(type);
|
||||
}
|
||||
|
||||
info.PluginConfig.Save();
|
||||
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
|
||||
|
||||
info.InternalOptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
|
||||
QueuedRoleRegistrations.Add(info, roles);
|
||||
|
||||
_registeredPlugins.Add(assembly, info);
|
||||
|
||||
info.SavePublicCollections();
|
||||
PresetManager.CreateDefaultPreset(info);
|
||||
PresetManager.LoadPresets(info);
|
||||
Logger<MiraApiPlugin>.Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API.");
|
||||
};
|
||||
IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors;
|
||||
IL2CPPChainloader.Instance.Finished += () =>
|
||||
{
|
||||
// Save all buttons into a read-only collection for easy access
|
||||
CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons);
|
||||
RegisteredPlugins = [.. _registeredPlugins.Values];
|
||||
|
||||
// Cache all the registered plugins into an array for easy access
|
||||
RegisteredPlugins = [.._registeredPlugins.Values];
|
||||
|
||||
ModifierManager.Modifiers = new ReadOnlyCollection<BaseModifier>(ModifierManager.InternalModifiers);
|
||||
};
|
||||
}
|
||||
@@ -75,90 +145,6 @@ public sealed class MiraPluginManager
|
||||
return Instance._registeredPlugins.Values.FirstOrDefault(plugin => plugin.PluginId == pluginId);
|
||||
}
|
||||
|
||||
private void RegisterPlugin(MiraPluginInfo info, Assembly assembly)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Info($"Registering plugin {info.PluginId} with Mira API.");
|
||||
|
||||
var roles = new List<Type>();
|
||||
|
||||
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
|
||||
info.PluginConfig.SaveOnConfigSet = false;
|
||||
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
if (type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var method in type.GetMethods())
|
||||
{
|
||||
var eventAttribute = method.GetCustomAttribute<RegisterEventAttribute>();
|
||||
if (eventAttribute == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!method.IsStatic)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Event method {method.Name} in {type.Name} must be static.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var parameters = method.GetParameters();
|
||||
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Invalid event registration method {method.Name} in {type.Name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var paramType = parameters[0].ParameterType;
|
||||
MiraEventManager.RegisterEventHandler(paramType, method, eventAttribute.Priority);
|
||||
}
|
||||
|
||||
if (RegisterModifier(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterOptions(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterRole(type, info, out var role))
|
||||
{
|
||||
roles.Add(role);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterButton(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterGameOver(type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RegisterColorClasses(type);
|
||||
}
|
||||
|
||||
info.PluginConfig.Save();
|
||||
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
|
||||
|
||||
info.InternalOptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
|
||||
|
||||
QueuedRoleRegistrations.TryAdd(info, []);
|
||||
QueuedRoleRegistrations[info].AddRange(roles);
|
||||
|
||||
info.SavePublicCollections();
|
||||
PresetManager.CreateDefaultPreset(info);
|
||||
PresetManager.LoadPresets(info);
|
||||
Logger<MiraApiPlugin>.Info($"{info.PluginId} finished registering.");
|
||||
}
|
||||
|
||||
private static bool RegisterGameOver(Type type)
|
||||
{
|
||||
try
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
namespace MiraAPI.Roles;
|
||||
|
||||
public enum RoleContext
|
||||
{
|
||||
|
||||
}
|
||||
@@ -49,4 +49,4 @@ public static class SpriteTools
|
||||
sprite.name = resourcePath;
|
||||
return sprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MiraAPI.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Extensions for IEnumerable.
|
||||
/// </summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Shuffle the elements of the source enumerable using a new instance of Random.
|
||||
/// </summary>
|
||||
/// <param name="source">The source enumerable.</param>
|
||||
/// <typeparam name="T">The type of the elements.</typeparam>
|
||||
/// <returns>>The shuffled enumerable.</returns>
|
||||
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
|
||||
{
|
||||
return source.Shuffle(new Random());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuffle the elements of the source enumerable using the provided Random instance.
|
||||
/// </summary>
|
||||
/// <param name="source">The source enumerable.</param>
|
||||
/// <param name="rng">The Random instance to use for shuffling.</param>
|
||||
/// <typeparam name="T">The type of the elements.</typeparam>
|
||||
/// <returns>>The shuffled enumerable.</returns>
|
||||
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(rng);
|
||||
|
||||
return source.ShuffleIterator(rng);
|
||||
}
|
||||
|
||||
private static IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source, Random rng)
|
||||
{
|
||||
var buffer = source.ToList();
|
||||
for (var i = 0; i < buffer.Count; i++)
|
||||
{
|
||||
var j = rng.Next(i, buffer.Count);
|
||||
yield return buffer[j];
|
||||
|
||||
buffer[j] = buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user