Decompiled source of InfiniteEmote v1.3.3

InfiniteEmote.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("InfiniteEmote")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adjusts CheckConditionsForEmote conditions")]
[assembly: AssemblyFileVersion("1.3.3.0")]
[assembly: AssemblyInformationalVersion("1.3.3+5772b8680c25c78aa9b8ebb313ada9a0f346c305")]
[assembly: AssemblyProduct("InfiniteEmote")]
[assembly: AssemblyTitle("InfiniteEmote")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.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;
		}
	}
}
namespace InfiniteEmote
{
	[Serializable]
	public class Config : SyncedInstance<Config>
	{
		public bool WhileJumping = true;

		public bool WhileWalking = true;

		public bool WhileSprinting = true;

		public bool WhileCrouching;

		public bool WhileLadder;

		public bool WhileGrabbing;

		public bool WhileTyping;

		public bool WhileTerminal;

		public bool WhileHolding = true;

		public bool WhileHoldingTwoHand = true;

		[NonSerialized]
		private static string Section = "Emote while";

		public Config(ConfigFile configFile)
		{
			InitInstance(this);
			Plugin.Debug("Loading emote while options");
			WhileJumping = configFile.Bind<bool>(Section, "Jumping", WhileJumping, "Whether or not to allow emoting while Jumping").Value;
			WhileWalking = configFile.Bind<bool>(Section, "Walking", WhileWalking, "Whether or not to allow emoting while Walking").Value;
			WhileSprinting = configFile.Bind<bool>(Section, "Sprinting", WhileSprinting, "Whether or not to allow emoting while Sprinting").Value;
			WhileCrouching = configFile.Bind<bool>(Section, "Crouching", WhileCrouching, "Whether or not to allow emoting while Crouching").Value;
			WhileLadder = configFile.Bind<bool>(Section, "Ladder", WhileLadder, "Whether or not to allow emoting while climbing Ladder").Value;
			WhileGrabbing = configFile.Bind<bool>(Section, "Grabbing", WhileGrabbing, "Whether or not to allow emoting while Grabbing").Value;
			WhileTyping = configFile.Bind<bool>(Section, "Typing", WhileTyping, "Whether or not to allow emoting while Typing").Value;
			WhileTerminal = configFile.Bind<bool>(Section, "Terminal", WhileTerminal, "Whether or not to allow emoting while in the Terminal").Value;
			WhileHolding = configFile.Bind<bool>(Section, "Holding", WhileHolding, "Whether or not to allow emoting while Holding an object").Value;
			WhileHoldingTwoHand = configFile.Bind<bool>(Section, "HoldingTwoHand", WhileHoldingTwoHand, "Whether or not to allow emoting while Holding a two handed object").Value;
		}

		public void DebugValues()
		{
			Plugin.Debug($"WhileJumping '{WhileJumping}'");
			Plugin.Debug($"WhileWalking '{WhileWalking}'");
			Plugin.Debug($"WhileSprinting '{WhileSprinting}'");
			Plugin.Debug($"WhileCrouching '{WhileCrouching}'");
			Plugin.Debug($"WhileLadder '{WhileLadder}'");
			Plugin.Debug($"WhileGrabbing '{WhileGrabbing}'");
			Plugin.Debug($"WhileTyping '{WhileTyping}'");
			Plugin.Debug($"WhileTerminal '{WhileTerminal}'");
			Plugin.Debug($"WhileHoldingTwoHand '{WhileHoldingTwoHand}'");
		}

		public static void RequestSync()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				SyncedInstance<Config>.MessageManager.SendNamedMessage("ModName_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsHost)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				SyncedInstance<Config>.MessageManager.SendNamedMessage("ModName_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize))
			{
				Plugin.Logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.Logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncedInstance<Config>.SyncInstance(data);
			Plugin.Logger.LogInfo((object)"Successfully synced config with host.");
		}
	}
	internal class Keybinds : LcInputActions
	{
		public InputAction StopEmote => ((LcInputActions)this).Asset["StopEmote"];

		public override void CreateInputActions(in InputActionMapBuilder builder)
		{
			((LcInputActions)this).CreateInputActions(ref builder);
			builder.NewActionBinding().WithActionId("StopEmote").WithActionType((InputActionType)1)
				.WithKbmPath(Patches.stopEmoteKey)
				.WithGamepadPath(Patches.stopEmoteController)
				.WithBindingName("Stop Emote")
				.Finish();
		}
	}
	internal class Patches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<CallbackContext> <0>__onStopEmoteKey;

			public static HandleNamedMessageDelegate <1>__OnRequestSync;

			public static HandleNamedMessageDelegate <2>__OnReceiveSync;
		}

		public static Keybinds keybinds;

		public static string stopEmoteKey;

		public static string stopEmoteController;

		public static bool moreEmotes;

		private static PlayerControllerB localPlayerController
		{
			get
			{
				StartOfRound instance = StartOfRound.Instance;
				if (!((Object)(object)instance != (Object)null))
				{
					return null;
				}
				return instance.localPlayerController;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(PlayerControllerB __instance)
		{
			Plugin.Debug("PlayerControllerB.StartPostfix");
			keybinds.StopEmote.performed += onStopEmoteKey;
			keybinds.StopEmote.Enable();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisablePostfix(PlayerControllerB __instance)
		{
			Plugin.Debug("OnDisablePostfix");
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				Plugin.Debug("localPlayerController is instance");
				keybinds.StopEmote.performed -= onStopEmoteKey;
				keybinds.StopEmote.Disable();
			}
		}

		private static void onStopEmoteKey(CallbackContext context)
		{
			Plugin.Debug("onStopEmoteKey");
			if (localPlayerController.isPlayerControlled && ((NetworkBehaviour)localPlayerController).IsOwner)
			{
				Plugin.Debug("isPlayerControlled and IsOwner");
				localPlayerController.performingEmote = false;
				localPlayerController.StopPerformingEmoteServerRpc();
				localPlayerController.timeSinceStartingEmote = 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "CheckConditionsForEmote")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "BetterEmotes", "MoreEmotes" })]
		private static void CheckConditionsForEmotePatch(PlayerControllerB __instance, ref bool __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (__instance.inSpecialInteractAnimation || __instance.isPlayerDead)
			{
				Plugin.Debug($"inSpecialInteractAnimation ({__instance.inSpecialInteractAnimation}) or isPlayerDead ({__instance.isPlayerDead})");
				__result = false;
				return;
			}
			if (__instance.isGrabbingObjectAnimation)
			{
				Plugin.Debug($"isGrabbingObjectAnimation ({__instance.isGrabbingObjectAnimation}), whileGrabbing ({SyncedInstance<Config>.Instance.WhileGrabbing})");
				if (!SyncedInstance<Config>.Instance.WhileGrabbing)
				{
					__result = false;
					return;
				}
				__result = true;
			}
			if (__instance.isHoldingObject)
			{
				Plugin.Debug($"isHoldingObject ({__instance.isHoldingObject}), whileHolding ({SyncedInstance<Config>.Instance.WhileHolding})");
				if (!SyncedInstance<Config>.Instance.WhileHolding)
				{
					__result = false;
					return;
				}
				if (__instance.twoHanded)
				{
					Plugin.Debug($"twoHanded ({__instance.twoHanded}), whileHoldingTwoHand ({SyncedInstance<Config>.Instance.WhileHoldingTwoHand})");
					if (!SyncedInstance<Config>.Instance.WhileHoldingTwoHand)
					{
						__result = false;
						return;
					}
					__result = true;
				}
				else
				{
					__result = true;
				}
			}
			if (__instance.isJumping)
			{
				Plugin.Debug($"isJumping, whileJumping ({SyncedInstance<Config>.Instance.WhileJumping})");
				__result = SyncedInstance<Config>.Instance.WhileJumping;
			}
			if (__instance.isWalking)
			{
				Plugin.Debug($"isWalking, whileWalking ({SyncedInstance<Config>.Instance.WhileWalking})");
				__result = SyncedInstance<Config>.Instance.WhileWalking;
			}
			if (__instance.isSprinting)
			{
				Plugin.Debug($"isSprinting, whileSprinting ({SyncedInstance<Config>.Instance.WhileSprinting})");
				__result = SyncedInstance<Config>.Instance.WhileSprinting;
			}
			if (__instance.isCrouching)
			{
				Plugin.Debug($"isCrouching, whileCrouching ({SyncedInstance<Config>.Instance.WhileCrouching})");
				__result = SyncedInstance<Config>.Instance.WhileCrouching;
			}
			if (__instance.isClimbingLadder)
			{
				Plugin.Debug($"isClimbingLadder, whileLadder ({SyncedInstance<Config>.Instance.WhileLadder})");
				__result = SyncedInstance<Config>.Instance.WhileLadder;
			}
			if (__instance.isTypingChat)
			{
				int integer = __instance.playerBodyAnimator.GetInteger("emoteNumber");
				Plugin.Debug($"isTypingChat, whileTyping ({SyncedInstance<Config>.Instance.WhileTyping}), moreEmotes ({moreEmotes}), currentEmote ({integer})");
				if (moreEmotes && integer == 10)
				{
					Plugin.Debug("isEmoteNumber 10 (Sign for MoreEmotes)");
					__result = true;
				}
				else
				{
					__result = SyncedInstance<Config>.Instance.WhileTyping;
				}
			}
			if (__instance.inTerminalMenu)
			{
				Plugin.Debug($"inTerminalMenu, whileTerminal ({SyncedInstance<Config>.Instance.WhileTerminal})");
				__result = SyncedInstance<Config>.Instance.WhileTerminal;
			}
			if (!__result)
			{
				Plugin.Debug("__result false, following values");
				Plugin.Debug($"!__instance.inSpecialInteractAnimation ({!__instance.inSpecialInteractAnimation})");
				Plugin.Debug($"!__instance.isPlayerDead ({!__instance.isPlayerDead})");
				Plugin.Debug($"!__instance.isJumping ({!__instance.isJumping})");
				Plugin.Debug($"!__instance.isWalking ({!__instance.isWalking})");
				Plugin.Debug($"!__instance.isCrouching ({!__instance.isCrouching})");
				Plugin.Debug($"!__instance.isClimbingLadder ({!__instance.isClimbingLadder})");
				Plugin.Debug($"!__instance.isGrabbingObjectAnimation ({!__instance.isGrabbingObjectAnimation})");
				Plugin.Debug($"!__instance.inTerminalMenu ({!__instance.inTerminalMenu})");
				Plugin.Debug($"!__instance.isTypingChat ({!__instance.isTypingChat})");
				bool flag = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !__instance.isJumping && !__instance.isWalking && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu && !__instance.isTypingChat;
				Plugin.Debug($"result ({flag})");
				__result = flag;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void InitializeLocalPlayer()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Plugin.Debug("InitializeLocalPlayer()");
			if (SyncedInstance<Config>.IsHost)
			{
				try
				{
					CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager;
					object obj = <>O.<1>__OnRequestSync;
					if (obj == null)
					{
						HandleNamedMessageDelegate val = Config.OnRequestSync;
						<>O.<1>__OnRequestSync = val;
						obj = (object)val;
					}
					messageManager.RegisterNamedMessageHandler("ModName_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
					SyncedInstance<Config>.Synced = true;
					return;
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)ex);
					return;
				}
			}
			SyncedInstance<Config>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager;
			object obj2 = <>O.<2>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = Config.OnReceiveSync;
				<>O.<2>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("ModName_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			Config.RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			Plugin.Debug("PlayerLeave()");
			SyncedInstance<Config>.RevertSync();
		}
	}
	[BepInPlugin("InfiniteEmote", "InfiniteEmote", "1.3.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Texture2D texture;

		public static bool debug;

		public static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin InfiniteEmote loading...");
			debug = ((BaseUnityPlugin)this).Config.Bind<bool>("Dev", "Debug", false, "Whether or not to enable debug logging and debug helpers").Value;
			Logger.LogInfo((object)$"Debug enabled: {debug}");
			new Config(((BaseUnityPlugin)this).Config);
			Debug("Loading keybind defaults");
			ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("Keys", "Stop Emote Key", "<Keyboard>/minus", "Default keybind to stop emoting");
			Patches.stopEmoteKey = validatePrefixes(new string[2] { "<Keyboard>", "<Mouse>" }, "<Keyboard>", val.Value);
			ConfigEntry<string> val2 = ((BaseUnityPlugin)this).Config.Bind<string>("Keys", "Stop Emote Button", "<Gamepad>/leftStickPress", "Default controller button to stop emoting");
			Patches.stopEmoteController = validatePrefixes(new string[1] { "<Gamepad>" }, "<Gamepad>", val2.Value);
			Debug("Loaded key '" + Patches.stopEmoteKey + "'");
			Debug("Loaded button '" + Patches.stopEmoteController + "'");
			checkForMods();
			Patches.keybinds = new Keybinds();
			new Harmony("InfiniteEmote").PatchAll(typeof(Patches));
			Logger.LogInfo((object)"Plugin InfiniteEmote is loaded!");
		}

		public static string validatePrefixes(string[] prefixes, string defaultPrefix, string value)
		{
			if (value.Equals(""))
			{
				return "";
			}
			foreach (string text in prefixes)
			{
				if (value.ToLower().StartsWith(text.ToLower()))
				{
					return value;
				}
			}
			return defaultPrefix + "/" + value;
		}

		public static void Debug(string message)
		{
			if (debug)
			{
				Logger.LogDebug((object)message);
			}
		}

		public static void checkForMods()
		{
			Debug("checkForMods");
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				BepInPlugin metadata = pluginInfo.Value.Metadata;
				if (metadata.GUID.Equals("MoreEmotes") || metadata.GUID.Equals("BetterEmotes"))
				{
					Debug("Found MoreEmotes/BetterEmotes");
					Patches.moreEmotes = true;
					break;
				}
			}
		}
	}
	[Serializable]
	public class SyncedInstance<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		internal static bool IsClient => NetworkManager.Singleton.IsClient;

		internal static bool IsHost => NetworkManager.Singleton.IsHost;

		public static T Default { get; private set; }

		public static T Instance { get; private set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = DeserializeFromBytes(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] SerializeToBytes(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error serializing instance: {arg}");
				return null;
			}
		}

		public static T DeserializeFromBytes(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error deserializing instance: {arg}");
				return default(T);
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "InfiniteEmote";

		public const string PLUGIN_NAME = "InfiniteEmote";

		public const string PLUGIN_VERSION = "1.3.3";
	}
}