Decompiled source of More Emotes Patch v1.1.0

MoreEmotesPatch.dll

Decompiled 9 months ago
using 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");
		}
	}
}