using System;
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 Microsoft.CodeAnalysis;
using Unity.XR.CoreUtils;
using UnityEngine;
[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("SpectatorCameraPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SpectatorCameraPlus")]
[assembly: AssemblyTitle("SpectatorCameraPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 SpectatorCameraPlus
{
[BepInPlugin("com.mrbub.spectatorcameraplus", "SpectatorCameraPlus", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static ConfigEntry<float> PositionSmoothTime;
public static ConfigEntry<float> RotationSmoothTime;
public static ConfigEntry<float> FieldOfView;
public static ConfigEntry<bool> SmoothingEnabled;
public static ConfigEntry<float> NearClipPlane;
public static ConfigEntry<bool> StabilizationEnabled;
public static ConfigEntry<float> StabilizationStrength;
public static ConfigEntry<float> RotationDeadzone;
public static ConfigEntry<float> PositionDeadzone;
private SpectatorCameraController _cameraController;
public static Plugin Instance { get; private set; }
public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;
private void Awake()
{
Instance = this;
InitConfig();
((BaseUnityPlugin)this).Logger.LogInfo((object)"SpectatorCameraPlus v1.0.0 loaded!");
}
private void InitConfig()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Expected O, but got Unknown
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Expected O, but got Unknown
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Expected O, but got Unknown
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Expected O, but got Unknown
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Expected O, but got Unknown
PositionSmoothTime = ((BaseUnityPlugin)this).Config.Bind<float>("Smoothing", "PositionSmoothTime", 0.15f, new ConfigDescription("Position smoothing time in seconds (lower = snappier, higher = smoother)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
RotationSmoothTime = ((BaseUnityPlugin)this).Config.Bind<float>("Smoothing", "RotationSmoothTime", 0.1f, new ConfigDescription("Rotation smoothing time in seconds (lower = snappier, higher = smoother)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
SmoothingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Smoothing", "Enabled", true, "Enable camera smoothing for a less jarring spectator view");
FieldOfView = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "FieldOfView", 90f, new ConfigDescription("Spectator camera field of view", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 120f), Array.Empty<object>()));
NearClipPlane = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "NearClipPlane", 0.01f, new ConfigDescription("Near clip plane distance (lower = less clipping through nearby objects)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.3f), Array.Empty<object>()));
StabilizationEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Stabilization", "Enabled", true, "Enable camera stabilization to reduce shakiness from rapid head movements");
StabilizationStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Stabilization", "Strength", 0.7f, new ConfigDescription("How much to dampen rapid movements (0 = none, 1 = maximum)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
RotationDeadzone = ((BaseUnityPlugin)this).Config.Bind<float>("Stabilization", "RotationDeadzone", 2f, new ConfigDescription("Ignore rotation changes smaller than this (degrees per second)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
PositionDeadzone = ((BaseUnityPlugin)this).Config.Bind<float>("Stabilization", "PositionDeadzone", 0.01f, new ConfigDescription("Ignore position changes smaller than this (meters per second)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>()));
}
private void Update()
{
if (!((Object)(object)_cameraController != (Object)null) && (!((Object)(object)Camera.main == (Object)null) || Camera.allCamerasCount != 0))
{
_cameraController = SpectatorCameraController.Create();
((BaseUnityPlugin)this).Logger.LogInfo((object)"SpectatorCameraController initialized");
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.mrbub.spectatorcameraplus";
public const string PLUGIN_NAME = "SpectatorCameraPlus";
public const string PLUGIN_VERSION = "1.0.0";
}
public class SpectatorCameraController : MonoBehaviour
{
private Camera _spectatorCamera;
private Transform _targetTransform;
private Camera _vrCamera;
private Vector3 _currentVelocity;
private Vector3 _smoothedPosition;
private Quaternion _smoothedRotation;
private bool _initialized;
private Vector3 _lastTargetPosition;
private Quaternion _lastTargetRotation;
private Vector3 _stabilizedTargetPosition;
private Quaternion _stabilizedTargetRotation;
private Vector3 _positionVelocity;
private float _angularVelocity;
public static SpectatorCameraController Create()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
GameObject val = new GameObject("SpectatorCameraPlus");
Object.DontDestroyOnLoad((Object)val);
return val.AddComponent<SpectatorCameraController>();
}
private void Awake()
{
_spectatorCamera = ((Component)this).gameObject.AddComponent<Camera>();
_spectatorCamera.stereoTargetEye = (StereoTargetEyeMask)0;
_spectatorCamera.depth = 100f;
_spectatorCamera.fieldOfView = Plugin.FieldOfView.Value;
_spectatorCamera.targetTexture = null;
Plugin.Log.LogInfo((object)"Spectator camera created");
}
private void Start()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
FindTargetTransform();
CopyVRCameraSettings();
if ((Object)(object)_targetTransform != (Object)null)
{
_smoothedPosition = _targetTransform.position;
_smoothedRotation = _targetTransform.rotation;
_lastTargetPosition = _targetTransform.position;
_lastTargetRotation = _targetTransform.rotation;
_stabilizedTargetPosition = _targetTransform.position;
_stabilizedTargetRotation = _targetTransform.rotation;
_initialized = true;
}
}
private void CopyVRCameraSettings()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_spectatorCamera == (Object)null))
{
_spectatorCamera.nearClipPlane = Plugin.NearClipPlane.Value;
if ((Object)(object)_vrCamera != (Object)null)
{
_spectatorCamera.farClipPlane = _vrCamera.farClipPlane;
_spectatorCamera.cullingMask = _vrCamera.cullingMask;
_spectatorCamera.clearFlags = _vrCamera.clearFlags;
_spectatorCamera.backgroundColor = _vrCamera.backgroundColor;
}
}
}
private void FindTargetTransform()
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
XROrigin val = Object.FindObjectOfType<XROrigin>();
if ((Object)(object)val != (Object)null && (Object)(object)val.Camera != (Object)null)
{
_targetTransform = ((Component)val.Camera).transform;
_vrCamera = val.Camera;
Plugin.Log.LogInfo((object)("Target found via XROrigin: " + ((Object)_targetTransform).name));
return;
}
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
_targetTransform = ((Component)main).transform;
_vrCamera = main;
Plugin.Log.LogInfo((object)("Target found via Camera.main: " + ((Object)_targetTransform).name));
return;
}
Camera[] allCameras = Camera.allCameras;
foreach (Camera val2 in allCameras)
{
if ((int)val2.stereoTargetEye != 0)
{
_targetTransform = ((Component)val2).transform;
_vrCamera = val2;
Plugin.Log.LogInfo((object)("Target found via stereo camera: " + ((Object)_targetTransform).name));
return;
}
}
if (Camera.allCamerasCount > 0)
{
Camera val3 = Camera.allCameras[0];
_targetTransform = ((Component)val3).transform;
_vrCamera = val3;
Plugin.Log.LogInfo((object)("Fallback target: " + ((Object)_targetTransform).name));
}
}
private void LateUpdate()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: 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_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_targetTransform == (Object)null)
{
FindTargetTransform();
return;
}
if (!_initialized)
{
_smoothedPosition = _targetTransform.position;
_smoothedRotation = _targetTransform.rotation;
_lastTargetPosition = _targetTransform.position;
_lastTargetRotation = _targetTransform.rotation;
_stabilizedTargetPosition = _targetTransform.position;
_stabilizedTargetRotation = _targetTransform.rotation;
_initialized = true;
CopyVRCameraSettings();
}
_spectatorCamera.fieldOfView = Plugin.FieldOfView.Value;
_spectatorCamera.nearClipPlane = Plugin.NearClipPlane.Value;
Vector3 stabilizedPos;
Quaternion stabilizedRot;
if (Plugin.StabilizationEnabled.Value)
{
ApplyStabilization(out stabilizedPos, out stabilizedRot);
}
else
{
stabilizedPos = _targetTransform.position;
stabilizedRot = _targetTransform.rotation;
}
if (Plugin.SmoothingEnabled.Value)
{
_smoothedPosition = Vector3.SmoothDamp(_smoothedPosition, stabilizedPos, ref _currentVelocity, Plugin.PositionSmoothTime.Value);
_smoothedRotation = Quaternion.Slerp(_smoothedRotation, stabilizedRot, 1f - Mathf.Exp(-10f / Plugin.RotationSmoothTime.Value * Time.deltaTime));
((Component)this).transform.position = _smoothedPosition;
((Component)this).transform.rotation = _smoothedRotation;
}
else
{
((Component)this).transform.position = stabilizedPos;
((Component)this).transform.rotation = stabilizedRot;
_smoothedPosition = stabilizedPos;
_smoothedRotation = stabilizedRot;
}
_lastTargetPosition = _targetTransform.position;
_lastTargetRotation = _targetTransform.rotation;
}
private void ApplyStabilization(out Vector3 stabilizedPos, out Quaternion stabilizedRot)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: 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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: 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_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: 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_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
float deltaTime = Time.deltaTime;
if (deltaTime <= 0f)
{
stabilizedPos = _stabilizedTargetPosition;
stabilizedRot = _stabilizedTargetRotation;
return;
}
float value = Plugin.StabilizationStrength.Value;
Vector3 val = _targetTransform.position - _lastTargetPosition;
_positionVelocity = val / deltaTime;
float num = Quaternion.Angle(_lastTargetRotation, _targetTransform.rotation);
_angularVelocity = num / deltaTime;
if (((Vector3)(ref _positionVelocity)).magnitude < Plugin.PositionDeadzone.Value)
{
stabilizedPos = _stabilizedTargetPosition;
}
else
{
float num2 = Mathf.Lerp(1f, 0.1f, value);
_stabilizedTargetPosition = Vector3.Lerp(_stabilizedTargetPosition, _targetTransform.position, num2);
stabilizedPos = _stabilizedTargetPosition;
}
if (_angularVelocity < Plugin.RotationDeadzone.Value)
{
stabilizedRot = _stabilizedTargetRotation;
return;
}
float num3 = (_angularVelocity - Plugin.RotationDeadzone.Value) / 90f;
num3 = Mathf.Clamp01(num3);
float num4 = Mathf.Lerp(0.05f, 1f, num3) * Mathf.Lerp(1f, 0.3f, value);
_stabilizedTargetRotation = Quaternion.Slerp(_stabilizedTargetRotation, _targetTransform.rotation, num4);
stabilizedRot = _stabilizedTargetRotation;
}
public void SnapToTarget()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: 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)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_targetTransform == (Object)null))
{
_smoothedPosition = _targetTransform.position;
_smoothedRotation = _targetTransform.rotation;
_stabilizedTargetPosition = _targetTransform.position;
_stabilizedTargetRotation = _targetTransform.rotation;
_currentVelocity = Vector3.zero;
((Component)this).transform.position = _smoothedPosition;
((Component)this).transform.rotation = _smoothedRotation;
}
}
}
}