585 lines
20 KiB
C#
585 lines
20 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using System.IO;
|
|
using System;
|
|
using MLAPI.Serialization.Pooled;
|
|
using MLAPI.Transports;
|
|
|
|
namespace MLAPI.NetworkVariable
|
|
{
|
|
/// <summary>
|
|
/// A variable that can be synchronized over the network.
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariable<T> : INetworkVariable
|
|
{
|
|
/// <summary>
|
|
/// The settings for this var
|
|
/// </summary>
|
|
public readonly NetworkVariableSettings Settings = new NetworkVariableSettings();
|
|
|
|
/// <summary>
|
|
/// The last time the variable was written to locally
|
|
/// </summary>
|
|
public ushort LocalTick { get; internal set; }
|
|
/// <summary>
|
|
/// The last time the variable was written to remotely. Uses the remote timescale
|
|
/// </summary>
|
|
public ushort RemoteTick { get; internal set; }
|
|
/// <summary>
|
|
/// Delegate type for value changed event
|
|
/// </summary>
|
|
/// <param name="previousValue">The value before the change</param>
|
|
/// <param name="newValue">The new value</param>
|
|
public delegate void OnValueChangedDelegate(T previousValue, T newValue);
|
|
/// <summary>
|
|
/// The callback to be invoked when the value gets changed
|
|
/// </summary>
|
|
public OnValueChangedDelegate OnValueChanged;
|
|
|
|
private NetworkBehaviour m_NetworkBehaviour;
|
|
|
|
/// <summary>
|
|
/// Creates a NetworkVariable with the default value and settings
|
|
/// </summary>
|
|
public NetworkVariable() { }
|
|
|
|
/// <summary>
|
|
/// Creates a NetworkVariable with the default value and custom settings
|
|
/// </summary>
|
|
/// <param name="settings">The settings to use for the NetworkVariable</param>
|
|
public NetworkVariable(NetworkVariableSettings settings)
|
|
{
|
|
Settings = settings;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a NetworkVariable with a custom value and custom settings
|
|
/// </summary>
|
|
/// <param name="settings">The settings to use for the NetworkVariable</param>
|
|
/// <param name="value">The initial value to use for the NetworkVariable</param>
|
|
public NetworkVariable(NetworkVariableSettings settings, T value)
|
|
{
|
|
Settings = settings;
|
|
m_InternalValue = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a NetworkVariable with a custom value and the default settings
|
|
/// </summary>
|
|
/// <param name="value">The initial value to use for the NetworkVariable</param>
|
|
public NetworkVariable(T value)
|
|
{
|
|
m_InternalValue = value;
|
|
}
|
|
|
|
[SerializeField]
|
|
private T m_InternalValue;
|
|
|
|
/// <summary>
|
|
/// The value of the NetworkVariable container
|
|
/// </summary>
|
|
public T Value
|
|
{
|
|
get => m_InternalValue;
|
|
set
|
|
{
|
|
if (EqualityComparer<T>.Default.Equals(m_InternalValue, value)) return;
|
|
|
|
// Setter is assumed to be called locally, by game code.
|
|
// When used by the host, it is its responsibility to set the RemoteTick
|
|
RemoteTick = NetworkTickSystem.NoTick;
|
|
|
|
m_IsDirty = true;
|
|
T previousValue = m_InternalValue;
|
|
m_InternalValue = value;
|
|
OnValueChanged?.Invoke(previousValue, m_InternalValue);
|
|
}
|
|
}
|
|
|
|
private bool m_IsDirty = false;
|
|
|
|
/// <summary>
|
|
/// Sets whether or not the variable needs to be delta synced
|
|
/// </summary>
|
|
public void SetDirty(bool isDirty)
|
|
{
|
|
m_IsDirty = isDirty;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool IsDirty()
|
|
{
|
|
return m_IsDirty;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void ResetDirty()
|
|
{
|
|
m_IsDirty = false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool CanClientRead(ulong clientId)
|
|
{
|
|
switch (Settings.ReadPermission)
|
|
{
|
|
case NetworkVariablePermission.Everyone:
|
|
return true;
|
|
case NetworkVariablePermission.ServerOnly:
|
|
return false;
|
|
case NetworkVariablePermission.OwnerOnly:
|
|
return m_NetworkBehaviour.OwnerClientId == clientId;
|
|
case NetworkVariablePermission.Custom:
|
|
{
|
|
if (Settings.ReadPermissionCallback == null) return false;
|
|
return Settings.ReadPermissionCallback(clientId);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Writes the variable to the writer
|
|
/// </summary>
|
|
/// <param name="stream">The stream to write the value to</param>
|
|
public void WriteDelta(Stream stream)
|
|
{
|
|
WriteField(stream);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool CanClientWrite(ulong clientId)
|
|
{
|
|
switch (Settings.WritePermission)
|
|
{
|
|
case NetworkVariablePermission.Everyone:
|
|
return true;
|
|
case NetworkVariablePermission.ServerOnly:
|
|
return false;
|
|
case NetworkVariablePermission.OwnerOnly:
|
|
return m_NetworkBehaviour.OwnerClientId == clientId;
|
|
case NetworkVariablePermission.Custom:
|
|
{
|
|
if (Settings.WritePermissionCallback == null) return false;
|
|
return Settings.WritePermissionCallback(clientId);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads value from the reader and applies it
|
|
/// </summary>
|
|
/// <param name="stream">The stream to read the value from</param>
|
|
/// <param name="keepDirtyDelta">Whether or not the container should keep the dirty delta, or mark the delta as consumed</param>
|
|
public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
|
|
{
|
|
// todo: This allows the host-returned value to be set back to an old value
|
|
// this will need to be adjusted to check if we're have a most recent value
|
|
LocalTick = localTick;
|
|
RemoteTick = remoteTick;
|
|
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
T previousValue = m_InternalValue;
|
|
m_InternalValue = (T)reader.ReadObjectPacked(typeof(T));
|
|
|
|
if (keepDirtyDelta) m_IsDirty = true;
|
|
|
|
OnValueChanged?.Invoke(previousValue, m_InternalValue);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void SetNetworkBehaviour(NetworkBehaviour behaviour)
|
|
{
|
|
m_NetworkBehaviour = behaviour;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
|
|
{
|
|
ReadDelta(stream, false, localTick, remoteTick);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void WriteField(Stream stream)
|
|
{
|
|
// Store the local tick at which this NetworkVariable was modified
|
|
LocalTick = NetworkBehaviour.CurrentTick;
|
|
using (var writer = PooledNetworkWriter.Get(stream))
|
|
{
|
|
writer.WriteObjectPacked(m_InternalValue); //BOX
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public NetworkChannel GetChannel()
|
|
{
|
|
return Settings.SendNetworkChannel;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds strings and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableString : NetworkVariable<string>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableString() : base(string.Empty) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableString(NetworkVariableSettings settings) : base(settings, string.Empty) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableString(string value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableString(NetworkVariableSettings settings, string value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds bools and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableBool : NetworkVariable<bool>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableBool() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableBool(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableBool(bool value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableBool(NetworkVariableSettings settings, bool value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds bytes and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableByte : NetworkVariable<byte>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableByte() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableByte(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableByte(byte value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableByte(NetworkVariableSettings settings, byte value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds sbytes and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableSByte : NetworkVariable<sbyte>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableSByte() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableSByte(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableSByte(sbyte value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableSByte(NetworkVariableSettings settings, sbyte value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds ushorts and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableUShort : NetworkVariable<ushort>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableUShort() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUShort(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUShort(ushort value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUShort(NetworkVariableSettings settings, ushort value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds shorts and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableShort : NetworkVariable<short>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableShort() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableShort(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableShort(short value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableShort(NetworkVariableSettings settings, short value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds uints and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableUInt : NetworkVariable<uint>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableUInt() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUInt(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUInt(uint value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableUInt(NetworkVariableSettings settings, uint value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds ints and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableInt : NetworkVariable<int>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableInt() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableInt(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableInt(int value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableInt(NetworkVariableSettings settings, int value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds ulongs and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableULong : NetworkVariable<ulong>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableULong() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableULong(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableULong(ulong value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableULong(NetworkVariableSettings settings, ulong value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds longs and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableLong : NetworkVariable<long>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableLong() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableLong(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableLong(long value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableLong(NetworkVariableSettings settings, long value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds floats and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableFloat : NetworkVariable<float>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableFloat() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableFloat(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableFloat(float value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableFloat(NetworkVariableSettings settings, float value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds doubles and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableDouble : NetworkVariable<double>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableDouble() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableDouble(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableDouble(double value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableDouble(NetworkVariableSettings settings, double value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds vector2s and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableVector2 : NetworkVariable<Vector2>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector2() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector2(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector2(Vector2 value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector2(NetworkVariableSettings settings, Vector2 value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds vector3s and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableVector3 : NetworkVariable<Vector3>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector3() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector3(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector3(Vector3 value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector3(NetworkVariableSettings settings, Vector3 value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds vector4s and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableVector4 : NetworkVariable<Vector4>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector4() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector4(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector4(Vector4 value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableVector4(NetworkVariableSettings settings, Vector4 value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds colors and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableColor : NetworkVariable<Color>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor(Color value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor(NetworkVariableSettings settings, Color value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds color32s and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableColor32 : NetworkVariable<Color32>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor32() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor32(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor32(Color32 value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableColor32(NetworkVariableSettings settings, Color32 value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds rays and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableRay : NetworkVariable<Ray>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableRay() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableRay(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableRay(Ray value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableRay(NetworkVariableSettings settings, Ray value) : base(settings, value) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A NetworkVariable that holds quaternions and support serialization
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkVariableQuaternion : NetworkVariable<Quaternion>
|
|
{
|
|
/// <inheritdoc />
|
|
public NetworkVariableQuaternion() { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableQuaternion(NetworkVariableSettings settings) : base(settings) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableQuaternion(Quaternion value) : base(value) { }
|
|
|
|
/// <inheritdoc />
|
|
public NetworkVariableQuaternion(NetworkVariableSettings settings, Quaternion value) : base(settings, value) { }
|
|
}
|
|
}
|