quantum-space-buddies/QSB/Utility/QSBNetworkBehaviour.cs

134 lines
3.1 KiB
C#
Raw Normal View History

2022-01-14 20:13:04 -08:00
using Mirror;
using QSB.WorldSync;
2022-01-14 20:13:04 -08:00
using System;
2022-03-02 19:46:33 -08:00
namespace QSB.Utility;
public abstract class QSBNetworkBehaviour : NetworkBehaviour
2022-01-14 20:13:04 -08:00
{
2022-03-02 19:46:33 -08:00
protected virtual float SendInterval => 0.1f;
protected virtual bool UseReliableRpc => false;
private double _lastSendTime;
private byte[] _lastKnownData;
2022-04-06 11:35:40 -07:00
public override void OnStartClient()
{
DontDestroyOnLoad(gameObject);
RequestInitialStatesMessage.SendInitialState += SendInitialState;
}
public override void OnStopClient() => RequestInitialStatesMessage.SendInitialState -= SendInitialState;
2022-03-14 02:34:04 -07:00
2022-03-02 19:46:33 -08:00
/// <summary>
/// checked before serializing
/// </summary>
protected abstract bool HasChanged();
2022-03-02 19:46:33 -08:00
protected abstract void Serialize(NetworkWriter writer);
2022-03-02 19:46:33 -08:00
/// <summary>
/// called right after serializing
/// </summary>
protected abstract void UpdatePrevData();
2022-03-02 19:46:33 -08:00
protected abstract void Deserialize(NetworkReader reader);
2022-03-02 19:46:33 -08:00
public bool IsValid { get; private set; }
protected virtual bool CheckValid() => QSBWorldSync.AllObjectsReady;
protected virtual void Update()
{
IsValid = CheckValid();
if (!IsValid)
{
return;
}
2023-05-08 11:27:32 -07:00
if (!isOwned)
2022-03-02 19:46:33 -08:00
{
return;
}
2022-03-02 19:46:33 -08:00
if (NetworkTime.localTime >= _lastSendTime + SendInterval)
2022-01-14 20:13:04 -08:00
{
2022-03-02 19:46:33 -08:00
_lastSendTime = NetworkTime.localTime;
if (!HasChanged())
2022-01-14 20:13:04 -08:00
{
return;
}
2023-04-26 22:28:52 +01:00
using var writer = NetworkWriterPool.Get();
2022-03-02 19:46:33 -08:00
Serialize(writer);
UpdatePrevData();
var data = writer.ToArraySegment();
if (UseReliableRpc)
{
2022-03-02 19:46:33 -08:00
CmdSendDataReliable(data);
}
else
{
CmdSendDataUnreliable(data);
2022-01-14 20:13:04 -08:00
}
2022-03-02 19:46:33 -08:00
if (QSBCore.IsHost)
{
2022-03-02 19:46:33 -08:00
_lastKnownData ??= new byte[data.Count];
Array.Copy(data.Array!, data.Offset, _lastKnownData, 0, data.Count);
}
}
2022-03-02 19:46:33 -08:00
}
2022-03-02 19:46:33 -08:00
/// <summary>
/// called on the host to send the last known data to a new client
/// <para/>
/// world objects will be ready on both sides at this point
/// </summary>
2022-04-06 11:35:40 -07:00
private void SendInitialState(uint to)
2022-03-02 19:46:33 -08:00
{
if (_lastKnownData != null)
{
2022-04-06 11:35:40 -07:00
TargetSendInitialData(to.GetNetworkConnection(), new ArraySegment<byte>(_lastKnownData));
}
2022-03-02 19:46:33 -08:00
}
2022-01-14 20:13:04 -08:00
2022-03-02 19:46:33 -08:00
[Command(channel = Channels.Reliable, requiresAuthority = true)]
private void CmdSendDataReliable(ArraySegment<byte> data) => RpcSendDataReliable(data);
2022-01-14 20:13:04 -08:00
2022-03-02 19:46:33 -08:00
[ClientRpc(channel = Channels.Reliable, includeOwner = false)]
private void RpcSendDataReliable(ArraySegment<byte> data) => OnData(data);
2022-01-14 21:25:02 -08:00
2022-03-02 19:46:33 -08:00
[Command(channel = Channels.Unreliable, requiresAuthority = true)]
private void CmdSendDataUnreliable(ArraySegment<byte> data) => RpcSendDataUnreliable(data);
2022-01-14 21:25:02 -08:00
2022-03-02 19:46:33 -08:00
[ClientRpc(channel = Channels.Unreliable, includeOwner = false)]
private void RpcSendDataUnreliable(ArraySegment<byte> data) => OnData(data);
2022-03-02 19:46:33 -08:00
[TargetRpc(channel = Channels.Reliable)]
private void TargetSendInitialData(NetworkConnection target, ArraySegment<byte> data) => OnData(data);
2022-03-02 19:46:33 -08:00
private void OnData(ArraySegment<byte> data)
{
if (!IsValid)
2022-02-25 11:46:44 -08:00
{
2022-03-02 19:46:33 -08:00
return;
}
2023-05-08 11:27:32 -07:00
if (isOwned)
2022-03-02 19:46:33 -08:00
{
return;
}
2022-03-02 19:46:33 -08:00
if (QSBCore.IsHost)
{
_lastKnownData ??= new byte[data.Count];
Array.Copy(data.Array!, data.Offset, _lastKnownData, 0, data.Count);
}
2022-03-02 19:46:33 -08:00
2023-04-26 22:28:52 +01:00
using var reader = NetworkReaderPool.Get(data);
2022-03-02 19:46:33 -08:00
Deserialize(reader);
2022-01-14 20:13:04 -08:00
}
2022-03-14 00:51:25 -07:00
}