update sync coroutine, holsters broken

This commit is contained in:
2025-03-30 23:39:16 +03:00
parent b72add4e81
commit 5f148bc86f
11 changed files with 98 additions and 43 deletions

View File

@@ -35,7 +35,7 @@ namespace BoneSync.Data
SyncLogger.Msg($"Done!"); SyncLogger.Msg($"Done!");
return temp; return temp;
} }
SyncLogger.Warning($"Failed to load embedded bundle data {name}! Bundle not found.");
return null; return null;
} }
} }

View File

@@ -17,7 +17,8 @@ namespace BoneSync.Networking.Messages
public float damage; public float damage;
public bool crit; public bool crit;
public AttackType attackType; 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; _health = health;
_hits = hits; _hits = hits;
@@ -25,6 +26,7 @@ namespace BoneSync.Networking.Messages
this.damage = damage; this.damage = damage;
this.crit = crit; this.crit = crit;
this.attackType = attackType; this.attackType = attackType;
this.index = index;
} }
} }
public enum ObjectDamageType public enum ObjectDamageType
@@ -52,6 +54,7 @@ namespace BoneSync.Networking.Messages
_objectEventInfo = objectEventInfo; _objectEventInfo = objectEventInfo;
byteEncoder.WriteUShort(_objectEventInfo.objectId); byteEncoder.WriteUShort(_objectEventInfo.objectId);
byteEncoder.WriteByte((byte)_objectEventInfo.eventType); byteEncoder.WriteByte((byte)_objectEventInfo.eventType);
byteEncoder.WriteByte(_objectEventInfo.objectHealthInfo.index);
byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health); byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health);
byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits); byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits);
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to write the rest of the data 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); byteEncoder.WriteBytes(packet.Data);
_objectEventInfo.objectId = byteEncoder.ReadUShort(); _objectEventInfo.objectId = byteEncoder.ReadUShort();
_objectEventInfo.eventType = (ObjectDamageType)byteEncoder.ReadByte(); _objectEventInfo.eventType = (ObjectDamageType)byteEncoder.ReadByte();
_objectEventInfo.objectHealthInfo.index = byteEncoder.ReadByte();
_objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat(); _objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat();
_objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt(); _objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt();
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data

View File

@@ -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 (damage > 0.5f) syncable.RegisterSyncable(); // register syncable if damage is very significant, e.g. a bullet hit
if (syncable.Registered && !syncable.isOwner) return false; if (syncable.Registered && !syncable.isOwner) return false;
//SyncLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name); //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); ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.DestructibleTakeDamage, objectHealthInfo);
@@ -74,7 +74,7 @@ namespace BoneSync.Patching
if (damage > 0.5f) syncable.RegisterSyncable(); if (damage > 0.5f) syncable.RegisterSyncable();
if (syncable.Registered && !syncable.isOwner) return false; if (syncable.Registered && !syncable.isOwner) return false;
//SyncLogger.Msg("Patch: Prop_Health.TAKEDAMAGE: " + damage + " " + syncable.gameObject.name); //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); ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.PropHealthTakeDamage, objectHealthInfo);

View File

@@ -70,7 +70,7 @@ namespace BoneSync.Patching
} }
} }
[HarmonyPatch(typeof(UnityEvent))] /*[HarmonyPatch(typeof(UnityEvent))]
internal class UnityEventPatches internal class UnityEventPatches
{ {
[HarmonyPatch(nameof(UnityEvent.Invoke)), HarmonyPrefix] [HarmonyPatch(nameof(UnityEvent.Invoke)), HarmonyPrefix]
@@ -84,5 +84,5 @@ namespace BoneSync.Patching
} }
return true; return true;
} }
} }*/
} }

View File

@@ -100,7 +100,14 @@ namespace BoneSync.Player
public void UpdatePose(Handedness hand, int index) public void UpdatePose(Handedness hand, int index)
{ {
Il2CppStringArray handPoses = PlayerScripts.playerHandPoses; 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) if (handPoses.Count < index + 1)
return; return;
UpdatePose(hand, handPoses[index]); UpdatePose(hand, handPoses[index]);

View File

@@ -68,6 +68,7 @@ namespace BoneSync.Sync.Components
} }
private bool _syncCoroutineRunning; private bool _syncCoroutineRunning;
private bool _ownerCoroutineRunning;
public ulong _ownerId public ulong _ownerId
{ {
@@ -81,7 +82,7 @@ namespace BoneSync.Sync.Components
private bool _attemptedRegister; private bool _attemptedRegister;
public bool Registered => _syncId != 0; 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 isOwner => _ownerId == BoneSync.lobby.GetLocalId();
public bool isValid => _GetIsValid(); public bool isValid => _GetIsValid();
@@ -142,6 +143,7 @@ namespace BoneSync.Sync.Components
private ButtonToggle[] buttonToggles; private ButtonToggle[] buttonToggles;
private SpawnFragment spawnFragment; private SpawnFragment spawnFragment;
private SpawnFragmentArray spawnFragmentArray;
private Powerable powerable; private Powerable powerable;
private Cart physicsCart; private Cart physicsCart;
@@ -150,8 +152,7 @@ namespace BoneSync.Sync.Components
{ {
if (!isValid) return; if (!isValid) return;
FindAndUpdateComponents(); FindAndUpdateComponents();
bool shouldAutoSync = ShouldAutoSync(); if (ShouldAutoSync())
if (shouldAutoSync && (BoneSync.lobby.IsHost || ClientSpawningAllowed()))
{ {
SyncLogger.Msg("AutoSyncing: " + transform.GetPath()); SyncLogger.Msg("AutoSyncing: " + transform.GetPath());
RegisterSyncable(); RegisterSyncable();
@@ -180,12 +181,13 @@ namespace BoneSync.Sync.Components
public bool ShouldAutoSync() 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 (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 (InPoolManagerTransform()) return false;
if (!gameObject.activeInHierarchy) return false; if (!gameObject.activeInHierarchy) return false;
if (poolee && poolee.pool) { if (poolee && poolee.pool) {
return true; return true;
} }
if (buttonToggles.Length > 0) return true; if (buttonToggles.Length > 0 && rigidbodies.Length == 0) return true;
if (physicsCart != null) return true; if (physicsCart != null) return true;
return false; return false;
} }
@@ -236,10 +238,10 @@ namespace BoneSync.Sync.Components
} }
spawnFragment = GetComponent<SpawnFragment>(); spawnFragment = GetComponent<SpawnFragment>();
spawnFragmentArray = GetComponent<SpawnFragmentArray>();
UpdateTransformList(); UpdateTransformList();
TryPatchUnityEvents(); TryPatchUnityEvents();
TrySendAttributeSync();
ObjectSyncCache.AddSyncable(this); ObjectSyncCache.AddSyncable(this);
} }
@@ -262,9 +264,9 @@ namespace BoneSync.Sync.Components
} }
public bool CanBeSynced() public bool CanBeSynced()
{ {
if (spawnFragment) return false; // if has spawn fragment, don't sync
FindAndUpdateComponents(); 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 (rigidbodies?.Length > 0) return true;
if (ShouldAutoSync()) return true; if (ShouldAutoSync()) return true;
return false; return false;
@@ -287,8 +289,6 @@ namespace BoneSync.Sync.Components
{ {
AlignPlug alignPlug = plugs[i]; AlignPlug alignPlug = plugs[i];
if (alignPlug.GetSocket()) return true; if (alignPlug.GetSocket()) return true;
if (alignPlug._isEnterTransition) return true;
if (alignPlug._isExitTransition) return true;
} }
return false; return false;
} }

View File

@@ -3,6 +3,7 @@ using BoneSync.Networking.Messages;
using BoneSync.Patching; using BoneSync.Patching;
using MelonLoader; using MelonLoader;
using StressLevelZero.Data; using StressLevelZero.Data;
using StressLevelZero.Props;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -14,23 +15,27 @@ namespace BoneSync.Sync.Components
{ {
public partial class Syncable : MonoBehaviour public partial class Syncable : MonoBehaviour
{ {
private LootTableData originalLootTableData = null; //private LootTableData originalLootTableData = null;
private Dictionary<int, LootTableData> originalLootTableData = new Dictionary<int, LootTableData>();
private void _UpdateLootTable() private void _UpdateLootTable(ObjectDestructable destructable)
{ {
if (!objectDestructable) return; if (!destructable) return;
if (originalLootTableData == null) if (!originalLootTableData.ContainsKey(destructable.GetHashCode()))
{ {
originalLootTableData = objectDestructable.lootTable; originalLootTableData[destructable.GetHashCode()] = destructable.lootTable;
} }
if (!BoneSync.IsConnected || BoneSync.lobby.IsHost) if (!BoneSync.IsConnected || BoneSync.lobby.IsHost)
{ {
objectDestructable.lootTable = originalLootTableData; if (originalLootTableData[destructable.GetHashCode()] != null)
{
destructable.lootTable = originalLootTableData[destructable.GetHashCode()];
}
} }
else else
{ {
objectDestructable.lootTable = null; destructable.lootTable = null;
} }
} }
@@ -49,7 +54,7 @@ namespace BoneSync.Sync.Components
} }
if (objectDestructable) if (objectDestructable)
{ {
_UpdateLootTable(); _UpdateLootTable(objectDestructable);
objectDestructable._health = health; objectDestructable._health = health;
objectDestructable._hits = hits; objectDestructable._hits = hits;
} }

View File

@@ -16,25 +16,52 @@ namespace BoneSync.Sync.Components
// SyncableNetworking.cs // SyncableNetworking.cs
public partial class Syncable : MonoBehaviour public partial class Syncable : MonoBehaviour
{ {
private float _syncInterval = 0f;
private Queue<byte[]> _simpleEventQueue = new Queue<byte[]>(); private Queue<byte[]> _simpleEventQueue = new Queue<byte[]>();
private void SendObjectSync() private void SendObjectSync()
{ {
_lastSyncTime = Time.realtimeSinceStartup; _lastSyncTime = Time.realtimeSinceStartup;
ObjectSync.SendObjectSyncMessage(this); 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() public IEnumerator SyncCoroutineAsync()
{ {
SyncLogger.Msg("Running sync coroutine for: " + transform.GetPath());
if (_syncCoroutineRunning) yield break; if (_syncCoroutineRunning) yield break;
if (!ShouldSendSync()) yield break;
SyncLogger.Msg("Starting sync coroutine for: " + transform.GetPath());
_syncCoroutineRunning = true; _syncCoroutineRunning = true;
_syncInterval = 1 / OBJECT_SYNC_FPS; // micro optimization to avoid division every frame, propably makes no difference
while (ShouldSendSync()) while (ShouldSendSync())
{ {
TrySendAISync(); try
{
SendObjectSync(); SendObjectSync();
TrySendPlugSync(); TrySendPlugSync();
yield return new WaitForSeconds( 1 / OBJECT_SYNC_FPS ); 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; _syncCoroutineRunning = false;
yield break; yield break;
} }
@@ -46,10 +73,11 @@ namespace BoneSync.Sync.Components
{ {
SyncLogger.Msg("Setting owner for " + _syncId + " to " + ownerId); SyncLogger.Msg("Setting owner for " + _syncId + " to " + ownerId);
_ownerId = ownerId; _ownerId = ownerId;
FindAndUpdateComponents(); //FindAndUpdateComponents();
RunSyncLoop();
UpdateKinematic(); UpdateKinematic();
RunSyncLoop();
TryCatchUpSimpleEvents(); TryCatchUpSimpleEvents();
MelonCoroutines.Start(OwnerCoroutineAsync());
} }
public bool ClientSpawningAllowed() public bool ClientSpawningAllowed()

View File

@@ -136,7 +136,7 @@ namespace BoneSync.Sync.Components
objectSyncTransforms[i] = new ObjectSyncTransform() objectSyncTransforms[i] = new ObjectSyncTransform()
{ {
transform = new SimpleSyncTransform(_transforms[i]), transform = new SimpleSyncTransform(_transforms[i]),
velocity = Vector3.zero velocity = rigidbodies[i].velocity,
}; };
} }
return objectSyncTransforms; return objectSyncTransforms;
@@ -144,6 +144,7 @@ namespace BoneSync.Sync.Components
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms) public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
{ {
_lastSyncTime = Time.realtimeSinceStartup;
if (IsPlugged()) { return; } if (IsPlugged()) { return; }
if (objectSyncTransforms.Length != rigidbodies.Length) if (objectSyncTransforms.Length != rigidbodies.Length)
{ {
@@ -156,8 +157,10 @@ namespace BoneSync.Sync.Components
Rigidbody rb = rigidbodies[i]; Rigidbody rb = rigidbodies[i];
rb.angularVelocity = objectSyncTransform.angularVelocity; rb.angularVelocity = objectSyncTransform.angularVelocity;
rb.velocity = objectSyncTransform.velocity; rb.velocity = objectSyncTransform.velocity;
rb.MovePosition(objectSyncTransform.transform.position); //rb.MovePosition(objectSyncTransform.transform.position);
rb.MoveRotation(objectSyncTransform.transform.rotation); //rb.MoveRotation(objectSyncTransform.transform.rotation);
rb.position = objectSyncTransform.transform.position;
rb.rotation = objectSyncTransform.transform.rotation;
_transforms[i].localScale = objectSyncTransform.transform.scale; _transforms[i].localScale = objectSyncTransform.transform.scale;
//_transforms[i].ApplySimpleTransform(objectSyncTransform.transform); //_transforms[i].ApplySimpleTransform(objectSyncTransform.transform);
} }
@@ -186,7 +189,11 @@ namespace BoneSync.Sync.Components
} }
if (poolee) if (poolee)
{ {
return new Rigidbody[] { poolee.GetComponentInChildren<Rigidbody>(true) }; return poolee.GetComponentsInChildren<Rigidbody>(true);
}
if (physicsCart)
{
return new Rigidbody[] { physicsCart.rb };
} }
return new Rigidbody[0]; return new Rigidbody[0];

View File

@@ -18,8 +18,8 @@ namespace BoneSync.Sync.Components
Socket socket = plug._lastSocket; Socket socket = plug._lastSocket;
if (!socket) return null; if (!socket) return null;
if (socket.LockedPlug == plug) return socket; if (socket.LockedPlug == plug) return socket;
if (plug._isExitTransition) return socket;
if (plug._isEnterTransition) return socket; if (plug._isEnterTransition) return socket;
if (plug._isExitTransition) return socket;
return null; return null;
} }
@@ -71,7 +71,7 @@ namespace BoneSync.Sync.Components
private const float PLUG_SYNC_FPS = 1f; private const float PLUG_SYNC_FPS = 1f;
private void TrySendPlugSync() private void TrySendPlugSync()
{ {
if (Time.realtimeSinceStartup - _lastPlugSyncTime > 1 / PLUG_SYNC_FPS) if (Time.realtimeSinceStartup - _lastPlugSyncTime > (1 / PLUG_SYNC_FPS))
{ {
_SendPlugSync(); _SendPlugSync();
} }

View File

@@ -110,7 +110,7 @@ namespace BoneSync.Sync
ObjectSyncMessage message = new ObjectSyncMessage(data); ObjectSyncMessage message = new ObjectSyncMessage(data);
message.Broadcast(); message.Broadcast();
} }
private static Transform _GetPerferredParentTransform(Transform t) private static Transform _GetPerferredSyncRootTransform(Transform t)
{ {
if (t == null) return null; if (t == null) return null;
Transform parent = t.parent; Transform parent = t.parent;
@@ -122,7 +122,7 @@ namespace BoneSync.Sync
InteractableHostManager manager = parent.GetComponentInParent<InteractableHostManager>(); InteractableHostManager manager = parent.GetComponentInParent<InteractableHostManager>();
if (manager) return manager.transform; if (manager) return manager.transform;
return parent; return t;
} }
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncables = true) private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncables = true)
@@ -162,9 +162,13 @@ namespace BoneSync.Sync
if (syncable == null) if (syncable == null)
{ {
Transform perferredObjectParent = _GetPerferredParentTransform(gameObject.transform); Transform perferredObjectParent = _GetPerferredSyncRootTransform(gameObject.transform);
syncable = _MakeOrGetSyncable(perferredObjectParent.gameObject, deleteSubSyncables); Syncable foundComponent = perferredObjectParent.GetComponent<Syncable>();
if (foundComponent)
{
return foundComponent;
}
syncable = perferredObjectParent.gameObject.AddComponent<Syncable>();
} }
return syncable; return syncable;
} }