Decompiled source of Ghost4Lins v1.0.2

plugins/YonDev.GhostMod4Lins.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.UI;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[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("YonDev.GhostMod4Lins")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+4a04c2a25b94ce1b89426d605d26b0e58893202f")]
[assembly: AssemblyProduct("Ghost4Lins")]
[assembly: AssemblyTitle("YonDev.GhostMod4Lins")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GhostMod4Lins
{
	[BepInPlugin("YonDev.GhostMod4Lins", "Ghost4Lins", "1.0.2")]
	public class GhostMod : BaseUnityPlugin
	{
		private class PlayerGhostPatch
		{
			[HarmonyPatch(typeof(PlayerGhost), "RPCA_InitGhost")]
			[HarmonyPostfix]
			private static void RPCA_InitGhostPostfix(PlayerGhost __instance)
			{
				ApplyVisibilitySettings(__instance);
				ApplySoundSettings(__instance);
			}
		}

		private class AnimatedMouthPatch
		{
			[HarmonyPatch(typeof(AnimatedMouth), "ProcessMicData")]
			[HarmonyPrefix]
			private static bool ProcessMicDataPrefix(AnimatedMouth __instance)
			{
				if ((Object)(object)__instance.character == (Object)null || (Object)(object)__instance.character.Ghost == (Object)null)
				{
					return true;
				}
				if (__instance.character.IsLocal)
				{
					AudioSource audioSource = __instance.audioSource;
					if (audioSource != null)
					{
						audioSource.mute = false;
					}
					return true;
				}
				if (GhostMute.Value)
				{
					AudioSource audioSource2 = __instance.audioSource;
					if (audioSource2 != null)
					{
						audioSource2.mute = true;
					}
					return false;
				}
				AudioSource audioSource3 = __instance.audioSource;
				if (audioSource3 != null)
				{
					audioSource3.mute = false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(KickButton), "Init")]
		public static class KickButton_Init_Patch
		{
			[HarmonyPostfix]
			private static void Postfix(KickButton __instance)
			{
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Expected O, but got Unknown
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Expected O, but got Unknown
				Transform parent = ((Component)__instance).transform.parent;
				if ((Object)(object)parent.Find("CustomButton") != (Object)null)
				{
					return;
				}
				AudioLevelSlider value = Traverse.Create((object)__instance).Field("_slider").GetValue<AudioLevelSlider>();
				Player player = value.player;
				if (!ghostVisibility.ContainsKey(player.ActorNumber))
				{
					ghostVisibility[player.ActorNumber] = GhostVisiblity.Value;
				}
				GameObject val = new GameObject("CustomButton");
				val.transform.SetParent(parent, false);
				val.transform.localScale = new Vector3(0.75f, 0.75f, 1f);
				RectTransform component = ((Component)__instance).GetComponent<RectTransform>();
				RectTransform val2 = val.AddComponent<RectTransform>();
				val2.anchoredPosition = new Vector2(-280f, component.anchoredPosition.y);
				Image val3 = val.AddComponent<Image>();
				val3.sprite = LoadSprite();
				Button val4 = val.AddComponent<Button>();
				((Selectable)val4).targetGraphic = (Graphic)(object)val3;
				val.transform.SetSiblingIndex(((Component)__instance).transform.GetSiblingIndex() + 1);
				((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
				{
					ghostVisibility[player.ActorNumber] = !ghostVisibility[player.ActorNumber];
					bool flag = ghostVisibility[player.ActorNumber];
					Character val5 = null;
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (((MonoBehaviourPun)allCharacter).photonView.Owner.ActorNumber == player.ActorNumber)
						{
							val5 = allCharacter;
							break;
						}
					}
					if (!((Object)(object)val5 == (Object)null) && !((Object)(object)val5.Ghost == (Object)null))
					{
						PlayerGhost ghost = val5.Ghost;
						Renderer[] playerRenderers = ghost.PlayerRenderers;
						foreach (Renderer val6 in playerRenderers)
						{
							if ((Object)(object)val6 != (Object)null)
							{
								val6.enabled = flag;
							}
						}
						Renderer[] eyeRenderers = ghost.EyeRenderers;
						foreach (Renderer val7 in eyeRenderers)
						{
							if ((Object)(object)val7 != (Object)null)
							{
								val7.enabled = flag;
							}
						}
						if ((Object)(object)ghost.mouthRenderer != (Object)null)
						{
							ghost.mouthRenderer.enabled = flag;
						}
						if ((Object)(object)ghost.accessoryRenderer != (Object)null)
						{
							ghost.accessoryRenderer.enabled = flag;
						}
						Notification(player.NickName + "'s ghost is now " + (flag ? "visible" : "hidden"), "00FFFF", sound: true);
					}
				});
			}
		}

		public static readonly Dictionary<int, bool> ghostVisibility = new Dictionary<int, bool>();

		public static ConfigEntry<KeyCode> GhostVisibilityToggle;

		public static ConfigEntry<bool> GhostVisiblity;

		public static ConfigEntry<KeyCode> GhostMuteToggle;

		public static ConfigEntry<bool> GhostMute;

		internal static ManualLogSource Logger;

		private readonly Harmony harmony = new Harmony("YonDev.GhostMod4Lins");

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"GhostMod4Lins v1.0.2 is loaded!");
			GhostVisibilityToggle = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Ghosts", "GhostVisibilityToggleKey", (KeyCode)44, "Key to toggle the ghosts' visibility on/off.");
			GhostMuteToggle = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Ghosts", "GhostMuteToggleKey", (KeyCode)109, "Key to toggle the ghosts' mute on/off.");
			GhostVisiblity = ((BaseUnityPlugin)this).Config.Bind<bool>("Ghosts", "GhostVisibility", true, "Toggle the ghosts' visibility on/off.");
			GhostMute = ((BaseUnityPlugin)this).Config.Bind<bool>("Ghosts", "GhostMute", true, "Toggle the ghosts' mute on/off.");
			GhostMute.Value = false;
			GhostVisiblity.Value = true;
			GhostVisiblity.SettingChanged += delegate
			{
				Notification("Ghost Visibility is " + (GhostVisiblity.Value ? "ON" : "OFF"));
				ApplyGhostSettingsToAllCharacters();
			};
			GhostMute.SettingChanged += delegate
			{
				Notification("Ghost Mute is " + (GhostMute.Value ? "ON" : "OFF"));
				ApplyGhostSettingsToAllCharacters();
			};
			harmony.PatchAll();
		}

		private void Update()
		{
			//IL_0026: 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)
			if (!((Object)(object)GUIManager.instance != (Object)null) || !GUIManager.instance.windowBlockingInput)
			{
				if (Input.GetKeyDown(GhostVisibilityToggle.Value))
				{
					GhostVisiblity.Value = !GhostVisiblity.Value;
				}
				if (Input.GetKeyDown(GhostMuteToggle.Value))
				{
					GhostMute.Value = !GhostMute.Value;
				}
			}
		}

		private static void ApplyGhostSettingsToAllCharacters()
		{
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if ((Object)(object)allCharacter.Ghost != (Object)null)
				{
					ApplyVisibilitySettings(allCharacter.Ghost);
					ApplySoundSettings(allCharacter.Ghost);
				}
			}
		}

		internal static void ApplyVisibilitySettings(PlayerGhost ghost)
		{
			if ((Object)(object)ghost.m_owner != (Object)null && ghost.m_owner.IsLocal)
			{
				return;
			}
			bool value = GhostVisiblity.Value;
			if (ghost.PlayerRenderers != null)
			{
				Renderer[] playerRenderers = ghost.PlayerRenderers;
				foreach (Renderer val in playerRenderers)
				{
					if (val != null)
					{
						val.enabled = value;
					}
				}
			}
			if (ghost.EyeRenderers != null)
			{
				Renderer[] eyeRenderers = ghost.EyeRenderers;
				foreach (Renderer val2 in eyeRenderers)
				{
					if (val2 != null)
					{
						val2.enabled = value;
					}
				}
			}
			Renderer mouthRenderer = ghost.mouthRenderer;
			if (mouthRenderer != null)
			{
				mouthRenderer.enabled = value;
			}
			Renderer accessoryRenderer = ghost.accessoryRenderer;
			if (accessoryRenderer != null)
			{
				accessoryRenderer.enabled = value;
			}
			Player owner = ghost.m_view.Owner;
			if (ghostVisibility.ContainsKey(owner.ActorNumber))
			{
				ghostVisibility[owner.ActorNumber] = GhostVisiblity.Value;
			}
			ManualLogSource logger = Logger;
			Character owner2 = ghost.m_owner;
			logger.LogDebug((object)$"Ghost '{((owner2 != null) ? owner2.characterName : null)}' visibility set to {value}.");
		}

		internal static void ApplySoundSettings(PlayerGhost ghost)
		{
			if ((Object)(object)ghost.m_owner == (Object)null || ghost.m_owner.IsLocal)
			{
				if ((Object)(object)ghost.animatedMouth?.audioSource != (Object)null)
				{
					ghost.animatedMouth.audioSource.mute = false;
				}
			}
			else if ((Object)(object)ghost.animatedMouth?.audioSource != (Object)null)
			{
				ghost.animatedMouth.audioSource.mute = GhostMute.Value;
				Logger.LogDebug((object)$"Ghost '{ghost.m_owner.characterName}' audio muted: {GhostMute.Value}.");
			}
			else
			{
				ManualLogSource logger = Logger;
				Character owner = ghost.m_owner;
				logger.LogWarning((object)("Could not find AnimatedMouth or AudioSource for ghost of " + ((owner != null) ? owner.characterName : null) + "."));
			}
		}

		public static void Notification(string message, string color = "FFFFFF", bool sound = false)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			PlayerConnectionLog val = Object.FindAnyObjectByType<PlayerConnectionLog>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string text = "<color=#" + color + ">" + message + "</color>";
			MethodInfo method = typeof(PlayerConnectionLog).GetMethod("AddMessage", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(val, new object[1] { text });
				if ((Object)(object)val.sfxJoin != (Object)null && sound)
				{
					val.sfxJoin.Play(default(Vector3));
				}
			}
			else
			{
				Logger.LogMessage((object)"AddMessage method not found.");
			}
		}

		private static Sprite LoadSprite()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("GhostMod4Lins.ghost.png");
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "YonDev.GhostMod4Lins";

		public const string PLUGIN_NAME = "Ghost4Lins";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}