Decompiled source of PathfindingLib v0.0.14

PathfindingLib.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using PathfindingLib.API;
using PathfindingLib.Patches;
using PathfindingLib.Patches.Native;
using PathfindingLib.Utilities;
using PathfindingLib.Utilities.Internal.IL;
using Unity.AI.Navigation;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using Unity.Jobs.LowLevel.Unsafe;
using Unity.Mathematics;
using Unity.Profiling;
using Unity.Profiling.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.AI;
using UnityEngine.Pool;
using UnityEngine.Scripting;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PathfindingLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PathfindingLib")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fedb984b-16ae-458c-b2cc-19590627c578")]
[assembly: AssemblyFileVersion("0.0.14")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.14.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
namespace PathfindingLib
{
	[BepInPlugin("Zaggy1024.PathfindingLib", "PathfindingLib", "0.0.14")]
	public class PathfindingLibPlugin : BaseUnityPlugin
	{
		public const string PluginName = "PathfindingLib";

		public const string PluginGUID = "Zaggy1024.PathfindingLib";

		public const string PluginVersion = "0.0.14";

		private readonly Harmony harmony = new Harmony("Zaggy1024.PathfindingLib");

		internal static PathfindingLibPlugin Instance { get; private set; }

		internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		public void Awake()
		{
			Instance = this;
			ApplyAllNativePatches();
			harmony.PatchAll(typeof(PatchNavMeshSurface));
		}

		private static ProcessModule GetUnityPlayerModule()
		{
			ProcessModuleCollection modules = Process.GetCurrentProcess().Modules;
			for (int i = 0; i < modules.Count; i++)
			{
				ProcessModule processModule = modules[i];
				if (processModule.ModuleName.Contains("UnityPlayer"))
				{
					return processModule;
				}
			}
			return null;
		}

		private static void ApplyAllNativePatches()
		{
			PatchApplyCarvingResults.Apply(GetUnityPlayerModule().BaseAddress);
		}
	}
}
namespace PathfindingLib.Utilities
{
	public static class AgentExtensions
	{
		public static Vector3 GetPathOrigin(this NavMeshAgent agent)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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)
			if (agent.isOnOffMeshLink)
			{
				OffMeshLinkData currentOffMeshLinkData = agent.currentOffMeshLinkData;
				return ((OffMeshLinkData)(ref currentOffMeshLinkData)).endPos;
			}
			return ((Component)agent).transform.position;
		}
	}
	public static class NavMeshQueryUtils
	{
		public const int RecommendedCornerCount = 128;

		private static float CrossMagnitude(float3 u, float3 v)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return u.z * v.x - u.x * v.z;
		}

		public static PathQueryStatus FindStraightPath(NavMeshQuery query, float3 startPos, float3 endPos, NativeSlice<PolygonId> path, int pathSize, NativeArray<NavMeshLocation> straightPath, out int straightPathCount)
		{
			//IL_0009: 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_0026: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00d2: 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)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			//IL_00c6: 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_00f5: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0116: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			straightPathCount = 0;
			if (((NavMeshQuery)(ref query)).IsValid(path[0]))
			{
				NavMeshLocation lastCorner = (straightPath[0] = ((NavMeshQuery)(ref query)).CreateLocation(float3.op_Implicit(startPos), path[0]));
				int num = 0;
				int n = 1;
				if (pathSize > 1)
				{
					Matrix4x4 val2 = ((NavMeshQuery)(ref query)).PolygonWorldToLocalMatrix(path[0]);
					Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint(float3.op_Implicit(startPos));
					Vector3 val4 = default(Vector3);
					((Vector3)(ref val4))..ctor(0f, 0f, 0f);
					Vector3 val5 = default(Vector3);
					((Vector3)(ref val5))..ctor(0f, 0f, 0f);
					int num2 = -1;
					int num3 = -1;
					Vector3 val8 = default(Vector3);
					Vector3 val7 = default(Vector3);
					for (int i = 1; i <= pathSize; i++)
					{
						Matrix4x4 val6 = ((NavMeshQuery)(ref query)).PolygonWorldToLocalMatrix(path[num]);
						if (i == pathSize)
						{
							val8 = (val7 = ((Matrix4x4)(ref val6)).MultiplyPoint(float3.op_Implicit(endPos)));
						}
						else
						{
							if (!((NavMeshQuery)(ref query)).GetPortalPoints(path[i - 1], path[i], ref val8, ref val7))
							{
								return (PathQueryStatus)int.MinValue;
							}
							val8 = ((Matrix4x4)(ref val6)).MultiplyPoint(val8);
							val7 = ((Matrix4x4)(ref val6)).MultiplyPoint(val7);
						}
						val8 -= val3;
						val7 -= val3;
						if (CrossMagnitude(float3.op_Implicit(val8), float3.op_Implicit(val7)) < 0f)
						{
							Vector3 val9 = val7;
							val7 = val8;
							val8 = val9;
						}
						if (CrossMagnitude(float3.op_Implicit(val4), float3.op_Implicit(val7)) < 0f)
						{
							Matrix4x4 val10 = ((NavMeshQuery)(ref query)).PolygonLocalToWorldMatrix(path[num]);
							Vector3 val11 = ((Matrix4x4)(ref val10)).MultiplyPoint(val3 + val4);
							RetracePortals(query, num, num2, path, ref n, float3.op_Implicit(val11), ref lastCorner, straightPath);
							if (n == straightPath.Length)
							{
								straightPathCount = n;
								return (PathQueryStatus)1073741856;
							}
							val3 = ((Matrix4x4)(ref val6)).MultiplyPoint(val11);
							((Vector3)(ref val4))..ctor(0f, 0f, 0f);
							((Vector3)(ref val5))..ctor(0f, 0f, 0f);
							i = (num = num2);
						}
						else if (CrossMagnitude(float3.op_Implicit(val5), float3.op_Implicit(val8)) > 0f)
						{
							Matrix4x4 val12 = ((NavMeshQuery)(ref query)).PolygonLocalToWorldMatrix(path[num]);
							Vector3 val13 = ((Matrix4x4)(ref val12)).MultiplyPoint(val3 + val5);
							RetracePortals(query, num, num3, path, ref n, float3.op_Implicit(val13), ref lastCorner, straightPath);
							if (n == straightPath.Length)
							{
								straightPathCount = n;
								return (PathQueryStatus)1073741856;
							}
							val3 = ((Matrix4x4)(ref val6)).MultiplyPoint(val13);
							((Vector3)(ref val4))..ctor(0f, 0f, 0f);
							((Vector3)(ref val5))..ctor(0f, 0f, 0f);
							i = (num = num3);
						}
						else
						{
							if (CrossMagnitude(float3.op_Implicit(val4), float3.op_Implicit(val8)) >= 0f)
							{
								val4 = val8;
								num2 = i;
							}
							if (CrossMagnitude(float3.op_Implicit(val5), float3.op_Implicit(val7)) <= 0f)
							{
								val5 = val7;
								num3 = i;
							}
						}
					}
				}
				if (n > 0 && ((NavMeshLocation)(ref lastCorner)).position == float3.op_Implicit(endPos))
				{
					n--;
				}
				RetracePortals(query, num, pathSize - 1, path, ref n, endPos, ref lastCorner, straightPath);
				if (n == straightPath.Length)
				{
					straightPathCount = n;
					return (PathQueryStatus)1073741904;
				}
				straightPathCount = n;
				return (PathQueryStatus)1073741824;
			}
			return (PathQueryStatus)int.MinValue;
		}

		private static void RetracePortals(NavMeshQuery query, int startIndex, int endIndex, NativeSlice<PolygonId> path, ref int n, float3 termPos, ref NavMeshLocation lastCorner, NativeArray<NavMeshLocation> straightPath)
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_00cb: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_003d: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			Vector3 val2 = default(Vector3);
			for (int i = startIndex; i < endIndex - 1; i++)
			{
				NavMeshPolyTypes polygonType = ((NavMeshQuery)(ref query)).GetPolygonType(path[i]);
				NavMeshPolyTypes polygonType2 = ((NavMeshQuery)(ref query)).GetPolygonType(path[i + 1]);
				if (polygonType != polygonType2)
				{
					((NavMeshQuery)(ref query)).GetPortalPoints(path[i], path[i + 1], ref val, ref val2);
					SegmentSegmentCPA(out var c, out var _, float3.op_Implicit(val), float3.op_Implicit(val2), float3.op_Implicit(((NavMeshLocation)(ref lastCorner)).position), termPos);
					lastCorner = ((NavMeshQuery)(ref query)).CreateLocation(float3.op_Implicit(c), path[i + 1]);
					straightPath[n] = lastCorner;
					if (++n == straightPath.Length)
					{
						return;
					}
				}
			}
			lastCorner = ((NavMeshQuery)(ref query)).CreateLocation(float3.op_Implicit(termPos), path[endIndex]);
			straightPath[n++] = lastCorner;
		}

		private static bool SegmentSegmentCPA(out float3 c0, out float3 c1, float3 p0, float3 p1, float3 q0, float3 q1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0009: 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_0010: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			float3 val = p1 - p0;
			float3 val2 = q1 - q0;
			float3 val3 = p0 - q0;
			float num = math.dot(val, val);
			float num2 = math.dot(val, val2);
			float num3 = math.dot(val2, val2);
			float num4 = math.dot(val, val3);
			float num5 = math.dot(val2, val3);
			float num6 = num * num3 - num2 * num2;
			float num7;
			float num8;
			if (num6 == 0f)
			{
				num7 = 0f;
				num8 = num4 / num2;
			}
			else
			{
				num7 = (num2 * num5 - num3 * num4) / (num * num3 - num2 * num2);
				num8 = (num * num5 - num2 * num4) / (num * num3 - num2 * num2);
			}
			c0 = math.lerp(p0, p1, num7);
			c1 = math.lerp(q0, q1, num8);
			return num6 != 0f;
		}
	}
	public struct NavMeshReadLocker : IDisposable
	{
		private bool locked;

		public NavMeshReadLocker()
		{
			locked = false;
			NavMeshLock.BeginRead();
			locked = true;
		}

		public void Yield()
		{
			NavMeshLock.YieldRead();
		}

		public void Dispose()
		{
			if (locked)
			{
				locked = false;
				NavMeshLock.EndRead();
			}
		}
	}
	public static class PathQueryStatusExtensions
	{
		public static PathQueryStatus GetResult(this PathQueryStatus status)
		{
			//IL_0000: 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)
			return (PathQueryStatus)(status & -16777216);
		}

		public static PathQueryStatus GetDetail(this PathQueryStatus status)
		{
			//IL_0000: 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)
			return (PathQueryStatus)(status & 0xFFFFFF);
		}
	}
	[IgnoredByDeepProfiler]
	[UsedByNativeCode]
	public struct TogglableProfilerAuto : IDisposable
	{
		[NativeDisableUnsafePtrRestriction]
		internal readonly IntPtr ptr;

		internal bool on;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public TogglableProfilerAuto(in ProfilerMarker marker)
		{
			ptr = marker.m_Ptr;
			on = true;
			ProfilerUnsafeUtility.BeginSample(ptr);
		}

		public void Pause()
		{
			if (on)
			{
				ProfilerUnsafeUtility.EndSample(ptr);
				on = false;
			}
		}

		public void Resume()
		{
			if (!on)
			{
				on = true;
				ProfilerUnsafeUtility.BeginSample(ptr);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Dispose()
		{
			if (on)
			{
				ProfilerUnsafeUtility.EndSample(ptr);
				on = false;
			}
		}
	}
}
namespace PathfindingLib.Utilities.Internal.IL
{
	internal class ILInjector
	{
		private const string INVALID = "Injector is invalid";

		private List<CodeInstruction> instructions = instructions.ToList();

		private ILGenerator generator;

		private int index;

		private int matchEnd;

		public bool IsValid
		{
			get
			{
				if (instructions != null)
				{
					return IsIndexValid(index);
				}
				return false;
			}
		}

		public CodeInstruction Instruction
		{
			get
			{
				if (!IsIndexInRange(index))
				{
					return null;
				}
				return instructions[index];
			}
			set
			{
				if (!IsIndexInRange(index))
				{
					throw new InvalidOperationException($"Current index {index} is out of range of instruction count {instructions.Count}");
				}
				instructions[index] = value;
			}
		}

		public CodeInstruction LastMatchedInstruction
		{
			get
			{
				int num = matchEnd - 1;
				if (!IsIndexInRange(num))
				{
					return null;
				}
				return instructions[num];
			}
			set
			{
				int num = matchEnd - 1;
				if (!IsIndexInRange(num))
				{
					throw new InvalidOperationException($"Last matched index {index} is out of range of instruction count {instructions.Count}");
				}
				instructions[num] = value;
			}
		}

		public ICollection<CodeInstruction> Instructions => instructions.AsReadOnly();

		public ILInjector(IEnumerable<CodeInstruction> instructions, ILGenerator generator = null)
		{
			this.generator = generator;
			matchEnd = -1;
			base..ctor();
		}

		public ILInjector GoToStart()
		{
			matchEnd = index;
			index = 0;
			return this;
		}

		public ILInjector GoToEnd()
		{
			matchEnd = index;
			index = instructions.Count;
			return this;
		}

		public ILInjector Forward(int offset)
		{
			if (!IsValid)
			{
				return this;
			}
			matchEnd = index;
			index = Math.Clamp(index + offset, -1, instructions.Count);
			return this;
		}

		public ILInjector Back(int offset)
		{
			return Forward(-offset);
		}

		private void MarkInvalid()
		{
			index = -1;
			matchEnd = -1;
		}

		private void Search(bool forward, ILMatcher[] predicates)
		{
			if (!IsValid)
			{
				return;
			}
			int num = 1;
			if (!forward)
			{
				num = -1;
				index--;
			}
			while (forward ? (index < instructions.Count) : (index >= 0))
			{
				if (forward && index + predicates.Length > instructions.Count)
				{
					index = instructions.Count;
					break;
				}
				int i;
				for (i = 0; i < predicates.Length && predicates[i].Matches(instructions[index + i]); i++)
				{
				}
				if (i == predicates.Length)
				{
					matchEnd = index + i;
					return;
				}
				index += num;
			}
			MarkInvalid();
		}

		public ILInjector Find(params ILMatcher[] predicates)
		{
			Search(forward: true, predicates);
			return this;
		}

		public ILInjector ReverseFind(params ILMatcher[] predicates)
		{
			Search(forward: false, predicates);
			return this;
		}

		public ILInjector GoToPush(int popIndex)
		{
			if (!IsValid)
			{
				return this;
			}
			matchEnd = index;
			index--;
			int num = 0;
			while (index >= 0)
			{
				CodeInstruction instruction = instructions[index];
				num += instruction.PushCount();
				num -= instruction.PopCount();
				if (num > popIndex)
				{
					return this;
				}
				index--;
			}
			return this;
		}

		public ILInjector SkipBranch()
		{
			if (Instruction == null)
			{
				return this;
			}
			if (!(Instruction.operand is Label label))
			{
				throw new InvalidOperationException($"Current instruction is not a branch: {Instruction}");
			}
			return FindLabel(label);
		}

		public ILInjector FindLabel(Label label)
		{
			matchEnd = index + 1;
			for (index = 0; index < instructions.Count; index++)
			{
				if (instructions[index].labels.Contains(label))
				{
					return this;
				}
			}
			MarkInvalid();
			return this;
		}

		public ILInjector GoToMatchEnd()
		{
			index = matchEnd;
			return this;
		}

		public ILInjector GoToLastMatchedInstruction()
		{
			if (!IsIndexValid(matchEnd))
			{
				return this;
			}
			index = matchEnd - 1;
			return this;
		}

		private bool IsIndexValid(int index)
		{
			return index != -1;
		}

		private bool IsIndexInRange(int index)
		{
			if (index >= 0)
			{
				return index < instructions.Count;
			}
			return false;
		}

		public CodeInstruction GetRelativeInstruction(int offset)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			int num = index + offset;
			if (!IsIndexInRange(num))
			{
				throw new IndexOutOfRangeException($"Offset {offset} would read out of bounds at index {num}");
			}
			return instructions[num];
		}

		public void SetRelativeInstruction(int offset, CodeInstruction instruction)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			int num = index + offset;
			if (!IsIndexInRange(num))
			{
				throw new IndexOutOfRangeException($"Offset {offset} would write out of bounds at index {num}");
			}
			instructions[num] = instruction;
		}

		public IEnumerable<CodeInstruction> GetRelativeInstructions(int offset, int size)
		{
			for (int i = 0; i < size; i++)
			{
				yield return instructions[index + offset + i];
			}
		}

		public IEnumerable<CodeInstruction> GetRelativeInstructions(int size)
		{
			return GetRelativeInstructions(0, size);
		}

		private void GetLastMatchRangeAbsolute(out int start, out int end)
		{
			start = index;
			end = matchEnd;
			if (start > end)
			{
				int num = end;
				int num2 = start;
				start = num;
				end = num2;
			}
		}

		private void GetLastMatchRange(out int start, out int size)
		{
			GetLastMatchRangeAbsolute(out start, out var end);
			if (start < 0 || start >= instructions.Count)
			{
				throw new InvalidOperationException($"Last match range starts at invalid index {start}");
			}
			if (end < 0 || end > instructions.Count)
			{
				throw new InvalidOperationException($"Last match range ends at invalid index {end}");
			}
			size = end - start;
		}

		public List<CodeInstruction> GetLastMatch()
		{
			GetLastMatchRange(out var start, out var size);
			return instructions.GetRange(start, size);
		}

		public Label AddLabel()
		{
			if (generator == null)
			{
				throw new InvalidOperationException("No ILGenerator was provided");
			}
			Label label = generator.DefineLabel();
			Instruction.labels.Add(label);
			return label;
		}

		public ILInjector AddLabel(Label label)
		{
			Instruction.labels.Add(label);
			return this;
		}

		public ILInjector InsertInPlace(params CodeInstruction[] instructions)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			this.instructions.InsertRange(index, instructions);
			if (matchEnd >= index)
			{
				matchEnd += instructions.Length;
			}
			return this;
		}

		public ILInjector Insert(params CodeInstruction[] instructions)
		{
			InsertInPlace(instructions);
			index += instructions.Length;
			return this;
		}

		public ILInjector InsertInPlaceAfterBranch(params CodeInstruction[] instructions)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			List<Label> labels = Instruction.labels;
			this.instructions.InsertRange(index, instructions);
			Instruction.labels.AddRange(labels);
			labels.Clear();
			if (matchEnd >= index)
			{
				matchEnd += instructions.Length;
			}
			return this;
		}

		public ILInjector InsertAfterBranch(params CodeInstruction[] instructions)
		{
			InsertInPlaceAfterBranch(instructions);
			index += instructions.Length;
			return this;
		}

		public ILInjector RemoveAllPreviousInstructions()
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			instructions.RemoveRange(0, index);
			matchEnd -= index;
			if (matchEnd < 0)
			{
				matchEnd = 0;
			}
			index = 0;
			return this;
		}

		public ILInjector Remove(int count = 1)
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid");
			}
			instructions.RemoveRange(index, count);
			if (matchEnd > index)
			{
				matchEnd = Math.Max(index, matchEnd - count);
			}
			return this;
		}

		public ILInjector RemoveLastMatch()
		{
			GetLastMatchRange(out var start, out var size);
			instructions.RemoveRange(start, size);
			index = start;
			matchEnd = start;
			return this;
		}

		public ILInjector ReplaceLastMatch(params CodeInstruction[] instructions)
		{
			RemoveLastMatch();
			Insert(instructions);
			return this;
		}

		public List<CodeInstruction> ReleaseInstructions()
		{
			List<CodeInstruction> result = instructions;
			instructions = null;
			return result;
		}

		public ILInjector PrintContext(int context, string header = "")
		{
			if (!IsValid)
			{
				throw new InvalidOperationException("Injector is invalid (" + header + ")");
			}
			StringBuilder stringBuilder = new StringBuilder(header);
			if (header.Length > 0)
			{
				stringBuilder.Append(':');
			}
			stringBuilder.AppendLine();
			GetLastMatchRangeAbsolute(out var start, out var end);
			int num = Math.Min(end + 1 + context, instructions.Count);
			for (int i = Math.Max(start - context, 0); i < num; i++)
			{
				if (end == -1 && i == index)
				{
					stringBuilder.Append("╶> ");
				}
				else
				{
					if (i >= start && i < end)
					{
						stringBuilder.Append("│");
					}
					else
					{
						stringBuilder.Append(" ");
					}
					if (i == index)
					{
						stringBuilder.Append("╶> ");
					}
					else
					{
						stringBuilder.Append("   ");
					}
				}
				stringBuilder.AppendLine($"{i}: {instructions[i]}");
			}
			PathfindingLibPlugin.Instance.Logger.LogInfo((object)stringBuilder);
			return this;
		}

		public ILInjector PrintContext(string header = "")
		{
			return PrintContext(4, header);
		}
	}
	internal interface ILMatcher
	{
		bool Matches(CodeInstruction instruction);

		static NotMatcher Not(ILMatcher matcher)
		{
			return new NotMatcher(matcher);
		}

		static OpcodeMatcher Opcode(OpCode opcode)
		{
			return new OpcodeMatcher(opcode);
		}

		static OpcodesMatcher Opcodes(params OpCode[] opcodes)
		{
			return new OpcodesMatcher(opcodes);
		}

		static OpcodeOperandMatcher OpcodeOperand(OpCode opcode, object operand)
		{
			return new OpcodeOperandMatcher(opcode, operand);
		}

		static InstructionMatcher Instruction(CodeInstruction instruction)
		{
			return new InstructionMatcher(instruction);
		}

		static LdargMatcher Ldarg(int? arg = null)
		{
			return new LdargMatcher(arg);
		}

		static LdlocMatcher Ldloc(int? loc = null)
		{
			return new LdlocMatcher(loc);
		}

		static StlocMatcher Stloc(int? loc = null)
		{
			return new StlocMatcher(loc);
		}

		static LdcI32Matcher Ldc(int? value = null)
		{
			return new LdcI32Matcher(value);
		}

		static BranchMatcher Branch()
		{
			return new BranchMatcher();
		}

		static OpcodeOperandMatcher Ldfld(FieldInfo field)
		{
			if (field == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Ldfld() was null\n{new StackTrace()}");
			}
			return new OpcodeOperandMatcher(OpCodes.Ldfld, field);
		}

		static OpcodeOperandMatcher Ldsfld(FieldInfo field)
		{
			if (field == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Ldsfld() was null\n{new StackTrace()}");
			}
			return new OpcodeOperandMatcher(OpCodes.Ldsfld, field);
		}

		static OpcodeOperandMatcher Stfld(FieldInfo field)
		{
			if (field == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Stfld() was null\n{new StackTrace()}");
			}
			return new OpcodeOperandMatcher(OpCodes.Stfld, field);
		}

		static OpcodeOperandMatcher Stsfld(FieldInfo field)
		{
			if (field == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Stsfld() was null\n{new StackTrace()}");
			}
			return new OpcodeOperandMatcher(OpCodes.Stsfld, field);
		}

		static OpcodeOperandMatcher Callvirt(MethodBase method)
		{
			if (method == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Method passed to ILMatcher.Callvirt() was null\n{new StackTrace()}");
			}
			return OpcodeOperand(OpCodes.Callvirt, method);
		}

		static OpcodeOperandMatcher Call(MethodBase method)
		{
			if (method == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Method passed to ILMatcher.Call() was null\n{new StackTrace()}");
			}
			return OpcodeOperand(OpCodes.Call, method);
		}

		static PredicateMatcher Predicate(Func<CodeInstruction, bool> predicate)
		{
			return new PredicateMatcher(predicate);
		}

		static PredicateMatcher Predicate(Func<FieldInfo, bool> predicate)
		{
			return new PredicateMatcher((CodeInstruction insn) => insn.operand is FieldInfo arg && predicate(arg));
		}
	}
	internal class NotMatcher : ILMatcher
	{
		private readonly ILMatcher matcher;

		public NotMatcher(ILMatcher matcher)
		{
			this.matcher = matcher;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return !matcher.Matches(instruction);
		}
	}
	internal class OpcodeMatcher : ILMatcher
	{
		private readonly OpCode opcode;

		public OpcodeMatcher(OpCode opcode)
		{
			this.opcode = opcode;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return instruction.opcode == opcode;
		}
	}
	internal class OpcodesMatcher : ILMatcher
	{
		private readonly OpCode[] opcodes;

		public OpcodesMatcher(OpCode[] opcodes)
		{
			this.opcodes = opcodes;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return opcodes.Contains(instruction.opcode);
		}
	}
	internal class OpcodeOperandMatcher : ILMatcher
	{
		private readonly OpCode opcode;

		private readonly object operand;

		public OpcodeOperandMatcher(OpCode opcode, object operand)
		{
			this.opcode = opcode;
			this.operand = operand;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (instruction.opcode == opcode)
			{
				return instruction.operand == operand;
			}
			return false;
		}
	}
	internal class InstructionMatcher : ILMatcher
	{
		private readonly OpCode opcode = instruction.opcode;

		private readonly object operand = instruction.operand;

		private readonly Label[] labels = instruction.labels.ToArray();

		public InstructionMatcher(CodeInstruction instruction)
		{
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (instruction.opcode != opcode)
			{
				return false;
			}
			if (instruction.operand != operand)
			{
				return false;
			}
			if (instruction.labels.Count != labels.Length)
			{
				return false;
			}
			for (int i = 0; i < labels.Length; i++)
			{
				if (labels[i] != instruction.labels[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	internal class LdargMatcher : ILMatcher
	{
		private readonly int? arg;

		public LdargMatcher(int? arg)
		{
			this.arg = arg;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!arg.HasValue)
			{
				return instruction.GetLdargIndex().HasValue;
			}
			return instruction.GetLdargIndex() == arg;
		}
	}
	internal class LdlocMatcher : ILMatcher
	{
		private readonly int? loc;

		public LdlocMatcher(int? loc)
		{
			this.loc = loc;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!loc.HasValue)
			{
				return instruction.GetLdlocIndex().HasValue;
			}
			return instruction.GetLdlocIndex() == loc;
		}
	}
	internal class StlocMatcher : ILMatcher
	{
		private readonly int? loc;

		public StlocMatcher(int? loc)
		{
			this.loc = loc;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (!loc.HasValue)
			{
				return instruction.GetStlocIndex().HasValue;
			}
			return instruction.GetStlocIndex() == loc;
		}
	}
	internal class LdcI32Matcher : ILMatcher
	{
		private readonly int? value;

		public LdcI32Matcher(int? value)
		{
			this.value = value;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			if (value.HasValue || !instruction.GetLdcI32().HasValue)
			{
				return instruction.GetLdcI32() == value;
			}
			return true;
		}
	}
	internal class BranchMatcher : ILMatcher
	{
		public bool Matches(CodeInstruction instruction)
		{
			Label? label = default(Label?);
			return CodeInstructionExtensions.Branches(instruction, ref label);
		}
	}
	internal class PredicateMatcher : ILMatcher
	{
		private readonly Func<CodeInstruction, bool> predicate;

		public PredicateMatcher(Func<CodeInstruction, bool> predicate)
		{
			this.predicate = predicate;
			base..ctor();
		}

		public bool Matches(CodeInstruction instruction)
		{
			return predicate(instruction);
		}
	}
	internal static class InstructionUtilities
	{
		public static CodeInstruction MakeLdarg(int index)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (index < 256)
			{
				return (CodeInstruction)(index switch
				{
					0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 
					1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 
					2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 
					3 => (object)new CodeInstruction(OpCodes.Ldarg_3, (object)null), 
					_ => (object)new CodeInstruction(OpCodes.Ldarg_S, (object)index), 
				});
			}
			return new CodeInstruction(OpCodes.Ldarg, (object)index);
		}

		public static int PopCount(this CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt)
			{
				MethodInfo obj = (MethodInfo)instruction.operand;
				int num = obj.GetParameters().Length;
				if (!obj.IsStatic)
				{
					num++;
				}
				return num;
			}
			if (instruction.opcode == OpCodes.Ret)
			{
				return 1;
			}
			return instruction.opcode.StackBehaviourPop switch
			{
				StackBehaviour.Pop0 => 0, 
				StackBehaviour.Pop1 => 1, 
				StackBehaviour.Pop1_pop1 => 2, 
				StackBehaviour.Popi => 1, 
				StackBehaviour.Popi_pop1 => 2, 
				StackBehaviour.Popi_popi => 2, 
				StackBehaviour.Popi_popi8 => 2, 
				StackBehaviour.Popi_popi_popi => 3, 
				StackBehaviour.Popi_popr4 => 2, 
				StackBehaviour.Popi_popr8 => 2, 
				StackBehaviour.Popref => 1, 
				StackBehaviour.Popref_pop1 => 2, 
				StackBehaviour.Popref_popi => 2, 
				StackBehaviour.Popref_popi_popi => 3, 
				StackBehaviour.Popref_popi_popi8 => 3, 
				StackBehaviour.Popref_popi_popr4 => 3, 
				StackBehaviour.Popref_popi_popr8 => 3, 
				StackBehaviour.Popref_popi_popref => 3, 
				StackBehaviour.Varpop => throw new NotImplementedException($"Variable pop on non-call instruction '{instruction}'"), 
				StackBehaviour.Popref_popi_pop1 => 3, 
				_ => throw new NotSupportedException($"StackBehaviourPop of {instruction.opcode.StackBehaviourPop} was not a pop for instruction '{instruction}'"), 
			};
		}

		public static int PushCount(this CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt)
			{
				if (((MethodInfo)instruction.operand).ReturnType == typeof(void))
				{
					return 0;
				}
				return 1;
			}
			return instruction.opcode.StackBehaviourPush switch
			{
				StackBehaviour.Push0 => 0, 
				StackBehaviour.Push1 => 1, 
				StackBehaviour.Push1_push1 => 2, 
				StackBehaviour.Pushi => 1, 
				StackBehaviour.Pushi8 => 1, 
				StackBehaviour.Pushr4 => 1, 
				StackBehaviour.Pushr8 => 1, 
				StackBehaviour.Pushref => 1, 
				StackBehaviour.Varpush => throw new NotImplementedException($"Variable push on non-call instruction '{instruction}'"), 
				_ => throw new NotSupportedException($"StackBehaviourPush of {instruction.opcode.StackBehaviourPush} was not a push for instruction '{instruction}'"), 
			};
		}

		public static int? GetLdargIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldarg_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldarg_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldarg_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldarg_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldarg || opcode == OpCodes.Ldarg_S)
			{
				return instruction.operand as int?;
			}
			return null;
		}

		public static int? GetLdlocIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldloc_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldloc_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldloc_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldloc_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S)
			{
				return (instruction.operand as LocalBuilder)?.LocalIndex;
			}
			return null;
		}

		public static int? GetStlocIndex(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Stloc_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Stloc_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Stloc_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Stloc_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S)
			{
				return (instruction.operand as LocalBuilder)?.LocalIndex;
			}
			return null;
		}

		public static CodeInstruction LdlocToStloc(this CodeInstruction instruction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldloc_0)
			{
				return new CodeInstruction(OpCodes.Stloc_0, (object)null);
			}
			if (opcode == OpCodes.Ldloc_1)
			{
				return new CodeInstruction(OpCodes.Stloc_1, (object)null);
			}
			if (opcode == OpCodes.Ldloc_2)
			{
				return new CodeInstruction(OpCodes.Stloc_2, (object)null);
			}
			if (opcode == OpCodes.Ldloc_3)
			{
				return new CodeInstruction(OpCodes.Stloc_3, (object)null);
			}
			if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S)
			{
				return new CodeInstruction(OpCodes.Stloc, instruction.operand);
			}
			return null;
		}

		public static CodeInstruction StlocToLdloc(this CodeInstruction instruction)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Stloc_0)
			{
				return new CodeInstruction(OpCodes.Ldloc_0, (object)null);
			}
			if (opcode == OpCodes.Stloc_1)
			{
				return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
			}
			if (opcode == OpCodes.Stloc_2)
			{
				return new CodeInstruction(OpCodes.Ldloc_2, (object)null);
			}
			if (opcode == OpCodes.Stloc_3)
			{
				return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
			}
			if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S)
			{
				return new CodeInstruction(OpCodes.Ldloc, instruction.operand);
			}
			return null;
		}

		public static int? GetLdcI32(this CodeInstruction instruction)
		{
			OpCode opcode = instruction.opcode;
			if (opcode == OpCodes.Ldc_I4_M1)
			{
				return -1;
			}
			if (opcode == OpCodes.Ldc_I4_0)
			{
				return 0;
			}
			if (opcode == OpCodes.Ldc_I4_1)
			{
				return 1;
			}
			if (opcode == OpCodes.Ldc_I4_2)
			{
				return 2;
			}
			if (opcode == OpCodes.Ldc_I4_3)
			{
				return 3;
			}
			if (opcode == OpCodes.Ldc_I4_4)
			{
				return 4;
			}
			if (opcode == OpCodes.Ldc_I4_5)
			{
				return 5;
			}
			if (opcode == OpCodes.Ldc_I4_6)
			{
				return 6;
			}
			if (opcode == OpCodes.Ldc_I4_7)
			{
				return 7;
			}
			if (opcode == OpCodes.Ldc_I4_8)
			{
				return 8;
			}
			if (opcode == OpCodes.Ldc_I4_S)
			{
				return instruction.operand as sbyte?;
			}
			if (opcode == OpCodes.Ldc_I4)
			{
				return instruction.operand as int?;
			}
			return null;
		}
	}
}
namespace PathfindingLib.Patches
{
	[HarmonyPatch(typeof(NavMeshSurface))]
	internal static class PatchNavMeshSurface
	{
		private static readonly MethodInfo m_BeginNavMeshWrite = typeof(NavMeshLock).GetMethod("BeginWrite", BindingFlags.Static | BindingFlags.Public);

		private static readonly MethodInfo m_EndNavMeshWrite = typeof(NavMeshLock).GetMethod("EndWrite", BindingFlags.Static | BindingFlags.Public);

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(NavMeshSurface), "BuildNavMesh")]
		[HarmonyPatch(typeof(NavMeshSurface), "AddData")]
		[HarmonyPatch(typeof(NavMeshSurface), "RemoveData")]
		private static IEnumerable<CodeInstruction> LockWriteForDurationOfMethodTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			return new ILInjector(instructions).Insert(new CodeInstruction(OpCodes.Call, (object)m_BeginNavMeshWrite)).GoToEnd().ReverseFind(ILMatcher.Opcode(OpCodes.Ret))
				.Insert(new CodeInstruction(OpCodes.Call, (object)m_EndNavMeshWrite))
				.ReleaseInstructions();
		}

		[HarmonyTranspiler]
		[HarmonyPatch("UpdateDataIfTransformChanged")]
		private static IEnumerable<CodeInstruction> UpdateDataIfTransformChangedTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			ILInjector iLInjector = new ILInjector(instructions).Find(ILMatcher.Ldarg(0), ILMatcher.Call(typeof(NavMeshSurface).GetMethod("RemoveData")));
			if (!iLInjector.IsValid)
			{
				PathfindingLibPlugin.Instance.Logger.LogError((object)"Failed to find the call to RemoveData in NavMeshSurface.UpdateDataIfTransformChanged.");
				return instructions;
			}
			iLInjector.Insert(new CodeInstruction(OpCodes.Call, (object)m_BeginNavMeshWrite)).Find(ILMatcher.Ldarg(0), ILMatcher.Call(typeof(NavMeshSurface).GetMethod("AddData"))).GoToMatchEnd();
			if (!iLInjector.IsValid)
			{
				PathfindingLibPlugin.Instance.Logger.LogError((object)"Failed to find the call to AddData in NavMeshSurface.UpdateDataIfTransformChanged.");
				return instructions;
			}
			return iLInjector.Insert(new CodeInstruction(OpCodes.Call, (object)m_EndNavMeshWrite)).ReleaseInstructions();
		}

		[HarmonyTranspiler]
		[HarmonyPatch("UpdateNavMesh")]
		private static IEnumerable<CodeInstruction> UpdateNavMeshTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			return new ILInjector(instructions).Insert(new CodeInstruction(OpCodes.Call, (object)m_BeginNavMeshWrite)).Find(ILMatcher.Opcode(OpCodes.Ret)).Insert(new CodeInstruction(OpCodes.Dup, (object)null), new CodeInstruction(OpCodes.Call, (object)typeof(PatchNavMeshSurface).GetMethod("EndNavMeshWriteAtEndOfAsyncOperation", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[1] { typeof(AsyncOperation) }, null)))
				.ReleaseInstructions();
		}

		private static void EndNavMeshWriteAtEndOfAsyncOperation(AsyncOperation operation)
		{
			operation.completed += delegate
			{
				NavMeshLock.EndWrite();
			};
		}
	}
}
namespace PathfindingLib.Patches.Native
{
	internal static class PatchApplyCarvingResults
	{
		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
		private delegate void ApplyCarvingResultsDelegate(IntPtr thisNavMeshCarving);

		private static readonly bool debug = Debug.isDebugBuild;

		private static NativeDetour detour;

		private static ApplyCarvingResultsDelegate original;

		internal static void Apply(IntPtr baseAddress)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			ulong num = 10899072uL;
			if (debug)
			{
				num = 19667088uL;
			}
			IntPtr intPtr = (IntPtr)((long)baseAddress + (long)num);
			IntPtr functionPointerForDelegate = Marshal.GetFunctionPointerForDelegate<ApplyCarvingResultsDelegate>(ApplyCarvingResultsDetour);
			detour = new NativeDetour(intPtr, functionPointerForDelegate);
			original = detour.GenerateTrampoline<ApplyCarvingResultsDelegate>();
		}

		private unsafe static void ApplyCarvingResultsDetour(IntPtr thisNavMeshCarving)
		{
			ulong num = 0uL;
			ulong num2 = 0uL;
			if (debug)
			{
				num = *(ulong*)((long)thisNavMeshCarving + 56);
				num2 = *(ulong*)((long)thisNavMeshCarving + 64);
			}
			else
			{
				num = *(ulong*)((long)thisNavMeshCarving + 40);
				num2 = *(ulong*)((long)thisNavMeshCarving + 48);
			}
			bool num3 = num2 > num;
			if (num3)
			{
				NavMeshLock.BeginWrite();
			}
			original(thisNavMeshCarving);
			if (num3)
			{
				NavMeshLock.EndWrite();
			}
		}
	}
}
namespace PathfindingLib.Jobs
{
	public struct FindPathJob : IJob, IDisposable
	{
		private const float MaximumOriginDistance = 5f;

		private const float MaximumEndpointDistance = 1.5f;

		private const float MaximumEndpointDistanceSquared = 2.25f;

		[ReadOnly]
		[NativeDisableContainerSafetyRestriction]
		private NativeArray<NavMeshQuery> ThreadQueriesRef;

		[ReadOnly]
		private int AgentTypeID;

		[ReadOnly]
		private int AreaMask;

		[ReadOnly]
		private Vector3 Origin;

		[ReadOnly]
		private Vector3 Destination;

		[ReadOnly]
		[NativeSetThreadIndex]
		private int ThreadIndex;

		[WriteOnly]
		private NativeArray<PathQueryStatus> Status;

		[WriteOnly]
		private NativeArray<float> PathLength;

		public void Initialize(Vector3 origin, Vector3 destination, NavMeshAgent agent)
		{
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			ThreadQueriesRef = PathfindingJobSharedResources.GetPerThreadQueriesArray();
			AgentTypeID = agent.agentTypeID;
			AreaMask = agent.areaMask;
			Origin = origin;
			Destination = destination;
			ThreadIndex = -1;
			CreateArrays();
			Status[0] = (PathQueryStatus)536870912;
			PathLength[0] = float.MaxValue;
		}

		private void CreateArrays()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (Status.Length != 1)
			{
				Status = new NativeArray<PathQueryStatus>(1, (Allocator)4, (NativeArrayOptions)1);
				PathLength = new NativeArray<float>(1, (Allocator)4, (NativeArrayOptions)1);
			}
		}

		private void DisposeArrays()
		{
			Status.Dispose();
			PathLength.Dispose();
		}

		public void Execute()
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00d6: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Invalid comparison between Unknown and I4
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Invalid comparison between Unknown and I4
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			NavMeshQuery query = ThreadQueriesRef[ThreadIndex];
			using PathfindingLib.Utilities.NavMeshReadLocker navMeshReadLocker = new PathfindingLib.Utilities.NavMeshReadLocker();
			Vector3 val = new Vector3(5f, 5f, 5f);
			NavMeshLocation val2 = ((NavMeshQuery)(ref query)).MapLocation(Origin, val, AgentTypeID, AreaMask);
			if (!((NavMeshQuery)(ref query)).IsValid(((NavMeshLocation)(ref val2)).polygon))
			{
				Status[0] = (PathQueryStatus)int.MinValue;
				return;
			}
			Vector3 val3 = new Vector3(1.5f, 1.5f, 1.5f);
			NavMeshLocation val4 = ((NavMeshQuery)(ref query)).MapLocation(Destination, val3, AgentTypeID, AreaMask);
			if (!((NavMeshQuery)(ref query)).IsValid(val4))
			{
				Status[0] = (PathQueryStatus)int.MinValue;
				return;
			}
			PathQueryStatus status = ((NavMeshQuery)(ref query)).BeginFindPath(val2, val4, AreaMask, default(NativeArray<float>));
			if ((int)status.GetResult() == int.MinValue)
			{
				Status[0] = (PathQueryStatus)int.MinValue;
				return;
			}
			int num = default(int);
			while ((int)status.GetResult() == 536870912)
			{
				status = ((NavMeshQuery)(ref query)).UpdateFindPath(NavMeshLock.RecommendedUpdateFindPathIterationCount, ref num);
				navMeshReadLocker.Yield();
			}
			int num2 = default(int);
			status = ((NavMeshQuery)(ref query)).EndFindPath(ref num2);
			if ((int)status.GetResult() != 1073741824)
			{
				Status[0] = (PathQueryStatus)int.MinValue;
				return;
			}
			NativeArray<PolygonId> val5 = new NativeArray<PolygonId>(num2, (Allocator)2, (NativeArrayOptions)1);
			((NavMeshQuery)(ref query)).GetPathResult(NativeSlice<PolygonId>.op_Implicit(val5));
			NativeArray<NavMeshLocation> straightPath = new NativeArray<NavMeshLocation>(128, (Allocator)2, (NativeArrayOptions)1);
			try
			{
				int straightPathCount;
				PathQueryStatus val6 = NavMeshQueryUtils.FindStraightPath(query, float3.op_Implicit(Origin), float3.op_Implicit(Destination), NativeSlice<PolygonId>.op_Implicit(val5), num2, straightPath, out straightPathCount);
				val5.Dispose();
				navMeshReadLocker.Dispose();
				if ((int)val6.GetResult() != 1073741824)
				{
					Status[0] = val6;
					return;
				}
				NavMeshLocation val7 = straightPath[straightPathCount - 1];
				Vector3 val8 = ((NavMeshLocation)(ref val7)).position - Destination;
				if (((Vector3)(ref val8)).sqrMagnitude > 2.25f)
				{
					Status[0] = (PathQueryStatus)int.MinValue;
					return;
				}
				float num3 = 0f;
				for (int i = 1; i < straightPathCount; i++)
				{
					float num4 = num3;
					val7 = straightPath[i - 1];
					Vector3 position = ((NavMeshLocation)(ref val7)).position;
					val7 = straightPath[i];
					num3 = num4 + Vector3.Distance(position, ((NavMeshLocation)(ref val7)).position);
				}
				PathLength[0] = num3;
				Status[0] = (PathQueryStatus)1073741824;
			}
			finally
			{
				((IDisposable)straightPath).Dispose();
			}
		}

		public PathQueryStatus GetStatus()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Status[0];
		}

		public float GetPathLength()
		{
			return PathLength[0];
		}

		public void Dispose()
		{
			DisposeArrays();
		}
	}
	public class PooledFindPathJob
	{
		private FindPathJob job;

		public ref FindPathJob Job => ref job;
	}
	public static class JobPools
	{
		private static readonly ObjectPool<PooledFindPathJob> findPathPool = new ObjectPool<PooledFindPathJob>((Func<PooledFindPathJob>)(() => new PooledFindPathJob()), (Action<PooledFindPathJob>)null, (Action<PooledFindPathJob>)null, (Action<PooledFindPathJob>)delegate(PooledFindPathJob j)
		{
			j.Job.Dispose();
		}, true, 10, 10000);

		public static PooledFindPathJob GetFindPathJob()
		{
			return findPathPool.Get();
		}

		public static void ReleaseFindPathJob(PooledFindPathJob job)
		{
			if (job == null)
			{
				PathfindingLibPlugin.Instance.Logger.LogError((object)$"Attempted to free a null job\n{new StackTrace()}");
			}
			else
			{
				findPathPool.Release(job);
			}
		}
	}
	public static class PathfindingJobSharedResources
	{
		public const int MaximumPathPolygonCount = 4096;

		[NativeDisableContainerSafetyRestriction]
		private static NativeArray<NavMeshQuery> StaticThreadQueries;

		public static ref readonly NativeArray<NavMeshQuery> GetPerThreadQueriesArray()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			int threadIndexCount = JobsUtility.ThreadIndexCount;
			if (StaticThreadQueries.Length >= threadIndexCount)
			{
				return ref StaticThreadQueries;
			}
			Application.quitting -= DisposeQueries;
			NativeArray<NavMeshQuery> staticThreadQueries = default(NativeArray<NavMeshQuery>);
			staticThreadQueries..ctor(threadIndexCount, (Allocator)4, (NativeArrayOptions)1);
			for (int i = 0; i < StaticThreadQueries.Length; i++)
			{
				staticThreadQueries[i] = StaticThreadQueries[i];
			}
			for (int j = StaticThreadQueries.Length; j < threadIndexCount; j++)
			{
				staticThreadQueries[j] = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), (Allocator)4, 4096);
			}
			StaticThreadQueries.Dispose();
			StaticThreadQueries = staticThreadQueries;
			Application.quitting += DisposeQueries;
			return ref StaticThreadQueries;
		}

		private static void DisposeQueries()
		{
			//IL_0005: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<NavMeshQuery> enumerator = StaticThreadQueries.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					NavMeshQuery current = enumerator.Current;
					((NavMeshQuery)(ref current)).Dispose();
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			StaticThreadQueries.Dispose();
			Application.quitting -= DisposeQueries;
		}
	}
}
namespace PathfindingLib.API
{
	public static class NavMeshLock
	{
		private const int recommendedSliceCount = 128;

		[ThreadStatic]
		private static int threadState = 0;

		private static readonly object conditionVariable = new object();

		private static int readersActive = 0;

		private static int writersWaiting = 0;

		private static bool writerActive = false;

		public static int RecommendedUpdateFindPathIterationCount => 128;

		public static void BeginWrite()
		{
			if (threadState < 0)
			{
				throw CreateAndPrintInvalidOperationException("Cannot begin a navmesh write while a read is ongoing.");
			}
			if (threadState++ > 0)
			{
				return;
			}
			lock (conditionVariable)
			{
				writersWaiting++;
				while (readersActive > 0 || writerActive)
				{
					Monitor.Wait(conditionVariable);
				}
				writersWaiting--;
				writerActive = true;
			}
		}

		public static void EndWrite()
		{
			if (threadState <= 0)
			{
				throw CreateAndPrintInvalidOperationException("A navmesh write has not been started.");
			}
			if (--threadState > 0)
			{
				return;
			}
			lock (conditionVariable)
			{
				if (!writerActive)
				{
					throw CreateAndPrintInvalidOperationException("EndWrite() was called without first calling BeginWrite.");
				}
				writerActive = false;
				Monitor.PulseAll(conditionVariable);
			}
		}

		public static void BeginRead()
		{
			if (threadState > 0)
			{
				throw CreateAndPrintInvalidOperationException("Cannot begin a navmesh read while a write is ongoing.");
			}
			if (threadState-- < 0)
			{
				return;
			}
			lock (conditionVariable)
			{
				while (writersWaiting > 0 || writerActive)
				{
					Monitor.Wait(conditionVariable);
				}
				readersActive++;
			}
		}

		public static void EndRead()
		{
			if (threadState >= 0)
			{
				throw CreateAndPrintInvalidOperationException("A navmesh read has not been started.");
			}
			if (++threadState < 0)
			{
				return;
			}
			lock (conditionVariable)
			{
				readersActive--;
				if (readersActive < 0)
				{
					throw CreateAndPrintInvalidOperationException("EndRead() was called more times than BeginRead.");
				}
				if (readersActive == 0)
				{
					Monitor.PulseAll(conditionVariable);
				}
			}
		}

		public static void YieldRead()
		{
			EndRead();
			BeginRead();
		}

		private static InvalidOperationException CreateAndPrintInvalidOperationException(string message)
		{
			PathfindingLibPlugin.Instance.Logger.LogError((object)message);
			PathfindingLibPlugin.Instance.Logger.LogError((object)"Check Unity's Player.log to see the exception's stack trace.");
			return new InvalidOperationException(message);
		}
	}
	[Obsolete("Use PathfindingLib.Utilities.NavMeshReadLocker")]
	internal class NavMeshReadLocker : IDisposable
	{
		private bool locked;

		public NavMeshReadLocker()
		{
			NavMeshLock.BeginRead();
			locked = true;
		}

		public void Yield()
		{
			NavMeshLock.YieldRead();
		}

		public void Dispose()
		{
			if (locked)
			{
				locked = false;
				NavMeshLock.EndRead();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}