Files
BoneSync/BoneSync/Sync/Components/SyncableNetworking.cs
2025-03-28 22:30:09 +02:00

195 lines
6.5 KiB
C#

using BoneSync.Data;
using BoneSync.Networking.Messages;
using BoneSync.Patching;
using MelonLoader;
using StressLevelZero.Zones;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace BoneSync.Sync.Components
{
// SyncableNetworking.cs
public partial class Syncable : MonoBehaviour
{
private Queue<byte[]> _simpleEventQueue = new Queue<byte[]>();
private void SendObjectSync()
{
_lastSyncTime = Time.realtimeSinceStartup;
ObjectSync.SendObjectSyncMessage(this);
}
private void TrySendObjectSync()
{
if (ShouldSendSync()) SendObjectSync();
}
public IEnumerator SyncCoroutineAsync()
{
SyncLogger.Msg("Running sync coroutine for: " + transform.GetPath());
if (_syncCoroutineRunning) yield break;
_syncCoroutineRunning = true;
while (isOwner)
{
TrySendAISync();
TrySendObjectSync();
TrySendPlugSync();
yield return new WaitForSeconds(!Registered ? 1 : 1 / OBJECT_SYNC_FPS);
}
_syncCoroutineRunning = false;
yield break;
}
public void SetOwner(ulong ownerId)
{
SyncLogger.Msg("Setting owner for " + _syncId + " to " + ownerId);
_ownerId = ownerId;
FindAndUpdateComponents();
MelonCoroutines.Start(SyncCoroutineAsync());
UpdateKinematic();
TryCatchUpSimpleEvents();
}
public bool ClientSpawningAllowed()
{
if (poolee && poolee.pool)
{
return PoolBlacklist.IsClientSpawnPool(poolee.pool);
}
return false;
}
private IEnumerator __SendRegisterSyncCo()
{
yield return null; // wait a frame
SetSyncId(ObjectSync.SendRegisterSyncableMessage(this));
SetOwner(BoneSync.lobby.GetLocalId());
yield break;
}
private void _SendRegisterSync()
{
SyncLogger.Msg("Registering syncable object: " + gameObject.name);
MelonCoroutines.Start(__SendRegisterSyncCo());
}
private void _SendDiscard(bool despawn = false)
{
SyncLogger.Msg("Sending discard for " + _syncId + " despawn: " + despawn);
DiscardSyncableMessageData discardSyncableMessageData = new DiscardSyncableMessageData()
{
syncId = _syncId,
despawn = despawn
};
DiscardSyncableMessage discardSyncableMessage = new DiscardSyncableMessage(discardSyncableMessageData);
discardSyncableMessage.Broadcast();
}
public void OnOwnershipTransferRequest(ulong newOwnerId)
{
//SyncLogger.Msg("Ownership transfer request for " + _syncId + " to " + newOwnerId);
if (isOwner && !IsHolding() && !_isInHolster)
{
SyncLogger.Msg("Sending ownership transfer for " + _syncId + " to " + newOwnerId);
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
{
syncId = _syncId,
NewOwnerId = newOwnerId,
force = true
};
OwnershipTransferMessage message = new OwnershipTransferMessage(data);
message.Broadcast();
SetOwner(newOwnerId);
}
}
public void TryBecomeOwner(bool force = false)
{
if (Registered && !isOwner)
{
ulong localId = BoneSync.lobby.GetLocalId();
SyncLogger.Msg("Attempting to become owner of " + _syncId + " force: " + force);
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
{
syncId = _syncId,
NewOwnerId = localId,
force = force
};
OwnershipTransferMessage message = new OwnershipTransferMessage(data);
message.Broadcast();
if (force)
{
SetOwner(localId);
}
}
}
public bool ShouldSendSync()
{
if (!Registered) return false;
if (!isOwner) return false;
if (isStale) return true;
if (_isInHolster) return true;
if (AllRigidbodiesSleeping()) return false;
return true;
}
private void AddSimpleEventToQueue(SimpleEventType eType, byte index = 0, byte len = 0)
{
_simpleEventQueue.Enqueue(new byte[] { (byte)eType, index, len });
TryCatchUpSimpleEvents();
}
private void TryCatchUpSimpleEvents()
{
if (Registered && !isOwner)
{
_simpleEventQueue.Clear();
SyncLogger.Debug("Clearing simple event queue for " + _syncId);
return;
}
if (_simpleEventQueue.Count > 0 && Registered && isOwner)
{
byte[] eventData = _simpleEventQueue.Dequeue();
_SendSimpleEvent((SimpleEventType)eventData[0], eventData[1], eventData[2]);
TryCatchUpSimpleEvents();
}
}
private void _SendSimpleEvent(SimpleEventType eType, byte index = 0, byte len = 0)
{
SyncLogger.Msg("Sending simple event: " + eType);
SimpleSyncableEvent data = new SimpleSyncableEvent()
{
syncId = _syncId,
eventType = eType,
index = index,
length = len
};
SimpleSyncableEventMessage simpleSyncEvent = new SimpleSyncableEventMessage(data);
simpleSyncEvent.Broadcast();
}
private void DestroyZoneTrackers()
{
/*ZoneTracker[] zoneTrackers = GetComponentsInChildren<ZoneTracker>(true);
foreach (ZoneTracker zoneTracker in zoneTrackers)
{
Destroy(zoneTracker);
}*/
}
public ushort GetSyncId() => _syncId;
public void SetSyncId(ushort id)
{
_syncId = id;
ObjectSyncCache.UpdateSyncId(this);
if (id != 0)
{
DestroyZoneTrackers();
}
}
}
}