diff --git a/BoneSync/Data/EmebeddedAssetBundle.cs b/BoneSync/Data/EmebeddedAssetBundle.cs index 9c6b1a3..a899001 100644 --- a/BoneSync/Data/EmebeddedAssetBundle.cs +++ b/BoneSync/Data/EmebeddedAssetBundle.cs @@ -34,8 +34,8 @@ namespace BoneSync.Data AssetBundle temp = AssetBundle.LoadFromMemory(bytes); SyncLogger.Msg($"Done!"); return temp; - } - + } + SyncLogger.Warning($"Failed to load embedded bundle data {name}! Bundle not found."); return null; } } diff --git a/BoneSync/Networking/Messages/ObjectDamageMessage.cs b/BoneSync/Networking/Messages/ObjectDamageMessage.cs index d4810ea..cd2b4a8 100644 --- a/BoneSync/Networking/Messages/ObjectDamageMessage.cs +++ b/BoneSync/Networking/Messages/ObjectDamageMessage.cs @@ -17,7 +17,8 @@ namespace BoneSync.Networking.Messages public float damage; public bool crit; public AttackType attackType; - public ObjectHealthInfo(float health, int hits, Vector3 normal, float damage, bool crit, AttackType attackType) + public byte index; + public ObjectHealthInfo(float health, int hits, Vector3 normal, float damage, bool crit, AttackType attackType, byte index) { _health = health; _hits = hits; @@ -25,6 +26,7 @@ namespace BoneSync.Networking.Messages this.damage = damage; this.crit = crit; this.attackType = attackType; + this.index = index; } } public enum ObjectDamageType @@ -52,6 +54,7 @@ namespace BoneSync.Networking.Messages _objectEventInfo = objectEventInfo; byteEncoder.WriteUShort(_objectEventInfo.objectId); byteEncoder.WriteByte((byte)_objectEventInfo.eventType); + byteEncoder.WriteByte(_objectEventInfo.objectHealthInfo.index); byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health); byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits); if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to write the rest of the data @@ -66,6 +69,7 @@ namespace BoneSync.Networking.Messages byteEncoder.WriteBytes(packet.Data); _objectEventInfo.objectId = byteEncoder.ReadUShort(); _objectEventInfo.eventType = (ObjectDamageType)byteEncoder.ReadByte(); + _objectEventInfo.objectHealthInfo.index = byteEncoder.ReadByte(); _objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat(); _objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt(); if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data diff --git a/BoneSync/Patching/ObjectHealthPatches.cs b/BoneSync/Patching/ObjectHealthPatches.cs index 0310215..7f79d1b 100644 --- a/BoneSync/Patching/ObjectHealthPatches.cs +++ b/BoneSync/Patching/ObjectHealthPatches.cs @@ -33,7 +33,7 @@ namespace BoneSync.Patching if (damage > 0.5f) syncable.RegisterSyncable(); // register syncable if damage is very significant, e.g. a bullet hit if (syncable.Registered && !syncable.isOwner) return false; //SyncLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name); - ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType); + ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType, 0); ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.DestructibleTakeDamage, objectHealthInfo); @@ -74,7 +74,7 @@ namespace BoneSync.Patching if (damage > 0.5f) syncable.RegisterSyncable(); if (syncable.Registered && !syncable.isOwner) return false; //SyncLogger.Msg("Patch: Prop_Health.TAKEDAMAGE: " + damage + " " + syncable.gameObject.name); - ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance.cur_Health, __instance.hits, Vector3.zero, damage, crit, attackType); + ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance.cur_Health, __instance.hits, Vector3.zero, damage, crit, attackType, 0); ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.PropHealthTakeDamage, objectHealthInfo); diff --git a/BoneSync/Patching/UnityEventPatching.cs b/BoneSync/Patching/UnityEventPatching.cs index 0f59f15..40bf9d1 100644 --- a/BoneSync/Patching/UnityEventPatching.cs +++ b/BoneSync/Patching/UnityEventPatching.cs @@ -70,7 +70,7 @@ namespace BoneSync.Patching } } - [HarmonyPatch(typeof(UnityEvent))] + /*[HarmonyPatch(typeof(UnityEvent))] internal class UnityEventPatches { [HarmonyPatch(nameof(UnityEvent.Invoke)), HarmonyPrefix] @@ -84,5 +84,5 @@ namespace BoneSync.Patching } return true; } - } + }*/ } diff --git a/BoneSync/Player/PlayerRig.cs b/BoneSync/Player/PlayerRig.cs index 951baaf..b95d216 100644 --- a/BoneSync/Player/PlayerRig.cs +++ b/BoneSync/Player/PlayerRig.cs @@ -100,7 +100,14 @@ namespace BoneSync.Player public void UpdatePose(Handedness hand, int index) { + Il2CppStringArray handPoses = PlayerScripts.playerHandPoses; + if (handPoses == null) + { + SyncLogger.Msg("PlayerScripts.playerHandPoses is null, getting hand poses..."); + PlayerScripts.GetHandPoses(); + handPoses = PlayerScripts.playerHandPoses; + } if (handPoses.Count < index + 1) return; UpdatePose(hand, handPoses[index]); diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs index eb3b9da..eba89ed 100644 --- a/BoneSync/Sync/Components/SyncableBase.cs +++ b/BoneSync/Sync/Components/SyncableBase.cs @@ -68,6 +68,7 @@ namespace BoneSync.Sync.Components } private bool _syncCoroutineRunning; + private bool _ownerCoroutineRunning; public ulong _ownerId { @@ -81,7 +82,7 @@ namespace BoneSync.Sync.Components private bool _attemptedRegister; public bool Registered => _syncId != 0; - public bool isStale => Time.realtimeSinceStartup - _lastSyncTime > 5f; + public bool isStale => Time.realtimeSinceStartup - _lastSyncTime > 30f; public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId(); public bool isValid => _GetIsValid(); @@ -142,6 +143,7 @@ namespace BoneSync.Sync.Components private ButtonToggle[] buttonToggles; private SpawnFragment spawnFragment; + private SpawnFragmentArray spawnFragmentArray; private Powerable powerable; private Cart physicsCart; @@ -150,8 +152,7 @@ namespace BoneSync.Sync.Components { if (!isValid) return; FindAndUpdateComponents(); - bool shouldAutoSync = ShouldAutoSync(); - if (shouldAutoSync && (BoneSync.lobby.IsHost || ClientSpawningAllowed())) + if (ShouldAutoSync()) { SyncLogger.Msg("AutoSyncing: " + transform.GetPath()); RegisterSyncable(); @@ -180,12 +181,13 @@ namespace BoneSync.Sync.Components public bool ShouldAutoSync() { if (SceneSync.TimeSinceLastSceneChange < SceneSync.MAP_LOAD_GRACE_PERIOD) return false; // don't sync if scene just changed, to prevent some weird stuff that happens when a level is loaded + if (!BoneSync.lobby.IsHost && !ClientSpawningAllowed()) return false; if (InPoolManagerTransform()) return false; if (!gameObject.activeInHierarchy) return false; if (poolee && poolee.pool) { return true; } - if (buttonToggles.Length > 0) return true; + if (buttonToggles.Length > 0 && rigidbodies.Length == 0) return true; if (physicsCart != null) return true; return false; } @@ -236,10 +238,10 @@ namespace BoneSync.Sync.Components } spawnFragment = GetComponent(); + spawnFragmentArray = GetComponent(); UpdateTransformList(); TryPatchUnityEvents(); - TrySendAttributeSync(); ObjectSyncCache.AddSyncable(this); } @@ -262,9 +264,9 @@ namespace BoneSync.Sync.Components } public bool CanBeSynced() { - - if (spawnFragment) return false; // if has spawn fragment, don't sync FindAndUpdateComponents(); + if (spawnFragment) return false; // if has spawn fragment, don't sync + if (spawnFragmentArray) return false; // if has spawn fragment array, don't sync if (rigidbodies?.Length > 0) return true; if (ShouldAutoSync()) return true; return false; @@ -287,8 +289,6 @@ namespace BoneSync.Sync.Components { AlignPlug alignPlug = plugs[i]; if (alignPlug.GetSocket()) return true; - if (alignPlug._isEnterTransition) return true; - if (alignPlug._isExitTransition) return true; } return false; } diff --git a/BoneSync/Sync/Components/SyncableDamage.cs b/BoneSync/Sync/Components/SyncableDamage.cs index 0c5ac24..f8931c4 100644 --- a/BoneSync/Sync/Components/SyncableDamage.cs +++ b/BoneSync/Sync/Components/SyncableDamage.cs @@ -3,6 +3,7 @@ using BoneSync.Networking.Messages; using BoneSync.Patching; using MelonLoader; using StressLevelZero.Data; +using StressLevelZero.Props; using System; using System.Collections.Generic; using System.Linq; @@ -14,23 +15,27 @@ namespace BoneSync.Sync.Components { public partial class Syncable : MonoBehaviour { - private LootTableData originalLootTableData = null; + //private LootTableData originalLootTableData = null; + private Dictionary originalLootTableData = new Dictionary(); - private void _UpdateLootTable() + private void _UpdateLootTable(ObjectDestructable destructable) { - if (!objectDestructable) return; - if (originalLootTableData == null) + if (!destructable) return; + if (!originalLootTableData.ContainsKey(destructable.GetHashCode())) { - originalLootTableData = objectDestructable.lootTable; + originalLootTableData[destructable.GetHashCode()] = destructable.lootTable; } if (!BoneSync.IsConnected || BoneSync.lobby.IsHost) { - objectDestructable.lootTable = originalLootTableData; + if (originalLootTableData[destructable.GetHashCode()] != null) + { + destructable.lootTable = originalLootTableData[destructable.GetHashCode()]; + } } else { - objectDestructable.lootTable = null; + destructable.lootTable = null; } } @@ -49,7 +54,7 @@ namespace BoneSync.Sync.Components } if (objectDestructable) { - _UpdateLootTable(); + _UpdateLootTable(objectDestructable); objectDestructable._health = health; objectDestructable._hits = hits; } diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs index f84c3c6..4744c4e 100644 --- a/BoneSync/Sync/Components/SyncableNetworking.cs +++ b/BoneSync/Sync/Components/SyncableNetworking.cs @@ -16,25 +16,52 @@ namespace BoneSync.Sync.Components // SyncableNetworking.cs public partial class Syncable : MonoBehaviour { + private float _syncInterval = 0f; private Queue _simpleEventQueue = new Queue(); private void SendObjectSync() { _lastSyncTime = Time.realtimeSinceStartup; ObjectSync.SendObjectSyncMessage(this); } - + private IEnumerator OwnerCoroutineAsync() + { + if (_ownerCoroutineRunning) yield break; + SyncLogger.Msg("Running owner coroutine for: " + _syncId); + _ownerCoroutineRunning = true; + while (isOwner) + { + if (!_syncCoroutineRunning) + { + RunSyncLoop(); // start sync loop if it's not running + } + yield return new WaitForSeconds(_syncInterval * 10f); // 10x sync interval + } + _ownerCoroutineRunning = false; + SyncLogger.Msg("Owner coroutine ended for: " + _syncId); + yield break; + } public IEnumerator SyncCoroutineAsync() { - SyncLogger.Msg("Running sync coroutine for: " + transform.GetPath()); if (_syncCoroutineRunning) yield break; + if (!ShouldSendSync()) yield break; + SyncLogger.Msg("Starting sync coroutine for: " + transform.GetPath()); _syncCoroutineRunning = true; + _syncInterval = 1 / OBJECT_SYNC_FPS; // micro optimization to avoid division every frame, propably makes no difference while (ShouldSendSync()) { - TrySendAISync(); - SendObjectSync(); - TrySendPlugSync(); - yield return new WaitForSeconds( 1 / OBJECT_SYNC_FPS ); + try + { + SendObjectSync(); + TrySendPlugSync(); + TrySendAISync(); + TrySendAttributeSync(); + } catch (Exception e) + { + MelonLogger.Error("Error in sync coroutine", e); + } + yield return new WaitForSeconds(_syncInterval); } + SyncLogger.Msg("Ending sync coroutine for: " + transform.GetPath()); _syncCoroutineRunning = false; yield break; } @@ -46,10 +73,11 @@ namespace BoneSync.Sync.Components { SyncLogger.Msg("Setting owner for " + _syncId + " to " + ownerId); _ownerId = ownerId; - FindAndUpdateComponents(); - RunSyncLoop(); + //FindAndUpdateComponents(); UpdateKinematic(); + RunSyncLoop(); TryCatchUpSimpleEvents(); + MelonCoroutines.Start(OwnerCoroutineAsync()); } public bool ClientSpawningAllowed() diff --git a/BoneSync/Sync/Components/SyncablePhysics.cs b/BoneSync/Sync/Components/SyncablePhysics.cs index c7f1c99..f5d8ab8 100644 --- a/BoneSync/Sync/Components/SyncablePhysics.cs +++ b/BoneSync/Sync/Components/SyncablePhysics.cs @@ -136,7 +136,7 @@ namespace BoneSync.Sync.Components objectSyncTransforms[i] = new ObjectSyncTransform() { transform = new SimpleSyncTransform(_transforms[i]), - velocity = Vector3.zero + velocity = rigidbodies[i].velocity, }; } return objectSyncTransforms; @@ -144,6 +144,7 @@ namespace BoneSync.Sync.Components public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms) { + _lastSyncTime = Time.realtimeSinceStartup; if (IsPlugged()) { return; } if (objectSyncTransforms.Length != rigidbodies.Length) { @@ -156,8 +157,10 @@ namespace BoneSync.Sync.Components Rigidbody rb = rigidbodies[i]; rb.angularVelocity = objectSyncTransform.angularVelocity; rb.velocity = objectSyncTransform.velocity; - rb.MovePosition(objectSyncTransform.transform.position); - rb.MoveRotation(objectSyncTransform.transform.rotation); + //rb.MovePosition(objectSyncTransform.transform.position); + //rb.MoveRotation(objectSyncTransform.transform.rotation); + rb.position = objectSyncTransform.transform.position; + rb.rotation = objectSyncTransform.transform.rotation; _transforms[i].localScale = objectSyncTransform.transform.scale; //_transforms[i].ApplySimpleTransform(objectSyncTransform.transform); } @@ -186,7 +189,11 @@ namespace BoneSync.Sync.Components } if (poolee) { - return new Rigidbody[] { poolee.GetComponentInChildren(true) }; + return poolee.GetComponentsInChildren(true); + } + if (physicsCart) + { + return new Rigidbody[] { physicsCart.rb }; } return new Rigidbody[0]; diff --git a/BoneSync/Sync/Components/SyncablePlugs.cs b/BoneSync/Sync/Components/SyncablePlugs.cs index 083a1ae..b622524 100644 --- a/BoneSync/Sync/Components/SyncablePlugs.cs +++ b/BoneSync/Sync/Components/SyncablePlugs.cs @@ -18,8 +18,8 @@ namespace BoneSync.Sync.Components Socket socket = plug._lastSocket; if (!socket) return null; if (socket.LockedPlug == plug) return socket; - if (plug._isExitTransition) return socket; if (plug._isEnterTransition) return socket; + if (plug._isExitTransition) return socket; return null; } @@ -71,7 +71,7 @@ namespace BoneSync.Sync.Components private const float PLUG_SYNC_FPS = 1f; private void TrySendPlugSync() { - if (Time.realtimeSinceStartup - _lastPlugSyncTime > 1 / PLUG_SYNC_FPS) + if (Time.realtimeSinceStartup - _lastPlugSyncTime > (1 / PLUG_SYNC_FPS)) { _SendPlugSync(); } diff --git a/BoneSync/Sync/ObjectSync.cs b/BoneSync/Sync/ObjectSync.cs index e1a4af4..6c6b95b 100644 --- a/BoneSync/Sync/ObjectSync.cs +++ b/BoneSync/Sync/ObjectSync.cs @@ -110,7 +110,7 @@ namespace BoneSync.Sync ObjectSyncMessage message = new ObjectSyncMessage(data); message.Broadcast(); } - private static Transform _GetPerferredParentTransform(Transform t) + private static Transform _GetPerferredSyncRootTransform(Transform t) { if (t == null) return null; Transform parent = t.parent; @@ -122,7 +122,7 @@ namespace BoneSync.Sync InteractableHostManager manager = parent.GetComponentInParent(); if (manager) return manager.transform; - return parent; + return t; } private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncables = true) @@ -162,9 +162,13 @@ namespace BoneSync.Sync if (syncable == null) { - Transform perferredObjectParent = _GetPerferredParentTransform(gameObject.transform); - syncable = _MakeOrGetSyncable(perferredObjectParent.gameObject, deleteSubSyncables); - + Transform perferredObjectParent = _GetPerferredSyncRootTransform(gameObject.transform); + Syncable foundComponent = perferredObjectParent.GetComponent(); + if (foundComponent) + { + return foundComponent; + } + syncable = perferredObjectParent.gameObject.AddComponent(); } return syncable; }