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.");
}
}
}