Decompiled source of StilettoMod v1.0.1

StilettoMod.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 Il2Cpp;
using Il2CppHurricaneVR.Framework.ControllerInput;
using Il2CppHurricaneVR.Framework.Core;
using Il2CppHurricaneVR.Framework.Core.Grabbers;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using Microsoft.CodeAnalysis;
using StilettoMelonMod;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Plugin), "Stiletto Blade", "misha", "1.0.1", null)]
[assembly: MelonGame("Kubunautilus", "BrutalistickVR")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("StilettoMelonMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("StilettoMelonMod")]
[assembly: AssemblyTitle("StilettoMelonMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StilettoMelonMod
{
	public class Plugin : MelonMod
	{
		private class Blade
		{
			public Transform hinge;

			public Transform moving;

			public Transform dummy;

			public Collider[] colliders;

			public MeleeWeaponWrapper wrapper;

			public bool deployed;

			public bool dummyWasActive;
		}

		private const string WeaponName = "Stiletto Knife";

		private const string DeployedName = "BladeDeployed";

		private const string FoldedName = "BladeFolded";

		private const string BladeColliderName = "BladeCollider";

		private const string TipColliderName = "TipCollider";

		private const string SliceTriggerPrefix = "SliceTrigger";

		private static readonly Quaternion DeployedRot = Quaternion.Euler(0f, 0f, 0f);

		private static readonly Quaternion FoldedRot = Quaternion.Euler(180f, 0f, 0f);

		private const float Speed = 1400f;

		private const float ColliderEpsilon = 6f;

		private const float RescanSeconds = 0.15f;

		private readonly List<Blade> blades = new List<Blade>();

		private readonly HashSet<int> seenHinges = new HashSet<int>();

		private float nextScan;

		private bool anyPressed;

		private bool inputsSeen;

		private static bool IsMovingCollider(string name)
		{
			return name.StartsWith("BladeCollider") || name == "TipCollider" || name.StartsWith("SliceTrigger");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			nextScan = 0f;
			anyPressed = false;
			UpgradeAll();
		}

		public override void OnUpdate()
		{
			//IL_0123: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			PollButton();
			if (Time.unscaledTime >= nextScan)
			{
				nextScan = Time.unscaledTime + 0.15f;
				UpgradeAll();
			}
			for (int num = blades.Count - 1; num >= 0; num--)
			{
				Blade blade = blades[num];
				if ((Object)(object)blade.hinge == (Object)null)
				{
					blades.RemoveAt(num);
				}
				else
				{
					bool activeSelf = ((Component)blade.hinge).gameObject.activeSelf;
					if (activeSelf != blade.dummyWasActive)
					{
						blade.dummyWasActive = activeSelf;
						MelonLogger.Msg($"Stiletto: the bundle's baked SetActive is still firing on '{((Object)((Component)blade.wrapper).transform).name}' (dummy active={activeSelf})");
					}
					Quaternion val = (blade.deployed ? DeployedRot : FoldedRot);
					blade.moving.localRotation = Quaternion.RotateTowards(blade.moving.localRotation, val, 1400f * Time.deltaTime);
					bool flag = blade.deployed && Quaternion.Angle(blade.moving.localRotation, DeployedRot) < 6f;
					for (int i = 0; i < blade.colliders.Length; i++)
					{
						Collider val2 = blade.colliders[i];
						if ((Object)(object)val2 != (Object)null && val2.enabled != flag)
						{
							val2.enabled = flag;
						}
					}
				}
			}
		}

		private static bool IsInHand(MeleeWeaponWrapper w)
		{
			Transform parent = ((Component)w).transform.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num++ < 32)
			{
				if ((Object)(object)((Component)parent).GetComponent<HVRHandPhysics>() != (Object)null)
				{
					return true;
				}
				if ((Object)(object)((Component)parent).GetComponent<HVRSocket>() != (Object)null)
				{
					return true;
				}
				parent = parent.parent;
			}
			return false;
		}

		private static void LogAncestry(MeleeWeaponWrapper w)
		{
			Transform val = ((Component)w).transform;
			int value = 0;
			while ((Object)(object)val != (Object)null && value++ < 24)
			{
				List<string> list = new List<string>();
				Il2CppArrayBase<Component> components = ((Component)val).GetComponents<Component>();
				for (int i = 0; i < components.Length; i++)
				{
					if ((Object)(object)components[i] != (Object)null)
					{
						list.Add(((object)components[i]).GetType().Name);
					}
				}
				MelonLogger.Msg($"Stiletto: ancestry {value} '{((Object)val).name}' active={((Component)val).gameObject.activeInHierarchy} [{string.Join(",", list)}]");
				val = val.parent;
			}
		}

		private void PollButton()
		{
			//IL_0018: 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)
			HVRGlobalInputs instance = HVRGlobalInputs.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			bool flag = instance.LeftSecondaryButtonState.Active || instance.RightSecondaryButtonState.Active;
			if (!inputsSeen)
			{
				inputsSeen = true;
				MelonLogger.Msg("Stiletto: reading the secondary button from HVRGlobalInputs");
			}
			if (flag && !anyPressed)
			{
				for (int i = 0; i < blades.Count; i++)
				{
					Blade blade = blades[i];
					if (!((Object)(object)blade.hinge == (Object)null))
					{
						blade.deployed = !blade.deployed;
						MelonLogger.Msg($"Stiletto: B on '{((Object)((Component)blade.wrapper).transform).name}', deployed={blade.deployed}");
					}
				}
			}
			anyPressed = flag;
		}

		private static void DisableVisuals(Transform t)
		{
			Il2CppArrayBase<Renderer> componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}

		private static bool HasBladeColliders(Transform source)
		{
			Il2CppArrayBase<Collider> componentsInChildren = ((Component)source).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				string name = ((Object)componentsInChildren[i]).name;
				if (IsMovingCollider(name))
				{
					return true;
				}
			}
			return false;
		}

		private Transform BuildMovingBlade(Transform source, out Collider[] colliders)
		{
			//IL_000d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = source.parent;
			Transform transform = new GameObject("StilettoBlade").transform;
			transform.SetParent(parent, false);
			transform.localPosition = source.localPosition;
			transform.localRotation = DeployedRot;
			transform.localScale = Vector3.one;
			MeshFilter componentInChildren = ((Component)source).GetComponentInChildren<MeshFilter>(true);
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMesh != (Object)null)
			{
				((Component)transform).gameObject.AddComponent<MeshFilter>().sharedMesh = componentInChildren.sharedMesh;
				MeshRenderer component = ((Component)componentInChildren).GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)((Component)transform).gameObject.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)component).sharedMaterials;
				}
			}
			List<Collider> list = new List<Collider>();
			Il2CppArrayBase<Collider> componentsInChildren = ((Component)source).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				string name = ((Object)componentsInChildren[i]).name;
				if (IsMovingCollider(name))
				{
					((Component)componentsInChildren[i]).transform.SetParent(transform, true);
					list.Add(componentsInChildren[i]);
				}
			}
			colliders = list.ToArray();
			return transform;
		}

		private void UpgradeAll()
		{
			Il2CppArrayBase<MeleeWeaponWrapper> val = Object.FindObjectsOfType<MeleeWeaponWrapper>();
			for (int i = 0; i < val.Length; i++)
			{
				MeleeWeaponWrapper val2 = val[i];
				if (!((Object)(object)val2 == (Object)null))
				{
					MeleeScriptableObject meleeWeaponSO = val2.meleeWeaponSO;
					if (!((Object)(object)meleeWeaponSO == (Object)null) && !(meleeWeaponSO.weaponName != "Stiletto Knife"))
					{
						TryUpgrade(val2);
					}
				}
			}
		}

		private void TryUpgrade(MeleeWeaponWrapper w)
		{
			Transform val = ((Component)w).transform.Find("BladeDeployed");
			Transform val2 = ((Component)w).transform.Find("BladeFolded");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				MelonLogger.Warning($"Stiletto: found a Stiletto named '{((Object)((Component)w).transform).name}' but it has no {"BladeDeployed"}/{"BladeFolded"}. The bundle layout changed; update this mod.");
			}
			else if (seenHinges.Add(((Object)val).GetInstanceID()))
			{
				if (!HasBladeColliders(val))
				{
					MelonLogger.Warning("Stiletto: no blade colliders under BladeDeployed; check the builder.");
					seenHinges.Remove(((Object)val).GetInstanceID());
					return;
				}
				Collider[] colliders;
				Transform val3 = BuildMovingBlade(val, out colliders);
				DisableVisuals(val);
				DisableVisuals(val2);
				((Component)val).gameObject.SetActive(false);
				((Component)val2).gameObject.SetActive(false);
				Blade item = new Blade
				{
					hinge = val,
					moving = val3,
					dummy = val,
					colliders = colliders,
					wrapper = w,
					deployed = true,
					dummyWasActive = false
				};
				blades.Add(item);
				w.hasEvents = false;
				MelonLogger.Msg($"Stiletto: upgraded '{((Object)((Component)w).transform).name}' (id {((Object)val).GetInstanceID()}), hinged blade on '{((Object)val3).name}' with {colliders.Length} collider(s), " + "bundle dummies switched off");
				LogAncestry(w);
			}
		}
	}
}