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);
}
}