Decompiled source of The Mimicry Mod v1.0.2

HoldensMimicryMod.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MimicryMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Holden")]
[assembly: AssemblyProduct("MimicryMod")]
[assembly: AssemblyCopyright("Copyright © Holden 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("14aa83f7-baa2-4226-be61-e878ccf60e56")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MimicryMod;

[ContentWarningPlugin("14aa83f7-baa2-4226-be61-e878ccf60e56", "1.0", true)]
[BepInPlugin("holden.plugin.test.MimicryMod", "Mimicry Mod!", "1.0")]
public class Mimicry : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Player), "Start")]
	public static class PlayerStartAPtch
	{
		[HarmonyPostfix]
		public static void StartPX()
		{
			if (MainMenuHandler.SteamLobbyHandler.IsPlayingWithRandoms())
			{
				isFriendOnly = false;
			}
			else
			{
				isFriendOnly = true;
			}
			CreateTriggerSpheres();
			hue = Player.localPlayer.refs.visor.hue.Value;
			colorInd = Player.localPlayer.refs.visor.visorColorIndex;
			faceText = ((TMP_Text)Player.localPlayer.refs.visor.visorFaceText).text;
			faceRotation = Player.localPlayer.refs.visor.FaceRotation;
			facesize = Player.localPlayer.refs.visor.FaceSize;
		}
	}

	private class HandCollider : MonoBehaviour
	{
		private Mimicry mod;

		private string handName;

		public void Initialize(Mimicry mod, string handName)
		{
			this.mod = mod;
			this.handName = handName;
		}

		private void OnTriggerEnter(Collider other)
		{
			mod.HandleCollision(other, handName);
		}
	}

	private static GameObject rightHandSphere;

	private static GameObject leftHandSphere;

	private static bool isPunching = false;

	private static bool isSet = false;

	private static bool isAMimic = false;

	private static List<string> hands = new List<string>();

	private static float hue;

	private static int colorInd;

	private static string faceText;

	private static float faceRotation;

	private static float facesize;

	private static bool isFriendOnly = false;

	private static ReflectionUtil<SteamLobbyHandler> steamHandler;

	private float timer;

	private float interval = 15f;

	private void Start()
	{
		steamHandler = new ReflectionUtil<SteamLobbyHandler>(MainMenuHandler.SteamLobbyHandler);
		hands.Add("Hand_R");
		hands.Add("Hand_L");
		ApplyPatches();
	}

	public static void ApplyPatches()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)"Trying to apply patches.");
		new Harmony("com.holden.codewarning").PatchAll(Assembly.GetExecutingAssembly());
		Debug.Log((object)"Harmony patches applied.");
	}

	private void Update()
	{
		if (!Object.op_Implicit((Object)(object)Player.localPlayer))
		{
			isSet = false;
			return;
		}
		if (!isSet)
		{
			CreateTriggerSpheres();
		}
		Punch();
		if (isAMimic)
		{
			if (Player.localPlayer.data.health <= 20f)
			{
				timer += Time.deltaTime;
			}
			else
			{
				timer = 0f;
			}
			if (timer >= 0.5f && Player.localPlayer.data.health <= 20f)
			{
				UI_Feedback.instance.TakeDamage(false);
			}
			if (timer >= interval && !Player.localPlayer.data.dead && Player.localPlayer.data.health <= 20f)
			{
				ChangeBack();
				timer = 0f;
			}
		}
	}

	private void ChangeBack()
	{
		HelmetText.Instance.SetHelmetText("You don't have the vitality to maintain this form any longer!", 2.5f);
		Player.localPlayer.refs.visor.SetAllFaceSettings(hue, colorInd, faceText, faceRotation, facesize);
		isAMimic = false;
	}

	private static void CreateTriggerSpheres()
	{
		if ((Object)(object)rightHandSphere == (Object)null)
		{
			rightHandSphere = CreateTriggerSphere("Hand_R_Collider");
		}
		if ((Object)(object)leftHandSphere == (Object)null)
		{
			leftHandSphere = CreateTriggerSphere("Hand_L_Collider");
		}
		if ((Object)(object)rightHandSphere != (Object)null && (Object)(object)leftHandSphere != (Object)null)
		{
			isSet = true;
		}
	}

	private static GameObject CreateTriggerSphere(string handName)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if (!isFriendOnly)
		{
			return null;
		}
		GameObject val = GameObject.Find(handName);
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogError((object)("Hand '" + handName + "' not found!"));
			return null;
		}
		Debug.LogError((object)("Creating Combat hand for " + ((Object)val).name));
		GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)0);
		val2.transform.SetParent(val.transform);
		val2.transform.localPosition = Vector3.zero;
		val2.transform.localScale = new Vector3(2f, 2f, 2f);
		val2.GetComponent<Renderer>().enabled = false;
		Collider component = val2.GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			Object.Destroy((Object)(object)component);
			((Collider)val2.AddComponent<SphereCollider>()).isTrigger = true;
		}
		Mimicry mod = new Mimicry();
		val2.AddComponent<HandCollider>().Initialize(mod, handName);
		if ((Object)(object)val2.transform.parent != (Object)(object)val.transform || !Object.op_Implicit((Object)(object)val2.GetComponent<HandCollider>()))
		{
			Object.Destroy((Object)(object)val2);
			return null;
		}
		return val2;
	}

	private void Punch()
	{
		//IL_00ac: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		if (!Input.anyKey || !Input.anyKeyDown || !Input.GetKeyDown((KeyCode)102) || (Object)(object)Camera.main == (Object)null)
		{
			return;
		}
		FieldInfo field = typeof(PlayerRagdoll).GetField("rigList", BindingFlags.Instance | BindingFlags.NonPublic);
		if (!(field != null) || !(field.GetValue(Player.localPlayer.refs.ragdoll) is List<Rigidbody> list))
		{
			return;
		}
		foreach (Rigidbody item in list)
		{
			if (!((Object)(object)item != (Object)null) || !(((Object)item).name == "Hip"))
			{
				continue;
			}
			Vector3 val = ((Component)MainCamera.instance).transform.rotation * Vector3.forward * 3f;
			Vector3 val2 = ((Component)MainCamera.instance).transform.position + val * 15f;
			val2.y += 10f;
			Vector3 val3 = val2 - item.position;
			Vector3 val4 = ((Vector3)(ref val3)).normalized * ((Vector3)(ref val3)).magnitude * 4f;
			MethodInfo method = typeof(Player).GetMethod("CallAddForceToBodyParts", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				if (ChooseHand() == "Hand_L")
				{
					isPunching = true;
					method.Invoke(Player.localPlayer, new object[2]
					{
						new int[1] { 5 },
						new Vector3[1] { val4 }
					});
					((MonoBehaviour)this).Invoke("StopPunching", 1f);
				}
				else
				{
					isPunching = true;
					method.Invoke(Player.localPlayer, new object[2]
					{
						new int[1] { 8 },
						new Vector3[1] { val4 }
					});
					((MonoBehaviour)this).Invoke("StopPunching", 1f);
				}
			}
		}
	}

	private string ChooseHand()
	{
		if (hands.Count == 0)
		{
			return null;
		}
		return hands[Random.Range(0, hands.Count)];
	}

	private void StopPunching()
	{
		isPunching = false;
	}

	public void HandleCollision(Collider other, string handName)
	{
		//IL_0063: 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_0077: 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_007f: 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)
		if (!isPunching)
		{
			return;
		}
		Player componentInParent = ((Component)other).GetComponentInParent<Player>();
		if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent == (Object)(object)Player.localPlayer || componentInParent.data.dead)
		{
			return;
		}
		float num = 4f;
		if (Player.localPlayer.data.health <= 20f && componentInParent.ai)
		{
			num = 20f;
		}
		Vector3 val = ((Component)other).transform.position - ((Component)Player.localPlayer).transform.position;
		_ = ((Vector3)(ref val)).normalized * num;
		if (!componentInParent.ai)
		{
			MethodInfo method = typeof(Player).GetMethod("CallMakeSound", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(componentInParent, new object[1] { 0 });
			}
			Player.localPlayer.refs.visor.SetAllFaceSettings(componentInParent.refs.visor.hue.Value, componentInParent.refs.visor.visorColorIndex, ((TMP_Text)componentInParent.refs.visor.visorFaceText).text, componentInParent.refs.visor.FaceRotation, componentInParent.refs.visor.FaceSize);
			Hat currentHat = componentInParent.data.currentHat;
			if ((Object)(object)currentHat != (Object)null)
			{
				Player.localPlayer.Call_EquipHat(currentHat.runtimeHatIndex);
			}
			else
			{
				Player.localPlayer.Call_RemoveHat();
			}
			isPunching = false;
			isAMimic = true;
			UI_Feedback.instance.HealFeedback();
			HelmetText.Instance.SetHelmetText("Unto Holden's grace, you are now a perfect Mimic of " + componentInParent.refs.view.Owner.NickName + "!", 1f);
		}
	}
}
public class ReflectionUtil<R>
{
	private const BindingFlags privateInst = BindingFlags.Instance | BindingFlags.NonPublic;

	private const BindingFlags privateStatic = BindingFlags.Static | BindingFlags.NonPublic;

	private const BindingFlags privateField = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField;

	private const BindingFlags privateProp = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty;

	private const BindingFlags privateMethod = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod;

	private const BindingFlags staticField = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField;

	private const BindingFlags staticProp = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty;

	private const BindingFlags staticMethod = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod;

	private R @object { get; }

	private Type type { get; }

	internal ReflectionUtil(R obj)
	{
		@object = obj;
		type = typeof(R);
	}

	private object GetValue(string variableName, BindingFlags flags)
	{
		FieldInfo field = type.GetField(variableName, flags);
		if (!(field != null))
		{
			return null;
		}
		return field.GetValue(@object);
	}

	private object GetProperty(string propertyName, BindingFlags flags)
	{
		PropertyInfo property = type.GetProperty(propertyName, flags);
		if (!(property != null))
		{
			return null;
		}
		return property.GetValue(@object);
	}

	private void SetValue(string variableName, object value, BindingFlags flags)
	{
		FieldInfo field = type.GetField(variableName, flags);
		if (field != null)
		{
			field.SetValue(@object, value);
		}
	}

	private void SetProperty(string propertyName, object value, BindingFlags flags)
	{
		PropertyInfo property = type.GetProperty(propertyName, flags);
		if (property != null)
		{
			property.SetValue(@object, value);
		}
	}

	private object InvokeMethod(string methodName, BindingFlags flags, params object[] args)
	{
		MethodInfo[] methods = type.GetMethods(flags);
		foreach (MethodInfo methodInfo in methods)
		{
			if (methodInfo.Name == methodName && MatchMethodParameters(methodInfo, args))
			{
				return methodInfo.Invoke(@object, args);
			}
		}
		return null;
	}

	private bool MatchMethodParameters(MethodInfo method, object[] args)
	{
		ParameterInfo[] parameters = method.GetParameters();
		if (parameters.Length != args.Length)
		{
			return false;
		}
		for (int i = 0; i < parameters.Length; i++)
		{
			if (!parameters[i].ParameterType.IsInstanceOfType(args[i]) && args[i] != null)
			{
				return false;
			}
		}
		return true;
	}

	public object GetValue(string fieldName, bool isStatic = false, bool isProperty = false)
	{
		BindingFlags flags = ((!isProperty) ? (isStatic ? (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField) : (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField)) : (isStatic ? (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty) : (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty)));
		if (!isProperty)
		{
			return GetValue(fieldName, flags);
		}
		return GetProperty(fieldName, flags);
	}

	public void SetValue(string fieldName, object value, bool isStatic = false, bool isProperty = false)
	{
		BindingFlags flags = ((!isProperty) ? (isStatic ? (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField) : (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField)) : (isStatic ? (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty) : (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty)));
		if (isProperty)
		{
			SetProperty(fieldName, value, flags);
		}
		else
		{
			SetValue(fieldName, value, flags);
		}
	}

	public object Invoke(string methodName, bool isStatic = false, params object[] args)
	{
		return InvokeMethod(methodName, isStatic ? (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod) : (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod), args);
	}
}
public static class ReflectorExtensions
{
	public static ReflectionUtil<R> Reflect<R>(this R obj)
	{
		return new ReflectionUtil<R>(obj);
	}
}