diff --git a/BoneSync/Networking/Messages/PlugSyncMessage.cs b/BoneSync/Networking/Messages/PlugSyncMessage.cs index 674d45a..d5135a4 100644 --- a/BoneSync/Networking/Messages/PlugSyncMessage.cs +++ b/BoneSync/Networking/Messages/PlugSyncMessage.cs @@ -1,5 +1,6 @@ using BoneSync.Sync; using BoneSync.Sync.Components; +using MelonLoader; using StressLevelZero.Interaction; using System; using System.Collections.Generic; @@ -41,14 +42,28 @@ namespace BoneSync.Networking.Messages public override void Execute() { + MelonLogger.Msg("Got PlugSyncMessage " + messageData.plugSyncId + ":" + messageData.plugIndex + " " + messageData.socketSyncId + ":" + messageData.socketIndex); Syncable plugSyncable = ObjectSyncCache.GetSyncable(messageData.plugSyncId); Syncable socketSyncable = ObjectSyncCache.GetSyncable(messageData.socketSyncId); - if (!plugSyncable || messageData.plugIndex == byte.MaxValue) { return; } - AlignPlug plug = (AlignPlug)plugSyncable.GetPlugFromId(messageData.plugIndex); - if (plug == null) { return; } + if (!plugSyncable || messageData.plugIndex == byte.MaxValue) + { + MelonLogger.Warning("PlugSyncable not found"); + return; + } + AlignPlug plug = plugSyncable.GetPlugFromId(messageData.plugIndex); + + if (plug == null) { + MelonLogger.Warning("Plug not found, " + plugSyncable.transform.GetPath()); + return; + } + if (plug == null) { + MelonLogger.Warning("Plug is not an AlignPlug"); + return; + } if (!socketSyncable || messageData.socketIndex == byte.MaxValue) { + MelonLogger.Warning("SocketSyncable not found"); plug.SafeEject(); return; } @@ -56,10 +71,13 @@ namespace BoneSync.Networking.Messages Socket socket = socketSyncable.GetSocketFromId(messageData.socketIndex); if (socket == null) { + MelonLogger.Warning("Unable to find socket from ID"); plug.SafeEject(); return; } + MelonLogger.Msg("Inserting networked plug"); + plug.SafeInsert(socket); } diff --git a/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs b/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs index ad7492c..386762f 100644 --- a/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs +++ b/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs @@ -27,7 +27,7 @@ namespace BoneSync.Networking.Messages public SimpleSyncableEventMessage(SimpleSyncableEvent simpleSyncableEvent) { eventData = simpleSyncableEvent; - byteEncoder.WriteULong(simpleSyncableEvent.syncId); + byteEncoder.WriteUShort(simpleSyncableEvent.syncId); byteEncoder.WriteByte((byte)simpleSyncableEvent.eventType); } diff --git a/BoneSync/Patching/GripPatches.cs b/BoneSync/Patching/GripPatches.cs index 82fde8b..3d6f23c 100644 --- a/BoneSync/Patching/GripPatches.cs +++ b/BoneSync/Patching/GripPatches.cs @@ -27,7 +27,7 @@ namespace BoneSync.Patching MelonLogger.Msg("ForcePullGrip.OnFarHandHoverUpdate: " + __instance.name + " Hand: " + hand.name); - InteractableHost interactableHost = __instance.GetComponent(); + InteractableHost interactableHost = __instance.GetComponentInParent(); if (interactableHost == null) return; Syncable syncable = ObjectSync.MakeOrGetSyncable(interactableHost); diff --git a/BoneSync/Patching/GunPatches.cs b/BoneSync/Patching/GunPatches.cs index 99d4592..51fd93a 100644 --- a/BoneSync/Patching/GunPatches.cs +++ b/BoneSync/Patching/GunPatches.cs @@ -7,6 +7,7 @@ using BoneSync.Networking.Messages; using BoneSync.Sync; using BoneSync.Sync.Components; using HarmonyLib; +using MelonLoader; using StressLevelZero.Props.Weapons; namespace BoneSync.Patching @@ -16,18 +17,19 @@ namespace BoneSync.Patching public class GunPatches { [HarmonyPatch(nameof(Gun.Fire)), HarmonyPrefix] - public static bool FirePatch(Gun __instance) + public static void FirePatch(Gun __instance) { - if (CallPatchedMethods.allowPatchedMethodCall) return true; + if (CallPatchedMethods.allowPatchedMethodCall) return; MelonLoader.MelonLogger.Msg("Gun fired: " + __instance.name); - if (!BoneSync.lobby.IsConnected()) return true; + if (!BoneSync.lobby.IsConnected()) return; Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject); - if (syncable == null) return true; - if (!syncable.Registered) return true; + if (syncable == null) return; + if (!syncable.Registered) return; if (syncable.isOwner) { + MelonLogger.Msg("Sending gun fire message: " + __instance.name); GunSyncInfo gunSyncInfo = new GunSyncInfo() { cartridgeState = __instance.cartridgeState, @@ -40,7 +42,7 @@ namespace BoneSync.Patching gunSyncMessage.Broadcast(); } - return true; + return; } diff --git a/BoneSync/Patching/PlugPatches.cs b/BoneSync/Patching/PlugPatches.cs index 6480cd0..9657708 100644 --- a/BoneSync/Patching/PlugPatches.cs +++ b/BoneSync/Patching/PlugPatches.cs @@ -13,70 +13,15 @@ using static MelonLoader.MelonLogger; namespace BoneSync.Patching { - /*[HarmonyPatch(typeof(Socket))] - public static class SocketPatches - { - public static void GenericSocketEnterPatch(Socket __instance, Plug plug) - { - if (!plug) return; - MelonLogger.Msg("Plug entered: " + __instance.name + " Plug: " + plug.name); - Syncable syncable = ObjectSyncCache.GetSyncable(plug); - if (!syncable) return; - byte plugId = syncable.GetPlugId(plug); - byte socketId = syncable.GetSocketId(__instance); - MelonLogger.Msg("Plug entered: " + __instance.transform.GetPath() + " Plug: " + plug.transform.GetPath() + " ID: " + plugId + " Socket ID: " + socketId); - - } - - public static void GenericSocketExitPatch(Socket __instance, Plug plug) - { - if (!plug) return; - MelonLogger.Msg("Plug exited: " + __instance.name + " Plug: " + plug.name); - Syncable syncable = ObjectSyncCache.GetSyncable(plug); - if (!syncable) return; - byte plugId = syncable.GetPlugId(plug); - byte socketId = syncable.GetSocketId(__instance); - MelonLogger.Msg("Plug exited: " + __instance.transform.GetPath() + " Plug: " + plug.transform.GetPath() + " ID: " + plugId + " Socket ID: " + socketId); - } - - - [HarmonyPatch(nameof(Socket.OnPlugEnter)), HarmonyPostfix] - public static void SocketEnterPatch(Socket __instance, Plug plug) - { - GenericSocketEnterPatch(__instance, plug); - } - - [HarmonyPatch(nameof(Socket.OnPlugExit)), HarmonyPostfix] - public static void SocketExitPatch(Socket __instance, Plug plug) - { - GenericSocketExitPatch(__instance, plug); - } - } - - [HarmonyPatch(typeof(MagazineSocket))] - public static class MagazineSocketPatches - { - [HarmonyPatch(nameof(MagazineSocket.OnPlugEnter)), HarmonyPostfix] - public static void MagazineSocketEnterPatch(MagazineSocket __instance, Plug plug) - { - SocketPatches.GenericSocketEnterPatch(__instance, plug); - } - - [HarmonyPatch(nameof(MagazineSocket.OnPlugExit)), HarmonyPostfix] - public static void SocketExitPatch(MagazineSocket __instance, Plug plug) - { - SocketPatches.GenericSocketExitPatch(__instance, plug); - } - }*/ [HarmonyPatch(typeof(AlignPlug))] public static class AlignPlugPatches { public static void OnPlugSocketChange(AlignPlug plug, Socket socket) { - + Syncable plugSyncable = plug.GetComponentInParent(); - Syncable socketSyncable = socket.GetComponentInParent(); + Syncable socketSyncable = socket?.GetComponentInParent(); if (!plugSyncable) { @@ -119,31 +64,32 @@ namespace BoneSync.Patching plugSyncMessage.Broadcast(); } - [HarmonyPatch(nameof(AlignPlug.InsertPlug)), HarmonyPostfix] - public static void AlignPlugInsertPatch(AlignPlug __instance, Socket socket) - { - MelonLogger.Msg("AlignPlug inserted: " + __instance.transform.GetPath() + " Socket: " + socket.transform.GetPath()); - OnPlugSocketChange(__instance, socket); - - } - - [HarmonyPatch(nameof(AlignPlug.EjectPlug)), HarmonyPostfix] + // for some reason AlignPlug.OnPlugInsertComplete can't be patched directly + /* + [HarmonyPatch(nameof(AlignPlug.OnPlugExitComplete)), HarmonyPostfix] public static void AlignPlugEjectPatch(AlignPlug __instance) { MelonLogger.Msg("AlignPlug ejected: " + __instance.transform.GetPath()); OnPlugSocketChange(__instance, null); + }*/ + + } + + [HarmonyPatch(typeof(MagazinePlug))] + public static class MagazinePlugPatches + { + [HarmonyPatch(nameof(MagazinePlug.OnPlugInsertComplete)), HarmonyPostfix] + public static void MagazinePlugInsertPatch(MagazinePlug __instance) + { + MelonLogger.Msg("MagazinePlug inserted: " + __instance.transform.GetPath()); + AlignPlugPatches.OnPlugSocketChange(__instance, __instance.GetSocket()); } - } - - - - public class PlugPatches - { - /*[HarmonyPatch(typeof(Plug))] - public class PlugPatches + [HarmonyPatch(nameof(MagazinePlug.OnPlugExitComplete)), HarmonyPostfix] + public static void MagazinePlugEjectPatch(MagazinePlug __instance) { - [HarmonyPatch(nameof(Plug.)), HarmonyPostfix] - }*/ + MelonLogger.Msg("MagazinePlug ejected: " + __instance.transform.GetPath()); + AlignPlugPatches.OnPlugSocketChange(__instance, null); + } } } diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs index 70625b0..2db12b1 100644 --- a/BoneSync/Sync/Components/SyncableBase.cs +++ b/BoneSync/Sync/Components/SyncableBase.cs @@ -107,7 +107,7 @@ namespace BoneSync.Sync.Components private Gun gun; private Magazine magazine; - private Plug[] plugs; + private AlignPlug[] plugs; private Socket[] sockets; private AIBrain aiBrain; @@ -180,7 +180,7 @@ namespace BoneSync.Sync.Components objectDestructable = GetComponent(); gun = GetComponent(); magazine = GetComponent(); - plugs = GetComponentsInChildren(); + plugs = GetComponentsInChildren(); sockets = GetComponentsInChildren(); spawnFragment = GetComponent(); @@ -215,7 +215,19 @@ namespace BoneSync.Sync.Components } yield break; } - + + public bool IsPlugged() + { + for (int i = 0; i < plugs.Length; i++) + { + AlignPlug alignPlug = plugs[i]; + if (alignPlug.GetSocket()) return true; + if (alignPlug._isEnterTransition) return true; + if (alignPlug._isExitTransition) return true; + } + return false; + } + private void _DiscardSyncable(bool force, bool despawn) { if (!this) return; // if object is destroyed, don't do anything @@ -223,19 +235,28 @@ namespace BoneSync.Sync.Components if (isRegistered) { - MelonLogger.Msg("Discarding syncable: " + transform.GetPath() + " force: " + force + " isRegistered: " + isRegistered + " despawn: " + despawn); + bool isPlugged = IsPlugged(); + + bool canDiscard = isOwner && (!isPlugged || force); // only owner can discard + MelonLogger.Msg("Discarding syncable: " + transform.GetPath() + " force:" + force + " registered:" + isRegistered + " despawn:" + despawn + " isPlugged:" + isPlugged + " canDiscard:" + canDiscard); //MelonLogger.Warning("Discarding registered syncable: " + transform.GetPath() + " force: " + force); - bool isowner = isOwner; + if (isPlugged) + { + MelonLogger.Warning("Trying to discard plugged syncable: " + transform.GetPath()); + } + - if (isowner) + if (canDiscard) { _SendDiscard(true); // owner sends discard message } - if (!isowner && !force) return; // only owner can discard + if (!canDiscard && !force) return; } + EjectAllPlugs(true); + if (gameObject) syncablesCache.Remove(gameObject); ObjectSyncCache.RemoveSyncable(this); @@ -271,7 +292,7 @@ namespace BoneSync.Sync.Components public void DiscardSyncableImmediate(bool force = false, bool despawn = false) { - _DiscardSyncable(true, despawn); + _DiscardSyncable(force, despawn); } public void OnDisable() diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs index b3ac98e..eebeb1a 100644 --- a/BoneSync/Sync/Components/SyncableNetworking.cs +++ b/BoneSync/Sync/Components/SyncableNetworking.cs @@ -50,11 +50,18 @@ namespace BoneSync.Sync.Components return false; } + private IEnumerator __SendRegisterSyncCo() + { + yield return null; // wait a frame + SetOwner(BoneSync.lobby.GetLocalId()); + SetSyncId(ObjectSync.SendRegisterSyncableMessage(this)); + yield break; + } + private void _SendRegisterSync() { MelonLogger.Msg("Registering syncable object: " + gameObject.name); - SetOwner(BoneSync.lobby.GetLocalId()); - SetSyncId(ObjectSync.SendRegisterSyncableMessage(this)); + MelonCoroutines.Start(__SendRegisterSyncCo()); } private void _SendDiscard(bool despawn = false) diff --git a/BoneSync/Sync/Components/SyncablePhysics.cs b/BoneSync/Sync/Components/SyncablePhysics.cs index 3c26f83..62d5dc4 100644 --- a/BoneSync/Sync/Components/SyncablePhysics.cs +++ b/BoneSync/Sync/Components/SyncablePhysics.cs @@ -111,7 +111,7 @@ namespace BoneSync.Sync.Components } if (poolee) { - return new Rigidbody[] { poolee.GetComponentInChildren() }; + return new Rigidbody[] { poolee.GetComponentInChildren(true) }; } return new Rigidbody[0]; @@ -127,7 +127,8 @@ namespace BoneSync.Sync.Components private void UpdateKinematic() { - SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered); + //SetKinematic(false); + SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered && !IsPlugged()); } internal void OnSimpleSyncableEvent(SimpleSyncableEvent eventData) diff --git a/BoneSync/Sync/Components/SyncablePlugs.cs b/BoneSync/Sync/Components/SyncablePlugs.cs index a9ac711..9a9ca20 100644 --- a/BoneSync/Sync/Components/SyncablePlugs.cs +++ b/BoneSync/Sync/Components/SyncablePlugs.cs @@ -15,10 +15,9 @@ namespace BoneSync.Sync.Components { Socket socket = plug._lastSocket; if (!socket) return null; - if (socket.LockedPlug == plug) - { - return socket; - } + if (socket.LockedPlug == plug) return socket; + if (plug._isExitTransition) return socket; + return null; } @@ -29,14 +28,23 @@ namespace BoneSync.Sync.Components return true; } + public static void ForceEject(this AlignPlug plug) + { + if (!plug.GetSocket()) return; + plug.EjectPlug(); + plug.ClearFromSocket(); + plug._isEnterTransition = false; + plug._isExitTransition = false; + plug._isExitComplete = true; + } + public static bool SafeInsert(this AlignPlug plug, Socket socket) { if (!socket) return false; if (socket.LockedPlug) return false; if (plug.GetSocket() && plug._lastSocket != socket) { - plug.EjectPlug(); - plug.ClearFromSocket(); + plug.ForceEject(); } plug.InsertPlug(socket); return true; @@ -44,7 +52,25 @@ namespace BoneSync.Sync.Components } public partial class Syncable : MonoBehaviour { - public Plug GetPlugFromId(byte id) + + public void EjectAllPlugs(bool force = false) + { + foreach (AlignPlug plug in plugs) + { + if (plug.GetSocket()) + { + if (force) + { + plug.ForceEject(); + } + else + { + plug.SafeEject(); + } + } + } + } + public AlignPlug GetPlugFromId(byte id) { if (plugs.Length <= id) { @@ -77,7 +103,7 @@ namespace BoneSync.Sync.Components return 255; } - public byte GetPlugId(Plug plug) + public byte GetPlugId(AlignPlug plug) { for (byte i = 0; i < plugs.Length; i++) { diff --git a/BoneSync/Sync/ObjectSync.cs b/BoneSync/Sync/ObjectSync.cs index 1cfa4f1..6c7d3c4 100644 --- a/BoneSync/Sync/ObjectSync.cs +++ b/BoneSync/Sync/ObjectSync.cs @@ -43,13 +43,19 @@ namespace BoneSync.Sync } else if (syncable.poolee && syncable.poolee.pool && (BoneSync.lobby.IsHost || allowClientRegister)) { + string spawnableRealTitle = syncable?.poolee?.spawnObject?.title; + string spawnableAlternateTitle = syncable?.poolee?.pool?.name.Replace("pool - ", ""); // hacky, but use when real title is unknown + + string spawnableTitle = spawnableRealTitle ?? spawnableAlternateTitle; + + MelonLogger.Msg("Spawnable title: " + spawnableTitle); info = new RegisterSyncableInfo() { ownerId = ownerId, type = RegisterSyncType.RegisterAndSpawn, spawnInfo = new SpawnPoolableInfo() { - spawnableTitle = syncable.poolee.spawnObject.title, + spawnableTitle = spawnableTitle, spawnLocation = new SimpleSyncTransform(syncable.poolee.transform), }, }; @@ -59,11 +65,12 @@ namespace BoneSync.Sync public static ushort SendRegisterSyncableMessage(Syncable syncable) { + MelonLogger.Msg("Sending register syncable message for: " + syncable.transform.name); RegisterSyncableInfo? infoNullable = GetRegisterInfo(syncable, syncable.ClientSpawningAllowed()); if (infoNullable == null) { - MelonLogger.Msg("No valid registeration method for syncable"); + MelonLogger.Warning("No valid registeration method for syncable"); return 0; } @@ -193,6 +200,7 @@ namespace BoneSync.Sync } public static void OnRegisterSyncMessage(RegisterSyncableMessage registerSyncableMessage) { + MelonLogger.Msg("Received register sync message"); Syncable syncable = null; RegisterSyncableInfo info = registerSyncableMessage.info; if (BoneSync.lobby.IsHost)