Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PathfindingLib v2.4.1
PathfindingLib.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; 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.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using PathfindingLib.API; using PathfindingLib.API.SmartPathfinding; using PathfindingLib.Components; using PathfindingLib.Data; using PathfindingLib.Jobs; using PathfindingLib.Patches; using PathfindingLib.Patches.Native; using PathfindingLib.Utilities; using PathfindingLib.Utilities.Collections; using PathfindingLib.Utilities.Internal.IL; using PathfindingLib.Utilities.Native; 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.Mathematics.Geometry; using Unity.Netcode; 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("2.4.1")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.1.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] internal sealed class IsUnmanagedAttribute : Attribute { } [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 PathfindingLib { [BepInPlugin("Zaggy1024.PathfindingLib", "PathfindingLib", "2.4.1")] public class PathfindingLibPlugin : BaseUnityPlugin { public const string PluginName = "PathfindingLib"; public const string PluginGUID = "Zaggy1024.PathfindingLib"; public const string PluginVersion = "2.4.1"; private readonly Harmony harmony = new Harmony("Zaggy1024.PathfindingLib"); internal ConfigEntry<bool> PatchOffMeshConnectionStutterStepping; internal static bool DisableOffMeshConnectionStutterSteppingPatches; internal static PathfindingLibPlugin Instance { get; private set; } internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; public void Awake() { //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_0093: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) Instance = this; PatchOffMeshConnectionStutterStepping = ((BaseUnityPlugin)this).Config.Bind<bool>("Vanilla Patches", "PatchOffMeshConnectionStutterStepping", true, "Whether to patch auto-updating OffMeshLinks and NavMeshLinks to avoid invalidating paths and causing AI to stutter-step."); ApplyAllNativePatches(); harmony.PatchAll(typeof(PatchNavMeshSurface)); harmony.PatchAll(typeof(PatchEntranceTeleport)); harmony.PatchAll(typeof(PatchMineshaftElevatorController)); if (PatchOffMeshConnectionStutterStepping.Value) { ApplyOffMeshConnectionStutterSteppingPatches(harmony); } GameObject val = new GameObject("SmartPathTaskDisposer"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<SmartPathTaskDisposer>(); } private static void ApplyAllNativePatches() { NativeFunctions.SetUpNativeMethodPointers(); NavMeshQueryUtils.SetUpNativeMethodPointers(); PatchNavMeshManagerUpdate.Apply(); PatchConnectUnconnectOffMeshConnection.Apply(); PatchApplyCarveResults.Apply(); PatchNavMeshAgent.Apply(); } private static void ApplyOffMeshConnectionStutterSteppingPatches(Harmony harmony) { harmony.PatchAll(typeof(PatchNavMeshLink)); PatchOffMeshLinkUpdatePositions.Apply(); } internal static void DisableOffMeshConnectionStutterSteppingPatchesThisRun() { Instance.Logger.LogError((object)"Disabling the stutter stepping patch for this run."); DisableOffMeshConnectionStutterSteppingPatches = true; } } } namespace PathfindingLib.Utilities { public static class AgentExtensions { public static Vector3 GetPathOrigin(this NavMeshAgent agent) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) IntPtr cachedPtr = ((Object)agent).GetCachedPtr(); return NativeFunctions.GetAgentPosition(cachedPtr); } public unsafe static void GetQueryFilter(this NavMeshAgent agent, out int agentTypeID, out int areaMask, out Span<float> costs) { agentTypeID = -1; areaMask = -1; costs = default(Span<float>); IntPtr cachedPtr = ((Object)agent).GetCachedPtr(); if (!(cachedPtr == IntPtr.Zero)) { QueryFilter* agentQueryFilter = NativeFunctions.GetAgentQueryFilter(cachedPtr); if (agentQueryFilter != null) { agentTypeID = (int)agentQueryFilter->AgentType; areaMask = (int)agentQueryFilter->AreaMask; costs = new Span<float>(UnsafeUtility.AddressOf<float>(ref agentQueryFilter->CostsStart), 32); } } } } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct NavMeshPathNative { public int offMeshLinkModCount; public int status; public IntPtr polygons; public unsafe fixed int padding[4]; public ulong size; public ulong capacity; public Vector3 sourcePosition; public Vector3 targetPosition; public unsafe Span<PolygonId> currentPolygons => new Span<PolygonId>(polygons.ToPointer(), (int)size); public override readonly string ToString() { //IL_003d: 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) return $"modcount {offMeshLinkModCount} status {status} polys {(ulong)(long)polygons:X16} source {sourcePosition} target {targetPosition} size {size} capacity {capacity}"; } public unsafe static NavMeshPathNative GetNativeData(NavMeshPath path) { return Unsafe.Read<NavMeshPathNative>(path.m_Ptr.ToPointer()); } } [Flags] public enum StraightPathFlags : byte { Start = 1, End = 2, OffMeshConnection = 4 } public static class NavMeshQueryUtils { [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate PathQueryStatus FindStraightPathDelegate(NavMeshQuery self, in Vector3 startPos, in Vector3 endPos, PolygonId* path, int pathSize, Vector3* straightPath, StraightPathFlags* straightPathFlags, PolygonId* straightPathRefs, ref int straightPathCount, int maxStraightPath); public const int RecommendedCornerCount = 128; private static FindStraightPathDelegate findStraightPathMethod; public static int RequiredCornerCount(int pathPolygonCount) { return pathPolygonCount + 2; } public static Vector3 GetQueryExtents(int agentTypeID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return NativeFunctions.GetQueryExtents(agentTypeID); } public unsafe static PathQueryStatus FindStraightPath(this NavMeshQuery query, in Vector3 startPos, in Vector3 endPos, in NativeSlice<PolygonId> path, int pathSize, in NativeArray<Vector3> straightPath, in NativeArray<StraightPathFlags> straightPathFlags, in NativeArray<PolygonId> straightPathRefs, out int straightPathCount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 //IL_00ae: 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_00e1: 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) if (path.Stride != UnsafeUtility.SizeOf<PolygonId>()) { throw new ArgumentException("Path slice must have a stride equal to the size of PolygonId."); } if (straightPathFlags.Length < straightPath.Length) { throw new ArgumentException("Straight path flags buffer is too small."); } if (straightPathRefs.Length < straightPath.Length) { throw new ArgumentException("Straight path refs buffer is too small."); } straightPathCount = 0; Vector3 endPos2 = default(Vector3); PathQueryStatus closestPointOnPoly = NavMeshQuery.GetClosestPointOnPoly(query.m_NavMeshQuery, path[pathSize - 1], endPos, ref endPos2); if ((int)closestPointOnPoly < 0) { return closestPointOnPoly; } return findStraightPathMethod(query, in startPos, in endPos2, path.GetPtr<PolygonId>(), pathSize, straightPath.GetPtr<Vector3>(), GetPtr(in straightPathFlags), straightPathRefs.GetPtr<PolygonId>(), ref straightPathCount, straightPath.Length); } public static PathQueryStatus FindStraightPath(this NavMeshQuery query, in Vector3 startPos, in Vector3 endPos, in NativeSlice<PolygonId> path, int pathSize, in NativeArray<Vector3> straightPath, out int straightPathCount) { //IL_0004: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) NativeArray<StraightPathFlags> straightPathFlags = default(NativeArray<StraightPathFlags>); straightPathFlags..ctor(straightPath.Length, (Allocator)2, (NativeArrayOptions)1); try { NativeArray<PolygonId> straightPathRefs = new NativeArray<PolygonId>(straightPath.Length, (Allocator)2, (NativeArrayOptions)1); try { return query.FindStraightPath(in startPos, in endPos, in path, pathSize, in straightPath, in straightPathFlags, in straightPathRefs, out straightPathCount); } finally { ((IDisposable)straightPathRefs).Dispose(); } } finally { ((IDisposable)straightPathFlags).Dispose(); } } [Obsolete("Use NativeArray<Vector3> for the straightPath parameter")] public static PathQueryStatus FindStraightPath(this NavMeshQuery query, float3 startPos, float3 endPos, NativeSlice<PolygonId> path, int pathSize, NativeArray<NavMeshLocation> straightPath, out int straightPathCount) { //IL_0019: 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_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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) NativeArray<Vector3> straightPath2 = default(NativeArray<Vector3>); straightPath2..ctor(straightPath.Length, (Allocator)2, (NativeArrayOptions)1); try { NativeArray<StraightPathFlags> straightPathFlags = new NativeArray<StraightPathFlags>(straightPath.Length, (Allocator)2, (NativeArrayOptions)1); try { NativeArray<PolygonId> straightPathRefs = new NativeArray<PolygonId>(straightPath.Length, (Allocator)2, (NativeArrayOptions)1); try { Vector3 startPos2 = float3.op_Implicit(startPos); Vector3 endPos2 = float3.op_Implicit(endPos); PathQueryStatus result = query.FindStraightPath(in startPos2, in endPos2, in path, pathSize, in straightPath2, in straightPathFlags, in straightPathRefs, out straightPathCount); for (int i = 0; i < straightPathCount; i++) { straightPath[i] = new NavMeshLocation(straightPath2[i], straightPathRefs[i]); } return result; } finally { ((IDisposable)straightPathRefs).Dispose(); } } finally { ((IDisposable)straightPathFlags).Dispose(); } } finally { ((IDisposable)straightPath2).Dispose(); } } internal static void SetUpNativeMethodPointers() { int num = 10997840; if (NativeHelpers.IsDebugBuild) { num = 19904400; } findStraightPathMethod = Marshal.GetDelegateForFunctionPointer<FindStraightPathDelegate>(NativeHelpers.BaseAddress + num); } private unsafe static T* GetPtr<T>(this in NativeArray<T> array) where T : unmanaged { return (T*)array.m_Buffer; } private unsafe static T* GetPtr<T>(this in NativeSlice<T> slice) where T : unmanaged { return (T*)slice.m_Buffer; } } 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.Native { internal static class NativeFunctions { [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate char* GetNameDelegate(IntPtr component); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr DerefPPtrDelegate(IntPtr thisPPtr); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate void GetPositionDelegate(IntPtr transform, Vector3* result); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate void GetQueryExtentsDelegate(IntPtr navMeshManager, Vector3* result, int agentTypeID); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate void GetLinkQueryExtentsDelegate(IntPtr navMeshManager, Vector3* result, int agentTypeID); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr GetAgentByRefDelegate(IntPtr crowdManager, ulong id); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr GetInternalAgentDelegate(IntPtr agent); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate QueryFilter* GetAgentFilterDelegate(IntPtr crowdManager, ulong id); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate QueryFilter* GetFilterDelegate(IntPtr agent); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate char* GrowStringDelegate(IntPtr str, ulong size); [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private unsafe delegate IntPtr* ScriptingWrapperForDelegate(IntPtr* result, IntPtr nativeObj); private static GetNameDelegate getNameMethod; private static DerefPPtrDelegate derefPPtrMethod; private static GetPositionDelegate getPositionMethod; private static GetQueryExtentsDelegate getQueryExtentsMethod; private static GetLinkQueryExtentsDelegate getLinkQueryExtentsMethod; private static GetAgentByRefDelegate getAgentByRefMethod; private static GetInternalAgentDelegate getInternalAgentMethod; private static GetAgentFilterDelegate getAgentFilterMethod; private static GetFilterDelegate getFilterMethod; private static GrowStringDelegate growStringMethod; private static ScriptingWrapperForDelegate scriptingWrapperForMethod; internal static void SetUpNativeMethodPointers() { SetUpGetName(); SetUpGetPPtr(); SetUpGetPosition(); SetUpGetQueryExtents(); SetUpGetLinkQueryExtents(); SetUpGetCrowdAgent(); SetUpGetAgentQueryFilter(); SetUpGrowString(); SetUpScriptingWrapperFor(); } private static void SetUpGetName() { int num = 3632432; if (NativeHelpers.IsDebugBuild) { num = 5559312; } getNameMethod = Marshal.GetDelegateForFunctionPointer<GetNameDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static string GetName(IntPtr component) { return Marshal.PtrToStringAnsi((IntPtr)getNameMethod(component)); } private static void SetUpGetPPtr() { int num = 1392096; if (NativeHelpers.IsDebugBuild) { num = 2281824; } derefPPtrMethod = Marshal.GetDelegateForFunctionPointer<DerefPPtrDelegate>(NativeHelpers.BaseAddress + num); } internal static IntPtr DerefPPtr(IntPtr pptr) { return derefPPtrMethod(pptr); } private static void SetUpGetPosition() { int num = 6790096; if (NativeHelpers.IsDebugBuild) { num = 13575728; } getPositionMethod = Marshal.GetDelegateForFunctionPointer<GetPositionDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static Vector3 GetPosition(IntPtr transform) { //IL_0002: 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) Vector3 result = default(Vector3); getPositionMethod(transform, &result); return result; } private static void SetUpGetQueryExtents() { int num = 10788400; if (NativeHelpers.IsDebugBuild) { num = 19691568; } getQueryExtentsMethod = Marshal.GetDelegateForFunctionPointer<GetQueryExtentsDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static Vector3 GetQueryExtents(int agentTypeID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) Vector3 zero = Vector3.zero; getQueryExtentsMethod(NativeHelpers.GetNavMeshManager(), &zero, agentTypeID); return zero; } private static void SetUpGetLinkQueryExtents() { int num = 10788752; if (NativeHelpers.IsDebugBuild) { num = 19690784; } getLinkQueryExtentsMethod = Marshal.GetDelegateForFunctionPointer<GetLinkQueryExtentsDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static Vector3 GetLinkQueryExtents(int agentTypeID) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) Vector3 zero = Vector3.zero; getLinkQueryExtentsMethod(NativeHelpers.GetNavMeshManager(), &zero, agentTypeID); return zero; } private static void SetUpGetCrowdAgent() { if (NativeHelpers.IsDebugBuild) { getAgentByRefMethod = Marshal.GetDelegateForFunctionPointer<GetAgentByRefDelegate>(NativeHelpers.BaseAddress + 19823696); } else { getInternalAgentMethod = Marshal.GetDelegateForFunctionPointer<GetInternalAgentDelegate>(NativeHelpers.BaseAddress + 10867344); } } private static IntPtr GetCrowdAgent(IntPtr agent) { if (getInternalAgentMethod != null) { return getInternalAgentMethod(agent); } return getAgentByRefMethod(NativeHelpers.GetCrowdManager(), NativeHelpers.GetAgentID(agent)); } internal unsafe static Vector3 GetAgentPosition(IntPtr agent) { //IL_0020: 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) IntPtr crowdAgent = GetCrowdAgent(agent); if (crowdAgent == IntPtr.Zero) { return Vector3.positiveInfinity; } return (Vector3)(*(void*)crowdAgent); } private static void SetUpGetAgentQueryFilter() { if (NativeHelpers.IsDebugBuild) { getAgentFilterMethod = Marshal.GetDelegateForFunctionPointer<GetAgentFilterDelegate>(NativeHelpers.BaseAddress + 19823776); } else { getFilterMethod = Marshal.GetDelegateForFunctionPointer<GetFilterDelegate>(NativeHelpers.BaseAddress + 10867200); } } internal unsafe static QueryFilter* GetAgentQueryFilter(IntPtr agent) { if (getFilterMethod != null) { return getFilterMethod(agent); } return getAgentFilterMethod(NativeHelpers.GetCrowdManager(), NativeHelpers.GetAgentID(agent)); } private static void SetUpGrowString() { int num = 1433136; if (NativeHelpers.IsDebugBuild) { num = 2304112; } growStringMethod = Marshal.GetDelegateForFunctionPointer<GrowStringDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static char* GrowString(IntPtr str, ulong size) { return growStringMethod(str, size); } private static void SetUpScriptingWrapperFor() { int num = 7924176; if (NativeHelpers.IsDebugBuild) { num = 16895344; } scriptingWrapperForMethod = Marshal.GetDelegateForFunctionPointer<ScriptingWrapperForDelegate>(NativeHelpers.BaseAddress + num); } internal unsafe static T ScriptingWrapperFor<T>(IntPtr nativeObj) { IntPtr zero = IntPtr.Zero; return Unsafe.Read<T>(scriptingWrapperForMethod(&zero, nativeObj)); } } internal static class NativeHelpers { [CompilerGenerated] private sealed class <GetAreaNames>d__12 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private IntPtr <nameAddress>5__2; private int <nameStride>5__3; private int <i>5__4; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAreaNames>d__12(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; GetNavMeshAreaNamesArray(out <nameAddress>5__2, out <nameStride>5__3); <i>5__4 = 0; break; case 1: <>1__state = -1; <nameAddress>5__2 += <nameStride>5__3; <i>5__4++; break; } if (<i>5__4 < 32) { <>2__current = GetBasicString(<nameAddress>5__2); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <GetAreaNames>d__12(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } internal static readonly IntPtr BaseAddress = GetUnityPlayerModule().BaseAddress; internal static readonly bool IsDebugBuild = Debug.isDebugBuild; 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; } internal unsafe static IntPtr GetNavMeshManager() { int num = 30629656; if (IsDebugBuild) { num = 55760608; } return *(IntPtr*)(void*)(BaseAddress + num); } internal unsafe static IntPtr GetNavMesh() { IntPtr navMeshManager = GetNavMeshManager(); if (IsDebugBuild) { return *(IntPtr*)(void*)(navMeshManager + 192); } return *(IntPtr*)(void*)(navMeshManager + 168); } internal unsafe static IntPtr GetCrowdManager() { IntPtr navMeshManager = GetNavMeshManager(); if (IsDebugBuild) { return *(IntPtr*)(void*)(navMeshManager + 168); } return *(IntPtr*)(void*)(navMeshManager + 144); } internal unsafe static IntPtr GetNavMeshProjectSettings() { int num = 30194280; if (IsDebugBuild) { num = 48269576; } return *(IntPtr*)(void*)(BaseAddress + num); } internal static void GetNavMeshAreaNamesArray(out IntPtr address, out int stride) { IntPtr navMeshProjectSettings = GetNavMeshProjectSettings(); if (IsDebugBuild) { address = navMeshProjectSettings + 72; stride = 56; } else { address = navMeshProjectSettings + 48; stride = 48; } } internal unsafe static ref FreeList<OffMeshConnection> GetOffMeshConnectionFreeList() { int num = 128; if (IsDebugBuild) { num = 136; } return ref *(FreeList<OffMeshConnection>*)(void*)(GetNavMesh() + num); } internal unsafe static int GetInstanceID(IntPtr obj) { if (Object.OffsetOfInstanceIDInCPlusPlusObject == -1) { Object.OffsetOfInstanceIDInCPlusPlusObject = Object.GetOffsetOfInstanceIDInCPlusPlusObject(); } return *(int*)(void*)(obj + Object.OffsetOfInstanceIDInCPlusPlusObject); } internal unsafe static ulong GetAgentID(IntPtr agent) { int num = 96; if (IsDebugBuild) { num = 120; } return *(ulong*)(void*)(agent + num); } internal unsafe static string GetBasicString(IntPtr ptr) { ref BasicStringFields reference = ref *(BasicStringFields*)(void*)ptr; byte* bytes; ulong val; if (reference.IsShortString) { bytes = (byte*)UnsafeUtility.AddressOf<BasicStringFields>(ref reference); val = (ulong)(24 - reference.ShortStringUnusedBytes); } else { bytes = reference.Data; val = reference.Length; } return Encoding.UTF8.GetString(bytes, (int)Math.Min(val, 2147483647uL)); } [IteratorStateMachine(typeof(<GetAreaNames>d__12))] internal static IEnumerable<string> GetAreaNames() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetAreaNames>d__12(-2); } internal unsafe static void SetBasicString(IntPtr ptr, string str) { ref BasicStringFields reference = ref *(BasicStringFields*)(void*)ptr; int byteCount = Encoding.UTF8.GetByteCount(str); char* pointer = NativeFunctions.GrowString(ptr, (ulong)byteCount); int bytes = Encoding.UTF8.GetBytes(str.AsSpan(), new Span<byte>(pointer, byteCount)); if (reference.IsShortString) { reference.ShortStringUnusedBytes = (byte)(24 - bytes); } else { reference.Length = (ulong)bytes; } } internal static void SetAreaName(int index, string name) { if (index < 0 || index >= 32) { throw new IndexOutOfRangeException($"Area index out of range: {index}"); } GetNavMeshAreaNamesArray(out var address, out var stride); SetBasicString(address + stride * index, name); } } internal static class NativeNavMeshUtils { [CompilerGenerated] private sealed class <GetOffMeshLinks>d__3 : IEnumerable<IntPtr>, IEnumerable, IEnumerator<IntPtr>, IEnumerator, IDisposable { private int <>1__state; private IntPtr <>2__current; private int <>l__initialThreadId; private IntPtr navMeshManager; public IntPtr <>3__navMeshManager; private IntPtr <links>5__2; private int <linkCount>5__3; private int <i>5__4; IntPtr IEnumerator<IntPtr>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetOffMeshLinks>d__3(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; GetOffMeshLinkList(navMeshManager, out <links>5__2, out <linkCount>5__3); if (<links>5__2 == IntPtr.Zero) { return false; } <i>5__4 = 0; break; case 1: <>1__state = -1; <i>5__4++; break; } if (<i>5__4 < <linkCount>5__3) { <>2__current = GetOffMeshLinkFromList(<links>5__2, <i>5__4); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<IntPtr> IEnumerable<IntPtr>.GetEnumerator() { <GetOffMeshLinks>d__3 <GetOffMeshLinks>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetOffMeshLinks>d__ = this; } else { <GetOffMeshLinks>d__ = new <GetOffMeshLinks>d__3(0); } <GetOffMeshLinks>d__.navMeshManager = <>3__navMeshManager; return <GetOffMeshLinks>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<IntPtr>)this).GetEnumerator(); } } internal unsafe static bool CarvingHasDataToApply(IntPtr navMeshCarving) { if (navMeshCarving == IntPtr.Zero) { return false; } ulong num = 0uL; ulong num2 = 0uL; if (NativeHelpers.IsDebugBuild) { num = *(ulong*)(void*)(navMeshCarving + 56); num2 = *(ulong*)(void*)(navMeshCarving + 64); } else { num = *(ulong*)((long)navMeshCarving + 40); num2 = *(ulong*)((long)navMeshCarving + 48); } return num2 > num; } private unsafe static void GetOffMeshLinkList(IntPtr navMeshManager, out IntPtr offMeshLinks, out int offMeshLinkCount) { if (NativeHelpers.IsDebugBuild) { offMeshLinks = *(IntPtr*)(void*)(navMeshManager + 112); offMeshLinkCount = *(int*)(void*)(navMeshManager + 136); } else { offMeshLinks = *(IntPtr*)(void*)(navMeshManager + 96); offMeshLinkCount = *(int*)(void*)(navMeshManager + 112); } } private unsafe static IntPtr GetOffMeshLinkFromList(IntPtr links, int index) { return *(IntPtr*)((byte*)(void*)links + (nint)index * (nint)sizeof(IntPtr)); } [IteratorStateMachine(typeof(<GetOffMeshLinks>d__3))] internal static IEnumerable<IntPtr> GetOffMeshLinks(IntPtr navMeshManager) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetOffMeshLinks>d__3(-2) { <>3__navMeshManager = navMeshManager }; } internal unsafe static ref OffMeshLinkFields GetOffMeshLinkFields(IntPtr offMeshLink) { int num = 64; if (NativeHelpers.IsDebugBuild) { num = 88; } return ref *(OffMeshLinkFields*)(void*)(offMeshLink + num); } internal unsafe static Vector3 GetOffMeshLinkEndPointPosition(NativeTransform* transform) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (transform == null) { return Vector3.positiveInfinity; } return NativeFunctions.GetPosition((IntPtr)transform); } internal unsafe static bool OffMeshLinkWillUpdate(IntPtr offMeshLink) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_004e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) ref OffMeshLinkFields offMeshLinkFields = ref GetOffMeshLinkFields(offMeshLink); NativeTransform* transform = Methods.Get(ref offMeshLinkFields.Start); NativeTransform* transform2 = Methods.Get(ref offMeshLinkFields.End); Vector3 offMeshLinkEndPointPosition = GetOffMeshLinkEndPointPosition(transform); Vector3 offMeshLinkEndPointPosition2 = GetOffMeshLinkEndPointPosition(transform2); if (!offMeshLinkFields.AutoUpdatePositions) { return false; } if (offMeshLinkFields.NeedsInitialUpdate) { return false; } float num = offMeshLinkFields.AutoUpdateDistance * offMeshLinkFields.AutoUpdateDistance; Vector3 val = offMeshLinkEndPointPosition - offMeshLinkFields.LastStartPosition; if (((Vector3)(ref val)).sqrMagnitude > num) { return true; } val = offMeshLinkEndPointPosition2 - offMeshLinkFields.LastEndPosition; if (((Vector3)(ref val)).sqrMagnitude > num) { return true; } return false; } internal unsafe static ref FreeList<NavMeshLinkRegistryEntry> GetNavMeshLinkRegistry() { int num = 128; if (NativeHelpers.IsDebugBuild) { num = 152; } return ref *(FreeList<NavMeshLinkRegistryEntry>*)(void*)(NativeHelpers.GetNavMeshManager() + num); } } internal struct PPtr<T> where T : unmanaged { public int Ptr; } internal struct FreeList<T> where T : unmanaged { public uint NextFree; public uint Capacity; public unsafe T* Elements; } [StructLayout(LayoutKind.Explicit)] internal struct NativeTransform { } [StructLayout(LayoutKind.Explicit)] internal struct QueryFilter { [FieldOffset(0)] internal float CostsStart; [FieldOffset(128)] internal uint AreaMask; [FieldOffset(132)] internal uint AgentType; } internal struct NavMeshLinkRegistryEntry { internal int UseCount; internal uint Next; internal ulong ConnectionID; } [StructLayout(LayoutKind.Explicit)] internal struct BasicStringFields { [FieldOffset(0)] internal unsafe byte* Data; [FieldOffset(8)] internal ulong Capacity; [FieldOffset(16)] internal ulong Length; [FieldOffset(24)] internal byte ShortStringUnusedBytes; [FieldOffset(32)] internal bool IsShortString; } internal static class Methods { [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static IntPtr GetPtr<T>(this ref PPtr<T> ptr) where T : unmanaged { return NativeFunctions.DerefPPtr((IntPtr)UnsafeUtility.AddressOf<PPtr<T>>(ref ptr)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static T* Get<T>(this ref PPtr<T> ptr) where T : unmanaged { return (T*)(void*)GetPtr(ref ptr); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static Vector3 GetPosition(this ref NativeTransform transform) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return NativeFunctions.GetPosition((IntPtr)UnsafeUtility.AddressOf<NativeTransform>(ref transform)); } } [StructLayout(LayoutKind.Explicit, Size = 208)] internal struct OffMeshConnection { [FieldOffset(0)] public int AgentTypeID; [FieldOffset(4)] public MinMaxAABB Bounds; [FieldOffset(32)] public OffMeshLinkEndPoint EndPointA; [FieldOffset(80)] public OffMeshLinkEndPoint EndPointB; [FieldOffset(128)] public Vector3 AxisX; [FieldOffset(140)] public Vector3 AxisY; [FieldOffset(152)] public Vector3 AxisZ; [FieldOffset(164)] public float Width; [FieldOffset(168)] public float CostModifier; [FieldOffset(172)] public bool Bidirectional; [FieldOffset(176)] public int AreaMask; [FieldOffset(180)] public byte Area; [FieldOffset(182)] public ushort LinkType; [FieldOffset(184)] public int UserID; [FieldOffset(188)] public int FirstLinkIndex; [FieldOffset(192)] public uint Salt; [FieldOffset(196)] public int Next; } [StructLayout(LayoutKind.Explicit, Size = 48)] internal struct OffMeshLinkEndPoint { [FieldOffset(0)] public Vector3 Pos; [FieldOffset(12)] public Vector3 MappedA; [FieldOffset(24)] public Vector3 MappedB; [FieldOffset(40)] public ulong TileRef; } [StructLayout(LayoutKind.Explicit)] internal ref struct OffMeshLinkFields { [FieldOffset(0)] public ulong ConnectionID; [FieldOffset(8)] public PPtr<NativeTransform> Start; [FieldOffset(12)] public PPtr<NativeTransform> End; [FieldOffset(16)] public Vector3 LastEndPosition; [FieldOffset(28)] public Vector3 LastStartPosition; [FieldOffset(40)] public float AutoUpdateDistance; [FieldOffset(44)] public float CostOverride; [FieldOffset(48)] public uint Area; [FieldOffset(52)] public int AgentTypeID; [FieldOffset(56)] public int ManagerLinkIndex; [FieldOffset(60)] public bool AutoUpdatePositions; [FieldOffset(61)] public bool NeedsInitialUpdate; [FieldOffset(62)] public bool Bidirectional; [FieldOffset(63)] public bool Activated; } } namespace PathfindingLib.Utilities.Internal.IL { internal class ILInjector { [CompilerGenerated] private sealed class <GetRelativeInstructions>d__34 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; public ILInjector <>4__this; private int offset; public int <>3__offset; private int size; public int <>3__size; private int <i>5__2; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRelativeInstructions>d__34(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ILInjector iLInjector = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < size) { <>2__current = iLInjector.instructions[iLInjector.index + offset + <i>5__2]; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <GetRelativeInstructions>d__34 <GetRelativeInstructions>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRelativeInstructions>d__ = this; } else { <GetRelativeInstructions>d__ = new <GetRelativeInstructions>d__34(0) { <>4__this = <>4__this }; } <GetRelativeInstructions>d__.offset = <>3__offset; <GetRelativeInstructions>d__.size = <>3__size; return <GetRelativeInstructions>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } private const string INVALID = "Injector is invalid"; private List<CodeInstruction> instructions = instructions.ToList(); private ILGenerator generator; private int index; private int matchEnd; public int Index { get { return index; } set { index = value; } } 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) { if (label == default(Label)) { return this; } matchEnd = index; 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 ILInjector 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; return this; } [IteratorStateMachine(typeof(<GetRelativeInstructions>d__34))] public IEnumerable<CodeInstruction> GetRelativeInstructions(int offset, int size) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRelativeInstructions>d__34(-2) { <>4__this = this, <>3__offset = offset, <>3__size = size }; } 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 ILInjector DefineLabel(out Label label) { if (generator == null) { throw new InvalidOperationException("No ILGenerator was provided"); } label = generator.DefineLabel(); return this; } public ILInjector AddLabel(out Label label) { DefineLabel(out label); return AddLabel(label); } public ILInjector AddLabel(Label label) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Instruction = new CodeInstruction(Instruction); 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) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } List<Label> labels = Instruction.labels; Instruction = new CodeInstruction(Instruction); Instruction.labels.Clear(); this.instructions.InsertRange(index, instructions); Instruction.labels.AddRange(labels); 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); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); index = start; matchEnd = start; instructions[start].labels.AddRange(labels); return this; } public ILInjector ReplaceLastMatch(params CodeInstruction[] replacementInstructions) { if (replacementInstructions.Length == 0) { throw new ArgumentException("Cannot replace a match with an empty array."); } GetLastMatchRange(out var start, out var size); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); instructions.InsertRange(start, replacementInstructions); index = start; matchEnd = start + replacementInstructions.Length; instructions[start].labels.AddRange(labels); 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); ILMatcher CaptureAs(out CodeInstruction variable) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown variable = new CodeInstruction(OpCodes.Nop, (object)null); return new InstructionCapturingMatcher(this, variable); } unsafe ILMatcher CaptureOperandAs<T>(out T operand) where T : unmanaged { operand = default(T); fixed (T* operand2 = &operand) { return new OperandCapturingMatcher<T>(this, operand2); } } ILMatcher Debug() { return new DebuggingMatcher(this); } static ILMatcher Not(ILMatcher matcher) { return new NotMatcher(matcher); } static ILMatcher Opcode(OpCode opcode) { return new OpcodeMatcher(opcode); } static ILMatcher Opcodes(params OpCode[] opcodes) { return new OpcodesMatcher(opcodes); } static ILMatcher OpcodeOperand(OpCode opcode, object operand) { return new OpcodeOperandMatcher(opcode, operand); } static ILMatcher Instruction(CodeInstruction instruction) { return new InstructionMatcher(instruction); } static ILMatcher Ldarg(int? arg = null) { return new LdargMatcher(arg); } static ILMatcher Ldloc(int? loc = null) { return new LdlocMatcher(loc); } static ILMatcher Stloc(int? loc = null) { return new StlocMatcher(loc); } static ILMatcher Ldc(int? value = null) { return new LdcI32Matcher(value); } static ILMatcher LdcF32(float? value = null) { return new LdcF32Matcher(value); } static ILMatcher Branch() { return new BranchMatcher(); } static ILMatcher Ldfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Ldfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldfld, field); } static ILMatcher Ldsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Ldsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldsfld, field); } static ILMatcher Stfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Stfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stfld, field); } static ILMatcher Stsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Field passed to ILMatcher.Stsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stsfld, field); } static ILMatcher Callvirt(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Method passed to ILMatcher.Callvirt() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Callvirt, method); } static ILMatcher Call(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { PathfindingLibPlugin.Instance.Logger.LogWarning((object)$"Method passed to ILMatcher.Call() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Call, method); } static ILMatcher Predicate(Func<CodeInstruction, bool> predicate) { return new PredicateMatcher(predicate); } static ILMatcher 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) { return instruction.GetLdcI32().HasValue; } return instruction.GetLdcI32() == value; } } internal class LdcF32Matcher : ILMatcher { private readonly float? value; public LdcF32Matcher(float? value) { this.value = value; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (instruction.opcode == OpCodes.Ldc_R4) { if (value.HasValue) { return (float)instruction.operand == value.Value; } return true; } return false; } } 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 class InstructionCapturingMatcher : ILMatcher { private readonly ILMatcher matcher; private readonly CodeInstruction variable; public InstructionCapturingMatcher(ILMatcher matcher, CodeInstruction variable) { this.matcher = matcher; this.variable = variable; base..ctor(); } public bool Matches(CodeInstruction instruction) { bool num = matcher.Matches(instruction); if (num) { variable.opcode = instruction.opcode; variable.operand = instruction.operand; variable.blocks = instruction.blocks.ToList(); variable.labels = instruction.labels.ToList(); } return num; } } internal class OperandCapturingMatcher<T> : ILMatcher where T : unmanaged { private readonly ILMatcher matcher; private unsafe readonly T* operand; public unsafe OperandCapturingMatcher(ILMatcher matcher, T* operand) { this.matcher = matcher; this.operand = operand; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { bool num = matcher.Matches(instruction); if (num) { *operand = (T)instruction.operand; } return num; } } internal class DebuggingMatcher : ILMatcher { private readonly ILMatcher matcher; public DebuggingMatcher(ILMatcher matcher) { this.matcher = matcher; base..ctor(); } public bool Matches(CodeInstruction instruction) { bool num = matcher.Matches(instruction); if (num) { PathfindingLibPlugin.Instance.Logger.LogInfo((object)$"{matcher} matched {instruction}"); } return num; } } 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 || instruction.opcode == OpCodes.Newobj) { MethodBase obj = (MethodBase)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 || instruction.opcode == OpCodes.Newobj) { if (instruction.operand is MethodInfo methodInfo && methodInfo.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.Utilities.Collections { internal struct NativeArrayBuilder<T> : IEnumerable<T>, IEnumerable, IDisposable where T : unmanaged { [CompilerGenerated] private sealed class <GetEnumerator>d__10 : IEnumerator<T>, IEnumerator, IDisposable { private int <>1__state; private T <>2__current; public NativeArrayBuilder<T> <>4__this; private int <i>5__2; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetEnumerator>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < <>4__this.size) { <>2__current = <>4__this.array[<i>5__2]; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <System-Collections-IEnumerable-GetEnumerator>d__11 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NativeArrayBuilder<T> <>4__this; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <System-Collections-IEnumerable-GetEnumerator>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < <>4__this.size) { <>2__current = <>4__this.array[<i>5__2]; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private NativeArray<T> array; private int size; public int Capacity { get { return array.Length; } set { //IL_0010: 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) NativeArray<T> val = default(NativeArray<T>); val..ctor(value, (Allocator)4, (NativeArrayOptions)1); array.CopyTo(val); array.Dispose(); array = val; } } public readonly int Count => size; public void Add(in T item) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (size >= Capacity) { int num; for (num = 8; num <= size; num <<= 1) { } Capacity = num; } array.GetRef<T>(size++) = item; } public void Clear() { size = 0; } public readonly NativeArray<T> Get() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return array; } [IteratorStateMachine(typeof(NativeArrayBuilder<>.<GetEnumerator>d__10))] public readonly IEnumerator<T> GetEnumerator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetEnumerator>d__10(0) { <>4__this = this }; } [IteratorStateMachine(typeof(NativeArrayBuilder<>.<System-Collections-IEnumerable-GetEnumerator>d__11))] readonly IEnumerator IEnumerable.GetEnumerator() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <System-Collections-IEnumerable-GetEnumerator>d__11(0) { <>4__this = this }; } public void Dispose() { array.Dispose(); } } internal static class NativeArrayExtensions { internal unsafe static ref T GetRef<T>(this NativeArray<T> array, int index) where T : unmanaged { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (index < 0) { throw new IndexOutOfRangeException("Index cannot be negative."); } if (index >= array.Length) { throw new IndexOutOfRangeException($"Index {index} is not within array length of {array.Length}."); } return ref *(T*)((byte*)array.m_Buffer + (nint)index * (nint)sizeof(T)); } internal unsafe static void SetAllElements<T>(this NativeArray<T> array, T value) where T : unmanaged { //IL_0000: Unknown result type (might be due to invalid IL or missing references) T* buffer = (T*)array.m_Buffer; int length = array.Length; for (int i = 0; i < length; i++) { buffer[i] = value; } } internal unsafe static void CopyFrom<T>(this NativeArray<T> to, Span<T> from) where T : struct { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (from.Length != 0) { UnsafeUtility.MemCpy(NativeArrayUnsafeUtility.GetUnsafePtr<T>(to), UnsafeUtility.AddressOf<T>(ref from[0]), (long)from.Length); } } } internal struct NativeHeapIndex { internal static readonly NativeHeapIndex Invalid = new NativeHeapIndex { TableIndex = -1 }; internal int TableIndex; internal readonly bool IsValid => TableIndex >= 0; } [NativeContainer] [DebuggerDisplay("Count = {Count}")] internal struct NativeHeap<T, U> : IDisposable where T : unmanaged where U : unmanaged, IComparer<T> { internal const int DEFAULT_CAPACITY = 128; private const int VALIDATION_ERROR_WRONG_INSTANCE = 1; private const int VALIDATION_ERROR_INVALID = 2; private const int VALIDATION_ERROR_REMOVED = 3; [NativeDisableUnsafePtrRestriction] private unsafe HeapData<T, U>* Data; private Allocator Allocator; internal unsafe int Capacity { get { return Data->Capacity; } set { //IL_000e: 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_00df: 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) TableValue* ptr = (TableValue*)UnsafeUtility.Malloc((long)(UnsafeUtility.SizeOf<TableValue>() * value), UnsafeUtility.AlignOf<TableValue>(), Allocator); HeapNode<T>* ptr2 = (HeapNode<T>*)UnsafeUtility.Malloc((long)(UnsafeUtility.SizeOf<HeapNode<T>>() * value), UnsafeUtility.AlignOf<HeapNode<T>>(), Allocator); int num = ((Data->Capacity < value) ? Data->Capacity : value); UnsafeUtility.MemCpy((void*)ptr, (void*)Data->Table, (long)(num * UnsafeUtility.SizeOf<TableValue>())); UnsafeUtility.MemCpy((void*)ptr2, (void*)Data->Heap, (long)(num * UnsafeUtility.SizeOf<HeapNode<T>>())); for (int i = 0; i < value - Data->Capacity; i++) { ptr2[i + Data->Capacity] = new HeapNode<T> { TableIndex = i + Data->Capacity }; } UnsafeUtility.Free((void*)Data->Table, Allocator); UnsafeUtility.Free((void*)Data->Heap, Allocator); Data->Table = ptr; Data->Heap = ptr2; Data->Capacity = value; } } internal unsafe int Count => Data->Count; internal unsafe U Comparator { get { return Data->Comparator; } set { Data->Comparator = value; } } internal NativeHeap(Allocator allocator, int initialCapacity = 128, U comparator = default(U)) : this(initialCapacity, comparator, allocator, 1) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) public unsafe void Dispose() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Data->Count = 0; Data->Capacity = 0; UnsafeUtility.Free((void*)Data->Heap, Allocator); UnsafeUtility.Free((void*)Data->Table, Allocator); UnsafeUtility.Free((void*)Data, Allocator); } internal unsafe void Clear() { Data->Count = 0; } internal bool IsValidIndex(NativeHeapIndex index) { return true; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] internal void AssertValidIndex(NativeHeapIndex index) { int num = 0; if (1 == 0) { switch (num) { case 1: throw new ArgumentException("The provided ItemHandle was not valid for this NativeHeap. It was taken from a different instance."); case 2: throw new ArgumentException("The provided ItemHandle was not valid for this NativeHeap."); case 3: throw new ArgumentException("The provided ItemHandle was not valid for this NativeHeap. The item it pointed to might have already been removed."); } } } internal T Peek() { if (!TryPeek(out var t)) { throw new InvalidOperationException("Cannot Peek NativeHeap when the count is zero."); } return t; } internal unsafe bool TryPeek(out T t) { if (Data->Count == 0) { t = default(T); return false; } t = Data->Heap->Item; return true; } internal T Pop() { if (!TryPop(out var t)) { throw new InvalidOperationException("Cannot Pop NativeHeap when the count is zero."); } return t; } internal unsafe bool TryPop(out T t) { if (Data->Count == 0) { t = default(T); return false; } HeapNode<T> heap = *Data->Heap; int num = --Data->Count; HeapNode<T> node = Data->Heap[num]; Data->Heap[num] = heap; InsertAndBubbleDown(node, 0); t = heap.Item; return true; } internal unsafe NativeHeapIndex Insert(in T t) { if (Data->Count == Data->Capacity) { Capacity *= 2; } HeapNode<T> node = Data->Heap[Data->Count]; node.Item = t; int insertIndex = Data->Count++; InsertAndBubbleUp(node, insertIndex); NativeHeapIndex result = default(NativeHeapIndex); result.TableIndex = node.TableIndex; return result; } internal unsafe T Remove(NativeHeapIndex index) { int heapIndex = Data->Table[index.TableIndex].HeapIndex; HeapNode<T> heapNode = Data->Heap[heapIndex]; HeapNode<T> node = Data->Heap[--Data->Count]; UnsafeUtility.WriteArrayElement<HeapNode<T>>((void*)Data->Heap, Data->Count, heapNode); if (heapIndex != 0) { int num = (heapIndex - 1) / 2; HeapNode<T> heapNode2 = Data->Heap[num]; if (Data->Comparator.Compare(node.Item, heapNode2.Item) < 0) { InsertAndBubbleUp(node, heapIndex); return heapNode.Item; } } InsertAndBubbleDown(node, heapIndex); return heapNode.Item; } internal unsafe T Get(NativeHeapIndex index) { int heapIndex = Data->Table[index.TableIndex].HeapIndex; return Data->Heap[heapIndex].Item; } private unsafe NativeHeap(int initialCapacity, U comparator, Allocator allocator, int disposeSentinelStackDepth) { //IL_000c: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) Data = (HeapData<T, U>*)UnsafeUtility.Malloc((long)UnsafeUtility.SizeOf<HeapData<T, U>>(), UnsafeUtility.AlignOf<HeapData<T, U>>(), allocator); Data->Heap = (HeapNode<T>*)UnsafeUtility.Malloc((long)(UnsafeUtility.SizeOf<HeapNode<T>>() * initialCapacity), UnsafeUtility.AlignOf<HeapNode<T>>(), allocator); Data->Table = (TableValue*)UnsafeUtility.Malloc((long)(UnsafeUtility.SizeOf<TableValue>() * initialCapacity), UnsafeUtility.AlignOf<TableValue>(), allocator); Allocator = allocator; for (int i = 0; i < initialCapacity; i++) { Data->Heap[i] = new HeapNode<T> { TableIndex = i }; } Data->Count = 0; Data->Capacity = initialCapacity; Data->Comparator = comparator; } private unsafe void InsertAndBubbleDown(HeapNode<T> node, int insertIndex) { while (true) { int num = insertIndex * 2 + 1; int num2 = insertIndex * 2 + 2; if (num >= Data->Count) { break; } if (num2 >= Data->Count || Data->Comparator.Compare(Data->Heap[num].Item, Data->Heap[num2].Item) <= 0) { HeapNode<T> heapNode = Data->Heap[num]; if (Data->Comparator.Compare(node.Item, heapNode.Item) <= 0) { break; } Data->Heap[insertIndex] = heapNode; Data->Table[heapNode.TableIndex].HeapIndex = insertIndex; insertIndex = num; } else { HeapNode<T> heapNode2 = Data->Heap[num2]; if (Data->Comparator.Compare(node.Item, heapNode2.Item) <= 0) { break; } Data->Heap[insertIndex] = heapNode2; Data->Table[heapNode2.TableIndex].HeapIndex = insertIndex; insertIndex = num2; } } Data->Heap[insertIndex] = node; Data->Table[node.TableIndex].HeapIndex = insertIndex; } private unsafe void InsertAndBubbleUp(HeapNode<T> node, int insertIndex) { while (insertIndex != 0) { int num = (insertIndex - 1) / 2; HeapNode<T> heapNode = Data->Heap[num]; if (Data->Comparator.Compare(heapNode.Item, node.Item) <= 0) { break; } Data->Heap[insertIndex] = heapNode; Data->Table[heapNode.TableIndex].HeapIndex = insertIndex; insertIndex = num; } Data->Heap[insertIndex] = node; Data->Table[node.TableIndex].HeapIndex = insertIndex; } [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] private void IsValidIndexInternal(NativeHeapIndex index, ref bool result, ref int errorCode) { } } internal struct TableValue { internal int HeapIndex; } internal struct HeapData<T, U> where T : unmanaged { internal int Count; internal int Capacity; internal unsafe HeapNode<T>* Heap; internal unsafe TableValue* Table; internal U Comparator; } internal struct HeapNode<T> where T : unmanaged { internal T Item; internal int TableIndex; } internal static class NativeListExtensions { internal static void Insert<T>(this ref UnsafeList<T> self, int index, T element) where T : unmanaged { self.InsertRangeWithBeginEnd(index, index + 1); self[index] = element; } public unsafe static int AddOrdered<T>(this ref UnsafeList<T> self, T item, IComparer<T> comparer) where T : unmanaged { int num = NativeSortExtension.BinarySearch<T, IComparer<T>>(self.Ptr, self.Length, item, comparer); if (num < 0) { num = ~num; } self.Insert(num, item); return num; } public static int FindIndex<T>(this in UnsafeList<T> self, Predicate<T> predicate) where T : unmanaged { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //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) for (int i = 0; i < self.Length; i++) { if (predicate(self[i])) { return i; } } return -1; } } } namespace PathfindingLib.Patches { internal static class PatchEntranceTeleport { internal static List<EntranceTeleport> allEntranceTeleports = new List<EntranceTeleport>(); [HarmonyPostfix] [HarmonyPatch(typeof(EntranceTeleport), "Awake")] private static void AwakePostfix(EntranceTeleport __instance) { allEntranceTeleports.Add(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(NetworkBehaviour), "OnDestroy")] private static void DestroyPostfix(NetworkBehaviour __instance) { EntranceTeleport val = (EntranceTeleport)(object)((__instance is EntranceTeleport) ? __instance : null); if (val != null) { allEntranceTeleports.Remove(val); SmartPathLinks.UnregisterEntranceTeleport(val); } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "SetExitIDs")] private static void SetExitIDsPostfix() { foreach (EntranceTeleport allEntranceTeleport in allEntranceTeleports) { if (!((Behaviour)allEntranceTeleport).isActiveAndEnabled) { continue; } foreach (EntranceTeleport allEntranceTeleport2 in allEntranceTeleports) { if (((Behaviour)allEntranceTeleport2).isActiveAndEnabled && allEntranceTeleport.entranceId == allEntranceTeleport2.entranceId && allEntranceTeleport.isEntranceToBuilding != allEntranceTeleport2.isEntranceToBuilding) { PathfindingLibPlugin.Instance.Logger.LogDebug((object)$"{allEntranceTeleport} ({((NetworkBehaviour)allEntranceTeleport).NetworkObjectId}) connects to {allEntranceTeleport2} ({((NetworkBehaviour)allEntranceTeleport2).NetworkObjectId})"); SmartPathLinks.RegisterEntranceTeleport(allEntranceTeleport, allEntranceTeleport2.entrancePoint); break; } } } } } [HarmonyPatch(typeof(MineshaftElevatorController))] internal static class PatchMineshaftElevatorController { [HarmonyPostfix] [HarmonyPatch("OnEnable")] private static void OnEnablePostfix(MineshaftElevatorController __instance) { MineshaftElevatorAdapter mineshaftElevatorAdapter = default(MineshaftElevatorAdapter); if (((Component)__instance).TryGetComponent<MineshaftElevatorAdapter>(ref mineshaftElevatorAdapter)) { ((Behaviour)mineshaftElevatorAdapter).enabled = true; } mineshaftElevatorAdapter = ((Component)__instance).gameObject.AddComponent<MineshaftElevatorAdapter>(); mineshaftElevatorAdapter.controller = __instance; } [HarmonyPostfix] [HarmonyPatch("OnDisable")] private static void OnDisablePostfix(MineshaftElevatorController __instance) { MineshaftElevatorAdapter mineshaftElevatorAdapter = default(MineshaftElevatorAdapter); if (((Component)__instance).TryGetComponent<MineshaftElevatorAdapter>(ref mineshaftElevatorAdapter)) { ((Behaviour)mineshaftElevatorAdapter).enabled = false; } } } [HarmonyPatch(typeof(NavMeshLink))] internal static class PatchNavMeshLink { private unsafe static bool TryUpdatingConnectionInPlace(NavMeshLink link) { //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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00c5: 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_00cf: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) if (PathfindingLibPlugin.DisableOffMeshConnectionStutterSteppingPatches) { return false; } IntPtr navMesh = NativeHelpers.GetNavMesh(); if (navMesh == IntPtr.Zero) { return false; } int id = ((NavMeshLinkInstance)(ref link.m_LinkInstance)).id; int num = id & 0xFFFF; ref FreeList<NavMeshLinkRegistryEntry> navMeshLinkRegistry = ref NativeNavMeshUtils.GetNavMeshLinkRegistry(); if (num >= navMeshLinkRegistry.Capacity) { return false; } ref NavMeshLinkRegistryEntry reference = ref navMeshLinkRegistry.Elements[num]; if (reference.ConnectionID == 0L) { return false; } int num2 = (id >> 16) & 0xFFFF; if (reference.UseCount != num2) { return false; } Vector3 position = ((Component)link).transform.position; Quaternion rotation = ((Component)link).transform.rotation; Matrix4x4 val = Matrix4x4.TRS(position, rotation, Vector3.one); Vector3 start = ((Matrix4x4)(ref val)).MultiplyPoint3x4(link.startPoint); Vector3 end = ((Matrix4x4)(ref val)).MultiplyPoint3x4(link.endPoint); Vector3 up = rotation * Vector3.up; uint num3 = (uint)(int)reference.ConnectionID & 0xFFFFu; uint num4 = (uint)(reference.ConnectionID >> 48); ref FreeList<OffMeshConnection> offMeshConnectionFreeList = ref NativeHelpers.GetOffMeshConnectionFreeList(); if (num3 >= offMeshConnectionFreeList.Capacity) { return false; } ref OffMeshConnection reference2 = ref offMeshConnectionFreeList.Elements[num3]; if (reference2.Salt != num4) { PathfindingLibPlugin.Instance.Logger.LogError((object)$"NavMeshLink {link}'s salt didn't match the value stored in the registry ({num4} != {reference2.Salt})."); PathfindingLibPlugin.DisableOffMeshConnectionStutterSteppingPatchesThisRun(); return false; } NavMeshLock.BeginWrite(); PatchConnectUnconnectOffMeshConnection.UnconnectOffMeshConnection(navMesh, num3); PatchOffMeshLinkUpdatePositions.UpdateConnection(ref reference2, start, end, up, link.width, link.costModifier, link.bidirectional, (byte)link.area, ((Behaviour)link).isActiveAndEnabled, ((Object)link).GetInstanceID(), link.agentTypeID); Vector3 linkQueryExtents = NativeFunctions.GetLinkQueryExtents(link.agentTypeID); PatchConnectUnconnectOffMeshConnection.ConnectOffMeshConnection(navMesh, num3, linkQueryExtents.x, linkQueryExtents.y); NavMeshLock.EndWrite(); link.m_LastPosition = position; link.m_LastRotation = rotation; return true; } [HarmonyPrefix] [HarmonyPatch("UpdateLink")] private static bool UpdateLinkPrefix(NavMeshLink __instance) { return !TryUpdatingConnectionInPlace(__instance); } } [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("UpdateDataIfTransformCh