Decompiled source of ThirdPersonMod v1.0.0

BepInEx/plugins/ThirdPersonMod.dll

Decompiled 8 hours 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ThirdPersonMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("第三人称相机mod")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a4ba00dda8158de92c3c4f8e568fd467b16de89d")]
[assembly: AssemblyProduct("ThirdPersonMod")]
[assembly: AssemblyTitle("ThirdPersonMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 ThirdPersonMod
{
	[BepInPlugin("camera.patcher.mod", "ThirdPersonMod", "1.0.0")]
	public class CameraPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<float> Sensitivity;

		internal static ConfigEntry<float> CamDist;

		internal static ConfigEntry<float> OffsetX;

		internal static ConfigEntry<float> OffsetY;

		internal static ConfigEntry<float> ConvergeDist;

		internal static ConfigEntry<float> RayOriginPush;

		private void Awake()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Sensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "鼠标灵敏度", 0.12f, "每像素鼠标位移对应的转向速度");
			CamDist = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "相机距离", 1.4f, "第三人称相机与角色的距离(米)");
			OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "水平偏移", -0.6f, "相机向左偏移量,越负人物越靠屏幕右侧");
			OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "垂直偏移", 0.4f, "相机向上偏移量,越大人物越靠屏幕下方");
			ConvergeDist = ((BaseUnityPlugin)this).Config.Bind<float>("瞄准", "汇聚距离", 40f, "准星线汇聚到视轴的距离(米),一般不用改");
			RayOriginPush = ((BaseUnityPlugin)this).Config.Bind<float>("瞄准", "射线校正", 0.3f, "拾取手感微调:捡近处物品差一点点就加大");
			new Harmony("camera.patcher.mod").PatchAll();
			RenderPipelineManager.beginCameraRendering += delegate
			{
				PatchThirdPerson.EnsureBodyVisible();
			};
			Log.LogInfo((object)"[ThirdPersonMod] 加载完成,B键切换第一/第三人称");
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "camera.patcher.mod";

		public const string Name = "ThirdPersonMod";

		public const string Version = "1.0.0";
	}
	[HarmonyPatch]
	public static class PatchThirdPerson
	{
		public class CamState
		{
			public bool thirdPerson;

			public float yaw;

			public float pitch = 12f;

			public float dist;
		}

		private static Type _cameraType;

		private static FieldInfo _followField;

		private static MethodBase _target;

		private static readonly Dictionary<Component, CamState> _states = new Dictionary<Component, CamState>();

		private static int? _origMask;

		private static Transform _cachedRoot;

		private static Renderer[] _cachedRenderers;

		private static readonly Dictionary<Renderer, ShadowCastingMode> _origShadowModes = new Dictionary<Renderer, ShadowCastingMode>();

		public static CamState CurrentState { get; private set; }

		public static Transform CurrentFollow { get; private set; }

		public static Vector3 EyeOffset { get; private set; } = Vector3.up * 1.55f;

		public static Type FindCameraType()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (type.Name == "ExampleCharacterCamera")
					{
						return type;
					}
				}
			}
			return null;
		}

		private static bool Prepare()
		{
			_cameraType = FindCameraType();
			if (_cameraType == null)
			{
				return false;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo[] fields = _cameraType.GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(Transform)))
				{
					if (fieldInfo.Name.Contains("Follow"))
					{
						_followField = fieldInfo;
						break;
					}
					if (_followField == null)
					{
						_followField = fieldInfo;
					}
				}
			}
			_target = _cameraType.GetMethod("UpdateWithInput", bindingAttr) ?? _cameraType.GetMethod("Update", bindingAttr) ?? _cameraType.GetMethod("LateUpdate", bindingAttr);
			return _target != null;
		}

		private static MethodBase TargetMethod()
		{
			return _target;
		}

		public static void EnsureBodyVisible()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			CamState currentState = CurrentState;
			Transform currentFollow = CurrentFollow;
			if (currentState == null || (Object)(object)currentFollow == (Object)null || !currentState.thirdPerson)
			{
				return;
			}
			Transform root = currentFollow.root;
			if (_cachedRenderers == null || (Object)(object)_cachedRoot != (Object)(object)root)
			{
				_cachedRoot = root;
				_cachedRenderers = ((Component)root).GetComponentsInChildren<Renderer>(true);
			}
			Renderer[] cachedRenderers = _cachedRenderers;
			foreach (Renderer val in cachedRenderers)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (!_origShadowModes.TryGetValue(val, out var _))
				{
					_origShadowModes[val] = val.shadowCastingMode;
				}
				if ((int)val.shadowCastingMode != 1)
				{
					val.shadowCastingMode = (ShadowCastingMode)1;
				}
				SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
				if (val2 != null && !((Component)val2).gameObject.activeInHierarchy)
				{
					((Component)val2).gameObject.SetActive(true);
					Transform parent = ((Component)val2).transform.parent;
					while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root && !((Component)parent).gameObject.activeInHierarchy)
					{
						((Component)parent).gameObject.SetActive(true);
						parent = parent.parent;
					}
				}
			}
		}

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

		private static void Postfix(Component __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			if (_followField == null)
			{
				return;
			}
			Mouse current = Mouse.current;
			Keyboard current2 = Keyboard.current;
			if (current == null || current2 == null || (int)Cursor.lockState != 1)
			{
				return;
			}
			object? value = _followField.GetValue(__instance);
			Transform val = (Transform)((value is Transform) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (!_states.TryGetValue(__instance, out var value2))
			{
				value2 = new CamState
				{
					yaw = __instance.transform.eulerAngles.y,
					dist = CameraPlugin.CamDist.Value
				};
				_states[__instance] = value2;
				CameraPlugin.Log.LogInfo((object)("[ThirdPersonMod] 已接管相机(B键切换),锚定: " + ((Object)val).name));
			}
			CurrentState = value2;
			CurrentFollow = val;
			Camera component = __instance.GetComponent<Camera>();
			if ((Object)(object)component != (Object)null && !_origMask.HasValue)
			{
				_origMask = component.cullingMask;
			}
			if (((ButtonControl)current2.bKey).wasPressedThisFrame)
			{
				value2.thirdPerson = !value2.thirdPerson;
				CameraPlugin.Log.LogInfo((object)(value2.thirdPerson ? "[ThirdPersonMod] 第三人称" : "[ThirdPersonMod] 第一人称"));
				if (value2.thirdPerson)
				{
					Vector3 eulerAngles = __instance.transform.eulerAngles;
					value2.yaw = eulerAngles.y;
					value2.pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
				}
			}
			Renderer[] cachedRenderers;
			if (!value2.thirdPerson)
			{
				if ((Object)(object)component != (Object)null && _origMask.HasValue)
				{
					component.cullingMask = _origMask.Value;
				}
				EyeOffset = __instance.transform.position - val.position;
				if (_cachedRenderers == null)
				{
					return;
				}
				cachedRenderers = _cachedRenderers;
				foreach (Renderer val2 in cachedRenderers)
				{
					if ((Object)(object)val2 != (Object)null && _origShadowModes.TryGetValue(val2, out var value3))
					{
						val2.shadowCastingMode = value3;
					}
				}
				return;
			}
			Vector2 val3 = ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue();
			value2.yaw += val3.x * CameraPlugin.Sensitivity.Value;
			value2.pitch = Mathf.Clamp(value2.pitch - val3.y * CameraPlugin.Sensitivity.Value, -35f, 70f);
			value2.dist = CameraPlugin.CamDist.Value;
			int num = 1 << ((Component)val).gameObject.layer;
			cachedRenderers = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in cachedRenderers)
			{
				num |= 1 << ((Component)val4).gameObject.layer;
			}
			if ((Object)(object)component != (Object)null)
			{
				component.cullingMask = (_origMask ?? component.cullingMask) | num;
			}
			Transform transform = __instance.transform;
			Quaternion val5 = Quaternion.Euler(value2.pitch, value2.yaw, 0f);
			Vector3 val6 = val.position + EyeOffset;
			Vector3 val7 = val5 * Vector3.back;
			Vector3 val8 = val5 * new Vector3(CameraPlugin.OffsetX.Value, CameraPlugin.OffsetY.Value, 0f);
			float num2 = value2.dist;
			Vector3 val9 = val6 + val7 * num2 + val8;
			Vector3 val10 = val9 - val6;
			RaycastHit[] array = Physics.RaycastAll(val6, ((Vector3)(ref val10)).normalized, num2);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val11 = array[i];
				if (!((RaycastHit)(ref val11)).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref val11)).collider).transform == (Object)(object)val) && !((Component)((RaycastHit)(ref val11)).collider).transform.IsChildOf(val))
				{
					num2 = Mathf.Min(num2, ((RaycastHit)(ref val11)).distance);
				}
			}
			num2 = Mathf.Max(num2 - 0.05f, 0.25f);
			transform.position = val6 + val7 * num2 + val8;
			transform.rotation = val5;
			EnsureBodyVisible();
		}
	}
	[HarmonyPatch(typeof(PlayerInteraction), "InteractionRay")]
	public static class PatchInteractionRay
	{
		private static bool _moved;

		private static Vector3 _pos;

		private static Quaternion _rot;

		private static Camera _gameCam;

		private static Camera GetGameCamera()
		{
			if ((Object)(object)_gameCam != (Object)null)
			{
				return _gameCam;
			}
			PlayerInteraction val = Object.FindObjectOfType<PlayerInteraction>();
			if ((Object)(object)val != (Object)null)
			{
				object? obj = typeof(PlayerInteraction).GetField("mainCamera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val);
				_gameCam = (Camera)((obj is Camera) ? obj : null);
			}
			if ((Object)(object)_gameCam == (Object)null)
			{
				_gameCam = Camera.main;
			}
			return _gameCam;
		}

		private static void Prefix()
		{
			//IL_0037: 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_0047: 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_0062: 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_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_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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00a9: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_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_00e4: Unknown result type (might be due to invalid IL or missing references)
			PatchThirdPerson.CamState currentState = PatchThirdPerson.CurrentState;
			Transform currentFollow = PatchThirdPerson.CurrentFollow;
			if (currentState != null && !((Object)(object)currentFollow == (Object)null) && currentState.thirdPerson)
			{
				Camera gameCamera = GetGameCamera();
				if (!((Object)(object)gameCamera == (Object)null))
				{
					_pos = ((Component)gameCamera).transform.position;
					_rot = ((Component)gameCamera).transform.rotation;
					Quaternion val = Quaternion.Euler(currentState.pitch, currentState.yaw, 0f);
					Vector3 val2 = currentFollow.position + PatchThirdPerson.EyeOffset;
					Vector3 val3 = val2 + val * Vector3.forward * CameraPlugin.ConvergeDist.Value - _pos;
					Vector3 normalized = ((Vector3)(ref val3)).normalized;
					float num = Vector3.Distance(_pos, val2) + CameraPlugin.RayOriginPush.Value;
					((Component)gameCamera).transform.SetPositionAndRotation(_pos + normalized * num, Quaternion.LookRotation(normalized));
					_moved = true;
				}
			}
		}

		private static void Postfix()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (_moved)
			{
				Camera gameCamera = GetGameCamera();
				if ((Object)(object)gameCamera != (Object)null)
				{
					((Component)gameCamera).transform.SetPositionAndRotation(_pos, _rot);
				}
				_moved = false;
			}
		}
	}
}