Decompiled source of GhostMod v1.0.0

BepInEx\plugins\GhostMod\GhostMod.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 GhostMod
{
	[BepInPlugin("com.ghostmod.lethalcompany", "GhostMod", "1.0.0")]
	public class GhostModPlugin : BaseUnityPlugin
	{
		private const string PLUGIN_GUID = "com.ghostmod.lethalcompany";

		private const string PLUGIN_NAME = "GhostMod";

		private const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource LogSource;

		private Harmony _harmony;

		internal static bool IsGhostMode;

		internal static GameObject GhostVisualObj;

		internal static float OrbitDist = 3.5f;

		internal static float OrbitYaw;

		internal static float OrbitPitch = 15f;

		internal static float BobTimer;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			LogSource = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("com.ghostmod.lethalcompany");
			_harmony.PatchAll();
			LogSource.LogInfo((object)"GhostMod v1.0.0 loaded!");
		}

		private void LateUpdate()
		{
			if (!IsGhostMode)
			{
				return;
			}
			PlayerControllerB localPlayer = GetLocalPlayer();
			if (!((Object)(object)localPlayer == (Object)null) && localPlayer.isPlayerDead)
			{
				PlayerControllerB spectatedPlayerScript = localPlayer.spectatedPlayerScript;
				if (!((Object)(object)spectatedPlayerScript == (Object)null) && !spectatedPlayerScript.isPlayerDead)
				{
					HandleInput();
					UpdateOrbitCamera(spectatedPlayerScript);
					UpdateGhostVisual(spectatedPlayerScript);
				}
			}
		}

		private void HandleInput()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Cursor.lockState == 1)
			{
				OrbitYaw += Input.GetAxis("Mouse X") * 2.5f;
				OrbitPitch -= Input.GetAxis("Mouse Y") * 2.5f;
				OrbitPitch = Mathf.Clamp(OrbitPitch, -75f, 75f);
			}
			float axis = Input.GetAxis("Mouse ScrollWheel");
			if (Mathf.Abs(axis) > 0.001f)
			{
				OrbitDist -= axis * 4f;
				OrbitDist = Mathf.Clamp(OrbitDist, 0.8f, 12f);
			}
		}

		private void UpdateOrbitCamera(PlayerControllerB spectated)
		{
			//IL_0030: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Camera val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.spectateCamera : null);
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 position = ((Component)spectated.gameplayCamera).transform.position;
				Vector3 val2 = Quaternion.Euler(OrbitPitch, OrbitYaw, 0f) * new Vector3(0f, 0f, 0f - OrbitDist);
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(position, ((Vector3)(ref val2)).normalized, ref val3, OrbitDist, StartOfRound.Instance.collidersAndRoomMask))
				{
					((Component)val).transform.position = position + ((Vector3)(ref val2)).normalized * (((RaycastHit)(ref val3)).distance - 0.2f);
				}
				else
				{
					((Component)val).transform.position = position + val2;
				}
				((Component)val).transform.LookAt(position);
			}
		}

		private void UpdateGhostVisual(PlayerControllerB spectated)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_006f: 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_0079: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)GhostVisualObj == (Object)null))
			{
				BobTimer += Time.deltaTime;
				float num = Mathf.Sin(BobTimer * 2f) * 0.06f;
				Vector3 position = ((Component)spectated.gameplayCamera).transform.position;
				Vector3 val = Quaternion.Euler(0f, OrbitYaw + 30f, 0f) * new Vector3(0f, 0f, -0.85f);
				Vector3 position2 = position + val;
				position2.y = ((Component)spectated).transform.position.y + 0.45f + num;
				GhostVisualObj.transform.position = position2;
				GhostVisualObj.transform.LookAt(new Vector3(position.x, GhostVisualObj.transform.position.y, position.z));
				Transform val2 = GhostVisualObj.transform.Find("Particles");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.Rotate(Vector3.up, 40f * Time.deltaTime, (Space)0);
				}
			}
		}

		private void OnGUI()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0027: Expected O, but got Unknown
			//IL_0041: 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)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009b: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (IsGhostMode)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					alignment = (TextAnchor)1
				};
				val.normal.textColor = new Color(0.6f, 0.85f, 1f, 0.85f);
				GUI.Label(new Rect((float)Screen.width / 2f - 120f, 12f, 240f, 30f), "· GHOST MODE ·", val);
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 12,
					alignment = (TextAnchor)1
				};
				val2.normal.textColor = new Color(0.75f, 0.75f, 0.75f, 0.55f);
				GUI.Label(new Rect((float)Screen.width / 2f - 180f, 36f, 360f, 22f), "Mouse: Rotacionar | Scroll: Zoom | V: VOIP", val2);
			}
		}

		internal static void ActivateGhost()
		{
			if (!IsGhostMode)
			{
				IsGhostMode = true;
				OrbitDist = 3.5f;
				OrbitYaw = 0f;
				OrbitPitch = 15f;
				BobTimer = 0f;
				CreateGhostVisual();
				LogSource.LogInfo((object)"Ghost mode activated.");
			}
		}

		internal static void DeactivateGhost()
		{
			IsGhostMode = false;
			if ((Object)(object)GhostVisualObj != (Object)null)
			{
				Object.Destroy((Object)(object)GhostVisualObj);
				GhostVisualObj = null;
			}
			LogSource.LogInfo((object)"Ghost mode deactivated.");
		}

		private static void CreateGhostVisual()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_004d: 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)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GhostVisualObj != (Object)null)
			{
				Object.Destroy((Object)(object)GhostVisualObj);
			}
			GhostVisualObj = new GameObject("GhostMod_Visual");
			Material val = CreateGhostMaterial();
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)1);
			obj.transform.SetParent(GhostVisualObj.transform);
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localScale = new Vector3(0.13f, 0.22f, 0.13f);
			SafeDestroyCollider(obj);
			obj.GetComponent<Renderer>().material = val;
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)0);
			obj2.transform.SetParent(GhostVisualObj.transform);
			obj2.transform.localPosition = new Vector3(0f, 0.3f, 0f);
			obj2.transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
			SafeDestroyCollider(obj2);
			obj2.GetComponent<Renderer>().material = val;
			for (int i = -1; i <= 1; i += 2)
			{
				GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)1);
				obj3.transform.SetParent(GhostVisualObj.transform);
				obj3.transform.localPosition = new Vector3((float)i * 0.12f, 0.05f, 0f);
				obj3.transform.localScale = new Vector3(0.04f, 0.1f, 0.04f);
				obj3.transform.localRotation = Quaternion.Euler(0f, 0f, (float)i * -30f);
				SafeDestroyCollider(obj3);
				obj3.GetComponent<Renderer>().material = val;
			}
			GameObject val2 = new GameObject("Particles");
			val2.transform.SetParent(GhostVisualObj.transform);
			val2.transform.localPosition = Vector3.zero;
			Material val3 = new Material(val);
			val3.color = new Color(0.7f, 0.92f, 1f, 0.45f);
			if (val3.HasProperty("_EmissionColor"))
			{
				val3.SetColor("_EmissionColor", new Color(0.4f, 0.65f, 1f) * 0.7f);
			}
			for (int j = 0; j < 5; j++)
			{
				GameObject obj4 = GameObject.CreatePrimitive((PrimitiveType)0);
				obj4.transform.SetParent(val2.transform);
				float num = (float)j * 72f * ((float)Math.PI / 180f);
				obj4.transform.localPosition = new Vector3(Mathf.Sin(num) * 0.22f, 0.05f + (float)j * 0.07f, Mathf.Cos(num) * 0.22f);
				obj4.transform.localScale = Vector3.one * 0.03f;
				SafeDestroyCollider(obj4);
				obj4.GetComponent<Renderer>().material = val3;
			}
			GhostVisualObj.transform.localScale = Vector3.one * 0.55f;
		}

		private static Material CreateGhostMaterial()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Legacy Shaders/Transparent/Diffuse");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Transparent/Diffuse");
			}
			Material val2 = new Material(val);
			if (val2.HasProperty("_Mode"))
			{
				val2.SetFloat("_Mode", 3f);
				val2.SetInt("_SrcBlend", 5);
				val2.SetInt("_DstBlend", 10);
				val2.SetInt("_ZWrite", 0);
				val2.DisableKeyword("_ALPHATEST_ON");
				val2.EnableKeyword("_ALPHABLEND_ON");
				val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val2.renderQueue = 3000;
			}
			val2.color = new Color(0.55f, 0.82f, 1f, 0.28f);
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", new Color(0.25f, 0.45f, 0.8f) * 0.4f);
			}
			return val2;
		}

		private static void SafeDestroyCollider(GameObject go)
		{
			Collider component = go.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
		}

		private static PlayerControllerB GetLocalPlayer()
		{
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return GameNetworkManager.Instance.localPlayerController;
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
	internal static class Patch_KillPlayer
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
			{
				GhostModPlugin.ActivateGhost();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "UpdatePlayerVoiceEffects")]
	internal static class Patch_VoiceEffects
	{
		[HarmonyPostfix]
		private static void Postfix(StartOfRound __instance)
		{
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			for (int i = 0; i < __instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val2 = __instance.allPlayerScripts[i];
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)val)
				{
					continue;
				}
				if (val2.isPlayerDead && !val.isPlayerDead)
				{
					AudioSource currentVoiceChatAudioSource = val2.currentVoiceChatAudioSource;
					if ((Object)(object)currentVoiceChatAudioSource != (Object)null)
					{
						currentVoiceChatAudioSource.volume = 0.7f;
						currentVoiceChatAudioSource.spatialBlend = 0f;
						currentVoiceChatAudioSource.mute = false;
						if ((Object)(object)((Component)currentVoiceChatAudioSource).GetComponent<AudioReverbFilter>() == (Object)null)
						{
							AudioReverbFilter obj = ((Component)currentVoiceChatAudioSource).gameObject.AddComponent<AudioReverbFilter>();
							obj.reverbPreset = (AudioReverbPreset)13;
							obj.dryLevel = -2f;
						}
						AudioHighPassFilter component = ((Component)currentVoiceChatAudioSource).GetComponent<AudioHighPassFilter>();
						if ((Object)(object)component != (Object)null)
						{
							((Behaviour)component).enabled = true;
							component.cutoffFrequency = 600f;
						}
					}
				}
				if (val.isPlayerDead && GhostModPlugin.IsGhostMode)
				{
					AudioSource currentVoiceChatAudioSource2 = val.currentVoiceChatAudioSource;
					if ((Object)(object)currentVoiceChatAudioSource2 != (Object)null)
					{
						currentVoiceChatAudioSource2.mute = false;
						currentVoiceChatAudioSource2.volume = 1f;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SetSpectatedPlayerEffects")]
	internal static class Patch_SpectateSwitch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance)
		{
			if (GhostModPlugin.IsGhostMode && ((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerDead)
			{
				GhostModPlugin.OrbitYaw = 0f;
				GhostModPlugin.OrbitPitch = 15f;
				GhostModPlugin.OrbitDist = 3.5f;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ReviveDeadPlayers")]
	internal static class Patch_Revive
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			GhostModPlugin.DeactivateGhost();
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
	internal static class Patch_Disconnect
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			GhostModPlugin.DeactivateGhost();
		}
	}
}