Decompiled source of ExtractionDelayConfirm v1.0.2

Zichen-ExtractionDelayConfirm.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-ExtractionDelayConfirm")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7b4141c723d8c586ca5b791cd5437b3bc83f8bb4")]
[assembly: AssemblyProduct("Zichen-ExtractionDelayConfirm")]
[assembly: AssemblyTitle("Zichen-ExtractionDelayConfirm")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("zichen.extractiondelayconfirm", "A.Extraction Delay Confirm", "1.0.1")]
public sealed class WzcExtractionDelayConfirmPlugin : BaseUnityPlugin
{
	private sealed class PendingExtractionState
	{
		public ExtractionPoint ExtractionPoint { get; }

		public Dictionary<int, PlayerConfirmTracker> PlayerTrackers { get; } = new Dictionary<int, PlayerConfirmTracker>();


		public string PromptText { get; set; } = "已达金额,等待确认提取";


		public float NextCheckTime { get; set; }

		public bool ConfirmTriggered { get; set; }

		public int LastObservedHaul { get; set; } = -1;


		public bool HasZehsConfirmButton { get; set; }

		public PendingExtractionState(ExtractionPoint extractionPoint)
		{
			ExtractionPoint = extractionPoint;
		}
	}

	private sealed class PlayerConfirmTracker
	{
		public Vector3 AnchorPosition;

		public float StillTime;
	}

	public const string PluginGuid = "zichen.extractiondelayconfirm";

	public const string PluginVersion = "1.0.1";

	public const string PluginName = "A.Extraction Delay Confirm";

	private const string ZehsConfirmPluginGuid = "com.github.zehsteam.ExtractionPointConfirmButton";

	private const string ZehsConfirmAssemblyName = "com.github.zehsteam.ExtractionPointConfirmButton";

	private const string ZehsConfirmPatchTypeName = "com.github.zehsteam.ExtractionPointConfirmButton.Patches.ExtractionPointPatch";

	private const string InfoSection = "模组信息";

	private const string EnhancerSection = "A.延迟提取确认";

	private const float ConfirmCheckIntervalSeconds = 0.1f;

	private const float PromptHeightOffset = 1.8f;

	private const float FixedMoveToleranceMeters = 0.1f;

	private static readonly FieldInfo ExtractionPointCurrentStateField = typeof(ExtractionPoint).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ExtractionPointIsShopField = typeof(ExtractionPoint).GetField("isShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly MethodInfo ExtractionPointStateSetMethod = typeof(ExtractionPoint).GetMethod("StateSet", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo ExtractionPointSuccessDelayField = typeof(ExtractionPoint).GetField("successDelay", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo RoundDirectorCurrentHaulField = typeof(RoundDirector).GetField("currentHaul", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PlayerAvatarIsDisabledField = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private readonly Dictionary<int, PendingExtractionState> pendingStates = new Dictionary<int, PendingExtractionState>();

	private readonly HashSet<int> allowSuccessInstanceIds = new HashSet<int>();

	private readonly List<int> pendingRemovalKeys = new List<int>(4);

	private readonly HashSet<int> scratchSeenPlayers = new HashSet<int>();

	private readonly List<int> scratchPlayerRemovalKeys = new List<int>(8);

	private ConfigEntry<string> moduleNameInfo;

	private ConfigEntry<string> moduleVersionInfo;

	private ConfigEntry<string> contactInfo;

	private ConfigEntry<bool> enhancerEnabled;

	private ConfigEntry<bool> showCountdownPrompt;

	private ConfigEntry<int> confirmRangeMeters;

	private ConfigEntry<int> standStillSeconds;

	private Harmony harmony;

	private GUIStyle promptStyle;

	private GUIStyle promptShadowStyle;

	private Camera cachedCamera;

	private int cachedCameraFrame = -1;

	private bool compatibilityChecked;

	private bool hasZehsConfirmButton;

	private Type zehsExtractionPointPatchType;

	private PropertyInfo zehsConfirmButtonsProperty;

	private MethodInfo zehsConfirmExtractionPointMethod;

	private MethodInfo zehsConfirmButtonOnClickMethod;

	public static WzcExtractionDelayConfirmPlugin Instance { get; private set; }

	private void Awake()
	{
		Instance = this;
		MakePluginHostPersistent();
		BindConfig();
		ResolveCompatibility();
		ApplyPatches();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"zichen-extraction-delay-confirm loaded.");
	}

	private void Update()
	{
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		if (!IsFeatureEnabled() || pendingStates.Count == 0)
		{
			return;
		}
		bool flag = IsHostAuthority();
		float time = Time.time;
		int currentHaulValue = GetCurrentHaulValue();
		List<PlayerAvatar> playerList = (((Object)(object)GameDirector.instance != (Object)null) ? GameDirector.instance.PlayerList : null);
		pendingRemovalKeys.Clear();
		foreach (KeyValuePair<int, PendingExtractionState> pendingState in pendingStates)
		{
			PendingExtractionState value = pendingState.Value;
			ExtractionPoint val = value?.ExtractionPoint;
			if (value == null || value.ConfirmTriggered || (Object)(object)val == (Object)null || !IsActiveGameplayExtractionPoint(val))
			{
				pendingRemovalKeys.Add(pendingState.Key);
				continue;
			}
			if (!IsGoalReached(val, currentHaulValue))
			{
				pendingRemovalKeys.Add(pendingState.Key);
				continue;
			}
			if (flag && !value.HasZehsConfirmButton)
			{
				KeepExtractionPending(val);
			}
			if (!(time < value.NextCheckTime))
			{
				value.NextCheckTime = time + 0.1f;
				if (UpdateNearbyPlayers(value, ((Component)val).transform.position, 0.1f, currentHaulValue, playerList) && flag)
				{
					value.ConfirmTriggered = true;
					TriggerConfirmedExtraction(val);
					pendingRemovalKeys.Add(pendingState.Key);
				}
			}
		}
		for (int i = 0; i < pendingRemovalKeys.Count; i++)
		{
			int num = pendingRemovalKeys[i];
			pendingStates.Remove(num);
			allowSuccessInstanceIds.Remove(num);
		}
	}

	private void OnGUI()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Invalid comparison between Unknown and I4
		//IL_00a7: 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)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		if ((int)Event.current.type != 7 || !IsFeatureEnabled() || showCountdownPrompt == null || !showCountdownPrompt.Value || pendingStates.Count == 0)
		{
			return;
		}
		Camera activeCamera = GetActiveCamera();
		if ((Object)(object)activeCamera == (Object)null)
		{
			return;
		}
		EnsurePromptStyles();
		foreach (PendingExtractionState value in pendingStates.Values)
		{
			if (!((Object)(object)value?.ExtractionPoint == (Object)null) && !value.ConfirmTriggered && !string.IsNullOrWhiteSpace(value.PromptText))
			{
				Vector3 val = ((Component)value.ExtractionPoint).transform.position + new Vector3(0f, 1.8f, 0f);
				Vector3 val2 = activeCamera.WorldToScreenPoint(val);
				if (!(val2.z <= 0f))
				{
					val2.y = (float)Screen.height - val2.y;
					DrawCenteredPrompt(new Vector2(val2.x, val2.y), value.PromptText);
				}
			}
		}
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		if (Instance == this)
		{
			Instance = null;
		}
	}

	private void BindConfig()
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected O, but got Unknown
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Expected O, but got Unknown
		moduleNameInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组名称", "Zichen_延迟提取确认", new ConfigDescription("当前模组的中文名称。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 1000,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		moduleNameInfo.Value = "Extraction Delay Confirm / 延迟提取确认";
		moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "1.0.1", new ConfigDescription("当前模组版本号。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 990,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		moduleVersionInfo.Value = "1.0.1";
		contactInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "REPO交流QQ群", "824639225", new ConfigDescription("REPO 游戏交流、BUG 反馈、优化建议、功能请求请加 QQ 群。此处仅用于显示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 980,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		contactInfo.Value = "824639225";
		enhancerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.延迟提取确认", "启用", true, ConfigDescriptionWithOrder("只要主机安装即可生效。达到提取金额后,不再自动提取,改为需要玩家在提取点附近站定确认。", 900));
		showCountdownPrompt = ((BaseUnityPlugin)this).Config.Bind<bool>("A.延迟提取确认", "显示倒计时提示", true, ConfigDescriptionWithOrder("开启后,安装了本模组的玩家会在提取点上方看到靠近提示和站立倒计时提示。", 890));
		confirmRangeMeters = ((BaseUnityPlugin)this).Config.Bind<int>("A.延迟提取确认", "确认范围/米", 4, ConfigDescriptionWithOrder("达到提取金额后,提取点多大范围内的玩家可以触发站定确认。默认 4 米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), 880));
		standStillSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("A.延迟提取确认", "站定确认秒数", 5, ConfigDescriptionWithOrder("达到提取金额后,范围内任意玩家连续站定多久才会自动触发提取。默认 5 秒。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), 870));
	}

	private void ApplyPatches()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Expected O, but got Unknown
		harmony = new Harmony("zichen.extractiondelayconfirm.patch");
		MethodInfo methodInfo = AccessTools.Method(typeof(ExtractionPoint), "StateSet", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(ExtractionPoint), "Update", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Failed to find ExtractionPoint.StateSet for patching.");
			return;
		}
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(WzcExtractionDelayConfirmPlugin), "StateSetPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		if (methodInfo2 != null)
		{
			harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(WzcExtractionDelayConfirmPlugin), "ExtractionPointUpdatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		if (zehsConfirmExtractionPointMethod != null)
		{
			harmony.Patch((MethodBase)zehsConfirmExtractionPointMethod, new HarmonyMethod(typeof(WzcExtractionDelayConfirmPlugin), "ZehsConfirmExtractionPointPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}

	private bool IsFeatureEnabled()
	{
		if (enhancerEnabled != null)
		{
			return enhancerEnabled.Value;
		}
		return false;
	}

	private static bool IsHostAuthority()
	{
		try
		{
			return SemiFunc.IsMasterClientOrSingleplayer();
		}
		catch
		{
			return false;
		}
	}

	private static bool IsActiveGameplayExtractionPoint(ExtractionPoint extractionPoint)
	{
		//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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Invalid comparison between Unknown and I4
		if ((Object)(object)extractionPoint == (Object)null || IsShopExtractionPoint(extractionPoint))
		{
			return false;
		}
		if (ExtractionPointCurrentStateField?.GetValue(extractionPoint) is State val)
		{
			return (int)val == 2;
		}
		return false;
	}

	private static bool IsShopExtractionPoint(ExtractionPoint extractionPoint)
	{
		bool flag = default(bool);
		int num;
		if ((Object)(object)extractionPoint != (Object)null && ExtractionPointIsShopField != null)
		{
			object value = ExtractionPointIsShopField.GetValue(extractionPoint);
			if (value is bool)
			{
				flag = (bool)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
		}
		else
		{
			num = 0;
		}
		return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
	}

	private static int GetCurrentHaulValue()
	{
		if ((Object)(object)RoundDirector.instance != (Object)null && RoundDirectorCurrentHaulField != null)
		{
			object value = RoundDirectorCurrentHaulField.GetValue(RoundDirector.instance);
			if (value is int)
			{
				return (int)value;
			}
		}
		return 0;
	}

	private static bool IsGoalReached(ExtractionPoint extractionPoint, int currentHaul)
	{
		if ((Object)(object)extractionPoint != (Object)null && extractionPoint.haulGoal > 0)
		{
			return currentHaul >= extractionPoint.haulGoal;
		}
		return false;
	}

	private bool UpdateNearbyPlayers(PendingExtractionState state, Vector3 extractionPosition, float deltaTime, int currentHaul, List<PlayerAvatar> playerList)
	{
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		if (state.LastObservedHaul >= 0 && currentHaul != state.LastObservedHaul)
		{
			ResetConfirmTracking(state);
		}
		state.LastObservedHaul = currentHaul;
		float num = Mathf.Max(1f, (float)confirmRangeMeters.Value);
		float num2 = num * num;
		float num3 = 0.010000001f;
		float num4 = Mathf.Max(1f, (float)standStillSeconds.Value);
		float num5 = 0f;
		int num6 = 0;
		if (playerList == null)
		{
			state.PlayerTrackers.Clear();
			state.PromptText = BuildApproachPrompt(confirmRangeMeters.Value);
			return false;
		}
		scratchSeenPlayers.Clear();
		foreach (PlayerAvatar player in playerList)
		{
			if ((Object)(object)player == (Object)null || IsPlayerDisabled(player))
			{
				continue;
			}
			Vector3 position = ((Component)player).transform.position;
			Vector3 val = position - extractionPosition;
			if (((Vector3)(ref val)).sqrMagnitude > num2)
			{
				continue;
			}
			num6++;
			int instanceID = ((Object)player).GetInstanceID();
			scratchSeenPlayers.Add(instanceID);
			if (!state.PlayerTrackers.TryGetValue(instanceID, out var value))
			{
				value = new PlayerConfirmTracker
				{
					AnchorPosition = position,
					StillTime = 0f
				};
				state.PlayerTrackers[instanceID] = value;
			}
			else
			{
				val = position - value.AnchorPosition;
				if (((Vector3)(ref val)).sqrMagnitude > num3)
				{
					value.AnchorPosition = position;
					value.StillTime = 0f;
				}
				else
				{
					value.StillTime += deltaTime;
				}
			}
			num5 = Mathf.Max(num5, value.StillTime);
			if (value.StillTime >= num4)
			{
				state.PromptText = "确认完成,正在开始提取...";
				return true;
			}
		}
		if (state.PlayerTrackers.Count > 0)
		{
			scratchPlayerRemovalKeys.Clear();
			foreach (int key in state.PlayerTrackers.Keys)
			{
				if (!scratchSeenPlayers.Contains(key))
				{
					scratchPlayerRemovalKeys.Add(key);
				}
			}
			for (int i = 0; i < scratchPlayerRemovalKeys.Count; i++)
			{
				state.PlayerTrackers.Remove(scratchPlayerRemovalKeys[i]);
			}
		}
		state.PromptText = ((num6 <= 0) ? BuildApproachPrompt(confirmRangeMeters.Value) : BuildCountdownPrompt(num4, num5));
		return false;
	}

	private static void ResetConfirmTracking(PendingExtractionState state)
	{
		state?.PlayerTrackers.Clear();
	}

	private void TriggerConfirmedExtraction(ExtractionPoint extractionPoint)
	{
		if (!TryTriggerZehsConfirmButton(extractionPoint))
		{
			AllowAndTriggerSuccess(extractionPoint);
		}
	}

	private void AllowAndTriggerSuccess(ExtractionPoint extractionPoint)
	{
		if ((Object)(object)extractionPoint == (Object)null || ExtractionPointStateSetMethod == null)
		{
			return;
		}
		int instanceID = ((Object)extractionPoint).GetInstanceID();
		allowSuccessInstanceIds.Add(instanceID);
		try
		{
			ExtractionPointStateSetMethod.Invoke(extractionPoint, new object[1] { (object)(State)3 });
		}
		catch (Exception ex)
		{
			allowSuccessInstanceIds.Remove(instanceID);
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to trigger extraction success: " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private void RegisterPendingState(ExtractionPoint extractionPoint, int currentHaul)
	{
		if ((Object)(object)extractionPoint == (Object)null)
		{
			return;
		}
		int instanceID = ((Object)extractionPoint).GetInstanceID();
		if (pendingStates.TryGetValue(instanceID, out var value))
		{
			if (value.LastObservedHaul < 0)
			{
				value.LastObservedHaul = currentHaul;
			}
			if (!value.HasZehsConfirmButton)
			{
				value.HasZehsConfirmButton = HasZehsConfirmButtonForExtractionPoint(extractionPoint);
			}
		}
		else
		{
			pendingStates[instanceID] = new PendingExtractionState(extractionPoint)
			{
				NextCheckTime = Time.time,
				LastObservedHaul = currentHaul,
				PromptText = BuildApproachPrompt((confirmRangeMeters != null) ? Mathf.Max(1, confirmRangeMeters.Value) : 4),
				HasZehsConfirmButton = HasZehsConfirmButtonForExtractionPoint(extractionPoint)
			};
		}
	}

	private void ResolveCompatibility()
	{
		if (!compatibilityChecked)
		{
			compatibilityChecked = true;
			hasZehsConfirmButton = Chainloader.PluginInfos.ContainsKey("com.github.zehsteam.ExtractionPointConfirmButton");
			if (hasZehsConfirmButton)
			{
				zehsExtractionPointPatchType = Type.GetType("com.github.zehsteam.ExtractionPointConfirmButton.Patches.ExtractionPointPatch, com.github.zehsteam.ExtractionPointConfirmButton", throwOnError: false);
				zehsConfirmButtonsProperty = zehsExtractionPointPatchType?.GetProperty("ConfirmButtons", BindingFlags.Static | BindingFlags.Public);
				zehsConfirmExtractionPointMethod = zehsExtractionPointPatchType?.GetMethod("ConfirmExtractionPoint", BindingFlags.Static | BindingFlags.Public);
			}
		}
	}

	private bool TryTriggerZehsConfirmButton(ExtractionPoint extractionPoint)
	{
		ResolveCompatibility();
		if (!hasZehsConfirmButton || (Object)(object)extractionPoint == (Object)null)
		{
			return false;
		}
		try
		{
			if (zehsConfirmExtractionPointMethod != null)
			{
				zehsConfirmExtractionPointMethod.Invoke(null, new object[1] { extractionPoint });
				return true;
			}
			object obj = TryGetZehsConfirmButton(extractionPoint);
			if (obj != null)
			{
				if ((object)zehsConfirmButtonOnClickMethod == null)
				{
					zehsConfirmButtonOnClickMethod = obj.GetType().GetMethod("OnClick", BindingFlags.Instance | BindingFlags.Public);
				}
				if (zehsConfirmButtonOnClickMethod != null)
				{
					MarkSuccessAllowed(extractionPoint);
					zehsConfirmButtonOnClickMethod.Invoke(obj, null);
					return true;
				}
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to trigger Zehs confirm compatibility path: " + ex.GetType().Name + ": " + ex.Message));
		}
		return false;
	}

	private object TryGetZehsConfirmButton(ExtractionPoint extractionPoint)
	{
		if (!(zehsConfirmButtonsProperty?.GetValue(null) is IDictionary dictionary))
		{
			return null;
		}
		if (!dictionary.Contains(extractionPoint))
		{
			return null;
		}
		return dictionary[extractionPoint];
	}

	private bool HasZehsConfirmButtonForExtractionPoint(ExtractionPoint extractionPoint)
	{
		ResolveCompatibility();
		if (hasZehsConfirmButton)
		{
			return TryGetZehsConfirmButton(extractionPoint) != null;
		}
		return false;
	}

	private void MarkSuccessAllowed(ExtractionPoint extractionPoint)
	{
		if (!((Object)(object)extractionPoint == (Object)null))
		{
			allowSuccessInstanceIds.Add(((Object)extractionPoint).GetInstanceID());
		}
	}

	private static void KeepExtractionPending(ExtractionPoint extractionPoint)
	{
		if (!((Object)(object)extractionPoint == (Object)null) && !(ExtractionPointSuccessDelayField == null))
		{
			ExtractionPointSuccessDelayField.SetValue(extractionPoint, 1.5f);
		}
	}

	private static string BuildApproachPrompt(int range)
	{
		return $"已达金额,靠近提取点 {Mathf.Max(1, range)} 米内开始提取";
	}

	private static string BuildCountdownPrompt(float requiredSeconds, float bestStillTime)
	{
		float num = Mathf.Max(0f, requiredSeconds - bestStillTime);
		return $"站立别动 {num:0.0} 秒开始提取...";
	}

	private void EnsurePromptStyles()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		if (promptStyle == null || promptShadowStyle == null)
		{
			promptStyle = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 28,
				fontStyle = (FontStyle)1,
				richText = false
			};
			promptStyle.normal.textColor = new Color(1f, 0.92f, 0.35f, 1f);
			promptShadowStyle = new GUIStyle(promptStyle);
			promptShadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.95f);
		}
	}

	private void DrawCenteredPrompt(Vector2 center, string text)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: 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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_004a: 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)
		Vector2 val = promptStyle.CalcSize(new GUIContent(text));
		Rect val2;
		Rect val3 = (val2 = new Rect(center.x - val.x * 0.5f, center.y - val.y * 0.5f, val.x, val.y));
		((Rect)(ref val2)).x = ((Rect)(ref val2)).x + 2f;
		((Rect)(ref val2)).y = ((Rect)(ref val2)).y + 2f;
		GUI.Label(val2, text, promptShadowStyle);
		GUI.Label(val3, text, promptStyle);
	}

	private Camera GetActiveCamera()
	{
		if (cachedCameraFrame == Time.frameCount)
		{
			return cachedCamera;
		}
		cachedCameraFrame = Time.frameCount;
		cachedCamera = Camera.main;
		if ((Object)(object)cachedCamera == (Object)null)
		{
			cachedCamera = Object.FindObjectOfType<Camera>();
		}
		return cachedCamera;
	}

	private void MakePluginHostPersistent()
	{
		try
		{
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private void DrawInfo(ConfigEntryBase entry)
	{
		GUILayout.Label(entry.BoxedValue?.ToString() ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, AcceptableValueBase acceptableValues, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, acceptableValues, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private static bool StateSetPrefix(ExtractionPoint __instance, State newState)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Invalid comparison between Unknown and I4
		WzcExtractionDelayConfirmPlugin instance = Instance;
		if ((Object)(object)instance == (Object)null || !instance.IsFeatureEnabled() || !IsHostAuthority())
		{
			return true;
		}
		if ((int)newState != 3)
		{
			return true;
		}
		if ((Object)(object)__instance == (Object)null || IsShopExtractionPoint(__instance) || !IsActiveGameplayExtractionPoint(__instance))
		{
			return true;
		}
		int instanceID = ((Object)__instance).GetInstanceID();
		if (instance.allowSuccessInstanceIds.Remove(instanceID))
		{
			return true;
		}
		if (instance.HasZehsConfirmButtonForExtractionPoint(__instance))
		{
			return true;
		}
		instance.RegisterPendingState(__instance, GetCurrentHaulValue());
		return false;
	}

	private static void ExtractionPointUpdatePrefix(ExtractionPoint __instance)
	{
		WzcExtractionDelayConfirmPlugin instance = Instance;
		if ((Object)(object)instance == (Object)null || !instance.IsFeatureEnabled() || (Object)(object)__instance == (Object)null || IsShopExtractionPoint(__instance) || !IsActiveGameplayExtractionPoint(__instance))
		{
			return;
		}
		int currentHaulValue = GetCurrentHaulValue();
		if (IsGoalReached(__instance, currentHaulValue))
		{
			instance.RegisterPendingState(__instance, currentHaulValue);
			if (IsHostAuthority() && !instance.HasZehsConfirmButtonForExtractionPoint(__instance))
			{
				KeepExtractionPending(__instance);
			}
		}
	}

	private static void ZehsConfirmExtractionPointPrefix(ExtractionPoint extractionPoint)
	{
		WzcExtractionDelayConfirmPlugin instance = Instance;
		if (!((Object)(object)instance == (Object)null) && instance.IsFeatureEnabled() && IsHostAuthority())
		{
			instance.MarkSuccessAllowed(extractionPoint);
		}
	}

	private static bool IsPlayerDisabled(PlayerAvatar player)
	{
		if (!((Object)(object)player == (Object)null))
		{
			bool flag = default(bool);
			int num;
			if (PlayerAvatarIsDisabledField != null)
			{
				object value = PlayerAvatarIsDisabledField.GetValue(player);
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}
		return true;
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;
}