Decompiled source of GMCameraPresetSwitcher v1.0.0

GM.CameraPresetSwitcher.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("GM.CameraPresetSwitcher")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GM.CameraPresetSwitcher")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6a764054-64cb-436a-99d8-3c321a2a5e2f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("gm.camera_live_editor", "GM Camera Live Editor", "1.6.1")]
public class CameraLiveEditor : BaseUnityPlugin
{
	private struct Preset
	{
		public string name;

		public Vector3 posOffset;

		public Vector3 targetOffset;

		public int fov;

		public bool hideHead;

		public bool hideHelmet;

		public int hideMode;
	}

	private KeyCode _toggleUiKey = (KeyCode)285;

	private KeyCode _cycleKey = (KeyCode)286;

	private KeyCode _slot1Key = (KeyCode)289;

	private KeyCode _slot2Key = (KeyCode)290;

	private KeyCode _slot3Key = (KeyCode)291;

	private KeyCode _toggleHideHeadKey = (KeyCode)287;

	private KeyCode _toggleHideHelmetKey = (KeyCode)288;

	private bool _uiOpen = false;

	private bool _livePreview = false;

	private ConfigEntry<int> _slotCount;

	private ConfigEntry<string> _cfgKeyToggleUI;

	private ConfigEntry<string> _cfgKeyCycle;

	private ConfigEntry<string> _cfgKeySlot1;

	private ConfigEntry<string> _cfgKeySlot2;

	private ConfigEntry<string> _cfgKeySlot3;

	private ConfigEntry<string> _cfgKeyHideHead;

	private ConfigEntry<string> _cfgKeyHideHelmet;

	private ConfigEntry<bool> _cfgEnglish;

	private ConfigEntry<bool> _cfgEnforceHide;

	private ConfigEntry<string> _cfgHeadKeywords;

	private ConfigEntry<string> _cfgHelmetKeywords;

	private bool _enforceHide = true;

	private float _nextHideRefresh = 0f;

	private string _headKeywordsStr = "head";

	private string _helmetKeywordsStr = "helmet";

	private string[] _headKeywords = new string[1] { "head" };

	private string[] _helmetKeywords = new string[1] { "helmet" };

	private Dictionary<Renderer, bool> _rendererPrevEnabled = new Dictionary<Renderer, bool>();

	private Dictionary<Transform, Vector3> _transformPrevScale = new Dictionary<Transform, Vector3>();

	private Preset[] _slots = new Preset[3];

	private int _currentSlot = 0;

	private string[] _nameStr = new string[3];

	private string[] _posX = new string[3];

	private string[] _posY = new string[3];

	private string[] _posZ = new string[3];

	private string[] _tgtX = new string[3];

	private string[] _tgtY = new string[3];

	private string[] _tgtZ = new string[3];

	private string[] _fov = new string[3];

	private ConfigEntry<string>[] _slotName;

	private ConfigEntry<string>[] _slotData;

	private Type _tSettingsHelper;

	private Type _tPlayerOptionsManager;

	private Type _tPlayerCameraSettings;

	private MethodInfo _mGetCameraSettings;

	private MethodInfo _mSetCameraSettings;

	private MethodInfo _mSavePlayerSettings;

	private MethodInfo _mLoadCameraSettings;

	private FieldInfo _fPOMSingleton;

	private Type _tCameraSmoothFollow;

	private MethodInfo _mCSF_SetCameraSettings;

	private FieldInfo _fCSF_Target;

	private PropertyInfo _pCSF_Target;

	private static readonly BindingFlags AnyStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

	private static readonly BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private const int FOV_MIN = 30;

	private const int FOV_MAX = 150;

	private bool _checkedInputSystem = false;

	private bool _hasInputSystem = false;

	private Type _tKeyboard = null;

	private PropertyInfo _pKeyboardCurrent = null;

	private void Awake()
	{
		_slotCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SlotCount", 3, "循环切换数量(2或3)");
		_cfgEnglish = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "English", false, "面板英文");
		_cfgKeyToggleUI = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "ToggleUI", "F4", "KeyCode");
		_cfgKeyCycle = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "Cycle", "F5", "KeyCode");
		_cfgKeySlot1 = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "Slot1", "F8", "KeyCode");
		_cfgKeySlot2 = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "Slot2", "F9", "KeyCode");
		_cfgKeySlot3 = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "Slot3", "F10", "KeyCode");
		_cfgKeyHideHead = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "ToggleHideHead", "F6", "KeyCode");
		_cfgKeyHideHelmet = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "ToggleHideHelmet", "F7", "KeyCode");
		ApplyHotkeysFromConfig();
		_cfgEnforceHide = ((BaseUnityPlugin)this).Config.Bind<bool>("Hide", "Enforce", true, "是否持续强制(防止被刷回)");
		_cfgHeadKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("Hide", "HeadKeywords", "head", "头部匹配关键词(逗号分隔)");
		_cfgHelmetKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("Hide", "HelmetKeywords", "helmet", "头盔匹配关键词(逗号分隔)");
		_enforceHide = _cfgEnforceHide.Value;
		_headKeywordsStr = _cfgHeadKeywords.Value;
		_helmetKeywordsStr = _cfgHelmetKeywords.Value;
		RefreshKeywords();
		_slotName = new ConfigEntry<string>[3];
		_slotData = new ConfigEntry<string>[3];
		for (int i = 0; i < 3; i++)
		{
			int num = i + 1;
			_slotName[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Presets", "Slot" + num + "_Name", "Preset " + num, "显示名称");
			string text = num switch
			{
				1 => "0,1.8,-1.8|0,0.6,0|70|0|0|0", 
				2 => "0,2.2,-2.5|0,0.8,0.2|80|0|0|0", 
				_ => "0,3.0,-4.0|0,1.2,0.6|95|0|0|0", 
			};
			_slotData[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Presets", "Slot" + num + "_Data", text, "pos|target|fov|hideHead|hideHelmet|hideMode");
		}
		LoadSlotsFromConfig();
		SlotsToInputStrings();
		CacheTypesAndMethods_SignatureBased();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"GM Camera Live Editor v1.6.1 loaded.");
	}

	private void OnDestroy()
	{
		RestoreHiddenParts();
	}

	private void ApplyHotkeysFromConfig()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_0034: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_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_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		_toggleUiKey = ParseKey(_cfgKeyToggleUI.Value, (KeyCode)285);
		_cycleKey = ParseKey(_cfgKeyCycle.Value, (KeyCode)286);
		_slot1Key = ParseKey(_cfgKeySlot1.Value, (KeyCode)289);
		_slot2Key = ParseKey(_cfgKeySlot2.Value, (KeyCode)290);
		_slot3Key = ParseKey(_cfgKeySlot3.Value, (KeyCode)291);
		_toggleHideHeadKey = ParseKey(_cfgKeyHideHead.Value, (KeyCode)287);
		_toggleHideHelmetKey = ParseKey(_cfgKeyHideHelmet.Value, (KeyCode)288);
	}

	private KeyCode ParseKey(string s, KeyCode fb)
	{
		//IL_000b: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_0024: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(s))
		{
			return fb;
		}
		try
		{
			if (Enum.TryParse<KeyCode>(s.Trim(), ignoreCase: true, out KeyCode result))
			{
				return result;
			}
		}
		catch
		{
		}
		return fb;
	}

	private void Update()
	{
		//IL_0003: 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_004f: 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_0089: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		if (IsKeyDownCompat(_toggleUiKey))
		{
			_uiOpen = !_uiOpen;
		}
		int slotCount = GetSlotCount();
		if (IsKeyDownCompat(_cycleKey))
		{
			int slotIndex = (_currentSlot + 1) % slotCount;
			ApplySlot(slotIndex, saveToGameSettings: false);
		}
		if (IsKeyDownCompat(_slot1Key))
		{
			ApplySlot(0, saveToGameSettings: false);
		}
		if (IsKeyDownCompat(_slot2Key))
		{
			ApplySlot(1, saveToGameSettings: false);
		}
		if (slotCount >= 3 && IsKeyDownCompat(_slot3Key))
		{
			ApplySlot(2, saveToGameSettings: false);
		}
		if (IsKeyDownCompat(_toggleHideHeadKey))
		{
			_slots[_currentSlot].hideHead = !_slots[_currentSlot].hideHead;
			SaveSlotToConfig(_currentSlot);
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		if (IsKeyDownCompat(_toggleHideHelmetKey))
		{
			_slots[_currentSlot].hideHelmet = !_slots[_currentSlot].hideHelmet;
			SaveSlotToConfig(_currentSlot);
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		if (_enforceHide && NeedHideNow() && Time.unscaledTime >= _nextHideRefresh)
		{
			ApplyHideOnce();
			_nextHideRefresh = Time.unscaledTime + 0.5f;
		}
	}

	private bool NeedHideNow()
	{
		Preset preset = _slots[_currentSlot];
		return preset.hideHead || preset.hideHelmet;
	}

	private void OnGUI()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		if (!_uiOpen)
		{
			return;
		}
		GUI.depth = 0;
		int num = 20;
		int num2 = 20;
		bool value = _cfgEnglish.Value;
		GUILayout.BeginArea(new Rect((float)num, (float)num2, 780f, 780f), GUI.skin.window);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(value ? "GM Camera Live Editor (Numeric Input)" : "GM Camera Live Editor(数字输入版)", Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		if (GUILayout.Button(value ? "EN/中文" : "中文/EN", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
		{
			_cfgEnglish.Value = !_cfgEnglish.Value;
			((BaseUnityPlugin)this).Config.Save();
		}
		GUILayout.EndHorizontal();
		GUILayout.Label(value ? "Hotkeys: ToggleUI/Cycle/HideHead/HideHelmet/Slot1/Slot2/Slot3 (configurable)" : "热键:面板/循环/隐藏头/隐藏盔/槽1/槽2/槽3(可在config改)", Array.Empty<GUILayoutOption>());
		GUILayout.Space(6f);
		bool flag = EnsureReady();
		GUILayout.Label((value ? "Hook(SettingsHelper/PlayerCameraSettings): " : "Hook(SettingsHelper/PlayerCameraSettings):") + (flag ? "OK" : "NOT FOUND"), Array.Empty<GUILayoutOption>());
		int num3 = CountCameraSmoothFollows();
		GUILayout.Label((value ? "CameraSmoothFollow found: " : "CameraSmoothFollow数量:") + num3, Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		_livePreview = GUILayout.Toggle(_livePreview, value ? "Live Preview" : "实时预览(输入时自动应用)", Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(value ? "Rescan Hook" : "重新扫描(修复Hook)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }))
		{
			CacheTypesAndMethods_SignatureBased();
		}
		if (GUILayout.Button(value ? "Reload hotkeys" : "重载热键(config)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }))
		{
			ApplyHotkeysFromConfig();
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		int slotCount = GetSlotCount();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("Slot 1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
		{
			_currentSlot = 0;
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		if (GUILayout.Button("Slot 2", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
		{
			_currentSlot = 1;
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		if (slotCount >= 3 && GUILayout.Button("Slot 3", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
		{
			_currentSlot = 2;
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(value ? "SlotCount(2/3)" : "SlotCount(2/3)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
		string s = GUILayout.TextField(slotCount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
		if (int.TryParse(s, out var result))
		{
			if (result < 2)
			{
				result = 2;
			}
			if (result > 3)
			{
				result = 3;
			}
			if (result != slotCount)
			{
				_slotCount.Value = result;
				((BaseUnityPlugin)this).Config.Save();
				if (_currentSlot >= result)
				{
					_currentSlot = result - 1;
				}
			}
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label(value ? "—— Global Hide Settings (keywords shared by all presets) ——" : "—— 全局隐藏设置(关键词全preset共用;是否隐藏跟preset走)——", Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		bool flag2 = GUILayout.Toggle(_enforceHide, value ? "Enforce (prevent revert)" : "持续强制(防止被刷回)", Array.Empty<GUILayoutOption>());
		if (flag2 != _enforceHide)
		{
			_enforceHide = flag2;
			_cfgEnforceHide.Value = _enforceHide;
			((BaseUnityPlugin)this).Config.Save();
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(value ? "Head keys:" : "Head关键词:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
		string text = GUILayout.TextField(_headKeywordsStr, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
		if (text != _headKeywordsStr)
		{
			_headKeywordsStr = text;
			_cfgHeadKeywords.Value = _headKeywordsStr;
			RefreshKeywords();
			((BaseUnityPlugin)this).Config.Save();
			if (NeedHideNow())
			{
				ApplyHideByCurrentPreset(forceRestoreFirst: true);
			}
		}
		GUILayout.Label(value ? "Helmet keys:" : "Helmet关键词:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) });
		string text2 = GUILayout.TextField(_helmetKeywordsStr, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
		if (text2 != _helmetKeywordsStr)
		{
			_helmetKeywordsStr = text2;
			_cfgHelmetKeywords.Value = _helmetKeywordsStr;
			RefreshKeywords();
			((BaseUnityPlugin)this).Config.Save();
			if (NeedHideNow())
			{
				ApplyHideByCurrentPreset(forceRestoreFirst: true);
			}
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(value ? "Log matched renderers" : "打印匹配结果(到BepInEx日志)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }))
		{
			LogHideMatches();
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		int currentSlot = _currentSlot;
		Preset preset = _slots[currentSlot];
		GUILayout.Label(value ? "—— Current Preset Hide (saved per preset) ——" : "—— 当前Preset隐藏设置(跟preset走)——", Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		bool flag3 = GUILayout.Toggle(preset.hideHead, value ? "Hide Head" : "隐藏头部", Array.Empty<GUILayoutOption>());
		bool flag4 = GUILayout.Toggle(preset.hideHelmet, value ? "Hide Helmet" : "隐藏头盔", Array.Empty<GUILayoutOption>());
		if (flag3 != preset.hideHead || flag4 != preset.hideHelmet)
		{
			preset.hideHead = flag3;
			preset.hideHelmet = flag4;
			_slots[currentSlot] = preset;
			SaveSlotToConfig(currentSlot);
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(value ? "Mode:" : "模式:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
		bool flag5 = GUILayout.Toggle(preset.hideMode == 0, value ? "Disable Renderer (recommended)" : "禁用Renderer(推荐)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) });
		bool flag6 = GUILayout.Toggle(preset.hideMode == 1, value ? "Scale Transform=0" : "缩放Transform(scale=0)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) });
		int num4 = preset.hideMode;
		if (flag5)
		{
			num4 = 0;
		}
		if (flag6)
		{
			num4 = 1;
		}
		if (num4 != preset.hideMode)
		{
			preset.hideMode = num4;
			_slots[currentSlot] = preset;
			SaveSlotToConfig(currentSlot);
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		GUILayout.EndHorizontal();
		if (GUILayout.Button(value ? "Force Restore Visible" : "恢复显示(强制)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }))
		{
			RestoreHiddenParts();
			_slots[currentSlot].hideHead = false;
			_slots[currentSlot].hideHelmet = false;
			SaveSlotToConfig(currentSlot);
		}
		GUILayout.Space(14f);
		GUILayout.Label(value ? "—— Camera Preset (numeric input) ——" : "—— 镜头Preset(数值输入)——", Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("Name", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
		_nameStr[currentSlot] = GUILayout.TextField(_nameStr[currentSlot], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(600f) });
		GUILayout.EndHorizontal();
		GUILayout.Space(8f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("FOV (" + 30 + "-" + 150 + ")", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
		_fov[currentSlot] = GUILayout.TextField(_fov[currentSlot], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label(value ? "Camera Position Offset (posOffset)" : "Camera Position Offset (posOffset)", Array.Empty<GUILayoutOption>());
		DrawXYZRow(_posX, _posY, _posZ, currentSlot);
		GUILayout.Space(10f);
		GUILayout.Label(value ? "Camera Target Offset (targetOffset)" : "Camera Target Offset (targetOffset)", Array.Empty<GUILayoutOption>());
		DrawXYZRow(_tgtX, _tgtY, _tgtZ, currentSlot);
		GUILayout.Space(14f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(value ? "Apply (live only)" : "应用(立刻生效,不写入设置)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }) && InputStringsToSlot(currentSlot))
		{
			ApplySlot(currentSlot, saveToGameSettings: false);
		}
		if (GUILayout.Button(value ? "Apply + Save to game settings" : "应用并写入游戏设置(防止打开设置刷回)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }) && InputStringsToSlot(currentSlot))
		{
			ApplySlot(currentSlot, saveToGameSettings: true);
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button(value ? "Read current game settings into this slot" : "从当前游戏设置读取到本槽", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }) && TryReadFromGame(out var p))
		{
			p.name = _nameStr[currentSlot];
			p.hideHead = _slots[currentSlot].hideHead;
			p.hideHelmet = _slots[currentSlot].hideHelmet;
			p.hideMode = _slots[currentSlot].hideMode;
			_slots[currentSlot] = p;
			SlotToInputStrings(currentSlot);
		}
		if (GUILayout.Button(value ? "Save this slot (BepInEx config)" : "保存本槽到BepInEx Config(重启保留)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }) && InputStringsToSlot(currentSlot))
		{
			SaveSlotToConfig(currentSlot);
		}
		GUILayout.EndHorizontal();
		if (_livePreview && TryParseInputToPreset(currentSlot, out var p2))
		{
			p2.hideHead = _slots[currentSlot].hideHead;
			p2.hideHelmet = _slots[currentSlot].hideHelmet;
			p2.hideMode = _slots[currentSlot].hideMode;
			_slots[currentSlot] = p2;
			ApplySlot(currentSlot, saveToGameSettings: false);
		}
		GUILayout.EndArea();
	}

	private void DrawXYZRow(string[] xs, string[] ys, string[] zs, int i)
	{
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(16f) });
		xs[i] = GUILayout.TextField(xs[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		GUILayout.Label("Y", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(16f) });
		ys[i] = GUILayout.TextField(ys[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		GUILayout.Label("Z", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(16f) });
		zs[i] = GUILayout.TextField(zs[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		GUILayout.EndHorizontal();
	}

	private int GetSlotCount()
	{
		int num = _slotCount.Value;
		if (num < 2)
		{
			num = 2;
		}
		if (num > 3)
		{
			num = 3;
		}
		return num;
	}

	private void RefreshKeywords()
	{
		_headKeywords = SplitKeywords(_headKeywordsStr, "head");
		_helmetKeywords = SplitKeywords(_helmetKeywordsStr, "helmet");
	}

	private static string[] SplitKeywords(string s, string fallback)
	{
		if (string.IsNullOrEmpty(s))
		{
			return new string[1] { fallback };
		}
		string[] array = s.Split(new char[1] { ',' });
		List<string> list = new List<string>();
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (!string.IsNullOrEmpty(text))
			{
				list.Add(text);
			}
		}
		if (list.Count == 0)
		{
			list.Add(fallback);
		}
		return list.ToArray();
	}

	private bool NameMatchesAny(string n, string[] keywords)
	{
		if (string.IsNullOrEmpty(n))
		{
			return false;
		}
		foreach (string value in keywords)
		{
			if (!string.IsNullOrEmpty(value) && n.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	private bool NameMatchesSelected(string n)
	{
		Preset preset = _slots[_currentSlot];
		bool flag = false;
		if (preset.hideHead)
		{
			flag |= NameMatchesAny(n, _headKeywords);
		}
		if (preset.hideHelmet)
		{
			flag |= NameMatchesAny(n, _helmetKeywords);
		}
		return flag;
	}

	private void CleanupHiddenCaches()
	{
		List<Renderer> list = null;
		foreach (KeyValuePair<Renderer, bool> item in _rendererPrevEnabled)
		{
			if ((Object)(object)item.Key == (Object)null)
			{
				if (list == null)
				{
					list = new List<Renderer>();
				}
				list.Add(item.Key);
			}
		}
		if (list != null)
		{
			for (int i = 0; i < list.Count; i++)
			{
				_rendererPrevEnabled.Remove(list[i]);
			}
		}
		List<Transform> list2 = null;
		foreach (KeyValuePair<Transform, Vector3> item2 in _transformPrevScale)
		{
			if ((Object)(object)item2.Key == (Object)null)
			{
				if (list2 == null)
				{
					list2 = new List<Transform>();
				}
				list2.Add(item2.Key);
			}
		}
		if (list2 != null)
		{
			for (int j = 0; j < list2.Count; j++)
			{
				_transformPrevScale.Remove(list2[j]);
			}
		}
	}

	private void ApplyHideByCurrentPreset(bool forceRestoreFirst)
	{
		if (forceRestoreFirst)
		{
			RestoreHiddenParts();
		}
		if (NeedHideNow())
		{
			ApplyHideOnce();
		}
	}

	private void ApplyHideOnce()
	{
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		if (!NeedHideNow())
		{
			return;
		}
		CleanupHiddenCaches();
		Transform val = TryGetLocalPlayerRootFromCameraTarget();
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Preset preset = _slots[_currentSlot];
		if (preset.hideMode == 0)
		{
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				string name = ((Object)val2).name;
				string n = (((Object)(object)((Component)val2).gameObject != (Object)null) ? ((Object)((Component)val2).gameObject).name : "");
				if (NameMatchesSelected(name) || NameMatchesSelected(n))
				{
					if (!_rendererPrevEnabled.ContainsKey(val2))
					{
						_rendererPrevEnabled.Add(val2, val2.enabled);
					}
					val2.enabled = false;
				}
			}
			return;
		}
		Transform[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Transform>(true);
		foreach (Transform val3 in componentsInChildren2)
		{
			if (!((Object)(object)val3 == (Object)null) && NameMatchesSelected(((Object)val3).name))
			{
				if (!_transformPrevScale.ContainsKey(val3))
				{
					_transformPrevScale.Add(val3, val3.localScale);
				}
				val3.localScale = Vector3.zero;
			}
		}
	}

	private void RestoreHiddenParts()
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		foreach (KeyValuePair<Renderer, bool> item in _rendererPrevEnabled)
		{
			if ((Object)(object)item.Key != (Object)null)
			{
				item.Key.enabled = item.Value;
			}
		}
		_rendererPrevEnabled.Clear();
		foreach (KeyValuePair<Transform, Vector3> item2 in _transformPrevScale)
		{
			if ((Object)(object)item2.Key != (Object)null)
			{
				item2.Key.localScale = item2.Value;
			}
		}
		_transformPrevScale.Clear();
	}

	private void LogHideMatches()
	{
		Transform val = TryGetLocalPlayerRootFromCameraTarget();
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[HideLog] local root = null (cannot get from CameraSmoothFollow target)");
			return;
		}
		int num = 0;
		int num2 = 0;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[HideLog] Root = " + ((Object)val).name));
		Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			string text = ((Object)val2).name ?? "";
			string text2 = (((Object)(object)((Component)val2).gameObject != (Object)null) ? (((Object)((Component)val2).gameObject).name ?? "") : "");
			bool flag = NameMatchesAny(text, _headKeywords) || NameMatchesAny(text2, _headKeywords);
			bool flag2 = NameMatchesAny(text, _helmetKeywords) || NameMatchesAny(text2, _helmetKeywords);
			if (flag || flag2)
			{
				if (flag)
				{
					num++;
				}
				if (flag2)
				{
					num2++;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HideLog] Renderer match: name='{text}', go='{text2}', enabled={val2.enabled}, head={flag}, helmet={flag2}");
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HideLog] Summary: matched head={num}, helmet={num2}");
	}

	private Transform TryGetLocalPlayerRootFromCameraTarget()
	{
		TryFindCameraSmoothFollow();
		if (_tCameraSmoothFollow == null)
		{
			return null;
		}
		Object[] array = FindObjectsOfTypeCompat(_tCameraSmoothFollow);
		if (array == null || array.Length == 0)
		{
			return null;
		}
		foreach (object obj in array)
		{
			if (obj == null)
			{
				continue;
			}
			Transform val = null;
			try
			{
				if (_fCSF_Target != null)
				{
					object value = _fCSF_Target.GetValue(obj);
					val = (Transform)((value is Transform) ? value : null);
				}
				if ((Object)(object)val == (Object)null && _pCSF_Target != null)
				{
					object value2 = _pCSF_Target.GetValue(obj, null);
					val = (Transform)((value2 is Transform) ? value2 : null);
				}
			}
			catch
			{
			}
			if ((Object)(object)val != (Object)null)
			{
				return ((Object)(object)val.root != (Object)null) ? val.root : val;
			}
		}
		return null;
	}

	private bool InputStringsToSlot(int i)
	{
		Preset preset = _slots[i];
		if (!TryParseInputToPreset(i, out var p))
		{
			return false;
		}
		p.hideHead = preset.hideHead;
		p.hideHelmet = preset.hideHelmet;
		p.hideMode = preset.hideMode;
		_slots[i] = p;
		return true;
	}

	private bool TryParseInputToPreset(int i, out Preset p)
	{
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		p = default(Preset);
		p.name = _nameStr[i];
		if (!TryParseFloat(_posX[i], out var v))
		{
			return false;
		}
		if (!TryParseFloat(_posY[i], out var v2))
		{
			return false;
		}
		if (!TryParseFloat(_posZ[i], out var v3))
		{
			return false;
		}
		if (!TryParseFloat(_tgtX[i], out var v4))
		{
			return false;
		}
		if (!TryParseFloat(_tgtY[i], out var v5))
		{
			return false;
		}
		if (!TryParseFloat(_tgtZ[i], out var v6))
		{
			return false;
		}
		if (!TryParseInt(_fov[i], out var v7))
		{
			return false;
		}
		if (v7 < 30)
		{
			v7 = 30;
		}
		if (v7 > 150)
		{
			v7 = 150;
		}
		p.posOffset = new Vector3(v, v2, v3);
		p.targetOffset = new Vector3(v4, v5, v6);
		p.fov = v7;
		p.hideHead = false;
		p.hideHelmet = false;
		p.hideMode = 0;
		return true;
	}

	private static bool TryParseFloat(string s, out float v)
	{
		return float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out v) || float.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out v);
	}

	private static bool TryParseInt(string s, out int v)
	{
		return int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out v) || int.TryParse(s, NumberStyles.Integer, CultureInfo.CurrentCulture, out v);
	}

	private void SlotsToInputStrings()
	{
		for (int i = 0; i < 3; i++)
		{
			SlotToInputStrings(i);
		}
	}

	private void SlotToInputStrings(int i)
	{
		_nameStr[i] = _slots[i].name;
		_posX[i] = _slots[i].posOffset.x.ToString(CultureInfo.InvariantCulture);
		_posY[i] = _slots[i].posOffset.y.ToString(CultureInfo.InvariantCulture);
		_posZ[i] = _slots[i].posOffset.z.ToString(CultureInfo.InvariantCulture);
		_tgtX[i] = _slots[i].targetOffset.x.ToString(CultureInfo.InvariantCulture);
		_tgtY[i] = _slots[i].targetOffset.y.ToString(CultureInfo.InvariantCulture);
		_tgtZ[i] = _slots[i].targetOffset.z.ToString(CultureInfo.InvariantCulture);
		_fov[i] = _slots[i].fov.ToString(CultureInfo.InvariantCulture);
	}

	private void ApplySlot(int slotIndex, bool saveToGameSettings)
	{
		//IL_0054: 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)
		int slotCount = GetSlotCount();
		if (slotIndex < 0 || slotIndex >= slotCount)
		{
			return;
		}
		if (!EnsureReady())
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Hook失败:找不到 SettingsHelper/PlayerCameraSettings/SetCameraSettings。点“重新扫描”试试。");
			return;
		}
		Preset preset = _slots[slotIndex];
		object obj = CreatePlayerCameraSettings(preset.posOffset, preset.targetOffset, preset.fov);
		if (obj == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"创建 PlayerCameraSettings 失败。");
			return;
		}
		try
		{
			_mSetCameraSettings.Invoke(null, new object[1] { obj });
			ApplyToLiveCameras(obj);
			try
			{
				if ((Object)(object)Camera.main != (Object)null)
				{
					Camera.main.fieldOfView = preset.fov;
				}
			}
			catch
			{
			}
			if (saveToGameSettings)
			{
				if (_mSavePlayerSettings != null)
				{
					_mSavePlayerSettings.Invoke(null, null);
				}
				if (_mLoadCameraSettings != null)
				{
					_mLoadCameraSettings.Invoke(null, null);
				}
			}
			TrySyncOptionsUI();
			_currentSlot = slotIndex;
			ApplyHideByCurrentPreset(forceRestoreFirst: true);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
		}
	}

	private void ApplyToLiveCameras(object playerCameraSettingsObj)
	{
		TryFindCameraSmoothFollow();
		if (_tCameraSmoothFollow == null || _mCSF_SetCameraSettings == null)
		{
			return;
		}
		Object[] array = FindObjectsOfTypeCompat(_tCameraSmoothFollow);
		if (array == null)
		{
			return;
		}
		foreach (object obj in array)
		{
			if (obj != null)
			{
				TryInvokeSetCameraSettings(obj, playerCameraSettingsObj);
			}
		}
	}

	private void TryInvokeSetCameraSettings(object cameraSmoothFollowInstance, object pcs)
	{
		try
		{
			ParameterInfo[] parameters = _mCSF_SetCameraSettings.GetParameters();
			if (parameters.Length == 3)
			{
				_mCSF_SetCameraSettings.Invoke(cameraSmoothFollowInstance, new object[3] { pcs, false, null });
			}
			else if (parameters.Length == 2)
			{
				_mCSF_SetCameraSettings.Invoke(cameraSmoothFollowInstance, new object[2] { pcs, false });
			}
			else
			{
				_mCSF_SetCameraSettings.Invoke(cameraSmoothFollowInstance, new object[1] { pcs });
			}
		}
		catch
		{
		}
	}

	private int CountCameraSmoothFollows()
	{
		TryFindCameraSmoothFollow();
		if (_tCameraSmoothFollow == null)
		{
			return -1;
		}
		Object[] array = FindObjectsOfTypeCompat(_tCameraSmoothFollow);
		if (array == null)
		{
			return 0;
		}
		return array.Length;
	}

	private void TryFindCameraSmoothFollow()
	{
		if (_tCameraSmoothFollow != null && _mCSF_SetCameraSettings != null)
		{
			return;
		}
		_tCameraSmoothFollow = FindTypeByName("CameraSmoothFollow");
		if (_tCameraSmoothFollow == null)
		{
			return;
		}
		MethodInfo[] methods = _tCameraSmoothFollow.GetMethods(AnyInstance);
		foreach (MethodInfo methodInfo in methods)
		{
			if (!(methodInfo.Name != "SetCameraSettings"))
			{
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length >= 1 && (!(_tPlayerCameraSettings != null) || !(parameters[0].ParameterType != _tPlayerCameraSettings)))
				{
					_mCSF_SetCameraSettings = methodInfo;
					break;
				}
			}
		}
		_fCSF_Target = _tCameraSmoothFollow.GetField("target", AnyInstance);
		_pCSF_Target = _tCameraSmoothFollow.GetProperty("target", AnyInstance);
		if (_fCSF_Target == null)
		{
			_fCSF_Target = _tCameraSmoothFollow.GetField("targetTransform", AnyInstance);
		}
		if (_pCSF_Target == null)
		{
			_pCSF_Target = _tCameraSmoothFollow.GetProperty("targetTransform", AnyInstance);
		}
		if (_fCSF_Target == null)
		{
			_fCSF_Target = _tCameraSmoothFollow.GetField("followTarget", AnyInstance);
		}
		if (_pCSF_Target == null)
		{
			_pCSF_Target = _tCameraSmoothFollow.GetProperty("followTarget", AnyInstance);
		}
	}

	private Object[] FindObjectsOfTypeCompat(Type t)
	{
		try
		{
			Type typeFromHandle = typeof(Object);
			MethodInfo methodInfo = null;
			MethodInfo[] methods = typeFromHandle.GetMethods(AnyStatic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "FindObjectsByType"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length >= 2 && parameters[0].ParameterType == typeof(Type))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (methodInfo != null)
			{
				object obj = null;
				Type parameterType = methodInfo.GetParameters()[1].ParameterType;
				if (parameterType != null && parameterType.IsEnum)
				{
					obj = Enum.Parse(parameterType, "None");
				}
				ParameterInfo[] parameters2 = methodInfo.GetParameters();
				if (parameters2.Length == 2)
				{
					return (Object[])methodInfo.Invoke(null, new object[2] { t, obj });
				}
				if (parameters2.Length == 3)
				{
					return (Object[])methodInfo.Invoke(null, new object[3] { t, obj, false });
				}
			}
			MethodInfo method = typeFromHandle.GetMethod("FindObjectsOfType", AnyStatic, null, new Type[1] { typeof(Type) }, null);
			if (method != null)
			{
				return (Object[])method.Invoke(null, new object[1] { t });
			}
			MethodInfo method2 = typeFromHandle.GetMethod("FindObjectsOfType", AnyStatic, null, new Type[2]
			{
				typeof(Type),
				typeof(bool)
			}, null);
			if (method2 != null)
			{
				return (Object[])method2.Invoke(null, new object[2] { t, false });
			}
		}
		catch
		{
		}
		return null;
	}

	private bool TryReadFromGame(out Preset p)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		p = default(Preset);
		if (!EnsureReady() || _mGetCameraSettings == null)
		{
			return false;
		}
		try
		{
			object obj = _mGetCameraSettings.Invoke(null, null);
			if (obj == null)
			{
				return false;
			}
			p.posOffset = ReadVector3(obj, "cameraPositionOffset", "cameraPositionOffsetX", "cameraPositionOffsetY", "cameraPositionOffsetZ");
			p.targetOffset = ReadVector3(obj, "cameraTargetOffset", "cameraTargetOffsetX", "cameraTargetOffsetY", "cameraTargetOffsetZ");
			FieldInfo field = obj.GetType().GetField("cameraFov", AnyInstance);
			p.fov = ((field != null) ? ((int)field.GetValue(obj)) : 70);
			p.name = _slots[_currentSlot].name;
			p.hideHead = _slots[_currentSlot].hideHead;
			p.hideHelmet = _slots[_currentSlot].hideHelmet;
			p.hideMode = _slots[_currentSlot].hideMode;
			return true;
		}
		catch
		{
			return false;
		}
	}

	private void TrySyncOptionsUI()
	{
		if (_tPlayerOptionsManager == null || _fPOMSingleton == null)
		{
			return;
		}
		object obj = null;
		try
		{
			obj = _fPOMSingleton.GetValue(null);
		}
		catch
		{
			return;
		}
		if (obj == null)
		{
			return;
		}
		try
		{
			MethodInfo method = _tPlayerOptionsManager.GetMethod("LoadCameraSettings", AnyInstance);
			if (method != null)
			{
				method.Invoke(obj, null);
			}
			MethodInfo method2 = _tPlayerOptionsManager.GetMethod("PreviewCameraSettings", AnyInstance);
			if (method2 != null)
			{
				method2.Invoke(obj, null);
			}
		}
		catch
		{
		}
	}

	private void SaveSlotToConfig(int i)
	{
		_slots[i].name = _nameStr[i];
		_slotName[i].Value = _slots[i].name;
		_slotData[i].Value = SerializePresetData(_slots[i]);
		((BaseUnityPlugin)this).Config.Save();
	}

	private void LoadSlotsFromConfig()
	{
		//IL_0074: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < 3; i++)
		{
			_slots[i].name = _slotName[i].Value;
			if (!TryParsePresetData(_slotData[i].Value, out var p))
			{
				p = default(Preset);
				p.name = _slots[i].name;
				p.posOffset = new Vector3(0f, 1.8f, -1.8f);
				p.targetOffset = new Vector3(0f, 0.6f, 0f);
				p.fov = 70;
				p.hideHead = false;
				p.hideHelmet = false;
				p.hideMode = 0;
			}
			p.name = _slots[i].name;
			_slots[i] = p;
		}
	}

	private static string SerializePresetData(Preset p)
	{
		//IL_000b: 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)
		return V3(p.posOffset) + "|" + V3(p.targetOffset) + "|" + p.fov.ToString(CultureInfo.InvariantCulture) + "|" + (p.hideHead ? "1" : "0") + "|" + (p.hideHelmet ? "1" : "0") + "|" + p.hideMode.ToString(CultureInfo.InvariantCulture);
		static string V3(Vector3 v)
		{
			return v.x.ToString(CultureInfo.InvariantCulture) + "," + v.y.ToString(CultureInfo.InvariantCulture) + "," + v.z.ToString(CultureInfo.InvariantCulture);
		}
	}

	private static bool TryParsePresetData(string s, out Preset p)
	{
		//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_003f: 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)
		p = default(Preset);
		try
		{
			string[] array = s.Split(new char[1] { '|' });
			if (array.Length < 3)
			{
				return false;
			}
			p.posOffset = ParseV3(array[0]);
			p.targetOffset = ParseV3(array[1]);
			p.fov = int.Parse(array[2], CultureInfo.InvariantCulture);
			p.hideHead = array.Length >= 4 && array[3] == "1";
			p.hideHelmet = array.Length >= 5 && array[4] == "1";
			p.hideMode = ((array.Length >= 6) ? int.Parse(array[5], CultureInfo.InvariantCulture) : 0);
			return true;
		}
		catch
		{
			return false;
		}
		static Vector3 ParseV3(string v3)
		{
			//IL_003a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			string[] array2 = v3.Split(new char[1] { ',' });
			return new Vector3(float.Parse(array2[0], CultureInfo.InvariantCulture), float.Parse(array2[1], CultureInfo.InvariantCulture), float.Parse(array2[2], CultureInfo.InvariantCulture));
		}
	}

	private void CacheTypesAndMethods_SignatureBased()
	{
		_tSettingsHelper = null;
		_tPlayerCameraSettings = null;
		_tPlayerOptionsManager = FindTypeByName("PlayerOptionsManager");
		if (_tPlayerOptionsManager != null)
		{
			_fPOMSingleton = _tPlayerOptionsManager.GetField("singleton", AnyStatic);
		}
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			Type[] types;
			try
			{
				types = assembly.GetTypes();
			}
			catch
			{
				continue;
			}
			Type[] array = types;
			foreach (Type type in array)
			{
				if (type.IsClass && type.Name.EndsWith("PlayerCameraSettings") && !(type.GetField("cameraFov", AnyInstance) == null))
				{
					_tPlayerCameraSettings = type;
					break;
				}
			}
			if (_tPlayerCameraSettings != null)
			{
				break;
			}
		}
		if (_tPlayerCameraSettings != null)
		{
			Assembly[] assemblies2 = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies2)
			{
				Type[] types2;
				try
				{
					types2 = assembly2.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array2 = types2;
				foreach (Type type2 in array2)
				{
					if (!type2.IsClass)
					{
						continue;
					}
					MethodInfo method = type2.GetMethod("GetCameraSettings", AnyStatic);
					MethodInfo method2 = type2.GetMethod("SetCameraSettings", AnyStatic);
					if (!(method == null) && !(method2 == null) && !(method.ReturnType != _tPlayerCameraSettings))
					{
						ParameterInfo[] parameters = method2.GetParameters();
						if (parameters.Length == 1 && !(parameters[0].ParameterType != _tPlayerCameraSettings))
						{
							_tSettingsHelper = type2;
							_mGetCameraSettings = method;
							_mSetCameraSettings = method2;
							_mSavePlayerSettings = type2.GetMethod("SavePlayerSettings", AnyStatic);
							_mLoadCameraSettings = type2.GetMethod("LoadCameraSettings", AnyStatic);
							break;
						}
					}
				}
				if (_tSettingsHelper != null)
				{
					break;
				}
			}
		}
		_tCameraSmoothFollow = null;
		_mCSF_SetCameraSettings = null;
		_fCSF_Target = null;
		_pCSF_Target = null;
		_checkedInputSystem = false;
		InitInputSystemReflection();
	}

	private static Type FindTypeByName(string fullOrShortName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				Type type = assembly.GetType(fullOrShortName, throwOnError: false);
				if (type != null)
				{
					return type;
				}
				Type[] types = assembly.GetTypes();
				for (int j = 0; j < types.Length; j++)
				{
					if (types[j].Name == fullOrShortName)
					{
						return types[j];
					}
				}
			}
			catch
			{
			}
		}
		return null;
	}

	private bool EnsureReady()
	{
		if (_tSettingsHelper == null || _tPlayerCameraSettings == null || _mSetCameraSettings == null)
		{
			CacheTypesAndMethods_SignatureBased();
		}
		TryFindCameraSmoothFollow();
		return _tSettingsHelper != null && _tPlayerCameraSettings != null && _mSetCameraSettings != null;
	}

	private object CreatePlayerCameraSettings(Vector3 posOffset, Vector3 targetOffset, int fov)
	{
		//IL_009a: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			object obj = Activator.CreateInstance(_tPlayerCameraSettings);
			FieldInfo field = _tPlayerCameraSettings.GetField("cameraFov", AnyInstance);
			if (field != null)
			{
				field.SetValue(obj, fov);
			}
			PropertyInfo property = _tPlayerCameraSettings.GetProperty("cameraPositionOffset", AnyInstance);
			PropertyInfo property2 = _tPlayerCameraSettings.GetProperty("cameraTargetOffset", AnyInstance);
			if (property != null)
			{
				property.SetValue(obj, posOffset, null);
			}
			else
			{
				SetPrivateFloatTriplet(obj, "cameraPositionOffsetX", "cameraPositionOffsetY", "cameraPositionOffsetZ", posOffset);
			}
			if (property2 != null)
			{
				property2.SetValue(obj, targetOffset, null);
			}
			else
			{
				SetPrivateFloatTriplet(obj, "cameraTargetOffsetX", "cameraTargetOffsetY", "cameraTargetOffsetZ", targetOffset);
			}
			return obj;
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
			return null;
		}
	}

	private void SetPrivateFloatTriplet(object obj, string fx, string fy, string fz, Vector3 v)
	{
		//IL_003f: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		Type type = obj.GetType();
		FieldInfo field = type.GetField(fx, AnyInstance);
		FieldInfo field2 = type.GetField(fy, AnyInstance);
		FieldInfo field3 = type.GetField(fz, AnyInstance);
		if (field != null)
		{
			field.SetValue(obj, v.x);
		}
		if (field2 != null)
		{
			field2.SetValue(obj, v.y);
		}
		if (field3 != null)
		{
			field3.SetValue(obj, v.z);
		}
	}

	private static Vector3 ReadVector3(object pcs, string propName, string fx, string fy, string fz)
	{
		//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)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		Type t = pcs.GetType();
		PropertyInfo property = t.GetProperty(propName, AnyInstance);
		if (!(property != null) || !(property.GetValue(pcs, null) is Vector3 result))
		{
			return new Vector3(ReadF(fx), ReadF(fy), ReadF(fz));
		}
		return result;
		float ReadF(string f)
		{
			FieldInfo field = t.GetField(f, AnyInstance);
			return (field != null) ? ((float)field.GetValue(pcs)) : 0f;
		}
	}

	private bool IsKeyDownCompat(KeyCode key)
	{
		//IL_0002: 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)
		try
		{
			if (Input.GetKeyDown(key))
			{
				return true;
			}
		}
		catch
		{
		}
		if (!_checkedInputSystem)
		{
			InitInputSystemReflection();
		}
		if (!_hasInputSystem)
		{
			return false;
		}
		string text = KeyCodeToInputSystemKeyProp(key);
		if (text == null)
		{
			return false;
		}
		try
		{
			object value = _pKeyboardCurrent.GetValue(null, null);
			if (value == null)
			{
				return false;
			}
			PropertyInfo property = _tKeyboard.GetProperty(text, BindingFlags.Instance | BindingFlags.Public);
			if (property == null)
			{
				return false;
			}
			object value2 = property.GetValue(value, null);
			if (value2 == null)
			{
				return false;
			}
			PropertyInfo property2 = value2.GetType().GetProperty("wasPressedThisFrame", BindingFlags.Instance | BindingFlags.Public);
			if (property2 == null)
			{
				return false;
			}
			return (bool)property2.GetValue(value2, null);
		}
		catch
		{
			return false;
		}
	}

	private void InitInputSystemReflection()
	{
		_checkedInputSystem = true;
		_tKeyboard = null;
		_pKeyboardCurrent = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				Type type = assembly.GetType("UnityEngine.InputSystem.Keyboard", throwOnError: false);
				if (type != null)
				{
					_tKeyboard = type;
					break;
				}
			}
			catch
			{
			}
		}
		if (_tKeyboard == null)
		{
			_hasInputSystem = false;
			return;
		}
		_pKeyboardCurrent = _tKeyboard.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
		_hasInputSystem = _pKeyboardCurrent != null;
	}

	private string KeyCodeToInputSystemKeyProp(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Invalid comparison between Unknown and I4
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Invalid comparison between Unknown and I4
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Invalid comparison between Unknown and I4
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Invalid comparison between Unknown and I4
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Invalid comparison between Unknown and I4
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Invalid comparison between Unknown and I4
		if ((int)key == 285)
		{
			return "f4Key";
		}
		if ((int)key == 286)
		{
			return "f5Key";
		}
		if ((int)key == 287)
		{
			return "f6Key";
		}
		if ((int)key == 288)
		{
			return "f7Key";
		}
		if ((int)key == 289)
		{
			return "f8Key";
		}
		if ((int)key == 290)
		{
			return "f9Key";
		}
		if ((int)key == 291)
		{
			return "f10Key";
		}
		return null;
	}
}