Decompiled source of FreecamSpectate v1.0.1

FreecamSpectate.dll

Decompiled 7 hours ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FreecamSpectate;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FreecamSpectate")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FreecamSpectate")]
[assembly: AssemblyTitle("FreecamSpectate")]
[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;
		}
	}
}
internal static class ReflectionHelper
{
	internal readonly struct ReflectedMember<T>
	{
		private readonly Delegate invokeDelegate;

		private readonly Delegate setDelegate;

		internal T value
		{
			get
			{
				return (T)(invokeDelegate?.DynamicInvoke());
			}
			set
			{
				setDelegate?.DynamicInvoke(value);
			}
		}

		internal ReflectedMember(Delegate invokeDelegate, Delegate setDelegate)
		{
			this.invokeDelegate = invokeDelegate;
			this.setDelegate = setDelegate;
		}

		internal T Invoke(object arg)
		{
			return (T)(invokeDelegate?.DynamicInvoke(arg));
		}

		internal T Invoke(params object[] args)
		{
			return (T)(invokeDelegate?.DynamicInvoke(new object[1] { args }));
		}
	}

	internal readonly struct ReflectedMember
	{
		private readonly Delegate invokeDelegate;

		internal ReflectedMember(Delegate invokeDelegate)
		{
			this.invokeDelegate = invokeDelegate;
		}

		internal void Invoke(params object[] args)
		{
			invokeDelegate?.DynamicInvoke(new object[1] { args });
		}
	}

	private const BindingFlags allBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

	internal static ReflectedMember<T> GetPrivateMember<T>(this object instance, string memberName, params Type[] methodArguments)
	{
		Type type = instance.GetType();
		if (instance is Type type2)
		{
			type = type2;
			instance = null;
		}
		MemberInfo[] member = type.GetMember(memberName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		MemberInfo memberInfo = member.Length switch
		{
			0 => throw new NullReferenceException("Member \"" + memberName + "\" cannot be found."), 
			1 => member[0], 
			_ => member.Cast<MethodInfo>().SingleOrDefault((MethodInfo methodInfo) => (from paramInfo in methodInfo.GetParameters()
				select paramInfo.ParameterType).SequenceEqual(methodArguments)), 
		};
		FieldInfo fieldInfo = memberInfo as FieldInfo;
		if ((object)fieldInfo == null)
		{
			PropertyInfo propertyInfo = memberInfo as PropertyInfo;
			if ((object)propertyInfo == null)
			{
				MethodInfo methodInfo2 = memberInfo as MethodInfo;
				if ((object)methodInfo2 != null)
				{
					return new ReflectedMember<T>((Func<object[], object>)((object[] args) => methodInfo2.Invoke(instance, args)), null);
				}
				return default(ReflectedMember<T>);
			}
			return new ReflectedMember<T>((Func<object>)(() => propertyInfo.GetValue(instance)), (Action<T>)delegate(T value)
			{
				propertyInfo.SetValue(instance, value);
			});
		}
		return new ReflectedMember<T>((Func<object>)(() => fieldInfo.GetValue(instance)), (Action<T>)delegate(T value)
		{
			fieldInfo.SetValue(instance, value);
		});
	}

	internal static ReflectedMember GetPrivateMember(this object instance, string memberName, params Type[] methodArguments)
	{
		Type type = instance.GetType();
		if (instance is Type type2)
		{
			type = type2;
			instance = null;
		}
		try
		{
			MethodInfo method = type.GetMethod(memberName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			return new ReflectedMember((Func<object[], object>)((object[] args) => method.Invoke(instance, args)));
		}
		catch (Exception ex)
		{
			Entry.logger.LogMessage((object)ex);
			throw;
		}
	}
}
namespace FreecamSpectate
{
	[BepInPlugin("nickklmao.freecamspectate", "Freecam Spectate", "1.0.0")]
	internal sealed class Entry : BaseUnityPlugin
	{
		internal static readonly ManualLogSource logger = Logger.CreateLogSource("Freecam Spectate");

		private static bool freecamToggle;

		private static void StateNormal_Hook(Action<SpectateCamera> orig, SpectateCamera self)
		{
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: 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)
			if (((ButtonControl)Keyboard.current[(Key)40]).wasPressedThisFrame)
			{
				freecamToggle = !freecamToggle;
			}
			if (!freecamToggle)
			{
				orig(self);
				return;
			}
			ReflectionHelper.ReflectedMember<bool> privateMember = self.GetPrivateMember<bool>("stateImpulse", Array.Empty<Type>());
			Camera value = self.GetPrivateMember<Camera>("MainCamera", Array.Empty<Type>()).value;
			PlayerAvatar value2 = self.GetPrivateMember<PlayerAvatar>("player", Array.Empty<Type>()).value;
			ReflectionHelper.ReflectedMember privateMember2 = self.GetPrivateMember("PlayerSwitch");
			if (privateMember.value)
			{
				privateMember2.Invoke(true);
				if (!Object.op_Implicit((Object)(object)value2))
				{
					return;
				}
				RenderSettings.fog = true;
				value.fieldOfView = self.GetPrivateMember<float>("previousFieldOfView", Array.Empty<Type>()).value;
				self.GetPrivateMember<Camera>("TopCamera", Array.Empty<Type>()).value.fieldOfView = value.fieldOfView;
				((Component)value).transform.localPosition = Vector3.zero;
				((Component)value).transform.localRotation = Quaternion.identity;
				AudioManager.instance.AudioListener.TargetPositionTransform = ((Component)value).transform;
				privateMember.value = false;
			}
			float num = SemiFunc.InputMouseX();
			float num2 = SemiFunc.InputMouseY();
			float num3 = CameraAim.Instance.AimSpeedMouse * 1.5f;
			ReflectionHelper.ReflectedMember<float> privateMember3 = self.GetPrivateMember<float>("normalAimHorizontal", Array.Empty<Type>());
			ReflectionHelper.ReflectedMember<float> privateMember4 = self.GetPrivateMember<float>("normalAimVertical", Array.Empty<Type>());
			privateMember3.value += num * num3;
			privateMember4.value -= num2 * num3;
			privateMember4.value = Mathf.Clamp(privateMember4.value, -90f, 90f);
			if (Mouse.current.middleButton.wasPressedThisFrame)
			{
				((Component)self).transform.position = value2.spectatePoint.position;
				((Component)self).transform.rotation = self.normalTransformDistance.rotation;
			}
			else
			{
				((Component)self).transform.rotation = Quaternion.Euler(privateMember4.value, privateMember3.value, 0f);
				Vector2 val = SemiFunc.InputMovement();
				Vector3 val2 = ((Component)self).transform.forward * val.y + ((Component)self).transform.right * val.x + Vector3.up * (float)((SemiFunc.InputHold((InputKey)1) || ((ButtonControl)Keyboard.current[(Key)19]).isPressed) ? 1 : ((SemiFunc.InputHold((InputKey)12) || ((ButtonControl)Keyboard.current[(Key)31]).isPressed) ? (-1) : 0));
				if (((Vector3)(ref val2)).sqrMagnitude > 1f)
				{
					((Vector3)(ref val2)).Normalize();
				}
				val2 *= (SemiFunc.InputHold((InputKey)15) ? 2f : 1f);
				((Component)self).transform.position = Vector3.Lerp(((Component)self).transform.position, ((Component)self).transform.position + val2, Time.deltaTime * 10f);
			}
			value.nearClipPlane = (RenderSettings.fogStartDistance = 0.1f);
			value.farClipPlane = 10000f;
			if (SemiFunc.InputDown((InputKey)23))
			{
				privateMember2.Invoke(true);
			}
			else if (SemiFunc.InputDown((InputKey)24))
			{
				privateMember2.Invoke(false);
			}
			if (Object.op_Implicit((Object)(object)value2) && value2.GetPrivateMember<bool>("voiceChatFetched", Array.Empty<Type>()).value)
			{
				value2.GetPrivateMember<PlayerVoiceChat>("voiceChat", Array.Empty<Type>()).value.SpatialDisable(0.1f);
			}
		}

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			logger.LogDebug((object)"Hooking `SpectateCamera.StateNormal`");
			new Hook((MethodBase)AccessTools.Method(typeof(SpectateCamera), "StateNormal", (Type[])null, (Type[])null), (Delegate)new Action<Action<SpectateCamera>, SpectateCamera>(StateNormal_Hook));
			logger.LogMessage((object)"While spectating, you can press \"Z\" to toggle freecam. Middle mouse button will teleport your camera back to the player you're spectating.");
		}
	}
}