Decompiled source of REPO Active v4.5.5

BepInEx\plugins\REPO_Active\REPO_Active.dll

Decompiled 19 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using REPO_Active.Reflection;
using REPO_Active.Runtime;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("REPO_Active")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("4.0.2.0")]
[assembly: AssemblyInformationalVersion("4.0.2")]
[assembly: AssemblyProduct("REPO_Active")]
[assembly: AssemblyTitle("REPO_Active")]
[assembly: AssemblyVersion("4.0.2.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.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]
	[Microsoft.CodeAnalysis.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]
	[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;
		}
	}
}
namespace REPO_Active
{
	[BepInPlugin("angelcomilk.repo_active", "REPO_Active", "4.5.5")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "angelcomilk.repo_active";

		public const string PluginName = "REPO_Active";

		public const string PluginVersion = "4.5.5";

		private ConfigEntry<bool> _autoActivate;

		private ConfigEntry<KeyCode> _keyActivateNearest;

		private ConfigEntry<bool> _discoverAllPoints;

		private ExtractionPointScanner _scanner;

		private ExtractionPointInvoker _invoker;

		private float _autoTimer;

		private float _discoverTimer;

		private float _autoReadyTime = -1f;

		private bool _autoPrimed;

		private float _discoverIntervalFixed = -1f;

		private const float RESCAN_COOLDOWN = 0.6f;

		private const bool VERBOSE = false;

		private const bool SKIP_ACTIVATED = true;

		private const float AUTO_INTERVAL = 5f;

		private const float DISCOVER_INTERVAL_BASE = 0.5f;

		private const float DISCOVER_INTERVAL_4_6 = 1f;

		private const float DISCOVER_INTERVAL_7_9 = 1.5f;

		private const float DISCOVER_INTERVAL_10_12 = 2f;

		private const float DISCOVER_RADIUS = 20f;

		private const float AUTO_READY_BUFFER = 30f;

		private void Awake()
		{
			_autoActivate = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto", "AutoActivate", false, "Auto activate when idle.");
			_keyActivateNearest = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keybinds", "ActivateNearest", (KeyCode)284, "Press to activate next extraction point (uses OnClick via reflection).");
			_discoverAllPoints = ((BaseUnityPlugin)this).Config.Bind<bool>("Discovery", "DiscoverAllPoints", false, "If true, treat all extraction points as discovered.");
			_invoker = new ExtractionPointInvoker(((BaseUnityPlugin)this).Logger, verbose: false);
			_scanner = new ExtractionPointScanner(((BaseUnityPlugin)this).Logger, _invoker, 0.6f, verbose: false);
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"REPO_Active 4.5.5 loaded. (OnClick reflection activation)");
		}

		private void OnDestroy()
		{
			try
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
			}
			catch
			{
			}
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(_keyActivateNearest.Value))
			{
				ActivateNearest();
			}
			_discoverTimer += Time.deltaTime;
			float num = ((_discoverIntervalFixed > 0f) ? _discoverIntervalFixed : 0.5f);
			if (_discoverTimer >= num)
			{
				_discoverTimer = 0f;
				DiscoveryTick();
			}
			if (!_autoActivate.Value)
			{
				return;
			}
			if (_autoReadyTime < 0f)
			{
				if (_scanner.EnsureReady())
				{
					List<Component> list = _scanner.ScanAndGetAllPoints();
					Vector3 referencePos = _scanner.GetReferencePos();
					if (list.Count > 0 && referencePos != Vector3.zero)
					{
						_scanner.CaptureSpawnPosIfNeeded(referencePos);
						_autoReadyTime = Time.realtimeSinceStartup;
						_autoTimer = 0f;
						_discoverIntervalFixed = ComputeDiscoveryInterval();
					}
				}
			}
			else if (Time.realtimeSinceStartup - _autoReadyTime >= 30f)
			{
				if (!_autoPrimed)
				{
					PrimeFirstPointIfAlreadyActivated();
					_autoPrimed = true;
				}
				_autoTimer += Time.deltaTime;
				if (_autoTimer >= 5f)
				{
					_autoTimer = 0f;
					AutoActivateIfIdle();
				}
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			_autoReadyTime = -1f;
			_autoPrimed = false;
			_discoverIntervalFixed = -1f;
			_autoTimer = 0f;
			_discoverTimer = 0f;
			_scanner.ResetForNewRound();
		}

		private void DiscoveryTick()
		{
			//IL_0020: 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_0055: 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)
			if (!_scanner.EnsureReady())
			{
				return;
			}
			List<Component> allPoints = _scanner.ScanAndGetAllPoints();
			Vector3 referencePos = _scanner.GetReferencePos();
			if (_discoverAllPoints.Value)
			{
				_scanner.MarkAllDiscovered(allPoints);
				return;
			}
			List<Vector3> list = TryGetAllPlayerPositionsHost();
			if (list.Count == 0)
			{
				_scanner.UpdateDiscovered(referencePos, 20f);
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				_scanner.UpdateDiscovered(list[i], 20f);
			}
		}

		private void AutoActivateIfIdle()
		{
			if (_scanner.EnsureReady())
			{
				ActivateNearest();
			}
		}

		private void ActivateNearest()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if (!_scanner.EnsureReady())
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"ExtractionPoint type not found yet.");
				return;
			}
			_scanner.ScanIfNeeded(force: true);
			List<Component> list = _scanner.ScanAndGetAllPoints();
			if (_scanner.IsAnyExtractionPointActivating(list))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"有提取点正在激活中,F3 忽略");
				return;
			}
			Vector3 referencePos = _scanner.GetReferencePos();
			_scanner.CaptureSpawnPosIfNeeded(referencePos);
			Vector3 spawnPos = _scanner.GetSpawnPos();
			if (_discoverAllPoints.Value)
			{
				_scanner.MarkAllDiscovered(list);
			}
			else
			{
				_scanner.UpdateDiscovered(referencePos, 20f);
			}
			List<Component> allPoints = (List<Component>)(_discoverAllPoints.Value ? ((IList)list) : ((IList)_scanner.FilterDiscovered(list)));
			List<Component> list2 = _scanner.BuildStage1PlannedList(allPoints, spawnPos, referencePos, skipActivated: true);
			if (list2.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"没有可激活的提取点(可能都已激活或未发现)");
				return;
			}
			Component val = list2[0];
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[F3] Activate planned EP: {((Object)val.gameObject).name} pos={val.transform.position} dist={Vector3.Distance(referencePos, val.transform.position):0.00}");
			if (_invoker.InvokeOnClick(val))
			{
				_scanner.MarkActivated(val);
			}
		}

		private void PrimeFirstPointIfAlreadyActivated()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			List<Component> list = _scanner.ScanAndGetAllPoints();
			if (list.Count == 0)
			{
				return;
			}
			Vector3 referencePos = _scanner.GetReferencePos();
			_scanner.CaptureSpawnPosIfNeeded(referencePos);
			if (_discoverAllPoints.Value)
			{
				_scanner.MarkAllDiscovered(list);
			}
			else
			{
				_scanner.UpdateDiscovered(referencePos, 20f);
			}
			List<Component> allPoints = (List<Component>)(_discoverAllPoints.Value ? ((IList)list) : ((IList)_scanner.FilterDiscovered(list)));
			List<Component> list2 = _scanner.BuildStage1PlannedList(allPoints, _scanner.GetSpawnPos(), referencePos, skipActivated: true);
			if (list2.Count != 0)
			{
				Component ep = list2[0];
				string text = _scanner.ReadStateName(ep);
				if (!string.IsNullOrEmpty(text) && !ExtractionPointScanner.IsIdleLikeState(text))
				{
					_scanner.MarkActivated(ep);
				}
			}
		}

		private List<Vector3> TryGetAllPlayerPositionsHost()
		{
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			try
			{
				Type type = Type.GetType("Photon.Pun.PhotonNetwork, PhotonUnityNetworking");
				if (type == null)
				{
					return list;
				}
				PropertyInfo property = type.GetProperty("InRoom");
				PropertyInfo property2 = type.GetProperty("IsMasterClient");
				bool flag = default(bool);
				int num;
				if (property != null)
				{
					object value = property.GetValue(null);
					if (value is bool)
					{
						flag = (bool)value;
						num = 1;
					}
					else
					{
						num = 0;
					}
				}
				else
				{
					num = 0;
				}
				int num2 = num & (flag ? 1 : 0);
				bool flag2 = default(bool);
				int num3;
				if (property2 != null)
				{
					object value = property2.GetValue(null);
					if (value is bool)
					{
						flag2 = (bool)value;
						num3 = 1;
					}
					else
					{
						num3 = 0;
					}
				}
				else
				{
					num3 = 0;
				}
				bool flag3 = (byte)((uint)num3 & (flag2 ? 1u : 0u)) != 0;
				if (num2 == 0 || !flag3)
				{
					return list;
				}
				Type type2 = Type.GetType("GameDirector, Assembly-CSharp");
				if (type2 == null)
				{
					return list;
				}
				object obj = null;
				PropertyInfo property3 = type2.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property3 != null)
				{
					obj = property3.GetValue(null, null);
				}
				if (obj == null)
				{
					FieldInfo field = type2.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						obj = field.GetValue(null);
					}
				}
				if (obj == null)
				{
					return list;
				}
				object obj2 = null;
				PropertyInfo property4 = type2.GetProperty("PlayerList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property4 != null)
				{
					obj2 = property4.GetValue(obj, null);
				}
				if (obj2 == null)
				{
					FieldInfo field2 = type2.GetField("PlayerList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						obj2 = field2.GetValue(obj);
					}
				}
				if (obj2 == null)
				{
					return list;
				}
				if (!(obj2 is IEnumerable enumerable))
				{
					return list;
				}
				foreach (object item in enumerable)
				{
					if (item == null)
					{
						continue;
					}
					Component val = (Component)((item is Component) ? item : null);
					if (val != null && (Object)(object)val.transform != (Object)null)
					{
						Vector3 position = val.transform.position;
						if (position != Vector3.zero)
						{
							list.Add(position);
						}
						continue;
					}
					Type type3 = item.GetType();
					object obj3 = null;
					PropertyInfo property5 = type3.GetProperty("PlayerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (property5 != null)
					{
						obj3 = property5.GetValue(item, null);
					}
					if (obj3 == null)
					{
						FieldInfo field3 = type3.GetField("PlayerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field3 != null)
						{
							obj3 = field3.GetValue(item);
						}
					}
					if (obj3 == null)
					{
						continue;
					}
					Component val2 = (Component)((obj3 is Component) ? obj3 : null);
					if (val2 != null && (Object)(object)val2.transform != (Object)null)
					{
						Vector3 position2 = val2.transform.position;
						if (position2 != Vector3.zero)
						{
							list.Add(position2);
						}
						continue;
					}
					PropertyInfo property6 = obj3.GetType().GetProperty("transform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					Transform val3 = (Transform)((property6 != null) ? /*isinst with value type is only supported in some contexts*/: null);
					if ((Object)(object)val3 != (Object)null)
					{
						Vector3 position3 = val3.position;
						if (position3 != Vector3.zero)
						{
							list.Add(position3);
						}
					}
				}
				return list;
			}
			catch
			{
				return list;
			}
		}

		private float ComputeDiscoveryInterval()
		{
			int playerCountHost = GetPlayerCountHost();
			if (playerCountHost <= 3)
			{
				return 0.5f;
			}
			if (playerCountHost <= 6)
			{
				return 1f;
			}
			if (playerCountHost <= 9)
			{
				return 1.5f;
			}
			return 2f;
		}

		private int GetPlayerCountHost()
		{
			try
			{
				Type type = Type.GetType("Photon.Pun.PhotonNetwork, PhotonUnityNetworking");
				if (type == null)
				{
					return 1;
				}
				PropertyInfo property = type.GetProperty("InRoom");
				PropertyInfo property2 = type.GetProperty("IsMasterClient");
				PropertyInfo property3 = type.GetProperty("PlayerList");
				bool flag = default(bool);
				int num;
				if (property != null)
				{
					object value = property.GetValue(null);
					if (value is bool)
					{
						flag = (bool)value;
						num = 1;
					}
					else
					{
						num = 0;
					}
				}
				else
				{
					num = 0;
				}
				int num2 = num & (flag ? 1 : 0);
				bool flag2 = default(bool);
				int num3;
				if (property2 != null)
				{
					object value = property2.GetValue(null);
					if (value is bool)
					{
						flag2 = (bool)value;
						num3 = 1;
					}
					else
					{
						num3 = 0;
					}
				}
				else
				{
					num3 = 0;
				}
				bool flag3 = (byte)((uint)num3 & (flag2 ? 1u : 0u)) != 0;
				if (num2 == 0 || !flag3)
				{
					return 1;
				}
				if (property3 != null && property3.GetValue(null) is Array array && array.Length > 0)
				{
					return array.Length;
				}
			}
			catch
			{
			}
			return 1;
		}
	}
}
namespace REPO_Active.Runtime
{
	public sealed class ActivationQueue
	{
		private readonly ManualLogSource _log;

		private readonly ExtractionPointInvoker _invoker;

		private readonly ExtractionPointScanner _scanner;

		private Coroutine? _running;

		public float PerActivationDelay { get; set; }

		public bool Verbose { get; set; }

		public ActivationQueue(ManualLogSource log, ExtractionPointInvoker invoker, ExtractionPointScanner scanner, float perActivationDelay, bool verbose)
		{
			_log = log;
			_invoker = invoker;
			_scanner = scanner;
			PerActivationDelay = perActivationDelay;
			Verbose = verbose;
		}

		public void StartQueue(MonoBehaviour host, List<Component> queue, Action<Component>? onActivated)
		{
			if (_running != null)
			{
				host.StopCoroutine(_running);
				_running = null;
			}
			_running = host.StartCoroutine(Run(queue, onActivated));
		}

		private IEnumerator Run(List<Component> queue, Action<Component>? onActivated)
		{
			for (int i = 0; i < queue.Count; i++)
			{
				Component val = queue[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (_invoker.InvokeOnClick(val))
				{
					onActivated?.Invoke(val);
					if (Verbose)
					{
						_log.LogInfo((object)$"[QUEUE] Activated {i + 1}/{queue.Count}: {((Object)val.gameObject).name}");
					}
				}
				else
				{
					_log.LogWarning((object)("[QUEUE] Activation failed: " + ((Object)val.gameObject).name));
				}
				if (PerActivationDelay > 0f)
				{
					yield return (object)new WaitForSeconds(PerActivationDelay);
				}
				else
				{
					yield return null;
				}
			}
			_log.LogInfo((object)"[QUEUE] Done.");
			_running = null;
		}
	}
	public sealed class ExtractionPointScanner
	{
		private readonly ManualLogSource _log;

		private readonly ExtractionPointInvoker _invoker;

		private Type? _epType;

		private readonly List<Component> _cached = new List<Component>();

		private float _lastScanRealtime;

		private Vector3? _spawnPos;

		private int? _spawnExcludedInstanceId;

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

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

		private int _spawnGateInstanceId;

		private float _blockUntil = -1f;

		public float RescanCooldown { get; set; }

		public bool Verbose { get; set; }

		public ExtractionPointScanner(ManualLogSource log, ExtractionPointInvoker invoker, float rescanCooldown, bool verbose)
		{
			_log = log;
			_invoker = invoker;
			RescanCooldown = rescanCooldown;
			Verbose = verbose;
			_blockUntil = Time.realtimeSinceStartup + 10f;
		}

		public bool EnsureReady()
		{
			if (_epType != null)
			{
				return true;
			}
			_epType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a)
			{
				try
				{
					return a.GetTypes();
				}
				catch
				{
					return Array.Empty<Type>();
				}
			}).FirstOrDefault((Type t) => t != null && t.Name == "ExtractionPoint");
			return _epType != null;
		}

		public void ScanIfNeeded(bool force)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (!force && realtimeSinceStartup - _lastScanRealtime < RescanCooldown)
				{
					return;
				}
				_lastScanRealtime = realtimeSinceStartup;
				if (EnsureReady())
				{
					Object[] source = Object.FindObjectsOfType(_epType);
					_cached.Clear();
					_cached.AddRange(from c in source.OfType<Component>()
						where (Object)(object)c != (Object)null
						select c);
					if (_spawnPos.HasValue)
					{
						UpdateSpawnGateAlwaysNearest(_cached, _spawnPos.Value);
					}
					if (Verbose)
					{
						_log.LogInfo((object)$"[SCAN] ExtractionPoint rescan: {_cached.Count}");
					}
				}
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"ScanIfNeeded failed: {arg}");
			}
		}

		public Vector3 GetReferencePos()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)Camera.main != (Object)null)
				{
					return ((Component)Camera.main).transform.position;
				}
			}
			catch
			{
			}
			try
			{
				GameObject val = GameObject.FindWithTag("Player");
				if ((Object)(object)val != (Object)null)
				{
					return val.transform.position;
				}
			}
			catch
			{
			}
			return Vector3.zero;
		}

		public void MarkAllDiscovered(List<Component> allPoints)
		{
			for (int i = 0; i < allPoints.Count; i++)
			{
				Component val = allPoints[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					_discovered.Add(((Object)val).GetInstanceID());
				}
			}
		}

		public void UpdateDiscovered(Vector3 refPos, float radius)
		{
			//IL_003c: 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)
			if (_cached.Count == 0)
			{
				return;
			}
			for (int i = 0; i < _cached.Count; i++)
			{
				Component val = _cached[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					int instanceID = ((Object)val).GetInstanceID();
					if (!_discovered.Contains(instanceID) && Vector3.Distance(refPos, val.transform.position) <= radius)
					{
						_discovered.Add(instanceID);
					}
				}
			}
		}

		public List<Component> FilterDiscovered(List<Component> allPoints)
		{
			List<Component> list = new List<Component>();
			for (int i = 0; i < allPoints.Count; i++)
			{
				Component val = allPoints[i];
				if (Object.op_Implicit((Object)(object)val) && _discovered.Contains(((Object)val).GetInstanceID()))
				{
					list.Add(val);
				}
			}
			return list;
		}

		public Vector3 GetSpawnPos()
		{
			//IL_0018: 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)
			return (Vector3)(((??)_spawnPos) ?? Vector3.zero);
		}

		public void CaptureSpawnPosIfNeeded(Vector3 refPos)
		{
			//IL_000e: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!_spawnPos.HasValue && !(refPos == Vector3.zero))
			{
				_spawnPos = refPos;
				if (Verbose)
				{
					_log.LogInfo((object)$"[SPAWN] spawnPos captured: {_spawnPos.Value}");
				}
			}
		}

		public List<Component> ScanAndGetAllPoints()
		{
			ScanIfNeeded(force: true);
			return _cached.Where((Component c) => (Object)(object)c != (Object)null).ToList();
		}

		public void ResetForNewRound()
		{
			_cached.Clear();
			_activatedIds.Clear();
			_discovered.Clear();
			_spawnPos = null;
			_spawnExcludedInstanceId = null;
			_spawnGateInstanceId = 0;
			_lastScanRealtime = 0f;
		}

		public void UpdateSpawnExcludeIfNeeded(Vector3 refPos, float spawnExcludeRadius)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!_spawnPos.HasValue)
			{
				if (!(refPos != Vector3.zero))
				{
					return;
				}
				_spawnPos = refPos;
				if (Verbose)
				{
					_log.LogInfo((object)$"[SPAWN] spawnPos captured: {_spawnPos.Value}");
				}
			}
			if (_spawnExcludedInstanceId.HasValue || _cached.Count == 0)
			{
				return;
			}
			Vector3 value = _spawnPos.Value;
			Component val = null;
			float num = float.MaxValue;
			foreach (Component item in _cached)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num2 = Vector3.Distance(value, item.transform.position);
					if (num2 < num)
					{
						num = num2;
						val = item;
					}
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				if (num <= spawnExcludeRadius)
				{
					_spawnExcludedInstanceId = ((Object)val).GetInstanceID();
					_log.LogInfo((object)$"[SPAWN] Excluding spawn-nearest EP: {((Object)val.gameObject).name} dist={num:0.00} (<= {spawnExcludeRadius:0.00})");
				}
				else if (Verbose)
				{
					_log.LogInfo((object)$"[SPAWN] Nearest EP is {num:0.00}m away (> {spawnExcludeRadius:0.00}), no spawn exclusion applied.");
				}
			}
		}

		public Component? FindNearest(Vector3 refPos, bool excludeSpawn, float spawnExcludeRadius, bool skipActivated)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (_cached.Count == 0)
			{
				return null;
			}
			Component result = null;
			float num = float.MaxValue;
			foreach (Component item in _cached)
			{
				if (!((Object)(object)item == (Object)null) && (!excludeSpawn || !IsSpawnExcluded(item, spawnExcludeRadius)) && (!skipActivated || !_activatedIds.Contains(((Object)item).GetInstanceID())))
				{
					float num2 = Vector3.Distance(refPos, item.transform.position);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		public List<Component> BuildSortedList(Vector3 refPos, bool excludeSpawn, float spawnExcludeRadius, bool skipActivated)
		{
			//IL_0015: 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)
			IEnumerable<Component> source = _cached.Where((Component c) => (Object)(object)c != (Object)null);
			if (excludeSpawn)
			{
				source = source.Where((Component ep) => !IsSpawnExcluded(ep, spawnExcludeRadius));
			}
			if (skipActivated)
			{
				source = source.Where((Component ep) => !_activatedIds.Contains(((Object)ep).GetInstanceID()));
			}
			return source.OrderBy((Component ep) => Vector3.Distance(refPos, ep.transform.position)).ToList();
		}

		public void MarkActivated(Component ep)
		{
			if (!((Object)(object)ep == (Object)null))
			{
				_activatedIds.Add(((Object)ep).GetInstanceID());
			}
		}

		private bool IsMarkedActivated(Component ep)
		{
			if ((Object)(object)ep == (Object)null)
			{
				return false;
			}
			return _activatedIds.Contains(((Object)ep).GetInstanceID());
		}

		private bool IsSpawnExcluded(Component ep, float spawnExcludeRadius)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ep == (Object)null)
			{
				return true;
			}
			if (_spawnExcludedInstanceId.HasValue)
			{
				return ((Object)ep).GetInstanceID() == _spawnExcludedInstanceId.Value;
			}
			if (!_spawnPos.HasValue)
			{
				return false;
			}
			if (Vector3.Distance(_spawnPos.Value, ep.transform.position) <= spawnExcludeRadius)
			{
				return ((Object)ep).GetInstanceID() == GetNearestToSpawnInstanceId();
			}
			return false;
		}

		private int? GetNearestToSpawnInstanceId()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!_spawnPos.HasValue)
			{
				return null;
			}
			if (_cached.Count == 0)
			{
				return null;
			}
			Vector3 value = _spawnPos.Value;
			Component val = null;
			float num = float.MaxValue;
			foreach (Component item in _cached)
			{
				if (!((Object)(object)item == (Object)null))
				{
					float num2 = Vector3.Distance(value, item.transform.position);
					if (num2 < num)
					{
						num = num2;
						val = item;
					}
				}
			}
			if (val == null)
			{
				return null;
			}
			return ((Object)val).GetInstanceID();
		}

		public Component? GetSpawnGatePoint(List<Component> allPoints)
		{
			if (_spawnGateInstanceId == 0)
			{
				return null;
			}
			for (int i = 0; i < allPoints.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)allPoints[i]) && ((Object)allPoints[i]).GetInstanceID() == _spawnGateInstanceId)
				{
					return allPoints[i];
				}
			}
			return null;
		}

		private void UpdateSpawnGateAlwaysNearest(List<Component> allPoints, Vector3 spawnPos)
		{
			//IL_0035: 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 (allPoints == null || allPoints.Count == 0)
			{
				_spawnGateInstanceId = 0;
				return;
			}
			Component val = null;
			float num = float.MaxValue;
			for (int i = 0; i < allPoints.Count; i++)
			{
				Component val2 = allPoints[i];
				if (Object.op_Implicit((Object)(object)val2))
				{
					float num2 = Vector3.Distance(val2.transform.position, spawnPos);
					if (num2 < num)
					{
						num = num2;
						val = val2;
					}
				}
			}
			_spawnGateInstanceId = (Object.op_Implicit((Object)(object)val) ? ((Object)val).GetInstanceID() : 0);
		}

		public bool IsSpawnGateBlocking(List<Component> allPoints)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (Time.realtimeSinceStartup < _blockUntil)
			{
				return true;
			}
			if (!_spawnPos.HasValue)
			{
				return false;
			}
			if (allPoints != null && allPoints.Count > 0)
			{
				UpdateSpawnGateAlwaysNearest(allPoints, _spawnPos.Value);
			}
			Component spawnGatePoint = GetSpawnGatePoint(allPoints);
			if (!Object.op_Implicit((Object)(object)spawnGatePoint))
			{
				return false;
			}
			try
			{
				Type type = ((object)spawnGatePoint).GetType();
				FieldInfo field = type.GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo property = type.GetProperty("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object obj = null;
				if (property != null)
				{
					obj = property.GetValue(spawnGatePoint, null);
				}
				if (obj == null && field != null)
				{
					obj = field.GetValue(spawnGatePoint);
				}
				if (obj == null)
				{
					return true;
				}
				if (IsCompletedLikeState(obj.ToString() ?? ""))
				{
					return false;
				}
			}
			catch
			{
				return true;
			}
			return true;
		}

		public bool IsAnyExtractionPointActivating(List<Component> allPoints)
		{
			if (allPoints == null || allPoints.Count == 0)
			{
				return false;
			}
			for (int i = 0; i < allPoints.Count; i++)
			{
				Component val = allPoints[i];
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				try
				{
					Type type = ((object)val).GetType();
					FieldInfo field = type.GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					PropertyInfo property = type.GetProperty("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					object obj = null;
					if (property != null)
					{
						obj = property.GetValue(val, null);
					}
					if (obj == null && field != null)
					{
						obj = field.GetValue(val);
					}
					if (obj != null)
					{
						string text = obj.ToString() ?? "";
						if (text.Length != 0 && !IsIdleLikeState(text) && !IsCompletedLikeState(text))
						{
							return true;
						}
					}
				}
				catch
				{
					return true;
				}
			}
			return false;
		}

		internal static bool IsIdleLikeState(string stateName)
		{
			if (string.IsNullOrEmpty(stateName))
			{
				return false;
			}
			return stateName.IndexOf("Idle", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		internal static bool IsCompletedLikeState(string stateName)
		{
			if (string.IsNullOrEmpty(stateName))
			{
				return false;
			}
			string text = stateName.ToLowerInvariant();
			if (!text.Contains("success") && !text.Contains("complete") && !text.Contains("submitted") && !text.Contains("finish"))
			{
				return text.Contains("done");
			}
			return true;
		}

		public string ReadStateName(Component ep)
		{
			if (!Object.op_Implicit((Object)(object)ep))
			{
				return "";
			}
			try
			{
				Type type = ((object)ep).GetType();
				FieldInfo field = type.GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo property = type.GetProperty("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object obj = null;
				if (property != null)
				{
					obj = property.GetValue(ep, null);
				}
				if (obj == null && field != null)
				{
					obj = field.GetValue(ep);
				}
				if (obj == null)
				{
					return "";
				}
				return obj.ToString() ?? "";
			}
			catch
			{
				return "";
			}
		}

		public List<Component> BuildStage1PlannedList(List<Component> allPoints, Vector3 spawnPos, Vector3 startPos, bool skipActivated)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			List<Component> list = new List<Component>();
			if (allPoints == null || allPoints.Count == 0)
			{
				return list;
			}
			List<Component> list2 = new List<Component>(allPoints.Count);
			for (int i = 0; i < allPoints.Count; i++)
			{
				Component val = allPoints[i];
				if (Object.op_Implicit((Object)(object)val) && (!skipActivated || !IsMarkedActivated(val)))
				{
					list2.Add(val);
				}
			}
			if (list2.Count == 0)
			{
				return list;
			}
			Component val2 = null;
			float num = float.MaxValue;
			for (int j = 0; j < list2.Count; j++)
			{
				float num2 = Vector3.Distance(list2[j].transform.position, spawnPos);
				if (num2 < num)
				{
					num = num2;
					val2 = list2[j];
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				if (!skipActivated || !IsMarkedActivated(val2))
				{
					list.Add(val2);
				}
				list2.Remove(val2);
			}
			if (list2.Count == 0)
			{
				return list;
			}
			int index = -1;
			float num3 = float.MaxValue;
			for (int k = 0; k < list2.Count; k++)
			{
				float num4 = Vector3.Distance(list2[k].transform.position, spawnPos);
				if (num4 < num3)
				{
					num3 = num4;
					index = k;
				}
			}
			Component item = list2[index];
			list2.RemoveAt(index);
			Vector3 val3 = startPos;
			while (list2.Count > 0)
			{
				int index2 = 0;
				float num5 = float.MaxValue;
				for (int l = 0; l < list2.Count; l++)
				{
					float num6 = Vector3.Distance(val3, list2[l].transform.position);
					if (num6 < num5)
					{
						num5 = num6;
						index2 = l;
					}
				}
				Component val4 = list2[index2];
				list2.RemoveAt(index2);
				list.Add(val4);
				val3 = val4.transform.position;
			}
			list.Add(item);
			return list;
		}
	}
}
namespace REPO_Active.Reflection
{
	public sealed class ExtractionPointInvoker
	{
		private readonly ManualLogSource _log;

		public bool Verbose { get; set; }

		public ExtractionPointInvoker(ManualLogSource log, bool verbose)
		{
			_log = log;
			Verbose = verbose;
		}

		public bool InvokeOnClick(Component ep)
		{
			if ((Object)(object)ep == (Object)null)
			{
				return false;
			}
			try
			{
				Type type = ((object)ep).GetType();
				MethodInfo method = type.GetMethod("OnClick", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					_log.LogWarning((object)("OnClick not found on " + type.FullName + ". (No activation performed)"));
					return false;
				}
				object[] array = BuildDefaultArgs(method);
				if (Verbose)
				{
					_log.LogInfo((object)$"Invoke: {type.Name}.OnClick({FormatSig(method)}) argsLen={((array != null) ? array.Length : 0)}");
				}
				method.Invoke(ep, array);
				return true;
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"InvokeOnClick failed: {arg}");
				return false;
			}
		}

		private static object[]? BuildDefaultArgs(MethodInfo mi)
		{
			try
			{
				ParameterInfo[] parameters = mi.GetParameters();
				if (parameters == null || parameters.Length == 0)
				{
					return null;
				}
				object[] array = new object[parameters.Length];
				for (int i = 0; i < parameters.Length; i++)
				{
					ParameterInfo parameterInfo = parameters[i];
					if (parameterInfo.HasDefaultValue)
					{
						array[i] = parameterInfo.DefaultValue;
						continue;
					}
					Type type = parameterInfo.ParameterType;
					if (type.IsByRef)
					{
						type = type.GetElementType() ?? type;
					}
					if (!type.IsValueType)
					{
						array[i] = null;
						continue;
					}
					try
					{
						array[i] = Activator.CreateInstance(type);
					}
					catch
					{
						array[i] = null;
					}
				}
				return array;
			}
			catch
			{
				return null;
			}
		}

		private static string FormatSig(MethodInfo mi)
		{
			try
			{
				ParameterInfo[] parameters = mi.GetParameters();
				return string.Join(",", parameters.Select((ParameterInfo x) => x.ParameterType.Name));
			}
			catch
			{
				return "";
			}
		}
	}
}