Decompiled source of Grappling v1.0.0

grappling.dll

Decompiled 4 months 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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("frici")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("grappling")]
[assembly: AssemblyTitle("grappling")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 GrapplingMod
{
	[BepInPlugin("com.frici.grappling", "Grappling Mod", "1.0.0")]
	public class GrapplingPlugin : BaseUnityPlugin
	{
		public static ManualLogSource Log;

		public static ConfigEntry<string> CfgKey;

		public static ConfigEntry<float> CfgSpeed;

		public static ConfigEntry<float> CfgMaxDist;

		public static ConfigEntry<float> CfgStopDist;

		public static ConfigEntry<float> CfgPullStrength;

		private void Awake()
		{
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"===== GRAPPLING MOD AWAKE =====");
			CfgKey = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "ToggleKey", "j", "Toggle key. Examples: j, k, g, h, f5");
			CfgSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "GrappleSpeed", 15f, "Pull acceleration. Higher = faster acceleration.");
			CfgMaxDist = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "MaxDistance", 50f, "Max grapple ray distance.");
			CfgStopDist = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "StopDistance", 2f, "Auto-stop distance.");
			CfgPullStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "PullStrength", 1f, "Multiplier for pull force. 0.5 = half strength, 2.0 = double strength.");
			Log.LogInfo((object)($"Key={CfgKey.Value} Speed={CfgSpeed.Value} " + $"MaxDist={CfgMaxDist.Value} StopDist={CfgStopDist.Value} " + $"PullStrength={CfgPullStrength.Value}"));
			GameObject val = new GameObject("__GrappleRunner__");
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<GrappleRunner>();
			Log.LogInfo((object)"[G] Runner created with DontDestroyOnLoad + HideAndDontSave");
			try
			{
				Harmony harmony = new Harmony("com.frici.grappling");
				PatchGame(harmony);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[G] Harmony error: " + ex.Message));
			}
			Log.LogInfo((object)"===== AWAKE DONE =====");
		}

		private static void PatchGame(Harmony harmony)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			string[] array = new string[6] { "PlayerController", "GameDirector", "RunManager", "GameManager", "SemiFunc", "LevelGenerator" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				try
				{
					Type type = AccessTools.TypeByName(text);
					if (!(type == null))
					{
						MethodInfo methodInfo = AccessTools.Method(type, "Update", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "LateUpdate", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null);
						if (!(methodInfo == null))
						{
							MethodInfo method = typeof(GamePatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public);
							harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							Log.LogInfo((object)("[G] PATCHED " + text + "." + methodInfo.Name + " ✓"));
							return;
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogInfo((object)("[G] Patch " + text + " skip: " + ex.Message));
				}
			}
			Log.LogWarning((object)"[G] No game methods patched — relying on Update/OnGUI");
		}
	}
	public static class GamePatch
	{
		public static void Postfix()
		{
			if ((Object)(object)GrappleRunner.Instance != (Object)null)
			{
				GrappleRunner.Instance.DoTick("HarmonyPatch");
			}
		}
	}
	public class GrappleRunner : MonoBehaviour
	{
		public static GrappleRunner Instance;

		public static bool ModOn = true;

		public static bool IsGrappling = false;

		public static Vector3 Target;

		public static Rigidbody PlayerRb;

		private int lastTickFrame = -1;

		private bool everTicked = false;

		private float heartbeat = 0f;

		private float pullLogT = 0f;

		private LineRenderer rope;

		private bool hasNewInput = false;

		private Type kbType;

		private Type msType;

		private Type keyType;

		private object parsedKey;

		private void Awake()
		{
			Instance = this;
			GrapplingPlugin.Log.LogInfo((object)"[G] Runner Awake()");
			DetectNewInput();
		}

		private void OnEnable()
		{
			Instance = this;
			GrapplingPlugin.Log.LogInfo((object)"[G] Runner OnEnable");
		}

		private void OnDisable()
		{
			GrapplingPlugin.Log.LogInfo((object)"[G] Runner OnDisable !!!");
		}

		private void OnDestroy()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			GrapplingPlugin.Log.LogInfo((object)"[G] Runner OnDestroy !!!");
			try
			{
				GameObject val = new GameObject("__GrappleRunner__");
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<GrappleRunner>();
				GrapplingPlugin.Log.LogInfo((object)"[G] Runner RESPAWNED");
			}
			catch
			{
			}
		}

		private void Update()
		{
			DoTick("Update");
		}

		private void FixedUpdate()
		{
			if (IsGrappling && (Object)(object)PlayerRb != (Object)null)
			{
				DoPull();
			}
		}

		private void OnGUI()
		{
			DoTick("OnGUI");
			DrawHUD();
		}

		private void DrawHUD()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_00be: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GUIStyle val = new GUIStyle(GUI.skin.label);
				val.fontSize = 20;
				val.fontStyle = (FontStyle)1;
				if (ModOn)
				{
					val.normal.textColor = Color.green;
					string text = (IsGrappling ? "GRAPPLE: ON - PULLING!" : "GRAPPLE: ON");
					GUI.Label(new Rect(10f, 10f, 600f, 35f), text, val);
				}
				else
				{
					val.normal.textColor = Color.red;
					GUI.Label(new Rect(10f, 10f, 600f, 35f), "GRAPPLE: OFF", val);
				}
				GUIStyle val2 = new GUIStyle(GUI.skin.label);
				val2.fontSize = 14;
				val2.normal.textColor = Color.white;
				GUI.Label(new Rect(10f, 40f, 600f, 25f), "Toggle: " + GrapplingPlugin.CfgKey.Value.ToUpper() + " | " + $"Speed: {GrapplingPlugin.CfgSpeed.Value} | " + $"Strength: {GrapplingPlugin.CfgPullStrength.Value:F1}x", val2);
				if (IsGrappling)
				{
					GUIStyle val3 = new GUIStyle(GUI.skin.label);
					val3.fontSize = 14;
					val3.normal.textColor = Color.yellow;
					GUI.Label(new Rect(10f, 70f, 600f, 25f), "LEFT-CLICK to change target | RIGHT-CLICK to release", val3);
				}
			}
			catch
			{
			}
		}

		public void DoTick(string source)
		{
			int frameCount = Time.frameCount;
			if (frameCount != lastTickFrame)
			{
				lastTickFrame = frameCount;
				if (!everTicked)
				{
					everTicked = true;
					GrapplingPlugin.Log.LogInfo((object)$"[G] *** FIRST TICK via {source} at frame {frameCount} ***");
				}
				try
				{
					HandleInput();
				}
				catch (Exception arg)
				{
					GrapplingPlugin.Log.LogError((object)$"[G] Tick error: {arg}");
				}
				heartbeat -= Time.unscaledDeltaTime;
				if (heartbeat <= 0f)
				{
					heartbeat = 10f;
					GrapplingPlugin.Log.LogInfo((object)$"[G] Heartbeat | On={ModOn} | Grap={IsGrappling} | F={frameCount}");
				}
			}
		}

		private void HandleInput()
		{
			if (AnyKeyDown(GrapplingPlugin.CfgKey.Value))
			{
				ModOn = !ModOn;
				GrapplingPlugin.Log.LogInfo((object)("[G] *** TOGGLE: " + (ModOn ? "ON" : "OFF") + " ***"));
				if (!ModOn && IsGrappling)
				{
					StopGrapple("toggled off");
				}
			}
			if (AnyMouseDown(0))
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] LEFT CLICK");
				if (ModOn)
				{
					if (IsGrappling)
					{
						GrapplingPlugin.Log.LogInfo((object)"[G]   changing target...");
						TryChangeTarget();
					}
					else
					{
						GrapplingPlugin.Log.LogInfo((object)"[G]   starting new grapple...");
						TryStartGrapple();
					}
				}
				else
				{
					GrapplingPlugin.Log.LogInfo((object)"[G]   mod is OFF");
				}
			}
			if (AnyMouseDown(1))
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] RIGHT CLICK");
				if (IsGrappling)
				{
					StopGrapple("right click");
				}
				else
				{
					GrapplingPlugin.Log.LogInfo((object)"[G]   not grappling");
				}
			}
		}

		private bool AnyKeyDown(string key)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Input.GetKeyDown(key.ToLower()))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (Enum.TryParse<KeyCode>(key, ignoreCase: true, out KeyCode result) && Input.GetKeyDown(result))
				{
					return true;
				}
			}
			catch
			{
			}
			if (hasNewInput && parsedKey != null)
			{
				try
				{
					if (NewKeyDown())
					{
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private bool AnyMouseDown(int btn)
		{
			try
			{
				if (Input.GetMouseButtonDown(btn))
				{
					return true;
				}
			}
			catch
			{
			}
			if (hasNewInput)
			{
				try
				{
					string btn2 = ((btn == 0) ? "leftButton" : "rightButton");
					if (NewMouseDown(btn2))
					{
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private void TryStartGrapple()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_006b: 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_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			Camera activeCamera = GetActiveCamera();
			if ((Object)(object)activeCamera == (Object)null)
			{
				GrapplingPlugin.Log.LogWarning((object)"[G] No camera!");
				return;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)activeCamera).transform.position, ((Component)activeCamera).transform.forward);
			float value = GrapplingPlugin.CfgMaxDist.Value;
			GrapplingPlugin.Log.LogInfo((object)$"[G] Ray origin={((Ray)(ref val)).origin} dir={((Ray)(ref val)).direction} max={value}");
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val, ref val2, value, -1, (QueryTriggerInteraction)1))
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] Raycast MISS");
				return;
			}
			bool flag = (Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody == (Object)null;
			bool flag2 = !flag && ((RaycastHit)(ref val2)).collider.attachedRigidbody.isKinematic;
			bool flag3 = flag || flag2;
			GrapplingPlugin.Log.LogInfo((object)$"[G] Hit '{((Object)((RaycastHit)(ref val2)).collider).name}' dist={((RaycastHit)(ref val2)).distance:F1} unmovable={flag3}");
			if (!flag3)
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] Movable object — skip");
				return;
			}
			PlayerRb = FindPlayerRb();
			if ((Object)(object)PlayerRb == (Object)null)
			{
				GrapplingPlugin.Log.LogWarning((object)"[G] No player RB found!");
				return;
			}
			Target = ((RaycastHit)(ref val2)).point;
			IsGrappling = true;
			pullLogT = 0f;
			float num = Vector3.Distance(PlayerRb.position, Target);
			GrapplingPlugin.Log.LogInfo((object)"======== GRAPPLE START ========");
			GrapplingPlugin.Log.LogInfo((object)$"[G] Player={((Object)PlayerRb).name} pos={PlayerRb.position}");
			GrapplingPlugin.Log.LogInfo((object)$"[G] Target={Target} dist={num:F1}");
			GrapplingPlugin.Log.LogInfo((object)$"[G] Speed={GrapplingPlugin.CfgSpeed.Value} Strength={GrapplingPlugin.CfgPullStrength.Value}");
			GrapplingPlugin.Log.LogInfo((object)"===============================");
			Vector3 val3 = Target - PlayerRb.position;
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			try
			{
				PlayerRb.isKinematic = false;
			}
			catch
			{
			}
			PlayerRb.WakeUp();
			PlayerRb.AddForce(normalized * GrapplingPlugin.CfgSpeed.Value * 0.5f, (ForceMode)2);
			PlayerRb.AddTorque(Random.insideUnitSphere * 3f, (ForceMode)2);
			EnsureRope();
		}

		private void TryChangeTarget()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			Camera activeCamera = GetActiveCamera();
			if ((Object)(object)activeCamera == (Object)null)
			{
				return;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)activeCamera).transform.position, ((Component)activeCamera).transform.forward);
			float value = GrapplingPlugin.CfgMaxDist.Value;
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val, ref val2, value, -1, (QueryTriggerInteraction)1))
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] Change target: raycast miss");
				return;
			}
			bool flag = (Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody == (Object)null;
			bool flag2 = !flag && ((RaycastHit)(ref val2)).collider.attachedRigidbody.isKinematic;
			bool flag3 = flag || flag2;
			GrapplingPlugin.Log.LogInfo((object)$"[G] Change target to '{((Object)((RaycastHit)(ref val2)).collider).name}' dist={((RaycastHit)(ref val2)).distance:F1}");
			if (!flag3)
			{
				GrapplingPlugin.Log.LogInfo((object)"[G] New target is movable, ignored");
				return;
			}
			Target = ((RaycastHit)(ref val2)).point;
			float num = Vector3.Distance(PlayerRb.position, Target);
			GrapplingPlugin.Log.LogInfo((object)$"[G] Target changed to {Target} dist={num:F1}");
		}

		private void DoPull()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerRb == (Object)null)
			{
				StopGrapple("player null");
				return;
			}
			float num = Vector3.Distance(PlayerRb.position, Target);
			if (num <= GrapplingPlugin.CfgStopDist.Value)
			{
				GrapplingPlugin.Log.LogInfo((object)$"[G] Reached target dist={num:F2}");
				StopGrapple("reached");
				return;
			}
			Vector3 val = Target - PlayerRb.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			PlayerRb.WakeUp();
			float num2 = GrapplingPlugin.CfgSpeed.Value * GrapplingPlugin.CfgPullStrength.Value;
			PlayerRb.AddForce(normalized * num2, (ForceMode)5);
			if ((Object)(object)rope != (Object)null && ((Renderer)rope).enabled)
			{
				rope.SetPosition(0, PlayerRb.position);
				rope.SetPosition(1, Target);
			}
			pullLogT -= Time.fixedDeltaTime;
			if (pullLogT <= 0f)
			{
				pullLogT = 0.5f;
				ManualLogSource log = GrapplingPlugin.Log;
				object arg = num;
				val = PlayerRb.velocity;
				log.LogInfo((object)$"[G] PULLING dist={arg:F1} vel={((Vector3)(ref val)).magnitude:F1}");
			}
		}

		private void StopGrapple(string reason)
		{
			IsGrappling = false;
			if ((Object)(object)rope != (Object)null)
			{
				((Renderer)rope).enabled = false;
				rope.positionCount = 0;
			}
			GrapplingPlugin.Log.LogInfo((object)("[G] === GRAPPLE STOP === reason=" + reason));
		}

		private void EnsureRope()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_0079: Expected O, but got Unknown
			if ((Object)(object)rope != (Object)null)
			{
				((Renderer)rope).enabled = true;
				rope.positionCount = 2;
				return;
			}
			try
			{
				rope = ((Component)this).gameObject.AddComponent<LineRenderer>();
				Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("UI/Default");
				if ((Object)(object)val != (Object)null)
				{
					((Renderer)rope).material = new Material(val);
				}
				rope.startWidth = 0.03f;
				rope.endWidth = 0.01f;
				rope.startColor = new Color(1f, 0.6f, 0f);
				rope.endColor = Color.white;
				((Renderer)rope).enabled = true;
				rope.positionCount = 2;
			}
			catch (Exception ex)
			{
				GrapplingPlugin.Log.LogWarning((object)("[G] Rope fail: " + ex.Message));
			}
		}

		private Camera GetActiveCamera()
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && ((Behaviour)main).isActiveAndEnabled)
			{
				return main;
			}
			Camera[] array = Object.FindObjectsOfType<Camera>();
			Camera[] array2 = array;
			foreach (Camera val in array2)
			{
				if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy)
				{
					return val;
				}
			}
			return null;
		}

		private Rigidbody FindPlayerRb()
		{
			GrapplingPlugin.Log.LogInfo((object)"[G] Searching player...");
			try
			{
				GameObject val = GameObject.FindWithTag("Player");
				if ((Object)(object)val != (Object)null)
				{
					Rigidbody val2 = val.GetComponent<Rigidbody>() ?? val.GetComponentInChildren<Rigidbody>() ?? val.GetComponentInParent<Rigidbody>();
					if ((Object)(object)val2 != (Object)null)
					{
						GrapplingPlugin.Log.LogInfo((object)("[G] Found by tag: " + GetPath(((Component)val2).transform)));
						return val2;
					}
				}
			}
			catch
			{
			}
			Rigidbody[] array = Object.FindObjectsOfType<Rigidbody>();
			GrapplingPlugin.Log.LogInfo((object)$"[G] Total RBs: {array.Length}");
			Rigidbody[] array2 = array;
			foreach (Rigidbody val3 in array2)
			{
				string path = GetPath(((Component)val3).transform);
				GrapplingPlugin.Log.LogInfo((object)$"[G]   {path} k={val3.isKinematic} m={val3.mass}");
			}
			Rigidbody[] array3 = array;
			foreach (Rigidbody val4 in array3)
			{
				string path2 = GetPath(((Component)val4).transform);
				if (path2.IndexOf("player", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					GrapplingPlugin.Log.LogInfo((object)("[G] MATCH: " + path2));
					return val4;
				}
			}
			string[] array4 = new string[6] { "PlayerController", "PlayerAvatar", "PlayerCharacter", "Player", "PlayerTumble", "PlayerPhysics" };
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				string[] array5 = array4;
				foreach (string text in array5)
				{
					try
					{
						Type type = assembly.GetType(text);
						if (type == null)
						{
							continue;
						}
						Object[] array6 = Object.FindObjectsOfType(type);
						if (array6.Length == 0)
						{
							continue;
						}
						Object obj2 = array6[0];
						Component val5 = (Component)(object)((obj2 is Component) ? obj2 : null);
						if (!((Object)(object)val5 == (Object)null))
						{
							Rigidbody val6 = val5.GetComponent<Rigidbody>() ?? val5.GetComponentInChildren<Rigidbody>() ?? val5.GetComponentInParent<Rigidbody>();
							if ((Object)(object)val6 != (Object)null)
							{
								GrapplingPlugin.Log.LogInfo((object)("[G] Found by type " + text + ": " + ((Object)val6).name));
								return val6;
							}
						}
					}
					catch
					{
					}
				}
			}
			Rigidbody[] array7 = array;
			foreach (Rigidbody val7 in array7)
			{
				if (!val7.isKinematic && val7.mass >= 1f)
				{
					GrapplingPlugin.Log.LogInfo((object)("[G] Fallback: " + GetPath(((Component)val7).transform)));
					return val7;
				}
			}
			return null;
		}

		private void DetectNewInput()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (kbType == null)
					{
						kbType = assembly.GetType("UnityEngine.InputSystem.Keyboard");
					}
					if (msType == null)
					{
						msType = assembly.GetType("UnityEngine.InputSystem.Mouse");
					}
					if (keyType == null)
					{
						keyType = assembly.GetType("UnityEngine.InputSystem.Key");
					}
				}
				if (kbType != null && msType != null && keyType != null)
				{
					hasNewInput = true;
					try
					{
						parsedKey = Enum.Parse(keyType, GrapplingPlugin.CfgKey.Value, ignoreCase: true);
					}
					catch
					{
						parsedKey = Enum.Parse(keyType, "J", ignoreCase: true);
					}
					GrapplingPlugin.Log.LogInfo((object)"[G] New Input System ready ✓");
				}
				else
				{
					GrapplingPlugin.Log.LogInfo((object)"[G] Legacy input only");
				}
			}
			catch (Exception ex)
			{
				GrapplingPlugin.Log.LogInfo((object)("[G] Input detect: " + ex.Message));
			}
		}

		private bool NewKeyDown()
		{
			object obj = kbType.GetProperty("current", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
			if (obj == null)
			{
				return false;
			}
			PropertyInfo property = kbType.GetProperty("Item", BindingFlags.Instance | BindingFlags.Public);
			if (property == null)
			{
				return false;
			}
			object value = property.GetValue(obj, new object[1] { parsedKey });
			if (value == null)
			{
				return false;
			}
			PropertyInfo property2 = value.GetType().GetProperty("wasPressedThisFrame");
			return property2 != null && (bool)property2.GetValue(value);
		}

		private bool NewMouseDown(string btn)
		{
			object obj = msType.GetProperty("current", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
			if (obj == null)
			{
				return false;
			}
			object obj2 = msType.GetProperty(btn, BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj);
			if (obj2 == null)
			{
				return false;
			}
			PropertyInfo property = obj2.GetType().GetProperty("wasPressedThisFrame");
			return property != null && (bool)property.GetValue(obj2);
		}

		private static string GetPath(Transform t)
		{
			string text = ((Object)t).name;
			while ((Object)(object)t.parent != (Object)null)
			{
				t = t.parent;
				text = ((Object)t).name + "/" + text;
			}
			return text;
		}
	}
}