195 lines
6.5 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|