using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Interaction; using Il2CppSystem.Collections.Generic; using LabFusion.Data.Serializables; using LabFusion.Entities; using LabFusion.Extensions; using LabFusion.Marrow.Extenders; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.SDK.Modules; using MelonLoader; using Microsoft.CodeAnalysis; using SpiderLab.Behaviours; using SpiderLab.Data; using SpiderlabFusionSync; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(SpiderlabFusionMod), "SpiderLab Fusion Sync Compat", "2.8.0", "notnotnotswipez; Patch 6 compatibility rebuild", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonAdditionalDependencies(new string[] { "LabFusion", "SpiderLab" })] [assembly: AssemblyFileVersion("2.8.0.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.8.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 SpiderlabFusionSync { public sealed class RepWebShooter : IDisposable { private sealed class WebVisual { public Hand Hand; public WebLine Line; public Rigidbody Body; public Vector3 Point; public bool Active; public uint Generation; public Vector3 WorldPoint { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)Body == (Object)null)) { return ((Component)Body).transform.TransformPoint(Point); } return Point; } } } private static readonly Dictionary Managers = new Dictionary(); private readonly WebVisual _left; private readonly WebVisual _right; private readonly AudioSource _audioSource; private RepWebShooter(RigManager rigManager) { _left = CreateVisual(rigManager.physicsRig.leftHand); _right = CreateVisual(rigManager.physicsRig.rightHand); _audioSource = ((Component)((Rig)rigManager.physicsRig).m_pelvis).gameObject.AddComponent(); _audioSource.playOnAwake = false; _audioSource.minDistance = 0.5f; _audioSource.spatialBlend = 1f; } public static bool TryGet(byte playerId, out RepWebShooter shooter) { return Managers.TryGetValue(playerId, out shooter); } public static void AddOrReplace(byte playerId, RigManager rigManager) { if (Managers.Remove(playerId, out var value)) { value.Dispose(); } Managers[playerId] = new RepWebShooter(rigManager); } public static void UpdateAll() { List list = null; foreach (KeyValuePair manager in Managers) { if (!NetworkPlayerManager.HasPlayer(manager.Key)) { (list ?? (list = new List())).Add(manager.Key); } else { manager.Value.Update(); } } if (list == null) { return; } foreach (byte item in list) { Managers[item].Dispose(); Managers.Remove(item); } } public static void DisposeAll() { foreach (RepWebShooter value in Managers.Values) { value.Dispose(); } Managers.Clear(); } public uint BeginWeb(byte hand) { WebVisual webVisual = Select(hand); webVisual.Generation++; return webVisual.Generation; } public void MakeWeb(byte hand, Vector3 point, Rigidbody body, uint generation) { //IL_001b: 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_0045: 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) WebVisual webVisual = Select(hand); if (webVisual.Generation == generation) { webVisual.Body = body; webVisual.Point = point; webVisual.Active = true; webVisual.Line.SetActive(true); webVisual.Line.UpdateLine(webVisual.Hand.palmPositionTransform.position, webVisual.WorldPoint); PlayAudio(Bundles.webLineAudioHigh, Bundles.webLineAudioLow); } } public void DestroyWeb(byte hand) { WebVisual webVisual = Select(hand); webVisual.Generation++; webVisual.Active = false; webVisual.Body = null; webVisual.Line.SetActive(false); } public void Dispose() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown DestroyVisual(_left); DestroyVisual(_right); if ((Object)_audioSource != (Object)null) { Object.Destroy((Object)_audioSource); } } private void Update() { UpdateVisual(_left); UpdateVisual(_right); } private static WebVisual CreateVisual(Hand hand) { WebLine val = Object.Instantiate(Bundles.webLinePrefab, ((Component)hand).transform).AddComponent(); val.SetActive(false); return new WebVisual { Hand = hand, Line = val }; } private static void UpdateVisual(WebVisual visual) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (visual.Active && !((Object)visual.Hand == (Object)null) && !((Object)visual.Line == (Object)null)) { visual.Line.UpdateLine(visual.Hand.palmPositionTransform.position, visual.WorldPoint); } } private static void DestroyVisual(WebVisual visual) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (visual != null && (Object)visual.Line != (Object)null) { Object.Destroy((Object)((Component)visual.Line).gameObject); } } private WebVisual Select(byte hand) { if (hand != 2) { return _left; } return _right; } private void PlayAudio(AudioClip high, AudioClip low) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (!((Object)high == (Object)null) && !((Object)low == (Object)null)) { _audioSource.loop = false; _audioSource.PlayOneShot((Random.value > 0.5f) ? high : low, 0.5f); } } } public sealed class SpiderDisarmRequestData : INetSerializable { public uint RequestId; public NetworkEntityReference Entity = new NetworkEntityReference(); public int? GetSize() { return null; } public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref RequestId); NetSerializerExtensions.SerializeValue(serializer, ref Entity); } public static SpiderDisarmRequestData Create(uint requestId, NetworkEntity entity) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return new SpiderDisarmRequestData { RequestId = requestId, Entity = new NetworkEntityReference(entity) }; } } public sealed class SpiderDisarmAckData : INetSerializable { public uint RequestId; public NetworkEntityReference Entity = new NetworkEntityReference(); public byte HandMask; public bool Accepted; public int? GetSize() { return null; } public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref RequestId); NetSerializerExtensions.SerializeValue(serializer, ref Entity); serializer.SerializeValue(ref HandMask); serializer.SerializeValue(ref Accepted); } } internal static class SpiderDisarmManager { private sealed class PendingDisarm { public uint RequestId; public WebShooter Shooter; public Rigidbody Body; public NetworkEntity Entity; public float Intensity; public float StartedAt; public int ResumeFrame; public bool OwnershipRequested; public readonly Dictionary ExpectedHands = new Dictionary(); public readonly HashSet AcknowledgedPlayers = new HashSet(); } private const byte LeftHandMask = 1; private const byte RightHandMask = 2; private const float TransactionTimeout = 1f; private const float RetryCooldown = 0.5f; private static readonly Dictionary PendingByShooter = new Dictionary(); private static readonly Dictionary RetryAfter = new Dictionary(); private static uint nextRequestId = 1u; public static void Initialize() { WebShooter.TargetPullIntercepted += OnTargetPullIntercepted; } public static void Deinitialize() { WebShooter.TargetPullIntercepted -= OnTargetPullIntercepted; PendingByShooter.Clear(); RetryAfter.Clear(); } public static void Cancel(WebShooter shooter) { if ((Object)(object)shooter != (Object)null) { PendingByShooter.Remove(shooter); } } public static void Update() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown if (PendingByShooter.Count == 0) { return; } foreach (PendingDisarm item in new List(PendingByShooter.Values)) { if (!IsPendingCurrent(item)) { continue; } if ((Object)item.Shooter == (Object)null || (Object)item.Body == (Object)null || item.Entity == null) { Fail(item, "web or target disappeared"); continue; } RemoveDisconnectedHolders(item); if (Time.unscaledTime - item.StartedAt >= 1f) { Fail(item, GetTimeoutReason(item)); continue; } if (!item.OwnershipRequested && AllHoldersAcknowledged(item)) { BeginOwnershipTransfer(item); } if (item.OwnershipRequested && item.Entity.IsOwner && !item.Body.isKinematic && Time.frameCount >= item.ResumeFrame) { PendingByShooter.Remove(item.Shooter); if (!item.Shooter.ResumeTargetPull(item.Body, item.Intensity)) { RetryAfter[item.Shooter] = Time.unscaledTime + 0.5f; } } } } private static bool OnTargetPullIntercepted(WebShooter shooter, Rigidbody body, float intensity) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0126: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) if (!NetworkInfo.HasServer || (Object)(object)shooter == (Object)null || (Object)body == (Object)null || IsPlayerBody(body)) { return false; } if (!TryGetTarget(body, out var entity, out var grips)) { return false; } if (!entity.IsRegistered || entity.ID == 0) { RetryAfter[shooter] = Time.unscaledTime + 0.5f; MelonLogger.Warning("SpiderLab target pull is waiting for Fusion to register the webbed object."); return true; } if (RetryAfter.TryGetValue(shooter, out var value) && Time.unscaledTime < value) { return true; } RetryAfter.Remove(shooter); bool hasUnmappedHands; Dictionary dictionary = FindPlayerHolders(grips, out hasUnmappedHands); if (dictionary.Count == 0 && entity.IsOwner && !body.isKinematic) { return false; } if (entity.IsOwnerLocked) { RetryAfter[shooter] = Time.unscaledTime + 0.5f; MelonLogger.Warning("SpiderLab target pull blocked because the Fusion object's ownership is locked."); return true; } if (hasUnmappedHands) { RetryAfter[shooter] = Time.unscaledTime + 0.5f; MelonLogger.Warning("SpiderLab disarm blocked because one or more item holders could not be resolved as Fusion players."); return true; } if (PendingByShooter.TryGetValue(shooter, out var value2)) { if ((Object)value2.Body == (Object)body) { value2.Intensity = Mathf.Max(value2.Intensity, intensity); return true; } PendingByShooter.Remove(shooter); } uint requestId = nextRequestId++; if (nextRequestId == 0) { nextRequestId = 1u; } PendingDisarm pendingDisarm = new PendingDisarm { RequestId = requestId, Shooter = shooter, Body = body, Entity = entity, Intensity = Mathf.Clamp01(intensity), StartedAt = Time.unscaledTime }; foreach (KeyValuePair item in dictionary) { pendingDisarm.ExpectedHands[item.Key] = item.Value; } PendingByShooter[shooter] = pendingDisarm; if (pendingDisarm.ExpectedHands.Count > 0) { SpiderDisarmRequestData spiderDisarmRequestData = SpiderDisarmRequestData.Create(requestId, entity); foreach (byte key in pendingDisarm.ExpectedHands.Keys) { if (key == PlayerIDManager.LocalSmallID) { byte handMask = DetachLocalHands(entity); MarkAcknowledged(pendingDisarm, key, handMask); } else { MessageRelay.RelayModule(spiderDisarmRequestData, new MessageRoute(key, (NetworkChannel)0)); } } } if (AllHoldersAcknowledged(pendingDisarm)) { BeginOwnershipTransfer(pendingDisarm); } return true; } public static void HandleRequest(byte requesterId, SpiderDisarmRequestData data) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown if (data != null && data.Entity.ID != 0) { ((NetworkEntityReference)(ref data.Entity)).HookEntityRegistered((NetworkEntityDelegate)delegate(NetworkEntity entity) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) bool flag = entity != null && entity.IsRegistered && !entity.IsOwnerLocked && !IsPlayerEntity(entity) && entity.GetExtender() != null; byte handMask = (byte)(flag ? DetachLocalHands(entity) : 0); MessageRelay.RelayModule(new SpiderDisarmAckData { RequestId = data.RequestId, Entity = data.Entity, HandMask = handMask, Accepted = flag }, new MessageRoute(requesterId, (NetworkChannel)0)); }); } } public static void HandleAck(byte holderId, SpiderDisarmAckData data) { if (data == null || data.Entity.ID == 0) { return; } PendingDisarm pendingDisarm = FindPending(data.RequestId); if (pendingDisarm == null || !pendingDisarm.ExpectedHands.ContainsKey(holderId) || pendingDisarm.AcknowledgedPlayers.Contains(holderId)) { return; } if (!data.Accepted) { Fail(pendingDisarm, $"player {holderId} rejected an invalid or ownership-locked disarm target"); return; } if (data.Entity.ID != pendingDisarm.Entity.ID) { Fail(pendingDisarm, "holder acknowledgement referenced a different Fusion entity"); return; } byte handMask = ((data.HandMask != 0) ? data.HandMask : pendingDisarm.ExpectedHands[holderId]); MarkAcknowledged(pendingDisarm, holderId, handMask); if (AllHoldersAcknowledged(pendingDisarm)) { BeginOwnershipTransfer(pendingDisarm); } } private static void MarkAcknowledged(PendingDisarm pending, byte holderId, byte handMask) { NetworkPlayer player = default(NetworkPlayer); if (pending.AcknowledgedPlayers.Add(holderId) && holderId != PlayerIDManager.LocalSmallID && NetworkPlayerManager.TryGetPlayer(holderId, ref player)) { DetachRemoteRepresentation(player, pending.Entity, handMask); } } private static void BeginOwnershipTransfer(PendingDisarm pending) { if (pending.OwnershipRequested || !IsPendingCurrent(pending)) { return; } if (pending.Entity == null || pending.Entity.IsOwnerLocked) { Fail(pending, "item ownership became locked before transfer"); return; } pending.OwnershipRequested = true; pending.ResumeFrame = Time.frameCount + 2; if (!pending.Entity.IsOwner) { NetworkEntityManager.TakeOwnership(pending.Entity); } } private static Dictionary FindPlayerHolders(List grips, out bool hasUnmappedHands) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 Dictionary dictionary = new Dictionary(); hasUnmappedHands = false; NetworkPlayer val = default(NetworkPlayer); foreach (Grip grip in grips) { Enumerator enumerator2 = grip.attachedHands.GetEnumerator(); while (enumerator2.MoveNext()) { Hand current = enumerator2.Current; if (!((Object)current == (Object)null) && !((Object)current.manager == (Object)null)) { if (!NetworkPlayerManager.TryGetPlayer(current.manager, ref val)) { hasUnmappedHands = true; continue; } byte b = (byte)(((int)current.handedness == 1) ? 1 : 2); byte smallID = val.PlayerID.SmallID; dictionary[smallID] = (dictionary.TryGetValue(smallID, out var value) ? ((byte)(value | b)) : b); } } } return dictionary; } private static byte DetachLocalHands(NetworkEntity targetEntity) { NetworkPlayer networkPlayer = LocalPlayer.GetNetworkPlayer(); if (networkPlayer == null || !networkPlayer.HasRig) { return 0; } byte b = 0; if (HandHoldsEntity(networkPlayer.RigRefs.LeftHand, targetEntity)) { HandExtensions.TryDetach(networkPlayer.RigRefs.LeftHand); b |= 1; } if (HandHoldsEntity(networkPlayer.RigRefs.RightHand, targetEntity)) { HandExtensions.TryDetach(networkPlayer.RigRefs.RightHand); b |= 2; } return b; } private static void DetachRemoteRepresentation(NetworkPlayer player, NetworkEntity targetEntity, byte handMask) { if (player != null && player.HasRig) { if ((handMask & 1) != 0 && HandHoldsEntity(player.RigRefs.LeftHand, targetEntity)) { player.Grabber.Detach((Handedness)1); } if ((handMask & 2) != 0 && HandHoldsEntity(player.RigRefs.RightHand, targetEntity)) { player.Grabber.Detach((Handedness)2); } } } private static bool HandHoldsEntity(Hand hand, NetworkEntity targetEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if ((Object)hand == (Object)null || (Object)(object)hand.m_CurrentAttachedGO == (Object)null) { return false; } Grip component = hand.m_CurrentAttachedGO.GetComponent(); NetworkEntity val = default(NetworkEntity); if ((Object)component != (Object)null && GripExtender.Cache.TryGet(component, ref val)) { return val == targetEntity; } return false; } private static bool TryGetTarget(Rigidbody body, out NetworkEntity entity, out List grips) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00c6: Expected O, but got Unknown entity = null; grips = new List(); if ((Object)body == (Object)null || IsPlayerBody(body)) { return false; } InteractableHost val = ((Component)body).GetComponentInParent(); if ((Object)val == (Object)null) { val = ((Component)body).GetComponentInChildren(); } Transform obj = (((Object)val != (Object)null) ? ((Component)val).transform : ((Component)body).transform.root); GameObject val2 = (((Object)val != (Object)null) ? ((Component)val).gameObject : null); NetworkEntity val3 = default(NetworkEntity); foreach (Grip componentsInChild in ((Component)obj).GetComponentsInChildren(true)) { if (!((Object)componentsInChild == (Object)null) && ((HandReciever)componentsInChild).HasHost && (((Object)(object)val2 != (Object)null) ? ((Object)(object)((HandReciever)componentsInChild).Host.GetHostGameObject() == (Object)(object)val2) : ((Object)((HandReciever)componentsInChild).Host.Rb == (Object)body)) && GripExtender.Cache.TryGet(componentsInChild, ref val3)) { if (entity == null) { entity = val3; } if (val3 == entity) { grips.Add(componentsInChild); } } } if (entity != null) { return grips.Count > 0; } return false; } private static bool IsPlayerBody(Rigidbody body) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if ((Object)body == (Object)null) { return false; } if ((Object)((Component)body).GetComponentInParent() != (Object)null) { return true; } Transform root = ((Component)body).transform.root; if ((Object)root == (Object)null) { return false; } string name = ((Object)root).name; if (!name.StartsWith("[RigManager (Networked)]", StringComparison.Ordinal)) { return name.StartsWith("[RigManager (FUSION PlayerRep)]", StringComparison.Ordinal); } return true; } private static bool IsPlayerEntity(NetworkEntity entity) { if (entity == null) { return false; } foreach (NetworkPlayer player in NetworkPlayer.Players) { if (player != null && player.NetworkEntity == entity) { return true; } } return false; } private static PendingDisarm FindPending(uint requestId) { foreach (PendingDisarm value in PendingByShooter.Values) { if (value.RequestId == requestId) { return value; } } return null; } private static bool AllHoldersAcknowledged(PendingDisarm pending) { foreach (byte key in pending.ExpectedHands.Keys) { if (!pending.AcknowledgedPlayers.Contains(key)) { return false; } } return true; } private static void RemoveDisconnectedHolders(PendingDisarm pending) { List list = null; foreach (byte key in pending.ExpectedHands.Keys) { if (key != PlayerIDManager.LocalSmallID && !NetworkPlayerManager.HasPlayer(key)) { (list ?? (list = new List())).Add(key); } } if (list == null) { return; } foreach (byte item in list) { pending.ExpectedHands.Remove(item); pending.AcknowledgedPlayers.Remove(item); } } private static bool IsPendingCurrent(PendingDisarm pending) { if (pending != null && (Object)(object)pending.Shooter != (Object)null && PendingByShooter.TryGetValue(pending.Shooter, out var value)) { return value == pending; } return false; } private static string GetTimeoutReason(PendingDisarm pending) { if (!AllHoldersAcknowledged(pending)) { List list = new List(); foreach (byte key in pending.ExpectedHands.Keys) { if (!pending.AcknowledgedPlayers.Contains(key)) { list.Add(key); } } return "no matching 2.7.1 disarm acknowledgement from Fusion player(s) " + string.Join(", ", list); } if (!pending.Entity.IsOwner) { return "Fusion ownership transfer timed out"; } if (pending.Body.isKinematic) { return "Fusion kept the owned target kinematic"; } return "transaction timed out"; } private static void Fail(PendingDisarm pending, string reason) { if (pending != null && !((Object)(object)pending.Shooter == (Object)null)) { PendingByShooter.Remove(pending.Shooter); RetryAfter[pending.Shooter] = Time.unscaledTime + 0.5f; MelonLogger.Warning("SpiderLab Fusion target pull cancelled: " + reason + "."); } } } public sealed class SpiderDisarmRequestMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (((ReceivedMessage)(ref received)).Sender.HasValue && ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID && NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value)) { SpiderDisarmManager.HandleRequest(((ReceivedMessage)(ref received)).Sender.Value, ((ReceivedMessage)(ref received)).ReadData()); } } } public sealed class SpiderDisarmAckMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (((ReceivedMessage)(ref received)).Sender.HasValue && ((ReceivedMessage)(ref received)).Sender.Value != PlayerIDManager.LocalSmallID && NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value)) { SpiderDisarmManager.HandleAck(((ReceivedMessage)(ref received)).Sender.Value, ((ReceivedMessage)(ref received)).ReadData()); } } } public sealed class SpiderlabFusionMod : MelonMod { public override void OnInitializeMelon() { if (ModuleMessageManager.GetHandlerByType(typeof(SpiderWebMessage)) == null) { ModuleMessageManager.RegisterHandler(); } if (ModuleMessageManager.GetHandlerByType(typeof(SpiderPullMessage)) == null) { ModuleMessageManager.RegisterHandler(); } if (ModuleMessageManager.GetHandlerByType(typeof(SpiderDisarmRequestMessage)) == null) { ModuleMessageManager.RegisterHandler(); } if (ModuleMessageManager.GetHandlerByType(typeof(SpiderDisarmAckMessage)) == null) { ModuleMessageManager.RegisterHandler(); } NetworkPlayer.OnNetworkRigCreated += OnNetworkRigCreated; WebShooter.WebCreated += OnLocalWebCreated; WebShooter.WebDestroyed += OnLocalWebDestroyed; WebShooter.TargetPulled += OnLocalTargetPulled; SpiderDisarmManager.Initialize(); foreach (NetworkPlayer player in NetworkPlayer.Players) { if (player.HasRig) { OnNetworkRigCreated(player, player.RigRefs.RigManager); } } MelonLogger.Msg("SpiderLab Fusion Sync compatibility module initialized."); } public override void OnDeinitializeMelon() { NetworkPlayer.OnNetworkRigCreated -= OnNetworkRigCreated; WebShooter.WebCreated -= OnLocalWebCreated; WebShooter.WebDestroyed -= OnLocalWebDestroyed; WebShooter.TargetPulled -= OnLocalTargetPulled; SpiderDisarmManager.Deinitialize(); RepWebShooter.DisposeAll(); } public override void OnUpdate() { RepWebShooter.UpdateAll(); SpiderDisarmManager.Update(); } private static void OnNetworkRigCreated(NetworkPlayer player, RigManager rigManager) { if (player != null && !((Object)(object)rigManager == (Object)null) && !player.NetworkEntity.IsOwner) { RepWebShooter.AddOrReplace(player.PlayerID.SmallID, rigManager); } } private static void OnLocalWebCreated(WebShooter shooter, RaycastHit hit) { //IL_0022: 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) if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null)) { MessageRelay.RelayModule(SpiderWebData.CreateWeb(shooter.Hand, hit), CommonMessageRoutes.ReliableToOtherClients); } } private static void OnLocalWebDestroyed(WebShooter shooter) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) SpiderDisarmManager.Cancel(shooter); if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null)) { MessageRelay.RelayModule(SpiderWebData.CreateDestroy(shooter.Hand), CommonMessageRoutes.ReliableToOtherClients); } } private static void OnLocalTargetPulled(WebShooter shooter, Rigidbody body, Vector3 velocityChange) { //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_0036: Unknown result type (might be due to invalid IL or missing references) if (NetworkInfo.HasServer && !((Object)(object)((shooter != null) ? shooter.Hand : null) == (Object)null) && !((Object)(object)body == (Object)null)) { MessageRelay.RelayModule(SpiderPullData.Create(body, Vector3.ClampMagnitude(velocityChange, 50f)), CommonMessageRoutes.ReliableToOtherClients); } } } public sealed class SpiderPullData : INetSerializable { public GameObjectReference Body = new GameObjectReference(); public Vector3 VelocityChange; public int? GetSize() { return null; } public void Serialize(INetSerializer serializer) { NetSerializerExtensions.SerializeValue(serializer, ref Body); NetSerializerUnityExtensions.SerializeValue(serializer, ref VelocityChange); } public static SpiderPullData Create(Rigidbody body, Vector3 velocityChange) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0023: 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) return new SpiderPullData { Body = new GameObjectReference(((Object)(object)body == (Object)null) ? null : ((Component)body).gameObject), VelocityChange = velocityChange }; } } public sealed class SpiderPullMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { //IL_004e: 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_005d: Unknown result type (might be due to invalid IL or missing references) if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value == PlayerIDManager.LocalSmallID || !NetworkPlayerManager.HasPlayer(((ReceivedMessage)(ref received)).Sender.Value)) { return; } SpiderPullData spiderPullData = ((ReceivedMessage)(ref received)).ReadData(); Vector3 velocityChange = Vector3.ClampMagnitude(spiderPullData.VelocityChange, 50f); spiderPullData.Body.HookGameObjectFound((Action)delegate(GameObject gameObject) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Rigidbody val = (((Object)(object)gameObject == (Object)null) ? null : gameObject.GetComponent()); if ((Object)(object)val != (Object)null && !val.isKinematic) { val.AddForce(velocityChange, (ForceMode)2); } }); } } public sealed class SpiderWebData : INetSerializable { public bool IsDestroy; public byte Hand; public GameObjectReference Body = new GameObjectReference(); public Vector3 Position; public float Distance; public int? GetSize() { return null; } public void Serialize(INetSerializer serializer) { serializer.SerializeValue(ref IsDestroy); serializer.SerializeValue(ref Hand); NetSerializerExtensions.SerializeValue(serializer, ref Body); NetSerializerUnityExtensions.SerializeValue(serializer, ref Position); serializer.SerializeValue(ref Distance); } public static SpiderWebData CreateDestroy(Hand hand) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) return new SpiderWebData { IsDestroy = true, Hand = (byte)hand.handedness, Body = new GameObjectReference((GameObject)null), Position = Vector3.zero, Distance = 0f }; } public static SpiderWebData CreateWeb(Hand hand, RaycastHit hit) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_006b: 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) Rigidbody rigidbody = ((RaycastHit)(ref hit)).rigidbody; GameObject val = (((Object)rigidbody == (Object)null) ? null : ((Component)rigidbody).gameObject); Vector3 position = (((Object)(object)val == (Object)null) ? ((RaycastHit)(ref hit)).point : val.transform.InverseTransformPoint(((RaycastHit)(ref hit)).point)); return new SpiderWebData { IsDestroy = false, Hand = (byte)hand.handedness, Body = new GameObjectReference(val), Position = position, Distance = ((RaycastHit)(ref hit)).distance }; } } public sealed class SpiderWebMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (!((ReceivedMessage)(ref received)).Sender.HasValue || ((ReceivedMessage)(ref received)).Sender.Value == PlayerIDManager.LocalSmallID) { return; } byte value = ((ReceivedMessage)(ref received)).Sender.Value; if (!NetworkPlayerManager.HasPlayer(value) || !RepWebShooter.TryGet(value, out var shooter)) { return; } SpiderWebData data = ((ReceivedMessage)(ref received)).ReadData(); if (data.IsDestroy) { shooter.DestroyWeb(data.Hand); return; } uint generation = shooter.BeginWeb(data.Hand); data.Body.HookGameObjectFound((Action)delegate(GameObject gameObject) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) Rigidbody body = (((Object)(object)gameObject == (Object)null) ? null : gameObject.GetComponent()); shooter.MakeWeb(data.Hand, data.Position, body, generation); }); } } }