using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using AIGraph; using Agents; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Enemies; using HarmonyLib; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Zose_hostType6SpawnEnemyFix { [BepInPlugin("com.zose.hostType6SpawnEnemyFix", "Zose_hostType6SpawnEnemyFix", "1.0.0")] public class EntryPoint : BasePlugin { public static ManualLogSource? L; public override void Load() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown L = ((BasePlugin)this).Log; Harmony val = new Harmony("com.zose.hostType6SpawnEnemyFix"); try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); L.LogInfo((object)"Applying patches..."); val.PatchAll(executingAssembly); List list = val.GetPatchedMethods().ToList(); L.LogInfo((object)("Zose_hostType6SpawnEnemyFix patches applied count: " + list.Count)); if (list.Count == 0) { L.LogWarning((object)"NO PATCHES APPLIED! Attempting fallback manual patch of SpawnPatch..."); val.PatchAll(typeof(SpawnPatch)); list = val.GetPatchedMethods().ToList(); L.LogInfo((object)("Fallback patch count: " + list.Count)); } foreach (MethodBase item in list) { L.LogInfo((object)(" - Patch Applied: " + item.DeclaringType?.FullName + "." + item.Name)); } L.LogInfo((object)"Zose_hostType6SpawnEnemyFix init."); } catch (Exception ex) { L.LogError((object)("patch fail: " + ex.Message + "\n" + ex.StackTrace)); } } } public static class SpawnPatch { private class PlayerNodeHistory { public AIG_CourseNode? LastValidNode = null; public float LastValidDistance = -1f; public float LastValidTime = 0f; } public static string LastLockedPlayerName = "Unknown"; public static string LastEvaluationDebug = ""; private static Dictionary _playerHistory = new Dictionary(); [HarmonyPatch(typeof(SurvivalWave), "MastermindUpdate")] [HarmonyPrefix] public static void SurvivalWave_MastermindUpdate_Prefix(SurvivalWave __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (!((Object)(object)__instance != (Object)null) || (int)__instance.m_spawnType != 6 || __instance.m_courseNode == null) { return; } string debugPlayerName = "Unknown"; AIG_CourseNode nearestPlayerCourseNodeToElevator = GetNearestPlayerCourseNodeToElevator(__instance.m_courseNode, out debugPlayerName); if (nearestPlayerCourseNodeToElevator != null) { LastLockedPlayerName = debugPlayerName; if (__instance.m_courseNode.NodeID != nearestPlayerCourseNodeToElevator.NodeID) { __instance.m_courseNode = nearestPlayerCourseNodeToElevator; } } } private static string FormatNodeLocation(AIG_CourseNode node) { if (node == null) { return "NULL Node"; } string value = (((Object)(object)node.m_zone != (Object)null) ? node.m_zone.Alias.ToString() : "?"); string value2 = (((Object)(object)node.m_area != (Object)null) ? node.m_area.m_geoArea : "?"); return $"Zone_{value}_Area_{value2} (Node {node.NodeID})"; } [HarmonyPatch(typeof(EnemyGroup), "Spawn", new Type[] { typeof(Vector3), typeof(Quaternion), typeof(AIG_CourseNode), typeof(EnemyGroupType), typeof(eEnemyGroupSpawnType), typeof(uint), typeof(float), typeof(IReplicator), typeof(SurvivalWave) })] [HarmonyPrefix] public static void EnemyGroup_Spawn_Prefix(Vector3 position, AIG_CourseNode courseNode, SurvivalWave __8) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (!((Object)(object)__8 != (Object)null) || (int)__8.m_spawnType != 6) { return; } ManualLogSource l = EntryPoint.L; if (l != null) { bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(101, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TowardsPositionFix] NATIVE ENGINE Spawning Group... Final target room: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(FormatNodeLocation(courseNode)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" | Baseline Player: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(LastLockedPlayerName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" | Eval: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(LastEvaluationDebug); } l.LogInfo(val); } } private static AIG_CourseNode GetDimensionStartNode(AIG_CourseNode originalNode) { //IL_0002: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) eDimensionIndex val = (eDimensionIndex)0; if (originalNode != null && (Object)(object)originalNode.m_zone != (Object)null) { Dimension dimension = originalNode.m_zone.Dimension; if (dimension != null) { AIG_CourseNode startCourseNode = dimension.GetStartCourseNode(); if (startCourseNode != null) { return startCourseNode; } } val = originalNode.m_zone.DimensionIndex; } AIG_CourseNode val2 = null; Enumerator enumerator = AIG_CourseNode.s_allNodes.GetEnumerator(); while (enumerator.MoveNext()) { AIG_CourseNode current = enumerator.Current; if (current != null && (Object)(object)current.m_zone != (Object)null && current.m_zone.DimensionIndex == val && (val2 == null || current.m_zone.ID < val2.m_zone.ID)) { val2 = current; } } return val2; } private static AIG_CourseNode GetNearestPlayerCourseNodeToElevator(AIG_CourseNode originalNode, out string debugPlayerName) { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode result = null; float num = float.MaxValue; debugPlayerName = "Unknown"; string text = ""; AIG_CourseNode dimensionStartNode = GetDimensionStartNode(originalNode); if (dimensionStartNode == null || PlayerManager.PlayerAgentsInLevel == null) { LastEvaluationDebug = "[Error: dimensionStartNode or PlayerAgentsInLevel is null]"; return null; } eDimensionIndex? obj; if (originalNode == null) { obj = null; } else { LG_Zone zone = originalNode.m_zone; obj = ((zone != null) ? new eDimensionIndex?(zone.DimensionIndex) : null); } eDimensionIndex? val = obj; eDimensionIndex valueOrDefault = val.GetValueOrDefault(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive) { continue; } string text2 = "Unknown"; try { SNet_Player owner = current.Owner; text2 = ((owner != null) ? owner.NickName : null) ?? ((Object)current).name; } catch { } int instanceID = ((Object)current).GetInstanceID(); if (!_playerHistory.TryGetValue(instanceID, out PlayerNodeHistory value)) { value = new PlayerNodeHistory(); _playerHistory[instanceID] = value; } float num2 = -1f; if (((Agent)current).CourseNode != null && (Object)(object)((Agent)current).CourseNode.m_zone != (Object)null && ((Agent)current).CourseNode.m_zone.DimensionIndex == valueOrDefault) { num2 = AIG_CourseGraph.GetDistanceBetweenToNodes(((Agent)current).CourseNode, dimensionStartNode); } AIG_CourseNode val2 = null; float num3 = -1f; if (num2 >= 0f && num2 <= 9999f) { value.LastValidNode = ((Agent)current).CourseNode; value.LastValidDistance = num2; value.LastValidTime = Time.time; val2 = ((Agent)current).CourseNode; num3 = num2; } else if (value.LastValidNode != null && Time.time - value.LastValidTime <= 3f) { val2 = value.LastValidNode; num3 = value.LastValidDistance; } if (val2 == null || num3 < 0f || num3 > 9999f) { text += $"[{text2}:ERR(cur:{num2:F1}, age:{Time.time - value.LastValidTime:F1}s)] "; continue; } text += $"[{text2}:{num3:F1}Grids] "; if (num3 < num) { num = num3; result = val2; debugPlayerName = text2; } } LastEvaluationDebug = text; return result; } } }