Decompiled source of StanceSelector v1.2.0

StanceSelector.dll

Decompiled a week ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Rombusz")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adds a stance selection page to PEAK's emote wheel.")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("StanceSelector")]
[assembly: AssemblyTitle("StanceSelector")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
namespace StanceSelector
{
	[BepInPlugin("Rombusz.StanceSelector", "StanceSelector", "1.2.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GUIManager), "UpdateEmoteWheel")]
		private static class ShortcutPatch
		{
			private static void Prefix(GameObject ___emoteWheel)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null || (Object)(object)___emoteWheel == (Object)null)
				{
					return;
				}
				if (Input.GetKey(stanceSelectorShortcutHotkey.Value))
				{
					if ((Object)(object)shortcutWheel == (Object)null)
					{
						OpenShortcutPage(___emoteWheel.GetComponent<EmoteWheel>());
					}
					localCharacter.input.emoteIsPressed = true;
				}
				else if ((Object)(object)shortcutWheel != (Object)null)
				{
					RestorePreviousPage(localCharacter.input.emoteIsPressed);
				}
				else if (localCharacter.data.usingEmoteWheel && ___emoteWheel.activeInHierarchy && Input.GetKeyDown(emoteWheelPageSwitcherHotkey.Value))
				{
					EmoteWheel component = ___emoteWheel.GetComponent<EmoteWheel>();
					WheelPage.Invoke(component) = ((WheelPage.Invoke(component) == 0) ? 1 : 0);
					component.InitWheel();
				}
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "Tab")]
		private static class ShortcutTabPatch
		{
			private static bool Prefix(EmoteWheel __instance)
			{
				return (Object)(object)__instance != (Object)(object)shortcutWheel;
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "InitWheel")]
		private static class WheelInitPatch
		{
			[HarmonyPrefix]
			[HarmonyPriority(0)]
			private static void Prefix(EmoteWheel __instance)
			{
				PrepareStancePage(__instance);
			}

			[HarmonyPostfix]
			[HarmonyPriority(800)]
			private static void Postfix(EmoteWheel __instance, int ___page)
			{
				DrawLabels(__instance, ___page);
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "Hover")]
		private static class WheelHoverPatch
		{
			private static bool Prefix(EmoteWheel __instance, EmoteWheelData emoteWheelData, ref EmoteWheelData ___chosenEmoteData)
			{
				int stance = GetStance(emoteWheelData);
				if (stance < 0)
				{
					return true;
				}
				((TMP_Text)__instance.selectedEmoteName).text = StanceNames[stance];
				___chosenEmoteData = emoteWheelData;
				return false;
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "Choose")]
		private static class WheelChoosePatch
		{
			private static bool Prefix(EmoteWheelData ___chosenEmoteData)
			{
				int stance = GetStance(___chosenEmoteData);
				if (stance < 0)
				{
					return true;
				}
				ApplyStance(stance);
				return false;
			}
		}

		[HarmonyPatch(typeof(CharacterCustomization), "Start")]
		private static class CharacterStartPatch
		{
			private static void Postfix(CharacterCustomization __instance)
			{
				//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)
				if (selectedStance < 0)
				{
					return;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				if (!IsMenuScene(((Scene)(ref activeScene)).name))
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)gameObject == (Object)(object)((localCharacter != null) ? ((Component)localCharacter).gameObject : null))
					{
						ApplyStance(selectedStance);
					}
				}
			}
		}

		public const string Guid = "Rombusz.StanceSelector";

		public const string Name = "StanceSelector";

		public const string Version = "1.2.0";

		private const int StancePage = 2;

		private const int PageSize = 8;

		private const int DataOffset = 16;

		private const string LabelName = "StanceSelector Label";

		private static readonly string[] StanceNames = new string[8] { "PRIDEFUL", "READY TO GO", "OPEN HANDS", "CLOSED HANDS", "HANDS ON HIPS", "NORMAL", "SHY", "SNATCH 'EM" };

		private static readonly EmoteWheelData[] StanceEntries = (EmoteWheelData[])(object)new EmoteWheelData[8];

		private static readonly FieldRef<EmoteWheel, int> WheelPage = AccessTools.FieldRefAccess<EmoteWheel, int>("page");

		private static ConfigEntry<KeyCode> stanceSelectorShortcutHotkey;

		private static ConfigEntry<KeyCode> emoteWheelPageSwitcherHotkey;

		private static int selectedStance = -1;

		private static int previousPage;

		private static EmoteWheel shortcutWheel;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			stanceSelectorShortcutHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Stance Selector Shortcut Hotkey", (KeyCode)116, "Hold to open the stance wheel directly.");
			emoteWheelPageSwitcherHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Emote Wheel Page Switcher Hotkey", (KeyCode)115, "Press while the vanilla emote wheel is open to switch between its two pages.");
			harmony = new Harmony("Rombusz.StanceSelector");
			harmony.PatchAll(typeof(Plugin).Assembly);
			SceneManager.sceneLoaded += SceneLoaded;
			((BaseUnityPlugin)this).Logger.LogMessage((object)"Plugin StanceSelector 1.2.0 is loaded!");
		}

		private void OnDestroy()
		{
			RestorePreviousPage(refresh: false);
			SceneManager.sceneLoaded -= SceneLoaded;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			EmoteWheelData[] stanceEntries = StanceEntries;
			foreach (EmoteWheelData val in stanceEntries)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static void PrepareStancePage(EmoteWheel wheel)
		{
			wheel.pages = Math.Max(3, wheel.pages);
			if (wheel.data.Length < 24)
			{
				Array.Resize(ref wheel.data, 24);
			}
			for (int i = 0; i < 8; i++)
			{
				EmoteWheelData[] data = wheel.data;
				int num = 16 + i;
				EmoteWheelData[] stanceEntries = StanceEntries;
				int num2 = i;
				data[num] = stanceEntries[num2] ?? (stanceEntries[num2] = CreateStance(i));
			}
		}

		private static EmoteWheelData CreateStance(int index)
		{
			EmoteWheelData val = ScriptableObject.CreateInstance<EmoteWheelData>();
			val.emoteName = StanceNames[index];
			val.anim = string.Empty;
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static void DrawLabels(EmoteWheel wheel, int page)
		{
			for (int i = 0; i < wheel.slices.Length; i++)
			{
				EmoteWheelSlice val = wheel.slices[i];
				Transform transform = ((Component)val.image).transform;
				Transform val2 = transform.Find("StanceSelector Label");
				TextMeshProUGUI val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<TextMeshProUGUI>() : CreateLabel(wheel, transform));
				bool flag = page == 2 && i < 8;
				((Component)val3).gameObject.SetActive(flag);
				((Behaviour)val.image).enabled = !flag && ((Selectable)((UIWheelSlice)val).button).interactable;
				if (flag)
				{
					((TMP_Text)val3).text = StanceNames[i];
				}
			}
			if ((Object)(object)wheel == (Object)(object)shortcutWheel)
			{
				((Component)wheel.prevButton).gameObject.SetActive(false);
			}
		}

		private static TextMeshProUGUI CreateLabel(EmoteWheel wheel, Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("StanceSelector Label", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI)
			});
			((Object)val).hideFlags = (HideFlags)52;
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			component.anchorMin = new Vector2(0.06f, 0.06f);
			component.anchorMax = new Vector2(0.94f, 0.94f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)component2).enableAutoSizing = true;
			((TMP_Text)component2).fontSizeMin = 14f;
			((TMP_Text)component2).fontSizeMax = 30f;
			((TMP_Text)component2).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)component2).overflowMode = (TextOverflowModes)1;
			((Graphic)component2).raycastTarget = false;
			((Graphic)component2).color = Color.black;
			((TMP_Text)component2).font = ((TMP_Text)wheel.selectedEmoteName).font;
			((TMP_Text)component2).fontSharedMaterial = ((TMP_Text)wheel.selectedEmoteName).fontSharedMaterial;
			return component2;
		}

		private static int GetStance(EmoteWheelData data)
		{
			return Array.IndexOf(StanceEntries, data);
		}

		private static void OpenShortcutPage(EmoteWheel wheel)
		{
			if (!((Object)(object)shortcutWheel != (Object)null) && !((Object)(object)wheel == (Object)null))
			{
				shortcutWheel = wheel;
				previousPage = WheelPage.Invoke(wheel);
				WheelPage.Invoke(wheel) = 2;
				if (((Component)wheel).gameObject.activeInHierarchy)
				{
					wheel.InitWheel();
				}
			}
		}

		private static void RestorePreviousPage(bool refresh)
		{
			EmoteWheel val = shortcutWheel;
			shortcutWheel = null;
			if (!((Object)(object)val == (Object)null))
			{
				WheelPage.Invoke(val) = previousPage;
				if (refresh && ((Component)val).gameObject.activeInHierarchy)
				{
					val.InitWheel();
				}
			}
		}

		private static void ApplyStance(int index)
		{
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null))
			{
				int num = Mathf.Clamp(localCharacter.refs.customization.maxIdles, 1, 8);
				index = Mathf.Clamp(index, 0, num - 1);
				selectedStance = index;
				PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
				if (photonView.IsMine && PhotonNetwork.InRoom)
				{
					PhotonNetwork.RemoveBufferedRPCs(photonView.ViewID, "SetCharacterIdle_RPC", (int[])null);
					photonView.RPC("SetCharacterIdle_RPC", (RpcTarget)3, new object[1] { index });
				}
				else
				{
					localCharacter.refs.animations.SetIdle(index);
				}
			}
		}

		private static bool IsMenuScene(string scene)
		{
			if (!scene.Equals("Airport", StringComparison.OrdinalIgnoreCase) && !scene.Equals("Title", StringComparison.OrdinalIgnoreCase))
			{
				return scene.Equals("MainMenu", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static void SceneLoaded(Scene scene, LoadSceneMode _)
		{
			if (IsMenuScene(((Scene)(ref scene)).name))
			{
				selectedStance = -1;
			}
			shortcutWheel = null;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}