Decompiled source of TitanStrength v1.0.1

Mods/TitanStrength.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppSLZ.VRMK;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using TitanStrength;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(TitanStrengthMod), "Titan Strength", "1.0.0", "ChappieStudios", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("TitanStrength")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TitanStrength")]
[assembly: AssemblyTitle("TitanStrength")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TitanStrength
{
	public sealed class TitanStrengthMod : MelonMod
	{
		private const float MenuStep = 5f;

		private const float MenuMin = 1f;

		private const float MenuMax = float.MaxValue;

		private MelonPreferences_Category _category;

		private MelonPreferences_Entry<bool> _enabled;

		private MelonPreferences_Entry<float> _strengthMultiplier;

		private MelonPreferences_Entry<float> _physHandMultiplier;

		private readonly Dictionary<string, float> _originalValues = new Dictionary<string, float>();

		private float _nextApplyTime;

		private bool _menuRegistered;

		public override void OnInitializeMelon()
		{
			_category = MelonPreferences.CreateCategory("TitanStrength");
			_enabled = _category.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_strengthMultiplier = _category.CreateEntry<float>("AvatarStrengthMultiplier", 50f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_physHandMultiplier = _category.CreateEntry<float>("HandForceMultiplier", 30f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			RegisterBoneMenu();
			((MelonBase)this).LoggerInstance.Msg("Titan Strength loaded. BoneMenu toggle is under Mods > Titan Strength. F8 toggles it too.");
		}

		public override void OnUpdate()
		{
			if (Input.GetKeyDown((KeyCode)289))
			{
				SetEnabled(!_enabled.Value);
			}
			if (!(Time.time < _nextApplyTime))
			{
				_nextApplyTime = Time.time + 0.75f;
				if (_enabled.Value)
				{
					ApplyStrength();
				}
				else
				{
					RestoreOriginals();
				}
			}
		}

		public override void OnDeinitializeMelon()
		{
			RestoreOriginals();
		}

		private void RegisterBoneMenu()
		{
			//IL_0023: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (_menuRegistered)
			{
				return;
			}
			try
			{
				Page obj = Page.Root.CreatePage("Titan Strength", new Color(1f, 0.25f, 0.05f), 0, true);
				obj.CreateBool("Enabled", Color.green, _enabled.Value, (Action<bool>)SetEnabled);
				obj.CreateFloat("Avatar Strength", Color.yellow, _strengthMultiplier.Value, 5f, 1f, float.MaxValue, (Action<float>)delegate(float value)
				{
					_strengthMultiplier.Value = value;
					_category.SaveToFile(false);
					if (_enabled.Value)
					{
						ClearCachedOriginalsForReapply();
						ApplyStrength();
					}
				});
				obj.CreateFloat("Hand Force", Color.cyan, _physHandMultiplier.Value, 5f, 1f, float.MaxValue, (Action<float>)delegate(float value)
				{
					_physHandMultiplier.Value = value;
					_category.SaveToFile(false);
					if (_enabled.Value)
					{
						ClearCachedOriginalsForReapply();
						ApplyStrength();
					}
				});
				obj.CreateFunction("Reapply Now", Color.white, (Action)ApplyStrength);
				_menuRegistered = true;
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("BoneMenu registration failed, F8 fallback still works: " + ex.Message);
			}
		}

		private void SetEnabled(bool enabled)
		{
			_enabled.Value = enabled;
			_category.SaveToFile(false);
			if (enabled)
			{
				ApplyStrength();
				((MelonBase)this).LoggerInstance.Msg("Titan Strength enabled.");
			}
			else
			{
				RestoreOriginals();
				((MelonBase)this).LoggerInstance.Msg("Titan Strength disabled.");
			}
		}

		private void ApplyStrength()
		{
			Avatar avatar = Player.Avatar;
			if ((Object)(object)avatar != (Object)null)
			{
				BoostFloatProperty(avatar, "_strengthUpper", _strengthMultiplier.Value);
				BoostFloatProperty(avatar, "_strengthLower", _strengthMultiplier.Value);
				BoostFloatProperty(avatar, "_strengthGrip", _strengthMultiplier.Value);
			}
			BoostHand(Player.LeftHand, "Left");
			BoostHand(Player.RightHand, "Right");
		}

		private void BoostHand(object hand, string side)
		{
			if (hand != null)
			{
				InvokeIfExists(hand, "SetGripStrength", _strengthMultiplier.Value);
				object propertyOrField = GetPropertyOrField(hand, "physHand");
				if (propertyOrField != null)
				{
					BoostFloatProperty(propertyOrField, "_forceMultiplier", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "gripMult", _strengthMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "xPosForce", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "xNegForce", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "yPosForce", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "yNegForce", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "zPosForce", _physHandMultiplier.Value, side + ".");
					BoostFloatProperty(propertyOrField, "zNegForce", _physHandMultiplier.Value, side + ".");
				}
			}
		}

		private void BoostFloatProperty(object target, string name, float multiplier, string prefix = "")
		{
			Type type = target.GetType();
			string key = prefix + type.FullName + "." + name;
			MemberInfo memberInfo = FindPropertyOrField(type, name);
			if (memberInfo == null)
			{
				return;
			}
			float? num = ReadFloat(target, memberInfo);
			if (num.HasValue)
			{
				if (!_originalValues.ContainsKey(key))
				{
					_originalValues[key] = num.Value;
				}
				float value = Mathf.Max(_originalValues[key] * multiplier, multiplier);
				WriteFloat(target, memberInfo, value);
			}
		}

		private void RestoreOriginals()
		{
			Avatar avatar = Player.Avatar;
			if ((Object)(object)avatar != (Object)null)
			{
				RestoreFloatProperty(avatar, "_strengthUpper");
				RestoreFloatProperty(avatar, "_strengthLower");
				RestoreFloatProperty(avatar, "_strengthGrip");
			}
			RestoreHand(Player.LeftHand, "Left");
			RestoreHand(Player.RightHand, "Right");
		}

		private void RestoreHand(object hand, string side)
		{
			if (hand == null)
			{
				return;
			}
			object propertyOrField = GetPropertyOrField(hand, "physHand");
			if (propertyOrField != null)
			{
				string[] array = new string[8] { "_forceMultiplier", "gripMult", "xPosForce", "xNegForce", "yPosForce", "yNegForce", "zPosForce", "zNegForce" };
				foreach (string name in array)
				{
					RestoreFloatProperty(propertyOrField, name, side + ".");
				}
			}
		}

		private void RestoreFloatProperty(object target, string name, string prefix = "")
		{
			Type type = target.GetType();
			string key = prefix + type.FullName + "." + name;
			if (_originalValues.TryGetValue(key, out var value))
			{
				MemberInfo memberInfo = FindPropertyOrField(type, name);
				if (memberInfo != null)
				{
					WriteFloat(target, memberInfo, value);
				}
			}
		}

		private void ClearCachedOriginalsForReapply()
		{
			RestoreOriginals();
			_originalValues.Clear();
		}

		private static MemberInfo FindPropertyOrField(Type type, string name)
		{
			return (MemberInfo)(((object)type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
		}

		private static float? ReadFloat(object target, MemberInfo member)
		{
			try
			{
				if (member is PropertyInfo propertyInfo && propertyInfo.PropertyType == typeof(float))
				{
					return (float)propertyInfo.GetValue(target);
				}
				if (member is FieldInfo fieldInfo && fieldInfo.FieldType == typeof(float))
				{
					return (float)fieldInfo.GetValue(target);
				}
			}
			catch
			{
			}
			return null;
		}

		private static void WriteFloat(object target, MemberInfo member, float value)
		{
			try
			{
				if (member is PropertyInfo propertyInfo)
				{
					if (propertyInfo.CanWrite && propertyInfo.PropertyType == typeof(float))
					{
						propertyInfo.SetValue(target, value);
					}
				}
				else if (member is FieldInfo fieldInfo && fieldInfo.FieldType == typeof(float))
				{
					fieldInfo.SetValue(target, value);
				}
			}
			catch
			{
			}
		}

		private static object GetPropertyOrField(object target, string name)
		{
			MemberInfo memberInfo = FindPropertyOrField(target.GetType(), name);
			try
			{
				if (memberInfo is PropertyInfo propertyInfo)
				{
					return propertyInfo.GetValue(target);
				}
				if (memberInfo is FieldInfo fieldInfo)
				{
					return fieldInfo.GetValue(target);
				}
			}
			catch
			{
			}
			return null;
		}

		private static void InvokeIfExists(object target, string name, params object[] args)
		{
			try
			{
				target.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(target, args);
			}
			catch
			{
			}
		}
	}
}