Decompiled source of FarGaze v0.5.1

FarGaze.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GlobalEnums;
using HarmonyLib;
using InControl;
using Microsoft.CodeAnalysis;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Models;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using UnityEngine;
using UnityEngine.SceneManagement;
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("FarGaze")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.1.0")]
[assembly: AssemblyInformationalVersion("0.5.1")]
[assembly: AssemblyProduct("FarGaze")]
[assembly: AssemblyTitle("FarGaze")]
[assembly: AssemblyVersion("0.5.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 FarGaze
{
	internal sealed class BlurTransition : IDisposable
	{
		private ManualLogSource _log;

		private LightBlur? _lightBlur;

		private LightBlurredBackground? _background;

		private float _amount = 1f;

		private float _target = 1f;

		private bool _scanned;

		private int _blurPlaneCount;

		private int _originalRenderTextureHeight;

		private int _currentRenderTextureHeight;

		private bool _highResolutionActive;

		private bool _useHighResolution = true;

		private int _maximumRenderTextureHeight = 2160;

		private static readonly MethodInfo? RefreshBackgroundTextureMethod = AccessTools.Method(typeof(LightBlurredBackground), "OnCameraAspectChanged", (Type[])null, (Type[])null);

		internal static BlurTransition? Instance { get; private set; }

		internal bool IsAvailable
		{
			get
			{
				if (Object.op_Implicit((Object)(object)_lightBlur) && ((Behaviour)_lightBlur).enabled)
				{
					return _blurPlaneCount > 0;
				}
				return false;
			}
		}

		internal float Amount => _amount;

		internal float BlurSampleScale
		{
			get
			{
				if (!_highResolutionActive || _originalRenderTextureHeight <= 0)
				{
					return 1f;
				}
				return (float)_currentRenderTextureHeight / (float)_originalRenderTextureHeight;
			}
		}

		internal bool NeedsRenderOverride
		{
			get
			{
				if (!(_amount < 0.9999f))
				{
					return BlurSampleScale > 1.0001f;
				}
				return true;
			}
		}

		internal void Initialise(ManualLogSource log)
		{
			_log = log;
			Instance = this;
		}

		internal void ConfigureResolution(bool useHighResolution, int maximumHeight)
		{
			_useHighResolution = useHighResolution;
			_maximumRenderTextureHeight = Mathf.Clamp(maximumHeight, 720, 4320);
		}

		internal void ScanSceneIfNeeded()
		{
			if (!_scanned || !Object.op_Implicit((Object)(object)_lightBlur) || _blurPlaneCount <= 0)
			{
				ScanScene();
			}
		}

		internal void ScanScene()
		{
			//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)
			bool flag = _target < 0.5f;
			RestoreBackgroundResolution();
			_lightBlur = null;
			_background = null;
			_blurPlaneCount = 0;
			_originalRenderTextureHeight = 0;
			_currentRenderTextureHeight = 0;
			_scanned = true;
			try
			{
				LightBlur[] array = Resources.FindObjectsOfTypeAll<LightBlur>();
				foreach (LightBlur val in array)
				{
					if (!Object.op_Implicit((Object)(object)val))
					{
						continue;
					}
					Scene scene = ((Component)val).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid() || !((Component)val).gameObject.activeInHierarchy)
					{
						continue;
					}
					GameCameras componentInParent = ((Component)val).GetComponentInParent<GameCameras>();
					if (((Object)val).name.Equals("BlurCamera", StringComparison.OrdinalIgnoreCase) || !((Object)(object)componentInParent == (Object)null))
					{
						_lightBlur = val;
						_background = (Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).GetComponent<LightBlurredBackground>() : null);
						if (Object.op_Implicit((Object)(object)_background))
						{
							_originalRenderTextureHeight = Math.Max(1, _background.RenderTextureHeight);
							_currentRenderTextureHeight = _originalRenderTextureHeight;
						}
						break;
					}
				}
				_blurPlaneCount = BlurPlane.BlurPlaneCount;
				if (flag)
				{
					EnableHighResolution();
				}
			}
			catch (Exception ex)
			{
				_log.LogDebug((object)("Background blur scan failed: " + ex.Message));
				_lightBlur = null;
				_background = null;
				_blurPlaneCount = 0;
			}
		}

		internal void SetLooking(bool looking)
		{
			ScanSceneIfNeeded();
			_target = (looking ? 0f : 1f);
			if (looking)
			{
				EnableHighResolution();
			}
		}

		internal void Tick(float delta, float duration)
		{
			if (Math.Abs(_amount - _target) < 0.0001f)
			{
				_amount = _target;
				if (_target > 0.5f)
				{
					RestoreBackgroundResolution();
				}
			}
			else
			{
				_amount = Mathf.MoveTowards(_amount, _target, delta / Math.Max(0.01f, duration));
				if (_target > 0.5f && _amount >= 0.9999f)
				{
					RestoreBackgroundResolution();
				}
			}
		}

		internal bool Owns(LightBlur candidate)
		{
			if (Object.op_Implicit((Object)(object)_lightBlur) && (Object)(object)candidate == (Object)(object)_lightBlur && ((Behaviour)_lightBlur).enabled)
			{
				return _blurPlaneCount > 0;
			}
			return false;
		}

		internal void RestoreImmediately()
		{
			_amount = (_target = 1f);
			RestoreBackgroundResolution();
		}

		internal string Describe()
		{
			string text = (Object.op_Implicit((Object)(object)_lightBlur) ? $"LightBlur '{((Object)_lightBlur).name}' enabled={((Behaviour)_lightBlur).enabled} passes={_lightBlur.BlurPassCount}" : "no LightBlur");
			string text2 = ((_originalRenderTextureHeight > 0) ? $", background-height={_originalRenderTextureHeight}->{_currentRenderTextureHeight}" : string.Empty);
			return $"{text}, blur-planes={_blurPlaneCount}, amount={_amount:0.00}{text2}";
		}

		internal void Dump(ManualLogSource log)
		{
			ScanScene();
			log.LogInfo((object)("Blur: " + Describe()));
			for (int i = 0; i < BlurPlane.BlurPlaneCount; i++)
			{
				BlurPlane blurPlane = BlurPlane.GetBlurPlane(i);
				MeshRenderer val = (Object.op_Implicit((Object)(object)blurPlane) ? ((Component)blurPlane).GetComponent<MeshRenderer>() : null);
				object[] obj = new object[6]
				{
					i,
					(blurPlane != null) ? ((Object)blurPlane).name : null,
					(blurPlane != null) ? new float?(blurPlane.PlaneZ) : ((float?)null),
					(val != null) ? new bool?(((Renderer)val).enabled) : ((bool?)null),
					null,
					null
				};
				object obj2;
				if (val == null)
				{
					obj2 = null;
				}
				else
				{
					Material sharedMaterial = ((Renderer)val).sharedMaterial;
					obj2 = ((sharedMaterial != null) ? ((Object)sharedMaterial).name : null);
				}
				obj[4] = obj2;
				object obj3;
				if (val == null)
				{
					obj3 = null;
				}
				else
				{
					Material sharedMaterial2 = ((Renderer)val).sharedMaterial;
					if (sharedMaterial2 == null)
					{
						obj3 = null;
					}
					else
					{
						Shader shader = sharedMaterial2.shader;
						obj3 = ((shader != null) ? ((Object)shader).name : null);
					}
				}
				obj[5] = obj3;
				log.LogInfo((object)string.Format("BlurPlane[{0}]: name={1}, z={2}, rendererEnabled={3}, material={4}, shader={5}", obj));
			}
		}

		public void Dispose()
		{
			RestoreImmediately();
			_lightBlur = null;
			_background = null;
			_blurPlaneCount = 0;
			if (Instance == this)
			{
				Instance = null;
			}
		}

		private void EnableHighResolution()
		{
			if (!_useHighResolution || !Object.op_Implicit((Object)(object)_background) || !Object.op_Implicit((Object)(object)_lightBlur) || _highResolutionActive || RefreshBackgroundTextureMethod == null)
			{
				return;
			}
			try
			{
				Camera val = (Object.op_Implicit((Object)(object)((Component)_lightBlur).transform.parent) ? ((Component)((Component)_lightBlur).transform.parent).GetComponent<Camera>() : null);
				int num = Mathf.Clamp(Object.op_Implicit((Object)(object)val) ? val.pixelHeight : Screen.height, _originalRenderTextureHeight, _maximumRenderTextureHeight);
				if (num > _originalRenderTextureHeight)
				{
					_currentRenderTextureHeight = num;
					_highResolutionActive = true;
					_background.RenderTextureHeight = num;
					RefreshBackgroundTextureMethod.Invoke(_background, new object[1] { ForceCameraAspect.CurrentViewportAspect });
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("Could not enable high-resolution background: " + ex.GetBaseException().Message));
				RestoreBackgroundResolution();
			}
		}

		private void RestoreBackgroundResolution()
		{
			if (!_highResolutionActive)
			{
				_currentRenderTextureHeight = _originalRenderTextureHeight;
				return;
			}
			try
			{
				if (Object.op_Implicit((Object)(object)_background) && RefreshBackgroundTextureMethod != null)
				{
					_background.RenderTextureHeight = _originalRenderTextureHeight;
					RefreshBackgroundTextureMethod.Invoke(_background, new object[1] { ForceCameraAspect.CurrentViewportAspect });
				}
			}
			catch (Exception ex)
			{
				_log.LogDebug((object)("Could not restore background resolution: " + ex.GetBaseException().Message));
			}
			finally
			{
				_currentRenderTextureHeight = _originalRenderTextureHeight;
				_highResolutionActive = false;
			}
		}
	}
	internal static class ControllerPromptAssets
	{
		private const string ResourcePrefix = "FarGaze.Assets.ControllerPrompts.";

		private static readonly Dictionary<string, Sprite> Cache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase);

		internal static Sprite? Disconnected => Load("disconnected");

		internal static Sprite? For(GamepadType gamepadType, ControllerBinding binding)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			string text;
			switch (gamepadType - 2)
			{
			case 2:
			case 6:
				text = "ps4";
				break;
			case 9:
				text = "ps5";
				break;
			case 10:
				text = "xbox_series";
				break;
			case 0:
			case 1:
				text = "xbox_one";
				break;
			case 7:
			case 8:
			case 12:
			case 13:
				text = "switch";
				break;
			default:
				text = null;
				break;
			}
			string text2 = text;
			if (text2 == null)
			{
				return null;
			}
			bool flag = text2 == "ps4" || text2 == "ps5";
			if (flag)
			{
				bool flag2 = (uint)(binding - 3) <= 3u;
				flag = flag2;
			}
			if (flag)
			{
				return null;
			}
			string text3 = binding switch
			{
				ControllerBinding.LeftStick => "left_stick", 
				ControllerBinding.RightStick => "right_stick", 
				ControllerBinding.FaceBottom => "face_bottom", 
				ControllerBinding.FaceRight => "face_right", 
				ControllerBinding.FaceLeft => "face_left", 
				ControllerBinding.FaceTop => "face_top", 
				ControllerBinding.LeftShoulder => "l1", 
				ControllerBinding.RightShoulder => "r1", 
				ControllerBinding.LeftTrigger => "l2", 
				ControllerBinding.RightTrigger => "r2", 
				ControllerBinding.DPadUp => "dpad_up", 
				ControllerBinding.DPadDown => "dpad_down", 
				ControllerBinding.DPadLeft => "dpad_left", 
				ControllerBinding.DPadRight => "dpad_right", 
				ControllerBinding.PrimaryMenu => "primary", 
				ControllerBinding.SecondaryMenu => "secondary", 
				ControllerBinding.TouchPad => "touchpad", 
				_ => null, 
			};
			if (text3 != null)
			{
				return Load(text2 + "_" + text3);
			}
			return null;
		}

		private static Sprite? Load(string assetName)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue(assetName, out Sprite value))
			{
				return value;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FarGaze.Assets.ControllerPrompts." + assetName + ".png");
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					return null;
				}
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = "FarGaze." + assetName,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(val, array, true))
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).name = "FarGaze." + assetName;
			Cache[assetName] = val2;
			return val2;
		}
	}
	[BepInPlugin("io.github.localdev.fargaze", "Far Gaze / 远眺", "0.5.1")]
	[BepInDependency("org.silksong-modding.modmenu", "0.7.6")]
	public sealed class FarGazePlugin : BaseUnityPlugin, IModMenuCustomMenu, IModMenuInterface
	{
		private enum GazeState
		{
			Inactive,
			Entering,
			Looking,
			Exiting
		}

		private sealed class ValidatedConfigModel<T> : AbstractValueModel<T>, IDisposable
		{
			internal delegate bool Validator(T candidate, out string message);

			private readonly ConfigEntry<T> _entry;

			private readonly Validator _validator;

			internal ValidatedConfigModel(ConfigEntry<T> entry, Validator validator)
			{
				_entry = entry;
				_validator = validator;
				_entry.SettingChanged += OnSettingChanged;
			}

			public override T GetValue()
			{
				return _entry.Value;
			}

			public override bool SetValue(T value)
			{
				if (EqualityComparer<T>.Default.Equals(_entry.Value, value))
				{
					return true;
				}
				if (!_validator(value, out var _))
				{
					return true;
				}
				_entry.Value = value;
				return true;
			}

			private void OnSettingChanged(object sender, EventArgs args)
			{
				base.InvokeOnValueChanged();
			}

			public void Dispose()
			{
				_entry.SettingChanged -= OnSettingChanged;
			}
		}

		public const string PluginGuid = "io.github.localdev.fargaze";

		public const string PluginName = "Far Gaze / 远眺";

		public const string PluginVersion = "0.5.1";

		private const float DefaultCameraLookDelay = 0.85f;

		private ConfigEntry<KeyCode> _gazeKey;

		private ConfigEntry<FarGazeInputMode> _inputMode;

		private ConfigEntry<KeyCode> _diagnosticKey;

		private ConfigEntry<float> _blurTransitionSeconds;

		private ConfigEntry<string> _entryClip;

		private ConfigEntry<string> _holdClip;

		private ConfigEntry<string> _exitClip;

		private ConfigEntry<bool> _verboseLogging;

		private ConfigEntry<bool> _highResolutionBackground;

		private ConfigEntry<int> _maximumBackgroundHeight;

		private readonly BlurTransition _blur = new BlurTransition();

		private Harmony _harmony;

		private GazeState _state;

		private HeroController? _controlledHero;

		private HeroAnimationController? _animationController;

		private float _animationEndsAt;

		private int _animationControlVersion = -1;

		private bool _ownsAnimation;

		private bool _warnedNoBlur;

		private bool _warnedNoAnimation;

		private int _gazeLookDirection;

		private float _gazeLookTimer;

		private static readonly MethodInfo? KeyCodeToInControlKey = typeof(KeyBindElement).Assembly.GetType("Silksong.ModMenu.Internal.KeyCodeUtil")?.GetMethod("ToKey", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[1] { typeof(KeyCode) }, null);

		private readonly DeviceBindingSourceListener _controllerBindingListener = new DeviceBindingSourceListener();

		private readonly BindingListenOptions _controllerListenOptions = new BindingListenOptions
		{
			IncludeControllers = true,
			IncludeUnknownControllers = true,
			IncludeNonStandardControls = false,
			IncludeMouseButtons = false,
			IncludeKeys = false,
			IncludeModifiersAsFirstClassKeys = false
		};

		private bool _capturingControllerBinding;

		private GamepadType _capturingGamepadType;

		private readonly Dictionary<GamepadType, ConfigEntry<ControllerBinding>> _controllerBindings = new Dictionary<GamepadType, ConfigEntry<ControllerBinding>>();

		private TextButton? _controllerBindingButton;

		private Image? _controllerPromptImage;

		private Text? _controllerPromptText;

		private Text? _keyboardBindingLabel;

		private Text? _modeLabel;

		private GamepadType _displayedGamepadType;

		private ControllerBinding _displayedControllerBinding;

		private TextLabel? _bindingStatusLabel;

		private string? _lastKeyboardConflict;

		private string? _lastControllerConflict;

		private void Awake()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			_gazeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "FarGazeKey", (KeyCode)98, "远眺键盘按键。默认:B;None 表示未绑定。");
			_inputMode = ((BaseUnityPlugin)this).Config.Bind<FarGazeInputMode>("Input", "InputMode", FarGazeInputMode.Press, "点按:按下时切换;长按:保持按住时远眺,松开时退出。");
			_diagnosticKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Diagnostics", "DumpDiagnosticsKey", (KeyCode)289, "把角色状态、候选动画和虚化组件写入 BepInEx 日志。");
			_blurTransitionSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "BlurTransitionSeconds", 0.16f, new ConfigDescription("解除/恢复背景虚化的过渡秒数。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.5f), Array.Empty<object>()));
			_entryClip = ((BaseUnityPlugin)this).Config.Bind<string>("Animation", "EntryClip", "TurnToBG", "进入远眺时播放的动画名。");
			_holdClip = ((BaseUnityPlugin)this).Config.Bind<string>("Animation", "HoldClip", "Idle BG", "远眺保持姿势的动画名。");
			_exitClip = ((BaseUnityPlugin)this).Config.Bind<string>("Animation", "ExitClip", "TurnToFG", "正常退出时播放的动画名。");
			_verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "VerboseLogging", false, "记录每次成功进入、正常退出和中断退出。");
			_highResolutionBackground = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "HighResolutionBackground", true, "远眺期间把背景渲染纹理提升到屏幕分辨率,避免解除虚化后出现低像素感。");
			_maximumBackgroundHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Visual", "MaximumBackgroundHeight", 2160, new ConfigDescription("高清背景纹理的最大高度;用于限制显存开销。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(720, 4320), Array.Empty<object>()));
			_blur.Initialise(((BaseUnityPlugin)this).Logger);
			_blur.ConfigureResolution(_highResolutionBackground.Value, _maximumBackgroundHeight.Value);
			_harmony = new Harmony("io.github.localdev.fargaze");
			_harmony.PatchAll();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Keyboard={2}, Controller={3}, Mode={4}, Diagnostics={5}", "Far Gaze / 远眺", "0.5.1", _gazeKey.Value, DescribeCurrentControllerBinding(), _inputMode.Value, _diagnosticKey.Value));
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ForceReset(immediate: true);
			((MonoBehaviour)this).StartCoroutine(ScanSceneAfterLoad(((Scene)(ref scene)).name));
		}

		private IEnumerator ScanSceneAfterLoad(string sceneName)
		{
			for (int i = 0; i < 12; i++)
			{
				yield return null;
			}
			_blur.ScanScene();
			if (_verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Scene '" + sceneName + "': " + _blur.Describe()));
			}
		}

		private void Update()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_blur.Tick(Time.unscaledDeltaTime, _blurTransitionSeconds.Value);
			if (Input.GetKeyDown(_diagnosticKey.Value))
			{
				DumpDiagnostics();
			}
			RefreshControllerBindingUi();
			if (ProcessControllerBindingCapture())
			{
				return;
			}
			HeroController instance = HeroController.instance;
			if (_state != GazeState.Inactive && (!Object.op_Implicit((Object)(object)instance) || (Object)(object)instance != (Object)(object)_controlledHero || !IsStandingPose(instance, requireIdleActorState: false, out string _)))
			{
				Interrupt();
				return;
			}
			if (_state == GazeState.Entering && Time.unscaledTime >= _animationEndsAt)
			{
				PlayHoldAnimation();
				_state = GazeState.Looking;
			}
			else if (_state == GazeState.Exiting && Time.unscaledTime >= _animationEndsAt)
			{
				FinishNormalExit();
			}
			if ((_state == GazeState.Entering || _state == GazeState.Looking) && Object.op_Implicit((Object)(object)instance))
			{
				UpdateGazeCameraLook(instance);
			}
			var (flag, flag2) = ReadFarGazeInput();
			if (_inputMode.Value == FarGazeInputMode.Press)
			{
				if (flag)
				{
					if (_state == GazeState.Inactive)
					{
						TryEnter(instance, logFailure: true);
					}
					else if (_state == GazeState.Entering || _state == GazeState.Looking)
					{
						BeginNormalExit();
					}
				}
			}
			else if (_state == GazeState.Inactive && flag2)
			{
				TryEnter(instance, flag);
			}
			else if ((_state == GazeState.Entering || _state == GazeState.Looking) && !flag2)
			{
				BeginNormalExit();
			}
		}

		private void TryEnter(HeroController? hero, bool logFailure)
		{
			string reason = null;
			if (Time.timeScale > 0.01f && Object.op_Implicit((Object)(object)hero) && IsStandingPose(hero, requireIdleActorState: true, out reason))
			{
				Enter(hero);
			}
			else if (logFailure)
			{
				LogIgnoredInput(hero, reason ?? "hero not available");
			}
		}

		private (bool Pressed, bool Held) ReadFarGazeInput()
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_006d: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = _gazeKey.Value;
			string actionName = string.Empty;
			bool flag = (int)value != 0 && TryFindKeyboardConflict(value, out actionName);
			ReportRuntimeBindingConflict("keyboard", flag ? actionName : null, ref _lastKeyboardConflict);
			bool num = (int)value != 0 && !flag && Input.GetKeyDown(value);
			bool flag2 = (int)value != 0 && !flag && Input.GetKey(value);
			InputControlType val = ResolveControllerControl(GetCurrentControllerBinding());
			string actionName2 = string.Empty;
			bool flag3 = (int)val != 0 && TryFindControllerConflict(val, out actionName2);
			ReportRuntimeBindingConflict("controller", flag3 ? actionName2 : null, ref _lastControllerConflict);
			InputDevice activeDevice = InputManager.ActiveDevice;
			InputControl val2 = (((int)val != 0 && !flag3 && activeDevice != null) ? activeDevice.GetControl(val) : null);
			bool flag4 = val2 != null && ((OneAxisInputControl)val2).WasPressed;
			bool flag5 = val2 != null && ((OneAxisInputControl)val2).IsPressed;
			return (Pressed: num || flag4, Held: flag2 || flag5);
		}

		private void ReportRuntimeBindingConflict(string device, string? action, ref string? lastConflict)
		{
			if (action == null)
			{
				lastConflict = null;
			}
			else if (!(lastConflict == action))
			{
				lastConflict = action;
				string text = ((device == "keyboard") ? "键盘" : "手柄");
				string text2 = "当前" + text + "远眺键与游戏操作“" + action + "”重复;为避免同时触发,远眺已暂时忽略该绑定。";
				((BaseUnityPlugin)this).Logger.LogWarning((object)text2);
				SetBindingStatus(text2, warning: true);
			}
		}

		private void Enter(HeroController hero)
		{
			_controlledHero = hero;
			_animationController = hero.AnimCtrl;
			_blur.ScanSceneIfNeeded();
			BeginGazeCameraLook(hero);
			_animationControlVersion = hero.StopAnimationControlVersioned();
			_ownsAnimation = true;
			float num = PlayClipAndGetDuration(_entryClip.Value, 0.35f);
			_animationEndsAt = Time.unscaledTime + num;
			_state = GazeState.Entering;
			_blur.SetLooking(looking: true);
			if (!_blur.IsAvailable && !_warnedNoBlur)
			{
				_warnedNoBlur = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"No active background LightBlur/BlurPlane was found in this scene. The pose will still work; press F8 for diagnostics.");
			}
			if (_verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Far gaze entered (entry={_entryClip.Value}, {num:0.000}s; {_blur.Describe()}).");
			}
		}

		private void PlayHoldAnimation()
		{
			if (!PlayClip(_holdClip.Value) && !_warnedNoAnimation)
			{
				_warnedNoAnimation = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Animation '" + _holdClip.Value + "' was not found/playable. Press F8 for candidates."));
			}
		}

		private void BeginNormalExit()
		{
			_blur.SetLooking(looking: false);
			string text = ((FindClip(_exitClip.Value) != null) ? _exitClip.Value : "TurnFromBG");
			float num = PlayClipAndGetDuration(text, 0.35f);
			_animationEndsAt = Time.unscaledTime + num;
			_state = GazeState.Exiting;
			if (_verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Far gaze normal exit (clip={text}, {num:0.000}s).");
			}
		}

		private void FinishNormalExit()
		{
			ReleaseAnimationControl();
			ClearHeroReferences();
			_state = GazeState.Inactive;
		}

		private void Interrupt()
		{
			if (_state != GazeState.Inactive)
			{
				_blur.SetLooking(looking: false);
				ReleaseAnimationControl();
				ClearHeroReferences();
				_state = GazeState.Inactive;
				if (_verboseLogging.Value)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Far gaze interrupted; exit animation skipped.");
				}
			}
		}

		private void ReleaseAnimationControl()
		{
			if (_ownsAnimation && Object.op_Implicit((Object)(object)_controlledHero))
			{
				_controlledHero.StartAnimationControl(_animationControlVersion);
			}
			_ownsAnimation = false;
			_animationControlVersion = -1;
		}

		private void ClearHeroReferences()
		{
			_controlledHero = null;
			_animationController = null;
			_gazeLookDirection = 0;
			_gazeLookTimer = 0f;
		}

		private void BeginGazeCameraLook(HeroController hero)
		{
			HeroControllerStates cState = hero.cState;
			_gazeLookDirection = (cState.lookingUp ? 1 : (cState.lookingDown ? 2 : 0));
			_gazeLookTimer = Reflection.AsFloat(Reflection.ReadMember(hero, "lookDelayTimer"), 0f);
			if (_gazeLookDirection != 0 && _gazeLookTimer < 0.85f)
			{
				_gazeLookTimer = 0.85f;
			}
		}

		private void UpdateGazeCameraLook(HeroController hero)
		{
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			HeroActions val = (Object.op_Implicit((Object)(object)silentInstance) ? silentInstance.inputActions : null);
			if (val == null)
			{
				return;
			}
			bool isPressed = ((OneAxisInputControl)val.RsUp).IsPressed;
			bool isPressed2 = ((OneAxisInputControl)val.RsDown).IsPressed;
			bool flag = ((OneAxisInputControl)val.Up).IsPressed || isPressed;
			bool flag2 = ((OneAxisInputControl)val.Down).IsPressed || isPressed2;
			if (_gazeLookDirection == 0)
			{
				if (flag)
				{
					_gazeLookDirection = 1;
				}
				else if (flag2)
				{
					_gazeLookDirection = 2;
				}
			}
			else if (_gazeLookDirection == 1 && !flag)
			{
				_gazeLookDirection = 0;
			}
			else if (_gazeLookDirection == 2 && !flag2)
			{
				_gazeLookDirection = 0;
			}
			HeroControllerStates cState = hero.cState;
			float num = Math.Max(0.01f, Reflection.AsFloat(Reflection.ReadMember(hero, "LOOK_DELAY"), 0.85f));
			if (_gazeLookDirection == 1)
			{
				cState.lookingDown = false;
				cState.lookingUp = isPressed || _gazeLookTimer >= num;
				if (!cState.lookingUp)
				{
					_gazeLookTimer += Time.deltaTime;
				}
			}
			else if (_gazeLookDirection == 2)
			{
				cState.lookingUp = false;
				bool flag3 = Reflection.ReadBool(hero, "lookDownBlocked");
				cState.lookingDown = !flag3 && (isPressed2 || _gazeLookTimer >= num);
				if (!flag3 && !cState.lookingDown)
				{
					_gazeLookTimer += Time.deltaTime;
				}
			}
			else
			{
				cState.lookingUp = false;
				cState.lookingDown = false;
				_gazeLookTimer = 0f;
			}
			cState.lookingUpAnim = false;
			cState.lookingDownAnim = false;
		}

		private float PlayClipAndGetDuration(string clipName, float fallback)
		{
			tk2dSpriteAnimationClip val = FindClip(clipName);
			if (val == null || !PlayClip(clipName))
			{
				if (!_warnedNoAnimation)
				{
					_warnedNoAnimation = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Animation '" + clipName + "' was not found/playable. Press F8 for candidates."));
				}
				return 0.01f;
			}
			if (!(val.fps > 0.01f))
			{
				return fallback;
			}
			return Math.Max(0.01f, val.Duration);
		}

		private bool PlayClip(string clipName)
		{
			if ((Object)(object)_animationController == (Object)null || FindClip(clipName) == null)
			{
				return false;
			}
			_animationController.PlayClipForced(clipName);
			return true;
		}

		private tk2dSpriteAnimationClip? FindClip(string name)
		{
			tk2dSpriteAnimator val = _animationController?.animator;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetClipByName(name);
		}

		private static bool IsStandingPose(HeroController hero, bool requireIdleActorState, out string? reason)
		{
			reason = null;
			object obj = Reflection.ReadMember(hero, "cState");
			if (obj == null)
			{
				reason = "cState unavailable";
				return false;
			}
			if (!Reflection.ReadBool(obj, "onGround"))
			{
				reason = "not on ground";
				return false;
			}
			string[] array = new string[23]
			{
				"dashing", "backDashing", "isSprinting", "isBackSprinting", "isBackScuttling", "attacking", "nailCharging", "casting", "focusing", "recoiling",
				"recoilFrozen", "dead", "hazardDeath", "hazardRespawning", "transitioning", "isToolThrowing", "parrying", "mantling", "isInCutsceneMovement", "isBinding",
				"needolinPlayingMemory", "evading", "whipLashing"
			};
			foreach (string text in array)
			{
				if (Reflection.ReadBool(obj, text))
				{
					reason = text;
					return false;
				}
			}
			string text2 = Reflection.ReadMember(hero, "hero_state")?.ToString();
			if (requireIdleActorState && !string.IsNullOrEmpty(text2) && !text2.Equals("idle", StringComparison.OrdinalIgnoreCase))
			{
				reason = "hero_state=" + text2;
				return false;
			}
			if (Math.Abs(Reflection.AsFloat(Reflection.ReadMember(hero, "move_input"), 0f)) > 0.01f)
			{
				reason = "movement input";
				return false;
			}
			return true;
		}

		private void LogIgnoredInput(HeroController? hero, string reason)
		{
			if (!Object.op_Implicit((Object)(object)hero))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Far gaze input ignored: " + reason + "."));
				return;
			}
			object target = Reflection.ReadMember(hero, "cState");
			tk2dSpriteAnimator val = (Object.op_Implicit((Object)(object)hero.AnimCtrl) ? hero.AnimCtrl.animator : null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)(string.Format("Far gaze input ignored: {0}; hero_state={1}; ", reason, Reflection.ReadMember(hero, "hero_state")) + string.Format("onGround={0}; move_input={1}; ", Reflection.ReadMember(target, "onGround"), Reflection.ReadMember(hero, "move_input")) + string.Format("clip={0}; animationControl={1}.", ((val == null) ? null : val.CurrentClip?.name) ?? "<none>", hero.HasAnimationControl)));
		}

		private void DumpDiagnostics()
		{
			//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_004e: Unknown result type (might be due to invalid IL or missing references)
			HeroController instance = HeroController.instance;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"========== Far Gaze diagnostics ==========");
			ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
			object[] array = new object[7];
			Scene activeScene = SceneManager.GetActiveScene();
			array[0] = ((Scene)(ref activeScene)).name;
			array[1] = _state;
			array[2] = _gazeKey.Value;
			array[3] = DescribeCurrentControllerBinding();
			array[4] = _inputMode.Value;
			array[5] = _gazeLookDirection;
			array[6] = _blur.Describe();
			logger.LogInfo((object)string.Format("Scene={0}; state={1}; keyboard={2}; controller={3}; mode={4}; gazeLook={5}; {6}", array));
			if (!Object.op_Implicit((Object)(object)instance))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"HeroController.instance is null.");
				return;
			}
			IsStandingPose(instance, requireIdleActorState: true, out string reason);
			object target = Reflection.ReadMember(instance, "cState");
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("hero_state={0}; standingReason={1}; onGround={2}", Reflection.ReadMember(instance, "hero_state"), reason ?? "OK", Reflection.ReadMember(target, "onGround")));
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("look: up={0}, down={1}, upAnim={2}, downAnim={3}, gazeDirection={4}", Reflection.ReadMember(target, "lookingUp"), Reflection.ReadMember(target, "lookingDown"), Reflection.ReadMember(target, "lookingUpAnim"), Reflection.ReadMember(target, "lookingDownAnim"), _gazeLookDirection));
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("move_input={0}; velocity={1}", Reflection.ReadMember(instance, "move_input"), Reflection.ReadMember(instance, "current_velocity")));
			HeroAnimationController animCtrl = instance.AnimCtrl;
			tk2dSpriteAnimator val = (Object.op_Implicit((Object)(object)animCtrl) ? animCtrl.animator : null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("animationControl={0}; currentClip={1}; playing={2}", instance.HasAnimationControl, ((val == null) ? null : val.CurrentClip?.name) ?? "<none>", (val != null) ? new bool?(val.Playing) : ((bool?)null)));
			List<string> list = new List<string>();
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.Library) && val.Library.clips != null)
			{
				tk2dSpriteAnimationClip[] clips = val.Library.clips;
				for (int i = 0; i < clips.Length; i++)
				{
					string text = clips[i]?.name;
					if (text != null && (text.IndexOf("BG", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Turn", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Challenge", StringComparison.OrdinalIgnoreCase) >= 0))
					{
						list.Add(text);
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Animation candidates ({0}): {1}", list.Count, string.Join(", ", list)));
			_blur.Dump(((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"==========================================");
		}

		private void ForceReset(bool immediate)
		{
			ReleaseAnimationControl();
			ClearHeroReferences();
			_state = GazeState.Inactive;
			if (immediate)
			{
				_blur.RestoreImmediately();
			}
			else
			{
				_blur.SetLooking(looking: false);
			}
		}

		private void OnDestroy()
		{
			CancelControllerBindingCapture(showMessage: false);
			SceneManager.sceneLoaded -= OnSceneLoaded;
			ForceReset(immediate: true);
			_blur.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		public LocalizedText ModMenuName()
		{
			return LocalizedText.op_Implicit("远眺");
		}

		public AbstractMenuScreen BuildCustomMenu()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_005f: 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_007b: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			SimpleMenuScreen val = new SimpleMenuScreen("远眺");
			ValidatedConfigModel<KeyCode> validatedConfigModel = new ValidatedConfigModel<KeyCode>(_gazeKey, ValidateKeyboardCandidate);
			KeyBindElement val2 = new KeyBindElement(LocalizedText.op_Implicit("键盘按键"), (IValueModel<KeyCode>)(object)validatedConfigModel);
			((MenuDisposable)val2).OnDispose += validatedConfigModel.Dispose;
			_keyboardBindingLabel = val2.LabelText;
			val.Add((MenuElement)(object)val2);
			TextButton controller = new TextButton(LocalizedText.op_Implicit("手柄按键"));
			controller.OnSubmit = delegate
			{
				BeginControllerBindingCapture(controller);
			};
			CreateControllerBindingVisual(controller);
			((MenuDisposable)controller).OnDispose += delegate
			{
				if (_controllerBindingButton == controller)
				{
					CancelControllerBindingCapture(showMessage: false);
					_controllerBindingButton = null;
					_controllerPromptImage = null;
					_controllerPromptText = null;
				}
			};
			_controllerBindingButton = controller;
			val.Add((MenuElement)(object)controller);
			ListChoiceModel<FarGazeInputMode> val3 = ChoiceModels.ForNamedValues<FarGazeInputMode>((IEnumerable<ValueTuple<FarGazeInputMode, string>>)new List<(FarGazeInputMode, string)>
			{
				(FarGazeInputMode.Press, "点按"),
				(FarGazeInputMode.Hold, "长按")
			});
			ChoiceElement<FarGazeInputMode> val4 = new ChoiceElement<FarGazeInputMode>(LocalizedText.op_Implicit("按键模式"), (IChoiceModel<FarGazeInputMode>)(object)val3);
			ConfigEntryFactoryExtensions.SynchronizeWith<FarGazeInputMode>((SelectableValueElement<FarGazeInputMode>)(object)val4, _inputMode);
			_modeLabel = val4.LabelText;
			val.Add((MenuElement)(object)val4);
			TextLabel status = new TextLabel(LocalizedText.op_Implicit(""));
			((MenuElement)status).Visibility.VisibleSelf = false;
			_bindingStatusLabel = status;
			((MenuDisposable)status).OnDispose += delegate
			{
				if (_bindingStatusLabel == status)
				{
					_bindingStatusLabel = null;
					_keyboardBindingLabel = null;
					_modeLabel = null;
				}
			};
			val.Add((MenuElement)(object)status);
			RefreshControllerBindingUi(force: true);
			SynchronizeBindingLabelStyles();
			ShowCurrentConflictIfAny();
			return (AbstractMenuScreen)val;
		}

		private void CreateControllerBindingVisual(TextButton button)
		{
			//IL_0043: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Expected O, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			((Component)button.DescriptionText).gameObject.SetActive(false);
			button.ButtonText.text = "手柄按键";
			button.ButtonText.alignment = (TextAnchor)3;
			RectTransform rectTransform = ((Graphic)button.ButtonText).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0f);
			rectTransform.anchorMax = new Vector2(0.55f, 1f);
			rectTransform.offsetMin = new Vector2(36f, 0f);
			rectTransform.offsetMax = Vector2.zero;
			GameObject val = new GameObject("FarGaze Controller Binding Text", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Text)
			});
			val.transform.SetParent(((Component)button.MenuButton).transform, false);
			_controllerPromptText = val.GetComponent<Text>();
			_controllerPromptText.font = button.ButtonText.font;
			_controllerPromptText.fontStyle = button.ButtonText.fontStyle;
			((Graphic)_controllerPromptText).color = ((Graphic)button.ButtonText).color;
			((Graphic)_controllerPromptText).material = ((Graphic)button.ButtonText).material;
			_controllerPromptText.supportRichText = button.ButtonText.supportRichText;
			((Graphic)_controllerPromptText).raycastTarget = false;
			_controllerPromptText.text = string.Empty;
			_controllerPromptText.alignment = (TextAnchor)5;
			RectTransform rectTransform2 = ((Graphic)_controllerPromptText).rectTransform;
			rectTransform2.anchorMin = new Vector2(0.55f, 0f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.offsetMin = Vector2.zero;
			rectTransform2.offsetMax = new Vector2(-38f, 0f);
			GameObject val2 = new GameObject("FarGaze Controller Binding Icon", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val2.transform.SetParent(((Component)button.MenuButton).transform, false);
			_controllerPromptImage = val2.GetComponent<Image>();
			_controllerPromptImage.preserveAspect = true;
			((Graphic)_controllerPromptImage).raycastTarget = false;
			RectTransform rectTransform3 = ((Graphic)_controllerPromptImage).rectTransform;
			rectTransform3.anchorMin = new Vector2(1f, 0.5f);
			rectTransform3.anchorMax = new Vector2(1f, 0.5f);
			rectTransform3.pivot = new Vector2(0.5f, 0.5f);
			rectTransform3.anchoredPosition = new Vector2(-92f, 0f);
			rectTransform3.sizeDelta = new Vector2(72f, 72f);
		}

		private bool ValidateKeyboardCandidate(KeyCode candidate, out string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((int)candidate == 0)
			{
				message = "键盘按键已设为“未绑定”。";
				SetBindingStatus(message, warning: false);
				return true;
			}
			if (TryFindKeyboardConflict(candidate, out string actionName))
			{
				message = $"无法绑定 {candidate}:它已用于“{actionName}”。原绑定保持不变。";
				SetBindingStatus(message, warning: true);
				return false;
			}
			message = $"键盘按键已绑定为 {candidate}。";
			SetBindingStatus(message, warning: false);
			return true;
		}

		private void BeginControllerBindingCapture(TextButton button)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			if (_capturingControllerBinding)
			{
				return;
			}
			GamepadType val = CurrentConnectedGamepadType();
			if ((int)val == 0)
			{
				SetBindingStatus("未检测到已连接的手柄,手柄绑定没有改变。", warning: true);
				return;
			}
			if (_state != GazeState.Inactive)
			{
				ForceReset(immediate: false);
			}
			_capturingControllerBinding = true;
			_capturingGamepadType = val;
			_controllerBindingButton = button;
			_controllerBindingListener.Reset();
			if (Object.op_Implicit((Object)(object)_controllerPromptImage))
			{
				((Component)_controllerPromptImage).gameObject.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_controllerPromptText))
			{
				_controllerPromptText.text = "…";
			}
			SetBindingStatus(string.Empty, warning: false);
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (Object.op_Implicit((Object)(object)silentInstance))
			{
				silentInstance.StopUIInput();
			}
		}

		private bool ProcessControllerBindingCapture()
		{
			//IL_005e: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			if (!_capturingControllerBinding)
			{
				return false;
			}
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (Input.GetKeyDown((KeyCode)27) || (Object.op_Implicit((Object)(object)silentInstance) && silentInstance.inputActions != null && ((OneAxisInputControl)silentInstance.inputActions.MenuCancel).WasPressed))
			{
				CancelControllerBindingCapture(showMessage: true);
				return true;
			}
			InputDevice activeDevice = InputManager.ActiveDevice;
			if (activeDevice == null || activeDevice == InputDevice.Null || !activeDevice.IsAttached || CurrentConnectedGamepadType() != _capturingGamepadType)
			{
				EndControllerBindingCapture();
				SetBindingStatus("手柄已断开,绑定没有改变。", warning: true);
				return true;
			}
			BindingSource val;
			try
			{
				val = _controllerBindingListener.Listen(_controllerListenOptions, activeDevice);
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Controller binding capture failed: {arg}");
				EndControllerBindingCapture();
				SetBindingStatus("手柄按键捕获失败;请查看 BepInEx 日志。", warning: true);
				return true;
			}
			DeviceBindingSource val2 = (DeviceBindingSource)(object)((val is DeviceBindingSource) ? val : null);
			if (val2 == null)
			{
				return true;
			}
			InputControlType control = val2.Control;
			if (!TryConvertCapturedControl(control, out var binding))
			{
				EndControllerBindingCapture();
				SetBindingStatus($"无法绑定 {control}:仅支持标准手柄按钮,不支持摇杆方向或轴。", warning: true);
				return true;
			}
			if (TryFindControllerConflict(control, out string actionName))
			{
				EndControllerBindingCapture();
				SetBindingStatus("无法绑定 " + ControllerBindingDisplay(binding) + ":它已用于“" + actionName + "”。原绑定保持不变。", warning: true);
				return true;
			}
			ConfigEntry<ControllerBinding> val3 = ControllerBindingEntry(_capturingGamepadType);
			if (val3 == null)
			{
				EndControllerBindingCapture();
				SetBindingStatus("无法识别当前手柄类型,绑定没有改变。", warning: true);
				return true;
			}
			val3.Value = binding;
			EndControllerBindingCapture();
			SetBindingStatus(string.Empty, warning: false);
			return true;
		}

		private void CancelControllerBindingCapture(bool showMessage)
		{
			if (_capturingControllerBinding)
			{
				EndControllerBindingCapture();
				if (showMessage)
				{
					SetBindingStatus(string.Empty, warning: false);
				}
			}
		}

		private void EndControllerBindingCapture()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_capturingControllerBinding = false;
			_capturingGamepadType = (GamepadType)0;
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (Object.op_Implicit((Object)(object)silentInstance))
			{
				silentInstance.StartUIInput();
			}
			RefreshControllerBindingUi(force: true);
		}

		private GamepadType CurrentConnectedGamepadType()
		{
			//IL_002c: 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)
			InputDevice activeDevice = InputManager.ActiveDevice;
			if (activeDevice == null || activeDevice == InputDevice.Null || !activeDevice.IsAttached)
			{
				return (GamepadType)0;
			}
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (!Object.op_Implicit((Object)(object)silentInstance))
			{
				return (GamepadType)1;
			}
			if ((int)silentInstance.activeGamepadType != 0)
			{
				return silentInstance.activeGamepadType;
			}
			return (GamepadType)1;
		}

		private unsafe ConfigEntry<ControllerBinding>? ControllerBindingEntry(GamepadType gamepadType)
		{
			//IL_0000: 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_0035: 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 ((int)gamepadType == 0)
			{
				return null;
			}
			if (_controllerBindings.TryGetValue(gamepadType, out ConfigEntry<ControllerBinding> value))
			{
				return value;
			}
			value = ((BaseUnityPlugin)this).Config.Bind<ControllerBinding>("Controller Bindings", ((object)(*(GamepadType*)(&gamepadType))/*cast due to .constrained prefix*/).ToString(), ControllerBinding.LeftStick, $"{gamepadType} 手柄的远眺按键。首次使用默认为按下左摇杆。");
			_controllerBindings.Add(gamepadType, value);
			return value;
		}

		private ControllerBinding GetCurrentControllerBinding()
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			GamepadType gamepadType = CurrentConnectedGamepadType();
			return ControllerBindingEntry(gamepadType)?.Value ?? ControllerBinding.None;
		}

		private string DescribeCurrentControllerBinding()
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			GamepadType val = CurrentConnectedGamepadType();
			if ((int)val != 0)
			{
				return $"{val}:{ControllerBindingDisplay(GetCurrentControllerBinding())}";
			}
			return "Disconnected";
		}

		private void RefreshControllerBindingUi(bool force = false)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0022: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_006b: 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_003d: 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)
			if (_controllerBindingButton == null || _capturingControllerBinding)
			{
				return;
			}
			SynchronizeBindingLabelStyles();
			GamepadType val = CurrentConnectedGamepadType();
			ControllerBinding controllerBinding = (((int)val != 0) ? (ControllerBindingEntry(val)?.Value ?? ControllerBinding.LeftStick) : ControllerBinding.None);
			if (force || val != _displayedGamepadType || controllerBinding != _displayedControllerBinding)
			{
				_displayedGamepadType = val;
				_displayedControllerBinding = controllerBinding;
				((SelectableElement)_controllerBindingButton).Interactable = (int)val > 0;
				if ((int)val == 0)
				{
					SetControllerPrompt(ControllerPromptAssets.Disconnected, "未连接手柄", disconnected: true);
					ShowCurrentConflictIfAny();
				}
				else
				{
					Sprite val2 = ControllerPromptAssets.For(val, controllerBinding) ?? GetNativeControllerSprite(controllerBinding);
					SetControllerPrompt(val2, Object.op_Implicit((Object)(object)val2) ? string.Empty : ControllerBindingDisplay(controllerBinding), disconnected: false);
					ShowCurrentConflictIfAny();
				}
			}
		}

		private void SynchronizeBindingLabelStyles()
		{
			if (Object.op_Implicit((Object)(object)_modeLabel))
			{
				if (Object.op_Implicit((Object)(object)_keyboardBindingLabel))
				{
					_keyboardBindingLabel.font = _modeLabel.font;
					_keyboardBindingLabel.fontSize = _modeLabel.fontSize;
					_keyboardBindingLabel.resizeTextForBestFit = _modeLabel.resizeTextForBestFit;
				}
				if (Object.op_Implicit((Object)(object)_controllerBindingButton?.ButtonText))
				{
					_controllerBindingButton.ButtonText.font = _modeLabel.font;
					_controllerBindingButton.ButtonText.fontSize = _modeLabel.fontSize;
					_controllerBindingButton.ButtonText.resizeTextForBestFit = _modeLabel.resizeTextForBestFit;
				}
				if (Object.op_Implicit((Object)(object)_controllerPromptText))
				{
					_controllerPromptText.font = _modeLabel.font;
					_controllerPromptText.fontSize = _modeLabel.fontSize;
				}
			}
		}

		private void SetControllerPrompt(Sprite? sprite, string text, bool disconnected)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_controllerPromptImage))
			{
				_controllerPromptImage.sprite = sprite;
				((Component)_controllerPromptImage).gameObject.SetActive(Object.op_Implicit((Object)(object)sprite));
				((Graphic)_controllerPromptImage).rectTransform.anchoredPosition = (disconnected ? new Vector2(-205f, 0f) : new Vector2(-92f, 0f));
			}
			if (Object.op_Implicit((Object)(object)_controllerPromptText))
			{
				_controllerPromptText.text = text;
			}
		}

		private unsafe static Sprite? GetNativeControllerSprite(ControllerBinding binding)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			InputControlType val = ResolveControllerControl(binding);
			if ((int)val == 0)
			{
				return null;
			}
			try
			{
				GameManager instance = GameManager.instance;
				UIButtonSkins val2 = ((instance == null) ? null : instance.ui?.uiButtonSkins);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					return null;
				}
				object? obj = Reflection.ReadMember(((object)val2).GetType().GetMethod("GetButtonSkinFor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null)?.Invoke(val2, new object[1] { ((object)(*(InputControlType*)(&val))/*cast due to .constrained prefix*/).ToString() }), "sprite");
				return (Sprite?)((obj is Sprite) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		private static string ControllerBindingDisplay(ControllerBinding binding)
		{
			return binding switch
			{
				ControllerBinding.None => "未绑定", 
				ControllerBinding.LeftStick => "L3 / LS / 左摇杆", 
				ControllerBinding.RightStick => "R3 / RS / 右摇杆", 
				ControllerBinding.FaceBottom => "× / A / B(下)", 
				ControllerBinding.FaceRight => "○ / B / A(右)", 
				ControllerBinding.FaceLeft => "□ / X / Y(左)", 
				ControllerBinding.FaceTop => "△ / Y / X(上)", 
				ControllerBinding.LeftShoulder => "L1 / LB / L", 
				ControllerBinding.RightShoulder => "R1 / RB / R", 
				ControllerBinding.LeftTrigger => "L2 / LT / ZL", 
				ControllerBinding.RightTrigger => "R2 / RT / ZR", 
				ControllerBinding.DPadUp => "方向键上", 
				ControllerBinding.DPadDown => "方向键下", 
				ControllerBinding.DPadLeft => "方向键左", 
				ControllerBinding.DPadRight => "方向键右", 
				ControllerBinding.PrimaryMenu => "Options / Menu / +", 
				ControllerBinding.SecondaryMenu => "Share / View / −", 
				ControllerBinding.TouchPad => "PS4/PS5 触摸板", 
				_ => binding.ToString(), 
			};
		}

		private static bool TryConvertCapturedControl(InputControlType control, out ControllerBinding binding)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected I4, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_0058: 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_00a1: Expected I4, but got Unknown
			ControllerBinding controllerBinding;
			if ((int)control <= 115)
			{
				switch (control - 5)
				{
				case 0:
					goto IL_00b5;
				case 5:
					goto IL_00b9;
				case 14:
					goto IL_00bd;
				case 15:
					goto IL_00c1;
				case 16:
					goto IL_00c5;
				case 17:
					goto IL_00c9;
				case 12:
					goto IL_00cd;
				case 13:
					goto IL_00d1;
				case 10:
					goto IL_00d5;
				case 11:
					goto IL_00da;
				case 6:
					goto IL_00df;
				case 7:
					goto IL_00e4;
				case 8:
					goto IL_00e9;
				case 9:
					goto IL_00ee;
				case 1:
				case 2:
				case 3:
				case 4:
					goto IL_0102;
				}
				switch (control - 100)
				{
				case 1:
				case 4:
				case 6:
				case 13:
					break;
				case 0:
				case 2:
				case 7:
				case 9:
				case 14:
				case 15:
					goto IL_00f8;
				default:
					goto IL_0102;
				}
			}
			else
			{
				if ((int)control == 258)
				{
					controllerBinding = ControllerBinding.TouchPad;
					goto IL_0104;
				}
				if ((int)control != 300)
				{
					goto IL_0102;
				}
			}
			controllerBinding = ControllerBinding.PrimaryMenu;
			goto IL_0104;
			IL_00c9:
			controllerBinding = ControllerBinding.FaceTop;
			goto IL_0104;
			IL_0104:
			binding = controllerBinding;
			return binding != ControllerBinding.None;
			IL_0102:
			controllerBinding = ControllerBinding.None;
			goto IL_0104;
			IL_00f8:
			controllerBinding = ControllerBinding.SecondaryMenu;
			goto IL_0104;
			IL_00b5:
			controllerBinding = ControllerBinding.LeftStick;
			goto IL_0104;
			IL_00b9:
			controllerBinding = ControllerBinding.RightStick;
			goto IL_0104;
			IL_00df:
			controllerBinding = ControllerBinding.DPadUp;
			goto IL_0104;
			IL_00e4:
			controllerBinding = ControllerBinding.DPadDown;
			goto IL_0104;
			IL_00e9:
			controllerBinding = ControllerBinding.DPadLeft;
			goto IL_0104;
			IL_00ee:
			controllerBinding = ControllerBinding.DPadRight;
			goto IL_0104;
			IL_00d5:
			controllerBinding = ControllerBinding.LeftTrigger;
			goto IL_0104;
			IL_00da:
			controllerBinding = ControllerBinding.RightTrigger;
			goto IL_0104;
			IL_00cd:
			controllerBinding = ControllerBinding.LeftShoulder;
			goto IL_0104;
			IL_00d1:
			controllerBinding = ControllerBinding.RightShoulder;
			goto IL_0104;
			IL_00bd:
			controllerBinding = ControllerBinding.FaceBottom;
			goto IL_0104;
			IL_00c1:
			controllerBinding = ControllerBinding.FaceRight;
			goto IL_0104;
			IL_00c5:
			controllerBinding = ControllerBinding.FaceLeft;
			goto IL_0104;
		}

		private bool TryFindKeyboardConflict(KeyCode keyCode, out string actionName)
		{
			//IL_0007: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			actionName = string.Empty;
			if ((int)keyCode == 0)
			{
				return false;
			}
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (!Object.op_Implicit((Object)(object)silentInstance) || silentInstance.inputActions == null || silentInstance.MappableKeyboardActions == null)
			{
				return false;
			}
			if (!TryConvertKeyCode(keyCode, out var key))
			{
				return false;
			}
			foreach (PlayerAction mappableKeyboardAction in silentInstance.MappableKeyboardActions)
			{
				if (mappableKeyboardAction == null)
				{
					continue;
				}
				foreach (BindingSource binding in mappableKeyboardAction.Bindings)
				{
					KeyBindingSource val = (KeyBindingSource)(object)((binding is KeyBindingSource) ? binding : null);
					if (val == null)
					{
						continue;
					}
					KeyCombo control = val.Control;
					for (int i = 0; i < ((KeyCombo)(ref control)).IncludeCount; i++)
					{
						if (((KeyCombo)(ref control)).GetInclude(i) == key)
						{
							actionName = FriendlyActionName(mappableKeyboardAction.Name);
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool TryFindControllerConflict(InputControlType control, out string actionName)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			actionName = string.Empty;
			if ((int)control == 0)
			{
				return false;
			}
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (!Object.op_Implicit((Object)(object)silentInstance) || silentInstance.inputActions == null || silentInstance.MappableControllerActions == null)
			{
				return false;
			}
			foreach (PlayerAction mappableControllerAction in silentInstance.MappableControllerActions)
			{
				if (ActionUsesControl(mappableControllerAction, control))
				{
					actionName = FriendlyActionName(mappableControllerAction.Name);
					return true;
				}
			}
			if (ActionUsesControl(silentInstance.inputActions.Pause, control))
			{
				actionName = FriendlyActionName(silentInstance.inputActions.Pause.Name);
				return true;
			}
			return false;
		}

		private static bool ActionUsesControl(PlayerAction? action, InputControlType control)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return false;
			}
			foreach (BindingSource binding in action.Bindings)
			{
				DeviceBindingSource val = (DeviceBindingSource)(object)((binding is DeviceBindingSource) ? binding : null);
				if (val != null && val.Control == control)
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryConvertKeyCode(KeyCode keyCode, out Key key)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			key = (Key)0;
			if (KeyCodeToInControlKey == null)
			{
				return false;
			}
			try
			{
				if (KeyCodeToInControlKey.Invoke(null, new object[1] { keyCode }) is Key val)
				{
					key = (Key)(int)val;
					return (int)val > 0;
				}
			}
			catch
			{
			}
			return false;
		}

		private static string FriendlyActionName(string name)
		{
			return name switch
			{
				"Jump" => "跳跃", 
				"Attack" => "攻击", 
				"Dash" => "冲刺", 
				"Cast" => "施法", 
				"Super Dash" => "蓄力冲刺", 
				"Dream Nail" => "织针能力", 
				"Quick Map" => "快捷地图", 
				"Quick Cast" => "快捷施法", 
				"Taunt" => "挑战", 
				"openInventory" => "打开物品栏", 
				"openInventoryMap" => "地图页", 
				"openInventoryJournal" => "日志页", 
				"openInventoryTools" => "工具页", 
				"openInventoryQuests" => "任务页", 
				"Up" => "向上", 
				"Down" => "向下", 
				"Left" => "向左", 
				"Right" => "向右", 
				"Pause" => "暂停", 
				_ => name, 
			};
		}

		private void ShowCurrentConflictIfAny()
		{
			//IL_0007: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (TryFindKeyboardConflict(_gazeKey.Value, out string actionName))
			{
				SetBindingStatus("当前键盘绑定与“" + actionName + "”重复,远眺已暂时禁用该键。请重新绑定。", warning: true);
				return;
			}
			InputControlType control = ResolveControllerControl(GetCurrentControllerBinding());
			if (TryFindControllerConflict(control, out string actionName2))
			{
				SetBindingStatus("当前手柄绑定与“" + actionName2 + "”重复,远眺已暂时禁用该键。请重新绑定。", warning: true);
			}
			else
			{
				SetBindingStatus(string.Empty, warning: false);
			}
		}

		private void SetBindingStatus(string message, bool warning)
		{
			//IL_0058: 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)
			if (Object.op_Implicit((Object)(object)_bindingStatusLabel?.Text))
			{
				_bindingStatusLabel.Text.text = (warning ? message : string.Empty);
				((Graphic)_bindingStatusLabel.Text).color = (Color)(warning ? new Color(1f, 0.55f, 0.35f) : Color.white);
				((MenuElement)_bindingStatusLabel).Visibility.VisibleSelf = warning && !string.IsNullOrWhiteSpace(message);
			}
			if (warning)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			}
		}

		private static InputControlType ResolveControllerControl(ControllerBinding binding)
		{
			//IL_0077: 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)
			return (InputControlType)(binding switch
			{
				ControllerBinding.LeftStick => 5, 
				ControllerBinding.RightStick => 10, 
				ControllerBinding.FaceBottom => 19, 
				ControllerBinding.FaceRight => 20, 
				ControllerBinding.FaceLeft => 21, 
				ControllerBinding.FaceTop => 22, 
				ControllerBinding.LeftShoulder => 17, 
				ControllerBinding.RightShoulder => 18, 
				ControllerBinding.LeftTrigger => 15, 
				ControllerBinding.RightTrigger => 16, 
				ControllerBinding.DPadUp => 11, 
				ControllerBinding.DPadDown => 12, 
				ControllerBinding.DPadLeft => 13, 
				ControllerBinding.DPadRight => 14, 
				ControllerBinding.PrimaryMenu => ResolvePrimaryMenuButton(), 
				ControllerBinding.SecondaryMenu => ResolveSecondaryMenuButton(), 
				ControllerBinding.TouchPad => 258, 
				_ => 0, 
			});
		}

		private static InputControlType ResolvePrimaryMenuButton()
		{
			//IL_0012: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected I4, but got Unknown
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (!Object.op_Implicit((Object)(object)silentInstance))
			{
				return (InputControlType)101;
			}
			GamepadType activeGamepadType = silentInstance.activeGamepadType;
			switch (activeGamepadType - 2)
			{
			case 2:
			case 9:
				return (InputControlType)104;
			case 0:
			case 10:
				return (InputControlType)106;
			case 7:
			case 8:
			case 12:
			case 13:
				return (InputControlType)113;
			default:
				return (InputControlType)101;
			}
		}

		private static InputControlType ResolveSecondaryMenuButton()
		{
			//IL_0012: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected I4, but got Unknown
			InputHandler silentInstance = ManagerSingleton<InputHandler>.SilentInstance;
			if (!Object.op_Implicit((Object)(object)silentInstance))
			{
				return (InputControlType)102;
			}
			GamepadType activeGamepadType = silentInstance.activeGamepadType;
			switch (activeGamepadType - 2)
			{
			case 2:
				return (InputControlType)107;
			case 9:
				return (InputControlType)115;
			case 0:
			case 10:
				return (InputControlType)109;
			case 7:
			case 8:
			case 12:
			case 13:
				return (InputControlType)114;
			default:
				return (InputControlType)102;
			}
		}
	}
	internal enum FarGazeInputMode
	{
		Press,
		Hold
	}
	internal enum ControllerBinding
	{
		None,
		LeftStick,
		RightStick,
		FaceBottom,
		FaceRight,
		FaceLeft,
		FaceTop,
		LeftShoulder,
		RightShoulder,
		LeftTrigger,
		RightTrigger,
		DPadUp,
		DPadDown,
		DPadLeft,
		DPadRight,
		PrimaryMenu,
		SecondaryMenu,
		TouchPad
	}
	[HarmonyPatch(typeof(LightBlur), "OnRenderImage")]
	internal static class LightBlurPatch
	{
		private static readonly int BlurInfoId = Shader.PropertyToID("_BlurInfo");

		private static bool Prefix(LightBlur __instance, RenderTexture source, RenderTexture destination, Material ___blurMaterial, bool ___effectIsSupported)
		{
			//IL_0063: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			BlurTransition instance = BlurTransition.Instance;
			if (instance == null || !instance.Owns(__instance) || !instance.NeedsRenderOverride || !___effectIsSupported || !Object.op_Implicit((Object)(object)___blurMaterial))
			{
				return true;
			}
			float amount = instance.Amount;
			if (amount <= 0.0001f)
			{
				Graphics.Blit((Texture)(object)source, destination);
				return false;
			}
			int blurPassCount = __instance.BlurPassCount;
			if (blurPassCount <= 0)
			{
				Graphics.Blit((Texture)(object)source, destination);
				return false;
			}
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 32, source.format);
			RenderTexture temporary2 = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 32, source.format);
			try
			{
				RenderTexture val = source;
				bool flag = true;
				float num = amount * instance.BlurSampleScale;
				Vector4 val2 = default(Vector4);
				((Vector4)(ref val2))..ctor(num / (float)((Texture)source).width, num / (float)((Texture)source).height, 0f, 0f);
				for (int i = 0; i < blurPassCount; i++)
				{
					RenderTexture val3;
					if (i == blurPassCount - 1)
					{
						val3 = destination;
					}
					else if (flag)
					{
						val3 = temporary;
						flag = false;
					}
					else
					{
						val3 = temporary2;
						flag = true;
					}
					___blurMaterial.SetVector(BlurInfoId, val2);
					((Texture)val).filterMode = (FilterMode)1;
					Graphics.Blit((Texture)(object)val, val3, ___blurMaterial, i % 2);
					val = val3;
				}
			}
			finally
			{
				RenderTexture.ReleaseTemporary(temporary);
				RenderTexture.ReleaseTemporary(temporary2);
			}
			return false;
		}
	}
	internal static class Reflection
	{
		private const BindingFlags Flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		internal static object? ReadMember(object? target, string name)
		{
			if (target == null)
			{
				return null;
			}
			try
			{
				Type type = target.GetType();
				FieldInfo field = type.GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field.GetValue(target);
				}
				return type.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(target, null);
			}
			catch
			{
				return null;
			}
		}

		internal static bool WriteMember(object? target, string name, object value)
		{
			if (target == null)
			{
				return false;
			}
			try
			{
				Type type = target.GetType();
				FieldInfo field = type.GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(target, Convert.ChangeType(value, field.FieldType, CultureInfo.InvariantCulture));
					return true;
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)property != null && property.CanWrite)
				{
					property.SetValue(target, Convert.ChangeType(value, property.PropertyType, CultureInfo.InvariantCulture), null);
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		internal static bool TryInvoke(object? target, string methodName, params object[] args)
		{
			if (target == null)
			{
				return false;
			}
			try
			{
				MethodInfo[] methods = target.GetType().GetMethods(BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!methodInfo.Name.Equals(methodName, StringComparison.OrdinalIgnoreCase))
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length != args.Length)
					{
						continue;
					}
					bool flag = true;
					for (int j = 0; j < args.Length; j++)
					{
						if (args[j] != null && !parameters[j].ParameterType.IsInstanceOfType(args[j]))
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						methodInfo.Invoke(target, args);
						return true;
					}
				}
			}
			catch
			{
				return false;
			}
			return false;
		}

		internal static bool ReadBool(object? target, string name)
		{
			object obj = ReadMember(target, name);
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		internal static float AsFloat(object? value, float fallback)
		{
			if (value == null)
			{
				return fallback;
			}
			try
			{
				return Convert.ToSingle(value, CultureInfo.InvariantCulture);
			}
			catch
			{
				return fallback;
			}
		}
	}
}