using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PunkEmotes")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1")]
[assembly: AssemblyProduct("PunkEmotes")]
[assembly: AssemblyTitle("PunkEmotes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.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 PunkEmotes
{
[BepInPlugin("punkalyn.punkemotes", "PunkEmotes", "0.1.0")]
[BepInProcess("ATLYSS.exe")]
public class Plugin : BaseUnityPlugin
{
public class AnimationConstructor
{
[HarmonyPatch(typeof(CharacterSelectManager), "Select_CharacterFile")]
private class ResetCache
{
private static void Postfix()
{
raceAnimatorReset = true;
PlayerRegistry.ClearRegistry();
}
}
[HarmonyPatch(typeof(PlayerVisual), "Iterate_AnimationCallback")]
public class LoadFBX
{
private static void Postfix(PlayerVisual __instance, ref string _animName, ref float _animLayer)
{
if (raceAnimatorReset)
{
LoadRaceFBXs();
}
}
}
public class AnimationLibrary
{
private static AnimationLibrary _instance;
private Dictionary<string, Dictionary<string, AnimationClip>> animationClips = new Dictionary<string, Dictionary<string, AnimationClip>>
{
{
"dance",
new Dictionary<string, AnimationClip>()
},
{
"general",
new Dictionary<string, AnimationClip>()
},
{
"override",
new Dictionary<string, AnimationClip>()
},
{
"sit",
new Dictionary<string, AnimationClip>()
}
};
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;
foreach (AnimationClip val in array2)
{
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;
LogInfo("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;
LogInfo("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;
LogInfo("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;
LogInfo("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;
LogInfo("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;
foreach (AnimationClip item in array)
{
list.Add(item);
}
return list.ToArray();
}
public void LoadAnimations()
{
AnimationClip[] array = Resources.LoadAll<AnimationClip>("Animations/");
AnimationClip[] array2 = array;
foreach (AnimationClip val in array2)
{
}
}
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;
}
}
LogInfo("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;
}
}
}
}
LogWarning("No animation found with the name: " + name);
return null;
}
}
private static Dictionary<string, Animator> raceAnimators = new Dictionary<string, Animator>();
private static bool raceAnimatorReset = true;
private static void LoadRaceFBXs()
{
string[] array = new string[5] { "byrdle", "chang", "imp", "Kobold", "poon" };
string[] array2 = array;
foreach (string text in array2)
{
GameObject val = GameObject.Find(text + "FBX");
if ((Object)(object)val != (Object)null)
{
Animator component = val.GetComponent<Animator>();
raceAnimators[text] = component;
LogInfo(text + " loaded into animation memory");
}
}
AnimationLibrary.Instance.PopulateDefaultAnimations();
raceAnimatorReset = false;
}
}
public class PunkEmotesManager : MonoBehaviour
{
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>>();
private string _currentAnimation;
private string _currentCategory;
private List<string> playerOverrides = new List<string>();
private Player _player;
public bool _isAnimationPlaying;
private void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: 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> { "_playeremote_sitinit", "_playeremote_sitloop", "_sitInit", "_sitLoop" };
overrideAliases["sit2"] = new List<string> { "_playeremote_sitinit02", "_playeremote_sitloop02", "_sitInit02", "_sitLoop02" };
}
private IEnumerator WaitForAnimator()
{
_player = ((Component)this).GetComponent<Player>();
if ((Object)(object)_player == (Object)null)
{
LogError("PunkEmotesManager must be attached to a Player object.");
yield break;
}
while ((Object)(object)_player._pVisual == (Object)null || (Object)(object)_player._pVisual._visualAnimator == (Object)null)
{
yield return null;
}
_animator = ((Component)_player._pVisual._visualAnimator).GetComponent<Animator>();
if ((Object)(object)_animator != (Object)null)
{
newOverrideController = new AnimatorOverrideController(_animator.runtimeAnimatorController);
InitializeGraph(_animator);
LogInfo("Attached PunkEmotesManager to player: " + _player._nickname);
SendSyncRequest();
}
else
{
LogError("Animator component not found on PlayerVisual.");
}
}
public void InitializeGraph(Animator animator)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)animator == (Object)null)
{
LogError("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()
{
string text = $"<>#PUNKEMOTES#{((NetworkBehaviour)_player).netId}#ALL#SYNCREQUEST#";
((Component)_player).GetComponent<ChatBehaviour>().Cmd_SendChatMessage(text, (ChatChannel)3);
}
private void SendSyncResponse(string target)
{
if (_isAnimationPlaying)
{
LogInfo("We're sending the animation to " + target);
SendAnimationCommand(target, "START", _currentAnimation, this, _currentCategory);
}
else
{
LogInfo("No animation playing, is this correct?");
}
if (playerOverrides != null)
{
LogInfo("We're sending override info to " + target);
{
foreach (string playerOverride in playerOverrides)
{
LogInfo(playerOverride ?? "");
string[] array = playerOverride.Split('_');
string animationName = array[0];
string originOverride = array[1];
ApplyPunkOverrides(target, this, animationName, originOverride);
}
return;
}
}
LogInfo("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 ((Object)(object)animation == (Object)null)
{
return;
}
RuntimeAnimatorController runtimeAnimatorController = _animator.runtimeAnimatorController;
AnimatorOverrideController val = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
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 (((key != null) ? ((Object)key).name.ToLowerInvariant() : null) == originOverride)
{
newOverrideController[item3.Key] = animation;
flag = true;
break;
}
}
if (!flag)
{
LogError(originOverride + " not found in override mappings.");
return;
}
_animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)newOverrideController;
LogInfo("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_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
AnimationClip animation = AnimationConstructor.AnimationLibrary.Instance.GetAnimation(animationName, animationCategory);
if (!((PlayableGraph)(ref emotesManager._playableGraph)).IsValid())
{
emotesManager.InitializeGraph(emotesManager._animator);
}
if ((Object)(object)animation == (Object)null)
{
LogError("AnimationClip is null.");
return;
}
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);
}
LogInfo($"Playing animation clip: {animationName} for player with netId {((NetworkBehaviour)emotesManager._player).netId}");
}
public void StopAnimation(PunkEmotesManager emotesManager)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: 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);
LogInfo($"Stopped custom animation for player with netId {((NetworkBehaviour)emotesManager._player).netId}.");
}
}
private void CrossfadeToCustomAnimation(PunkEmotesManager emotesManager, AnimationClip animationClip, float crossfadeDuration = 0.3f)
{
//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)
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
{
LogError("Base layer not found in animator.");
}
}
LogInfo($"Crossfaded to custom animation: {((Object)animationClip).name} with a {crossfadeDuration}s transition.");
}
public void CrossfadeToDefaultState()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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);
}
LogInfo("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();
LogInfo("PlayableGraph destroyed.");
}
}
public void SendAnimationCommand(string target, string command, string animationName, PunkEmotesManager emotesManager, string categoryOrOrigin = null)
{
string text = $"<>#PUNKEMOTES#{((NetworkBehaviour)emotesManager._player).netId}#{target}#{command}#{animationName}#{categoryOrOrigin}";
((Component)_player).GetComponent<ChatBehaviour>().Cmd_SendChatMessage(text, (ChatChannel)3);
}
public void HandleChatAnimationMessage(string message)
{
if (string.IsNullOrEmpty(message))
{
return;
}
string[] array = message.ToLower().Split(new string[1] { "#" }, StringSplitOptions.None);
if (array.Length >= 5)
{
if (uint.TryParse(array[2], out var result))
{
string text = array[3];
string text2 = array[4];
string text3 = array[5];
string text4 = ((array.Length > 6) ? array[6] : null);
if (result == ((NetworkBehaviour)Player._mainPlayer).netId)
{
LogInfo("Skipping local player animation reprocessing to prevent infinite loop.");
}
else
{
if (!(text == "all") && (!uint.TryParse(text, out var result2) || result2 != ((NetworkBehaviour)Player._mainPlayer).netId))
{
return;
}
Player playerByNetId = PlayerRegistry.GetPlayerByNetId(result);
if ((Object)(object)playerByNetId != (Object)null)
{
PunkEmotesManager component = ((Component)playerByNetId).GetComponent<PunkEmotesManager>();
if ((Object)(object)component != (Object)null)
{
switch (text2)
{
case "syncrequest":
LogInfo("Sync requested, sending response:");
SendSyncResponse(result.ToString());
break;
case "start":
if (!string.IsNullOrEmpty(text4))
{
component.PlayAnimationClip(null, component, text3, text4);
}
else
{
component.PlayAnimationClip(null, component, text3);
}
break;
case "override":
if (!string.IsNullOrEmpty(text4))
{
if (overrideAliases.ContainsKey(text4))
{
List<string> list = overrideAliases[text4];
string animationName = text3 + list[2];
string animationName2 = text3 + list[3];
component.ApplyPunkOverrides(null, component, animationName, list[0]);
component.ApplyPunkOverrides(null, component, animationName2, list[1]);
}
else
{
component.ApplyPunkOverrides(null, component, text3, text4);
}
}
else
{
LogWarning("Override command missing originOverride for animation '" + text3 + "'.");
}
break;
case "stop":
component.StopAnimation(component);
break;
default:
LogWarning("Unknown command '" + text2 + "' received in PUNKEMOTES message.");
break;
}
}
else
{
LogWarning($"PunkEmotesManager not found for sender player with netId '{result}'.");
}
}
else
{
LogWarning($"Sender player with netId '{result}' not found.");
}
}
}
else
{
LogWarning("Failed to parse sender's netId from message: " + array[2]);
}
}
else
{
LogWarning("Invalid PUNKEMOTES message format. Insufficient parts.");
}
}
}
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)
{
PlayerEntry value;
return _playersByNetId.TryGetValue(netId, out value) ? value.EmotesManager : null;
}
public static Player GetPlayerByNetId(uint netId)
{
PlayerEntry value;
return _playersByNetId.TryGetValue(netId, out value) ? value.PlayerInstance : null;
}
public static Player GetPlayerByNickname(string nickname)
{
foreach (PlayerEntry value in _playersByNetId.Values)
{
if (value.Nickname == nickname)
{
return value.PlayerInstance;
}
}
return null;
}
}
[HarmonyPatch]
public static class PatchWrapper
{
[HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")]
public class PlayPunkEmote
{
private static bool Prefix(ref string _message, ChatBehaviour __instance)
{
if (string.IsNullOrEmpty(_message))
{
return true;
}
if (!_message.StartsWith("/em ", StringComparison.OrdinalIgnoreCase))
{
return true;
}
PunkEmotesManager emotesManagerByNetId = PlayerRegistry.GetEmotesManagerByNetId(((NetworkBehaviour)Player._mainPlayer).netId);
string text = _message.Substring(4).Trim();
string[] array = text.Split(' ');
string text2 = array[0].ToLower();
string text3 = text2;
if (!(text3 == "overrides"))
{
if (text3 == "help")
{
SendChatMessage("Commands: '/em animation_name (or race)'");
SendChatMessage("Commands: '/em category animation_name (or race)'");
SendChatMessage("Categories: 'sit', 'dance'");
SendChatMessage("Test animation: '/em 02'");
LogInfo("Available commands: overrides, help");
return false;
}
if (array.Length == 3 && array[0].ToLower() == "override")
{
string text4 = array[1].ToLower();
string text5 = array[2].ToLower();
if ((Object)(object)AnimationConstructor.AnimationLibrary.Instance.GetAnimation(text5, "override") == (Object)null)
{
LogError("Override animation '" + text5 + "' not found.");
return false;
}
if (emotesManagerByNetId.overrideAliases.ContainsKey(text4))
{
List<string> list = emotesManagerByNetId.overrideAliases[text4];
string animationName = text5 + list[2];
string animationName2 = text5 + list[3];
emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, animationName, list[0]);
emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, animationName2, list[1]);
}
else
{
emotesManagerByNetId.ApplyPunkOverrides("ALL", emotesManagerByNetId, text5, text4);
}
return false;
}
if (array.Length == 2)
{
string animationCategory = array[0].ToLower();
string animationName3 = array[1].ToLower();
emotesManagerByNetId.PlayAnimationClip("ALL", emotesManagerByNetId, animationName3, animationCategory);
return false;
}
if (array.Length == 1)
{
string animationName4 = array[0].ToLower();
emotesManagerByNetId.PlayAnimationClip("ALL", emotesManagerByNetId, animationName4);
return false;
}
LogWarning("Invalid emotes format. Expected '/em [category] [name]', '/em [name]', or '/em override [originOverride] [newOverride]'.");
return false;
}
AnimationClip[] animationClips = emotesManagerByNetId._animator.runtimeAnimatorController.animationClips;
if (animationClips != null && animationClips.Length != 0)
{
AnimationClip[] array2 = animationClips;
foreach (AnimationClip val in array2)
{
LogInfo("Overridable animation: " + ((Object)val).name);
}
}
else
{
LogWarning("No animation clips found in the Animator.");
}
return false;
}
}
[HarmonyPatch(typeof(PlayerMove), "Set_MovementAction")]
public class SetMovementActionPatch
{
private static void Postfix(PlayerMove __instance, MovementAction _mA)
{
//IL_0030: 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);
}
}
}
}
private static MethodInfo rpcMethod = typeof(ChatBehaviour).GetMethod("Rpc_RecieveChatMessage", BindingFlags.Instance | BindingFlags.NonPublic);
[HarmonyPatch(typeof(ChatBehaviour), "UserCode_Rpc_RecieveChatMessage__String__Boolean__ChatChannel")]
[HarmonyPrefix]
public static bool UserCode_Rpc_RecieveChatMessage__String__Boolean__ChatChannel_Prefix(string message, bool _isEmoteMessage, ChatChannel _chatChannel)
{
LogInfo(message);
if (message.Contains("<>#PUNKEMOTES#"))
{
LogInfo("PUNKEMOTES detected in RPC!");
string[] array = message.Split(new string[1] { "#" }, StringSplitOptions.None);
if (array.Length >= 4)
{
if (!uint.TryParse(array[2], out var result))
{
LogWarning("Failed to parse netId from message: " + array[2]);
return false;
}
Player playerByNetId = PlayerRegistry.GetPlayerByNetId(result);
if (!((Object)(object)playerByNetId != (Object)null))
{
LogWarning($"Player with netId '{result}' not found.");
return false;
}
PunkEmotesManager component = ((Component)playerByNetId).GetComponent<PunkEmotesManager>();
if ((Object)(object)component != (Object)null)
{
component.HandleChatAnimationMessage(message);
return false;
}
}
return false;
}
return true;
}
[HarmonyPatch(typeof(ChatBehaviour), "UserCode_Cmd_SendChatMessage__String__ChatChannel")]
[HarmonyPrefix]
public static bool UserCode_Cmd_SendChatMessage__String__ChatChannel_Prefix(ChatBehaviour __instance, string _message, ChatChannel _chatChannel)
{
if (_message.Contains("<>#PUNKEMOTES#"))
{
if (rpcMethod != null)
{
rpcMethod.Invoke(__instance, new object[3]
{
_message,
true,
(object)(ChatChannel)3
});
LogInfo("Caught <>#PUNKEMOTES#, sent to RPC");
return false;
}
return false;
}
return true;
}
[HarmonyPatch(typeof(Player), "Start")]
private static void 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 ManualLogSource Logger;
public static bool logInfoEnabled = false;
public static bool logWarningEnabled = true;
public static bool logErrorEnabled = true;
private static bool logMethod = true;
private void Awake()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
LogInfo("Punk Emotes is rockin'!");
Harmony val = new Harmony("punkalyn.punkemotes");
int num = 7;
try
{
val.PatchAll();
if (num != val.GetPatchedMethods().Count())
{
LogError($"Punk Emotes patched {val.GetPatchedMethods().Count()} methods out of {num} intended patches!");
}
}
catch (Exception ex)
{
LogError("Exception caught while patching: " + ex.Message);
}
}
public static void LogMethod(bool enable)
{
logMethod = enable;
}
public static void LogInfo(string message, bool? shouldLog = null)
{
if ((shouldLog ?? logInfoEnabled) && logMethod)
{
Logger.LogInfo((object)message);
}
}
public static void LogWarning(string message, bool? shouldLog = null)
{
if ((shouldLog ?? logWarningEnabled) && logMethod)
{
Logger.LogWarning((object)message);
}
}
public static void LogError(string message, bool? shouldLog = null)
{
if ((shouldLog ?? logErrorEnabled) && logMethod)
{
Logger.LogError((object)message);
}
}
private static void SendChatMessage(string message)
{
if (Object.op_Implicit((Object)(object)Player._mainPlayer))
{
Player._mainPlayer._cB.New_ChatMessage(message);
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "PunkEmotes";
public const string PLUGIN_NAME = "PunkEmotes";
public const string PLUGIN_VERSION = "0.0.1";
}
}