Decompiled source of FishVisuals v1.10.4

FishVisuals.dll

Decompiled 18 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using FishyUI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SpongeMods.ModMenu;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;

[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("FishVisuals")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FishVisuals")]
[assembly: AssemblyTitle("FishVisuals")]
[assembly: AssemblyVersion("1.0.0.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 FishVisuals
{
	internal static class ColorEffects
	{
		private static GameObject _root;

		private static Volume _volume;

		private static ColorAdjustments _color;

		private static WhiteBalance _whiteBalance;

		private static Vignette _vignette;

		private static Bloom _bloom;

		internal static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_volume != (Object)null))
			{
				_root = new GameObject("FishVisuals.ColorEffects");
				Object.DontDestroyOnLoad((Object)(object)_root);
				((Object)_root).hideFlags = (HideFlags)61;
				_volume = _root.AddComponent<Volume>();
				_volume.isGlobal = true;
				_volume.priority = 100f;
				_volume.weight = 1f;
				_volume.profile = ScriptableObject.CreateInstance<VolumeProfile>();
				((Object)_volume.profile).hideFlags = (HideFlags)61;
				_color = _volume.profile.Add<ColorAdjustments>(true);
				_whiteBalance = _volume.profile.Add<WhiteBalance>(true);
				_vignette = _volume.profile.Add<Vignette>(true);
				_bloom = _volume.profile.Add<Bloom>(true);
				Apply();
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Color effects volume ready");
				}
			}
		}

		internal static void Apply()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.FxEnabled != null)
			{
				Ensure();
				bool value = Plugin.FxEnabled.Value;
				((Behaviour)_volume).enabled = value;
				_volume.weight = (value ? 1f : 0f);
				if ((Object)(object)_color != (Object)null)
				{
					((VolumeComponent)_color).active = value;
					Set(_color.postExposure, Plugin.FxBrightness.Value);
					Set((FloatParameter)(object)_color.contrast, Plugin.FxContrast.Value);
					Set((FloatParameter)(object)_color.saturation, Plugin.FxSaturation.Value);
					Set((FloatParameter)(object)_color.hueShift, Plugin.FxHue.Value);
					Set(_color.colorFilter, Plugin.FxTint.Value);
				}
				if ((Object)(object)_whiteBalance != (Object)null)
				{
					((VolumeComponent)_whiteBalance).active = value;
					Set((FloatParameter)(object)_whiteBalance.temperature, Plugin.FxTemperature.Value);
					Set((FloatParameter)(object)_whiteBalance.tint, Plugin.FxWbTint.Value);
				}
				if ((Object)(object)_vignette != (Object)null)
				{
					bool active = value && Plugin.FxVignette.Value > 0.001f;
					((VolumeComponent)_vignette).active = active;
					Set((FloatParameter)(object)_vignette.intensity, Plugin.FxVignette.Value);
					Set((FloatParameter)(object)_vignette.smoothness, 0.4f);
					Set(_vignette.color, Color.black);
				}
				if ((Object)(object)_bloom != (Object)null)
				{
					bool active2 = value && Plugin.FxBloom.Value > 0.001f;
					((VolumeComponent)_bloom).active = active2;
					Set((FloatParameter)(object)_bloom.intensity, Plugin.FxBloom.Value);
					Set((FloatParameter)(object)_bloom.threshold, Plugin.FxBloomThreshold.Value);
					Set((FloatParameter)(object)_bloom.scatter, 0.7f);
				}
			}
		}

		internal static void ResetDefaults()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.FxBrightness != null)
			{
				Plugin.FxBrightness.Value = 0f;
			}
			if (Plugin.FxContrast != null)
			{
				Plugin.FxContrast.Value = 0f;
			}
			if (Plugin.FxSaturation != null)
			{
				Plugin.FxSaturation.Value = 0f;
			}
			if (Plugin.FxHue != null)
			{
				Plugin.FxHue.Value = 0f;
			}
			if (Plugin.FxTint != null)
			{
				Plugin.FxTint.Value = Color.white;
			}
			if (Plugin.FxTemperature != null)
			{
				Plugin.FxTemperature.Value = 0f;
			}
			if (Plugin.FxWbTint != null)
			{
				Plugin.FxWbTint.Value = 0f;
			}
			if (Plugin.FxVignette != null)
			{
				Plugin.FxVignette.Value = 0f;
			}
			if (Plugin.FxBloom != null)
			{
				Plugin.FxBloom.Value = 0f;
			}
			if (Plugin.FxBloomThreshold != null)
			{
				Plugin.FxBloomThreshold.Value = 1f;
			}
			Apply();
		}

		private static void Set(FloatParameter p, float value)
		{
			if (p != null)
			{
				((VolumeParameter)p).overrideState = true;
				((VolumeParameter<float>)(object)p).value = value;
			}
		}

		private static void Set(ColorParameter p, Color value)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (p != null)
			{
				((VolumeParameter)p).overrideState = true;
				((VolumeParameter<Color>)(object)p).value = value;
			}
		}

		private static void Set(BoolParameter p, bool value)
		{
			if (p != null)
			{
				((VolumeParameter)p).overrideState = true;
				((VolumeParameter<bool>)(object)p).value = value;
			}
		}
	}
	[Serializable]
	internal class VisualProfile
	{
		public string name = "Profile";

		public bool vmEnabled = true;

		public float offsetX;

		public float offsetY;

		public float offsetZ;

		public bool stretchEnabled;

		public int aspectPreset;

		public float stretchAmount = 1f;

		public float horizontalScale = 1f;

		public bool fxEnabled;

		public float fxBrightness;

		public float fxContrast;

		public float fxSaturation;

		public float fxHue;

		public float tintR = 1f;

		public float tintG = 1f;

		public float tintB = 1f;

		public float tintA = 1f;

		public float fxTemperature;

		public float fxWbTint;

		public float fxVignette;

		public float fxBloom;

		public float fxBloomThreshold = 1f;
	}
	internal static class ConfigProfiles
	{
		private static string Folder
		{
			get
			{
				string text = Path.Combine(Paths.ConfigPath, "FishVisuals", "profiles");
				Directory.CreateDirectory(text);
				return text;
			}
		}

		internal static string[] ListNames()
		{
			try
			{
				return Directory.GetFiles(Folder, "*.json").Select(Path.GetFileNameWithoutExtension).OrderBy<string, string>((string n) => n, StringComparer.OrdinalIgnoreCase)
					.ToArray();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Profile list failed: " + ex.Message));
				}
				return Array.Empty<string>();
			}
		}

		internal static VisualProfile CaptureCurrent(string name)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_019b: Unknown result type (might be due to invalid IL or missing references)
			Color val = Plugin.FxTint?.Value ?? Color.white;
			return new VisualProfile
			{
				name = SanitizeName(name),
				vmEnabled = (Plugin.Enabled?.Value ?? true),
				offsetX = (Plugin.OffsetX?.Value ?? 0f),
				offsetY = (Plugin.OffsetY?.Value ?? 0f),
				offsetZ = (Plugin.OffsetZ?.Value ?? 0f),
				stretchEnabled = (Plugin.StretchEnabled?.Value ?? false),
				aspectPreset = (int)(Plugin.AspectPreset?.Value ?? AspectPreset.Native),
				stretchAmount = (Plugin.StretchAmount?.Value ?? 0f),
				horizontalScale = (Plugin.HorizontalScale?.Value ?? 1f),
				fxEnabled = (Plugin.FxEnabled?.Value ?? false),
				fxBrightness = (Plugin.FxBrightness?.Value ?? 0f),
				fxContrast = (Plugin.FxContrast?.Value ?? 0f),
				fxSaturation = (Plugin.FxSaturation?.Value ?? 0f),
				fxHue = (Plugin.FxHue?.Value ?? 0f),
				tintR = val.r,
				tintG = val.g,
				tintB = val.b,
				tintA = val.a,
				fxTemperature = (Plugin.FxTemperature?.Value ?? 0f),
				fxWbTint = (Plugin.FxWbTint?.Value ?? 0f),
				fxVignette = (Plugin.FxVignette?.Value ?? 0f),
				fxBloom = (Plugin.FxBloom?.Value ?? 0f),
				fxBloomThreshold = (Plugin.FxBloomThreshold?.Value ?? 1f)
			};
		}

		internal static bool Save(string name)
		{
			name = SanitizeName(name);
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			try
			{
				VisualProfile visualProfile = CaptureCurrent(name);
				string text = Path.Combine(Folder, name + ".json");
				string contents = JsonUtility.ToJson((object)visualProfile, true);
				File.WriteAllText(text, contents);
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Save();
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Config profile saved: " + text));
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("Save profile failed: " + ex.Message));
				}
				return false;
			}
		}

		internal static bool Load(string name)
		{
			name = SanitizeName(name);
			string path = Path.Combine(Folder, name + ".json");
			if (!File.Exists(path))
			{
				return false;
			}
			try
			{
				VisualProfile visualProfile = JsonUtility.FromJson<VisualProfile>(File.ReadAllText(path));
				if (visualProfile == null)
				{
					return false;
				}
				Apply(visualProfile);
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Save();
				}
				ScreenStretch.ApplyLocalPlayerCamera();
				ColorEffects.Apply();
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Config profile loaded: " + name));
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("Load profile failed: " + ex.Message));
				}
				return false;
			}
		}

		internal static bool Delete(string name)
		{
			name = SanitizeName(name);
			string path = Path.Combine(Folder, name + ".json");
			try
			{
				if (!File.Exists(path))
				{
					return false;
				}
				File.Delete(path);
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Config profile deleted: " + name));
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("Delete profile failed: " + ex.Message));
				}
				return false;
			}
		}

		internal static void Apply(VisualProfile p)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Enabled != null)
			{
				Plugin.Enabled.Value = p.vmEnabled;
			}
			if (Plugin.OffsetX != null)
			{
				Plugin.OffsetX.Value = p.offsetX;
			}
			if (Plugin.OffsetY != null)
			{
				Plugin.OffsetY.Value = p.offsetY;
			}
			if (Plugin.OffsetZ != null)
			{
				Plugin.OffsetZ.Value = p.offsetZ;
			}
			if (Plugin.StretchEnabled != null)
			{
				Plugin.StretchEnabled.Value = p.stretchEnabled;
			}
			if (Plugin.AspectPreset != null)
			{
				Plugin.AspectPreset.Value = (AspectPreset)Mathf.Clamp(p.aspectPreset, 0, 5);
			}
			if (Plugin.StretchAmount != null)
			{
				Plugin.StretchAmount.Value = Mathf.Clamp01(p.stretchAmount);
			}
			if (Plugin.HorizontalScale != null)
			{
				Plugin.HorizontalScale.Value = Mathf.Clamp(p.horizontalScale, 0.5f, 2f);
			}
			if (Plugin.FxEnabled != null)
			{
				Plugin.FxEnabled.Value = p.fxEnabled;
			}
			if (Plugin.FxBrightness != null)
			{
				Plugin.FxBrightness.Value = p.fxBrightness;
			}
			if (Plugin.FxContrast != null)
			{
				Plugin.FxContrast.Value = p.fxContrast;
			}
			if (Plugin.FxSaturation != null)
			{
				Plugin.FxSaturation.Value = p.fxSaturation;
			}
			if (Plugin.FxHue != null)
			{
				Plugin.FxHue.Value = p.fxHue;
			}
			if (Plugin.FxTint != null)
			{
				Plugin.FxTint.Value = new Color(p.tintR, p.tintG, p.tintB, p.tintA);
			}
			if (Plugin.FxTemperature != null)
			{
				Plugin.FxTemperature.Value = p.fxTemperature;
			}
			if (Plugin.FxWbTint != null)
			{
				Plugin.FxWbTint.Value = p.fxWbTint;
			}
			if (Plugin.FxVignette != null)
			{
				Plugin.FxVignette.Value = p.fxVignette;
			}
			if (Plugin.FxBloom != null)
			{
				Plugin.FxBloom.Value = p.fxBloom;
			}
			if (Plugin.FxBloomThreshold != null)
			{
				Plugin.FxBloomThreshold.Value = p.fxBloomThreshold;
			}
		}

		internal static string SanitizeName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return string.Empty;
			}
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			char[] array = name.Trim().ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				if (Array.IndexOf(invalidFileNameChars, array[i]) >= 0)
				{
					array[i] = '_';
				}
			}
			string text = new string(array).Trim();
			if (text.Length > 48)
			{
				text = text.Substring(0, 48);
			}
			return text;
		}
	}
	internal static class HandPreview
	{
		private static readonly Vector3 BaseRight = new Vector3(0.22f, -0.28f, 0.45f);

		private static readonly Vector3 BaseLeft = new Vector3(-0.22f, -0.28f, 0.45f);

		internal static void DrawImGui(Rect area, Vector3 offset, bool enabled)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0082: 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)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			Color color = GUI.color;
			GUI.color = new Color(0.12f, 0.14f, 0.16f, 0.95f);
			GUI.DrawTexture(area, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = new Color(0.35f, 0.4f, 0.45f, 1f);
			GUI.Box(area, GUIContent.none);
			DrawCrosshair(area);
			Vector3 camLocal = BaseRight + (enabled ? offset : Vector3.zero);
			Vector3 camLocal2 = BaseLeft + (enabled ? offset : Vector3.zero);
			DrawHandMarker(area, camLocal2, new Color(0.35f, 0.65f, 1f, 0.95f), "L");
			DrawHandMarker(area, camLocal, new Color(1f, 0.55f, 0.25f, 0.95f), "R");
			GUI.color = color;
		}

		private static void DrawCrosshair(Rect area)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Rect)(ref area)).x + ((Rect)(ref area)).width * 0.5f;
			float num2 = ((Rect)(ref area)).y + ((Rect)(ref area)).height * 0.42f;
			GUI.color = new Color(1f, 1f, 1f, 0.35f);
			GUI.DrawTexture(new Rect(num - 6f, num2 - 1f, 12f, 2f), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(num - 1f, num2 - 6f, 2f, 12f), (Texture)(object)Texture2D.whiteTexture);
		}

		private static void DrawHandMarker(Rect area, Vector3 camLocal, Color color, string label)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			CamToPreview(area, camLocal, out var px, out var py, out var scale);
			float num = 36f * scale;
			float num2 = 48f * scale;
			Rect val = new Rect(px - num * 0.5f, py - num2 * 0.5f, num, num2);
			GUI.color = color;
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontStyle = (FontStyle)1,
				fontSize = Mathf.RoundToInt(12f * scale)
			};
			GUI.Label(val, label, val2);
		}

		private static void CamToPreview(Rect area, Vector3 camLocal, out float px, out float py, out float scale)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			float num = Mathf.Max(0.15f, camLocal.z);
			float num2 = 1.1f;
			float num3 = camLocal.x / num / num2;
			float num4 = camLocal.y / num / num2;
			px = ((Rect)(ref area)).x + ((Rect)(ref area)).width * (0.5f + num3 * 0.5f);
			py = ((Rect)(ref area)).y + ((Rect)(ref area)).height * (0.42f - num4 * 0.55f);
			scale = Mathf.Clamp(0.55f / num, 0.45f, 1.6f);
		}

		internal static void BuildFishyRow(RectTransform parent)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)parent == (Object)null))
			{
				ClearChildren((Transform)(object)parent);
				GameObject val = new GameObject("ViewmodelPreview", new Type[1] { typeof(RectTransform) });
				RectTransform component = val.GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)parent, false);
				Stretch(component);
				Image obj = val.AddComponent<Image>();
				((Graphic)obj).color = new Color(0.1f, 0.12f, 0.14f, 0.92f);
				((Graphic)obj).raycastTarget = false;
				SetAnchor(MakePanel(component, "Cross", new Color(1f, 1f, 1f, 0.3f)), new Vector2(0.5f, 0.58f), new Vector2(14f, 2f));
				SetAnchor(MakePanel(component, "CrossV", new Color(1f, 1f, 1f, 0.3f)), new Vector2(0.5f, 0.58f), new Vector2(2f, 14f));
				RectTransform left = MakeHand(component, "Left", new Color(0.35f, 0.65f, 1f, 0.95f), "L");
				RectTransform right = MakeHand(component, "Right", new Color(1f, 0.55f, 0.25f, 0.95f), "R");
				val.AddComponent<HandPreviewDriver>().Init(left, right, component);
			}
		}

		private static RectTransform MakeHand(RectTransform parent, string name, Color color, string label)
		{
			//IL_0002: 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_0026: 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)
			RectTransform val = MakePanel(parent, name, color);
			GameObject val2 = new GameObject("Label", new Type[1] { typeof(RectTransform) });
			RectTransform component = val2.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)val, false);
			Stretch(component);
			TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).text = label;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			((TMP_Text)obj).fontSize = 18f;
			((Graphic)obj).color = Color.white;
			((Graphic)obj).raycastTarget = false;
			return val;
		}

		private static RectTransform MakePanel(RectTransform parent, string name, Color color)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			((Graphic)val.GetComponent<Image>()).color = color;
			((Graphic)val.GetComponent<Image>()).raycastTarget = false;
			return component;
		}

		private static void Stretch(RectTransform rt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		private static void SetAnchor(RectTransform rt, Vector2 anchor, Vector2 size)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = anchor;
			rt.anchorMax = anchor;
			rt.pivot = new Vector2(0.5f, 0.5f);
			rt.sizeDelta = size;
			rt.anchoredPosition = Vector2.zero;
		}

		private static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject);
			}
		}

		internal static void LayoutHands(RectTransform host, RectTransform left, RectTransform right, Vector3 offset, bool enabled)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0044: 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)
			if (!((Object)(object)host == (Object)null) && !((Object)(object)left == (Object)null) && !((Object)(object)right == (Object)null))
			{
				Place(host, left, BaseLeft + (enabled ? offset : Vector3.zero));
				Place(host, right, BaseRight + (enabled ? offset : Vector3.zero));
			}
		}

		private static void Place(RectTransform host, RectTransform hand, Vector3 camLocal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = host.rect;
			float num = Mathf.Max(0.15f, camLocal.z);
			float num2 = 1.1f;
			float num3 = camLocal.x / num / num2;
			float num4 = camLocal.y / num / num2;
			float num5 = ((Rect)(ref rect)).width * (0.5f + num3 * 0.5f);
			float num6 = ((Rect)(ref rect)).height * (0.58f + num4 * 0.55f);
			float num7 = Mathf.Clamp(0.55f / num, 0.45f, 1.6f);
			hand.anchorMin = Vector2.zero;
			hand.anchorMax = Vector2.zero;
			hand.pivot = new Vector2(0.5f, 0.5f);
			hand.sizeDelta = new Vector2(34f * num7, 46f * num7);
			hand.anchoredPosition = new Vector2(num5, num6);
		}
	}
	internal sealed class HandPreviewDriver : MonoBehaviour
	{
		private RectTransform _host;

		private RectTransform _left;

		private RectTransform _right;

		public void Init(RectTransform left, RectTransform right, RectTransform host)
		{
			_left = left;
			_right = right;
			_host = host;
		}

		private void LateUpdate()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_host == (Object)null) && !((Object)(object)_left == (Object)null) && !((Object)(object)_right == (Object)null) && Plugin.Enabled != null)
			{
				HandPreview.LayoutHands(_host, _left, _right, Plugin.ConfigLocalOffset, Plugin.Enabled.Value);
			}
		}
	}
	internal static class MenuInputBlock
	{
		internal static bool IsLocalCamera(PlayerCamera cam)
		{
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)cam == (Object)null)
			{
				return false;
			}
			try
			{
				if ((Object)(object)localPlayer.Camera != (Object)null && localPlayer.Camera == cam)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)localPlayer.CurCam != (Object)null && (Object)(object)((Component)cam).GetComponent<Camera>() == (Object)(object)localPlayer.CurCam)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (((NetworkBehaviour)cam).IsOwner)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		internal static bool IsLocalHolding(PlayerHolding holding)
		{
			if ((Object)(object)holding == (Object)null)
			{
				return false;
			}
			try
			{
				if (((NetworkBehaviour)holding).IsOwner)
				{
					return true;
				}
			}
			catch
			{
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			try
			{
				return (Object)(object)localPlayer.Holding == (Object)(object)holding;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsLocalPunching(PlayerPunching punching)
		{
			if ((Object)(object)punching == (Object)null)
			{
				return false;
			}
			try
			{
				if (((NetworkBehaviour)punching).IsOwner)
				{
					return true;
				}
			}
			catch
			{
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			try
			{
				return (Object)(object)localPlayer.Punching == (Object)(object)punching;
			}
			catch
			{
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "MouseMovement")]
	internal static class PlayerCameraMouseMovementPatch
	{
		private static bool Prefix(PlayerCamera __instance)
		{
			if (!ModMenu.BlocksGameLook)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalCamera(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "MouseInput")]
	internal static class PlayerCameraMouseInputPatch
	{
		private static bool Prefix(PlayerCamera __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalCamera(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "MouseClick")]
	internal static class PlayerCameraMouseClickPatch
	{
		private static bool Prefix(PlayerCamera __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalCamera(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerHolding), "PrimaryInput")]
	internal static class PlayerHoldingPrimaryPatch
	{
		private static bool Prefix(PlayerHolding __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalHolding(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerHolding), "PrimaryInputCanceled")]
	internal static class PlayerHoldingPrimaryCancelPatch
	{
		private static bool Prefix(PlayerHolding __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalHolding(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerPunching), "PunchInput")]
	internal static class PlayerPunchingInputPatch
	{
		private static bool Prefix(PlayerPunching __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalPunching(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerPunching), "PunchInputCanceled")]
	internal static class PlayerPunchingInputCancelPatch
	{
		private static bool Prefix(PlayerPunching __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalPunching(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerPunching), "StartPunching")]
	internal static class PlayerPunchingStartPatch
	{
		private static bool Prefix(PlayerPunching __instance)
		{
			if (!ModMenu.BlocksGameClicks)
			{
				return true;
			}
			return !MenuInputBlock.IsLocalPunching(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerToolMovement), "LookAround")]
	internal static class ToolLookAroundPatch
	{
		private static bool Prefix()
		{
			return !ModMenu.BlocksGameLook;
		}
	}
	internal enum MenuSection
	{
		Viewmodel,
		Stretch,
		Filters,
		Configs
	}
	internal static class ModMenu
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawWindow;
		}

		private static MenuSection _section = MenuSection.Viewmodel;

		private static Vector2 _scroll;

		private static Vector2 _profileScroll;

		private static string _saveName = "My setup";

		private static string _status = string.Empty;

		private static float _statusUntil;

		private static string[] _cachedProfiles = Array.Empty<string>();

		private static float _profilesRefreshAt;

		private static readonly AspectPreset[] PresetOrder = new AspectPreset[6]
		{
			AspectPreset.Native,
			AspectPreset.Ratio4_3,
			AspectPreset.Ratio5_4,
			AspectPreset.Ratio16_10,
			AspectPreset.Ratio16_9,
			AspectPreset.Ratio21_9
		};

		private const float WinW = 760f;

		private const float WinH = 440f;

		private static Rect _windowRect = new Rect(80f, 80f, 760f, 440f);

		private const int WindowId = 985421;

		private static bool _openFlag;

		private static bool _isOpen;

		internal static bool BlocksGameLook
		{
			get
			{
				if (_isOpen)
				{
					return IsPointerOverWindow();
				}
				return false;
			}
		}

		internal static bool BlocksGameClicks => _isOpen;

		internal static bool BlocksGameMouse
		{
			get
			{
				if (!BlocksGameLook)
				{
					return BlocksGameClicks;
				}
				return true;
			}
		}

		internal static void SetOpen(bool open)
		{
			_isOpen = open;
		}

		private static bool IsPointerOverWindow()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = GuiMousePosition();
			Rect windowRect = _windowRect;
			((Rect)(ref windowRect)).xMin = ((Rect)(ref windowRect)).xMin - 2f;
			((Rect)(ref windowRect)).yMin = ((Rect)(ref windowRect)).yMin - 2f;
			((Rect)(ref windowRect)).xMax = ((Rect)(ref windowRect)).xMax + 2f;
			((Rect)(ref windowRect)).yMax = ((Rect)(ref windowRect)).yMax + 2f;
			return ((Rect)(ref windowRect)).Contains(val);
		}

		internal static void Draw(ref bool open)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0084: Expected O, but got Unknown
			_isOpen = open;
			if (open)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				if (((Rect)(ref _windowRect)).width < 100f || ((Rect)(ref _windowRect)).height < 100f)
				{
					_windowRect = new Rect(80f, 80f, 760f, 440f);
				}
				_openFlag = open;
				Rect windowRect = _windowRect;
				object obj = <>O.<0>__DrawWindow;
				if (obj == null)
				{
					WindowFunction val = DrawWindow;
					<>O.<0>__DrawWindow = val;
					obj = (object)val;
				}
				_windowRect = GUI.Window(985421, windowRect, (WindowFunction)obj, "FishVisuals");
				open = _openFlag;
				_isOpen = open;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private static Vector2 GuiMousePosition()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0041: 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_0051: 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)
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Mouse current = Mouse.current;
				if (current != null)
				{
					return GUIUtility.ScreenToGUIPoint(((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue());
				}
			}
			catch
			{
			}
			try
			{
				return GUIUtility.ScreenToGUIPoint(Vector2.op_Implicit(Input.mousePosition));
			}
			catch
			{
				if (Event.current != null)
				{
					return Event.current.mousePosition;
				}
				return Vector2.zero;
			}
		}

		private static void DrawWindow(int id)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Invalid comparison between Unknown and I4
			DrawTabs();
			GUILayout.Space(6f);
			_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
			switch (_section)
			{
			case MenuSection.Viewmodel:
				DrawViewmodel();
				break;
			case MenuSection.Stretch:
				DrawStretch();
				break;
			case MenuSection.Filters:
				DrawFilters();
				break;
			case MenuSection.Configs:
				DrawConfigs();
				break;
			}
			GUILayout.EndScrollView();
			if (!string.IsNullOrEmpty(_status) && Time.unscaledTime < _statusUntil)
			{
				GUILayout.Space(4f);
				GUILayout.Label(_status, Array.Empty<GUILayoutOption>());
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
			if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 27)
			{
				_openFlag = false;
				Event.current.Use();
			}
		}

		private static void DrawTabs()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Tab("Viewmodel", MenuSection.Viewmodel);
			Tab("Stretch", MenuSection.Stretch);
			Tab("Filters", MenuSection.Filters);
			Tab("Configs", MenuSection.Configs);
			GUILayout.FlexibleSpace();
			GUILayout.Label("Insert / F7 / Esc", Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		private static void Tab(string label, MenuSection section)
		{
			bool num = _section == section;
			GUIStyle val = (num ? GUI.skin.box : GUI.skin.button);
			if (GUILayout.Button(num ? ("[" + label + "]") : label, val, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(26f),
				GUILayout.MinWidth(100f)
			}))
			{
				_section = section;
			}
		}

		private static void DrawViewmodel()
		{
			//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)
			GUILayout.Label("Viewmodel — idle hand offset (client only)", Array.Empty<GUILayoutOption>());
			Plugin.Enabled.Value = GUILayout.Toggle(Plugin.Enabled.Value, "Offset enabled", Array.Empty<GUILayoutOption>());
			Plugin.OffsetX.Value = Slider("X", Plugin.OffsetX.Value, -1.5f, 1.5f);
			Plugin.OffsetY.Value = Slider("Y", Plugin.OffsetY.Value, -1.5f, 1.5f);
			Plugin.OffsetZ.Value = Slider("Z", Plugin.OffsetZ.Value, -1.5f, 1.5f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Reset XYZ", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
			{
				Plugin.OffsetX.Value = 0f;
				Plugin.OffsetY.Value = 0f;
				Plugin.OffsetZ.Value = 0f;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.Label("Hand preview", Array.Empty<GUILayoutOption>());
			HandPreview.DrawImGui(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(120f),
				GUILayout.ExpandWidth(true)
			}), Plugin.ConfigLocalOffset, Plugin.Enabled.Value);
		}

		private static void DrawStretch()
		{
			GUILayout.Label("Screen stretch — saved automatically", Array.Empty<GUILayoutOption>());
			Plugin.StretchEnabled.Value = GUILayout.Toggle(Plugin.StretchEnabled.Value, "Stretch enabled", Array.Empty<GUILayoutOption>());
			GUILayout.Label("Current: " + ScreenStretch.PresetLabel(Plugin.AspectPreset.Value), Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.Label("Presets", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			AspectPreset[] presetOrder = PresetOrder;
			foreach (AspectPreset preset in presetOrder)
			{
				if (GUILayout.Button(ScreenStretch.PresetLabel(preset), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }))
				{
					ScreenStretch.ApplyPreset(preset);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			Plugin.StretchAmount.Value = Slider("Stretch amount", Plugin.StretchAmount.Value, 0f, 1f);
			Plugin.HorizontalScale.Value = Slider("Horizontal scale (Native only)", Plugin.HorizontalScale.Value, 0.5f, 2f);
			GUILayout.Label($"Native {ScreenStretch.NativeAspect():0.###}  →  cam {ScreenStretch.GetTargetAspect():0.###}", Array.Empty<GUILayoutOption>());
		}

		private static void DrawFilters()
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Filters — ReShade-style grading", Array.Empty<GUILayoutOption>());
			Plugin.FxEnabled.Value = GUILayout.Toggle(Plugin.FxEnabled.Value, "Effects enabled", Array.Empty<GUILayoutOption>());
			Plugin.FxBrightness.Value = Slider("Brightness", Plugin.FxBrightness.Value, -2f, 2f);
			Plugin.FxContrast.Value = Slider("Contrast", Plugin.FxContrast.Value, -100f, 100f);
			Plugin.FxSaturation.Value = Slider("Saturation", Plugin.FxSaturation.Value, -100f, 100f);
			Plugin.FxHue.Value = Slider("Hue", Plugin.FxHue.Value, -180f, 180f);
			Plugin.FxTemperature.Value = Slider("Temperature", Plugin.FxTemperature.Value, -100f, 100f);
			Plugin.FxWbTint.Value = Slider("WB tint", Plugin.FxWbTint.Value, -100f, 100f);
			Plugin.FxVignette.Value = Slider("Vignette", Plugin.FxVignette.Value, 0f, 1f);
			Plugin.FxBloom.Value = Slider("Bloom", Plugin.FxBloom.Value, 0f, 5f);
			Plugin.FxBloomThreshold.Value = Slider("Bloom threshold", Plugin.FxBloomThreshold.Value, 0f, 2f);
			GUILayout.Space(4f);
			GUILayout.Label("Tint RGB", Array.Empty<GUILayoutOption>());
			Color value = Plugin.FxTint.Value;
			value.r = Slider("R", value.r, 0f, 1f);
			value.g = Slider("G", value.g, 0f, 1f);
			value.b = Slider("B", value.b, 0f, 1f);
			Plugin.FxTint.Value = value;
			if (GUILayout.Button("Reset filters", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
			{
				ColorEffects.ResetDefaults();
			}
		}

		private static void DrawConfigs()
		{
			//IL_0143: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			RefreshProfilesIfNeeded();
			GUILayout.Label("Save / load full setups (viewmodel + stretch + filters)", Array.Empty<GUILayoutOption>());
			GUILayout.Label("Folder: BepInEx/config/FishVisuals/profiles/", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Name", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) });
			_saveName = GUILayout.TextField(_saveName ?? string.Empty, 48, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Save", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(80f),
				GUILayout.Height(24f)
			}))
			{
				if (ConfigProfiles.Save(_saveName))
				{
					SetStatus("Saved \"" + ConfigProfiles.SanitizeName(_saveName) + "\"");
					ForceRefreshProfiles();
				}
				else
				{
					SetStatus("Save failed — enter a valid name");
				}
			}
			if (GUILayout.Button("Save BepInEx.cfg", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(130f),
				GUILayout.Height(24f)
			}))
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Save();
				}
				SetStatus("Wrote cursor.FishVisuals.cfg");
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.Label("Saved profiles", Array.Empty<GUILayoutOption>());
			_profileScroll = GUILayout.BeginScrollView(_profileScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(180f) });
			if (_cachedProfiles.Length == 0)
			{
				GUILayout.Label("(none yet — save one above)", Array.Empty<GUILayoutOption>());
			}
			else
			{
				string[] cachedProfiles = _cachedProfiles;
				foreach (string text in cachedProfiles)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
					if (GUILayout.Button("Load", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(70f),
						GUILayout.Height(22f)
					}))
					{
						if (ConfigProfiles.Load(text))
						{
							_saveName = text;
							SetStatus("Loaded \"" + text + "\"");
						}
						else
						{
							SetStatus("Load failed: " + text);
						}
					}
					if (GUILayout.Button("Delete", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(70f),
						GUILayout.Height(22f)
					}) && ConfigProfiles.Delete(text))
					{
						SetStatus("Deleted \"" + text + "\"");
						ForceRefreshProfiles();
					}
					GUILayout.EndHorizontal();
				}
			}
			GUILayout.EndScrollView();
			if (GUILayout.Button("Refresh list", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
			{
				ForceRefreshProfiles();
			}
		}

		private static void RefreshProfilesIfNeeded()
		{
			if (Time.unscaledTime >= _profilesRefreshAt)
			{
				ForceRefreshProfiles();
			}
		}

		private static void ForceRefreshProfiles()
		{
			_cachedProfiles = ConfigProfiles.ListNames();
			_profilesRefreshAt = Time.unscaledTime + 2f;
		}

		private static void SetStatus(string msg)
		{
			_status = msg;
			_statusUntil = Time.unscaledTime + 3f;
		}

		private static float Slider(string label, float value, float min, float max)
		{
			GUILayout.Label($"{label}: {value:0.###}", Array.Empty<GUILayoutOption>());
			return GUILayout.HorizontalSlider(value, min, max, Array.Empty<GUILayoutOption>());
		}
	}
	[HarmonyPatch(typeof(PlayerHands), "CurDefaultHandPos")]
	internal static class DefaultHandPosPatch
	{
		private static readonly FieldRef<PlayerHands, Player> PlayerRef = AccessTools.FieldRefAccess<PlayerHands, Player>("_player");

		private static void Postfix(PlayerHands __instance, ref Vector3 __result)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			Player val;
			try
			{
				val = PlayerRef.Invoke(__instance);
			}
			catch
			{
				return;
			}
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.LocalPlayer) && Plugin.TryGetWorldOffset(val, out var worldOffset))
			{
				__result += worldOffset;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerToolMovement), "GlueToCamera")]
	internal static class ToolGluePatch
	{
		private static void Postfix(Player ____player, Tool ____tool)
		{
			//IL_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)____player == (Object)null) && !((Object)(object)____tool == (Object)null) && !((Object)(object)Player.LocalPlayer != (Object)(object)____player) && Plugin.TryGetWorldOffset(____player, out var worldOffset))
			{
				Transform transform = ((Component)____tool).transform;
				transform.position += worldOffset;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerHolding), "CalculateHoldTargetPos")]
	internal static class HoldTargetPatch
	{
		private static void Postfix(PlayerHolding __instance, Player ____player, ref Vector3 __result)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)____player == (Object)null) && !((Object)(object)Player.LocalPlayer != (Object)(object)____player) && Plugin.TryGetWorldOffset(____player, out var worldOffset))
			{
				__result += worldOffset;
			}
		}
	}
	[BepInPlugin("cursor.FishVisuals", "FishVisuals", "1.10.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "cursor.FishVisuals";

		public const string PluginName = "FishVisuals";

		public const string PluginVersion = "1.10.4";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> OffsetX;

		internal static ConfigEntry<float> OffsetY;

		internal static ConfigEntry<float> OffsetZ;

		internal static ConfigEntry<bool> StretchEnabled;

		internal static ConfigEntry<AspectPreset> AspectPreset;

		internal static ConfigEntry<float> StretchAmount;

		internal static ConfigEntry<float> HorizontalScale;

		internal static ConfigEntry<bool> FxEnabled;

		internal static ConfigEntry<float> FxBrightness;

		internal static ConfigEntry<float> FxContrast;

		internal static ConfigEntry<float> FxSaturation;

		internal static ConfigEntry<float> FxHue;

		internal static ConfigEntry<Color> FxTint;

		internal static ConfigEntry<float> FxTemperature;

		internal static ConfigEntry<float> FxWbTint;

		internal static ConfigEntry<float> FxVignette;

		internal static ConfigEntry<float> FxBloom;

		internal static ConfigEntry<float> FxBloomThreshold;

		internal static ConfigEntry<KeyboardShortcut> MenuKey;

		private static readonly FieldRef<Weapon, float> AimPercent = AccessTools.FieldRefAccess<Weapon, float>("_aimPercent");

		private Harmony _harmony;

		private bool _guiOpen;

		private bool _insertHeld;

		private float _menuToggleAt = -10f;

		private const int VkInsert = 45;

		private const float MenuToggleCooldown = 0.35f;

		internal static Vector3 ConfigLocalOffset => new Vector3(OffsetX.Value, OffsetY.Value, OffsetZ.Value);

		[DllImport("user32.dll")]
		private static extern short GetAsyncKeyState(int vKey);

		private void Awake()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			BindViewmodel();
			BindStretch();
			BindEffects();
			MenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Menu Key", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Toggle the FishVisuals menu (default Insert).");
			KeyboardShortcut value = MenuKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 288)
			{
				MenuKey.Value = new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>());
			}
			_harmony = new Harmony("cursor.FishVisuals");
			_harmony.PatchAll(typeof(DefaultHandPosPatch));
			_harmony.PatchAll(typeof(ToolGluePatch));
			_harmony.PatchAll(typeof(HoldTargetPatch));
			_harmony.PatchAll(typeof(PlayerCameraStretchPatch));
			try
			{
				_harmony.PatchAll(typeof(PlayerCameraStretchEnablePatch));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("PlayerCamera OnEnable stretch patch skipped: " + ex.Message));
			}
			_harmony.PatchAll(typeof(PlayerCameraMouseMovementPatch));
			_harmony.PatchAll(typeof(PlayerCameraMouseInputPatch));
			_harmony.PatchAll(typeof(PlayerCameraMouseClickPatch));
			_harmony.PatchAll(typeof(PlayerHoldingPrimaryPatch));
			_harmony.PatchAll(typeof(PlayerHoldingPrimaryCancelPatch));
			_harmony.PatchAll(typeof(PlayerPunchingInputPatch));
			_harmony.PatchAll(typeof(PlayerPunchingInputCancelPatch));
			_harmony.PatchAll(typeof(PlayerPunchingStartPatch));
			try
			{
				_harmony.PatchAll(typeof(ToolLookAroundPatch));
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("LookAround patch skipped: " + ex2.Message));
			}
			ColorEffects.Ensure();
			TryRegisterFishyOptions();
			TryRegisterSpongeMenu();
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(PauseManager), "Awake", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "OnPauseAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex3)
			{
				Log.LogWarning((object)("PauseManager hook failed: " + ex3.Message));
			}
			ScreenStretch.SanitizeLoadedConfig();
			ScreenStretch.HookRenderPipeline();
			ScreenStretch.ApplyLocalPlayerCamera();
			Log.LogInfo((object)"FishVisuals 1.10.4 loaded (author: cursor). Press Insert for menu.");
		}

		private static void OnPauseAwake()
		{
			Instance?.TryRegisterFishyOptions();
		}

		private void BindViewmodel()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			AcceptableValueRange<float> val = new AcceptableValueRange<float>(-1.5f, 1.5f);
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Viewmodel", "Enabled", true, "Shift local idle hand pose (client-only). Punches still use the vanilla hit point.");
			OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Viewmodel", "Offset X", 0f, new ConfigDescription("Right (+) / left (-).", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Viewmodel", "Offset Y", 0f, new ConfigDescription("Up (+) / down (-).", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			OffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Viewmodel", "Offset Z", 0f, new ConfigDescription("Forward (+) / back (-).", (AcceptableValueBase)(object)val, Array.Empty<object>()));
		}

		private void BindStretch()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			StretchEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Stretch", "Enabled", false, "CS-style screen stretch.");
			AspectPreset = ((BaseUnityPlugin)this).Config.Bind<AspectPreset>("Stretch", "Aspect Preset", FishVisuals.AspectPreset.Native, "Target aspect ratio.");
			StretchAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Stretch", "Stretch Amount", 0f, new ConfigDescription("0 = native, 1 = full preset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			HorizontalScale = ((BaseUnityPlugin)this).Config.Bind<float>("Stretch", "Horizontal Scale", 1f, new ConfigDescription("Extra horizontal stretch.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
			ScreenStretch.BindSettingEvents();
		}

		private void BindEffects()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_0124: 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_0170: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Expected O, but got Unknown
			FxEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Enabled", false, "ReShade-style color grading.");
			FxBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Brightness", 0f, new ConfigDescription("Post exposure.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), Array.Empty<object>()));
			FxContrast = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Contrast", 0f, new ConfigDescription("Contrast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FxSaturation = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Saturation", 0f, new ConfigDescription("Saturation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FxHue = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Hue", 0f, new ConfigDescription("Hue shift (degrees).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			FxTint = ((BaseUnityPlugin)this).Config.Bind<Color>("Effects", "Tint", Color.white, "Color filter / tint.");
			FxTemperature = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Temperature", 0f, new ConfigDescription("White balance temperature (cold ↔ warm).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FxWbTint = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "WB Tint", 0f, new ConfigDescription("White balance green ↔ magenta.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FxVignette = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Vignette", 0f, new ConfigDescription("Vignette intensity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			FxBloom = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Bloom", 0f, new ConfigDescription("Bloom intensity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			FxBloomThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Bloom Threshold", 1f, new ConfigDescription("Bloom threshold.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			FxEnabled.SettingChanged += OnFx;
			FxBrightness.SettingChanged += OnFx;
			FxContrast.SettingChanged += OnFx;
			FxSaturation.SettingChanged += OnFx;
			FxHue.SettingChanged += OnFx;
			FxTint.SettingChanged += OnFx;
			FxTemperature.SettingChanged += OnFx;
			FxWbTint.SettingChanged += OnFx;
			FxVignette.SettingChanged += OnFx;
			FxBloom.SettingChanged += OnFx;
			FxBloomThreshold.SettingChanged += OnFx;
			static void OnFx(object _s, EventArgs _e)
			{
				ColorEffects.Apply();
			}
		}

		internal static bool TryGetWorldOffset(Player player, out Vector3 worldOffset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_007a: 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)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			worldOffset = Vector3.zero;
			if (Enabled == null || !Enabled.Value || (Object)(object)player == (Object)null)
			{
				return false;
			}
			Vector3 val = ConfigLocalOffset;
			if (((Vector3)(ref val)).sqrMagnitude < 1E-07f)
			{
				return false;
			}
			float adsBlend = GetAdsBlend(player);
			if (adsBlend >= 0.999f)
			{
				return false;
			}
			if (adsBlend > 0f)
			{
				val *= 1f - adsBlend;
			}
			Transform camObject = player.CamObject;
			if ((Object)(object)camObject == (Object)null)
			{
				return false;
			}
			worldOffset = camObject.TransformDirection(val);
			return true;
		}

		private static float GetAdsBlend(Player player)
		{
			Item val = (((Object)(object)player.Holding != (Object)null) ? player.Holding.HeldItem : null);
			Weapon val2 = (((Object)(object)val != (Object)null && (Object)(object)val.Tool != (Object)null) ? ((Item)val.Tool).Weapon : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return 0f;
			}
			try
			{
				return Mathf.Clamp01(AimPercent.Invoke(val2));
			}
			catch
			{
				return val2.IsAds ? 1f : 0f;
			}
		}

		private void Update()
		{
			if (IsMenuToggleDown())
			{
				ToggleMenu();
			}
		}

		private void LateUpdate()
		{
			ScreenStretch.ApplyLocalPlayerCamera();
		}

		private void OnGUI()
		{
			try
			{
				GUI.depth = -1000;
				ModMenu.Draw(ref _guiOpen);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Menu draw failed: {arg}");
			}
		}

		private bool IsMenuToggleDown()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0098: 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_00a5: Invalid comparison between Unknown and I4
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime - _menuToggleAt < 0.35f)
			{
				return false;
			}
			bool flag = (GetAsyncKeyState(45) & 0x8000) != 0;
			if (!Application.isFocused)
			{
				_insertHeld = flag;
				return false;
			}
			bool num = flag && !_insertHeld;
			_insertHeld = flag;
			if (num)
			{
				return true;
			}
			try
			{
				if (UnityInput.Current != null && UnityInput.Current.GetKeyDown((KeyCode)288))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (MenuKey != null)
				{
					KeyboardShortcut value = MenuKey.Value;
					if ((int)((KeyboardShortcut)(ref value)).MainKey != 0)
					{
						value = MenuKey.Value;
						if ((int)((KeyboardShortcut)(ref value)).MainKey != 277)
						{
							value = MenuKey.Value;
							if ((int)((KeyboardShortcut)(ref value)).MainKey != 288)
							{
								value = MenuKey.Value;
								if (((KeyboardShortcut)(ref value)).IsDown())
								{
									return true;
								}
							}
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private void ToggleMenu()
		{
			_menuToggleAt = Time.unscaledTime;
			_guiOpen = !_guiOpen;
			ModMenu.SetOpen(_guiOpen);
			Log.LogInfo((object)(_guiOpen ? "Menu OPEN" : "Menu CLOSED"));
		}

		private void TryRegisterFishyOptions()
		{
			if (!Chainloader.PluginInfos.ContainsKey("com.sopika.fishyui"))
			{
				return;
			}
			try
			{
				RegisterFishyOptions();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("FishyUI Options failed: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void RegisterFishyOptions()
		{
			Type type = AccessTools.TypeByName("FishyUI.Options");
			if (type == null)
			{
				return;
			}
			MethodInfo method = type.GetMethod("Page", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
			if (method == null)
			{
				return;
			}
			object? obj = method.Invoke(null, new object[1] { "FishVisuals" });
			Page val = (Page)((obj is Page) ? obj : null);
			if (val != null)
			{
				type.GetMethod("Remove", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null)?.Invoke(null, new object[1] { "Viewmodel" });
				val.Clear();
				val.Header("Viewmodel");
				val.Toggle("Enabled", Enabled);
				val.Slider("Offset X", OffsetX, -1.5f, 1.5f);
				val.Slider("Offset Y", OffsetY, -1.5f, 1.5f);
				val.Slider("Offset Z", OffsetZ, -1.5f, 1.5f);
				val.Button("Reset XYZ", (Action)delegate
				{
					OffsetX.Value = 0f;
					OffsetY.Value = 0f;
					OffsetZ.Value = 0f;
				});
				val.Header("Hand preview");
				val.Custom("Hands", 2.8f, (Action<RectTransform>)HandPreview.BuildFishyRow);
				val.Header("Screen stretch");
				val.Toggle("Stretch Enabled", StretchEnabled);
				val.Readout("Aspect", (Func<string>)(() => ScreenStretch.PresetLabel(AspectPreset.Value)));
				val.Tip("Pick a preset below. Current choice is saved automatically.");
				val.Buttons(new(string, Action)[6]
				{
					("4:3", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio4_3);
					}),
					("5:4", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio5_4);
					}),
					("16:10", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio16_10);
					}),
					("16:9", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio16_9);
					}),
					("21:9", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio21_9);
					}),
					("Native", delegate
					{
						ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Native);
					})
				});
				val.Slider("Stretch Amount", StretchAmount, 0f, 1f);
				val.Slider("Horizontal Scale", HorizontalScale, 0.5f, 2f);
				val.Header("Effects");
				val.Toggle("Effects Enabled", FxEnabled);
				val.Slider("Brightness", FxBrightness, -2f, 2f);
				val.Slider("Contrast", FxContrast, -100f, 100f);
				val.Slider("Saturation", FxSaturation, -100f, 100f);
				val.Slider("Hue", FxHue, -180f, 180f);
				val.Colour("Tint", FxTint);
				val.Slider("Temperature", FxTemperature, -100f, 100f);
				val.Slider("WB Tint", FxWbTint, -100f, 100f);
				val.Slider("Vignette", FxVignette, 0f, 1f);
				val.Slider("Bloom", FxBloom, 0f, 5f);
				val.Slider("Bloom Threshold", FxBloomThreshold, 0f, 2f);
				val.Button("Reset effects", (Action)ColorEffects.ResetDefaults);
				Log.LogInfo((object)"Registered FishyUI Options page: FishVisuals");
			}
		}

		private void TryRegisterSpongeMenu()
		{
			if (!Chainloader.PluginInfos.ContainsKey("SpongeMods.ModMenu"))
			{
				return;
			}
			try
			{
				RegisterSpongeMenu();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Sponge menu failed: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void RegisterSpongeMenu()
		{
			SpongeMenu.Tab("cursor.FishVisuals", "FishVisuals", 40).Heading("Viewmodel").Toggle("Enabled", Enabled)
				.Number("Offset X", OffsetX)
				.Number("Offset Y", OffsetY)
				.Number("Offset Z", OffsetZ)
				.Heading("Screen stretch")
				.Toggle("Stretch Enabled", StretchEnabled)
				.Choice("Aspect", (IReadOnlyList<string>)ScreenStretch.PresetLabels, (Func<int>)(() => (int)AspectPreset.Value), (Action<int>)delegate(int i)
				{
					ScreenStretch.ApplyPreset((AspectPreset)i);
				})
				.Number("Stretch Amount", StretchAmount)
				.Number("Horizontal Scale", HorizontalScale)
				.Press("4:3", (Action)delegate
				{
					ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio4_3);
				})
				.Press("16:9", (Action)delegate
				{
					ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Ratio16_9);
				})
				.Press("Native", (Action)delegate
				{
					ScreenStretch.ApplyPreset(FishVisuals.AspectPreset.Native);
				})
				.Heading("Effects")
				.Toggle("Effects Enabled", FxEnabled)
				.Number("Brightness", FxBrightness)
				.Number("Contrast", FxContrast)
				.Number("Saturation", FxSaturation)
				.Number("Hue", FxHue)
				.Number("Temperature", FxTemperature)
				.Number("WB Tint", FxWbTint)
				.Number("Vignette", FxVignette)
				.Number("Bloom", FxBloom)
				.Number("Bloom Threshold", FxBloomThreshold)
				.Press("Reset effects", (Action)ColorEffects.ResetDefaults)
				.Note("Tint colour + hand preview: Options → Mods → FishVisuals or Insert.");
			Log.LogInfo((object)"Registered Sponge Mod Menu tab: FishVisuals");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public enum AspectPreset
	{
		Native,
		Ratio4_3,
		Ratio5_4,
		Ratio16_10,
		Ratio16_9,
		Ratio21_9
	}
	internal static class ScreenStretch
	{
		internal static readonly string[] PresetLabels = new string[6] { "Native", "4:3", "5:4", "16:10", "16:9", "21:9" };

		private static bool _loggedWait;

		private static bool _renderHooked;

		internal static string PresetLabel(AspectPreset preset)
		{
			int num = (int)preset;
			if (num >= 0 && num < PresetLabels.Length)
			{
				return PresetLabels[num];
			}
			return preset.ToString();
		}

		internal static float PresetAspect(AspectPreset preset)
		{
			return preset switch
			{
				AspectPreset.Ratio4_3 => 1.3333334f, 
				AspectPreset.Ratio5_4 => 1.25f, 
				AspectPreset.Ratio16_10 => 1.6f, 
				AspectPreset.Ratio16_9 => 1.7777778f, 
				AspectPreset.Ratio21_9 => 2.3333333f, 
				_ => NativeAspect(), 
			};
		}

		internal static float NativeAspect()
		{
			int num = Mathf.Max(1, Screen.width);
			int num2 = Mathf.Max(1, Screen.height);
			return (float)num / (float)num2;
		}

		internal static bool ScreenReady()
		{
			if (Screen.width >= 64)
			{
				return Screen.height >= 64;
			}
			return false;
		}

		internal static float GetTargetAspect()
		{
			float num = NativeAspect();
			if (Plugin.StretchEnabled == null || !Plugin.StretchEnabled.Value)
			{
				return num;
			}
			AspectPreset aspectPreset = ((Plugin.AspectPreset != null) ? Plugin.AspectPreset.Value : AspectPreset.Native);
			float num2 = ((Plugin.StretchAmount != null) ? Mathf.Clamp01(Plugin.StretchAmount.Value) : 0f);
			float num3 = ((Plugin.HorizontalScale != null) ? Mathf.Max(0.25f, Plugin.HorizontalScale.Value) : 1f);
			if (aspectPreset != AspectPreset.Native && num2 > 0.0001f)
			{
				float num4 = PresetAspect(aspectPreset);
				return Mathf.Clamp(Mathf.Lerp(num, num4, num2), 0.2f, 5f);
			}
			if (Mathf.Abs(num3 - 1f) <= 0.001f)
			{
				return num;
			}
			return Mathf.Clamp(num / num3, 0.2f, 5f);
		}

		internal static bool IsActive()
		{
			if (Plugin.StretchEnabled == null || !Plugin.StretchEnabled.Value)
			{
				return false;
			}
			if (!ScreenReady())
			{
				return false;
			}
			float num = ((Plugin.StretchAmount != null) ? Plugin.StretchAmount.Value : 0f);
			float num2 = ((Plugin.HorizontalScale != null) ? Plugin.HorizontalScale.Value : 1f);
			if (Plugin.AspectPreset != null && Plugin.AspectPreset.Value != AspectPreset.Native && num > 0.001f)
			{
				return true;
			}
			if (Mathf.Abs(num2 - 1f) > 0.001f)
			{
				return true;
			}
			return false;
		}

		internal static void ApplyTo(Camera cam)
		{
			if ((Object)(object)cam == (Object)null)
			{
				return;
			}
			if (!ScreenReady())
			{
				if (!_loggedWait)
				{
					_loggedWait = true;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Stretch waiting for valid screen size…");
					}
				}
			}
			else
			{
				float aspect = (IsActive() ? GetTargetAspect() : NativeAspect());
				cam.aspect = aspect;
			}
		}

		internal static void ApplyLocalPlayerCamera()
		{
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				if ((Object)(object)localPlayer.CurCam != (Object)null)
				{
					ApplyTo(localPlayer.CurCam);
				}
				try
				{
					if ((Object)(object)localPlayer.Camera != (Object)null)
					{
						Camera component = ((Component)localPlayer.Camera).GetComponent<Camera>();
						if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)localPlayer.CurCam)
						{
							ApplyTo(component);
						}
					}
					return;
				}
				catch
				{
					return;
				}
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				ApplyTo(Camera.main);
			}
		}

		internal static void ApplyPreset(AspectPreset preset)
		{
			if (Plugin.AspectPreset == null)
			{
				return;
			}
			Plugin.AspectPreset.Value = preset;
			if (preset == AspectPreset.Native)
			{
				if (Plugin.StretchEnabled != null)
				{
					Plugin.StretchEnabled.Value = false;
				}
				if (Plugin.StretchAmount != null)
				{
					Plugin.StretchAmount.Value = 0f;
				}
				if (Plugin.HorizontalScale != null)
				{
					Plugin.HorizontalScale.Value = 1f;
				}
			}
			else
			{
				if (Plugin.StretchEnabled != null)
				{
					Plugin.StretchEnabled.Value = true;
				}
				if (Plugin.StretchAmount != null)
				{
					Plugin.StretchAmount.Value = 1f;
				}
				if (Plugin.HorizontalScale != null)
				{
					Plugin.HorizontalScale.Value = 1f;
				}
			}
			Plugin instance = Plugin.Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Config.Save();
			}
			ApplyLocalPlayerCamera();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Stretch preset → " + PresetLabel(preset) + " " + $"(enabled={Plugin.StretchEnabled?.Value}, amount={Plugin.StretchAmount?.Value}, " + $"aspect={GetTargetAspect():0.####}, native={NativeAspect():0.####})"));
			}
		}

		internal static void SanitizeLoadedConfig()
		{
			if (Plugin.AspectPreset == null || Plugin.StretchEnabled == null)
			{
				return;
			}
			AspectPreset value = Plugin.AspectPreset.Value;
			if (!Plugin.StretchEnabled.Value || value == AspectPreset.Native)
			{
				return;
			}
			bool flag = false;
			if (Plugin.StretchAmount != null && Plugin.StretchAmount.Value < 0.999f)
			{
				Plugin.StretchAmount.Value = 1f;
				flag = true;
			}
			if (Plugin.HorizontalScale != null && Mathf.Abs(Plugin.HorizontalScale.Value - 1f) > 0.001f)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)($"Stretch: resetting Horizontal Scale {Plugin.HorizontalScale.Value:0.###} → 1 " + "(saved preset " + PresetLabel(value) + " is absolute)"));
				}
				Plugin.HorizontalScale.Value = 1f;
				flag = true;
			}
			if (flag)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Save();
				}
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("Stretch restored from config: " + PresetLabel(value) + " " + $"(target={GetTargetAspect():0.####})"));
			}
		}

		internal static void BindSettingEvents()
		{
			if (Plugin.StretchEnabled != null)
			{
				Plugin.StretchEnabled.SettingChanged += OnChange;
			}
			if (Plugin.AspectPreset != null)
			{
				Plugin.AspectPreset.SettingChanged += OnChange;
			}
			if (Plugin.StretchAmount != null)
			{
				Plugin.StretchAmount.SettingChanged += OnChange;
			}
			if (Plugin.HorizontalScale != null)
			{
				Plugin.HorizontalScale.SettingChanged += OnChange;
			}
			static void OnChange(object _s, EventArgs _e)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Save();
				}
				ApplyLocalPlayerCamera();
			}
		}

		internal static void HookRenderPipeline()
		{
			if (!_renderHooked)
			{
				RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
				_renderHooked = true;
			}
		}

		private static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
		{
			if ((Object)(object)camera == (Object)null || !IsActive())
			{
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				if (!((Object)(object)camera == (Object)(object)localPlayer.CurCam))
				{
					try
					{
						if ((Object)(object)localPlayer.Camera != (Object)null && (Object)(object)camera == (Object)(object)((Component)localPlayer.Camera).GetComponent<Camera>())
						{
							ApplyTo(camera);
						}
						return;
					}
					catch
					{
						return;
					}
				}
				ApplyTo(camera);
			}
			else if ((Object)(object)camera == (Object)(object)Camera.main)
			{
				ApplyTo(camera);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "Update")]
	internal static class PlayerCameraStretchPatch
	{
		private static void Postfix(PlayerCamera __instance)
		{
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)localPlayer.Camera == (Object)(object)__instance || localPlayer.Camera == __instance)
				{
					ScreenStretch.ApplyTo(((Object)(object)localPlayer.CurCam != (Object)null) ? localPlayer.CurCam : ((Component)__instance).GetComponent<Camera>());
					return;
				}
			}
			catch
			{
			}
			Camera component = ((Component)__instance).GetComponent<Camera>();
			if ((Object)(object)component != (Object)null && ((Object)(object)component == (Object)(object)localPlayer.CurCam || (Object)(object)component == (Object)(object)Camera.main))
			{
				ScreenStretch.ApplyTo(component);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerCamera), "OnEnable")]
	internal static class PlayerCameraStretchEnablePatch
	{
		private static void Postfix(PlayerCamera __instance)
		{
			ScreenStretch.ApplyLocalPlayerCamera();
		}
	}
}