Decompiled source of Punkalyn PunkEmotes v2.1.2

plugins/PunkEmotes_RePunked.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Newtonsoft.Json;
using PunkEmotes.Components;
using PunkEmotes.Internals;
using PunkEmotes.Patches;
using SimpleCommandLib;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Punkalyn, Robyn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.2.0")]
[assembly: AssemblyInformationalVersion("2.1.2+06d22e98b9a664b56b8e79c88ff7f6be5a7bde94")]
[assembly: AssemblyProduct("PunkEmotes_RePunked")]
[assembly: AssemblyTitle("PunkEmotes_RePunked")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.2.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "punkalyn.punkemotes";

	public const string PLUGIN_NAME = "PunkEmotes_RePunked";

	public const string PLUGIN_VERSION = "2.1.2";
}
namespace PunkEmotes
{
	[BepInPlugin("punkalyn.punkemotes", "PunkEmotes_RePunked", "2.1.2")]
	[BepInProcess("ATLYSS.exe")]
	public class PunkEmotesPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static PacketListener <0>__HandleChatAnimationMessage;
		}

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Punk Emotes is rockin'!");
			Harmony val = new Harmony("punkalyn.punkemotes");
			int num = 5;
			try
			{
				val.PatchAll(typeof(CharacterSelectManager_Patches));
				val.PatchAll(typeof(ChatBehaviour_Patches));
				val.PatchAll(typeof(Player_Patches));
				val.PatchAll(typeof(PlayerMove_Patches));
				val.PatchAll(typeof(PlayerVisual_Patches));
				if (num != val.GetPatchedMethods().Count())
				{
					Log.LogError((object)$"Punk Emotes patched {val.GetPatchedMethods().Count()} methods out of {num} intended patches!");
				}
				object obj = <>O.<0>__HandleChatAnimationMessage;
				if (obj == null)
				{
					PacketListener val2 = PunkEmotesManager.HandleChatAnimationMessage;
					<>O.<0>__HandleChatAnimationMessage = val2;
					obj = (object)val2;
				}
				CodeTalkerNetwork.RegisterListener<PunkAnimationPacket>((PacketListener)obj);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Exception caught while patching: " + ex.Message));
			}
		}

		internal static void SendChatMessage(string message)
		{
			if (Object.op_Implicit((Object)(object)Player._mainPlayer))
			{
				Player._mainPlayer._cB.New_ChatMessage(message);
			}
		}
	}
}
namespace PunkEmotes.Patches
{
	internal static class CharacterSelectManager_Patches
	{
		[HarmonyPatch(typeof(CharacterSelectManager), "Select_CharacterFile")]
		[HarmonyPostfix]
		private static void Select_CharacterFile_Postfix()
		{
			AnimationConstructor.raceAnimatorReset = true;
			PlayerRegistry.ClearRegistry();
		}
	}
	internal static class ChatBehaviour_Patches
	{
		private static readonly PunkEmotesCommandDispatcher PunkDispatcher = new PunkEmotesCommandDispatcher();

		[HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")]
		[HarmonyPrefix]
		private static bool Send_ChatMessage_Prefix(ref string _message, ChatBehaviour __instance)
		{
			if (string.IsNullOrEmpty(_message))
			{
				return true;
			}
			if (!_message.StartsWith("/em ", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			string text = _message.Replace("/em", string.Empty);
			((CommandDispatcher)PunkDispatcher).ParseAndRunCommand(text);
			return false;
		}
	}
	internal static class Player_Patches
	{
		[HarmonyPatch(typeof(Player), "Start")]
		[HarmonyPostfix]
		private static void Start_Postfix(Player __instance)
		{
			PunkEmotesManager punkEmotesManager = ((Component)__instance).gameObject.GetComponent<PunkEmotesManager>();
			if ((Object)(object)punkEmotesManager == (Object)null)
			{
				punkEmotesManager = ((Component)__instance).gameObject.AddComponent<PunkEmotesManager>();
			}
			PlayerRegistry.RegisterPlayer(__instance, punkEmotesManager);
		}
	}
	internal static class PlayerMove_Patches
	{
		[HarmonyPatch(typeof(PlayerMove), "Set_MovementAction")]
		[HarmonyPostfix]
		private static void Set_MovementAction_Postfix(PlayerMove __instance, MovementAction _mA)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Player component = ((Component)__instance).gameObject.GetComponent<Player>();
			if (!((Object)(object)component == (Object)null))
			{
				PunkEmotesManager component2 = ((Component)component).GetComponent<PunkEmotesManager>();
				if (!((Object)(object)component2 == (Object)null) && (int)_mA != 0 && component2._isAnimationPlaying)
				{
					component2.StopAnimation(component2);
				}
			}
		}
	}
	internal static class PlayerVisual_Patches
	{
		[HarmonyPatch(typeof(PlayerVisual), "Iterate_AnimationCallback")]
		[HarmonyPostfix]
		private static void Iterate_AnimationCallback_Postfix(PlayerVisual __instance, ref string _animName, ref float _animLayer)
		{
			if (AnimationConstructor.raceAnimatorReset)
			{
				AnimationConstructor.LoadRaceFBXs();
			}
		}
	}
}
namespace PunkEmotes.Internals
{
	public class AnimationConstructor
	{
		public class AnimationLibrary
		{
			private static AnimationLibrary? _instance;

			internal readonly Dictionary<string, Dictionary<string, AnimationClip>> animationClips = new Dictionary<string, Dictionary<string, AnimationClip>>(StringComparer.InvariantCultureIgnoreCase)
			{
				{
					"dance",
					new Dictionary<string, AnimationClip>(StringComparer.InvariantCultureIgnoreCase)
				},
				{
					"general",
					new Dictionary<string, AnimationClip>(StringComparer.InvariantCultureIgnoreCase)
				},
				{
					"override",
					new Dictionary<string, AnimationClip>(StringComparer.InvariantCultureIgnoreCase)
				},
				{
					"sit",
					new Dictionary<string, AnimationClip>(StringComparer.InvariantCultureIgnoreCase)
				}
			};

			public static AnimationLibrary Instance
			{
				get
				{
					if (_instance == null)
					{
						_instance = new AnimationLibrary();
					}
					return _instance;
				}
			}

			private AnimationLibrary()
			{
			}

			public void PopulateDefaultAnimations()
			{
				foreach (KeyValuePair<string, Animator> raceAnimator in raceAnimators)
				{
					string key = raceAnimator.Key;
					Animator value = raceAnimator.Value;
					AnimationClip[] array = ExtractAnimationsFromAnimator(value);
					AnimationClip[] array2 = array;
					AnimationClip[] array3 = array2;
					foreach (AnimationClip val in array3)
					{
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						if (((Object)val).name.Contains("dance"))
						{
							if (((Object)val).name == "Kobold_dance")
							{
								((Object)val).name = "kubold_dance";
							}
							animationClips["dance"][key + "_dance"] = val;
							PunkEmotesPlugin.Log.LogDebug((object)("Added " + ((Object)val).name + " as " + key + "_dance to animation library!"));
						}
						if (((Object)val).name.Contains("sitInit") && !((Object)val).name.Contains("02"))
						{
							if (((Object)val).name == "Kobold_sitInit")
							{
								((Object)val).name = "kubold_sitInit";
							}
							animationClips["override"][key + "_sitInit"] = val;
							animationClips["sit"][key + "_sitInit"] = val;
							PunkEmotesPlugin.Log.LogDebug((object)("Added " + ((Object)val).name + " as " + key + "_sitInit to animation library!"));
						}
						if (((Object)val).name.Contains("sitLoop") && !((Object)val).name.Contains("02"))
						{
							if (((Object)val).name == "Kobold_sitLoop")
							{
								((Object)val).name = "kubold_sitLoop";
							}
							animationClips["override"][key + "_sitLoop"] = val;
							PunkEmotesPlugin.Log.LogDebug((object)("Added " + ((Object)val).name + " as " + key + "_sitLoop to animation library!"));
						}
						if (((Object)val).name.Contains("sitInit02"))
						{
							if (((Object)val).name == "Kobold_sitInit02")
							{
								((Object)val).name = "kubold_sitInit02";
							}
							animationClips["override"][key + "_sitInit02"] = val;
							PunkEmotesPlugin.Log.LogDebug((object)("Added " + ((Object)val).name + " as " + key + "_sitInit02 to animation library!"));
						}
						if (((Object)val).name.Contains("sitLoop02"))
						{
							if (((Object)val).name == "Kobold_sitLoop")
							{
								((Object)val).name = "kubold_sitLoop";
							}
							animationClips["override"][key + "_sitLoop02"] = val;
							PunkEmotesPlugin.Log.LogDebug((object)("Added " + ((Object)val).name + " as " + key + "_sitLoop02 to animation library!"));
						}
					}
				}
			}

			private AnimationClip[] ExtractAnimationsFromAnimator(Animator animator)
			{
				List<AnimationClip> list = new List<AnimationClip>();
				AnimationClip[] array = animator.runtimeAnimatorController.animationClips;
				AnimationClip[] array2 = array;
				foreach (AnimationClip item in array2)
				{
					list.Add(item);
				}
				return list.ToArray();
			}

			public void LoadAnimations()
			{
				AnimationClip[] array = Resources.LoadAll<AnimationClip>("Animations/");
				AnimationClip[] array2 = array;
				AnimationClip[] array3 = array2;
				foreach (AnimationClip val in array3)
				{
				}
			}

			public AnimationClip? GetAnimation(string name, string? category)
			{
				name = name.ToLowerInvariant();
				if (!string.IsNullOrEmpty(category) && animationClips.ContainsKey(category))
				{
					Dictionary<string, AnimationClip> dictionary = animationClips[category];
					if (dictionary.ContainsKey(name))
					{
						return dictionary[name];
					}
					foreach (AnimationClip value in dictionary.Values)
					{
						if (((Object)value).name.Equals(name, StringComparison.OrdinalIgnoreCase))
						{
							return value;
						}
					}
					foreach (string key in dictionary.Keys)
					{
						if (key.Contains(name))
						{
							return dictionary[key];
						}
					}
					foreach (AnimationClip value2 in dictionary.Values)
					{
						if (((Object)value2).name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return value2;
						}
					}
					PunkEmotesPlugin.Log.LogDebug((object)("No animation named: " + name + " in category: " + category));
				}
				if (animationClips.ContainsKey("general") && category == null)
				{
					Dictionary<string, AnimationClip> dictionary2 = animationClips["general"];
					if (dictionary2.ContainsKey(name))
					{
						return dictionary2[name];
					}
					foreach (AnimationClip value3 in dictionary2.Values)
					{
						if (((Object)value3).name.Equals(name, StringComparison.OrdinalIgnoreCase))
						{
							return value3;
						}
					}
					foreach (string key2 in dictionary2.Keys)
					{
						if (key2.Contains(name))
						{
							return dictionary2[key2];
						}
					}
					foreach (AnimationClip value4 in dictionary2.Values)
					{
						if (((Object)value4).name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return value4;
						}
					}
				}
				if (category == null)
				{
					foreach (Dictionary<string, AnimationClip> value5 in animationClips.Values)
					{
						if (value5.ContainsKey(name))
						{
							return value5[name];
						}
						foreach (AnimationClip value6 in value5.Values)
						{
							if (((Object)value6).name.Equals(name, StringComparison.OrdinalIgnoreCase))
							{
								return value6;
							}
						}
						foreach (string key3 in value5.Keys)
						{
							if (key3.Contains(name))
							{
								return value5[key3];
							}
						}
						foreach (AnimationClip value7 in value5.Values)
						{
							if (((Object)value7).name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
							{
								return value7;
							}
						}
					}
				}
				PunkEmotesPlugin.Log.LogWarning((object)("No animation found with the name: " + name));
				return null;
			}
		}

		private static Dictionary<string, Animator> raceAnimators = new Dictionary<string, Animator>();

		internal static bool raceAnimatorReset = true;

		internal static void LoadRaceFBXs()
		{
			string[] array = new string[5] { "byrdle", "chang", "imp", "Kobold", "poon" };
			string[] array2 = array;
			string[] array3 = array2;
			foreach (string text in array3)
			{
				GameObject val = GameObject.Find(text + "FBX");
				if ((Object)(object)val != (Object)null)
				{
					Animator component = val.GetComponent<Animator>();
					raceAnimators[text] = component;
					PunkEmotesPlugin.Log.LogDebug((object)(text + " loaded into animation memory"));
				}
			}
			AnimationLibrary.Instance.PopulateDefaultAnimations();
			raceAnimatorReset = false;
		}
	}
	internal class CommandHelp : ICommandRunner
	{
		public string CommandName => "help";

		public string CommandUsage => string.Empty;

		public bool Execute(string[] args)
		{
			PunkEmotesPlugin.SendChatMessage("Commands: '/em animation_name (or race)'");
			PunkEmotesPlugin.SendChatMessage("Commands: '/em category animation_name (or race)'");
			PunkEmotesPlugin.SendChatMessage("Categories: 'sit', 'dance'");
			PunkEmotesPlugin.SendChatMessage("Test animation: '/em 02'");
			PunkEmotesPlugin.Log.LogDebug((object)"Available commands: overrides, list, help");
			return true;
		}
	}
	internal class CommandList : ICommandRunner
	{
		public string CommandName => "list";

		public string CommandUsage => string.Empty;

		public bool Execute(string[] args)
		{
			StringBuilder stringBuilder = new StringBuilder("All Animations:\n\n");
			foreach (KeyValuePair<string, Dictionary<string, AnimationClip>> animationClip in AnimationConstructor.AnimationLibrary.Instance.animationClips)
			{
				stringBuilder.Append(animationClip.Key);
				stringBuilder.AppendLine(":");
				foreach (KeyValuePair<string, AnimationClip> item in animationClip.Value)
				{
					stringBuilder.Append("  ");
					stringBuilder.Append(item.Key);
					stringBuilder.Append(": ");
					stringBuilder.AppendLine(((Object)item.Value).name);
				}
				stringBuilder.Append('\n');
			}
			PunkEmotesPlugin.Log.LogDebug((object)stringBuilder.ToString());
			return true;
		}
	}
	internal class CommandOverride : ICommandRunner
	{
		public string CommandName => "override";

		public string CommandUsage => string.Empty;

		public bool Execute(string[] args)
		{
			if (args.Length < 2)
			{
				return false;
			}
			PunkEmotesManager emotesManagerByNetId = PlayerRegistry.GetEmotesManagerByNetId(((NetworkBehaviour)Player._mainPlayer).netId);
			if (emotesManagerByNetId == null)
			{
				PunkEmotesPlugin.Log.LogWarning((object)$"Unable to get emotes manager for client ID (ChatBehavior): {((NetworkBehaviour)Player._mainPlayer).netId}");
				return false;
			}
			string text = args[0].ToLower();
			string text2 = args[1].ToLower();
			if ((Object)(object)AnimationConstructor.AnimationLibrary.Instance.GetAnimation(text2, "override") == (Object)null)
			{
				PunkEmotesPlugin.Log.LogError((object)("Override animation '" + text2 + "' not found."));
				return false;
			}
			if (emotesManagerByNetId.overrideAliases.ContainsKey(text))
			{
				List<string> list = emotesManagerByNetId.overrideAliases[text];
				string animationName = text2 + list[2];
				string animationName2 = text2 + list[3];
				emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, animationName, list[0]);
				emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, animationName2, list[1]);
			}
			else
			{
				emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, text2, text);
			}
			return true;
		}
	}
	internal class CommandPlayEmote : ICommandRunner
	{
		public string CommandName => "emote";

		public string CommandUsage => string.Empty;

		public bool Execute(string[] args)
		{
			if (args.Length == 0)
			{
				return false;
			}
			PunkEmotesManager emotesManagerByNetId = PlayerRegistry.GetEmotesManagerByNetId(((NetworkBehaviour)Player._mainPlayer).netId);
			if (emotesManagerByNetId == null)
			{
				PunkEmotesPlugin.Log.LogWarning((object)$"Unable to get emotes manager for client ID (ChatBehavior): {((NetworkBehaviour)Player._mainPlayer).netId}");
				return false;
			}
			string animationCategory = ((args.Length > 1) ? args[0] : null);
			string animationName = ((args.Length == 1) ? args[0] : args[1]);
			emotesManagerByNetId.PlayAnimationClip("ALL", emotesManagerByNetId, animationName, animationCategory);
			return true;
		}
	}
	internal class PunkEmotesCommandDispatcher : CommandDispatcher
	{
		protected ICommandRunner EmotesCommand;

		private readonly Dictionary<string, ICommandRunner> _commands = new Dictionary<string, ICommandRunner>(StringComparer.InvariantCultureIgnoreCase);

		protected override Dictionary<string, ICommandRunner> CommandsMap
		{
			get
			{
				return _commands;
			}
			set
			{
			}
		}

		public PunkEmotesCommandDispatcher()
		{
			EmotesCommand = (ICommandRunner)(object)new CommandPlayEmote();
			((CommandDispatcher)this).TryAddCommand((ICommandRunner)(object)new CommandHelp());
			((CommandDispatcher)this).TryAddCommand((ICommandRunner)(object)new CommandOverride());
			((CommandDispatcher)this).TryAddCommand((ICommandRunner)(object)new CommandList());
		}

		public override void OnCommandNotFound(string commandName)
		{
		}

		public override bool RunCommand(string commandName, string[] args)
		{
			if (((CommandDispatcher)this).RunCommand(commandName, args))
			{
				return true;
			}
			string[] array = (from s in new string[1] { commandName.ToLowerInvariant() }.Concat(args)
				select s.ToLowerInvariant()).ToArray();
			PunkEmotesPlugin.Log.LogDebug((object)$"Running em with {array.Length} args");
			return EmotesCommand.Execute(array);
		}
	}
	public static class PlayerRegistry
	{
		private class PlayerEntry
		{
			public string? Nickname { get; set; }

			public Player? PlayerInstance { get; set; }

			public PunkEmotesManager? EmotesManager { get; set; }
		}

		private static Dictionary<uint, PlayerEntry> _playersByNetId = new Dictionary<uint, PlayerEntry>();

		public static void RegisterPlayer(Player player, PunkEmotesManager emotesManager)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)emotesManager != (Object)null)
			{
				uint netId = ((NetworkBehaviour)player).netId;
				if (!_playersByNetId.ContainsKey(netId))
				{
					_playersByNetId[netId] = new PlayerEntry
					{
						Nickname = player.Network_nickname,
						PlayerInstance = player,
						EmotesManager = emotesManager
					};
				}
			}
		}

		public static void UnregisterPlayer(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				uint netId = ((NetworkBehaviour)player).netId;
				_playersByNetId.Remove(netId);
			}
		}

		public static void ClearRegistry()
		{
			_playersByNetId.Clear();
		}

		public static PunkEmotesManager? GetEmotesManagerByNetId(uint netId)
		{
			if (!_playersByNetId.TryGetValue(netId, out PlayerEntry value))
			{
				return null;
			}
			return value.EmotesManager;
		}

		public static Player? GetPlayerByNetId(uint netId)
		{
			if (!_playersByNetId.TryGetValue(netId, out PlayerEntry value))
			{
				return null;
			}
			return value.PlayerInstance;
		}

		public static Player? GetPlayerByNickname(string nickname)
		{
			foreach (PlayerEntry value in _playersByNetId.Values)
			{
				if (value.Nickname == nickname)
				{
					return value.PlayerInstance;
				}
			}
			return null;
		}
	}
	internal class PunkAnimationPacket : PacketBase
	{
		[JsonProperty]
		public readonly uint SenderNetworkID;

		[JsonProperty]
		public readonly bool TargetAll;

		[JsonProperty]
		public readonly uint? MessageTargetNetworkID;

		[JsonProperty]
		public readonly string RequestType;

		[JsonProperty]
		public readonly string AnimationName;

		[JsonProperty]
		public readonly string AnimationCategory;

		public override string PacketSourceGUID => "punkalyn.punkemotes";

		[JsonConstructor]
		internal PunkAnimationPacket(uint SenderNetworkID, bool TargetAll, uint? MessageTargetNetworkID, string RequestType, string AnimationName, string AnimationCategory)
		{
			this.SenderNetworkID = SenderNetworkID;
			this.TargetAll = TargetAll;
			this.MessageTargetNetworkID = MessageTargetNetworkID;
			this.RequestType = RequestType;
			this.AnimationName = AnimationName;
			this.AnimationCategory = AnimationCategory;
		}

		public PunkAnimationPacket(uint sender, string targetInfo, string requestType, string animationName, string animationCategory)
		{
			SenderNetworkID = sender;
			if (targetInfo.Equals("ALL", StringComparison.InvariantCultureIgnoreCase))
			{
				TargetAll = true;
			}
			else
			{
				if (!uint.TryParse(targetInfo, out var result))
				{
					throw new ArgumentException("targetInfo must either be ALL or network ID of target, message is malformed!\nInput: " + targetInfo);
				}
				MessageTargetNetworkID = result;
			}
			RequestType = requestType;
			AnimationName = animationName;
			AnimationCategory = animationCategory;
		}

		[Obsolete("PunkEmotes no longer supports using strings to create packets please use the common constructor instead")]
		public static bool TryFromString(string message, [NotNullWhen(true)] out PunkAnimationPacket? result)
		{
			result = null;
			string[] array = message.ToLower().Split('#');
			if (array.Length < 5)
			{
				PunkEmotesPlugin.Log.LogWarning((object)("Attempted to parse malformed network message (Block count): " + message));
				return false;
			}
			if (uint.TryParse(array[2], out var result2))
			{
				string targetInfo = array[3];
				string requestType = array[4];
				string animationName = array[5];
				string animationCategory = ((array.Length > 6) ? array[6] : string.Empty);
				try
				{
					result = new PunkAnimationPacket(result2, targetInfo, requestType, animationName, animationCategory);
					return true;
				}
				catch (ArgumentException arg)
				{
					PunkEmotesPlugin.Log.LogError((object)$"Error while parsing: \n{arg}\n");
				}
				return false;
			}
			PunkEmotesPlugin.Log.LogWarning((object)("Attempted to parse malformed network message (SenderID): " + message));
			return false;
		}

		public string SerializeToString()
		{
			return ((object)this).ToString();
		}
	}
}
namespace PunkEmotes.Components
{
	public class PunkEmotesManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <WaitForAnimator>d__14 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PunkEmotesManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForAnimator>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Expected O, but got Unknown
				int num = <>1__state;
				PunkEmotesManager punkEmotesManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					punkEmotesManager._player = ((Component)punkEmotesManager).GetComponent<Player>();
					if ((Object)(object)punkEmotesManager._player == (Object)null)
					{
						PunkEmotesPlugin.Log.LogError((object)"PunkEmotesManager must be attached to a Player object.");
						return false;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)punkEmotesManager._player._pVisual == (Object)null || (Object)(object)punkEmotesManager._player._pVisual._visualAnimator == (Object)null)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				punkEmotesManager._animator = ((Component)punkEmotesManager._player._pVisual._visualAnimator).GetComponent<Animator>();
				if ((Object)(object)punkEmotesManager._animator != (Object)null)
				{
					punkEmotesManager.newOverrideController = new AnimatorOverrideController(punkEmotesManager._animator.runtimeAnimatorController);
					punkEmotesManager.InitializeGraph(punkEmotesManager._animator);
					PunkEmotesPlugin.Log.LogDebug((object)("Attached PunkEmotesManager to player: " + punkEmotesManager._player._nickname));
					punkEmotesManager.Initialized = true;
					punkEmotesManager.SendSyncRequest();
				}
				else
				{
					PunkEmotesPlugin.Log.LogError((object)"Animator component not found on PlayerVisual, the component is not initialized, networking disabled!");
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private bool Initialized;

		private PlayableGraph _playableGraph;

		public Animator _animator;

		private AnimationClipPlayable _currentClipPlayable;

		private AnimationLayerMixerPlayable _layerMixerPlayable;

		private AnimatorOverrideController newOverrideController;

		public Dictionary<string, List<string>> overrideAliases = new Dictionary<string, List<string>>();

		internal static readonly ChatChannel PUNK_NETWORK_CHANNEL = (ChatChannel)3;

		private string? _currentAnimation = string.Empty;

		private string? _currentCategory = string.Empty;

		private List<string> playerOverrides = new List<string>();

		private Player _player;

		public bool _isAnimationPlaying;

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StartCoroutine(WaitForAnimator());
			_animator = ((Component)this).GetComponent<Animator>();
			_playableGraph = PlayableGraph.Create();
			_player = ((Component)this).GetComponent<Player>();
			_currentClipPlayable = AnimationClipPlayable.Create(_playableGraph, (AnimationClip)null);
			overrideAliases["sit"] = new List<string>(4) { "_playeremote_sitinit", "_playeremote_sitloop", "_sitInit", "_sitLoop" };
			overrideAliases["sit2"] = new List<string>(4) { "_playeremote_sitinit02", "_playeremote_sitloop02", "_sitInit02", "_sitLoop02" };
		}

		[IteratorStateMachine(typeof(<WaitForAnimator>d__14))]
		private IEnumerator WaitForAnimator()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForAnimator>d__14(0)
			{
				<>4__this = this
			};
		}

		public void InitializeGraph(Animator animator)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)animator == (Object)null)
			{
				PunkEmotesPlugin.Log.LogError((object)"Animator is null.");
				return;
			}
			_playableGraph = PlayableGraph.Create("AnimationGraph");
			_layerMixerPlayable = AnimationLayerMixerPlayable.Create(_playableGraph, 2);
			AnimationPlayableOutput val = AnimationPlayableOutput.Create(_playableGraph, "AnimationOutput", animator);
			PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationLayerMixerPlayable>(val, _layerMixerPlayable);
		}

		private void SendSyncRequest()
		{
			PunkAnimationPacket punkAnimationPacket = new PunkAnimationPacket(((NetworkBehaviour)_player).netId, "ALL", "SYNCREQUEST", string.Empty, string.Empty);
			CodeTalkerNetwork.SendNetworkPacket((PacketBase)(object)punkAnimationPacket);
		}

		private void SendSyncResponse(string target)
		{
			if (_isAnimationPlaying)
			{
				PunkEmotesPlugin.Log.LogDebug((object)("We're sending the animation to " + target));
				SendAnimationCommand(target, "START", _currentAnimation, this, _currentCategory);
			}
			else
			{
				PunkEmotesPlugin.Log.LogDebug((object)"No animation playing, is this correct?");
			}
			if (playerOverrides != null)
			{
				PunkEmotesPlugin.Log.LogDebug((object)("We're sending override info to " + target));
				{
					foreach (string playerOverride in playerOverrides)
					{
						if (playerOverride != null)
						{
							string text = playerOverride;
							PunkEmotesPlugin.Log.LogDebug((object)text);
							string[] array = text.Split('_');
							string animationName = array[0];
							string originOverride = array[1];
							ApplyPunkOverrides(target, this, animationName, originOverride);
						}
					}
					return;
				}
			}
			PunkEmotesPlugin.Log.LogDebug((object)"No override info to send, is this correct?");
		}

		public void ApplyPunkOverrides(string? target, PunkEmotesManager emotesManager, string animationName, string originOverride)
		{
			AnimationClip animation = AnimationConstructor.AnimationLibrary.Instance.GetAnimation(animationName, "override");
			if (animation == null)
			{
				return;
			}
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			RuntimeAnimatorController runtimeAnimatorController = _animator.runtimeAnimatorController;
			AnimatorOverrideController val = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
			if (val != null)
			{
				val.GetOverrides(list);
			}
			foreach (KeyValuePair<AnimationClip, AnimationClip> item2 in list)
			{
				newOverrideController[item2.Key] = item2.Value;
			}
			bool flag = false;
			foreach (KeyValuePair<AnimationClip, AnimationClip> item3 in list)
			{
				AnimationClip key = item3.Key;
				if ((((Object)(object)key != (Object)null) ? ((Object)key).name.ToLowerInvariant() : null) == originOverride)
				{
					newOverrideController[item3.Key] = animation;
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				PunkEmotesPlugin.Log.LogError((object)(originOverride + " not found in override mappings."));
				return;
			}
			_animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)newOverrideController;
			PunkEmotesPlugin.Log.LogDebug((object)("Applied override: '" + originOverride + "' -> '" + animationName + "'."));
			string item = animationName + "_" + originOverride;
			if (!playerOverrides.Contains(item))
			{
				playerOverrides.Add(item);
			}
			SendAnimationCommand("ALL", "Override", animationName, emotesManager, originOverride);
		}

		public void PlayAnimationClip(string? target, PunkEmotesManager emotesManager, string animationName, string? animationCategory = null)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			AnimationClip animation = AnimationConstructor.AnimationLibrary.Instance.GetAnimation(animationName, animationCategory);
			if (animation == null)
			{
				PunkEmotesPlugin.Log.LogError((object)"AnimationClip is null.");
				return;
			}
			if (!((PlayableGraph)(ref emotesManager._playableGraph)).IsValid())
			{
				emotesManager.InitializeGraph(emotesManager._animator);
			}
			emotesManager.CrossfadeToCustomAnimation(emotesManager, animation);
			AnimationClipPlayable val = AnimationClipPlayable.Create(emotesManager._playableGraph, animation);
			PlayableExtensions.ConnectInput<AnimationLayerMixerPlayable, AnimationClipPlayable>(_layerMixerPlayable, 1, val, 0);
			PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(_layerMixerPlayable, 1, 1f);
			PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(_layerMixerPlayable, 0, 0f);
			((PlayableGraph)(ref emotesManager._playableGraph)).Play();
			emotesManager._currentClipPlayable = val;
			emotesManager._isAnimationPlaying = true;
			emotesManager._currentAnimation = animationName;
			emotesManager._currentCategory = animationCategory;
			if (((NetworkBehaviour)Player._mainPlayer).netId == ((NetworkBehaviour)_player).netId)
			{
				SendAnimationCommand("ALL", "START", animationName, emotesManager, animationCategory);
			}
			PunkEmotesPlugin.Log.LogDebug((object)$"Playing animation clip: {animationName} for player with netId {((NetworkBehaviour)emotesManager._player).netId}");
		}

		public void StopAnimation(PunkEmotesManager emotesManager)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (emotesManager._isAnimationPlaying && ((PlayableGraph)(ref emotesManager._playableGraph)).IsValid())
			{
				string animationName = null;
				PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(_layerMixerPlayable, 1, 0f);
				PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(_layerMixerPlayable, 0, 1f);
				((PlayableGraph)(ref emotesManager._playableGraph)).Stop();
				PlayableExtensions.Destroy<AnimationClipPlayable>(_currentClipPlayable);
				emotesManager._currentAnimation = null;
				emotesManager._isAnimationPlaying = false;
				SendAnimationCommand("ALL", "STOP", animationName, emotesManager);
				PunkEmotesPlugin.Log.LogDebug((object)$"Stopped custom animation for player with netId {((NetworkBehaviour)emotesManager._player).netId}.");
			}
		}

		private void CrossfadeToCustomAnimation(PunkEmotesManager emotesManager, AnimationClip animationClip, float crossfadeDuration = 0.3f)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			RuntimeAnimatorController runtimeAnimatorController = emotesManager._animator.runtimeAnimatorController;
			AnimatorOverrideController val = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
			if (val != null)
			{
				int num = 0;
				if (emotesManager._animator.layerCount > num)
				{
					AnimatorStateInfo currentAnimatorStateInfo = emotesManager._animator.GetCurrentAnimatorStateInfo(num);
					string text = (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Idle") ? "Idle" : "Default");
					val[text] = animationClip;
					emotesManager._animator.CrossFade(text, crossfadeDuration, num);
				}
				else
				{
					PunkEmotesPlugin.Log.LogError((object)"Base layer not found in animator.");
				}
			}
			PunkEmotesPlugin.Log.LogDebug((object)$"Crossfaded to custom animation: {((Object)animationClip).name} with a {crossfadeDuration}s transition.");
		}

		public void CrossfadeToDefaultState()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
			if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Walk") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Run") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Jump") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Dash"))
			{
				_animator.CrossFade(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, 0.2f);
			}
			else
			{
				_animator.CrossFade("Idle", 0.2f);
			}
			PunkEmotesPlugin.Log.LogDebug((object)"Crossfaded back to default state (Idle/Walk/Run) after custom animation.");
		}

		public void Dispose(PunkEmotesManager emotesManager)
		{
			if (((PlayableGraph)(ref emotesManager._playableGraph)).IsValid())
			{
				((PlayableGraph)(ref emotesManager._playableGraph)).Destroy();
				PunkEmotesPlugin.Log.LogDebug((object)"PlayableGraph destroyed.");
			}
		}

		public void SendAnimationCommand(string target, string command, string? animationName, PunkEmotesManager emotesManager, string? categoryOrOrigin = null)
		{
			PunkAnimationPacket punkAnimationPacket = new PunkAnimationPacket(((NetworkBehaviour)emotesManager._player).netId, target, command, animationName ?? string.Empty, categoryOrOrigin ?? string.Empty);
			CodeTalkerNetwork.SendNetworkPacket((PacketBase)(object)punkAnimationPacket);
		}

		internal static void HandleChatAnimationMessage(PacketHeader header, PacketBase incPacket)
		{
			if (!(incPacket is PunkAnimationPacket punkAnimationPacket) || (Object)(object)Player._mainPlayer == (Object)null)
			{
				return;
			}
			Player playerByNetId = PlayerRegistry.GetPlayerByNetId(punkAnimationPacket.SenderNetworkID);
			if (playerByNetId == null)
			{
				PunkEmotesPlugin.Log.LogWarning((object)$"Unable to find player for NetID: {punkAnimationPacket.SenderNetworkID}");
				return;
			}
			if (((NetworkBehaviour)Player._mainPlayer).netId == ((NetworkBehaviour)playerByNetId).netId)
			{
				PunkEmotesPlugin.Log.LogDebug((object)"Skipping local player's message.");
				return;
			}
			PunkEmotesManager component = ((Component)playerByNetId).GetComponent<PunkEmotesManager>();
			if ((Object)(object)component == (Object)null || !component.Initialized)
			{
				return;
			}
			switch (punkAnimationPacket.RequestType.ToLower())
			{
			case "syncrequest":
				component.SendSyncResponse(punkAnimationPacket.SenderNetworkID.ToString());
				break;
			case "override":
				if (!string.IsNullOrEmpty(punkAnimationPacket.AnimationCategory))
				{
					if (component.overrideAliases.ContainsKey(punkAnimationPacket.AnimationCategory))
					{
						List<string> list = component.overrideAliases[punkAnimationPacket.AnimationCategory];
						string animationName = punkAnimationPacket.AnimationName + list[2];
						string animationName2 = punkAnimationPacket.AnimationName + list[3];
						component.ApplyPunkOverrides(null, component, animationName, list[0]);
						component.ApplyPunkOverrides(null, component, animationName2, list[1]);
					}
					else
					{
						component.ApplyPunkOverrides(null, component, punkAnimationPacket.AnimationName, punkAnimationPacket.AnimationCategory);
					}
				}
				else
				{
					PunkEmotesPlugin.Log.LogWarning((object)("Override command missing originOverride for animation '" + punkAnimationPacket.AnimationName + "'."));
				}
				break;
			case "start":
				if (!string.IsNullOrEmpty(punkAnimationPacket.AnimationCategory))
				{
					component.PlayAnimationClip(null, component, punkAnimationPacket.AnimationName, punkAnimationPacket.AnimationCategory);
				}
				else
				{
					component.PlayAnimationClip(null, component, punkAnimationPacket.AnimationName);
				}
				break;
			case "stop":
				component.StopAnimation(component);
				break;
			default:
				PunkEmotesPlugin.Log.LogWarning((object)("Unknown request '" + punkAnimationPacket.RequestType + "' received in PUNKEMOTES message."));
				break;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}