Decompiled source of MEM ThirdPerson CameraFix v1.0.0

MEM-ThirdPerson_CameraFix.dll

Decompiled 7 hours ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace MEM.ThirdPersonCameraFix;

[BepInPlugin("com.mem.thirdperson.camerafix", "MEM-ThirdPerson_CameraFix", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CameraFixPlugin : BaseUnityPlugin
{
	private static CameraFixPlugin _self;

	private static Type _pluginType;

	private static object _pluginInstance;

	private static bool _loggedMissing;

	private static PropertyInfo _instanceProp;

	private static FieldInfo _lockRuntimeField;

	private static FieldInfo _currentDistanceField;

	private static FieldInfo _defaultDistanceField;

	private static FieldInfo _scrollSensitivityField;

	private static FieldInfo _keyZoomSpeedField;

	private static FieldInfo _zoomInKeyField;

	private static FieldInfo _zoomOutKeyField;

	private static FieldInfo _minDistanceField;

	private static FieldInfo _maxDistanceField;

	private static FieldInfo _runtimeOffsetXField;

	private static FieldInfo _runtimeOffsetYField;

	private static FieldInfo _startingOffsetXField;

	private static FieldInfo _startingOffsetYField;

	private static FieldInfo _offsetAdjustSpeedField;

	private static FieldInfo _resetOffsetsKeyField;

	private static MethodInfo _canAcceptZoomInputMethod;

	private static MethodInfo _canAcceptOffsetInputMethod;

	private static MethodInfo _logCameraSettingsMethod;

	private static MethodInfo _isKeyPressedThisFrameMethod;

	private static MethodInfo _isKeyHeldMethod;

	private void Awake()
	{
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Expected O, but got Unknown
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Expected O, but got Unknown
		//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Expected O, but got Unknown
		_self = this;
		try
		{
			_pluginType = AccessTools.TypeByName("RepoThirdPerson.Plugin");
			if (_pluginType == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"RepoThirdPerson.Plugin type not found");
				return;
			}
			_instanceProp = AccessTools.Property(_pluginType, "Instance");
			_lockRuntimeField = AccessTools.Field(_pluginType, "_lockRuntimeCameraTuning");
			_currentDistanceField = AccessTools.Field(_pluginType, "_currentDistance");
			_defaultDistanceField = AccessTools.Field(_pluginType, "_defaultDistance");
			_scrollSensitivityField = AccessTools.Field(_pluginType, "_scrollSensitivity");
			_keyZoomSpeedField = AccessTools.Field(_pluginType, "_keyZoomSpeed");
			_zoomInKeyField = AccessTools.Field(_pluginType, "_zoomInKey");
			_zoomOutKeyField = AccessTools.Field(_pluginType, "_zoomOutKey");
			_minDistanceField = AccessTools.Field(_pluginType, "_minDistance");
			_maxDistanceField = AccessTools.Field(_pluginType, "_maxDistance");
			_runtimeOffsetXField = AccessTools.Field(_pluginType, "_runtimeOffsetX");
			_runtimeOffsetYField = AccessTools.Field(_pluginType, "_runtimeOffsetY");
			_startingOffsetXField = AccessTools.Field(_pluginType, "_startingOffsetX");
			_startingOffsetYField = AccessTools.Field(_pluginType, "_startingOffsetY");
			_offsetAdjustSpeedField = AccessTools.Field(_pluginType, "_offsetAdjustSpeed");
			_resetOffsetsKeyField = AccessTools.Field(_pluginType, "_resetOffsetsKey");
			_canAcceptZoomInputMethod = AccessTools.Method(_pluginType, "CanAcceptZoomInput", (Type[])null, (Type[])null);
			_canAcceptOffsetInputMethod = AccessTools.Method(_pluginType, "CanAcceptOffsetInput", (Type[])null, (Type[])null);
			_logCameraSettingsMethod = AccessTools.Method(_pluginType, "LogCameraSettings", new Type[1] { typeof(string) }, (Type[])null);
			_isKeyPressedThisFrameMethod = AccessTools.Method(_pluginType, "IsKeyPressedThisFrame", new Type[1] { typeof(KeyCode) }, (Type[])null);
			_isKeyHeldMethod = AccessTools.Method(_pluginType, "IsKeyHeld", new Type[1] { typeof(KeyCode) }, (Type[])null);
			Harmony val = new Harmony("com.mem.thirdperson.camerafix");
			MethodInfo methodInfo = AccessTools.Method(_pluginType, "HandleZoomInput", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(CameraFixPlugin), "HandleZoomInputPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.Method(_pluginType, "HandleOffsetInput", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(CameraFixPlugin), "HandleOffsetInputPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(_pluginType, "GetEffectiveCameraOffsetX", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				val.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(CameraFixPlugin), "GetEffectiveCameraOffsetXPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched zoom + symmetric horizontal offset (v1.0.0)");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Camera fix failed: " + ex));
		}
	}

	private static bool TryGetPluginInstance()
	{
		if (_pluginInstance != null)
		{
			return true;
		}
		if (_pluginType == null)
		{
			return false;
		}
		try
		{
			if (_instanceProp != null)
			{
				_pluginInstance = _instanceProp.GetValue(null, null);
			}
			if (_pluginInstance == null)
			{
				PropertyInfo[] properties = _pluginType.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (propertyInfo.PropertyType == _pluginType)
					{
						_pluginInstance = propertyInfo.GetValue(null, null);
						if (_pluginInstance != null)
						{
							break;
						}
					}
				}
			}
		}
		catch
		{
		}
		if (_pluginInstance == null && !_loggedMissing && (Object)(object)_self != (Object)null)
		{
			_loggedMissing = true;
			((BaseUnityPlugin)_self).Logger.LogWarning((object)"Could not resolve RepoThirdPerson.Plugin.Instance yet");
		}
		return _pluginInstance != null;
	}

	private static T GetConfigValue<T>(FieldInfo field, T fallback)
	{
		try
		{
			if (field == null || _pluginInstance == null)
			{
				return fallback;
			}
			object value = field.GetValue(_pluginInstance);
			if (value == null)
			{
				return fallback;
			}
			PropertyInfo property = value.GetType().GetProperty("Value");
			if (property == null)
			{
				return fallback;
			}
			return (T)property.GetValue(value, null);
		}
		catch
		{
			return fallback;
		}
	}

	private static float GetFloatField(FieldInfo field, float fallback)
	{
		try
		{
			if (field == null || _pluginInstance == null)
			{
				return fallback;
			}
			return (float)field.GetValue(_pluginInstance);
		}
		catch
		{
			return fallback;
		}
	}

	private static void SetFloatField(FieldInfo field, float value)
	{
		try
		{
			if (field != null && _pluginInstance != null)
			{
				field.SetValue(_pluginInstance, value);
			}
		}
		catch
		{
		}
	}

	private static bool CallBoolMethod(MethodInfo method, params object[] args)
	{
		try
		{
			if (method == null)
			{
				return true;
			}
			object obj = ((!method.IsStatic) ? _pluginInstance : null);
			return (bool)method.Invoke(obj, args);
		}
		catch
		{
			return true;
		}
	}

	private static void LogSettings(string reason)
	{
		try
		{
			if (_logCameraSettingsMethod != null && _pluginInstance != null)
			{
				_logCameraSettingsMethod.Invoke(_pluginInstance, new object[1] { reason });
			}
		}
		catch
		{
		}
	}

	public static bool GetEffectiveCameraOffsetXPrefix(ref float __result)
	{
		if (!TryGetPluginInstance())
		{
			return true;
		}
		__result = GetFloatField(_runtimeOffsetXField, 0.45f);
		return false;
	}

	public static bool HandleZoomInputPrefix()
	{
		//IL_00c4: 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_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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!TryGetPluginInstance())
			{
				return false;
			}
			bool configValue = GetConfigValue(_lockRuntimeField, fallback: false);
			float num = GetFloatField(_currentDistanceField, 3f);
			if (configValue)
			{
				float configValue2 = GetConfigValue(_defaultDistanceField, 3f);
				SetFloatField(_currentDistanceField, ClampDistance(configValue2));
				return false;
			}
			if (!CallBoolMethod(_canAcceptZoomInputMethod))
			{
				return false;
			}
			float num2 = num;
			float num3 = ReadScrollSafe();
			if (Mathf.Abs(num3) > 0.001f)
			{
				float configValue3 = GetConfigValue(_scrollSensitivityField, 1f);
				num -= num3 * configValue3;
			}
			float configValue4 = GetConfigValue(_keyZoomSpeedField, 5f);
			KeyCode configValue5 = GetConfigValue<KeyCode>(_zoomInKeyField, (KeyCode)270);
			KeyCode configValue6 = GetConfigValue<KeyCode>(_zoomOutKeyField, (KeyCode)269);
			if (Input.GetKey(configValue5))
			{
				num -= configValue4 * Time.deltaTime;
			}
			if (Input.GetKey(configValue6))
			{
				num += configValue4 * Time.deltaTime;
			}
			num = ClampDistance(num);
			SetFloatField(_currentDistanceField, num);
			if (Mathf.Abs(num - num2) > 0.001f)
			{
				LogSettings("Camera distance adjusted");
			}
		}
		catch (Exception ex)
		{
			if ((Object)(object)_self != (Object)null)
			{
				((BaseUnityPlugin)_self).Logger.LogWarning((object)("HandleZoomInputPrefix: " + ex.Message));
			}
		}
		return false;
	}

	public static bool HandleOffsetInputPrefix()
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!TryGetPluginInstance())
			{
				return false;
			}
			bool configValue = GetConfigValue(_lockRuntimeField, fallback: false);
			float floatField = GetFloatField(_startingOffsetXField, 0.45f);
			float floatField2 = GetFloatField(_startingOffsetYField, 1.55f);
			if (configValue)
			{
				SetFloatField(_runtimeOffsetXField, floatField);
				SetFloatField(_runtimeOffsetYField, floatField2);
				return false;
			}
			if (!CallBoolMethod(_canAcceptOffsetInputMethod))
			{
				return false;
			}
			KeyCode configValue2 = GetConfigValue<KeyCode>(_resetOffsetsKeyField, (KeyCode)278);
			bool flag = false;
			if ((!(_isKeyPressedThisFrameMethod != null)) ? Input.GetKeyDown(configValue2) : CallBoolMethod(_isKeyPressedThisFrameMethod, configValue2))
			{
				SetFloatField(_runtimeOffsetXField, floatField);
				SetFloatField(_runtimeOffsetYField, floatField2);
				float configValue3 = GetConfigValue(_defaultDistanceField, 3f);
				SetFloatField(_currentDistanceField, ClampDistance(configValue3));
				LogSettings("Camera offset reset");
				return false;
			}
			float num = GetConfigValue(_offsetAdjustSpeedField, 1f) * Time.deltaTime;
			if (num <= 0f)
			{
				return false;
			}
			float floatField3 = GetFloatField(_runtimeOffsetXField, floatField);
			float floatField4 = GetFloatField(_runtimeOffsetYField, floatField2);
			float num2 = floatField3;
			float num3 = floatField4;
			bool flag2 = ((!(_isKeyHeldMethod != null)) ? Input.GetKey((KeyCode)276) : CallBoolMethod(_isKeyHeldMethod, (object)(KeyCode)276));
			bool flag3 = ((!(_isKeyHeldMethod != null)) ? Input.GetKey((KeyCode)275) : CallBoolMethod(_isKeyHeldMethod, (object)(KeyCode)275));
			bool flag4 = ((!(_isKeyHeldMethod != null)) ? Input.GetKey((KeyCode)273) : CallBoolMethod(_isKeyHeldMethod, (object)(KeyCode)273));
			bool flag5 = ((!(_isKeyHeldMethod != null)) ? Input.GetKey((KeyCode)274) : CallBoolMethod(_isKeyHeldMethod, (object)(KeyCode)274));
			if (flag2)
			{
				num2 -= num;
			}
			if (flag3)
			{
				num2 += num;
			}
			if (flag4)
			{
				num3 += num;
			}
			if (flag5)
			{
				num3 -= num;
			}
			if (num2 < -2f)
			{
				num2 = -2f;
			}
			if (num2 > 2f)
			{
				num2 = 2f;
			}
			SetFloatField(_runtimeOffsetXField, num2);
			SetFloatField(_runtimeOffsetYField, num3);
			if (Mathf.Abs(num2 - floatField3) > 0.001f || Mathf.Abs(num3 - floatField4) > 0.001f)
			{
				LogSettings("Camera offset adjusted");
			}
		}
		catch (Exception ex)
		{
			if ((Object)(object)_self != (Object)null)
			{
				((BaseUnityPlugin)_self).Logger.LogWarning((object)("HandleOffsetInputPrefix: " + ex.Message));
			}
		}
		return false;
	}

	private static float ReadScrollSafe()
	{
		//IL_0014: 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_0049: 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)
		try
		{
			if (Mouse.current != null)
			{
				float y = ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y;
				if (Mathf.Abs(y) > 0.001f)
				{
					return Mathf.Sign(y);
				}
			}
		}
		catch
		{
		}
		try
		{
			float y2 = Input.mouseScrollDelta.y;
			if (Mathf.Abs(y2) > 0.001f)
			{
				return Mathf.Sign(y2);
			}
		}
		catch
		{
		}
		return 0f;
	}

	private static float ClampDistance(float value)
	{
		float configValue = GetConfigValue(_minDistanceField, 0.8f);
		float configValue2 = GetConfigValue(_maxDistanceField, 8f);
		return Mathf.Clamp(value, configValue, configValue2);
	}
}