Decompiled source of SelfCam v0.1.1

SelfCam.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SelfCam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+74055779b1a902632814c8c1932fdea642c0b55b")]
[assembly: AssemblyProduct("SelfCam")]
[assembly: AssemblyTitle("SelfCam")]
[assembly: AssemblyVersion("0.1.1.0")]
[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 QuarterViewSelfCam
{
	[BepInPlugin("erick.straftat.selfcam", "SelfCam", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "erick.straftat.selfcam";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<KeyboardShortcut> PlaceKey;

		internal static ConfigEntry<KeyboardShortcut> LockKey;

		internal static ConfigEntry<KeyboardShortcut> DelayDownKey;

		internal static ConfigEntry<KeyboardShortcut> DelayUpKey;

		internal static ConfigEntry<KeyboardShortcut> ScreenshotKey;

		internal static ConfigEntry<float> Delay;

		internal static ConfigEntry<float> Fov;

		private void Awake()
		{
			//IL_0042: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for the self-cam PIP.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)111, Array.Empty<KeyCode>()), "Show/hide the PIP (on/off).");
			PlaceKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "PlaceKey", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Drop the camera at head level; it stays there and keeps looking at your head.");
			LockKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "LockKey", new KeyboardShortcut((KeyCode)108, Array.Empty<KeyCode>()), "Lock/unlock: toggle between tracking your head and holding the current view.");
			DelayDownKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "DelayDownKey", new KeyboardShortcut((KeyCode)91, Array.Empty<KeyCode>()), "Decrease replay delay ( [ ).");
			DelayUpKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "DelayUpKey", new KeyboardShortcut((KeyCode)93, Array.Empty<KeyCode>()), "Increase replay delay ( ] ).");
			ScreenshotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ScreenshotKey", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), "Save a full-resolution PNG of the self-cam view to your Pictures folder.");
			Delay = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Delay", 0f, new ConfigDescription("Replay delay in seconds: the PIP shows you this many seconds in the past (0 = live). Adjust live with [ and ].", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			Fov = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Fov", 100f, new ConfigDescription("Self-cam field of view (deg).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 100f), Array.Empty<object>()));
			GameObject val = new GameObject("SelfCam")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<SelfCam>();
			Log.LogInfo((object)"SelfCam loaded.");
		}
	}
	public class SelfCam : MonoBehaviour
	{
		private const int BodyLayer = 16;

		private const int WeaponLayer = 8;

		private const int HudLayer = 25;

		private const int PipWidth = 480;

		private const int PipHeight = 270;

		private const int Margin = 16;

		private const int RingN = 150;

		private const float SampleInterval = 1f / 30f;

		private const float HeadHeightFallback = 1.55f;

		private Camera _cam;

		private RawImage _image;

		private RenderTexture[] _ring;

		private float[] _ringT;

		private int _head;

		private float _lastStamp = -999f;

		private bool _visible = true;

		private bool _failed;

		private int _lastAllowed = -1;

		private object _currentFpc;

		private PlayerHealth _health;

		private Renderer[] _parts;

		private int _scanFrame;

		private int _selfCamLayer = -1;

		private Vector3 _placedPos;

		private bool _placeRequested;

		private bool _shotRequested;

		private bool _locked;

		private GameObject _marker;

		private Material _markerMat;

		private Text _delayText;

		private void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: 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_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			_ring = (RenderTexture[])(object)new RenderTexture[150];
			_ringT = new float[150];
			for (int i = 0; i < 150; i++)
			{
				_ring[i] = new RenderTexture(480, 270, 16);
				_ringT[i] = -1f;
			}
			GameObject val = new GameObject("SelfCamCamera");
			val.transform.SetParent(((Component)this).transform, false);
			_cam = val.AddComponent<Camera>();
			((Behaviour)_cam).enabled = false;
			GameObject val2 = new GameObject("SelfCamCanvas");
			val2.transform.SetParent(((Component)this).transform, false);
			Canvas obj = val2.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 30000;
			GameObject val3 = new GameObject("SelfCamImage");
			val3.transform.SetParent(val2.transform, false);
			_image = val3.AddComponent<RawImage>();
			_image.texture = (Texture)(object)_ring[0];
			((Graphic)_image).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)_image).rectTransform;
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(1f, 0f);
			rectTransform.pivot = val4;
			Vector2 anchorMin = (rectTransform.anchorMax = val4);
			rectTransform.anchorMin = anchorMin;
			rectTransform.sizeDelta = new Vector2(480f, 270f);
			rectTransform.anchoredPosition = new Vector2(-16f, 16f);
			GameObject val6 = new GameObject("SelfCamDelayText");
			val6.transform.SetParent(val2.transform, false);
			_delayText = val6.AddComponent<Text>();
			_delayText.font = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial", "Liberation Sans", "DejaVu Sans", "sans-serif" }, 16);
			_delayText.fontSize = 16;
			_delayText.fontStyle = (FontStyle)1;
			((Graphic)_delayText).color = Color.white;
			_delayText.alignment = (TextAnchor)8;
			((Graphic)_delayText).raycastTarget = false;
			_delayText.horizontalOverflow = (HorizontalWrapMode)1;
			RectTransform rectTransform2 = ((Graphic)_delayText).rectTransform;
			((Vector2)(ref val4))..ctor(1f, 0f);
			rectTransform2.pivot = val4;
			anchorMin = (rectTransform2.anchorMax = val4);
			rectTransform2.anchorMin = anchorMin;
			rectTransform2.sizeDelta = new Vector2(480f, 22f);
			rectTransform2.anchoredPosition = new Vector2(-16f, 288f);
			_marker = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)_marker).name = "SelfCamMarker";
			Collider component = _marker.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			_marker.transform.SetParent(((Component)this).transform, false);
			_marker.transform.localScale = Vector3.one * 0.2f;
			MeshRenderer component2 = _marker.GetComponent<MeshRenderer>();
			((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component2).receiveShadows = false;
			_markerMat = ((Renderer)component2).material;
			_markerMat.EnableKeyword("_EMISSION");
			Hide();
		}

		private void Update()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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)
			//IL_00df: 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)
			if (!_failed)
			{
				KeyboardShortcut value = Plugin.ToggleKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					_visible = !_visible;
				}
				value = Plugin.PlaceKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					_placeRequested = true;
				}
				value = Plugin.LockKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					_locked = !_locked;
				}
				value = Plugin.DelayDownKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Plugin.Delay.Value = Mathf.Max(0f, Plugin.Delay.Value - 0.25f);
				}
				value = Plugin.DelayUpKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Plugin.Delay.Value = Mathf.Min(5f, Plugin.Delay.Value + 0.25f);
				}
				value = Plugin.ScreenshotKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					_shotRequested = true;
				}
			}
		}

		private void LateUpdate()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			if (_failed)
			{
				return;
			}
			try
			{
				bool flag = PracticeContextAllowed();
				if ((flag ? 1 : 0) != _lastAllowed)
				{
					_lastAllowed = (flag ? 1 : 0);
					bool flag2 = false;
					bool flag3 = false;
					try
					{
						flag2 = (Object)(object)PauseManager.Instance != (Object)null && PauseManager.Instance.nonSteamworksTransport;
					}
					catch
					{
					}
					try
					{
						flag3 = (Object)(object)SceneMotor.Instance != (Object)null && SceneMotor.Instance.testMap;
					}
					catch
					{
					}
					ManualLogSource log = Plugin.Log;
					object[] obj3 = new object[4] { flag, flag2, flag3, null };
					Scene activeScene = SceneManager.GetActiveScene();
					obj3[3] = ((Scene)(ref activeScene)).name;
					log.LogInfo((object)string.Format("[SelfCam] gate: allowed={0} offline={1} testMap={2} scene={3}", obj3));
				}
				if (!Plugin.Enabled.Value || !_visible || !flag || MenuOpen())
				{
					Hide();
					return;
				}
				FirstPersonController val = (((Object)(object)Settings.Instance != (Object)null) ? Settings.Instance.localPlayer : null);
				if ((Object)(object)val == (Object)null)
				{
					RestoreBody();
					Hide();
					return;
				}
				Camera playerCamera = val.playerCamera;
				Vector3 val2 = (((Object)(object)playerCamera != (Object)null) ? ((Component)playerCamera).transform.position : (((Component)val).transform.position + Vector3.up * 1.55f));
				if (val != _currentFpc)
				{
					_currentFpc = val;
					_placedPos = val2;
					_parts = null;
					_health = ((Component)val).GetComponent<PlayerHealth>() ?? ((Component)val).GetComponentInParent<PlayerHealth>() ?? ((Component)val).GetComponentInChildren<PlayerHealth>(true);
				}
				if ((Object)(object)_health != (Object)null && _health.health <= 0f)
				{
					RestoreBody();
					Hide();
					return;
				}
				if (_parts == null || ++_scanFrame >= 30)
				{
					_scanFrame = 0;
					List<Renderer> list = new List<Renderer>();
					Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val3 in componentsInChildren)
					{
						if (!(val3 is MeshRenderer) && !(val3 is SkinnedMeshRenderer))
						{
							continue;
						}
						int layer = ((Component)val3).gameObject.layer;
						if (layer != 8 && layer != 25 && !((Object)val3).name.EndsWith("_Col", StringComparison.Ordinal) && ((Object)val3).name.IndexOf("upression", StringComparison.Ordinal) < 0)
						{
							SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val3 is SkinnedMeshRenderer) ? val3 : null);
							if (val4 != null)
							{
								val4.updateWhenOffscreen = true;
							}
							list.Add(val3);
						}
					}
					_parts = list.ToArray();
				}
				if (_placeRequested)
				{
					_placeRequested = false;
					_placedPos = val2;
				}
				if ((Object)(object)playerCamera != (Object)null)
				{
					if (_selfCamLayer < 0)
					{
						for (int num = 31; num >= 8; num--)
						{
							if (num != 16 && (playerCamera.cullingMask & (1 << num)) == 0)
							{
								_selfCamLayer = num;
								break;
							}
						}
					}
					if (_parts != null && _selfCamLayer >= 0)
					{
						Transform transform = ((Component)val).transform;
						Renderer[] componentsInChildren = _parts;
						foreach (Renderer val5 in componentsInChildren)
						{
							if ((Object)(object)val5 == (Object)null)
							{
								continue;
							}
							((Component)val5).gameObject.layer = _selfCamLayer;
							Transform val6 = ((Component)val5).transform;
							while ((Object)(object)val6 != (Object)null && val6 != transform)
							{
								if (!((Component)val6).gameObject.activeSelf)
								{
									((Component)val6).gameObject.SetActive(true);
								}
								val6 = val6.parent;
							}
						}
					}
					_cam.cullingMask = playerCamera.cullingMask | 0x10000 | ((_selfCamLayer >= 0) ? (1 << _selfCamLayer) : 0);
					_cam.clearFlags = playerCamera.clearFlags;
					_cam.backgroundColor = playerCamera.backgroundColor;
					_cam.nearClipPlane = playerCamera.nearClipPlane;
					_cam.farClipPlane = playerCamera.farClipPlane;
				}
				_cam.fieldOfView = Plugin.Fov.Value;
				((Component)_cam).transform.position = _placedPos;
				if (!_locked)
				{
					Vector3 val7 = val2 - _placedPos;
					if (((Vector3)(ref val7)).sqrMagnitude > 0.0001f)
					{
						((Component)_cam).transform.rotation = Quaternion.LookRotation(val7, Vector3.up);
					}
				}
				float time = Time.time;
				float num2 = time - Plugin.Delay.Value;
				int num3 = -1;
				float num4 = float.MaxValue;
				for (int j = 0; j < 150; j++)
				{
					if (j != _head && !(_ringT[j] < 0f))
					{
						float num5 = Mathf.Abs(_ringT[j] - num2);
						if (num5 < num4)
						{
							num4 = num5;
							num3 = j;
						}
					}
				}
				if (num3 >= 0)
				{
					_image.texture = (Texture)(object)_ring[num3];
				}
				_cam.targetTexture = _ring[_head];
				if (time - _lastStamp >= 1f / 30f)
				{
					_ringT[_head] = time;
					_lastStamp = time;
					_head = (_head + 1) % 150;
				}
				if (_shotRequested)
				{
					_shotRequested = false;
					CaptureScreenshot();
				}
				Show();
			}
			catch (Exception ex)
			{
				_failed = true;
				Hide();
				Plugin.Log.LogError((object)("QuarterView SelfCam disabled after error: " + ex));
			}
		}

		private static bool PracticeContextAllowed()
		{
			try
			{
				PauseManager instance = PauseManager.Instance;
				if ((Object)(object)instance != (Object)null && instance.nonSteamworksTransport)
				{
					return true;
				}
				SceneMotor instance2 = SceneMotor.Instance;
				if ((Object)(object)instance2 != (Object)null && instance2.testMap)
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		private void RestoreBody()
		{
			if (_parts == null)
			{
				return;
			}
			Renderer[] parts = _parts;
			foreach (Renderer val in parts)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.layer == _selfCamLayer)
				{
					((Component)val).gameObject.layer = 16;
				}
			}
			_parts = null;
		}

		private static bool MenuOpen()
		{
			try
			{
				PauseManager instance = PauseManager.Instance;
				return (Object)(object)instance != (Object)null && (instance.pause || instance.inVictoryMenu || instance.onEndRoundScreen);
			}
			catch
			{
				return false;
			}
		}

		private void CaptureScreenshot()
		{
			//IL_0144: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_017d: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00df: Expected O, but got Unknown
			try
			{
				int num;
				int num2;
				byte[] bytes;
				if (Plugin.Delay.Value <= 0.001f)
				{
					num = Screen.width;
					num2 = Screen.height;
					if (num < 320)
					{
						num = 1920;
					}
					if (num2 < 240)
					{
						num2 = 1080;
					}
					RenderTexture val = new RenderTexture(num, num2, 24);
					RenderTexture targetTexture = _cam.targetTexture;
					RenderTexture active = RenderTexture.active;
					_cam.targetTexture = val;
					_cam.aspect = (float)num / (float)num2;
					_cam.Render();
					RenderTexture.active = val;
					Texture2D val2 = new Texture2D(num, num2, (TextureFormat)3, false);
					val2.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0);
					val2.Apply();
					RenderTexture.active = active;
					_cam.targetTexture = targetTexture;
					_cam.ResetAspect();
					bytes = ImageConversion.EncodeToPNG(val2);
					Object.Destroy((Object)val2);
					val.Release();
					Object.Destroy((Object)(object)val);
				}
				else
				{
					Texture texture = _image.texture;
					RenderTexture val3 = (RenderTexture)(object)((texture is RenderTexture) ? texture : null);
					if ((Object)(object)val3 == (Object)null)
					{
						Plugin.Log.LogWarning((object)"SelfCam screenshot: no buffered frame yet.");
						return;
					}
					num = ((Texture)val3).width;
					num2 = ((Texture)val3).height;
					RenderTexture active2 = RenderTexture.active;
					RenderTexture.active = val3;
					Texture2D val4 = new Texture2D(num, num2, (TextureFormat)3, false);
					val4.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0);
					val4.Apply();
					RenderTexture.active = active2;
					bytes = ImageConversion.EncodeToPNG(val4);
					Object.Destroy((Object)val4);
				}
				string text = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
				if (string.IsNullOrEmpty(text))
				{
					text = Application.persistentDataPath;
				}
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				string text2 = Path.Combine(text, $"SelfCam_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png");
				File.WriteAllBytes(text2, bytes);
				Plugin.Log.LogInfo((object)$"SelfCam screenshot saved: {text2} ({num}x{num2})");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("SelfCam screenshot failed: " + ex));
			}
		}

		private void Show()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)_cam).enabled = true;
			((Behaviour)_image).enabled = true;
			if ((Object)(object)_delayText != (Object)null)
			{
				((Behaviour)_delayText).enabled = true;
				_delayText.text = ((Plugin.Delay.Value <= 0.001f) ? "LIVE" : $"-{Plugin.Delay.Value:0.00}s");
			}
			if ((Object)(object)_marker != (Object)null)
			{
				_marker.transform.position = _placedPos;
				if (!_marker.activeSelf)
				{
					_marker.SetActive(true);
				}
				Color val = (_locked ? new Color(1f, 0.35f, 0.2f) : new Color(0.2f, 0.9f, 1f));
				_markerMat.color = val;
				_markerMat.SetColor("_EmissionColor", val * 2f);
			}
		}

		private void Hide()
		{
			if ((Object)(object)_cam != (Object)null)
			{
				((Behaviour)_cam).enabled = false;
			}
			if ((Object)(object)_image != (Object)null)
			{
				((Behaviour)_image).enabled = false;
			}
			if ((Object)(object)_delayText != (Object)null)
			{
				((Behaviour)_delayText).enabled = false;
			}
			if ((Object)(object)_marker != (Object)null && _marker.activeSelf)
			{
				_marker.SetActive(false);
			}
			if (_ringT != null)
			{
				for (int i = 0; i < _ringT.Length; i++)
				{
					_ringT[i] = -1f;
				}
				_head = 0;
				_lastStamp = -999f;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_cam != (Object)null)
			{
				_cam.targetTexture = null;
			}
			if (_ring == null)
			{
				return;
			}
			RenderTexture[] ring = _ring;
			foreach (RenderTexture val in ring)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Release();
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
}