Decompiled source of SpiderLab Patch6 FusionCompat v2.8.0

Mods\SpiderLab.dll

Decompiled 2 days ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.UI;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab.SaveData;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Input;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSLZ.VRMK;
using Il2CppSystem;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using SpiderLab;
using SpiderLab.Behaviours;
using SpiderLab.Data;
using SpiderLab.Preferences;
using SpiderLab.Utils;
using UnityEngine;
using UnityEngine.XR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SpiderLab")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany(null)]
[assembly: AssemblyProduct("SpiderLab")]
[assembly: AssemblyCopyright("Created by Parzival")]
[assembly: AssemblyTrademark(null)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("2.8.0.0")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: MelonInfo(typeof(Main), "SpiderLab Compat", "2.8.0", "Parzival; Patch 6 compatibility rebuild", "https://bonelab.thunderstore.io/package/Parzival/SpiderLab/")]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonIncompatibleAssemblies(new string[] { "SpiderlectricBoogaloo", "AvatarStatsLoader", "StatOverride" })]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.8.0.0")]
[module: UnverifiableCode]
[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 SpiderLab
{
	public static class BuildInfo
	{
		public const string Name = "SpiderLab";

		public const string Author = "Parzival";

		public const string Company = null;

		public const string Version = "1.0.2";

		public const string DownloadLink = "https://bonelab.thunderstore.io/package/Parzival/SpiderLab/";

		public const string GameName = "BONELAB";

		public const string DeveloperName = "Stress Level Zero";
	}
	public class Main : MelonMod
	{
		private float nextInitializationAttempt;

		public override void OnInitializeMelon()
		{
			Prefs.Initialize();
			Patches.Initialize();
			Bundles.LoadAssets();
			ExternalWebMaterial.TryApply();
			Hooking.OnLevelLoaded += OnLevelInitialized;
		}

		public override void OnDeinitializeMelon()
		{
			Prefs.prefsCategory.SaveToFile(true);
		}

		private void OnLevelInitialized(LevelInfo info)
		{
			TryInitializePlayer(logIfUnavailable: true);
		}

		public override void OnUpdate()
		{
			if (!(Time.unscaledTime < nextInitializationAttempt))
			{
				nextInitializationAttempt = Time.unscaledTime + 1f;
				TryInitializePlayer(logIfUnavailable: false);
			}
		}

		private static void TryInitializePlayer(bool logIfUnavailable)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			if (!Player.HandsExist || (Object)Player.LeftHand == (Object)null || (Object)Player.RightHand == (Object)null)
			{
				if (logIfUnavailable)
				{
					MelonLogger.Warning("Couldn't initialize WebShooters yet; player hands are not ready.");
				}
				return;
			}
			bool flag = false;
			GameObject gameObject = ((Component)Player.LeftHand).gameObject;
			GameObject gameObject2 = ((Component)Player.RightHand).gameObject;
			if ((Object)gameObject.GetComponent<WebShooter>() == (Object)null)
			{
				gameObject.AddComponent<WebShooter>();
				flag = true;
			}
			if ((Object)gameObject2.GetComponent<WebShooter>() == (Object)null)
			{
				gameObject2.AddComponent<WebShooter>();
				flag = true;
			}
			Component physicsRig = (Component)(object)Player.GetPhysicsRig();
			if ((Object)physicsRig != (Object)null && (Object)physicsRig.gameObject.GetComponent<AirControl>() == (Object)null)
			{
				physicsRig.gameObject.AddComponent<AirControl>();
			}
			if (flag)
			{
				MelonLogger.Msg("WebShooters attached to both player hands.");
			}
		}

		private void LogAvatarInfo(Avatar avatar)
		{
			Msg("===========================");
			Msg("Name:           " + ((Object)avatar).name);
			Msg("Pointer:        " + ((Il2CppObjectBase)avatar).Pointer.ToString("x"));
			Msg("Strength Boost: " + Prefs.enableSpiderStrength.Value);
			Msg("Mass:           " + avatar.massTotal);
			Msg("Strength Upper: " + avatar.strengthUpper);
			Msg("Strength Lower: " + avatar.strengthLower);
			float num = avatar.strengthUpper / avatar.massTotal;
			Msg("Strength Upper to Total Mass: " + num);
			Msg("Strength % of Mass:           " + num * 100f);
			Msg("Raw Strength Upper:           " + avatar.strengthUpper / (avatar.massTotal / 75f));
			static void Msg(string txt)
			{
				MelonLogger.Msg(txt);
			}
		}
	}
	internal static class Patches
	{
		private const float MAX_WALL_GRIP_DISTANCE = 0.2f;

		public static void Initialize()
		{
			Hooking.CreateHook(typeof(WorldGrip).GetMethod("ValidateGripScore", AccessTools.all), typeof(Patches).GetMethod("WorldGripScorePostfix", AccessTools.all), false);
			Hooking.CreateHook(typeof(PhysicsRig).GetMethod("SetAvatar", AccessTools.all), typeof(Patches).GetMethod("PhysicsRigSetAvatarPrefix", AccessTools.all), true);
		}

		private static void WorldGripScorePostfix(Hand hand, SimpleTransform handTransform, ref ValueTuple<float, float, Vector3, Vector3> __result, WorldGrip __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0062: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			HandToGenericGripState val = default(HandToGenericGripState);
			if (!Prefs.enableWallCrawling.Value || IsWallGripInputBlocked(hand) || (Object)__instance == (Object)null || __instance.genericHandStates == null || !__instance.genericHandStates.TryGetValue(hand, ref val) || val == null || !val.isRaycastHit)
			{
				return;
			}
			Vector3 position = hand.palmPositionTransform.position;
			Vector3 raycastPoint = val.raycastPoint;
			if (!IsFinite(position) || !IsFinite(raycastPoint))
			{
				return;
			}
			Vector3 val2 = position - raycastPoint;
			float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
			if (!(sqrMagnitude <= 1E-06f) && !(sqrMagnitude > 0.040000003f))
			{
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (!(Vector3.Dot(-normalized, hand.palmPositionTransform.forward) < 0.75f))
				{
					val.raycastNormal = normalized;
					__result.Item1 = 1.5f;
				}
			}
		}

		private static bool IsWallGripInputBlocked(Hand hand)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			if ((Object)hand == (Object)null || (Object)hand.palmPositionTransform == (Object)null || hand.HasAttachedObject() || (Object)Player.GetObjectInHand(hand) != (Object)null || (Object)hand.Skeleton == (Object)null || hand.Skeleton.IsSnatching())
			{
				return true;
			}
			GUIMenu instance = GUIMenu.Instance;
			if ((Object)instance != (Object)null && ((Component)instance).gameObject.activeInHierarchy)
			{
				return true;
			}
			return false;
		}

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
			{
				return !float.IsInfinity(value.z);
			}
			return false;
		}

		internal static void PhysicsRigSetAvatarPrefix(Avatar avatar)
		{
			if (Prefs.enableSpiderStrength.Value)
			{
				float num = Prefs.upperProportionalStrengthPerc.Value / 100f * avatar.massTotal * Prefs.upperStrengthBoostMultiplier.Value;
				avatar._strengthUpper = Mathf.Max(num, avatar._strengthUpper);
				float num2 = Prefs.lowerProportionalStrengthPerc.Value / 100f * avatar.massTotal * Prefs.lowerStrengthBoostMultiplier.Value;
				avatar._strengthLower = Mathf.Max(num2, avatar._strengthLower);
			}
		}
	}
}
namespace SpiderLab.Utils
{
	public static class AssetBundleExtensions
	{
		public static T LoadAssetWithFlags<T>(this AssetBundle bundle, string name) where T : Object
		{
			T val = bundle.LoadAsset<T>(name);
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}
	}
	public struct BoolTimer
	{
		private float resetTime;

		public void Set(float time, bool overwrite = false)
		{
			if (overwrite)
			{
				resetTime = Time.time + time;
			}
			else
			{
				resetTime = Mathf.Max(resetTime, Time.time + time);
			}
		}

		public void Reset()
		{
			resetTime = Time.time - 1f;
		}

		public bool GetValue()
		{
			return Time.time <= resetTime;
		}

		public static implicit operator bool(BoolTimer bt)
		{
			return bt.GetValue();
		}
	}
	public static class ControllerInfo
	{
		public static bool GetTouchpadTouch(Handedness hand)
		{
			//IL_0000: 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_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (!TryGetXRController(hand, out var controller))
			{
				return false;
			}
			bool flag = controller.TouchpadTouch || controller.JoystickTouch;
			if ((int)controller.Type == 0 || (int)controller.Type == 4)
			{
				InputDevice xrDevice = ((XRDevice)controller)._xrDevice;
				bool flag2 = default(bool);
				if (((InputDevice)(ref xrDevice)).TryGetFeatureValue(CommonUsages.thumbrest, ref flag2))
				{
					flag = flag || flag2;
				}
			}
			return flag;
		}

		public static bool GetFaceButtonsTouch(Handedness hand)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetXRController(hand, out var controller))
			{
				return false;
			}
			if (controller.ATouch)
			{
				return controller.BTouch;
			}
			return false;
		}

		public static float GetTrigger(Handedness hand)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetXRController(hand, out var controller))
			{
				return 0f;
			}
			return controller.Trigger;
		}

		public static float GetGrip(Handedness hand)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetXRController(hand, out var controller))
			{
				return 0f;
			}
			return controller.Grip;
		}

		private unsafe static bool TryGetXRController(Handedness hand, out XRController controller)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)hand != 1)
			{
				if ((int)hand == 2)
				{
					controller = MarrowGame.xr.RightController;
					return true;
				}
				MelonLogger.Error("Invalid hand type: " + ((object)(*(Handedness*)(&hand))/*cast due to .constrained prefix*/).ToString());
				controller = null;
				return false;
			}
			controller = MarrowGame.xr.LeftController;
			return true;
		}
	}
	public static class GeneralExtensions
	{
		public static void MatchRotation(this ref Vector3 vector, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			vector = Vector3.RotateTowards(vector, target, maxRadiansDelta, maxMagnitudeDelta);
		}

		public static void PointTowards(this ref Vector3 vector, Vector3 target, float maxRadiansDelta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			vector = Vector3.RotateTowards(vector, target - vector, maxRadiansDelta, 0f);
		}

		public static GameObject CreateChild(this GameObject go, string name, Vector3 localPosition = default(Vector3))
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_003c: Expected O, but got Unknown
			//IL_0028: 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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(go.transform);
			if (localPosition == default(Vector3))
			{
				localPosition = Vector3.zero;
			}
			val.transform.localPosition = localPosition;
			return val;
		}

		public static bool IsStaticLayer(this GameObject obj)
		{
			return (obj.layer & 0x2000) > 0;
		}
	}
	public static class JointExtensions
	{
		public static Vector3 GetConnectedPoint(this ConfigurableJoint joint)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_002b: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)((Joint)joint).connectedBody != (Object)null)
			{
				return ((Component)((Joint)joint).connectedBody).transform.TransformPoint(((Joint)joint).connectedAnchor);
			}
			return ((Joint)joint).connectedAnchor;
		}

		public static void SetConnectedPoint(this ConfigurableJoint joint, Vector3 worldPoint)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			((Joint)joint).autoConfigureConnectedAnchor = false;
			if ((Object)((Joint)joint).connectedBody != (Object)null)
			{
				((Joint)joint).connectedAnchor = ((Component)((Joint)joint).connectedBody).transform.InverseTransformPoint(worldPoint);
			}
			else
			{
				((Joint)joint).connectedAnchor = worldPoint;
			}
		}

		public static Vector3 GetAnchorPoint(this ConfigurableJoint joint)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)joint).transform.TransformPoint(((Joint)joint).anchor);
		}

		public static void SetAnchorPoint(this ConfigurableJoint joint, Vector3 worldPoint)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((Joint)joint).anchor = ((Component)joint).transform.InverseTransformPoint(worldPoint);
		}

		public static Vector3 GetTargetPosition(this ConfigurableJoint joint)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)joint).transform.TransformPoint(joint.targetPosition);
		}

		public static void SetTargetPosition(this ConfigurableJoint joint, Vector3 worldPos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			joint.targetPosition = ((Component)joint).transform.InverseTransformPoint(worldPos);
		}

		public static void SetLinearLimit(this ConfigurableJoint joint, float limit, float bounciness)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			SoftJointLimit linearLimit = joint.linearLimit;
			((SoftJointLimit)(ref linearLimit)).limit = limit;
			((SoftJointLimit)(ref linearLimit)).bounciness = bounciness;
			joint.linearLimit = linearLimit;
		}

		public static void SetLinearMotion(this ConfigurableJoint joint, ConfigurableJointMotion motion)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			joint.xMotion = motion;
			joint.yMotion = motion;
			joint.zMotion = motion;
		}

		public static void SetSpringLimit(this ConfigurableJoint joint, float spring, float damper)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			SoftJointLimitSpring linearLimitSpring = joint.linearLimitSpring;
			((SoftJointLimitSpring)(ref linearLimitSpring)).spring = spring;
			((SoftJointLimitSpring)(ref linearLimitSpring)).damper = damper;
			joint.linearLimitSpring = linearLimitSpring;
		}

		public static void SetSpringDrive(this ConfigurableJoint joint, float spring, float damper, float max)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			JointDrive val = default(JointDrive);
			((JointDrive)(ref val)).positionSpring = spring;
			((JointDrive)(ref val)).positionDamper = damper;
			((JointDrive)(ref val)).maximumForce = max;
			joint.xDrive = val;
			joint.yDrive = val;
			joint.zDrive = val;
		}
	}
}
namespace SpiderLab.Preferences
{
	public enum HandGesture
	{
		SPIDEY,
		GRIP
	}
	internal static class Prefs
	{
		public static MelonPreferences_Entry<bool> enableAimReticle;

		public static MelonPreferences_Entry<bool> enableWallCrawling;

		public static MelonPreferences_Entry<HandGesture> selectedGesture;

		public static MelonPreferences_Entry<WeblineInput> weblineInput;

		public static MelonPreferences_Entry<bool> enableWebSwinging;

		public static MelonPreferences_Entry<float> webzipPullSpeedMin;

		public static MelonPreferences_Entry<float> webzipStrengthMultiplier;

		public static MelonPreferences_Entry<bool> enableWebzipWallAutoGrab;

		public static MelonPreferences_Entry<bool> enableTargetPulling;

		public static MelonPreferences_Entry<float> targetPullStrengthMultiplier;

		public static MelonPreferences_Entry<float> targetPullGestureSpeedMin;

		public static MelonPreferences_Entry<bool> enableTargetAutoCatch;

		public static MelonPreferences_Entry<float> targetAutoCatchDistance;

		public static MelonPreferences_Entry<bool> enableSpiderStrength;

		public static MelonPreferences_Entry<float> upperStrengthBoostMultiplier;

		public static MelonPreferences_Entry<float> upperProportionalStrengthPerc;

		public static MelonPreferences_Entry<float> lowerStrengthBoostMultiplier;

		public static MelonPreferences_Entry<float> lowerProportionalStrengthPerc;

		public static MelonPreferences_Category prefsCategory;

		public static Page menuCategory;

		public static bool WebShootersEnabled => enableWebSwinging.Value;

		public static float WebzipPullSpeedMax => webzipPullSpeedMin.Value + 1f;

		public static float WebzipImpulseSpeed => 50f * webzipStrengthMultiplier.Value;

		public static float TargetPullImpulseSpeed => 12f * targetPullStrengthMultiplier.Value;

		public static void Initialize()
		{
			prefsCategory = MelonPreferences.CreateCategory("SpiderLab");
			selectedGesture = prefsCategory.CreateEntry<HandGesture>("Hand Gesture", HandGesture.GRIP, (string)null, "Required hand gesture for Webshooter inputs to register (SPIDEY, GRIP) (SPIDEY gesture requires finger tracking!)", false, false, (ValueValidator)null, (string)null);
			weblineInput = prefsCategory.CreateEntry<WeblineInput>("Webline Input", WeblineInput.DOUBLE_TRIGGER_OR_GRIP, (string)null, "Choose DOUBLE_TRIGGER, DOUBLE_GRIP, DOUBLE_TRIGGER_OR_GRIP, a legacy input, or DISABLED. Double-trigger still uses the selected hand gesture; double-grip uses the grip itself.", false, false, (ValueValidator)null, (string)null);
			enableWallCrawling = prefsCategory.CreateEntry<bool>("Enable Wall Crawling", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			enableWebSwinging = prefsCategory.CreateEntry<bool>("Enable Web Swinging", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			enableSpiderStrength = prefsCategory.CreateEntry<bool>("Enable Spider Strength", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			upperStrengthBoostMultiplier = prefsCategory.CreateEntry<float>("Upper Strength Boost Multiplier", 1f, (string)null, "Controls the how strong the upper-body strength boost is", false, false, (ValueValidator)null, (string)null);
			upperProportionalStrengthPerc = prefsCategory.CreateEntry<float>("Upper Proportional Strength Percentage", 5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			lowerStrengthBoostMultiplier = prefsCategory.CreateEntry<float>("Lower Strength Boost Multiplier", 1f, (string)null, "Controls the how strong the lower-body strength boost is", false, false, (ValueValidator)null, (string)null);
			lowerProportionalStrengthPerc = prefsCategory.CreateEntry<float>("Lower Proportional Strength Percentage", 3.45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			webzipPullSpeedMin = prefsCategory.CreateEntry<float>("WebZip Minimum Pull Speed", 4f, (string)null, "Minimum pull speed for WebZip to kick in (m/s)", false, false, (ValueValidator)null, (string)null);
			webzipStrengthMultiplier = prefsCategory.CreateEntry<float>("WebZip Strength Multiplier", 1f, (string)null, "Controls how strong a maxxed WebZip is", false, false, (ValueValidator)null, (string)null);
			enableWebzipWallAutoGrab = prefsCategory.CreateEntry<bool>("Enable WebZip Wall Auto Grab", true, (string)null, "Automatically switch from the webline to BONELAB's normal world grip when the empty web-shooting hand reaches the webbed wall.", false, false, (ValueValidator)null, (string)null);
			enableTargetPulling = prefsCategory.CreateEntry<bool>("Enable Target Pulling", true, (string)null, "Pull movable props, NPC bodies, and synchronized player bodies toward you when you yank a webline.", false, false, (ValueValidator)null, (string)null);
			targetPullStrengthMultiplier = prefsCategory.CreateEntry<float>("Target Pull Strength Multiplier", 4f, (string)null, "Controls how quickly movable webbed targets are pulled toward your chest.", false, false, (ValueValidator)null, (string)null);
			targetPullGestureSpeedMin = prefsCategory.CreateEntry<float>("Target Pull Minimum Hand Speed", 3f, (string)null, "Minimum backward hand speed required to yank a movable webbed target.", false, false, (ValueValidator)null, (string)null);
			enableTargetAutoCatch = prefsCategory.CreateEntry<bool>("Enable Target Auto Catch", true, (string)null, "Automatically catch any normally grabbable web-pulled item when its grip or surface reaches the web-shooting hand.", false, false, (ValueValidator)null, (string)null);
			targetAutoCatchDistance = prefsCategory.CreateEntry<float>("Target Auto Catch Distance", 0.45f, (string)null, "Maximum grip distance in meters before a pulled item is caught. Surface-contact catching uses a smaller hand-sized radius.", false, false, (ValueValidator)null, (string)null);
			enableAimReticle = prefsCategory.CreateEntry<bool>("Enable Aiming Reticle", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			SetupBoneMenu();
			prefsCategory.SaveToFile(false);
		}

		private static void SetupBoneMenu()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			menuCategory = Page.Root.CreatePage("SpiderLab", Color.red, 0, true);
			Page obj = menuCategory.CreatePage("Input", Color.white, 0, true);
			obj.CreateEnum(((MelonPreferences_Entry)selectedGesture).Identifier, Color.white, (Enum)selectedGesture.Value, (Action<Enum>)delegate(Enum gesture)
			{
				selectedGesture.Value = (HandGesture)(object)gesture;
			});
			obj.CreateEnum(((MelonPreferences_Entry)weblineInput).Identifier, Color.white, (Enum)weblineInput.Value, (Action<Enum>)delegate(Enum webInput)
			{
				weblineInput.Value = (WeblineInput)(object)webInput;
			});
			Page obj2 = menuCategory.CreatePage("Web Swinging", Color.white, 0, true);
			obj2.CreateBool(((MelonPreferences_Entry)enableAimReticle).Identifier, Color.white, enableAimReticle.Value, (Action<bool>)delegate(bool value)
			{
				enableAimReticle.Value = value;
			});
			obj2.CreateBool(((MelonPreferences_Entry)enableWebSwinging).Identifier, Color.white, enableWebSwinging.Value, (Action<bool>)delegate(bool value)
			{
				enableWebSwinging.Value = value;
			});
			obj2.CreateFloat(((MelonPreferences_Entry)webzipPullSpeedMin).Identifier, Color.white, webzipPullSpeedMin.Value, 0.5f, 0f, 10f, (Action<float>)delegate(float value)
			{
				webzipPullSpeedMin.Value = value;
			});
			obj2.CreateFloat(((MelonPreferences_Entry)webzipStrengthMultiplier).Identifier, Color.white, webzipStrengthMultiplier.Value, 0.2f, 0f, 10f, (Action<float>)delegate(float value)
			{
				webzipStrengthMultiplier.Value = value;
			});
			obj2.CreateBool(((MelonPreferences_Entry)enableWebzipWallAutoGrab).Identifier, Color.white, enableWebzipWallAutoGrab.Value, (Action<bool>)delegate(bool value)
			{
				enableWebzipWallAutoGrab.Value = value;
			});
			obj2.CreateBool(((MelonPreferences_Entry)enableTargetPulling).Identifier, Color.white, enableTargetPulling.Value, (Action<bool>)delegate(bool value)
			{
				enableTargetPulling.Value = value;
			});
			obj2.CreateFloat(((MelonPreferences_Entry)targetPullStrengthMultiplier).Identifier, Color.white, targetPullStrengthMultiplier.Value, 0.1f, 0f, 5f, (Action<float>)delegate(float value)
			{
				targetPullStrengthMultiplier.Value = value;
			});
			obj2.CreateFloat(((MelonPreferences_Entry)targetPullGestureSpeedMin).Identifier, Color.white, targetPullGestureSpeedMin.Value, 0.25f, 0.5f, 5f, (Action<float>)delegate(float value)
			{
				targetPullGestureSpeedMin.Value = value;
			});
			obj2.CreateBool(((MelonPreferences_Entry)enableTargetAutoCatch).Identifier, Color.white, enableTargetAutoCatch.Value, (Action<bool>)delegate(bool value)
			{
				enableTargetAutoCatch.Value = value;
			});
			obj2.CreateFloat(((MelonPreferences_Entry)targetAutoCatchDistance).Identifier, Color.white, targetAutoCatchDistance.Value, 0.05f, 0.15f, 1f, (Action<float>)delegate(float value)
			{
				targetAutoCatchDistance.Value = value;
			});
			Page obj3 = menuCategory.CreatePage("Spider Strength", Color.white, 0, true);
			obj3.CreateBool(((MelonPreferences_Entry)enableSpiderStrength).Identifier, Color.white, enableSpiderStrength.Value, (Action<bool>)delegate(bool value)
			{
				enableSpiderStrength.Value = value;
			});
			obj3.CreateFunction("Update Stats", Color.yellow, (Action)UpdateStrengthStats);
			Page obj4 = obj3.CreatePage("Upper Strength", Color.white, 0, true);
			obj4.CreateFloat("Strength Boost Multiplier", Color.white, upperStrengthBoostMultiplier.Value, 0.1f, 0f, 100f, (Action<float>)delegate(float value)
			{
				upperStrengthBoostMultiplier.Value = value;
			});
			obj4.CreateFloat("Proportional Strength Percentage", Color.white, upperProportionalStrengthPerc.Value, 1f, 0f, 100f, (Action<float>)delegate(float value)
			{
				upperProportionalStrengthPerc.Value = value;
			});
			Page obj5 = obj3.CreatePage("Lower Strength", Color.white, 0, true);
			obj5.CreateFloat("Strength Boost Multiplier", Color.white, lowerStrengthBoostMultiplier.Value, 0.1f, 0f, 100f, (Action<float>)delegate(float value)
			{
				lowerStrengthBoostMultiplier.Value = value;
			});
			obj5.CreateFloat("Proportional Strength Percentage", Color.white, lowerProportionalStrengthPerc.Value, 1f, 0f, 100f, (Action<float>)delegate(float value)
			{
				lowerProportionalStrengthPerc.Value = value;
			});
			menuCategory.CreateBool(((MelonPreferences_Entry)enableWallCrawling).Identifier, Color.white, enableWallCrawling.Value, (Action<bool>)delegate(bool value)
			{
				enableWallCrawling.Value = value;
			});
		}

		public static void UpdateStrengthStats()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			Avatar avatar = Player.Avatar;
			if ((Object)avatar != (Object)null)
			{
				Patches.PhysicsRigSetAvatarPrefix(avatar);
			}
		}
	}
	public enum WeblineInput
	{
		TOUCHPAD,
		DOUBLE_TOUCHPAD,
		DOUBLE_GESTURE,
		DOUBLE_TRIGGER,
		DOUBLE_TOUCH_BUTTONS,
		DOUBLE_GRIP,
		DOUBLE_TRIGGER_OR_GRIP,
		DISABLED
	}
}
namespace SpiderLab.Data
{
	public static class Bundles
	{
		public static AssetBundle spiderLabBundle;

		public static GameObject webLinePrefab;

		public static GameObject webShooterReticlePrefab;

		public static AudioClip webLineAudioLow;

		public static AudioClip webLineAudioHigh;

		public static AudioClip webShotAudioLow;

		public static AudioClip webShotAudioHigh;

		public static void LoadAssets()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (HelperMethods.IsAndroid())
			{
				CreateAndroidSafeAssets();
				return;
			}
			spiderLabBundle = EmebeddedAssetBundle.LoadFromAssembly(Assembly.GetExecutingAssembly(), "SpiderLab.src.Data.spiderlab.bundle");
			if ((Object)spiderLabBundle == (Object)null)
			{
				throw new NullReferenceException("SpiderLab bundle is null! Did you forget to compile the bundle into the dll?");
			}
			webLinePrefab = spiderLabBundle.LoadAssetWithFlags<GameObject>("prefabs/webline");
			webShooterReticlePrefab = spiderLabBundle.LoadAssetWithFlags<GameObject>("prefabs/webshooterreticle");
			webLineAudioHigh = spiderLabBundle.LoadAssetWithFlags<AudioClip>("audio/webline_high");
			webLineAudioLow = spiderLabBundle.LoadAssetWithFlags<AudioClip>("audio/webline_low");
			webShotAudioHigh = spiderLabBundle.LoadAssetWithFlags<AudioClip>("audio/webshot_high");
			webShotAudioLow = spiderLabBundle.LoadAssetWithFlags<AudioClip>("audio/webshot_low");
			spiderLabBundle.Unload(false);
		}

		private static void CreateAndroidSafeAssets()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			Material val = CreateRuntimeMaterial("SpiderLab Quest Web Material", Color.white);
			Material val2 = CreateRuntimeMaterial("SpiderLab Quest Reticle Material", new Color(0.25f, 0.85f, 1f, 0.9f));
			webLinePrefab = new GameObject("SpiderLab Quest WebLine Prefab");
			Object.DontDestroyOnLoad((Object)(object)webLinePrefab);
			LineRenderer val3 = webLinePrefab.AddComponent<LineRenderer>();
			val3.useWorldSpace = true;
			val3.positionCount = 2;
			val3.startWidth = 0.012f;
			val3.endWidth = 0.008f;
			val3.numCapVertices = 4;
			val3.startColor = Color.white;
			val3.endColor = new Color(0.78f, 0.9f, 1f, 1f);
			if ((Object)val != (Object)null)
			{
				((Renderer)val3).sharedMaterial = val;
			}
			((Renderer)val3).enabled = false;
			webShooterReticlePrefab = new GameObject("SpiderLab Quest Reticle Prefab");
			Object.DontDestroyOnLoad((Object)(object)webShooterReticlePrefab);
			LineRenderer val4 = webShooterReticlePrefab.AddComponent<LineRenderer>();
			val4.useWorldSpace = false;
			val4.loop = true;
			val4.positionCount = 24;
			val4.startWidth = 0.0035f;
			val4.endWidth = 0.0035f;
			val4.numCapVertices = 2;
			val4.startColor = new Color(0.25f, 0.85f, 1f, 0.9f);
			val4.endColor = val4.startColor;
			if ((Object)val2 != (Object)null)
			{
				((Renderer)val4).sharedMaterial = val2;
			}
			for (int i = 0; i < val4.positionCount; i++)
			{
				float num = (float)i / (float)val4.positionCount * (float)Math.PI * 2f;
				val4.SetPosition(i, new Vector3(Mathf.Cos(num) * 0.035f, Mathf.Sin(num) * 0.035f, 0f));
			}
			webShooterReticlePrefab.SetActive(false);
			webLineAudioLow = null;
			webLineAudioHigh = null;
			webShotAudioLow = null;
			webShotAudioHigh = null;
			MelonLogger.Msg("Quest standalone detected: using Android-safe runtime web visuals; bundled PC web audio was skipped.");
		}

		private static Material CreateRuntimeMaterial(string name, Color color)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0077: Expected O, but got Unknown
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)val == (Object)null)
			{
				val = Shader.Find("Universal Render Pipeline/Unlit");
			}
			if ((Object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Color");
			}
			if ((Object)val == (Object)null)
			{
				MelonLogger.Warning("Quest runtime web shader was unavailable; LineRenderer will use Unity's fallback material.");
				return null;
			}
			Material val2 = new Material(val)
			{
				name = name,
				color = color
			};
			Object.DontDestroyOnLoad((Object)val2);
			return val2;
		}
	}
	public static class EmebeddedAssetBundle
	{
		public static AssetBundle LoadFromAssembly(Assembly assembly, string name)
		{
			if (assembly.GetManifestResourceNames().Contains(name))
			{
				MelonLogger.Msg(ConsoleColor.DarkCyan, "Loading embedded bundle " + name + "...");
				byte[] array;
				using (Stream stream = assembly.GetManifestResourceStream(name))
				{
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
				MelonLogger.Msg(ConsoleColor.DarkCyan, "Done!");
				return AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(array));
			}
			MelonLogger.Warning("Missing embedded bundle " + name);
			return null;
		}
	}
	internal static class ExternalWebMaterial
	{
		private const string ProviderFileName = "Spidermanihatemyself1327.dll";

		private const string ProviderDirectoryName = "SpiderLabAssets";

		private const string BundleResourceBase = "Spiderman.Resources.spiderfx.sres";

		private const string WebRendererAssetName = "SpiderWeb_Renderer";

		public static string ProviderPath => Path.Combine(MelonEnvironment.UserDataDirectory, "SpiderLabAssets", "Spidermanihatemyself1327.dll");

		public static bool TryApply()
		{
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			if (!File.Exists(ProviderPath))
			{
				MelonLogger.Msg("Optional ihatemyself1327 web material not found at " + ProviderPath + "; using the bundled SpiderLab web material.");
				return false;
			}
			AssetBundle val = null;
			try
			{
				Assembly assembly = Assembly.Load(File.ReadAllBytes(ProviderPath));
				string text = "Spiderman.Resources.spiderfx.sres" + (HelperMethods.IsAndroid() ? ".android" : ".pc");
				using Stream stream = assembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					MelonLogger.Warning("The optional web-material provider does not contain " + text + ".");
					return false;
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				val = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray()));
				if ((Object)val == (Object)null)
				{
					MelonLogger.Warning("The optional ihatemyself1327 web-material bundle could not be loaded.");
					return false;
				}
				GameObject val2 = val.LoadAsset<GameObject>("SpiderWeb_Renderer");
				LineRenderer val3 = (((Object)val2 == (Object)null) ? null : val2.GetComponent<LineRenderer>());
				LineRenderer val4 = (((Object)Bundles.webLinePrefab == (Object)null) ? null : Bundles.webLinePrefab.GetComponent<LineRenderer>());
				Material val5 = (((Object)val3 == (Object)null) ? null : ((Renderer)val3).sharedMaterial);
				if ((Object)val5 == (Object)null || (Object)val4 == (Object)null)
				{
					MelonLogger.Warning("The optional web-material provider is missing its SpiderWeb_Renderer material.");
					return false;
				}
				Material val6 = Object.Instantiate<Material>(val5);
				((Object)val6).name = "SpiderLab Web Material (ihatemyself1327 provider)";
				((Object)val6).hideFlags = (HideFlags)32;
				Object.DontDestroyOnLoad((Object)val6);
				((Renderer)val4).sharedMaterial = val6;
				MelonLogger.Msg("Applied ihatemyself1327's optional SpiderWeb_Renderer material to SpiderLab web lines.");
				return true;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Could not apply the optional ihatemyself1327 web material: " + ex.Message);
				return false;
			}
			finally
			{
				if ((Object)val != (Object)null)
				{
					val.Unload(false);
				}
			}
		}
	}
}
namespace SpiderLab.Behaviours
{
	[RegisterTypeInIl2Cpp]
	public class AirControl : MonoBehaviour
	{
		private RigManager rigMan;

		public AirControl(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			rigMan = Player.RigManager;
		}

		private void FixedUpdate()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_007f: 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_008e: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)rigMan.activeSeat != (Object)null) && !rigMan.physicsRig.physG.isGrounded)
			{
				Vector2 val = (Player.ControllerRig.isRightHanded ? Player.LeftHand.Controller.GetThumbStickAxis() : Player.RightHand.Controller.GetThumbStickAxis());
				Vector3 val2 = Player.ControllerRig.directionMasterTransform.rotation * new Vector3(val.x, 0f, val.y) * 12f;
				rigMan.physicsRig.torso.rbChest.AddForce(val2, (ForceMode)5);
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	public class WebLine : MonoBehaviour
	{
		public Vector3 anchorPoint;

		public Vector3 connectedPoint;

		private LineRenderer lRenderer;

		private void EnsureRenderer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)lRenderer == (Object)null)
			{
				lRenderer = ((Component)this).GetComponent<LineRenderer>();
			}
		}

		public WebLine(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Start()
		{
			EnsureRenderer();
		}

		public void SetActive(bool value)
		{
			EnsureRenderer();
			((Renderer)lRenderer).enabled = value;
		}

		public void UpdateLine(Vector3 anchorPoint, Vector3 connectedPoint)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			this.anchorPoint = anchorPoint;
			this.connectedPoint = connectedPoint;
			UpdateLine();
		}

		public void UpdateLine()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			EnsureRenderer();
			lRenderer.SetPosition(0, anchorPoint);
			lRenderer.SetPosition(1, connectedPoint);
		}

		public Vector3 GetLineSegment()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return connectedPoint - anchorPoint;
		}

		public Vector3 GetNormal()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Vector3 lineSegment = GetLineSegment();
			return ((Vector3)(ref lineSegment)).normalized;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class WebShooter : MonoBehaviour
	{
		private const float YOUNGS_MODULUS = 2E+11f;

		private const float WEB_CROSS_SECTIONAL_AREA = 0.0001767f;

		private const float LINEAR_SPRING_CONSTANT = 1372344f / (float)Math.E;

		private const float LINEAR_SPRING_DAMPER = 50485.715f;

		private float WEB_BREAK_FORCE = 1000000f;

		private const float MAX_WEB_RANGE = 100000f;

		private const float LINEAR_DRIVE_SPRING = 500f;

		private const float LINEAR_DRIVE_DAMPER = 1f;

		private const float LINEAR_DRIVE_MAX = 2500f;

		private const float WALL_AUTO_GRAB_DISTANCE = 0.18f;

		private const float FLOOR_NORMAL_DOT_MIN = 0.55f;

		public bool doWebWrapping;

		private LayerMask layerMask = LayerMask.op_Implicit(46081);

		private WebLine webLine;

		private Hand hand;

		private Transform aimReticle;

		private AudioSource audioSource;

		private float webLine_lowestLength;

		private ConfigurableJoint webJoint;

		private Collider webbedCollider;

		private bool webActive;

		private BoolTimer isWebShotBtnPressMomentary;

		private BoolTimer weblineDoubleTap;

		private bool weblineLastDoubleTapState;

		private BoolTimer triggerDoubleTap;

		private bool triggerLastDoubleTapState;

		private BoolTimer gripDoubleTap;

		private bool gripLastDoubleTapState;

		private BoolTimer webzipCooldown;

		private Vector3 lastControllerPos;

		private const int ROLLING_AVERAGE_VELOCITY_MAX = 8;

		private Vector3[] controllerVelocities = (Vector3[])(object)new Vector3[8];

		private int rollingAverageVelIndex;

		private bool initialized;

		private ForcePullGrip pendingAutoCatch;

		private Grip pendingAutoCatchGrip;

		private int pendingAutoCatchFrame;

		private bool pendingAutoCatchIsPlayer;

		[HideFromIl2Cpp]
		public Hand Hand => hand;

		[HideFromIl2Cpp]
		public static event Action<WebShooter, RaycastHit> WebCreated;

		[HideFromIl2Cpp]
		public static event Action<WebShooter> WebDestroyed;

		[HideFromIl2Cpp]
		public static event Action<WebShooter, Rigidbody, Vector3> TargetPulled;

		[HideFromIl2Cpp]
		public static event Func<WebShooter, Rigidbody, float, bool> TargetPullIntercepted;

		public WebShooter(IntPtr ptr)
			: base(ptr)
		{
		}//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)


		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			hand = ((Component)this).GetComponent<Hand>();
			if ((Object)hand == (Object)null || (Object)Bundles.webLinePrefab == (Object)null || (Object)Bundles.webShooterReticlePrefab == (Object)null)
			{
				MelonLogger.Error("WebShooter could not initialize because its hand or embedded prefabs are unavailable.");
				return;
			}
			webLine = Object.Instantiate<GameObject>(Bundles.webLinePrefab, ((Component)this).transform).AddComponent<WebLine>();
			aimReticle = Object.Instantiate<GameObject>(Bundles.webShooterReticlePrefab).transform;
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			audioSource.playOnAwake = false;
			audioSource.minDistance = 0.5f;
			audioSource.spatialBlend = 1f;
			initialized = true;
		}

		private void LateUpdate()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if (!initialized)
			{
				return;
			}
			if (IsWebInputBlocked())
			{
				((Component)aimReticle).gameObject.SetActive(false);
				if (IsWebAttatched())
				{
					DestroyWebJoint();
				}
				ResetWebInputTimers();
			}
			else if ((Object)pendingAutoCatch != (Object)null || (Object)pendingAutoCatchGrip != (Object)null)
			{
				UpdatePendingAutoCatch();
			}
			else if (!Prefs.WebShootersEnabled)
			{
				((Component)aimReticle).gameObject.SetActive(false);
				if (IsWebAttatched())
				{
					DestroyWebJoint();
				}
			}
			else if (IsWebAttatched())
			{
				UpdateWeb();
			}
			else
			{
				if (webActive)
				{
					DestroyWebJoint();
				}
				webLine.SetActive(value: false);
				HandleAiming();
			}
		}

		private void UpdateWeb()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_00aa: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0193: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = webJoint.GetConnectedPoint();
			Vector3 anchorPoint = webJoint.GetAnchorPoint();
			Vector3 val2;
			if (doWebWrapping)
			{
				val2 = val - anchorPoint;
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(anchorPoint, ((Vector3)(ref val2)).normalized, ref val3, 100000f, ((LayerMask)(ref layerMask)).value, (QueryTriggerInteraction)1) && ((Component)((RaycastHit)(ref val3)).collider).gameObject.isStatic && (((RaycastHit)(ref val3)).colliderInstanceID != ((Object)webbedCollider).GetInstanceID() || Vector3.Distance(((RaycastHit)(ref val3)).point, val) > 0.01f))
				{
					((Joint)webJoint).connectedBody = ((RaycastHit)(ref val3)).rigidbody;
					webJoint.SetConnectedPoint(((RaycastHit)(ref val3)).point);
					val = ((RaycastHit)(ref val3)).point;
				}
			}
			webLine.UpdateLine(hand.palmPositionTransform.position, val);
			val2 = val - anchorPoint;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			if (magnitude < webLine_lowestLength)
			{
				webJoint.SetLinearLimit(magnitude, 1f);
				webLine_lowestLength = magnitude;
			}
			if ((Object)webbedCollider == (Object)null || !((Component)webbedCollider).gameObject.activeInHierarchy)
			{
				DestroyWebJoint();
				return;
			}
			Rigidbody attachedRigidbody = webbedCollider.attachedRigidbody;
			float num = (((Object)Player.Avatar == (Object)null) ? 75f : Mathf.Max(Player.Avatar.massTotal, 1f));
			bool flag = IsPlayerRigBody(attachedRigidbody);
			bool flag2 = Prefs.enableTargetPulling.Value && (Object)attachedRigidbody != (Object)null && attachedRigidbody.mass < num * 10f && !IsLocalPlayerBody(attachedRigidbody);
			bool flag3 = flag2 && !attachedRigidbody.isKinematic;
			if ((flag && TryAutoCatchPlayer(attachedRigidbody)) || (flag3 && TryAutoCatchTarget(attachedRigidbody)) || (!flag3 && !flag && TryAutoGrabWebbedWall(attachedRigidbody)))
			{
				return;
			}
			float minimumPullSpeed = (flag2 ? Prefs.targetPullGestureSpeedMin.Value : Prefs.webzipPullSpeedMin.Value);
			if (IsYanking(out var intensity, minimumPullSpeed))
			{
				bool flag4 = false;
				if (flag2 && TryInterceptTargetPull(attachedRigidbody, intensity))
				{
					return;
				}
				if (flag3)
				{
					flag4 = PullTargetTowardPlayer(attachedRigidbody, intensity);
				}
				else if ((Object)attachedRigidbody == (Object)null || attachedRigidbody.isKinematic || attachedRigidbody.mass >= num * 10f)
				{
					float num2 = Prefs.WebzipImpulseSpeed * intensity;
					Player.RigManager.physicsRig.torso.rbChest.AddForce(webLine.GetNormal() * num2, (ForceMode)2);
					flag4 = true;
				}
				if (flag4)
				{
					hand.Controller.haptor.Haptic_Knock();
					webzipCooldown.Set(1f);
				}
			}
			if (!IsPlayerGesturing(HandGesture.GRIP))
			{
				DestroyWebJoint();
			}
		}

		[HideFromIl2Cpp]
		public bool ResumeTargetPull(Rigidbody targetBody, float intensity)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0058: Expected O, but got Unknown
			if (!initialized || !webActive || !Prefs.enableTargetPulling.Value || (Object)targetBody == (Object)null || (Object)webbedCollider == (Object)null || (Object)webbedCollider.attachedRigidbody != (Object)targetBody || IsLocalPlayerBody(targetBody))
			{
				return false;
			}
			bool num = PullTargetTowardPlayer(targetBody, Mathf.Clamp01(intensity));
			if (num)
			{
				hand.Controller.haptor.Haptic_Knock();
				webzipCooldown.Set(1f);
			}
			return num;
		}

		private bool TryInterceptTargetPull(Rigidbody targetBody, float intensity)
		{
			Delegate[] array = WebShooter.TargetPullIntercepted?.GetInvocationList();
			if (array == null)
			{
				return false;
			}
			Delegate[] array2 = array;
			foreach (Delegate obj in array2)
			{
				try
				{
					if (((Func<WebShooter, Rigidbody, float, bool>)obj)(this, targetBody, intensity))
					{
						return true;
					}
				}
				catch (Exception value)
				{
					MelonLogger.Error($"Target pull interceptor failed: {value}");
				}
			}
			return false;
		}

		private bool TryAutoGrabWebbedWall(Rigidbody targetBody)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0116: 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)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if (!Prefs.enableWebzipWallAutoGrab.Value || !Prefs.enableWallCrawling.Value || hand.HasAttachedObject() || !IsPlayerGesturing(HandGesture.GRIP))
			{
				return false;
			}
			if ((Object)targetBody != (Object)null && (!targetBody.isKinematic || (Object)((Component)targetBody).GetComponentInParent<InteractableHost>() != (Object)null || (Object)((Component)targetBody).GetComponentInChildren<Grip>() != (Object)null))
			{
				return false;
			}
			Vector3 position = hand.palmPositionTransform.position;
			Vector3 val = webbedCollider.ClosestPoint(position);
			if (Vector3.Distance(position, val) > 0.18f)
			{
				return false;
			}
			WorldGrip worldGrip = Player.RigManager.worldGrip;
			if ((Object)worldGrip == (Object)null || worldGrip.genericHandStates == null)
			{
				return false;
			}
			((HandReciever)worldGrip).OnHandHoverUpdate(hand);
			HandToGenericGripState val2 = default(HandToGenericGripState);
			if (!worldGrip.genericHandStates.TryGetValue(hand, ref val2) || val2 == null || !val2.isRaycastHit || Vector3.Distance(position, val2.raycastPoint) > 0.18f)
			{
				return false;
			}
			Vector3 val3 = val2.raycastNormal;
			if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
			{
				val3 = position - val2.raycastPoint;
			}
			if (((Vector3)(ref val3)).sqrMagnitude > 0.001f && Vector3.Dot(((Vector3)(ref val3)).normalized, Vector3.up) >= 0.55f)
			{
				return false;
			}
			DestroyWebJoint();
			((Grip)worldGrip).Snatch(hand, true);
			hand.Controller.haptor.Haptic_Knock();
			return true;
		}

		private bool IsYanking(out float intensity, float minimumPullSpeed)
		{
			//IL_000a: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			//IL_0067: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			//IL_00ce: 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_00da: 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)
			Vector3 val = Player.ControllerRig.vrRoot.rotation * ((((Component)hand.Controller).transform.localPosition - lastControllerPos) / Time.deltaTime);
			lastControllerPos = ((Component)hand.Controller).transform.localPosition;
			controllerVelocities[rollingAverageVelIndex] = val;
			rollingAverageVelIndex = (rollingAverageVelIndex + 1) % 8;
			intensity = 0f;
			if ((bool)webzipCooldown)
			{
				return false;
			}
			Vector3 val2 = Vector3.zero;
			Vector3[] array = controllerVelocities;
			foreach (Vector3 val3 in array)
			{
				val2 += val3;
			}
			val2 /= (float)controllerVelocities.Length;
			if (Vector3.Dot(-webLine.GetNormal(), ((Vector3)(ref val2)).normalized) >= 0.4f && ((Vector3)(ref val2)).sqrMagnitude >= minimumPullSpeed * minimumPullSpeed)
			{
				float num = Mathf.InverseLerp(minimumPullSpeed, minimumPullSpeed + 1f, ((Vector3)(ref val2)).magnitude);
				intensity = 1f - Mathf.Pow(1f - Mathf.Clamp01(num), 3f);
				return true;
			}
			return false;
		}

		private static bool IsLocalPlayerBody(Rigidbody body)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			if ((Object)body == (Object)null || (Object)Player.RigManager == (Object)null)
			{
				return false;
			}
			return (Object)((Component)body).transform.root == (Object)((Component)Player.RigManager).transform.root;
		}

		private static bool IsPlayerRigBody(Rigidbody body)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if ((Object)body == (Object)null)
			{
				return false;
			}
			if ((Object)((Component)body).GetComponentInParent<RigManager>() != (Object)null)
			{
				return true;
			}
			Transform root = ((Component)body).transform.root;
			if ((Object)root == (Object)null)
			{
				return false;
			}
			string name = ((Object)root).name;
			if (!name.StartsWith("[RigManager (Networked)]", StringComparison.Ordinal))
			{
				return name.StartsWith("[RigManager (FUSION PlayerRep)]", StringComparison.Ordinal);
			}
			return true;
		}

		private bool PullTargetTowardPlayer(Rigidbody targetBody, float intensity)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody rbChest = Player.RigManager.physicsRig.torso.rbChest;
			if ((Object)rbChest == (Object)null || (Object)targetBody == (Object)null)
			{
				return false;
			}
			Vector3 val = rbChest.worldCenterOfMass - targetBody.worldCenterOfMass;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude <= 0.25f)
			{
				return false;
			}
			Vector3 val2 = val / magnitude;
			float num = Mathf.Min(Prefs.TargetPullImpulseSpeed * intensity, magnitude * 2.5f);
			float num2 = Vector3.Dot(targetBody.velocity, val2);
			float num3 = Mathf.Clamp(num - num2, 0f, Prefs.TargetPullImpulseSpeed);
			if (num3 <= 0.01f)
			{
				return false;
			}
			Vector3 val3 = val2 * num3;
			if (!targetBody.isKinematic)
			{
				targetBody.AddForce(val3, (ForceMode)2);
			}
			WebShooter.TargetPulled?.Invoke(this, targetBody, val3);
			return true;
		}

		private bool TryAutoCatchTarget(Rigidbody targetBody)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (!Prefs.enableTargetAutoCatch.Value || hand.HasAttachedObject() || (Object)Player.GetObjectInHand(hand) != (Object)null || TargetHasAttachedHands(targetBody))
			{
				return false;
			}
			if (!TryFindAutoCatchGrip(targetBody, out var forcePullGrip, out var grip) || grip.HasAttachedHands())
			{
				return false;
			}
			if (!IsAutoCatchInRange(targetBody, grip))
			{
				return false;
			}
			pendingAutoCatch = forcePullGrip;
			pendingAutoCatchGrip = grip;
			pendingAutoCatchFrame = Time.frameCount + 2;
			pendingAutoCatchIsPlayer = false;
			DestroyWebJoint();
			return true;
		}

		private static bool TargetHasAttachedHands(Rigidbody targetBody)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00d6: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00b9: Expected O, but got Unknown
			if ((Object)targetBody == (Object)null)
			{
				return false;
			}
			InteractableHost val = ((Component)targetBody).GetComponentInParent<InteractableHost>();
			if ((Object)val == (Object)null)
			{
				val = ((Component)targetBody).GetComponentInChildren<InteractableHost>();
			}
			Transform obj = (((Object)val != (Object)null) ? ((Component)val).transform : ((Component)targetBody).transform.root);
			GameObject val2 = (((Object)val != (Object)null) ? ((Component)val).gameObject : null);
			foreach (Grip componentsInChild in ((Component)obj).GetComponentsInChildren<Grip>(true))
			{
				if (!((Object)componentsInChild == (Object)null) && ((HandReciever)componentsInChild).HasHost && (((Object)val2 != (Object)null) ? ((Object)((HandReciever)componentsInChild).Host.GetHostGameObject() == (Object)val2) : ((Object)((HandReciever)componentsInChild).Host.Rb == (Object)targetBody)) && componentsInChild.HasAttachedHands())
				{
					return true;
				}
			}
			return false;
		}

		private bool TryAutoCatchPlayer(Rigidbody targetBody)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (!Prefs.enableTargetAutoCatch.Value || hand.HasAttachedObject() || (Object)Player.GetObjectInHand(hand) != (Object)null)
			{
				return false;
			}
			if (!TryFindAutoCatchGrip(targetBody, out var _, out var grip) || grip.HasAttachedHands() || !IsPlayerGrip(grip))
			{
				return false;
			}
			if (!IsAutoCatchInRange(targetBody, grip))
			{
				return false;
			}
			pendingAutoCatch = null;
			pendingAutoCatchGrip = grip;
			pendingAutoCatchFrame = Time.frameCount + 2;
			pendingAutoCatchIsPlayer = true;
			DestroyWebJoint();
			return true;
		}

		private void UpdatePendingAutoCatch()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00be: Expected O, but got Unknown
			if (Time.frameCount < pendingAutoCatchFrame)
			{
				return;
			}
			ForcePullGrip val = pendingAutoCatch;
			Grip val2 = pendingAutoCatchGrip;
			bool flag = pendingAutoCatchIsPlayer;
			pendingAutoCatch = null;
			pendingAutoCatchGrip = null;
			pendingAutoCatchIsPlayer = false;
			if (!((Object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy && !val2.HasAttachedHands() && !hand.HasAttachedObject() && !((Object)Player.GetObjectInHand(hand) != (Object)null))
			{
				if (flag)
				{
					AttachPlayerGripAtHandSurface(val2);
				}
				else if ((Object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy && (Object)val._grip == (Object)val2)
				{
					val.Pull(hand);
				}
				else
				{
					val2.Snatch(hand, true);
				}
				hand.Controller.haptor.Haptic_Tap();
			}
		}

		private void AttachPlayerGripAtHandSurface(Grip grip)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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 (IsPlayerGrip(grip))
			{
				hand.GrabLock = false;
				hand.HoverLock();
				SimpleTransform val = SimpleTransform.Create(((Component)hand).transform);
				((HandReciever)grip).ValidateGripScore(hand, val);
				grip.OnHandHoverBegin(hand, true);
				((HandReciever)grip).ValidateGripScore(hand, val);
				hand._mHoveringReceiver = (HandReciever)(object)grip;
				grip.OnGrabConfirm(hand, false);
			}
		}

		private static bool IsPlayerGrip(Grip grip)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if ((Object)grip != (Object)null)
			{
				return (Object)((Component)grip).GetComponentInParent<RigManager>() != (Object)null;
			}
			return false;
		}

		private bool IsAutoCatchInRange(Rigidbody targetBody, Grip grip)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = hand.palmPositionTransform.position;
			float value = Prefs.targetAutoCatchDistance.Value;
			if (Vector3.Distance(position, GetSafeGripPullPosition(grip)) <= value)
			{
				return true;
			}
			float num = Mathf.Min(value, 0.15f);
			float maxDistanceSqr = num * num;
			if (IsColliderInAutoCatchRange(webbedCollider, position, maxDistanceSqr))
			{
				return true;
			}
			InteractableHost val = ((Component)targetBody).GetComponentInParent<InteractableHost>();
			if ((Object)val == (Object)null)
			{
				val = ((Component)targetBody).GetComponentInChildren<InteractableHost>();
			}
			if ((Object)val != (Object)null && val.Colliders != null)
			{
				for (int i = 0; i < ((Il2CppArrayBase<Collider>)(object)val.Colliders).Length; i++)
				{
					if (IsColliderInAutoCatchRange(((Il2CppArrayBase<Collider>)(object)val.Colliders)[i], position, maxDistanceSqr))
					{
						return true;
					}
				}
			}
			foreach (Collider componentsInChild in ((Component)targetBody).GetComponentsInChildren<Collider>(true))
			{
				if (IsColliderInAutoCatchRange(componentsInChild, position, maxDistanceSqr))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsColliderInAutoCatchRange(Collider candidate, Vector3 palmPosition, float maxDistanceSqr)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)candidate == (Object)null || !candidate.enabled || !((Component)candidate).gameObject.activeInHierarchy)
			{
				return false;
			}
			Vector3 val = candidate.ClosestPoint(palmPosition) - palmPosition;
			return ((Vector3)(ref val)).sqrMagnitude <= maxDistanceSqr;
		}

		private bool TryFindAutoCatchGrip(Rigidbody targetBody, out ForcePullGrip forcePullGrip, out Grip grip)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			forcePullGrip = null;
			grip = null;
			Gun val = ((Component)targetBody).GetComponentInParent<Gun>();
			if ((Object)val == (Object)null)
			{
				val = ((Component)targetBody).GetComponentInChildren<Gun>();
			}
			if ((Object)val != (Object)null && (Object)val.triggerGrip != (Object)null)
			{
				grip = val.triggerGrip;
				forcePullGrip = FindForcePullForGrip(((Component)val).transform.root, grip);
				return true;
			}
			InteractableHost val2 = ((Component)targetBody).GetComponentInParent<InteractableHost>();
			if ((Object)val2 == (Object)null)
			{
				val2 = ((Component)targetBody).GetComponentInChildren<InteractableHost>();
			}
			Transform searchRoot = (((Object)val2 != (Object)null) ? ((Component)val2).transform : ((Component)targetBody).transform.root);
			grip = FindNearestNormalGrip(searchRoot, val2, targetBody);
			if ((Object)grip != (Object)null)
			{
				forcePullGrip = FindForcePullForGrip(searchRoot, grip);
				return true;
			}
			forcePullGrip = ((Component)targetBody).GetComponentInChildren<ForcePullGrip>();
			if ((Object)forcePullGrip == (Object)null)
			{
				forcePullGrip = ((Component)targetBody).GetComponentInParent<ForcePullGrip>();
			}
			if ((Object)forcePullGrip == (Object)null || (Object)forcePullGrip._grip == (Object)null)
			{
				return false;
			}
			grip = forcePullGrip._grip;
			return true;
		}

		private Grip FindNearestNormalGrip(Transform searchRoot, InteractableHost targetHost, Rigidbody targetBody)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00d8: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00b8: Expected O, but got Unknown
			//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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			Grip result = null;
			float num = float.MaxValue;
			Vector3 position = hand.palmPositionTransform.position;
			GameObject val = (((Object)targetHost != (Object)null) ? ((Component)targetHost).gameObject : null);
			foreach (Grip componentsInChild in ((Component)searchRoot).GetComponentsInChildren<Grip>(true))
			{
				if ((Object)componentsInChild == (Object)null || !((HandReciever)componentsInChild).IsEnabled || !((HandReciever)componentsInChild).HasHost || !((Component)componentsInChild).gameObject.activeInHierarchy || componentsInChild.HasAttachedHands())
				{
					continue;
				}
				if ((Object)val != (Object)null)
				{
					if ((Object)((HandReciever)componentsInChild).Host.GetHostGameObject() != (Object)val)
					{
						continue;
					}
				}
				else if ((Object)((HandReciever)componentsInChild).Host.Rb != (Object)targetBody)
				{
					continue;
				}
				Vector3 val2 = GetSafeGripPullPosition(componentsInChild) - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					result = componentsInChild;
				}
			}
			return result;
		}

		private Vector3 GetSafeGripPullPosition(Grip grip)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return grip.GetForcePullTransform(hand).position;
			}
			catch (Exception)
			{
			}
			return ((Component)grip).transform.position;
		}

		private static ForcePullGrip FindForcePullForGrip(Transform searchRoot, Grip grip)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_003a: Expected O, but got Unknown
			foreach (ForcePullGrip componentsInChild in ((Component)searchRoot).GetComponentsInChildren<ForcePullGrip>(true))
			{
				if ((Object)componentsInChild != (Object)null && (Object)componentsInChild._grip == (Object)grip)
				{
					return componentsInChild;
				}
			}
			return null;
		}

		private void HandleAiming()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			if ((Object)Player.GetObjectInHand(hand) != (Object)null)
			{
				ToggleReticle(value: false);
				return;
			}
			aimReticle.rotation = Quaternion.LookRotation(Player.Head.forward);
			if (TryGetAimHit(out var hit))
			{
				aimReticle.position = ((RaycastHit)(ref hit)).point;
				ToggleReticle(value: true);
				if (CanShootWebLine())
				{
					CreateWebJoint(hit);
					PlayAudio(Bundles.webLineAudioHigh, Bundles.webLineAudioLow);
					hand.Controller.haptor.Haptic_Tap();
					ToggleReticle(value: false);
				}
			}
			else
			{
				ToggleReticle(value: false);
			}
		}

		private bool TryGetAimHit(out RaycastHit hit)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b7: 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)
			Vector3 position = ((Component)this).transform.position;
			Vector3 forward = ((Component)this).transform.forward;
			bool flag = Physics.SphereCast(position, 0.07f, forward, ref hit, 100000f, ((LayerMask)(ref layerMask)).value, (QueryTriggerInteraction)1);
			float num = (flag ? ((RaycastHit)(ref hit)).distance : 100000f);
			foreach (RaycastHit item in (Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(position, forward, 100000f))
			{
				RaycastHit current = item;
				if (!((Object)((RaycastHit)(ref current)).collider == (Object)null) && !(((RaycastHit)(ref current)).distance >= num))
				{
					Transform root = ((Component)((RaycastHit)(ref current)).collider).transform.root;
					if ((Object)root != (Object)null && ((Object)root).name.StartsWith("[RigManager (Networked)]", StringComparison.Ordinal))
					{
						hit = current;
						num = ((RaycastHit)(ref current)).distance;
						flag = true;
					}
				}
			}
			return flag;
		}

		private void ToggleReticle(bool value)
		{
			((Component)aimReticle).gameObject.SetActive(Prefs.enableAimReticle.Value && value);
		}

		private bool CheckDoubleTapWebline(bool currentState)
		{
			return CheckDoubleTap(ref weblineDoubleTap, ref weblineLastDoubleTapState, currentState);
		}

		private static bool CheckDoubleTap(ref BoolTimer timer, ref bool lastState, bool currentState)
		{
			bool result = false;
			if (currentState && !lastState)
			{
				if ((bool)timer)
				{
					timer.Reset();
					result = true;
				}
				else
				{
					timer.Set(0.3f, overwrite: true);
				}
			}
			lastState = currentState;
			return result;
		}

		private bool CanShootWebLine()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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)
			if (!Prefs.enableWebSwinging.Value || IsWebInputBlocked())
			{
				return false;
			}
			switch (Prefs.weblineInput.Value)
			{
			case WeblineInput.TOUCHPAD:
				if (ControllerInfo.GetTouchpadTouch(hand.handedness))
				{
					return IsPlayerGesturing(Prefs.selectedGesture.Value);
				}
				return false;
			case WeblineInput.DOUBLE_TOUCHPAD:
				if (CheckDoubleTapWebline(ControllerInfo.GetTouchpadTouch(hand.handedness)))
				{
					return IsPlayerGesturing(Prefs.selectedGesture.Value);
				}
				return false;
			case WeblineInput.DOUBLE_GESTURE:
				return CheckDoubleTapWebline(IsPlayerGesturing(Prefs.selectedGesture.Value));
			case WeblineInput.DOUBLE_TRIGGER:
				if (CheckDoubleTap(ref triggerDoubleTap, ref triggerLastDoubleTapState, ControllerInfo.GetTrigger(hand.handedness) >= 0.75f))
				{
					return IsPlayerGesturing(Prefs.selectedGesture.Value);
				}
				return false;
			case WeblineInput.DOUBLE_TOUCH_BUTTONS:
				if (CheckDoubleTapWebline(ControllerInfo.GetFaceButtonsTouch(hand.handedness)))
				{
					return IsPlayerGesturing(Prefs.selectedGesture.Value);
				}
				return false;
			case WeblineInput.DOUBLE_GRIP:
				return CheckDoubleTap(ref gripDoubleTap, ref gripLastDoubleTapState, ControllerInfo.GetGrip(hand.handedness) >= 0.75f);
			case WeblineInput.DOUBLE_TRIGGER_OR_GRIP:
			{
				bool flag = CheckDoubleTap(ref triggerDoubleTap, ref triggerLastDoubleTapState, ControllerInfo.GetTrigger(hand.handedness) >= 0.75f);
				if (!CheckDoubleTap(ref gripDoubleTap, ref gripLastDoubleTapState, ControllerInfo.GetGrip(hand.handedness) >= 0.75f))
				{
					if (flag)
					{
						return IsPlayerGesturing(Prefs.selectedGesture.Value);
					}
					return false;
				}
				return true;
			}
			case WeblineInput.DISABLED:
				return false;
			default:
				return false;
			}
		}

		private bool CanShootWebShot()
		{
			if (!IsWebAttatched() && IsPlayerGesturing(Prefs.selectedGesture.Value))
			{
				if (!hand.Controller.GetBButtonDown())
				{
					if (hand.Controller.GetBButtonUp())
					{
						return isWebShotBtnPressMomentary;
					}
					return false;
				}
				isWebShotBtnPressMomentary.Set(0.2f);
			}
			return false;
		}

		private bool IsPlayerGesturing(HandGesture gesture)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if ((Object)Player.GetObjectInHand(hand) != (Object)null || hand.Skeleton.IsSnatching())
			{
				return false;
			}
			BaseController controller = hand.Controller;
			switch (gesture)
			{
			case HandGesture.SPIDEY:
				if (controller.GetIndexCurlAxis() <= 0.3f && controller.GetMiddleCurlAxis() >= 0.7f && controller.GetRingCurlAxis() >= 0.7f)
				{
					return controller.GetPinkyCurlAxis() <= 0.3f;
				}
				return false;
			case HandGesture.GRIP:
				return controller.GetIndexCurlAxis() + controller.GetMiddleCurlAxis() + controller.GetRingCurlAxis() + controller.GetPinkyCurlAxis() >= 1.4f;
			default:
				return false;
			}
		}

		private bool IsWebAttatched()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Object)webJoint != (Object)null;
		}

		private void CreateWebJoint(RaycastHit hit)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			webJoint = ((Component)this).gameObject.AddComponent<ConfigurableJoint>();
			((Joint)webJoint).connectedBody = ((RaycastHit)(ref hit)).rigidbody;
			webJoint.SetAnchorPoint(((Component)this).transform.position);
			webJoint.SetConnectedPoint(((RaycastHit)(ref hit)).point);
			webJoint.SetLinearMotion((ConfigurableJointMotion)1);
			webJoint.SetLinearLimit(((RaycastHit)(ref hit)).distance + 0.075f, 1f);
			webLine_lowestLength = ((RaycastHit)(ref hit)).distance;
			webJoint.SetSpringLimit(1372344f / (float)Math.E, 50485.715f);
			webJoint.SetSpringDrive(0f, 0f, 0f);
			((Joint)webJoint).breakForce = WEB_BREAK_FORCE;
			((Joint)webJoint).enableCollision = true;
			webbedCollider = ((RaycastHit)(ref hit)).collider;
			webActive = true;
			webLine.SetActive(value: true);
			webLine.UpdateLine(hand.palmPositionTransform.position, ((RaycastHit)(ref hit)).point);
			WebShooter.WebCreated?.Invoke(this, hit);
		}

		private bool IsWebInputBlocked()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if ((Object)hand == (Object)null || hand.HasAttachedObject() || (Object)Player.GetObjectInHand(hand) != (Object)null || hand.Skeleton.IsSnatching())
			{
				return true;
			}
			GUIMenu instance = GUIMenu.Instance;
			if ((Object)instance != (Object)null)
			{
				return ((Component)instance).gameObject.activeInHierarchy;
			}
			return false;
		}

		private void ResetWebInputTimers()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			weblineDoubleTap.Reset();
			triggerDoubleTap.Reset();
			gripDoubleTap.Reset();
			weblineLastDoubleTapState = false;
			triggerLastDoubleTapState = ControllerInfo.GetTrigger(hand.handedness) >= 0.75f;
			gripLastDoubleTapState = ControllerInfo.GetGrip(hand.handedness) >= 0.75f;
		}

		private void DestroyWebJoint()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if (webActive)
			{
				webActive = false;
				ConfigurableJoint val = webJoint;
				webJoint = null;
				webbedCollider = null;
				WebShooter.WebDestroyed?.Invoke(this);
				webLine.SetActive(value: false);
				if ((Object)val != (Object)null)
				{
					Object.Destroy((Object)val);
				}
			}
		}

		private void PlayAudio(AudioClip high, AudioClip low)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!((Object)audioSource == (Object)null) && !((Object)high == (Object)null) && !((Object)low == (Object)null))
			{
				AudioClip val = ((Random.value > 0.5f) ? high : low);
				float num = 0.5f * (DataManager.ActiveSave.PlayerSettings.VolumeSFX / 10f);
				audioSource.loop = false;
				audioSource.PlayOneShot(val, num);
			}
		}
	}
}

Mods\SpiderlabFusionSync.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSystem.Collections.Generic;
using LabFusion.Data.Serializables;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Marrow.Extenders;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using MelonLoader;
using Microsoft.CodeAnalysis;
using SpiderLab.Behaviours;
using SpiderLab.Data;
using SpiderlabFusionSync;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(SpiderlabFusionMod), "SpiderLab Fusion Sync Compat", "2.8.0", "notnotnotswipez; Patch 6 compatibility rebuild", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "LabFusion", "SpiderLab" })]
[assembly: AssemblyFileVersion("2.8.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.8.0.0")]
[module: UnverifiableCode]
[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 SpiderlabFusionSync
{
	public sealed class RepWebShooter : IDisposable
	{
		private sealed class WebVisual
		{
			public Hand Hand;

			public WebLine Line;

			public Rigidbody Body;

			public Vector3 Point;

			public bool Active;

			public uint Generation;

			public Vector3 WorldPoint
			{
				get
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Expected O, but got Unknown
					//IL_002b: 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_0024: Unknown result type (might be due to invalid IL or missing references)
					if (!((Object)Body == (Object)null))
					{
						return ((Component)Body).transform.TransformPoint(Point);
					}
					return Point;
				}
			}
		}

		private static readonly Dictionary<byte, RepWebShooter> Managers = new Dictionary<byte, RepWebShooter>();

		private readonly WebVisual _left;

		private readonly WebVisual _right;

		private readonly AudioSource _audioSource;

		private RepWebShooter(RigManager rigManager)
		{
			_left = CreateVisual(rigManager.physicsRig.leftHand);
			_right = CreateVisual(rigManager.physicsRig.rightHand);
			_audioSource = ((Component)((Rig)rigManager.physicsRig).m_pelvis).gameObject.AddComponent<AudioSource>();
			_audioSource.playOnAwake = false;
			_audioSource.minDistance = 0.5f;
			_audioSource.spatialBlend = 1f;
		}

		public static bool TryGet(byte playerId, out RepWebShooter shooter)
		{
			return Managers.TryGetValue(playerId, out shooter);
		}

		public static void AddOrReplace(byte playerId, RigManager rigManager)
		{
			if (Managers.Remove(playerId, out var value))
			{
				value.Dispose();
			}
			Managers[playerId] = new RepWebShooter(rigManager);
		}

		public static void UpdateAll()
		{
			List<byte> list = null;
			foreach (KeyValuePair<byte, RepWebShooter> manager in Managers)
			{
				if (!NetworkPlayerManager.HasPlayer(manager.Key))
				{
					(list ?? (list = new List<byte>())).Add(manager.Key);
				}
				else
				{
					manager.Value.Update();
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (byte item in list)
			{
				Managers[item].Dispose();
				Managers.Remove(item);
			}
		}

		public static void DisposeAll()
		{
			foreach (RepWebShooter value in Managers.Values)
			{
				value.Dispose();
			}
			Managers.Clear();
		}

		public uint BeginWeb(byte hand)
		{
			WebVisual webVisual = Select(hand);
			webVisual.Generation++;
			return webVisual.Generation;
		}

		public void MakeWeb(byte hand, Vector3 point, Rigidbody body, uint generation)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			WebVisual webVisual = Select(hand);
			if (webVisual.Generation == generation)
			{
				webVisual.Body = body;
				webVisual.Point = point;
				webVisual.Active = true;
				webVisual.Line.SetActive(true);
				webVisual.Line.UpdateLine(webVisual.Hand.palmPositionTransform.position, webVisual.WorldPoint);
				PlayAudio(Bundles.webLineAudioHigh, Bundles.webLineAudioLow);
			}
		}

		public void DestroyWeb(byte hand)
		{
			WebVisual webVisual = Select(hand);
			webVisual.Generation++;
			webVisual.Active = false;
			webVisual.Body = null;
			webVisual.Line.SetActive(false);
		}

		public void Dispose()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			DestroyVisual(_left);
			DestroyVisual(_right);
			if ((Object)_audioSource != (Object)null)
			{
				Object.Destroy((Object)_audioSource);
			}
		}

		private void Update()
		{
			UpdateVisual(_left);
			UpdateVisual(_right);
		}

		private static WebVisual CreateVisual(Hand hand)
		{
			WebLine val = Object.Instantiate<GameObject>(Bundles.webLinePrefab, ((Component)hand).transform).AddComponent<WebLine>();
			val.SetActive(false);
			return new WebVisual
			{
				Hand = hand,
				Line = val
			};
		}

		private static void UpdateVisual(WebVisual visual)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (visual.Active && !((Object)visual.Hand == (Object)null) && !((Object)visual.Line == (Object)null))
			{
				visual.Line.UpdateLine(visual.Hand.palmPositionTransform.position, visual.WorldPoint);
			}
		}

		private static void DestroyVisual(WebVisual visual)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (visual != null && (Object)visual.Line != (Object)null)
			{
				Object.Destroy((Object)((Component)visual.Line).gameObject);
			}
		}

		private WebVisual Select(byte hand)
		{
			if (hand != 2)
			{
				return _left;
			}
			return _right;
		}

		private void PlayAudio(AudioClip high, AudioClip low)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			if (!((Object)high == (Object)null) && !((Object)low == (Object)null))
			{
				_audioSource.loop = false;
				_audioSource.PlayOneShot((Random.value > 0.5f) ? high : low, 0.5f);
			}
		}
	}
	public sealed class SpiderDisarmRequestData : INetSerializable
	{
		public uint RequestId;

		public NetworkEntityReference Entity = new NetworkEntityReference();

		public int? GetSize()
		{
			return null;
		}

		public void Serialize(INetSerializer serializer)
		{
			serializer.SerializeValue(ref RequestId);
			NetSerializerExtensions.SerializeValue<NetworkEntityReference>(serializer, ref Entity);
		}

		public static SpiderDisarmRequestData Create(uint requestId, NetworkEntity entity)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new SpiderDisarmRequestData
			{
				RequestId = requestId,
				Entity = new NetworkEntityReference(entity)
			};
		}
	}
	public sealed class SpiderDisarmAckData : INetSerializable
	{
		public uint RequestId;

		public NetworkEntityReference Entity = new NetworkEntityReference();

		public byte HandMask;

		public bool Accepted;

		public int? GetSize()
		{
			return null;
		}

		public void Serialize(INetSerializer serializer)
		{
			serializer.SerializeValue(ref RequestId);
			NetSerializerExtensions.SerializeValue<NetworkEntityReference>(serializer, ref Entity);
			serializer.SerializeValue(ref HandMask);
			serializer.SerializeValue(ref Accepted);
		}
	}
	internal static class SpiderDisarmManager
	{
		private sealed class PendingDisarm
		{
			public uint RequestId;

			public WebShooter Shooter;

			public Rigidbody Body;

			public NetworkEntity Entity;

			public float Intensity;

			public float StartedAt;

			public int ResumeFrame;

			public bool OwnershipRequested;

			public readonly Dictionary<byte, byte> ExpectedHands = new Dictionary<byte, byte>();

			public readonly HashSet<byte> AcknowledgedPlayers = new HashSet<byte>();
		}

		private const byte LeftHandMask = 1;

		private const byte RightHandMask = 2;

		private const float TransactionTimeout = 1f;

		private const float RetryCooldown = 0.5f;

		private static readonly Dictionary<WebShooter, PendingDisarm> PendingByShooter = new Dictionary<WebShooter, PendingDisarm>();

		private static readonly Dictionary<WebShooter, float> RetryAfter = new Dictionary<WebShooter, float>();

		private static uint nextRequestId = 1u;

		public static void Initialize()
		{
			WebShooter.TargetPullIntercepted += OnTargetPullIntercepted;
		}

		public static void Deinitialize()
		{
			WebShooter.TargetPullIntercepted -= OnTargetPullIntercepted;
			PendingByShooter.Clear();
			RetryAfter.Clear();
		}

		public static void Cancel(WebShooter shooter)
		{
			if ((Object)(object)shooter != (Object)null)
			{
				PendingByShooter.Remove(shooter);
			}
		}

		public static void Update()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if (PendingByShooter.Count == 0)
			{
				return;
			}
			foreach (PendingDisarm item in new List<PendingDisarm>(PendingByShooter.Values))
			{
				if (!IsPendingCurrent(item))
				{
					continue;
				}
				if ((Object)item.Shooter == (Object)null || (Object)item.Body == (Object)null || item.Entity == null)
				{
					Fail(item, "web or target disappeared");
					continue;
				}
				RemoveDisconnectedHolders(item);
				if (Time.unscaledTime - item.StartedAt >= 1f)
				{
					Fail(item, GetTimeoutReason(item));
					continue;
				}
				if (!item.OwnershipRequested && AllHoldersAcknowledged(item))
				{
					BeginOwnershipTransfer(item);
				}
				if (item.OwnershipRequested && item.Entity.IsOwner && !item.Body.isKinematic && Time.frameCount >= item.ResumeFrame)
				{
					PendingByShooter.Remove(item.Shooter);
					if (!item.Shooter.ResumeTargetPull(item.Body, item.Intensity))
					{
						RetryAfter[item.Shooter] = Time.unscaledTime + 0.5f;
					}
				}
			}
		}

		private static bool OnTargetPullIntercepted(WebShooter shooter, Rigidbody body, float intensity)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0126: Expected O, but got Unknown
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkInfo.HasServer || (Object)(object)shooter == (Object)null || (Object)body == (Object)null || IsPlayerBody(body))
			{
				return false;
			}
			if (!TryGetTarget(body, out var entity, out var grips))
			{
				return false;
			}
			if (!entity.IsRegistered || entity.ID == 0)
			{
				RetryAfter[shooter] = Time.unscaledTime + 0.5f;
				MelonLogger.Warning("SpiderLab target pull is waiting for Fusion to register the webbed object.");
				return true;
			}
			if (RetryAfter.TryGetValue(shooter, out var value) && Time.unscaledTime < value)
			{
				return true;
			}
			RetryAfter.Remove(shooter);
			bool hasUnmappedHands;
			Dictionary<byte, byte> dictionary = FindPlayerHolders(grips, out hasUnmappedHands);
			if (dictionary.Count == 0 && entity.IsOwner && !body.isKinematic)
			{
				return false;
			}
			if (entity.IsOwnerLocked)
			{
				RetryAfter[shooter] = Time.unscaledTime + 0.5f;
				MelonLogger.Warning("SpiderLab target pull blocked because the Fusion object's ownership is locked.");
				return true;
			}
			if (hasUnmappedHands)
			{
				RetryAfter[shooter] = Time.unscaledTime + 0.5f;
				MelonLogger.Warning("SpiderLab disarm blocked because one or more item holders could not be resolved as Fusion players.");
				return true;
			}
			if (PendingByShooter.TryGetValue(shooter, out var value2))
			{
				if ((Object)value2.Body == (Object)body)
				{
					value2.Intensity = Mathf.Max(value2.Intensity, intensity);
					return true;
				}
				PendingByShooter.Remove(shooter);
			}
			uint requestId = nextRequestId++;
			if (nextRequestId == 0)
			{
				nextRequestId = 1u;
			}
			PendingDisarm pendingDisarm = new PendingDisarm
			{
				RequestId = requestId,
				Shooter = shooter,
				Body = body,
				Entity = entity,
				Intensity = Mathf.Clamp01(intensity),
				StartedAt = Time.unscaledTime
			};
			foreach (KeyValuePair<byte, byte> item in dictionary)
			{
				pendingDisarm.ExpectedHands[item.Key] = item.Value;
			}
			PendingByShooter[shooter] = pendingDisarm;
			if (pendingDisarm.ExpectedHands.Count > 0)
			{
				SpiderDisarmRequestData spiderDisarmRequestData = SpiderDisarmRequestData.Create(requestId, entity);
				foreach (byte key in pendingDisarm.ExpectedHands.Keys)
				{
					if (key == PlayerIDManager.LocalSmallID)
					{
						byte handMask = DetachLocalHands(entity);
						MarkAcknowledged(pendingDisarm, key, handMask);
					}
					else
					{
						MessageRelay.RelayModule<SpiderDisarmRequestMessage, SpiderDisarmRequestData>(spiderDisarmRequestData, new MessageRoute(key, (NetworkChannel)0));
					}
				}
			}
			if (AllHoldersAcknowledged(pendingDisarm))
			{
				BeginOwnershipTransfer(pendingDisarm);
			}
			return true;
		}

		public static void HandleRequest(byte requesterId, SpiderDisarmRequestData data)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (data != null && data.Entity.ID != 0)
			{
				((NetworkEntityReference)(ref data.Entity)).HookEntityRegistered((NetworkEntityDelegate)delegate(NetworkEntity entity)
				{
					//IL_0052: Unknown result type (might be due to invalid IL or missing references)
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_0071: Unknown result type (might be due to invalid IL or missing references)
					bool flag = entity != null && entity.IsRegistered && !entity.IsOwnerLocked && !IsPlayerEntity(entity) && entity.GetExtender<GripExtender>() != null;
					byte handMask = (byte)(flag ? DetachLocalHands(entity) : 0);
					MessageRelay.RelayModule<SpiderDisarmAckMessage, SpiderDisarmAckData>(new SpiderDisarmAckData
					{
						RequestId = data.RequestId,
						Entity = data.Entity,
						HandMask = handMask,
						Accepted = flag
					}, new MessageRoute(requesterId, (NetworkChannel)0));
				});
			}
		}

		public static void HandleAck(byte holderId, SpiderDisarmAckData data)
		{
			if (data == null || data.Entity.ID == 0)
			{
				return;
			}
			PendingDisarm pendingDisarm = FindPending(data.RequestId);
			if (pendingDisarm == null || !pendingDisarm.ExpectedHands.ContainsKey(holderId) || pendingDisarm.AcknowledgedPlayers.Contains(holderId))
			{
				return;
			}
			if (!data.Accepted)
			{
				Fail(pendingDisarm, $"player {holderId} rejected an invalid or ownership-locked disarm target");
				return;
			}
			if (data.Entity.ID != pendingDisarm.Entity.ID)
			{
				Fail(pendingDisarm, "holder acknowledgement referenced a different Fusion entity");
				return;
			}
			byte handMask = ((data.HandMask != 0) ? data.HandMask : pendingDisarm.ExpectedHands[holderId]);
			MarkAcknowledged(pendingDisarm, holderId, handMask);
			if (AllHoldersAcknowledged(pendingDisarm))
			{
				BeginOwnershipTransfer(pendingDisarm);
			}
		}

		private static void MarkAcknowledged(PendingDisarm pending, byte holderId, byte handMask)
		{
			NetworkPlayer player = default(NetworkPlayer);
			if (pending.AcknowledgedPlayers.Add(holderId) && holderId != PlayerIDManager.LocalSmallID && NetworkPlayerManager.TryGetPlayer(holderId, ref player))
			{
				DetachRemoteRepresentation(player, pending.Entity, handMask);
			}
		}

		private static void BeginOwnershipTransfer(PendingDisarm pending)
		{
			if (pending.OwnershipRequested || !IsPendingCurrent(pending))
			{
				return;
			}
			if (pending.Entity == null || pending.Entity.IsOwnerLocked)
			{
				Fail(pending, "item ownership became locked before transfer");
				return;
			}
			pending.OwnershipRequested = true;
			pending.ResumeFrame = Time.frameCount + 2;
			if (!pending.Entity.IsOwner)
			{
				NetworkEntityManager.TakeOwnership(pending.Entity);
			}
		}

		private static Dictionary<byte, byte> FindPlayerHolders(List<Grip> grips, out bool hasUnmappedHands)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			Dictionary<byte, byte> dictionary = new Dictionary<byte, byte>();
			hasUnmappedHands = false;
			NetworkPlayer val = default(NetworkPlayer);
			foreach (Grip grip in grips)
			{
				Enumerator<Hand> enumerator2 = grip.attachedHands.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					Hand current = enumerator2.Current;
					if (!((Object)current == (Object)null) && !((Object)current.manager == (Object)null))
					{
						if (!NetworkPlayerManager.TryGetPlayer(current.manager, ref val))
						{
							hasUnmappedHands = true;
							continue;
						}
						byte b = (byte)(((int)current.handedness == 1) ? 1 : 2);
						byte smallID = val.PlayerID.SmallID;
						dictionary[smallID] = (dictionary.TryGetValue(smallID, out var value) ? ((byte)(value | b)) : b);
					}
				}
			}
			return dictionary;
		}

		private static byte DetachLocalHands(NetworkEntity targetEntity)
		{
			NetworkPlayer networkPlayer = LocalPlayer.GetNetworkPlayer();
			if (networkPlayer == null || !networkPlayer.HasRig)
			{
				return 0;
			}
			byte b = 0;
			if (HandHoldsEntity(networkPlayer.RigRefs.LeftHand, targetEntity))
			{
				HandExtensions.TryDetach(networkPlayer.RigRefs.LeftHand);
				b |= 1;
			}
			if (HandHoldsEntity(networkPlayer.RigRefs.RightHand, targetEntity))
			{
				HandExtensions.TryDetach(networkPlayer.RigRefs.RightHand);
				b |= 2;
			}
			return b;
		}

		private static void DetachRemoteRepresentation(NetworkPlayer player, NetworkEntity targetEntity, byte handMask)
		{
			if (player != null && player.HasRig)
			{
				if ((handMask & 1) != 0 && HandHoldsEntity(player.RigRefs.LeftHand, targetEntity))
				{
					player.Grabber.Detach((Handedness)1);
				}
				if ((handMask & 2) != 0 && HandHoldsEntity(player.RigRefs.RightHand, targetEntity))
				{
					player.Grabber.Detach((Handedness)2);
				}
			}
		}

		private static bool HandHoldsEntity(Hand hand, NetworkEntity targetEntity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)hand == (Object)null || (Object)(object)hand.m_CurrentAttachedGO == (Object)null)
			{
				return false;
			}
			Grip component = hand.m_CurrentAttachedGO.GetComponent<Grip>();
			NetworkEntity val = default(NetworkEntity);
			if ((Object)component != (Object)null && GripExtender.Cache.TryGet(component, ref val))
			{
				return val == targetEntity;
			}
			return false;
		}

		private static bool TryGetTarget(Rigidbody body, out NetworkEntity entity, out List<Grip> grips)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00c6: Expected O, but got Unknown
			entity = null;
			grips = new List<Grip>();
			if ((Object)body == (Object)null || IsPlayerBody(body))
			{
				return false;
			}
			InteractableHost val = ((Component)body).GetComponentInParent<InteractableHost>();
			if ((Object)val == (Object)null)
			{
				val = ((Component)body).GetComponentInChildren<InteractableHost>();
			}
			Transform obj = (((Object)val != (Object)null) ? ((Component)val).transform : ((Component)body).transform.root);
			GameObject val2 = (((Object)val != (Object)null) ? ((Component)val).gameObject : null);
			NetworkEntity val3 = default(NetworkEntity);
			foreach (Grip componentsInChild in ((Component)obj).GetComponentsInChildren<Grip>(true))
			{
				if (!((Object)componentsInChild == (Object)null) && ((HandReciever)componentsInChild).HasHost && (((Object)(object)val2 != (Object)null) ? ((Object)(object)((HandReciever)componentsInChild).Host.GetHostGameObject() == (Object)(object)val2) : ((Object)((HandReciever)componentsInChild).Host.Rb == (Object)body)) && GripExtender.Cache.TryGet(componentsInChild, ref val3))
				{
					if (entity == null)
					{
						entity = val3;
					}
					if (val3 == entity)
					{
						grips.Add(componentsInChild);
					}
				}
			}
			if (entity != null)
			{
				return grips.Count > 0;
			}
			return false;
		}

		private static bool IsPlayerBody(Rigidbody body)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if ((Object)body == (Object)null)
			{
				return false;
			}
			if ((Object)((Component)body).GetComponentInParent<RigManager>() != (Object)null)
			{
				return true;
			}
			Transform root = ((Component)body).transform.root;
			if ((Object)root == (Object)null)
			{
				return false;
			}
			string name = ((Object)root).name;
			if (!name.StartsWith("[RigManager (Networked)]", StringComparison.Ordinal))
			{
				return name.StartsWith("[RigManager (FUSION PlayerRep)]", StringComparison.Ordinal);
			}
			return true;
		}

		private static bool IsPlayerEntity(NetworkEntity entity)
		{
			if (entity == null)
			{
				return false;
			}
			foreach (NetworkPlayer player in NetworkPlayer.Players)
			{
				if (player != null && player.NetworkEntity == entity)
				{
					return true;
				}
			}
			return false;
		}

		private static PendingDisarm FindPending(uint requestId)
		{
			foreach (PendingDisarm value in PendingByShooter.Values)
			{
				if (value.RequestId == requestId)
				{
					return value;
				}
			}
			return null;
		}

		private static bool AllHoldersAcknowledged(PendingDisarm pending)
		{
			foreach (byte key in pending.ExpectedHands.Keys)
			{
				if (!pending.AcknowledgedPlayers.Contains(key))
				{
					return false;
				}
			}
			return true;
		}

		private static void RemoveDisconnectedHolders(PendingDisarm pending)
		{
			List<byte> list = null;
			foreach (byte key in pending.ExpectedHands.Keys)
			{
				if (key != PlayerIDManager.LocalSmallID && !NetworkPlayerManager.HasPlayer(key))
				{
					(list ?? (list = new List<byte>())).Add(key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (byte item in list)
			{
				pending.ExpectedHands.Remove(item);
				pending.AcknowledgedPlayers.Remove(item);
			}
		}

		private static bool IsPendingCurrent(PendingDisarm pending)
		{
			if (pending != null && (Object)(object)pending.Shooter != (Object)null && PendingByShooter.TryGetValue(pending.Shooter, out var value))
			{
				return value == pending;
			}
			return false;
		}

		private static string GetTimeoutReason(PendingDisarm pending)
		{
			if (!AllHoldersAcknowledged(pending))
			{
				List<byte> list = new List<byte>();
				foreach (byte key in pending.ExpectedHands.Keys)
				{
					if (!pending.AcknowledgedPlayers.Contains(key))
					{
						list.Add(key);
					}
				}
				return "no matching 2.7.1 disarm acknowledgement from Fusion player(s) " + string.Join(", ", list);
			}
			if (!pending.Entity.IsOwner)
			{
				return "Fusion ownership transfer timed out";
			}
			if (pending.Body.isKinematic)
			{
				return "Fusion kept the owned target kinematic";
			}
			return "transaction timed out";
		}

		private static void Fail(PendingDisarm pending, string reason)
		{
			if (pending != null && !((Object)(object)pending.Shooter == (Object)null))
			{
				PendingByShooter.Remove(pending.Shooter);
				RetryAfter[pending.Shooter] = Time.unscaledTime + 0.5f;
				MelonLogger.Warning("SpiderLab Fusion target pull cancelled: " + reason + ".");
			}
		}
	}
	public sealed class SpiderDisarmRequestMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			if (((ReceivedMessage)(ref received)).Sender.HasValue && ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID && NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value))
			{
				SpiderDisarmManager.HandleRequest(((ReceivedMessage)(ref received)).Sender.Value, ((ReceivedMessage)(ref received)).ReadData<SpiderDisarmRequestData>());
			}
		}
	}
	public sealed class SpiderDisarmAckMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			if (((ReceivedMessage)(ref received)).Sender.HasValue && ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID && NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value))
			{
				SpiderDisarmManager.HandleAck(((ReceivedMessage)(ref received)).Sender.Value, ((ReceivedMessage)(ref received)).ReadData<SpiderDisarmAckData>());
			}
		}
	}
	public sealed class SpiderlabFusionMod : MelonMod
	{
		public override void OnInitializeMelon()
		{
			if (ModuleMessageManager.GetHandlerByType(typeof(SpiderWebMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<SpiderWebMessage>();
			}
			if (ModuleMessageManager.GetHandlerByType(typeof(SpiderPullMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<SpiderPullMessage>();
			}
			if (ModuleMessageManager.GetHandlerByType(typeof(SpiderDisarmRequestMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<SpiderDisarmRequestMessage>();
			}
			if (ModuleMessageManager.GetHandlerByType(typeof(SpiderDisarmAckMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<SpiderDisarmAckMessage>();
			}
			NetworkPlayer.OnNetworkRigCreated += OnNetworkRigCreated;
			WebShooter.WebCreated += OnLocalWebCreated;
			WebShooter.WebDestroyed += OnLocalWebDestroyed;
			WebShooter.TargetPulled += OnLocalTargetPulled;
			SpiderDisarmManager.Initialize();
			foreach (NetworkPlayer player in NetworkPlayer.Players)
			{
				if (player.HasRig)
				{
					OnNetworkRigCreated(player, player.RigRefs.RigManager);
				}
			}
			MelonLogger.Msg("SpiderLab Fusion Sync compatibility module initialized.");
		}

		public override void OnDeinitializeMelon()
		{
			NetworkPlayer.OnNetworkRigCreated -= OnNetworkRigCreated;
			WebShooter.WebCreated -= OnLocalWebCreated;
			WebShooter.WebDestroyed -= OnLocalWebDestroyed;
			WebShooter.TargetPulled -= OnLocalTargetPulled;
			SpiderDisarmManager.Deinitialize();
			RepWebShooter.DisposeAll();
		}

		public override void OnUpdate()
		{
			RepWebShooter.UpdateAll();
			SpiderDisarmManager.Update();
		}

		private static void OnNetworkRigCreated(NetworkPlayer player, RigManager rigManager)
		{
			if (player != null && !((Object)(object)rigManager == (Object)null) && !player.NetworkEntity.IsOwner)
			{
				RepWebShooter.AddOrReplace(player.PlayerID.SmallID, rigManager);
			}
		}

		private static void OnLocalWebCreated(WebShooter shooter, RaycastHit hit)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null))
			{
				MessageRelay.RelayModule<SpiderWebMessage, SpiderWebData>(SpiderWebData.CreateWeb(shooter.Hand, hit), CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		private static void OnLocalWebDestroyed(WebShooter shooter)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			SpiderDisarmManager.Cancel(shooter);
			if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null))
			{
				MessageRelay.RelayModule<SpiderWebMessage, SpiderWebData>(SpiderWebData.CreateDestroy(shooter.Hand), CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		private static void OnLocalTargetPulled(WebShooter shooter, Rigidbody body, Vector3 velocityChange)
		{
			//IL_0026: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null) && !((Object)(object)body == (Object)null))
			{
				MessageRelay.RelayModule<SpiderPullMessage, SpiderPullData>(SpiderPullData.Create(body, Vector3.ClampMagnitude(velocityChange, 50f)), CommonMessageRoutes.ReliableToOtherClients);
			}
		}
	}
	public sealed class SpiderPullData : INetSerializable
	{
		public GameObjectReference Body = new GameObjectReference();

		public Vector3 VelocityChange;

		public int? GetSize()
		{
			return null;
		}

		public void Serialize(INetSerializer serializer)
		{
			NetSerializerExtensions.SerializeValue<GameObjectReference>(serializer, ref Body);
			NetSerializerUnityExtensions.SerializeValue(serializer, ref VelocityChange);
		}

		public static SpiderPullData Create(Rigidbody body, Vector3 velocityChange)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new SpiderPullData
			{
				Body = new GameObjectReference(((Object)(object)body == (Object)null) ? null : ((Component)body).gameObject),
				VelocityChange = velocityChange
			};
		}
	}
	public sealed class SpiderPullMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value == PlayerIDManager.LocalSmallID || !NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value))
			{
				return;
			}
			SpiderPullData spiderPullData = ((ReceivedMessage)(ref received)).ReadData<SpiderPullData>();
			Vector3 velocityChange = Vector3.ClampMagnitude(spiderPullData.VelocityChange, 50f);
			spiderPullData.Body.HookGameObjectFound((Action<GameObject>)delegate(GameObject gameObject)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				Rigidbody val = (((Object)(object)gameObject == (Object)null) ? null : gameObject.GetComponent<Rigidbody>());
				if ((Object)(object)val != (Object)null && !val.isKinematic)
				{
					val.AddForce(velocityChange, (ForceMode)2);
				}
			});
		}
	}
	public sealed class SpiderWebData : INetSerializable
	{
		public bool IsDestroy;

		public byte Hand;

		public GameObjectReference Body = new GameObjectReference();

		public Vector3 Position;

		public float Distance;

		public int? GetSize()
		{
			return null;
		}

		public void Serialize(INetSerializer serializer)
		{
			serializer.SerializeValue(ref IsDestroy);
			serializer.SerializeValue(ref Hand);
			NetSerializerExtensions.SerializeValue<GameObjectReference>(serializer, ref Body);
			NetSerializerUnityExtensions.SerializeValue(serializer, ref Position);
			serializer.SerializeValue(ref Distance);
		}

		public static SpiderWebData CreateDestroy(Hand hand)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			return new SpiderWebData
			{
				IsDestroy = true,
				Hand = (byte)hand.handedness,
				Body = new GameObjectReference((GameObject)null),
				Position = Vector3.zero,
				Distance = 0f
			};
		}

		public static SpiderWebData CreateWeb(Hand hand, RaycastHit hit)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_006b: 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)
			Rigidbody rigidbody = ((RaycastHit)(ref hit)).rigidbody;
			GameObject val = (((Object)rigidbody == (Object)null) ? null : ((Component)rigidbody).gameObject);
			Vector3 position = (((Object)(object)val == (Object)null) ? ((RaycastHit)(ref hit)).point : val.transform.InverseTransformPoint(((RaycastHit)(ref hit)).point));
			return new SpiderWebData
			{
				IsDestroy = false,
				Hand = (byte)hand.handedness,
				Body = new GameObjectReference(val),
				Position = position,
				Distance = ((RaycastHit)(ref hit)).distance
			};
		}
	}
	public sealed class SpiderWebMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value == PlayerIDManager.LocalSmallID)
			{
				return;
			}
			byte value = ((ReceivedMessage)(ref received)).Sender.Value;
			if (!NetworkPlayerManager.HasPlayer(value) || !RepWebShooter.TryGet(value, out var shooter))
			{
				return;
			}
			SpiderWebData data = ((ReceivedMessage)(ref received)).ReadData<SpiderWebData>();
			if (data.IsDestroy)
			{
				shooter.DestroyWeb(data.Hand);
				return;
			}
			uint generation = shooter.BeginWeb(data.Hand);
			data.Body.HookGameObjectFound((Action<GameObject>)delegate(GameObject gameObject)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				Rigidbody body = (((Object)(object)gameObject == (Object)null) ? null : gameObject.GetComponent<Rigidbody>());
				shooter.MakeWeb(data.Hand, data.Position, body, generation);
			});
		}
	}
}