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";
}
}