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 LateLanding v1.0.1
plugins/LateLanding/aj.LateLanding.dll
Decompiled 16 hours 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.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using GameNetcodeStuff; using HarmonyLib; using LateLanding.Configuration; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("aj.LateLanding")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("LateLanding")] [assembly: AssemblyTitle("aj.LateLanding")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was created with the assistance of generative AI (code); see the README credits for which assets.")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 LateLanding { [HarmonyPatch] internal static class JoinGate { private static ulong? preparing; private static float preparingSince; private const float PreparingTimeout = 120f; private static bool? lobbyOpen; private static bool checkedOtherGates; internal static ulong? Preparing { get { return preparing; } set { preparing = value; preparingSince = Time.time; } } private static StartOfRound? Round => StartOfRound.Instance; internal static bool Landed { get { if ((Object)(object)Round != (Object)null && !Round.inShipPhase && Round.shipDoorsEnabled) { return !Round.shipIsLeaving; } return false; } } internal static bool CanJoinNow { get { StartOfRound round = Round; if ((Object)(object)round == (Object)null) { return true; } if (round.inShipPhase) { return !round.newGameIsLoading; } if (Plugin.BoundConfig.JoinWhileLanded.Value && Landed) { return !Preparing.HasValue; } return false; } } [HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")] [HarmonyPrefix] private static void OpenForApproval(out bool __state) { GameNetworkManager instance = GameNetworkManager.Instance; __state = instance.gameHasStarted && CanJoinNow; if (__state) { instance.gameHasStarted = false; } } [HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")] [HarmonyPostfix] private static void NoteLateJoiner(ConnectionApprovalRequest request, ConnectionApprovalResponse response, bool __state) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (__state && response.Approved && Landed) { Preparing = request.ClientNetworkId; Plugin.Logger.LogInfo((object)$"Late joiner {request.ClientNetworkId} approved while landed."); } } [HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")] [HarmonyFinalizer] private static void CloseAfterApproval(bool __state) { if (__state) { GameNetworkManager.Instance.gameHasStarted = true; } } [HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")] [HarmonyPrefix] private static bool KeepHostLobby() { if (!((Object)(object)NetworkManager.Singleton == (Object)null)) { return !NetworkManager.Singleton.IsServer; } return true; } [HarmonyPatch(typeof(QuickMenuManager), "DisableInviteFriendsButton")] [HarmonyPrefix] private static bool KeepInviteButton() { return false; } [HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")] [HarmonyPrefix] private static bool InviteAfterLanding() { if (!GameNetworkManager.Instance.gameHasStarted) { return true; } if (CanJoinNow) { GameNetworkManager.Instance.InviteFriendsUI(); } return false; } [HarmonyPatch(typeof(StartOfRound), "OnClientDisconnect")] [HarmonyPostfix] private static void JoinerLeft(ulong clientId) { if (Preparing == clientId) { Preparing = null; } } internal static void UpdateLobby() { if (preparing.HasValue && Time.time - preparingSince > 120f) { Plugin.Logger.LogWarning((object)$"Late joiner {preparing} never finished catching up; opening the gate again."); Preparing = null; } GameNetworkManager instance = GameNetworkManager.Instance; if (!((Object)(object)instance == (Object)null) && !instance.disableSteam && instance.currentLobby.HasValue && !((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsServer) { bool flag = CanJoinNow && instance.connectedPlayers < instance.maxAllowedPlayers; if (lobbyOpen != flag) { lobbyOpen = flag; instance.SetLobbyJoinable(flag); } } } internal static void Reset() { preparing = null; lobbyOpen = null; } internal static void WarnAboutOtherGates() { if (checkedOtherGates) { return; } checkedOtherGates = true; MethodInfo methodInfo = AccessTools.Method(typeof(GameNetworkManager), "ConnectionApproval", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(GameNetworkManager), "LeaveLobbyAtGameStart", (Type[])null, (Type[])null); HashSet<string> hashSet = new HashSet<string>(); MethodInfo[] array = new MethodInfo[2] { methodInfo, methodInfo2 }; foreach (MethodInfo methodInfo3 in array) { Patches val = ((methodInfo3 != null) ? Harmony.GetPatchInfo((MethodBase)methodInfo3) : null); if (val != null) { hashSet.UnionWith(val.Owners); } } hashSet.Remove("aj.LateLanding"); if (hashSet.Count > 0) { Plugin.Logger.LogWarning((object)("Other mods also change who may join (" + string.Join(", ", hashSet) + "). If late joins misbehave, try without them; two late-join mods at once will clash.")); } } } [HarmonyPatch] internal static class JoinMessageFix { internal class Kept { public float globalTime; public int[] weathers; public int[] sales; public TerminalNode[] decor; } [HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")] [HarmonyPrefix] private static void KeepRound(StartOfRound __instance, ulong clientId, out Kept? __state) { __state = null; if (!((NetworkBehaviour)__instance).IsServer && !__instance.inShipPhase && clientId != NetworkManager.Singleton.LocalClientId) { Terminal val = Object.FindObjectOfType<Terminal>(); __state = new Kept { globalTime = TimeOfDay.Instance.globalTime, weathers = __instance.levels.Select((SelectableLevel l) => (int)l.currentWeather).ToArray(), sales = (int[])val.itemSalesPercentages.Clone(), decor = val.ShipDecorSelection.ToArray() }; } } [HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")] [HarmonyPostfix] private static void RestoreRound(StartOfRound __instance, Kept? __state) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (__state != null) { TimeOfDay.Instance.globalTime = __state.globalTime; for (int i = 0; i < __instance.levels.Length; i++) { __instance.levels[i].currentWeather = (LevelWeatherType)__state.weathers[i]; } Terminal obj = Object.FindObjectOfType<Terminal>(); obj.itemSalesPercentages = __state.sales; obj.ShipDecorSelection.Clear(); obj.ShipDecorSelection.AddRange(__state.decor); HideSpace(__instance); __instance.SwitchMapMonitorPurpose(false); } if (GameNetworkManager.Instance.gameHasStarted) { RecountLiving(__instance); } KnowEveryone(__instance); } private static void KnowEveryone(StartOfRound round) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown int num = Mathf.Min(round.connectedPlayersAmount + 1, round.allPlayerScripts.Length); PumaAI[] array = Object.FindObjectsOfType<PumaAI>(); foreach (PumaAI val in array) { if (val.playerKnowledge != null && val.playerKnowledge.Length < num) { PumaPlayerKnowledge[] playerKnowledge = val.playerKnowledge; val.playerKnowledge = (PumaPlayerKnowledge[])(object)new PumaPlayerKnowledge[num]; for (int j = 0; j < num; j++) { val.playerKnowledge[j] = (PumaPlayerKnowledge)((j < playerKnowledge.Length && playerKnowledge[j] != null) ? ((object)playerKnowledge[j]) : ((object)new PumaPlayerKnowledge(round.allPlayerScripts[j]))); } } } } internal static void HideSpace(StartOfRound round) { if ((Object)(object)round.currentPlanetPrefab != (Object)null) { round.currentPlanetPrefab.SetActive(false); } ((Component)round.outerSpaceSunAnimator).gameObject.SetActive(false); } internal static void RecountLiving(StartOfRound round) { int num = 0; PlayerControllerB[] allPlayerScripts = round.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.isPlayerDead) { val.isPlayerControlled = false; } else if (val.isPlayerControlled) { num++; } } round.livingPlayers = num; } } [HarmonyPatch] internal static class LandingJournal { private enum Phase : byte { Generation, Setup, Spawn } private class Entry { public Phase phase; public float sentAt; public string message = ""; public ulong objectId; public ushort behaviour; public uint method; public byte[] payload; } private const float SpawnSetupSeconds = 3f; private const int MaxJournalBytes = 262144; private const string OwnMessages = "aj.LateLanding."; private static readonly FieldInfo ExecStage = AccessTools.Field(typeof(NetworkBehaviour), "__rpc_exec_stage"); private static readonly FieldInfo RpcTable = AccessTools.Field(typeof(NetworkBehaviour), "__rpc_func_table"); private static readonly MethodInfo InvokeNamed = AccessTools.Method(typeof(CustomMessagingManager), "InvokeNamedMessage", (Type[])null, (Type[])null); private static readonly HashSet<string> EveryoneTargets = new HashSet<string> { "EveryoneRpcTarget", "ClientsAndHostRpcTarget", "NotServerRpcTarget", "NotMeRpcTarget", "NotOwnerRpcTarget" }; private static readonly List<Entry> entries = new List<Entry>(); private static readonly Dictionary<ulong, float> spawnedAt = new Dictionary<ulong, float>(); private static readonly Dictionary<ulong, float> connectedAt = new Dictionary<ulong, float>(); private static readonly Dictionary<(Type, uint), bool> fromOtherMods = new Dictionary<(Type, uint), bool>(); private static bool generating; private static float setupEndsAt = -1f; private static int journalBytes; private static List<Entry> received = new List<Entry>(); private static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton != (Object)null) { return NetworkManager.Singleton.IsServer; } return false; } } private static Phase? LandingPhase { get { if (!generating) { if (!(Time.time < setupEndsAt)) { return null; } return Phase.Setup; } return Phase.Generation; } } private static bool Executing(NetworkBehaviour b) { return ExecStage.GetValue(b).ToString() == "Execute"; } [HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")] [HarmonyPrefix] private static void LandingStarts(RoundManager __instance) { if (!IsHost || Executing((NetworkBehaviour)(object)__instance)) { return; } entries.Clear(); journalBytes = 0; generating = true; setupEndsAt = -1f; Dictionary<ulong, NetworkObject> spawned = NetworkManager.Singleton.SpawnManager.SpawnedObjects; foreach (ulong item in spawnedAt.Keys.Where((ulong id) => !spawned.ContainsKey(id)).ToList()) { spawnedAt.Remove(item); } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")] [HarmonyPrefix] private static void SetupStarts(RoundManager __instance) { if (IsHost && generating && !Executing((NetworkBehaviour)(object)__instance)) { generating = false; setupEndsAt = Time.time + 9f; } } [HarmonyPatch(typeof(NetworkSpawnManager), "SpawnNetworkObjectLocallyCommon")] [HarmonyPostfix] private static void Spawned(NetworkObject networkObject) { if (IsHost) { spawnedAt[networkObject.NetworkObjectId] = Time.time; } } [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] [HarmonyPostfix] private static void Connected(ulong clientId) { if (IsHost) { connectedAt[clientId] = Time.time; } } [HarmonyPatch(typeof(NetworkBehaviour), "__endSendClientRpc")] [HarmonyPrefix] private static void ClientRpcGoesOut(NetworkBehaviour __instance, ref FastBufferWriter bufferWriter, uint rpcMethodId, ClientRpcParams clientRpcParams, RpcDelivery rpcDelivery) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: 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) if ((int)rpcDelivery != 1 && clientRpcParams.Send.TargetClientIds == null && !clientRpcParams.Send.TargetClientIdsNativeArray.HasValue) { Record(__instance, rpcMethodId, ref bufferWriter); } } [HarmonyPatch(typeof(NetworkBehaviour), "__endSendRpc")] [HarmonyPrefix] private static void RpcGoesOut(NetworkBehaviour __instance, ref FastBufferWriter bufferWriter, uint rpcMethodId, RpcParams rpcParams, SendTo defaultTarget, RpcDelivery rpcDelivery) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: 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_0010: Unknown result type (might be due to invalid IL or missing references) if ((int)rpcDelivery != 1 && ToEveryone(rpcParams.Send.Target, defaultTarget)) { Record(__instance, rpcMethodId, ref bufferWriter); } } private static bool ToEveryone(BaseRpcTarget? target, SendTo defaultTarget) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (target != null) { return EveryoneTargets.Contains(((object)target).GetType().Name); } if ((int)defaultTarget != 6 && (int)defaultTarget != 7 && (int)defaultTarget != 3 && (int)defaultTarget != 5) { return (int)defaultTarget == 1; } return true; } private static void Record(NetworkBehaviour b, uint method, ref FastBufferWriter payload) { if (!IsHost || !b.IsSpawned || journalBytes > 262144) { return; } Phase? phase = LandingPhase; if (!phase.HasValue) { if (!spawnedAt.TryGetValue(b.NetworkObjectId, out var value) || Time.time - value > 3f) { return; } phase = Phase.Spawn; } if (FromAnotherMod(((object)b).GetType(), method)) { byte[] array = ((FastBufferWriter)(ref payload)).ToArray(); journalBytes += array.Length + 24; entries.Add(new Entry { phase = phase.Value, sentAt = Time.time, objectId = b.NetworkObjectId, behaviour = b.NetworkBehaviourId, method = method, payload = array }); } } [HarmonyPatch(typeof(CustomMessagingManager), "SendNamedMessage", new Type[] { typeof(string), typeof(IReadOnlyList<ulong>), typeof(FastBufferWriter), typeof(NetworkDelivery) })] [HarmonyPrefix] private static void NamedMessageGoesOut(string messageName, IReadOnlyList<ulong> clientIds, FastBufferWriter messageStream, NetworkDelivery networkDelivery) { //IL_003c: 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_0041: Invalid comparison between Unknown and I4 Phase? landingPhase = LandingPhase; if (IsHost && landingPhase.HasValue && journalBytes <= 262144 && !messageName.StartsWith("aj.LateLanding.") && (int)networkDelivery != 0 && (int)networkDelivery != 1 && NetworkManager.Singleton.ConnectedClientsIds.Where((ulong id) => id != 0).All((ulong id) => clientIds.Contains(id))) { byte[] array = ((FastBufferWriter)(ref messageStream)).ToArray(); journalBytes += array.Length + messageName.Length + 24; entries.Add(new Entry { phase = landingPhase.Value, sentAt = Time.time, message = messageName, payload = array }); } } private static bool FromAnotherMod(Type type, uint method) { if (!fromOtherMods.TryGetValue((type, method), out var value)) { Assembly assembly = Handler(type, method)?.Method.DeclaringType?.Assembly; value = assembly != null && IsAnotherMod(assembly); fromOtherMods[(type, method)] = value; } return value; } private static bool IsAnotherMod(Assembly assembly) { string name = assembly.GetName().Name; if (assembly != typeof(LandingJournal).Assembly && name != "Assembly-CSharp" && name != "Assembly-CSharp-firstpass" && !name.StartsWith("Unity.")) { return !name.StartsWith("UnityEngine"); } return false; } private static Delegate? Handler(Type type, uint method) { if (!(RpcTable.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(type) || !(dictionary[type] is IDictionary dictionary2) || !dictionary2.Contains(method)) { return null; } return dictionary2[method] as Delegate; } internal static byte[] Describe(ulong joiner) { float value; float cutoff = (connectedAt.TryGetValue(joiner, out value) ? value : float.MaxValue); Dictionary<ulong, NetworkObject> spawned = NetworkManager.Singleton.SpawnManager.SpawnedObjects; List<Entry> list = entries.Where((Entry e) => e.sentAt < cutoff && (e.message.Length > 0 || spawned.ContainsKey(e.objectId))).ToList(); using MemoryStream memoryStream = new MemoryStream(); using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(list.Count); foreach (Entry item in list) { binaryWriter.Write((byte)item.phase); binaryWriter.Write(item.message); binaryWriter.Write(item.objectId); binaryWriter.Write(item.behaviour); binaryWriter.Write(item.method); binaryWriter.Write(item.payload.Length); binaryWriter.Write(item.payload); } } return memoryStream.ToArray(); } internal static void Read(byte[] journal) { received = new List<Entry>(); if (journal.Length == 0) { return; } using BinaryReader binaryReader = new BinaryReader(new MemoryStream(journal)); int num = binaryReader.ReadInt32(); for (int i = 0; i < num; i++) { Entry entry = new Entry { phase = (Phase)binaryReader.ReadByte(), message = binaryReader.ReadString(), objectId = binaryReader.ReadUInt64(), behaviour = binaryReader.ReadUInt16(), method = binaryReader.ReadUInt32() }; entry.payload = binaryReader.ReadBytes(binaryReader.ReadInt32()); received.Add(entry); } } internal static void ReplayGeneration() { Replay("while the facility was generated", (Entry e) => e.phase == Phase.Generation); } internal static void ReplaySetup() { Replay("while the moon was set up and as things spawned", (Entry e) => e.phase != Phase.Generation); } private static void Replay(string when, Func<Entry, bool> which) { List<Entry> list = received.Where(which).ToList(); if (list.Count == 0) { return; } List<string> ran = new List<string>(); foreach (Entry e in list) { MoonSnapshot.Safely($"another mod's message ({e.message}{e.objectId}/{e.method})", delegate { string text2 = Run(e); if (text2 != null) { ran.Add(text2); } }); } string text = string.Join(", ", from w in ran group w by w into g select (g.Count() <= 1) ? g.Key : $"{g.Key} x{g.Count()}"); Plugin.Logger.LogInfo((object)$"Replayed {ran.Count} of {list.Count} messages other mods sent {when}: {text}."); } private unsafe static string? Run(Entry e) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; FastBufferReader val = default(FastBufferReader); ((FastBufferReader)(ref val))..ctor(e.payload, (Allocator)2, -1, 0); try { if (e.message.Length > 0) { ulong? num = NamedHash(singleton, e.message); if (!num.HasValue) { return null; } InvokeNamed.Invoke(singleton.CustomMessagingManager, new object[4] { num.Value, 0uL, val, 0 }); return e.message; } if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(e.objectId, out var value)) { return null; } NetworkBehaviour networkBehaviourAtOrderIndex = value.GetNetworkBehaviourAtOrderIndex(e.behaviour); Delegate obj = (((Object)(object)networkBehaviourAtOrderIndex != (Object)null) ? Handler(((object)networkBehaviourAtOrderIndex).GetType(), e.method) : null); if ((object)obj == null) { return null; } obj.DynamicInvoke(networkBehaviourAtOrderIndex, val, (object)default(__RpcParams)); return ((object)networkBehaviourAtOrderIndex).GetType().Name; } finally { ((IDisposable)(*(FastBufferReader*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static ulong? NamedHash(NetworkManager nm, string name) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 bool flag = (int)nm.NetworkConfig.RpcHashSize == 0; foreach (KeyValuePair<ulong, string> item in Traverse.Create((object)nm.CustomMessagingManager).Field(flag ? "m_MessageHandlerNameLookup32" : "m_MessageHandlerNameLookup64").GetValue<Dictionary<ulong, string>>()) { if (item.Value == name) { return item.Key; } } return null; } internal static void Reset() { received.Clear(); entries.Clear(); spawnedAt.Clear(); connectedAt.Clear(); generating = false; setupEndsAt = -1f; journalBytes = 0; } } [HarmonyPatch] internal static class LateJoiner { private static Vector3 shipSpot; private const float ScrapRecheckDelay = 4f; private static float recheckScrapAt = -1f; internal static bool Waiting { get; private set; } [HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")] [HarmonyPostfix] private static void AskHost(StartOfRound __instance, ulong clientId) { if (!((NetworkBehaviour)__instance).IsServer && clientId == NetworkManager.Singleton.LocalClientId) { LateNet.SayHello(); } } internal static void ApplyLanded(LateNet.LevelInfo info) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)instance == (Object)null || (Object)(object)localPlayerController == (Object)null) { return; } Terminal val = Object.FindObjectOfType<Terminal>(); for (int i = 0; i < instance.levels.Length && i < info.weathers.Length; i++) { instance.levels[i].currentWeather = (LevelWeatherType)info.weathers[i]; } val.itemSalesPercentages = info.sales; List<UnlockableItem> unlockables = instance.unlockablesList.unlockables; val.ShipDecorSelection.Clear(); val.ShipDecorSelection.AddRange(from index in info.decor where index >= 0 && index < unlockables.Count select unlockables[index].shopSelectionNode); GameNetworkManager.Instance.gameHasStarted = true; instance.inShipPhase = false; instance.shipHasLanded = true; instance.shipDoorsEnabled = true; instance.SetPlayerObjectExtrapolate(false); ((Component)instance.shipAnimatorObject).GetComponent<Animator>().Play("ShipIdleLanded", 0, 0f); instance.SetShipDoorsClosed(info.hangarDoorsClosed); instance.shipDoorsAnimator.SetBool("Closed", info.hangarDoorsClosed); Object.FindObjectOfType<HangarShipDoor>().SetDoorButtonsEnabled(true); JoinMessageFix.HideSpace(instance); instance.SwitchMapMonitorPurpose(false); LevelWeatherType currentWeather = instance.currentLevel.currentWeather; TimeOfDay.Instance.currentLevelWeather = currentWeather; if ((int)currentWeather != -1) { WeatherEffect val2 = TimeOfDay.Instance.effects[currentWeather]; val2.effectEnabled = true; if ((Object)(object)val2.effectPermanentObject != (Object)null) { val2.effectPermanentObject.SetActive(true); } } TimeOfDay.Instance.globalTime = info.globalTime; if (instance.currentLevel.planetHasTime) { TimeOfDay.Instance.currentDayTimeStarted = true; TimeOfDay.Instance.movingGlobalTimeForward = true; } StartMatchLever obj = Object.FindObjectOfType<StartMatchLever>(); obj.leverHasBeenPulled = true; obj.triggerScript.animationString = "SA_PushLeverBack"; obj.triggerScript.interactable = true; JoinMessageFix.RecountLiving(instance); DetachMoonScrap(instance); recheckScrapAt = Time.time + 4f; shipSpot = ((Component)localPlayerController).transform.position; Waiting = true; HUDManager.Instance.DisplayTip("Late Landing", "You landed late. Hang on in the ship while the moon catches up...", false, false, "LC_Tip1"); Plugin.Logger.LogInfo((object)$"Joined while landed on {instance.currentLevel.PlanetName} ({currentWeather}); rebuilding the moon."); try { MoonRebuild.Start(info); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Couldn't rebuild the moon: {arg}"); MoonRebuild.Reset(); CouldNotMatch(); } } internal static void ApplySnapshot(MoonSnapshot snapshot) { if (Waiting) { snapshot.Apply(); Waiting = false; HideLoading(); HUDManager.Instance.DisplayTip("Late Landing", "You landed with the crew. Go get some scrap!", false, false, "LC_Tip1"); Plugin.Logger.LogInfo((object)$"Caught up with the round: {snapshot.players.Count} players, {snapshot.enemies.Count} monsters, {snapshot.webs.Count} webs, {snapshot.doors.Count} doors, {snapshot.scrap.Count} scrap. Playing."); LateNet.SayReady(playing: true); } } internal static void CouldNotMatch() { HideLoading(); HUDManager.Instance.DisplayTip("Late Landing", "This moon couldn't be matched for you. Wait in the ship: you'll join the crew when it takes off.", true, false, "LC_Tip1"); LateNet.SayReady(playing: false); } private static void HideLoading() { ((Behaviour)HUDManager.Instance.loadingText).enabled = false; HUDManager.Instance.LoadingScreen.SetBool("IsLoading", false); } private static void DetachMoonScrap(StartOfRound round) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = round.shipBounds.bounds; Transform spawnedScrapContainer = RoundManager.Instance.spawnedScrapContainer; GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject val in array) { if (!((Object)(object)((Component)val).transform.parent != (Object)(object)round.elevatorTransform) && !((Bounds)(ref bounds)).Contains(((Component)val).transform.position)) { ((Component)val).transform.SetParent(spawnedScrapContainer, true); val.isInElevator = false; val.isInShipRoom = false; val.scrapPersistedThroughRounds = false; } } } internal static void Tick() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (!Waiting) { return; } StartOfRound instance = StartOfRound.Instance; PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)instance == (Object)null || (Object)(object)localPlayerController == (Object)null || instance.inShipPhase) { Waiting = false; MoonRebuild.Reset(); return; } MoonRebuild.Tick(); if (recheckScrapAt > 0f && Time.time >= recheckScrapAt) { recheckScrapAt = -1f; DetachMoonScrap(instance); } if (localPlayerController.isPlayerControlled && !localPlayerController.isPlayerDead && !localPlayerController.isInHangarShipRoom && !instance.shipIsLeaving) { localPlayerController.TeleportPlayer(shipSpot, false, 0f, false, true); HUDManager.Instance.DisplayTip("Late Landing", "Stay in the ship until it takes off.", false, false, "LC_Tip1"); } } internal static void Reset() { Waiting = false; MoonRebuild.Reset(); } [HarmonyPatch(typeof(EnemyAI), "ChangeOwnershipOfEnemy")] [HarmonyPrefix] private static bool KeepGhostGirlsVictim(EnemyAI __instance) { if (__instance is DressGirlAI && !((NetworkBehaviour)__instance).IsServer && (Object)(object)StartOfRound.Instance != (Object)null) { return StartOfRound.Instance.shipHasLanded; } return true; } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] [HarmonyPrefix] private static bool NoDamageWhileWaiting(PlayerControllerB __instance) { if (Waiting) { return !((NetworkBehaviour)__instance).IsOwner; } return true; } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] [HarmonyPrefix] private static bool NoDeathWhileWaiting(PlayerControllerB __instance) { if (Waiting && ((NetworkBehaviour)__instance).IsOwner) { return StartOfRound.Instance.shipIsLeaving; } return true; } } internal static class LateNet { internal class LevelInfo { public float globalTime; public int[] weathers; public int[] sales; public int[] decor; public bool hangarDoorsClosed; public int seed; public int levelID; public int moldIterations; public int moldStart; public int interiorNodes; public int[] destroyedMold = new int[0]; public float interiorHash; public byte[] journal = new byte[0]; public void Write(FastBufferWriter w) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref globalTime, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(weathers, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(sales, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(decor, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref hangarDoorsClosed, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref seed, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref levelID, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref moldIterations, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref moldStart, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(destroyedMold, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref interiorNodes, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref interiorHash, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<byte>(journal, default(ForPrimitives)); } public static LevelInfo Read(FastBufferReader r) { //IL_0010: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) LevelInfo levelInfo = new LevelInfo(); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref levelInfo.globalTime, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.weathers, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.sales, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.decor, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref levelInfo.hangarDoorsClosed, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.seed, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.levelID, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.moldIterations, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.moldStart, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.destroyedMold, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref levelInfo.interiorNodes, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref levelInfo.interiorHash, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref levelInfo.journal, default(ForPrimitives)); return levelInfo; } } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnHello; public static HandleNamedMessageDelegate <1>__OnLevelInfo; public static HandleNamedMessageDelegate <2>__OnBuilt; public static HandleNamedMessageDelegate <3>__OnSnapshot; public static HandleNamedMessageDelegate <4>__OnReady; public static HandleNamedMessageDelegate <5>__OnJoined; } private const string HelloMessage = "aj.LateLanding.Hello"; private const string LevelInfoMessage = "aj.LateLanding.LevelInfo"; private const string BuiltMessage = "aj.LateLanding.Built"; private const string SnapshotMessage = "aj.LateLanding.Snapshot"; private const string ReadyMessage = "aj.LateLanding.Ready"; private const string JoinedMessage = "aj.LateLanding.Joined"; private const int MaxMessageBytes = 524288; private static readonly string[] All = new string[6] { "aj.LateLanding.Hello", "aj.LateLanding.LevelInfo", "aj.LateLanding.Built", "aj.LateLanding.Snapshot", "aj.LateLanding.Ready", "aj.LateLanding.Joined" }; private const int PieceBytes = 1000; private const int PiecesPerFrame = 24; private static readonly Queue<(ulong client, string message, int index, int pieces, byte[] bytes)> outgoing = new Queue<(ulong, string, int, int, byte[])>(); private static readonly List<byte[]> received = new List<byte[]>(); private static CustomMessagingManager? Messages { get { if (!((Object)(object)NetworkManager.Singleton != (Object)null)) { return null; } return NetworkManager.Singleton.CustomMessagingManager; } } internal static void Register() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0092: 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_009d: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown CustomMessagingManager messages = Messages; if (messages != null) { object obj = <>O.<0>__OnHello; if (obj == null) { HandleNamedMessageDelegate val = OnHello; <>O.<0>__OnHello = val; obj = (object)val; } messages.RegisterNamedMessageHandler("aj.LateLanding.Hello", (HandleNamedMessageDelegate)obj); object obj2 = <>O.<1>__OnLevelInfo; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnLevelInfo; <>O.<1>__OnLevelInfo = val2; obj2 = (object)val2; } messages.RegisterNamedMessageHandler("aj.LateLanding.LevelInfo", (HandleNamedMessageDelegate)obj2); object obj3 = <>O.<2>__OnBuilt; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnBuilt; <>O.<2>__OnBuilt = val3; obj3 = (object)val3; } messages.RegisterNamedMessageHandler("aj.LateLanding.Built", (HandleNamedMessageDelegate)obj3); object obj4 = <>O.<3>__OnSnapshot; if (obj4 == null) { HandleNamedMessageDelegate val4 = OnSnapshot; <>O.<3>__OnSnapshot = val4; obj4 = (object)val4; } messages.RegisterNamedMessageHandler("aj.LateLanding.Snapshot", (HandleNamedMessageDelegate)obj4); object obj5 = <>O.<4>__OnReady; if (obj5 == null) { HandleNamedMessageDelegate val5 = OnReady; <>O.<4>__OnReady = val5; obj5 = (object)val5; } messages.RegisterNamedMessageHandler("aj.LateLanding.Ready", (HandleNamedMessageDelegate)obj5); object obj6 = <>O.<5>__OnJoined; if (obj6 == null) { HandleNamedMessageDelegate val6 = OnJoined; <>O.<5>__OnJoined = val6; obj6 = (object)val6; } messages.RegisterNamedMessageHandler("aj.LateLanding.Joined", (HandleNamedMessageDelegate)obj6); } } internal static void Unregister() { outgoing.Clear(); received.Clear(); CustomMessagingManager messages = Messages; if (messages != null) { string[] all = All; foreach (string text in all) { messages.UnregisterNamedMessageHandler(text); } } } internal static void SayHello() { SendToHost("aj.LateLanding.Hello", null); } internal static void AskSnapshot() { SendToHost("aj.LateLanding.Built", null); } internal static void SayReady(bool playing) { SendToHost("aj.LateLanding.Ready", delegate(FastBufferWriter w) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) ((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref playing, default(ForPrimitives)); }); } private unsafe static void SendToHost(string message, Action<FastBufferWriter>? write) { //IL_002e: 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) CustomMessagingManager messages = Messages; if (messages == null || NetworkManager.Singleton.IsServer) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1); try { write?.Invoke(val); messages.SendNamedMessage(message, 0uL, val, (NetworkDelivery)2); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static void OnHello(ulong sender, FastBufferReader reader) { StartOfRound instance = StartOfRound.Instance; if (!NetworkManager.Singleton.IsServer || (Object)(object)instance == (Object)null || instance.inShipPhase) { return; } Terminal val = Object.FindObjectOfType<Terminal>(); List<UnlockableItem> unlockables = instance.unlockablesList.unlockables; LevelInfo levelInfo = new LevelInfo { globalTime = TimeOfDay.Instance.globalTime, weathers = instance.levels.Select((SelectableLevel l) => (int)l.currentWeather).ToArray(), sales = val.itemSalesPercentages, decor = (from node in val.ShipDecorSelection select unlockables.FindIndex((UnlockableItem u) => (Object)(object)u.shopSelectionNode == (Object)(object)node) into i where i >= 0 select i).ToArray(), hangarDoorsClosed = instance.hangarDoorsClosed }; MoonRebuild.Describe(levelInfo, sender); SendTo(sender, "aj.LateLanding.LevelInfo", levelInfo.Write); } private static void OnBuilt(ulong sender, FastBufferReader reader) { if (NetworkManager.Singleton.IsServer && (Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.inShipPhase) { try { SendInOrder(sender, "aj.LateLanding.Snapshot", MoonSnapshot.Take().Write); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Couldn't describe the round for the late joiner: {arg}"); } } } private unsafe static void SendInOrder(ulong client, string message, Action<FastBufferWriter> write) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter obj = default(FastBufferWriter); ((FastBufferWriter)(ref obj))..ctor(1024, (Allocator)2, 524288); byte[] array; try { write(obj); array = ((FastBufferWriter)(ref obj)).ToArray(); } finally { ((IDisposable)(*(FastBufferWriter*)(&obj))/*cast due to .constrained prefix*/).Dispose(); } int num = Mathf.Max(1, (array.Length + 1000 - 1) / 1000); for (int i = 0; i < num; i++) { int num2 = i * 1000; int num3 = Mathf.Min(1000, array.Length - num2); byte[] array2 = new byte[num3]; Array.Copy(array, num2, array2, 0, num3); outgoing.Enqueue((client, message, i, num, array2)); } Pump(); } internal unsafe static void Pump() { //IL_0065: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_009b: Unknown result type (might be due to invalid IL or missing references) CustomMessagingManager messages = Messages; FastBufferWriter val = default(FastBufferWriter); for (int i = 0; i < 24; i++) { if (outgoing.Count <= 0) { break; } var (num, text, num2, num3, array) = outgoing.Dequeue(); if (messages != null && NetworkManager.Singleton.ConnectedClientsIds.Contains(num)) { ((FastBufferWriter)(ref val))..ctor(1032, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num2, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num3, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<byte>(array, default(ForPrimitives)); messages.SendNamedMessage(text, num, val, (NetworkDelivery)3); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } } } private static bool Collect(FastBufferReader reader, out byte[] whole) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); int num2 = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num2, default(ForPrimitives)); byte[] item = default(byte[]); ((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref item, default(ForPrimitives)); if (num == 0) { received.Clear(); } received.Add(item); whole = null; if (received.Count < num2) { return false; } whole = received.SelectMany((byte[] p) => p).ToArray(); received.Clear(); return true; } private unsafe static void OnReady(ulong sender, FastBufferReader reader) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_0082: 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_00c4: Unknown result type (might be due to invalid IL or missing references) if (!NetworkManager.Singleton.IsServer || (Object)(object)StartOfRound.Instance == (Object)null) { return; } bool playing = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref playing, default(ForPrimitives)); int value; int slot = (StartOfRound.Instance.ClientPlayerList.TryGetValue(sender, out value) ? value : (-1)); CustomMessagingManager messages = Messages; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref slot, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref playing, default(ForPrimitives)); List<ulong> list = NetworkManager.Singleton.ConnectedClientsIds.Where((ulong id) => id != 0L && id != sender).ToList(); if (list.Count > 0) { messages.SendNamedMessage("aj.LateLanding.Joined", (IReadOnlyList<ulong>)list, val, (NetworkDelivery)2); } } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } LateRunner.AnnounceJoin(slot, playing); JoinMessageFix.RecountLiving(StartOfRound.Instance); if (JoinGate.Preparing == sender) { JoinGate.Preparing = null; } } private unsafe static void SendTo(ulong client, string message, Action<FastBufferWriter> write) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, 524288); try { write(val); Messages.SendNamedMessage(message, client, val, (NetworkDelivery)4); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private static void OnLevelInfo(ulong sender, FastBufferReader reader) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (sender == 0L) { LateJoiner.ApplyLanded(LevelInfo.Read(reader)); } } private unsafe static void OnSnapshot(ulong sender, FastBufferReader reader) { //IL_0003: 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) if (sender != 0L || !Collect(reader, out byte[] whole)) { return; } FastBufferReader r = default(FastBufferReader); ((FastBufferReader)(ref r))..ctor(whole, (Allocator)2, -1, 0); try { LateJoiner.ApplySnapshot(MoonSnapshot.Read(r)); } finally { ((IDisposable)(*(FastBufferReader*)(&r))/*cast due to .constrained prefix*/).Dispose(); } } private static void OnJoined(ulong sender, FastBufferReader reader) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) if (sender == 0L) { int slot = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref slot, default(ForPrimitives)); bool playing = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref playing, default(ForPrimitives)); LateRunner.AnnounceJoin(slot, playing); } } } [HarmonyPatch] internal class LateRunner : MonoBehaviour { private const float AnnounceDelay = 2.5f; private const float LobbyCheckEvery = 1f; private static readonly List<(int slot, bool playing, float at)> announcements = new List<(int, bool, float)>(); private float nextLobbyCheck; private bool wasLanded; [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void Attach(StartOfRound __instance) { ((Component)__instance).gameObject.AddComponent<LateRunner>(); LateNet.Register(); JoinGate.WarnAboutOtherGates(); } internal static void AnnounceJoin(int slot, bool playing) { if (slot >= 0) { announcements.Add((slot, playing, Time.time + 2.5f)); } } private void Update() { if (Time.time >= nextLobbyCheck) { nextLobbyCheck = Time.time + 1f; JoinGate.UpdateLobby(); } if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && JoinGate.Landed != wasLanded) { wasLanded = JoinGate.Landed; if (wasLanded) { Plugin.Logger.LogInfo((object)("Ship landed on " + StartOfRound.Instance.currentLevel.PlanetName + ": late joins are open.")); } } LateJoiner.Tick(); MonsterCatchUp.Tick(); LateNet.Pump(); for (int num = announcements.Count - 1; num >= 0; num--) { if (!(Time.time < announcements[num].at)) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; var (num2, flag, _) = announcements[num]; announcements.RemoveAt(num); if (num2 < allPlayerScripts.Length && (Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Late Landing", flag ? (allPlayerScripts[num2].playerUsername + " joined and landed with the crew.") : (allPlayerScripts[num2].playerUsername + " landed late. They'll join in when the ship takes off."), false, false, "LC_Tip1"); } } } } private void OnDestroy() { LateNet.Unregister(); JoinGate.Reset(); LateJoiner.Reset(); MonsterCatchUp.Reset(); announcements.Clear(); } } internal static class MonsterCatchUp { private class Handler { public Action<EnemyAI, BinaryWriter> describe; public Action<EnemyAI, BinaryReader> apply; public bool early; } private const float PlantSizeScale = 7.75f; private static readonly Vector3 PlantMarkerOffset = Vector3.up * 1.1f; private const float PlantMarkerMatch = 0.3f; private const float FlowerGrowthsPerInfection = 8f; private const string DescribeHook = "LateLandingDescribe"; private const string CatchUpHook = "LateLandingCatchUp"; private static readonly Dictionary<Type, Handler> handlers = new Dictionary<Type, Handler> { [typeof(SpringManAI)] = new Handler { describe = DescribeCoilHead, apply = ApplyCoilHead }, [typeof(MaskedPlayerEnemy)] = new Handler { describe = DescribeMasked, apply = ApplyMasked, early = true }, [typeof(BushWolfEnemy)] = new Handler { describe = DescribeFox, apply = ApplyFox }, [typeof(CrawlerAI)] = new Handler { describe = DescribeThumper, apply = ApplyThumper }, [typeof(NutcrackerEnemyAI)] = new Handler { describe = DescribeNutcracker, apply = ApplyNutcracker, early = true }, [typeof(HoarderBugAI)] = new Handler { describe = DescribeHoardingBug, apply = ApplyHoardingBug }, [typeof(BaboonBirdAI)] = new Handler { describe = DescribeBaboonHawk, apply = ApplyBaboonHawk }, [typeof(GiantKiwiAI)] = new Handler { describe = DescribeSapsucker, apply = ApplySapsucker }, [typeof(CaveDwellerAI)] = new Handler { describe = DescribeManeater, apply = ApplyManeater, early = true }, [typeof(RedLocustBees)] = new Handler { describe = DescribeBees, apply = ApplyBees }, [typeof(ClaySurgeonAI)] = new Handler { describe = DescribeBarber, apply = ApplyBarber }, [typeof(DressGirlAI)] = new Handler { describe = DescribeGhostGirl, apply = ApplyGhostGirl }, [typeof(CentipedeAI)] = new Handler { describe = DescribeSnareFlea, apply = ApplySnareFlea }, [typeof(ForestGiantAI)] = new Handler { describe = DescribeForestGiant, apply = ApplyForestGiant }, [typeof(PumaAI)] = new Handler { describe = DescribeFeiopar, apply = ApplyFeiopar }, [typeof(StingrayAI)] = new Handler { describe = DescribeStingray, apply = ApplyStingray }, [typeof(MouthDogAI)] = new Handler { describe = DescribeDog, apply = ApplyDog, early = true }, [typeof(RadMechAI)] = new Handler { describe = DescribeOldBird, apply = ApplyOldBird }, [typeof(ButlerEnemyAI)] = new Handler { describe = DescribeButler, apply = ApplyButler }, [typeof(FlowerSnakeEnemy)] = new Handler { describe = DescribeTulipSnake, apply = ApplyTulipSnake }, [typeof(SandSpiderAI)] = new Handler { describe = DescribeSpider, apply = ApplySpider }, [typeof(FlowermanAI)] = new Handler { describe = DescribeBracken, apply = ApplyBracken }, [typeof(JesterAI)] = new Handler { describe = DescribeJester, apply = ApplyJester }, [typeof(CadaverGrowthAI)] = new Handler { describe = DescribeCadaverGrowth, apply = ApplyCadaverGrowth }, [typeof(CadaverBloomAI)] = new Handler { describe = DescribeCadaverBloom, apply = ApplyCadaverBloom, early = true } }; private static readonly Dictionary<Type, (MethodInfo? describe, MethodInfo? apply)> hooks = new Dictionary<Type, (MethodInfo, MethodInfo)>(); private const int FramesToLetStateStart = 2; private static readonly List<(int frame, string what, Action action)> later = new List<(int, string, Action)>(); private static void DescribeCadaverGrowth(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: 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_01cb: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) CadaverGrowthAI val = (CadaverGrowthAI)e; Traverse val2 = Traverse.Create((object)e); ReadOnlyCollection<Tile> allTiles = RoundManager.Instance.dungeonGenerator.Generator.CurrentDungeon.AllTiles; w.Write(val.GrowthTiles.Count); foreach (TileWithGrowth growthTile in val.GrowthTiles) { w.Write(allTiles.IndexOf(growthTile.tile)); Write(w, growthTile.lastPlantGrownPosition); w.Write(growthTile.eradicated); w.Write(growthTile.cannotSpread); } (int, int, int) value = val2.Field<(int, int, int)>("growingPlant").Value; float value2 = val2.Field<float>("recentPlantSizeTarget").Value; w.Write(val.plantBatchers.Length); for (int i = 0; i < val.plantBatchers.Length; i++) { BatchAllMeshChildren obj = val.plantBatchers[i]; List<Matrix4x4> list = obj.Batches.SelectMany((List<Matrix4x4> b) => b).ToList(); List<Vector3> list2 = obj.batchedPositions ?? new List<Vector3>(); List<int> list3 = obj.batchedPositionTiles ?? new List<int>(); int num = Mathf.Min(list.Count, Mathf.Min(list2.Count, list3.Count)); w.Write(num); for (int num2 = 0; num2 < num; num2++) { int num3 = list3[num2]; bool flag = val.growingRecentPlant && value.Item3 == i && value.Item1 * 1000 + value.Item2 == num2; w.Write(num3); Write(w, list2[num2]); Matrix4x4 val3 = list[num2]; Quaternion rotation = ((Matrix4x4)(ref val3)).rotation; w.Write(rotation.x); w.Write(rotation.y); w.Write(rotation.z); w.Write(rotation.w); float num4; if (!flag) { val3 = list[num2]; num4 = ((Matrix4x4)(ref val3)).lossyScale.x; } else { num4 = value2; } w.Write(num4 / 7.75f); var (value3, value4) = PlantMarkers(val, num3, list2[num2]); w.Write(value3); w.Write(value4); } } w.Write(val.playerInfections.Length); for (int num5 = 0; num5 < val.playerInfections.Length; num5++) { PlayerInfection val4 = val.playerInfections[num5]; w.Write(val4.infected); w.Write(val4.severe); w.Write(val4.emittingSpores); w.Write(val4.bloomOnDeath); w.Write(val4.infectionMeter); bool flag2 = (Object)(object)Player(num5) == (Object)(object)GameNetworkManager.Instance.localPlayerController; w.Write((flag2 && val4.infected) ? (-1) : (val4.backFlowerRenderers?.Count((MeshRenderer r) => (Object)(object)r != (Object)null && ((Renderer)r).enabled) ?? 0)); } w.Write(val.bloomEnemies.Length); CadaverBloomAI[] bloomEnemies = val.bloomEnemies; foreach (CadaverBloomAI c in bloomEnemies) { WriteObject(w, (Component?)(object)c); } } private static (bool scan, bool decal) PlantMarkers(CadaverGrowthAI growth, int tileIndex, Vector3 plant) { //IL_003c: 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_0047: 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_0065: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) bool item = false; bool item2 = false; GameObject val = ((tileIndex >= 0 && tileIndex < growth.GrowthTiles.Count) ? growth.GrowthTiles[tileIndex].scanNodesContainer : null); if ((Object)(object)val == (Object)null) { return (scan: false, decal: false); } Vector3 val2 = plant + PlantMarkerOffset; foreach (Transform item3 in val.transform) { Transform val3 = item3; if (!(Vector3.Distance(val3.position, val2) > 0.3f)) { if ((Object)(object)((Component)val3).GetComponent<ScanNodeProperties>() != (Object)null) { item = true; } else { item2 = true; } } } return (scan: item, decal: item2); } private static void ApplyCadaverGrowth(EnemyAI e, BinaryReader r) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) CadaverGrowthAI growth = (CadaverGrowthAI)e; Traverse val = Traverse.Create((object)e); ReadOnlyCollection<Tile> allTiles = RoundManager.Instance.dungeonGenerator.Generator.CurrentDungeon.AllTiles; foreach (TileWithGrowth growthTile in growth.GrowthTiles) { GameObject[] array = (GameObject[])(object)new GameObject[4] { growthTile.plantsContainer, growthTile.particlesContainer, growthTile.scanNodesContainer, growthTile.decalsContainer }; foreach (GameObject val2 in array) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } growth.GrowthTiles.Clear(); BatchAllMeshChildren[] plantBatchers = growth.plantBatchers; foreach (BatchAllMeshChildren obj in plantBatchers) { obj.Batches.Clear(); obj.batchedPositions = new List<Vector3>(); obj.batchedPositionTiles = new List<int>(); obj.amountOfMatrices = 0; } growth.growingRecentPlant = false; val.Field<(int, int, int)>("growingPlant").Value = (-1, -1, -1); int num = r.ReadInt32(); for (int j = 0; j < num; j++) { int num2 = r.ReadInt32(); Vector3 val3 = ReadVector(r); bool eradicated = r.ReadBoolean(); bool cannotSpread = r.ReadBoolean(); if (num2 < 0 || num2 >= allTiles.Count) { throw new InvalidDataException($"room {num2} isn't in this facility"); } growth.GrowthTiles.Add(new TileWithGrowth(allTiles[num2], growth.TileCapacity, growth.CaveTileTag, growth.RoomTileTag, growth.TunnelTileTag, val3) { eradicated = eradicated, cannotSpread = cannotSpread }); } growth.plantAudio.mute = true; int num3 = r.ReadInt32(); int num4 = 0; for (int k = 0; k < num3; k++) { int num5 = r.ReadInt32(); for (int l = 0; l < num5; l++) { int tileIndex = r.ReadInt32(); Vector3 position = ReadVector(r); Quaternion rotation = new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); float size = r.ReadSingle(); bool scan = r.ReadBoolean(); bool decal = r.ReadBoolean(); if (k < growth.plantBatchers.Length && tileIndex < growth.GrowthTiles.Count) { int plantType = k; MoonRebuild.RunAsReceived((NetworkBehaviour)(object)growth, delegate { //IL_0018: 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) growth.SyncSpawnPlantRpc(plantType, tileIndex, position, rotation, size, scan, decal); }); num4++; } } } if (num4 > 0) { AccessTools.Method(typeof(CadaverGrowthAI), "QuickFinishGrowingPlant", (Type[])null, (Type[])null).Invoke(growth, null); } Later("the Cadaver plants' sound", delegate { growth.plantAudio.mute = false; }); int num6 = r.ReadInt32(); PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; for (int num7 = 0; num7 < num6; num7++) { bool num8 = r.ReadBoolean(); bool flag = r.ReadBoolean(); bool flag2 = r.ReadBoolean(); bool bloomOnDeath = r.ReadBoolean(); float num9 = r.ReadSingle(); int num10 = r.ReadInt32(); PlayerControllerB val4 = Player(num7); if (!num8 || (Object)(object)val4 == (Object)null || (Object)(object)val4 == (Object)(object)localPlayerController || num7 >= growth.playerInfections.Length) { continue; } growth.InfectPlayer(val4, flag, flag2); PlayerInfection val5 = growth.playerInfections[num7]; val5.infectionMeter = num9; val5.bloomOnDeath = bloomOnDeath; MethodInfo methodInfo = AccessTools.Method(typeof(CadaverGrowthAI), "IncreaseBackFlowers", (Type[])null, (Type[])null); if (num10 < 0) { for (int num11 = 0; num11 < Mathf.CeilToInt(num9 * 8f); num11++) { methodInfo.Invoke(growth, new object[1] { num7 }); } } else if (num10 > 0) { methodInfo.Invoke(growth, new object[1] { num7 }); int num12 = 0; while (val5.backFlowerRenderers != null && num12 < val5.backFlowerRenderers.Length) { ((Renderer)val5.backFlowerRenderers[num12]).enabled = num12 < num10; num12++; } } } int num13 = r.ReadInt32(); CadaverBloomAI[] array2 = (CadaverBloomAI[])(object)new CadaverBloomAI[growth.bloomEnemies.Length]; for (int num14 = 0; num14 < num13; num14++) { NetworkObject? obj2 = ReadObject(r); CadaverBloomAI val6 = ((obj2 != null) ? ((Component)obj2).GetComponent<CadaverBloomAI>() : null); if (num14 < array2.Length) { array2[num14] = val6; } } growth.bloomEnemies = array2; } private static void DescribeCadaverBloom(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown CadaverBloomAI val = (CadaverBloomAI)e; w.Write(val.hasBurst); w.Write(Slot(val.burstPlayer)); w.Write(e.isEnemyDead); } private static void ApplyCadaverBloom(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0056: 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) CadaverBloomAI val = (CadaverBloomAI)e; bool num = r.ReadBoolean(); PlayerControllerB val2 = Player(r.ReadInt32()); bool flag = r.ReadBoolean(); if (num && !((Object)(object)val2 == (Object)null) && !val.hasBurst) { if (flag) { val.burstPlayer = val2; val.hasBurst = true; val2.redirectToEnemy = (EnemyAI)(object)val; } else { val.BurstForth(val2, false, ((Component)val).transform.position, ((Component)val).transform.eulerAngles); } } } internal static byte[]? Describe(EnemyAI enemy) { Type type = ((object)enemy).GetType(); if (handlers.TryGetValue(type, out Handler value)) { using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter arg = new BinaryWriter(memoryStream)) { value.describe(enemy, arg); } return memoryStream.ToArray(); } } MethodInfo item = Hooks(type).describe; if (!(item != null)) { return null; } return item.Invoke(enemy, null) as byte[]; } internal static void Apply(EnemyAI enemy, byte[] data, bool early) { Type type = ((object)enemy).GetType(); if (handlers.TryGetValue(type, out Handler value)) { if (value.early == early) { using (BinaryReader arg = new BinaryReader(new MemoryStream(data))) { value.apply(enemy, arg); } } } else if (!early) { Hooks(type).apply?.Invoke(enemy, new object[1] { data }); } } private static (MethodInfo? describe, MethodInfo? apply) Hooks(Type type) { if (!hooks.TryGetValue(type, out (MethodInfo, MethodInfo) value)) { MethodInfo methodInfo = AccessTools.Method(type, "LateLandingDescribe", Type.EmptyTypes, (Type[])null); MethodInfo item = AccessTools.Method(type, "LateLandingCatchUp", new Type[1] { typeof(byte[]) }, (Type[])null); value = ((methodInfo != null && methodInfo.ReturnType == typeof(byte[])) ? methodInfo : null, item); hooks[type] = value; if (value.Item1 != null && value.Item2 != null) { Plugin.Logger.LogInfo((object)(type.Name + " catches late joiners up itself.")); } } return value; } private static void DescribeCoilHead(EnemyAI e, BinaryWriter w) { Traverse val = Traverse.Create((object)e); w.Write(val.Field<bool>("stoppingMovement").Value); w.Write(val.Field<bool>("setOnCooldown").Value); w.Write(val.Field<float>("onCooldownPhase").Value); } private static void ApplyCoilHead(EnemyAI e, BinaryReader r) { Traverse val = Traverse.Create((object)e); val.Field<bool>("stoppingMovement").Value = r.ReadBoolean(); bool num = r.ReadBoolean(); float value = r.ReadSingle(); if (num) { val.Field<bool>("setOnCooldown").Value = true; val.Field<bool>("inCooldownAnimation").Value = true; val.Field<float>("onCooldownPhase").Value = value; } } private static void DescribeMasked(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown MaskedPlayerEnemy val = (MaskedPlayerEnemy)e; w.Write(val.allowSpawningWithoutPlayer); w.Write(((Object)(object)val.mimickingPlayer != (Object)null) ? ((int)val.mimickingPlayer.playerClientId) : (-1)); w.Write(((Object)(object)val.mimickingPlayer != (Object)null) ? val.mimickingPlayer.currentSuitID : 0); w.Write((Traverse.Create((object)val).Field<int>("maskTypeIndex").Value == 1) ? 5 : 4); Traverse val2 = Traverse.Create((object)val); w.Write(val2.Field<bool>("crouching").Value); w.Write(val2.Field<bool>("handsOut").Value); w.Write(val2.Field<bool>("running").Value); Transform stareAtTransform = val.stareAtTransform; w.Write(((Object)(object)stareAtTransform != (Object)null) ? Slot(((Component)stareAtTransform).GetComponentInParent<PlayerControllerB>()) : (-1)); } private static void ApplyMasked(EnemyAI e, BinaryReader r) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown MaskedPlayerEnemy masked = (MaskedPlayerEnemy)e; masked.allowSpawningWithoutPlayer = r.ReadBoolean(); int num = r.ReadInt32(); int suit = r.ReadInt32(); int maskType = r.ReadInt32(); if (num >= 0 && num < StartOfRound.Instance.allPlayerScripts.Length) { PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[num]; masked.mimickingPlayer = val; masked.SetSuit(suit); masked.SetMaskType(maskType); val.redirectToEnemy = (EnemyAI)(object)masked; } masked.SetVisibilityOfMaskedEnemy(); bool crouch = r.ReadBoolean(); bool hands = r.ReadBoolean(); bool run = r.ReadBoolean(); PlayerControllerB watched = Player(r.ReadInt32()); Later("the Masked's pose", delegate { Traverse obj = Traverse.Create((object)masked); obj.Field<bool>("crouching").Value = crouch; ((EnemyAI)masked).creatureAnimator.SetBool("Crouching", crouch); obj.Field<bool>("handsOut").Value = hands; ((EnemyAI)masked).creatureAnimator.SetBool("HandsOut", hands); obj.Field<bool>("running").Value = run; ((EnemyAI)masked).creatureAnimator.SetBool("Running", run); masked.stareAtTransform = (((Object)(object)watched != (Object)null) ? ((Component)watched.gameplayCamera).transform : null); }); } private static void DescribeFox(EnemyAI e, BinaryWriter w) { //IL_0013: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown Traverse val = Traverse.Create((object)e); Write(w, val.Field<Vector3>("mostHiddenPosition").Value); Write(w, val.Field<Vector3>("aggressivePosition").Value); Write(w, val.Field<Vector3>("currentHidingSpot").Value); BushWolfEnemy val2 = (BushWolfEnemy)e; w.Write(val2.nestRange); w.Write(val.Field<float>("baseNestRange").Value); } private static void ApplyFox(EnemyAI e, BinaryReader r) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //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_0043: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ReadVector(r); Vector3 value = ReadVector(r); Vector3 value2 = ReadVector(r); float nestRange = r.ReadSingle(); float value3 = r.ReadSingle(); if (!(val == Vector3.zero)) { Traverse obj = Traverse.Create((object)e); obj.Field<Vector3>("mostHiddenPosition").Value = val; obj.Field<Vector3>("aggressivePosition").Value = value; obj.Field<Vector3>("currentHidingSpot").Value = value2; ((BushWolfEnemy)e).nestRange = nestRange; obj.Field<float>("baseNestRange").Value = value3; } } private static void DescribeThumper(EnemyAI e, BinaryWriter w) { w.Write((e.movingTowardsTargetPlayer && (Object)(object)e.targetPlayer != (Object)null) ? ((int)e.targetPlayer.playerClientId) : (-1)); } private static void ApplyThumper(EnemyAI e, BinaryReader r) { int num = r.ReadInt32(); if (num >= 0 && num < StartOfRound.Instance.allPlayerScripts.Length) { e.SetMovingTowardsTargetPlayer(StartOfRound.Instance.allPlayerScripts[num]); } } private static void DescribeNutcracker(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown NutcrackerEnemyAI val = (NutcrackerEnemyAI)e; Traverse val2 = Traverse.Create((object)e); w.Write(e.isEnemyDead); WriteObject(w, (Component?)(object)val.gun); w.Write((Object)(object)val.gun != (Object)null && (Object)(object)((GrabbableObject)val.gun).parentObject == (Object)(object)val.gunPoint); w.Write(((Object)(object)val.gun != (Object)null) ? val.gun.shellsLoaded : 0); w.Write(val2.Field<int>("randomSeedNumber").Value); w.Write(val2.Field<int>("timesDoingInspection").Value); w.Write(val.lastPlayerSeenMoving); w.Write(val2.Field<bool>("lostPlayerInChase").Value); w.Write(e.currentBehaviourStateIndex == 1); } private static void ApplyNutcracker(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) NutcrackerEnemyAI val = (NutcrackerEnemyAI)e; Traverse val2 = Traverse.Create((object)e); bool flag = r.ReadBoolean(); NetworkObject val3 = ReadObject(r); bool flag2 = r.ReadBoolean(); int shellsLoaded = r.ReadInt32(); val2.Field<int>("randomSeedNumber").Value = r.ReadInt32(); int value = r.ReadInt32(); int num = r.ReadInt32(); bool value2 = r.ReadBoolean(); val2.Field<int>("timesDoingInspection").Value = value; if (r.ReadBoolean()) { val2.Field<int>("previousBehaviourState").Value = 1; } ShotgunItem val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<ShotgunItem>() : null); if ((Object)(object)val4 != (Object)null) { val2.Field<NetworkObjectReference>("gunObjectRef").Value = new NetworkObjectReference(val3); if (flag) { val.gun = val4; if (flag2) { ((GrabbableObject)val4).parentObject = val.gunPoint; ((GrabbableObject)val4).isHeldByEnemy = false; ((GrabbableObject)val4).grabbable = true; ((GrabbableObject)val4).grabbableToEnemies = true; } } else { AccessTools.Method(typeof(NutcrackerEnemyAI), "GrabGun", (Type[])null, (Type[])null).Invoke(val, new object[1] { ((Component)val4).gameObject }); val4.shellsLoaded = shellsLoaded; } } if (num >= 0 && num < StartOfRound.Instance.allPlayerScripts.Length) { AccessTools.Method(typeof(NutcrackerEnemyAI), "SwitchTargetToPlayer", (Type[])null, (Type[])null).Invoke(val, new object[1] { num }); } val2.Field<bool>("lostPlayerInChase").Value = value2; } private static void DescribeHoardingBug(EnemyAI e, BinaryWriter w) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected I4, but got Unknown HoarderBugAI bug = (HoarderBugAI)e; Write(w, bug.nestPosition); GrabbableObject c = bug.heldItem?.itemGrabbableObject; WriteObject(w, (Component?)(object)c); List<HoarderBugItem> list = HoarderBugAI.HoarderBugItems.Where((HoarderBugItem i) => i != null && (Object)(object)i.itemGrabbableObject != (Object)null && i.itemNestPosition == bug.nestPosition).ToList(); if (bug.heldItem != null) { list.Remove(bug.heldItem); } w.Write(list.Count); foreach (HoarderBugItem item in list) { WriteObject(w, (Component?)(object)item.itemGrabbableObject); w.Write((int)item.status); } } private static void ApplyHoardingBug(EnemyAI e, BinaryReader r) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_009a: Expected O, but got Unknown HoarderBugAI bug = (HoarderBugAI)e; bug.nestPosition = ReadVector(r); NetworkObject val = ReadObject(r); HoarderBugAI.HoarderBugItems.RemoveAll((HoarderBugItem i) => i == null || (Object)(object)i.itemGrabbableObject == (Object)null || i.itemNestPosition == bug.nestPosition); int num = r.ReadInt32(); for (int num2 = 0; num2 < num; num2++) { NetworkObject val2 = ReadObject(r); HoarderBugItemStatus val3 = (HoarderBugItemStatus)r.ReadInt32(); GrabbableObject val4 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<GrabbableObject>() : null); if ((Object)(object)val4 != (Object)null) { HoarderBugAI.HoarderBugItems.Add(new HoarderBugItem(val4, val3, bug.nestPosition)); } } if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<GrabbableObject>() != (Object)null) { AccessTools.Method(typeof(HoarderBugAI), "GrabItem", (Type[])null, (Type[])null).Invoke(bug, new object[1] { val }); } } private static void DescribeBaboonHawk(EnemyAI e, BinaryWriter w) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) WriteObject(w, (Component?)(object)((BaboonBirdAI)e).heldScrap); Traverse val = Traverse.Create((object)e); w.Write(val.Field<int>("aggressiveMode").Value); w.Write(e.creatureAnimator.GetBool("sit") || e.creatureAnimator.GetBool("sleep")); w.Write(val.Field<bool>("eyesClosed").Value); w.Write(val.Field<bool>("restingAtCamp").Value); } private static void ApplyBaboonHawk(EnemyAI e, BinaryReader r) { NetworkObject val = ReadObject(r); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<GrabbableObject>() != (Object)null) { AccessTools.Method(typeof(BaboonBirdAI), "GrabScrap", (Type[])null, (Type[])null).Invoke(e, new object[1] { val }); } Traverse val2 = Traverse.Create((object)e); val2.Field<int>("aggressiveMode").Value = r.ReadInt32(); bool num = r.ReadBoolean(); bool flag = r.ReadBoolean(); bool value = r.ReadBoolean(); if (num) { val2.Field<bool>("restingAtCamp").Value = value; val2.Field<bool>("eyesClosed").Value = flag; e.creatureAnimator.SetBool("sleep", flag); e.creatureAnimator.SetBool("sit", !flag); } } private static void DescribeSapsucker(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GiantKiwiAI val = (GiantKiwiAI)e; Traverse val2 = Traverse.Create((object)e); w.Write(val2.Field<bool>("hasSpawnedEggs").Value); List<KiwiBabyItem> list = val.eggs.Where((KiwiBabyItem egg) => (Object)(object)egg != (Object)null).ToList(); w.Write(list.Count); foreach (KiwiBabyItem item in list) { WriteObject(w, (Component?)(object)item); } KiwiBabyItem value = val2.Field<KiwiBabyItem>("takeEggBackToNest").Value; WriteObject(w, (Component?)(object)(val.carryingEgg ? value : null)); IVisibleThreat value2 = val2.Field<IVisibleThreat>("attackingThreat").Value; WriteObject(w, (Component?)(object)((value2 is Component) ? value2 : null)); IVisibleThreat value3 = val2.Field<IVisibleThreat>("watchingThreat").Value; WriteObject(w, (Component?)(object)((value3 is Component) ? value3 : null)); w.Write(Slot(((EnemyAI)val).targetPlayer)); w.Write(Slot(val.abandonedThreat)); int[] array = (from tr in val2.Field<List<Transform>>("seenThreatsHoldingEgg").Value select (!((Object)(object)tr != (Object)null)) ? (-1) : Slot(((Component)tr).GetComponentInParent<PlayerControllerB>()) into i where i >= 0 select i).ToArray(); w.Write(array.Length); int[] array2 = array; foreach (int value4 in array2) { w.Write(value4); } w.Write(val2.Field<int>("idleBehaviour").Value); w.Write(e.creatureAnimator.GetBool("Asleep")); w.Write(val2.Field<bool>("isPeckingTree").Value); } private static void ApplySapsucker(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GiantKiwiAI val = (GiantKiwiAI)e; Traverse.Create((object)e).Field<bool>("hasSpawnedEggs").Value = r.ReadBoolean(); int num = r.ReadInt32(); val.eggs.Clear(); for (int i = 0; i < num; i++) { NetworkObject? obj = ReadObject(r); KiwiBabyItem val2 = ((obj != null) ? ((Component)obj).GetComponent<KiwiBabyItem>() : null); if (!((Object)(object)val2 == (Object)null)) { val.eggs.Add(val2); ScanNodeProperties componentInChildren = ((Component)val2).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.headerText = "Egg"; } } } NetworkObject val3 = ReadObject(r); if ((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).GetComponent<KiwiBabyItem>() != (Object)null) { AccessTools.Method(typeof(GiantKiwiAI), "GrabScrap", (Type[])null, (Type[])null).Invoke(val, new object[1] { val3 }); } Traverse val4 = Traverse.Create((object)e); NetworkObject val5 = ReadObject(r); NetworkObject val6 = ReadObject(r); IVisibleThreat value = default(IVisibleThreat); if ((Object)(object)val5 != (Object)null && ((Component)val5).TryGetComponent<IVisibleThreat>(ref value)) { val4.Field<IVisibleThreat>("attackingThreat").Value = value; } IVisibleThreat value2 = default(IVisibleThreat); if ((Object)(object)val6 != (Object)null && ((Component)val6).TryGetComponent<IVisibleThreat>(ref value2)) { val4.Field<IVisibleThreat>("watchingThreat").Value = value2; } ((EnemyAI)val).targetPlayer = Player(r.ReadInt32()); val.abandonedThreat = Player(r.ReadInt32()); int[] array = new int[r.ReadInt32()]; for (int j = 0; j < array.Length; j++) { array[j] = r.ReadInt32(); } if (array.Length != 0) { AccessTools.Method(typeof(GiantKiwiAI), "AddPlayerIDsToSeenThreatsHoldingEggsList", (Type[])null, (Type[])null).Invoke(val, new object[1] { array }); } val4.Field<int>("idleBehaviour").Value = r.ReadInt32(); if (r.ReadBoolean()) { ((EnemyAI)val).creatureSFX.Play(); ((EnemyAI)val).creatureAnimator.SetBool("Asleep", true); } bool flag = r.ReadBoolean(); val4.Field<bool>("isPeckingTree").Value = flag; ((EnemyAI)val).creatureAnimator.SetBool("peckTree", flag); } private static void DescribeManeater(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) CaveDwellerAI val = (CaveDwellerAI)e; Traverse val2 = Traverse.Create((object)e); w.Write(val.adultContainer.activeSelf); w.Write(val.leapSpeed); Write(w, val2.Field<Vector3>("caveHidingSpot").Value); w.Write(val2.Field<bool>("isFakingBabyVoice").Value); w.Write(val2.Field<bool>("clickingMandibles").Value); w.Write(val2.Field<bool>("chasingAfterLeap").Value); w.Write(val.babyCrying); w.Write(val.rolledOver); w.Write(val2.Field<int>("scrapEaten").Value); Write(w, val.spine2.localScale); } private static void ApplyManeater(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) CaveDwellerAI val = (CaveDwellerAI)e; Traverse val2 = Traverse.Create((object)e); bool flag = r.ReadBoolean(); if (flag && !val.adultContainer.activeSelf) { ((EnemyAI)val).agent.acceleration = 425f; ((EnemyAI)val).agent.angularSpeed = 700f; ((EnemyAI)val).syncMovementSpeed = 0.15f; ((EnemyAI)val).addPlayerVelocityToDestination = 1f; ((EnemyAI)val).updatePositionThreshold = 0.8f; ((GrabbableObject)val.propScript).EnablePhysics(false); ((GrabbableObject)val.propScript).grabbable = false; ((GrabbableObject)val.propScript).grabbableToEnemies = false; ((Behaviour)val.propScript).enabled = false; val.babyContainer.SetActive(false); val.adultContainer.SetActive(true); } val.leapSpeed = r.ReadSingle(); val2.Field<Vector3>("caveHidingSpot").Value = ReadVector(r); val2.Field<bool>("isFakingBabyVoice").Value = r.ReadBoolean(); val2.Field<bool>("clickingMandibles").Value = r.ReadBoolean(); bool flag2 = r.ReadBoolean(); val2.Field<bool>("chasingAfterLeap").Value = flag2; if (flag2) { ((EnemyAI)val).syncMovementSpeed = 0.2f; } bool flag3 = r.ReadBoolean(); bool flag4 = r.ReadBoolean(); int value = r.ReadInt32(); Vector3 localScale = ReadVector(r); if (!flag) { if (flag3 != val.babyCrying) { AccessTools.Method(typeof(CaveDwellerAI), "SetCryingLocalClient", (Type[])null, (Type[])null).Invoke(val, new object[1] { flag3 }); } if (flag4 != val.rolledOver) { AccessTools.Method(typeof(CaveDwellerAI), "SetRolledOverLocalClient", (Type[])null, (Type[])null).Invoke(val, new object[2] { flag4, false }); } val2.Field<int>("scrapEaten").Value = value; val.spine2.localScale = localScale; } else { val.babyCrying = flag3; } } private static void DescribeBees(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) RedLocustBees val = (RedLocustBees)e; Traverse val2 = Traverse.Create((object)e); WriteObject(w, (Component?)(object)(val2.Field<bool>("hasSpawnedHive").Value ? val.hive : null)); Write(w, val.lastKnownHivePosition); w.Write(val2.Field<bool>("syncedLastKnownHivePosition").Value); } private static void ApplyBees(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //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) RedLocustBees val = (RedLocustBees)e; Traverse val2 = Traverse.Create((object)e); NetworkObject? obj = ReadObject(r); GrabbableObject val3 = ((obj != null) ? ((Component)obj).GetComponent<GrabbableObject>() : null); val.lastKnownHivePosition = ReadVector(r); val2.Field<bool>("syncedLastKnownHivePosition").Value = r.ReadBoolean(); if ((Object)(object)val3 != (Object)null) { val.hive = val3; ScanNodeProperties componentInChildren = ((Component)val3).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.headerText = "Bee hive"; } val2.Field<bool>("hasSpawnedHive").Value = true; } } private static void DescribeBarber(EnemyAI e, BinaryWriter w) { w.Write(Traverse.Create((object)e).Field<bool>("isMaster").Value); } private static void ApplyBarber(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ClaySurgeonAI val = (ClaySurgeonAI)e; if (r.ReadBoolean() && (Object)(object)val.master == (Object)null) { MoonRebuild.RunAsReceived((NetworkBehaviour)(object)val, (Action)val.SyncMasterClaySurgeonClientRpc); } } private static void DescribeGhostGirl(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown DressGirlAI val = (DressGirlAI)e; w.Write(Slot(val.hauntingPlayer)); w.Write(Traverse.Create((object)e).Field<int>("timesChoosingAPlayer").Value); } private static void ApplyGhostGirl(EnemyAI e, BinaryReader r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown DressGirlAI val = (DressGirlAI)e; PlayerControllerB val2 = Player(r.ReadInt32()); Traverse.Create((object)e).Field<int>("timesChoosingAPlayer").Value = r.ReadInt32(); if ((Object)(object)val2 != (Object)null) { val.hauntingPlayer = val2; val.hauntingLocalPlayer = (Object)(object)val2 == (Object)(object)GameNetworkManager.Instance.localPlayerController; } } private static void DescribeSnareFlea(EnemyAI e, BinaryWriter w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) CentipedeAI val = (CentipedeAI)e; w.Write(e.currentBehaviourStateIndex); Write(w, val.ceilingHidingPoint); w.Write(Slot(val.clingingToPlayer)); } private static void ApplySnareFlea(EnemyAI e, BinaryReader r) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005d: 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) CentipedeAI flea = (CentipedeAI)e; int num = r.ReadInt32(); Vector3 ceiling = ReadVector(r); PlayerControllerB val = Player(r.ReadInt32()); flea.ceilingHidingPoint = ceiling; if ((Object)(object)val != (Object)null) { ClingToPlayer(flea, val); } else if (num == 1 && ceiling != Vector3.zero) { MoonRebuild.RunAsReceived((NetworkBehaviour)(object)flea, delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) flea.SwitchToHidingOnCeilingClientRpc(ceiling); }); } } private static void ClingToPlayer(CentipedeAI flea, PlayerControllerB victim) { Traverse val = Traverse.Create((object)flea); Coroutine value = val.Field<Coroutine>("ceilingAnimationCoroutine").Value; if (value != null) { ((MonoBehaviour)flea).StopCoroutine(value); val.Field<Coroutine>("ceilingAnimationCoroutine").Value = null; } val.Field<bool>("startedCeilingAnimationCoroutine").Value = false; val.Field<bool>("clingingToCeiling").Value = false; val.Fi