diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj
index 5c8db6c..88bd138 100644
--- a/BoneSync/BoneSync.csproj
+++ b/BoneSync/BoneSync.csproj
@@ -89,6 +89,7 @@
+
diff --git a/BoneSync/Patching/HolsterSlotPatches.cs b/BoneSync/Patching/HolsterSlotPatches.cs
new file mode 100644
index 0000000..0130d29
--- /dev/null
+++ b/BoneSync/Patching/HolsterSlotPatches.cs
@@ -0,0 +1,48 @@
+using BoneSync.Sync;
+using BoneSync.Sync.Components;
+using HarmonyLib;
+using MelonLoader;
+using StressLevelZero.Interaction;
+using StressLevelZero.Props.Weapons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+namespace BoneSync.Patching
+{
+ internal class HolsterSlotPatches
+ {
+ [HarmonyPatch(typeof(HandWeaponSlotReciever), nameof(HandWeaponSlotReciever.MakeStatic))]
+ public static void StaticPatch(HandWeaponSlotReciever __instance)
+ {
+ MelonLogger.Msg("HandWeaponSlotReciever.MakeStatic: " + __instance.name);
+ InteractableHost interactableHost = __instance.m_WeaponHost;
+ if (interactableHost == null)
+ {
+ MelonLogger.Error("InteractableHost is null for " + __instance.transform.GetPath());
+ return;
+ }
+
+ Syncable syncable = ObjectSync.MakeOrGetSyncable(interactableHost);
+ syncable?.SetInHolster(true);
+ }
+
+ [HarmonyPatch(typeof(HandWeaponSlotReciever), nameof(HandWeaponSlotReciever.MakeDynamic))]
+ public static void DynamicPatch(HandWeaponSlotReciever __instance)
+ {
+ MelonLogger.Msg("HandWeaponSlotReciever.MakeDynamic: " + __instance.name);
+ InteractableHost interactableHost = __instance.m_WeaponHost;
+ if (interactableHost == null)
+ {
+ MelonLogger.Error("InteractableHost is null for " + __instance.transform.GetPath());
+ return;
+ }
+
+ Syncable syncable = ObjectSync.MakeOrGetSyncable(interactableHost);
+ syncable?.SetInHolster(false);
+
+ }
+ }
+}
diff --git a/BoneSync/Patching/PoolPatches.cs b/BoneSync/Patching/PoolPatches.cs
index 86829f5..c09bed0 100644
--- a/BoneSync/Patching/PoolPatches.cs
+++ b/BoneSync/Patching/PoolPatches.cs
@@ -134,10 +134,15 @@ namespace BoneSync.Patching
bool spawnNormally = BoneSync.lobby.IsHost || PoolBlacklist.IsClientSpawnPool(__instance.pool);
- if (spawnNormally) return;
+ if (!spawnNormally) {
+ MelonCoroutines.Start(OnSpawnClient(__instance)); // block object from spawning
+ return;
+ }
+ if (syncable == null) return;
+
+ MelonLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath() + " " + syncable.GetSyncId());
- MelonCoroutines.Start(OnSpawnClient(__instance)); // block object from spawning
}
diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs
index af78395..e68c012 100644
--- a/BoneSync/Sync/Components/SyncableBase.cs
+++ b/BoneSync/Sync/Components/SyncableBase.cs
@@ -75,12 +75,20 @@ namespace BoneSync.Sync.Components
private ushort _syncId;
private float _lastSyncTime;
+ private bool _isInHolster;
private bool _attemptedRegister;
public bool Registered => _syncId != 0;
public bool isStale => Time.time - _lastSyncTime > 5f;
public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId();
+ public void SetInHolster(bool val)
+ {
+ MelonLogger.Msg(transform.GetPath() + " hosterState:" + val);
+ _isInHolster = val;
+ FindAndUpdateComponents();
+ }
+
public bool IsHolding()
{
if (interactableManager)
@@ -119,7 +127,7 @@ namespace BoneSync.Sync.Components
private void CheckAutoSync()
{
- bool shouldAutoSync = CheckIfShouldAutoSync();
+ bool shouldAutoSync = ShouldAutoSync();
if (shouldAutoSync && (BoneSync.lobby.IsHost || ClientSpawningAllowed()))
{
MelonLogger.Msg("AutoSyncing: " + transform.GetPath());
@@ -128,7 +136,10 @@ namespace BoneSync.Sync.Components
}
private IEnumerator _OnEnableCo()
{
- yield return null; // wait a frame to make sure all components are initialized, I hate this but it works
+ // wait for a couple frames to make sure all components are initialized, I hate this but it works
+ yield return null;
+ yield return null;
+ yield return null;
FindAndUpdateComponents();
CheckAutoSync();
yield break;
@@ -143,7 +154,7 @@ namespace BoneSync.Sync.Components
MelonCoroutines.Start(_OnEnableCo());
}
- public bool CheckIfShouldAutoSync()
+ public bool ShouldAutoSync()
{
if (InPoolManagerTransform()) return false;
if (!gameObject.activeInHierarchy) return false;
@@ -225,6 +236,7 @@ namespace BoneSync.Sync.Components
public bool IsPlugged()
{
+ if (plugs.Length == 0) return false;
for (int i = 0; i < plugs.Length; i++)
{
AlignPlug alignPlug = plugs[i];
@@ -239,13 +251,13 @@ namespace BoneSync.Sync.Components
{
if (!this) return; // if object is destroyed, don't do anything
bool isRegistered = Registered;
-
+
if (isRegistered)
{
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.Msg("Discarding syncable: " + transform.GetPath() + " force:" + force + " registered:" + isRegistered + " despawn:" + despawn + " isPlugged:" + isPlugged + " canDiscard:" + canDiscard);
//MelonLogger.Warning("Discarding registered syncable: " + transform.GetPath() + " force: " + force);
if (canDiscard)
@@ -256,6 +268,8 @@ namespace BoneSync.Sync.Components
if (!canDiscard && !force) return;
}
+ //MelonLogger.Msg("Discarding syncable: " + transform.GetPath() + " force:" + force + " registered:" + isRegistered + " despawn:" + despawn + " isPlugged:" + IsPlugged());
+
try
{
EjectAllPlugs(true);
@@ -317,6 +331,7 @@ namespace BoneSync.Sync.Components
public void RegisterSyncable()
{
if (!BoneSync.lobby.IsConnected()) return;
+ FindAndUpdateComponents();
if (Registered)
{
TryBecomeOwner();
diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs
index eebeb1a..82d982a 100644
--- a/BoneSync/Sync/Components/SyncableNetworking.cs
+++ b/BoneSync/Sync/Components/SyncableNetworking.cs
@@ -61,7 +61,7 @@ namespace BoneSync.Sync.Components
private void _SendRegisterSync()
{
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
- MelonCoroutines.Start(__SendRegisterSyncCo());
+ MelonCoroutines.Start(__SendRegisterSyncCo());
}
private void _SendDiscard(bool despawn = false)
@@ -119,6 +119,7 @@ namespace BoneSync.Sync.Components
if (!Registered) return false;
if (!isOwner) return false;
if (isStale) return true;
+ if (_isInHolster) return true;
if (AllRigidbodiesSleeping()) return false;
return true;
}
diff --git a/BoneSync/Sync/Components/SyncablePhysics.cs b/BoneSync/Sync/Components/SyncablePhysics.cs
index 838a851..d8651bd 100644
--- a/BoneSync/Sync/Components/SyncablePhysics.cs
+++ b/BoneSync/Sync/Components/SyncablePhysics.cs
@@ -93,6 +93,7 @@ namespace BoneSync.Sync.Components
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
{
+ if (IsPlugged()) { return; }
if (objectSyncTransforms.Length != rigidbodies.Length)
{
MelonLogger.Warning("ObjectSyncTransforms length mismatch: " + objectSyncTransforms.Length + " != " + _transforms.Length);
@@ -142,7 +143,7 @@ namespace BoneSync.Sync.Components
private void UpdateTransformList()
{
// get non-null rigidbodies
- Rigidbody[] rbs = GetRigidbodies().Where(rb => rb != null && RigidbodyBelongsToSyncable(rb)).ToArray();
+ Rigidbody[] rbs = GetRigidbodies().Where(rb => rb != null).ToArray();
rigidbodies = rbs;
_transforms = rbs.Select(rb => rb.transform).ToArray();
}
diff --git a/BoneSync/Sync/ObjectSync.cs b/BoneSync/Sync/ObjectSync.cs
index f75e37c..bf15177 100644
--- a/BoneSync/Sync/ObjectSync.cs
+++ b/BoneSync/Sync/ObjectSync.cs
@@ -112,7 +112,7 @@ namespace BoneSync.Sync
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncabled = true)
{
//Scene scene = gameObject.scene;
- //MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name);
+ //MelonLogger.Msg("Making or getting syncable for: " + gameObject.name);
if (gameObject == null)
{
return null;
@@ -122,23 +122,32 @@ namespace BoneSync.Sync
// delete all sub syncables
if (deleteSubSyncabled)
{
- Syncable[] subSyncables = gameObject.GetComponentsInChildren(true);
- for (int i = 0; i < subSyncables.Length; i++)
+ try
{
- Syncable subSyncable = subSyncables[i];
- if (subSyncable == syncable) continue;
- bool isRegistered = subSyncable.Registered;
- bool isPlugged = subSyncable.IsPlugged();
+ Syncable[] subSyncables = gameObject.GetComponentsInChildren(true);
+ for (int i = 0; i < subSyncables.Length; i++)
+ {
+ Syncable subSyncable = subSyncables[i];
+ if (subSyncable == syncable) continue;
+ if (subSyncable == null) continue;
+ bool isRegistered = subSyncable.Registered;
+ bool isPlugged = subSyncable.IsPlugged();
- MelonLogger.Msg("Discarding subSyncable: " + subSyncable.transform.GetPath() + " registered:" + isRegistered + " plugged:" + isPlugged);
- if (isRegistered || isPlugged) continue;
- subSyncable.DiscardSyncableImmediate(true, false);
+ MelonLogger.Msg("Discarding subSyncable: " + subSyncable.transform.GetPath() + " registered:" + isRegistered + " plugged:" + isPlugged);
+ if (isRegistered || isPlugged) continue;
+ subSyncable.DiscardSyncable();
+ }
+ }
+ catch (Exception e)
+ {
+ MelonLogger.Warning("Failed to delete sub syncables: " + e.Message);
}
}
if (syncable == null)
{
syncable = gameObject.AddComponent();
+ // MelonLogger.Msg("Created syncable for: " + gameObject.name);
}
return syncable;
}
@@ -175,7 +184,7 @@ namespace BoneSync.Sync
public static Syncable MakeOrGetSyncable(InteractableHostManager interactableHostManager)
{
- return _MakeOrGetSyncable(interactableHostManager.gameObject);
+ return _MakeOrGetSyncable(interactableHostManager.gameObject, true);
}
public static Syncable SpawnPooleeAndMakeSyncable(SpawnPoolableInfo spawnInfo)