using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using IL.RoR2; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using RoR2; using RoR2.Navigation; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NavYoink")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("NavYoink")] [assembly: AssemblyTitle("NavYoink")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ThinkInvisible.NavYoink; [BepInPlugin("com.ThinkInvisible.NavYoink", "NavYoink", "1.0.0")] public class NavYoinkPlugin : BaseUnityPlugin { public const string ModVer = "1.0.0"; public const string ModName = "NavYoink"; public const string ModGuid = "com.ThinkInvisible.NavYoink"; internal static ManualLogSource _logger; internal NavYoinkPlugin() { } public void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown _logger = ((BaseUnityPlugin)this).Logger; DirectorCore.TrySpawnObject += new Manipulator(IL_DCTrySpawnObject); OccupyNearbyNodes.OnSceneDirectorPrePopulateSceneServer += new hook_OnSceneDirectorPrePopulateSceneServer(OccupyNearbyNodes_OnSceneDirectorPrePopulateSceneServer); } private static void OccupyNearbyNodes_OnSceneDirectorPrePopulateSceneServer(orig_OnSceneDirectorPrePopulateSceneServer orig, SceneDirector sceneDirector) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(sceneDirector); NodeGraph nodeGraph = SceneInfo.instance.GetNodeGraph((GraphType)0); HashSet hashSet = new HashSet(); foreach (OccupyNearbyNodes instances in OccupyNearbyNodes.instancesList) { NodeOccupationInfo nodeOccupationInfo = ((Component)instances).GetComponent(); if (!Object.op_Implicit((Object)(object)nodeOccupationInfo)) { nodeOccupationInfo = ((Component)instances).gameObject.AddComponent(); } List list = nodeGraph.FindNodesInRange(((Component)instances).transform.position, 0f, instances.radius, (HullMask)0); foreach (NodeIndex item in list) { if (!hashSet.Contains(item)) { hashSet.Add(item); nodeOccupationInfo._indices.Add(new KeyValuePair(nodeGraph, item)); } } } } private static void IL_DCTrySpawnObject(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int graphind = -1; if (!val.TryGotoNext(new Func[2] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "GetNodeGraph"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref graphind) })) { _logger.LogError((object)"Failed to apply IL patch (DCTrySpawnObject => graphind), RemoveAllOccupiedNodes will not work for single objects"); return; } val.Index = 0; int instind = -1; if (!val.TryGotoNext(new Func[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "spawnedInstance"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref instind) })) { _logger.LogError((object)"Failed to apply IL patch (DCTrySpawnObject => instind), RemoveAllOccupiedNodes will not work for single objects"); return; } val.Index = 0; while (val.TryGotoNext(new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "AddOccupiedNode") })) { val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldloc, graphind); val.Emit(OpCodes.Ldloc, instind); val.EmitDelegate>((Action)delegate(NodeIndex ind, NodeGraph graph, GameObject res) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)res)) { NodeOccupationInfo nodeOccupationInfo = res.gameObject.GetComponent(); if (!Object.op_Implicit((Object)(object)nodeOccupationInfo)) { nodeOccupationInfo = res.gameObject.AddComponent(); } nodeOccupationInfo._indices.Add(new KeyValuePair(graph, ind)); } }); int index = val.Index; val.Index = index + 1; } } } public static class Extensions { public static bool RemoveOccupiedNode(this DirectorCore self, NodeGraph nodeGraph, NodeIndex nodeIndex) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) int num = self.occupiedNodes.Length; self.occupiedNodes = self.occupiedNodes.Where((NodeReference x) => (Object)(object)x.nodeGraph != (Object)(object)nodeGraph || x.nodeIndex != nodeIndex).ToArray(); if (num == self.occupiedNodes.Length) { NavYoinkPlugin._logger.LogWarning((object)"RemoveOccupiedNode was passed an already-removed or otherwise nonexistent node"); return false; } return true; } public static bool RemoveAllOccupiedNodes(this DirectorCore self, GameObject obj) { NodeOccupationInfo component = obj.GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return true; } component._indices.RemoveAll((KeyValuePair i) => self.RemoveOccupiedNode(i.Key, i.Value)); return component._indices.Count == 0; } public static void UpdateOccupiedNodesReference(this DirectorCore _, GameObject oldObj, GameObject newObj) { NodeOccupationInfo component = oldObj.GetComponent(); NodeOccupationInfo component2 = newObj.GetComponent(); if (Object.op_Implicit((Object)(object)component) && !Object.op_Implicit((Object)(object)component2)) { component2 = newObj.AddComponent(); component2._indices.AddRange(component._indices); } } } public class NodeOccupationInfo : MonoBehaviour { internal readonly List> _indices; public readonly ReadOnlyCollection> indices; public NodeOccupationInfo() { _indices = new List>(); indices = _indices.AsReadOnly(); } }