Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of More Emotes Patch v1.1.0
MoreEmotesPatch.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using Microsoft.CodeAnalysis; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("MoreEmotesPatch + BetterEmotes Support")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MoreEmotesPatch + BetterEmotes Support")] [assembly: AssemblyCopyright("Copyright © RtPoogle 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f985f2ab-4c3b-4066-aa78-fe8865941283")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace MoreEmotesPatch { internal static class Extensions { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] internal class HarmonyPatchCategory : Attribute { public string Category { get; } public HarmonyPatchCategory(string category) { Category = category; base..ctor(); } } public static int CurrentTime => (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; public static T _get<T>(Type type, string pof) { return (T)AccessTools.Property(type, pof).GetValue(null); } public static bool StopAnyEmotes(PlayerControllerB __instance) { __instance.performingEmote = false; __instance.StopPerformingEmoteServerRpc(); __instance.timeSinceStartingEmote = 0f; return false; } public static void PatchCategory(this Harmony harmony, string category) { CollectionExtensions.DoIf<PatchClassProcessor>((IEnumerable<PatchClassProcessor>)((IEnumerable<Type>)AccessTools.GetTypesFromAssembly(new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly)).Select((Func<Type, PatchClassProcessor>)harmony.CreateClassProcessor).ToArray(), (Func<PatchClassProcessor, bool>)((PatchClassProcessor patchClass) => ((HarmonyPatchCategory)patchClass.containerType.GetCustomAttribute(typeof(HarmonyPatchCategory), inherit: true))?.Category == category), (Action<PatchClassProcessor>)delegate(PatchClassProcessor patchClass) { patchClass.Patch(); }); } public static void PatchAllUncategorized(this Harmony harmony) { CollectionExtensions.DoIf<PatchClassProcessor>((IEnumerable<PatchClassProcessor>)((IEnumerable<Type>)AccessTools.GetTypesFromAssembly(new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly)).Select((Func<Type, PatchClassProcessor>)harmony.CreateClassProcessor).ToArray(), (Func<PatchClassProcessor, bool>)((PatchClassProcessor patchClass) => string.IsNullOrEmpty(((HarmonyPatchCategory)patchClass.containerType.GetCustomAttribute(typeof(HarmonyPatchCategory), inherit: true))?.Category)), (Action<PatchClassProcessor>)delegate(PatchClassProcessor patchClass) { patchClass.Patch(); }); } } internal class Log { private static bool Dbg; private static ManualLogSource Src; public Log(ManualLogSource logSrc, bool debug = false) { Src = logSrc; Dbg = debug; } public static void Info(object message) { ManualLogSource src = Src; if (src != null) { src.LogInfo(message); } } public static void Warn(object message) { ManualLogSource src = Src; if (src != null) { src.LogWarning(message); } } public static void Error(object message) { ManualLogSource src = Src; if (src != null) { src.LogError(message); } } public static void Debug(object message) { if (Dbg) { ManualLogSource src = Src; if (src != null) { src.LogDebug(message); } } } } [BepInPlugin("xyz.poogle.moreemotespatch", "More Emotes Patch", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MoreEmotesPatchPlugin : BaseUnityPlugin { private enum InitType { None, BetterEmotes, MoreEmotes, Both } private static InitType init_mode = InitType.None; private readonly Harmony harmony = new Harmony("xyz.poogle.moreemotespatch"); public const string GUID = "xyz.poogle.moreemotespatch"; public const string NAME = "More Emotes Patch"; public const string VER = "1.1.0"; internal static ConfigEntry<int> maxEmoteTime; internal static Type BE_emoteDefs = AccessTools.TypeByName("BetterEmote.Utils.EmoteDefs"); internal static Type BE_emotes = AccessTools.TypeByName("BetterEmote.Utils.Emote"); internal static Type BE_doubleEmotes = AccessTools.TypeByName("BetterEmote.Utils.DoubleEmote"); internal static Type BE_altEmotes = AccessTools.TypeByName("BetterEmote.Utils.AltEmote"); internal static Type ME_emotePatch = AccessTools.TypeByName("MoreEmotes.Patch.EmotePatch"); internal static Type ME_emotes = AccessTools.TypeByName("MoreEmotes.Patch.Emotes"); private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0057: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown new Log(Logger.CreateLogSource("xyz.poogle.moreemotespatch"), debug: true); maxEmoteTime = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxEmoteTime", 30, "The max time for any emote to last before auto cancelled in seconds.\n(0 will never cancel.)"); ConfigEntry<int> obj = maxEmoteTime; IntSliderOptions val = new IntSliderOptions { RequiresRestart = false }; ((BaseRangeOptions<int>)val).Min = 0; ((BaseRangeOptions<int>)val).Max = 120; LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(obj, val)); if (BE_emoteDefs != null && BE_emotes != null && BE_doubleEmotes != null && BE_altEmotes != null) { Log.Warn("Found BetterEmotes for patching!"); if (Harmony.HasAnyPatches("BetterEmotes")) { init_mode |= InitType.BetterEmotes; BE_Patches.InitPatches(harmony); } else { Log.Warn("BetterEmotes doesn't have a harmony instance to patch."); } } if (ME_emotes != null && ME_emotePatch != null) { Log.Warn("Using legacy MoreEmotes patch, you should switch to BetterEmotes!"); if (Harmony.HasAnyPatches("MoreEmotes")) { init_mode |= InitType.MoreEmotes; ME_Patches.InitPatches(harmony); } else { Log.Warn("MoreEmotes doesn't have a harmony instance to patch."); } } if (init_mode != 0) { Log.Info($"We have initialized with patches: {init_mode}"); } else { Log.Error("Could not initialize as no compatible mod was found."); } } } internal class Common_Patches { [HarmonyPatch(typeof(PlayerControllerB))] [HarmonyPatch("CheckConditionsForEmote")] public static class PlayerControllerB_CheckConditionsForEmote_Patch { [HarmonyPriority(0)] public static void Postfix(PlayerControllerB __instance, ref bool __result) { __result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.inTerminalMenu; } } } internal class BE_Patches { [HarmonyPatch(typeof(PlayerControllerB))] [HarmonyPatch("PerformEmote")] [Extensions.HarmonyPatchCategory("BetterEmotes")] public static class PlayerControllerB_PerformEmote_Patch { [HarmonyPriority(800)] public static bool Prefix(PlayerControllerB __instance, int emoteID) { int integer = __instance.playerBodyAnimator.GetInteger("emoteNumber"); if (__instance.performingEmote) { if (BE_Doubles.Contains(emoteID)) { if (integer == emoteID + BE_Offset) { return Extensions.StopAnyEmotes(__instance); } return true; } if (integer == emoteID) { return Extensions.StopAnyEmotes(__instance); } } LastEmoteTime = Extensions.CurrentTime; return true; } } [HarmonyPatch(typeof(PlayerControllerB))] [HarmonyPatch("Update")] [Extensions.HarmonyPatchCategory("BetterEmotes")] public static class PlayerControllerB_Update_Patch { [HarmonyPriority(800)] public static bool Prefix(PlayerControllerB __instance) { if (MoreEmotesPatchPlugin.maxEmoteTime.Value > 0 && __instance.performingEmote) { if (__instance.playerBodyAnimator.GetInteger("emoteNumber") != (int)Enum.Parse(MoreEmotesPatchPlugin.BE_emotes, "Sign") && LastEmoteTime != -1 && Extensions.CurrentTime - LastEmoteTime > MoreEmotesPatchPlugin.maxEmoteTime.Value) { Extensions.StopAnyEmotes(__instance); } if (!__instance.CheckConditionsForEmote()) { Extensions.StopAnyEmotes(__instance); } } return true; } } private static int LastEmoteTime = -1; internal static int BE_Offset = ((int[])Enum.GetValues(MoreEmotesPatchPlugin.BE_doubleEmotes))[0] - (int)AccessTools.Method(MoreEmotesPatchPlugin.BE_emoteDefs, "normalizeEmoteNumber", (Type[])null, (Type[])null).Invoke(null, new object[1] { ((int[])Enum.GetValues(MoreEmotesPatchPlugin.BE_doubleEmotes))[0] }); internal static int[] BE_Doubles = (from x in CollectionExtensions.AddRangeToArray<int>((int[])Enum.GetValues(MoreEmotesPatchPlugin.BE_doubleEmotes), (int[])Enum.GetValues(MoreEmotesPatchPlugin.BE_altEmotes)) select x - BE_Offset).ToArray(); internal static void InitPatches(Harmony harmony) { harmony.PatchAllUncategorized(); harmony.PatchCategory("BetterEmotes"); } } internal class ME_Patches { [HarmonyPatch] [Extensions.HarmonyPatchCategory("MoreEmotes")] public static class MoreEmotes_EmotePatch_CheckEmoteInput_Patch { private static MethodBase TargetMethod() { return MoreEmotesPatchPlugin.ME_emotePatch.GetMethod("CheckEmoteInput", AccessTools.all); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown Log.Info("Patching CheckEmoteInput!"); MethodInfo methodInfo = AccessTools.Method(typeof(InputControlExtensions), "IsPressed", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(ButtonControl), "wasPressedThisFrame"); List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count - 1; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 0f && CodeInstructionExtensions.Calls(list[i + 1], methodInfo)) { list[i] = new CodeInstruction(OpCodes.Castclass, (object)typeof(ButtonControl)); list[i + 1] = new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2); Log.Info("Patched CheckEmoteInput!"); return list; } } Log.Error("Could not find IL to transpile, bailing patch!"); return list; } } [HarmonyPatch(typeof(PlayerControllerB))] [HarmonyPatch("PerformEmote")] [Extensions.HarmonyPatchCategory("MoreEmotes")] public static class PlayerControllerB_PerformEmote_Patch { [HarmonyPriority(800)] public static bool Prefix(PlayerControllerB __instance, int emoteID) { int integer = __instance.playerBodyAnimator.GetInteger("emoteNumber"); if (__instance.performingEmote) { if (MO_Doubles.Contains(emoteID)) { if (integer == emoteID + MO_Offset) { return Extensions.StopAnyEmotes(__instance); } return true; } if (integer == emoteID) { return Extensions.StopAnyEmotes(__instance); } } LastEmoteTime = Extensions.CurrentTime; return true; } } [HarmonyPatch(typeof(PlayerControllerB))] [HarmonyPatch("Update")] [Extensions.HarmonyPatchCategory("MoreEmotes")] public static class PlayerControllerB_Update_Patch { [HarmonyPriority(800)] public static bool Prefix(PlayerControllerB __instance) { if (MoreEmotesPatchPlugin.maxEmoteTime.Value > 0 && __instance.performingEmote) { if (__instance.playerBodyAnimator.GetInteger("emoteNumber") != (int)Enum.Parse(MoreEmotesPatchPlugin.ME_emotes, "Sign") && LastEmoteTime != -1 && Extensions.CurrentTime - LastEmoteTime > MoreEmotesPatchPlugin.maxEmoteTime.Value) { Extensions.StopAnyEmotes(__instance); } if (!__instance.CheckConditionsForEmote()) { Extensions.StopAnyEmotes(__instance); } } return true; } } private static int LastEmoteTime = -1; internal static int MO_Offset = Extensions._get<int>(MoreEmotesPatchPlugin.ME_emotePatch, "_AlternateEmoteIDOffset"); internal static int[] MO_Doubles = (from x in (int[])Enum.GetValues(MoreEmotesPatchPlugin.ME_emotes) where x - MO_Offset > 0 select x - MO_Offset).ToArray(); internal static void InitPatches(Harmony harmony) { harmony.PatchAllUncategorized(); harmony.PatchCategory("MoreEmotes"); } } }