mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: Removed old obsoletes (#3900)
This commit is contained in:
parent
2f874d3dc4
commit
a00db9fe85
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: bfbf2a1f2b300c5489dcab219ef2846e
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,97 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Mirror.Experimental
|
|
||||||
{
|
|
||||||
[AddComponentMenu("")]
|
|
||||||
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-lerp-rigidbody")]
|
|
||||||
[Obsolete("Use the new NetworkRigidbodyReliable/Unreliable component with Snapshot Interpolation instead.")]
|
|
||||||
public class NetworkLerpRigidbody : NetworkBehaviour
|
|
||||||
{
|
|
||||||
[Header("Settings")]
|
|
||||||
[SerializeField] internal Rigidbody target = null;
|
|
||||||
|
|
||||||
[Tooltip("How quickly current velocity approaches target velocity")]
|
|
||||||
[SerializeField] float lerpVelocityAmount = 0.5f;
|
|
||||||
|
|
||||||
[Tooltip("How quickly current position approaches target position")]
|
|
||||||
[SerializeField] float lerpPositionAmount = 0.5f;
|
|
||||||
|
|
||||||
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
|
||||||
[SerializeField] bool clientAuthority = false;
|
|
||||||
|
|
||||||
double nextSyncTime;
|
|
||||||
|
|
||||||
[SyncVar()]
|
|
||||||
Vector3 targetVelocity;
|
|
||||||
|
|
||||||
[SyncVar()]
|
|
||||||
Vector3 targetPosition;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignore value if is host or client with Authority
|
|
||||||
/// </summary>
|
|
||||||
bool IgnoreSync => isServer || ClientWithAuthority;
|
|
||||||
|
|
||||||
bool ClientWithAuthority => clientAuthority && isOwned;
|
|
||||||
|
|
||||||
protected override void OnValidate()
|
|
||||||
{
|
|
||||||
base.OnValidate();
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Reset()
|
|
||||||
{
|
|
||||||
if (target == null)
|
|
||||||
target = GetComponent<Rigidbody>();
|
|
||||||
|
|
||||||
syncDirection = SyncDirection.ClientToServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
if (isServer)
|
|
||||||
SyncToClients();
|
|
||||||
else if (ClientWithAuthority)
|
|
||||||
SendToServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncToClients()
|
|
||||||
{
|
|
||||||
targetVelocity = target.velocity;
|
|
||||||
targetPosition = target.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendToServer()
|
|
||||||
{
|
|
||||||
double now = NetworkTime.localTime; // Unity 2019 doesn't have Time.timeAsDouble yet
|
|
||||||
if (now > nextSyncTime)
|
|
||||||
{
|
|
||||||
nextSyncTime = now + syncInterval;
|
|
||||||
CmdSendState(target.velocity, target.position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendState(Vector3 velocity, Vector3 position)
|
|
||||||
{
|
|
||||||
target.velocity = velocity;
|
|
||||||
target.position = position;
|
|
||||||
targetVelocity = velocity;
|
|
||||||
targetPosition = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FixedUpdate()
|
|
||||||
{
|
|
||||||
if (IgnoreSync) { return; }
|
|
||||||
|
|
||||||
target.velocity = Vector3.Lerp(target.velocity, targetVelocity, lerpVelocityAmount);
|
|
||||||
target.position = Vector3.Lerp(target.position, targetPosition, lerpPositionAmount);
|
|
||||||
// add velocity to position as position would have moved on server at that velocity
|
|
||||||
target.position += target.velocity * Time.fixedDeltaTime;
|
|
||||||
|
|
||||||
// TODO does this also need to sync acceleration so and update velocity?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7f032128052c95a46afb0ddd97d994cc
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,354 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Mirror.Experimental
|
|
||||||
{
|
|
||||||
[AddComponentMenu("")]
|
|
||||||
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-rigidbody")]
|
|
||||||
[Obsolete("Use the new NetworkRigidbodyReliable/Unreliable component with Snapshot Interpolation instead.")]
|
|
||||||
public class NetworkRigidbody : NetworkBehaviour
|
|
||||||
{
|
|
||||||
[Header("Settings")]
|
|
||||||
[SerializeField] internal Rigidbody target = null;
|
|
||||||
|
|
||||||
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
|
||||||
public bool clientAuthority = false;
|
|
||||||
|
|
||||||
[Header("Velocity")]
|
|
||||||
[Tooltip("Syncs Velocity every SyncInterval")]
|
|
||||||
[SerializeField] bool syncVelocity = true;
|
|
||||||
|
|
||||||
[Tooltip("Set velocity to 0 each frame (only works if syncVelocity is false")]
|
|
||||||
[SerializeField] bool clearVelocity = false;
|
|
||||||
|
|
||||||
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
|
||||||
[SerializeField] float velocitySensitivity = 0.1f;
|
|
||||||
|
|
||||||
[Header("Angular Velocity")]
|
|
||||||
[Tooltip("Syncs AngularVelocity every SyncInterval")]
|
|
||||||
[SerializeField] bool syncAngularVelocity = true;
|
|
||||||
|
|
||||||
[Tooltip("Set angularVelocity to 0 each frame (only works if syncAngularVelocity is false")]
|
|
||||||
[SerializeField] bool clearAngularVelocity = false;
|
|
||||||
|
|
||||||
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
|
||||||
[SerializeField] float angularVelocitySensitivity = 0.1f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Values sent on client with authority after they are sent to the server
|
|
||||||
/// </summary>
|
|
||||||
readonly ClientSyncState previousValue = new ClientSyncState();
|
|
||||||
|
|
||||||
protected override void OnValidate()
|
|
||||||
{
|
|
||||||
base.OnValidate();
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Reset()
|
|
||||||
{
|
|
||||||
if (target == null)
|
|
||||||
target = GetComponent<Rigidbody>();
|
|
||||||
|
|
||||||
syncDirection = SyncDirection.ClientToServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Sync vars
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnVelocityChanged))]
|
|
||||||
Vector3 velocity;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnAngularVelocityChanged))]
|
|
||||||
Vector3 angularVelocity;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnIsKinematicChanged))]
|
|
||||||
bool isKinematic;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnUseGravityChanged))]
|
|
||||||
bool useGravity;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnuDragChanged))]
|
|
||||||
float drag;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnAngularDragChanged))]
|
|
||||||
float angularDrag;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignore value if is host or client with Authority
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
bool IgnoreSync => isServer || ClientWithAuthority;
|
|
||||||
|
|
||||||
bool ClientWithAuthority => clientAuthority && isOwned;
|
|
||||||
|
|
||||||
void OnVelocityChanged(Vector3 _, Vector3 newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.velocity = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnAngularVelocityChanged(Vector3 _, Vector3 newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.angularVelocity = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnIsKinematicChanged(bool _, bool newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.isKinematic = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnUseGravityChanged(bool _, bool newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.useGravity = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnuDragChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.drag = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnAngularDragChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.angularDrag = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
if (isServer)
|
|
||||||
SyncToClients();
|
|
||||||
else if (ClientWithAuthority)
|
|
||||||
SendToServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void FixedUpdate()
|
|
||||||
{
|
|
||||||
if (clearAngularVelocity && !syncAngularVelocity)
|
|
||||||
target.angularVelocity = Vector3.zero;
|
|
||||||
|
|
||||||
if (clearVelocity && !syncVelocity)
|
|
||||||
target.velocity = Vector3.zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates sync var values on server so that they sync to the client
|
|
||||||
/// </summary>
|
|
||||||
[Server]
|
|
||||||
void SyncToClients()
|
|
||||||
{
|
|
||||||
// only update if they have changed more than Sensitivity
|
|
||||||
|
|
||||||
Vector3 currentVelocity = syncVelocity ? target.velocity : default;
|
|
||||||
Vector3 currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
|
||||||
|
|
||||||
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
|
||||||
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
|
||||||
|
|
||||||
if (velocityChanged)
|
|
||||||
{
|
|
||||||
velocity = currentVelocity;
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (angularVelocityChanged)
|
|
||||||
{
|
|
||||||
angularVelocity = currentAngularVelocity;
|
|
||||||
previousValue.angularVelocity = currentAngularVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other rigidbody settings
|
|
||||||
isKinematic = target.isKinematic;
|
|
||||||
useGravity = target.useGravity;
|
|
||||||
drag = target.drag;
|
|
||||||
angularDrag = target.angularDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uses Command to send values to server
|
|
||||||
/// </summary>
|
|
||||||
[Client]
|
|
||||||
void SendToServer()
|
|
||||||
{
|
|
||||||
if (!isOwned)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("SendToServer called without authority");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendVelocity();
|
|
||||||
SendRigidBodySettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Client]
|
|
||||||
void SendVelocity()
|
|
||||||
{
|
|
||||||
double now = NetworkTime.localTime; // Unity 2019 doesn't have Time.timeAsDouble yet
|
|
||||||
if (now < previousValue.nextSyncTime)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3 currentVelocity = syncVelocity ? target.velocity : default;
|
|
||||||
Vector3 currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
|
||||||
|
|
||||||
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
|
||||||
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
|
||||||
|
|
||||||
// if angularVelocity has changed it is likely that velocity has also changed so just sync both values
|
|
||||||
// however if only velocity has changed just send velocity
|
|
||||||
if (angularVelocityChanged)
|
|
||||||
{
|
|
||||||
CmdSendVelocityAndAngular(currentVelocity, currentAngularVelocity);
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
previousValue.angularVelocity = currentAngularVelocity;
|
|
||||||
}
|
|
||||||
else if (velocityChanged)
|
|
||||||
{
|
|
||||||
CmdSendVelocity(currentVelocity);
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// only update syncTime if either has changed
|
|
||||||
if (angularVelocityChanged || velocityChanged)
|
|
||||||
previousValue.nextSyncTime = now + syncInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Client]
|
|
||||||
void SendRigidBodySettings()
|
|
||||||
{
|
|
||||||
// These shouldn't change often so it is ok to send in their own Command
|
|
||||||
if (previousValue.isKinematic != target.isKinematic)
|
|
||||||
{
|
|
||||||
CmdSendIsKinematic(target.isKinematic);
|
|
||||||
previousValue.isKinematic = target.isKinematic;
|
|
||||||
}
|
|
||||||
if (previousValue.useGravity != target.useGravity)
|
|
||||||
{
|
|
||||||
CmdSendUseGravity(target.useGravity);
|
|
||||||
previousValue.useGravity = target.useGravity;
|
|
||||||
}
|
|
||||||
if (previousValue.drag != target.drag)
|
|
||||||
{
|
|
||||||
CmdSendDrag(target.drag);
|
|
||||||
previousValue.drag = target.drag;
|
|
||||||
}
|
|
||||||
if (previousValue.angularDrag != target.angularDrag)
|
|
||||||
{
|
|
||||||
CmdSendAngularDrag(target.angularDrag);
|
|
||||||
previousValue.angularDrag = target.angularDrag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when only Velocity has changed on the client
|
|
||||||
/// </summary>
|
|
||||||
[Command]
|
|
||||||
void CmdSendVelocity(Vector3 velocity)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.velocity = velocity;
|
|
||||||
target.velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when angularVelocity has changed on the client
|
|
||||||
/// </summary>
|
|
||||||
[Command]
|
|
||||||
void CmdSendVelocityAndAngular(Vector3 velocity, Vector3 angularVelocity)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (syncVelocity)
|
|
||||||
{
|
|
||||||
this.velocity = velocity;
|
|
||||||
target.velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.angularVelocity = angularVelocity;
|
|
||||||
target.angularVelocity = angularVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendIsKinematic(bool isKinematic)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.isKinematic = isKinematic;
|
|
||||||
target.isKinematic = isKinematic;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendUseGravity(bool useGravity)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.useGravity = useGravity;
|
|
||||||
target.useGravity = useGravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendDrag(float drag)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.drag = drag;
|
|
||||||
target.drag = drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendAngularDrag(float angularDrag)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.angularDrag = angularDrag;
|
|
||||||
target.angularDrag = angularDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// holds previously synced values
|
|
||||||
/// </summary>
|
|
||||||
public class ClientSyncState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Next sync time that velocity will be synced, based on syncInterval.
|
|
||||||
/// </summary>
|
|
||||||
public double nextSyncTime;
|
|
||||||
public Vector3 velocity;
|
|
||||||
public Vector3 angularVelocity;
|
|
||||||
public bool isKinematic;
|
|
||||||
public bool useGravity;
|
|
||||||
public float drag;
|
|
||||||
public float angularDrag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 83392ae5c1b731446909f252fd494ae4
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,351 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Mirror.Experimental
|
|
||||||
{
|
|
||||||
[AddComponentMenu("")]
|
|
||||||
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-rigidbody")]
|
|
||||||
[Obsolete("Use the new NetworkRigidbodyReliable/Unreliable 2D component with Snapshot Interpolation instead.")]
|
|
||||||
public class NetworkRigidbody2D : NetworkBehaviour
|
|
||||||
{
|
|
||||||
[Header("Settings")]
|
|
||||||
[SerializeField] internal Rigidbody2D target = null;
|
|
||||||
|
|
||||||
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
|
||||||
public bool clientAuthority = false;
|
|
||||||
|
|
||||||
[Header("Velocity")]
|
|
||||||
[Tooltip("Syncs Velocity every SyncInterval")]
|
|
||||||
[SerializeField] bool syncVelocity = true;
|
|
||||||
|
|
||||||
[Tooltip("Set velocity to 0 each frame (only works if syncVelocity is false")]
|
|
||||||
[SerializeField] bool clearVelocity = false;
|
|
||||||
|
|
||||||
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
|
||||||
[SerializeField] float velocitySensitivity = 0.1f;
|
|
||||||
|
|
||||||
[Header("Angular Velocity")]
|
|
||||||
[Tooltip("Syncs AngularVelocity every SyncInterval")]
|
|
||||||
[SerializeField] bool syncAngularVelocity = true;
|
|
||||||
|
|
||||||
[Tooltip("Set angularVelocity to 0 each frame (only works if syncAngularVelocity is false")]
|
|
||||||
[SerializeField] bool clearAngularVelocity = false;
|
|
||||||
|
|
||||||
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
|
||||||
[SerializeField] float angularVelocitySensitivity = 0.1f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Values sent on client with authority after they are sent to the server
|
|
||||||
/// </summary>
|
|
||||||
readonly ClientSyncState previousValue = new ClientSyncState();
|
|
||||||
|
|
||||||
protected override void OnValidate()
|
|
||||||
{
|
|
||||||
base.OnValidate();
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Reset()
|
|
||||||
{
|
|
||||||
if (target == null)
|
|
||||||
target = GetComponent<Rigidbody2D>();
|
|
||||||
|
|
||||||
syncDirection = SyncDirection.ClientToServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Sync vars
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnVelocityChanged))]
|
|
||||||
Vector2 velocity;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnAngularVelocityChanged))]
|
|
||||||
float angularVelocity;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnIsKinematicChanged))]
|
|
||||||
bool isKinematic;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnGravityScaleChanged))]
|
|
||||||
float gravityScale;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnuDragChanged))]
|
|
||||||
float drag;
|
|
||||||
|
|
||||||
[SyncVar(hook = nameof(OnAngularDragChanged))]
|
|
||||||
float angularDrag;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ignore value if is host or client with Authority
|
|
||||||
/// </summary>
|
|
||||||
bool IgnoreSync => isServer || ClientWithAuthority;
|
|
||||||
|
|
||||||
bool ClientWithAuthority => clientAuthority && isOwned;
|
|
||||||
|
|
||||||
void OnVelocityChanged(Vector2 _, Vector2 newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.velocity = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnAngularVelocityChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.angularVelocity = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnIsKinematicChanged(bool _, bool newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.isKinematic = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnGravityScaleChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.gravityScale = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnuDragChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.drag = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnAngularDragChanged(float _, float newValue)
|
|
||||||
{
|
|
||||||
if (IgnoreSync)
|
|
||||||
return;
|
|
||||||
|
|
||||||
target.angularDrag = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
if (isServer)
|
|
||||||
SyncToClients();
|
|
||||||
else if (ClientWithAuthority)
|
|
||||||
SendToServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void FixedUpdate()
|
|
||||||
{
|
|
||||||
if (clearAngularVelocity && !syncAngularVelocity)
|
|
||||||
target.angularVelocity = 0f;
|
|
||||||
|
|
||||||
if (clearVelocity && !syncVelocity)
|
|
||||||
target.velocity = Vector2.zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates sync var values on server so that they sync to the client
|
|
||||||
/// </summary>
|
|
||||||
[Server]
|
|
||||||
void SyncToClients()
|
|
||||||
{
|
|
||||||
// only update if they have changed more than Sensitivity
|
|
||||||
|
|
||||||
Vector2 currentVelocity = syncVelocity ? target.velocity : default;
|
|
||||||
float currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
|
||||||
|
|
||||||
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
|
||||||
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity) > angularVelocitySensitivity);
|
|
||||||
|
|
||||||
if (velocityChanged)
|
|
||||||
{
|
|
||||||
velocity = currentVelocity;
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (angularVelocityChanged)
|
|
||||||
{
|
|
||||||
angularVelocity = currentAngularVelocity;
|
|
||||||
previousValue.angularVelocity = currentAngularVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other rigidbody settings
|
|
||||||
isKinematic = target.isKinematic;
|
|
||||||
gravityScale = target.gravityScale;
|
|
||||||
drag = target.drag;
|
|
||||||
angularDrag = target.angularDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uses Command to send values to server
|
|
||||||
/// </summary>
|
|
||||||
[Client]
|
|
||||||
void SendToServer()
|
|
||||||
{
|
|
||||||
if (!isOwned)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("SendToServer called without authority");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendVelocity();
|
|
||||||
SendRigidBodySettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Client]
|
|
||||||
void SendVelocity()
|
|
||||||
{
|
|
||||||
float now = Time.time;
|
|
||||||
if (now < previousValue.nextSyncTime)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector2 currentVelocity = syncVelocity ? target.velocity : default;
|
|
||||||
float currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
|
||||||
|
|
||||||
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
|
||||||
bool angularVelocityChanged = syncAngularVelocity && previousValue.angularVelocity != currentAngularVelocity;//((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
|
||||||
|
|
||||||
// if angularVelocity has changed it is likely that velocity has also changed so just sync both values
|
|
||||||
// however if only velocity has changed just send velocity
|
|
||||||
if (angularVelocityChanged)
|
|
||||||
{
|
|
||||||
CmdSendVelocityAndAngular(currentVelocity, currentAngularVelocity);
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
previousValue.angularVelocity = currentAngularVelocity;
|
|
||||||
}
|
|
||||||
else if (velocityChanged)
|
|
||||||
{
|
|
||||||
CmdSendVelocity(currentVelocity);
|
|
||||||
previousValue.velocity = currentVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only update syncTime if either has changed
|
|
||||||
if (angularVelocityChanged || velocityChanged)
|
|
||||||
previousValue.nextSyncTime = now + syncInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Client]
|
|
||||||
void SendRigidBodySettings()
|
|
||||||
{
|
|
||||||
// These shouldn't change often so it is ok to send in their own Command
|
|
||||||
if (previousValue.isKinematic != target.isKinematic)
|
|
||||||
{
|
|
||||||
CmdSendIsKinematic(target.isKinematic);
|
|
||||||
previousValue.isKinematic = target.isKinematic;
|
|
||||||
}
|
|
||||||
if (previousValue.gravityScale != target.gravityScale)
|
|
||||||
{
|
|
||||||
CmdChangeGravityScale(target.gravityScale);
|
|
||||||
previousValue.gravityScale = target.gravityScale;
|
|
||||||
}
|
|
||||||
if (previousValue.drag != target.drag)
|
|
||||||
{
|
|
||||||
CmdSendDrag(target.drag);
|
|
||||||
previousValue.drag = target.drag;
|
|
||||||
}
|
|
||||||
if (previousValue.angularDrag != target.angularDrag)
|
|
||||||
{
|
|
||||||
CmdSendAngularDrag(target.angularDrag);
|
|
||||||
previousValue.angularDrag = target.angularDrag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when only Velocity has changed on the client
|
|
||||||
/// </summary>
|
|
||||||
[Command]
|
|
||||||
void CmdSendVelocity(Vector2 velocity)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.velocity = velocity;
|
|
||||||
target.velocity = velocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when angularVelocity has changed on the client
|
|
||||||
/// </summary>
|
|
||||||
[Command]
|
|
||||||
void CmdSendVelocityAndAngular(Vector2 velocity, float angularVelocity)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (syncVelocity)
|
|
||||||
{
|
|
||||||
this.velocity = velocity;
|
|
||||||
target.velocity = velocity;
|
|
||||||
}
|
|
||||||
this.angularVelocity = angularVelocity;
|
|
||||||
target.angularVelocity = angularVelocity;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendIsKinematic(bool isKinematic)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.isKinematic = isKinematic;
|
|
||||||
target.isKinematic = isKinematic;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdChangeGravityScale(float gravityScale)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.gravityScale = gravityScale;
|
|
||||||
target.gravityScale = gravityScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendDrag(float drag)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.drag = drag;
|
|
||||||
target.drag = drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Command]
|
|
||||||
void CmdSendAngularDrag(float angularDrag)
|
|
||||||
{
|
|
||||||
// Ignore messages from client if not in client authority mode
|
|
||||||
if (!clientAuthority)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.angularDrag = angularDrag;
|
|
||||||
target.angularDrag = angularDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// holds previously synced values
|
|
||||||
/// </summary>
|
|
||||||
public class ClientSyncState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Next sync time that velocity will be synced, based on syncInterval.
|
|
||||||
/// </summary>
|
|
||||||
public float nextSyncTime;
|
|
||||||
public Vector2 velocity;
|
|
||||||
public float angularVelocity;
|
|
||||||
public bool isKinematic;
|
|
||||||
public float gravityScale;
|
|
||||||
public float drag;
|
|
||||||
public float angularDrag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ab2cbc52526ea384ba280d13cd1a57b9
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Mirror
|
|
||||||
{
|
|
||||||
// DEPRECATED 2023-06-15
|
|
||||||
[AddComponentMenu("")]
|
|
||||||
[Obsolete("NetworkTransform was renamed to NetworkTransformUnreliable.\nYou can easily swap the component's script by going into the Unity Inspector debug mode:\n1. Click the vertical dots on the top right in the Inspector tab.\n2. Find your NetworkTransform component\n3. Drag NetworkTransformUnreliable into the 'Script' field in the Inspector.\n4. Find the three dots and return to Normal mode.")]
|
|
||||||
public class NetworkTransform : NetworkTransformUnreliable {}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2f74aedd71d9a4f55b3ce499326d45fb
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,12 +0,0 @@
|
|||||||
// A component to synchronize the position of child transforms of networked objects.
|
|
||||||
// There must be a NetworkTransform on the root object of the hierarchy. There can be multiple NetworkTransformChild components on an object. This does not use physics for synchronization, it simply synchronizes the localPosition and localRotation of the child transform and lerps towards the recieved values.
|
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Mirror
|
|
||||||
{
|
|
||||||
// Deprecated 2022-10-25
|
|
||||||
[AddComponentMenu("")]
|
|
||||||
[Obsolete("NetworkTransformChild is not needed anymore. The .target is now exposed in NetworkTransform itself. Note you can open the Inspector in debug view and replace the source script instead of reassigning everything.")]
|
|
||||||
public class NetworkTransformChild : NetworkTransform {}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 734b48bea0b204338958ee3d885e11f0
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -565,23 +565,6 @@ public static void RegisterHandler<T>(Action<T, int> handler, bool requireAuthen
|
|||||||
handlers[msgType] = NetworkMessages.WrapHandler((Action<NetworkConnection, T, int>)HandlerWrapped, requireAuthentication, exceptionsDisconnect);
|
handlers[msgType] = NetworkMessages.WrapHandler((Action<NetworkConnection, T, int>)HandlerWrapped, requireAuthentication, exceptionsDisconnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated 2024-01-21
|
|
||||||
[Obsolete("Use ReplaceHandler without the NetworkConnection parameter instead. This version is obsolete and will be removed soon.")]
|
|
||||||
public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true)
|
|
||||||
where T : struct, NetworkMessage
|
|
||||||
{
|
|
||||||
// we use the same WrapHandler function for server and client.
|
|
||||||
// so let's wrap it to ignore the NetworkConnection parameter.
|
|
||||||
// it's not needed on client. it's always NetworkClient.connection.
|
|
||||||
ushort msgType = NetworkMessageId<T>.Id;
|
|
||||||
|
|
||||||
// register Id <> Type in lookup for debugging.
|
|
||||||
NetworkMessages.Lookup[msgType] = typeof(T);
|
|
||||||
|
|
||||||
void HandlerWrapped(NetworkConnection _, T value) => handler(_, value);
|
|
||||||
handlers[msgType] = NetworkMessages.WrapHandler((Action<NetworkConnection, T>)HandlerWrapped, requireAuthentication, exceptionsDisconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Replace a handler for a particular message type. Should require authentication by default.</summary>
|
/// <summary>Replace a handler for a particular message type. Should require authentication by default.</summary>
|
||||||
// RegisterHandler throws a warning (as it should) if a handler is assigned twice
|
// RegisterHandler throws a warning (as it should) if a handler is assigned twice
|
||||||
// Use of ReplaceHandler makes it clear the user intended to replace the handler
|
// Use of ReplaceHandler makes it clear the user intended to replace the handler
|
||||||
|
@ -207,15 +207,6 @@ internal set
|
|||||||
[FormerlySerializedAs("visible")]
|
[FormerlySerializedAs("visible")]
|
||||||
public Visibility visibility = Visibility.Default;
|
public Visibility visibility = Visibility.Default;
|
||||||
|
|
||||||
// Deprecated 2024-01-21
|
|
||||||
[HideInInspector]
|
|
||||||
[Obsolete("Deprecated - Use .visibility instead. This will be removed soon.")]
|
|
||||||
public Visibility visible
|
|
||||||
{
|
|
||||||
get => visibility;
|
|
||||||
set => visibility = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// broadcasting serializes all entities around a player for each player.
|
// broadcasting serializes all entities around a player for each player.
|
||||||
// we don't want to serialize one entity twice in the same tick.
|
// we don't want to serialize one entity twice in the same tick.
|
||||||
// so we cache the last serialization and remember the timestamp so we
|
// so we cache the last serialization and remember the timestamp so we
|
||||||
|
@ -42,22 +42,6 @@ public class NetworkManager : MonoBehaviour
|
|||||||
[FormerlySerializedAs("serverTickRate")]
|
[FormerlySerializedAs("serverTickRate")]
|
||||||
public int sendRate = 60;
|
public int sendRate = 60;
|
||||||
|
|
||||||
// Deprecated 2023-11-25
|
|
||||||
// Using SerializeField and HideInInspector to self-correct for being
|
|
||||||
// replaced by headlessStartMode. This can be removed in the future.
|
|
||||||
// See OnValidate() for how we handle this.
|
|
||||||
[Obsolete("Deprecated - Use headlessStartMode instead.")]
|
|
||||||
[FormerlySerializedAs("autoStartServerBuild"), SerializeField, HideInInspector]
|
|
||||||
public bool autoStartServerBuild = true;
|
|
||||||
|
|
||||||
// Deprecated 2023-11-25
|
|
||||||
// Using SerializeField and HideInInspector to self-correct for being
|
|
||||||
// replaced by headlessStartMode. This can be removed in the future.
|
|
||||||
// See OnValidate() for how we handle this.
|
|
||||||
[Obsolete("Deprecated - Use headlessStartMode instead.")]
|
|
||||||
[FormerlySerializedAs("autoConnectClientBuild"), SerializeField, HideInInspector]
|
|
||||||
public bool autoConnectClientBuild;
|
|
||||||
|
|
||||||
// client send rate follows server send rate to avoid errors for now
|
// client send rate follows server send rate to avoid errors for now
|
||||||
/// <summary>Client Update frequency, per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.</summary>
|
/// <summary>Client Update frequency, per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.</summary>
|
||||||
// [Tooltip("Client broadcasts 'sendRate' times per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.")]
|
// [Tooltip("Client broadcasts 'sendRate' times per second. Use around 60Hz for fast paced games like Counter-Strike to minimize latency. Use around 30Hz for games like WoW to minimize computations. Use around 1-10Hz for slow paced games like EVE.")]
|
||||||
@ -181,24 +165,6 @@ public class NetworkManager : MonoBehaviour
|
|||||||
// virtual so that inheriting classes' OnValidate() can call base.OnValidate() too
|
// virtual so that inheriting classes' OnValidate() can call base.OnValidate() too
|
||||||
public virtual void OnValidate()
|
public virtual void OnValidate()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618
|
|
||||||
// autoStartServerBuild and autoConnectClientBuild are now obsolete, but to avoid
|
|
||||||
// a breaking change we'll set headlessStartMode to what the user had set before.
|
|
||||||
//
|
|
||||||
// headlessStartMode defaults to DoNothing, so if the user had neither of these
|
|
||||||
// set, then it will remain as DoNothing, and if they set headlessStartMode to
|
|
||||||
// any selection in the inspector it won't get changed back.
|
|
||||||
if (autoStartServerBuild)
|
|
||||||
headlessStartMode = HeadlessStartOptions.AutoStartServer;
|
|
||||||
else if (autoConnectClientBuild)
|
|
||||||
headlessStartMode = HeadlessStartOptions.AutoStartClient;
|
|
||||||
|
|
||||||
// Setting both to false here prevents this code from fighting with user
|
|
||||||
// selection in the inspector, and they're both SerialisedField's.
|
|
||||||
autoStartServerBuild = false;
|
|
||||||
autoConnectClientBuild = false;
|
|
||||||
#pragma warning restore 618
|
|
||||||
|
|
||||||
// always >= 0
|
// always >= 0
|
||||||
maxConnections = Mathf.Max(maxConnections, 0);
|
maxConnections = Mathf.Max(maxConnections, 0);
|
||||||
|
|
||||||
@ -400,11 +366,6 @@ void SetupClient()
|
|||||||
{
|
{
|
||||||
InitializeSingleton();
|
InitializeSingleton();
|
||||||
|
|
||||||
#pragma warning disable 618
|
|
||||||
// Remove when OnConnectionQualityChanged is removed.
|
|
||||||
NetworkClient.onConnectionQualityChanged += OnConnectionQualityChanged;
|
|
||||||
#pragma warning restore 618
|
|
||||||
|
|
||||||
// apply settings before initializing anything
|
// apply settings before initializing anything
|
||||||
NetworkClient.exceptionsDisconnect = exceptionsDisconnect;
|
NetworkClient.exceptionsDisconnect = exceptionsDisconnect;
|
||||||
// NetworkClient.sendRate = clientSendRate;
|
// NetworkClient.sendRate = clientSendRate;
|
||||||
@ -672,11 +633,6 @@ public void StopClient()
|
|||||||
// NetworkManager.OnClientDisconnect
|
// NetworkManager.OnClientDisconnect
|
||||||
NetworkClient.Disconnect();
|
NetworkClient.Disconnect();
|
||||||
|
|
||||||
#pragma warning disable 618
|
|
||||||
// Remove when OnConnectionQualityChanged is removed.
|
|
||||||
NetworkClient.onConnectionQualityChanged -= OnConnectionQualityChanged;
|
|
||||||
#pragma warning restore 618
|
|
||||||
|
|
||||||
// UNET invoked OnDisconnected cleanup immediately.
|
// UNET invoked OnDisconnected cleanup immediately.
|
||||||
// let's keep it for now, in case any projects depend on it.
|
// let's keep it for now, in case any projects depend on it.
|
||||||
// TODO simply remove this in the future.
|
// TODO simply remove this in the future.
|
||||||
@ -1435,24 +1391,6 @@ public virtual void OnClientConnect()
|
|||||||
/// <summary>Called on clients when disconnected from a server.</summary>
|
/// <summary>Called on clients when disconnected from a server.</summary>
|
||||||
public virtual void OnClientDisconnect() { }
|
public virtual void OnClientDisconnect() { }
|
||||||
|
|
||||||
// Deprecated 2023-12-05
|
|
||||||
/// <summary>Deprecated: NetworkClient handles this now.</summary>
|
|
||||||
[Obsolete("NetworkClient handles this now.")]
|
|
||||||
public virtual void CalculateConnectionQuality()
|
|
||||||
{
|
|
||||||
// Moved to NetworkClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated 2023-12-05
|
|
||||||
/// <summary>Deprecated: NetworkClient handles this now.</summary>
|
|
||||||
[Obsolete("This will be removed. Subscribe to NetworkClient.onConnectionQualityChanged in your own code")]
|
|
||||||
public virtual void OnConnectionQualityChanged(ConnectionQuality previous, ConnectionQuality current)
|
|
||||||
{
|
|
||||||
// logging the change is very useful to track down user's lag reports.
|
|
||||||
// we want to include as much detail as possible for debugging.
|
|
||||||
//Debug.Log($"[Mirror] Connection Quality changed from {previous} to {current}:\n rtt={(NetworkTime.rtt * 1000):F1}ms\n rttVar={(NetworkTime.rttVariance * 1000):F1}ms\n bufferTime={(NetworkClient.bufferTime * 1000):F1}ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Called on client when transport raises an exception.</summary>
|
/// <summary>Called on client when transport raises an exception.</summary>
|
||||||
public virtual void OnClientError(TransportError error, string reason) { }
|
public virtual void OnClientError(TransportError error, string reason) { }
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
// "NetworkReaderPooled" instead of "PooledNetworkReader" to group files, for
|
|
||||||
// easier IDE workflow and more elegant code.
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Mirror
|
namespace Mirror
|
||||||
{
|
{
|
||||||
/// <summary>Pooled NetworkReader, automatically returned to pool when using 'using'</summary>
|
/// <summary>Pooled NetworkReader, automatically returned to pool when using 'using'</summary>
|
||||||
// TODO make sealed again after removing obsolete NetworkReaderPooled!
|
public sealed class NetworkReaderPooled : NetworkReader, IDisposable
|
||||||
public class NetworkReaderPooled : NetworkReader, IDisposable
|
|
||||||
{
|
{
|
||||||
internal NetworkReaderPooled(byte[] bytes) : base(bytes) {}
|
internal NetworkReaderPooled(byte[] bytes) : base(bytes) {}
|
||||||
internal NetworkReaderPooled(ArraySegment<byte> segment) : base(segment) {}
|
internal NetworkReaderPooled(ArraySegment<byte> segment) : base(segment) {}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
// "NetworkWriterPooled" instead of "PooledNetworkWriter" to group files, for
|
|
||||||
// easier IDE workflow and more elegant code.
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Mirror
|
namespace Mirror
|
||||||
{
|
{
|
||||||
/// <summary>Pooled NetworkWriter, automatically returned to pool when using 'using'</summary>
|
/// <summary>Pooled NetworkWriter, automatically returned to pool when using 'using'</summary>
|
||||||
// TODO make sealed again after removing obsolete NetworkWriterPooled!
|
public sealed class NetworkWriterPooled : NetworkWriter, IDisposable
|
||||||
public class NetworkWriterPooled : NetworkWriter, IDisposable
|
|
||||||
{
|
{
|
||||||
public void Dispose() => NetworkWriterPool.Return(this);
|
public void Dispose() => NetworkWriterPool.Return(this);
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,6 @@ public class SyncIDictionary<TKey, TValue> : SyncObject, IDictionary<TKey, TValu
|
|||||||
/// <summary>This is called before the data is cleared</summary>
|
/// <summary>This is called before the data is cleared</summary>
|
||||||
public Action OnClear;
|
public Action OnClear;
|
||||||
|
|
||||||
// Deprecated 2024-03-22
|
|
||||||
[Obsolete("Use individual Actions, which pass OLD values where appropriate, instead.")]
|
|
||||||
public Action<Operation, TKey, TValue> Callback;
|
|
||||||
|
|
||||||
protected readonly IDictionary<TKey, TValue> objects;
|
protected readonly IDictionary<TKey, TValue> objects;
|
||||||
|
|
||||||
public SyncIDictionary(IDictionary<TKey, TValue> objects)
|
public SyncIDictionary(IDictionary<TKey, TValue> objects)
|
||||||
@ -343,10 +339,6 @@ void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool chec
|
|||||||
OnChange?.Invoke(op, default, default);
|
OnChange?.Invoke(op, default, default);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
Callback?.Invoke(op, key, item);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => objects.GetEnumerator();
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => objects.GetEnumerator();
|
||||||
|
@ -38,10 +38,6 @@ public enum Operation : byte
|
|||||||
/// <summary>This is called before the list is cleared so the list can be iterated</summary>
|
/// <summary>This is called before the list is cleared so the list can be iterated</summary>
|
||||||
public Action OnClear;
|
public Action OnClear;
|
||||||
|
|
||||||
// Deprecated 2024-03-23
|
|
||||||
[Obsolete("Use individual Actions, which pass OLD values where appropriate, instead.")]
|
|
||||||
public Action<Operation, int, T, T> Callback;
|
|
||||||
|
|
||||||
readonly IList<T> objects;
|
readonly IList<T> objects;
|
||||||
readonly IEqualityComparer<T> comparer;
|
readonly IEqualityComparer<T> comparer;
|
||||||
|
|
||||||
@ -133,10 +129,6 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA
|
|||||||
OnChange?.Invoke(op, itemIndex, default);
|
OnChange?.Invoke(op, itemIndex, default);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
Callback?.Invoke(op, itemIndex, oldItem, newItem);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSerializeAll(NetworkWriter writer)
|
public override void OnSerializeAll(NetworkWriter writer)
|
||||||
|
@ -23,10 +23,6 @@ public class SyncSet<T> : SyncObject, ISet<T>
|
|||||||
/// <summary>This is called BEFORE the data is cleared</summary>
|
/// <summary>This is called BEFORE the data is cleared</summary>
|
||||||
public Action OnClear;
|
public Action OnClear;
|
||||||
|
|
||||||
// Deprecated 2024-03-22
|
|
||||||
[Obsolete("Use individual Actions, which pass OLD value where appropriate, instead.")]
|
|
||||||
public Action<Operation, T> Callback;
|
|
||||||
|
|
||||||
protected readonly ISet<T> objects;
|
protected readonly ISet<T> objects;
|
||||||
|
|
||||||
public int Count => objects.Count;
|
public int Count => objects.Count;
|
||||||
@ -116,23 +112,14 @@ void AddOperation(Operation op, T oldItem, T newItem, bool checkAccess)
|
|||||||
case Operation.OP_ADD:
|
case Operation.OP_ADD:
|
||||||
OnAdd?.Invoke(newItem);
|
OnAdd?.Invoke(newItem);
|
||||||
OnChange?.Invoke(op, newItem);
|
OnChange?.Invoke(op, newItem);
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
Callback?.Invoke(op, newItem);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
break;
|
break;
|
||||||
case Operation.OP_REMOVE:
|
case Operation.OP_REMOVE:
|
||||||
OnRemove?.Invoke(oldItem);
|
OnRemove?.Invoke(oldItem);
|
||||||
OnChange?.Invoke(op, oldItem);
|
OnChange?.Invoke(op, oldItem);
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
Callback?.Invoke(op, oldItem);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
break;
|
break;
|
||||||
case Operation.OP_CLEAR:
|
case Operation.OP_CLEAR:
|
||||||
OnClear?.Invoke();
|
OnClear?.Invoke();
|
||||||
OnChange?.Invoke(op, default);
|
OnChange?.Invoke(op, default);
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
Callback?.Invoke(op, default);
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
namespace Mirror
|
namespace Mirror
|
||||||
{
|
{
|
||||||
/// <summary>Pooled (not threadsafe) NetworkWriter used from Concurrent pool (thread safe). Automatically returned to concurrent pool when using 'using'</summary>
|
/// <summary>Pooled (not threadsafe) NetworkWriter used from Concurrent pool (thread safe). Automatically returned to concurrent pool when using 'using'</summary>
|
||||||
// TODO make sealed again after removing obsolete NetworkWriterPooled!
|
public sealed class ConcurrentNetworkWriterPooled : NetworkWriter, IDisposable
|
||||||
public class ConcurrentNetworkWriterPooled : NetworkWriter, IDisposable
|
|
||||||
{
|
{
|
||||||
public void Dispose() => ConcurrentNetworkWriterPool.Return(this);
|
public void Dispose() => ConcurrentNetworkWriterPool.Return(this);
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,6 @@ IEnumerator AddPlayersToMatchController()
|
|||||||
|
|
||||||
public override void OnStartClient()
|
public override void OnStartClient()
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
|
||||||
matchPlayerData.Callback = UpdateWins;
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
||||||
|
|
||||||
canvasGroup.alpha = 1f;
|
canvasGroup.alpha = 1f;
|
||||||
canvasGroup.interactable = true;
|
canvasGroup.interactable = true;
|
||||||
canvasGroup.blocksRaycasts = true;
|
canvasGroup.blocksRaycasts = true;
|
||||||
|
@ -80,19 +80,6 @@ public void CurlyBracesConstructor()
|
|||||||
public void TestAdd()
|
public void TestAdd()
|
||||||
{
|
{
|
||||||
// Adds a new entry with index of 4 using .Add method
|
// Adds a new entry with index of 4 using .Add method
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
|
||||||
Assert.That(key, Is.EqualTo(4));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnAdd = (key) =>
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
{
|
{
|
||||||
@ -105,7 +92,6 @@ public void TestAdd()
|
|||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(4));
|
Assert.That(clientSyncDictionary.ContainsKey(4));
|
||||||
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,17 +99,6 @@ public void TestAdd()
|
|||||||
public void TestClear()
|
public void TestClear()
|
||||||
{
|
{
|
||||||
// Verifies that the clear method works and that the data is still present for the Callback.
|
// Verifies that the clear method works and that the data is still present for the Callback.
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_CLEAR));
|
|
||||||
Assert.That(clientSyncDictionary.Count, Is.EqualTo(3));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnClear = () =>
|
clientSyncDictionary.OnClear = () =>
|
||||||
{
|
{
|
||||||
@ -134,7 +109,6 @@ public void TestClear()
|
|||||||
serverSyncDictionary.Clear();
|
serverSyncDictionary.Clear();
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(serverSyncDictionary, Is.EquivalentTo(new SyncDictionary<int, string>()));
|
Assert.That(serverSyncDictionary, Is.EquivalentTo(new SyncDictionary<int, string>()));
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,20 +116,6 @@ public void TestClear()
|
|||||||
public void TestSet()
|
public void TestSet()
|
||||||
{
|
{
|
||||||
// Overwrites an existing entry
|
// Overwrites an existing entry
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_SET));
|
|
||||||
Assert.That(key, Is.EqualTo(1));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
|
||||||
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnSet = (key, oldItem) =>
|
clientSyncDictionary.OnSet = (key, oldItem) =>
|
||||||
{
|
{
|
||||||
@ -169,7 +129,6 @@ public void TestSet()
|
|||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(1));
|
Assert.That(clientSyncDictionary.ContainsKey(1));
|
||||||
Assert.That(clientSyncDictionary[1], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[1], Is.EqualTo("yay"));
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,20 +136,6 @@ public void TestSet()
|
|||||||
public void TestBareSet()
|
public void TestBareSet()
|
||||||
{
|
{
|
||||||
// Adds a new entry with index of 4 without using .Add method
|
// Adds a new entry with index of 4 without using .Add method
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
|
||||||
Assert.That(key, Is.EqualTo(4));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
|
||||||
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnAdd = (key) =>
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
{
|
{
|
||||||
@ -203,7 +148,6 @@ public void TestBareSet()
|
|||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(4));
|
Assert.That(clientSyncDictionary.ContainsKey(4));
|
||||||
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,20 +212,6 @@ public void TestContains()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackTest()
|
public void CallbackTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
|
||||||
Assert.That(key, Is.EqualTo(3));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
|
||||||
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnAdd = (key) =>
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
{
|
{
|
||||||
@ -301,7 +231,6 @@ public void CallbackTest()
|
|||||||
|
|
||||||
serverSyncDictionary.Add(3, "yay");
|
serverSyncDictionary.Add(3, "yay");
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -309,19 +238,6 @@ public void CallbackTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void ServerCallbackTest()
|
public void ServerCallbackTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
serverSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
|
||||||
Assert.That(key, Is.EqualTo(3));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
Assert.That(serverSyncDictionary[key], Is.EqualTo("yay"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
serverSyncDictionary.OnAdd = (key) =>
|
serverSyncDictionary.OnAdd = (key) =>
|
||||||
{
|
{
|
||||||
@ -340,7 +256,6 @@ public void ServerCallbackTest()
|
|||||||
};
|
};
|
||||||
|
|
||||||
serverSyncDictionary[3] = "yay";
|
serverSyncDictionary[3] = "yay";
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -348,17 +263,6 @@ public void ServerCallbackTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackRemoveTest()
|
public void CallbackRemoveTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_REMOVE));
|
|
||||||
Assert.That(key, Is.EqualTo(1));
|
|
||||||
Assert.That(item, Is.EqualTo("World"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncDictionary.OnRemove = (key, oldItem) =>
|
clientSyncDictionary.OnRemove = (key, oldItem) =>
|
||||||
{
|
{
|
||||||
@ -379,7 +283,6 @@ public void CallbackRemoveTest()
|
|||||||
|
|
||||||
serverSyncDictionary.Remove(1);
|
serverSyncDictionary.Remove(1);
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
@ -47,17 +47,15 @@ public void OldValueShouldNotBeNewValue()
|
|||||||
player.item.price = 15;
|
player.item.price = 15;
|
||||||
serverList[0] = player;
|
serverList[0] = player;
|
||||||
|
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool callbackCalled = false;
|
bool callbackCalled = false;
|
||||||
clientList.Callback = (SyncList<TestPlayer>.Operation op, int itemIndex, TestPlayer oldItem, TestPlayer newItem) =>
|
clientList.OnChange = (SyncList<TestPlayer>.Operation op, int itemIndex, TestPlayer oldItem) =>
|
||||||
{
|
{
|
||||||
Assert.That(op == SyncList<TestPlayer>.Operation.OP_SET, Is.True);
|
Assert.That(op == SyncList<TestPlayer>.Operation.OP_SET, Is.True);
|
||||||
Assert.That(itemIndex, Is.EqualTo(0));
|
Assert.That(itemIndex, Is.EqualTo(0));
|
||||||
Assert.That(oldItem.item.price, Is.EqualTo(10));
|
Assert.That(oldItem.item.price, Is.EqualTo(10));
|
||||||
Assert.That(newItem.item.price, Is.EqualTo(15));
|
Assert.That(clientList[itemIndex].item.price, Is.EqualTo(15));
|
||||||
callbackCalled = true;
|
callbackCalled = true;
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
SyncListTest.SerializeDeltaTo(serverList, clientList);
|
SyncListTest.SerializeDeltaTo(serverList, clientList);
|
||||||
Assert.IsTrue(callbackCalled);
|
Assert.IsTrue(callbackCalled);
|
||||||
|
@ -97,16 +97,14 @@ public void TestAddRange()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestClear()
|
public void TestClear()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_CLEAR));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_CLEAR));
|
||||||
Assert.That(clientSyncList.Count, Is.EqualTo(3));
|
Assert.That(clientSyncList.Count, Is.EqualTo(3));
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnClear = () =>
|
clientSyncList.OnClear = () =>
|
||||||
@ -125,17 +123,15 @@ public void TestClear()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestInsert()
|
public void TestInsert()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_INSERT));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_INSERT));
|
||||||
Assert.That(index, Is.EqualTo(0));
|
Assert.That(index, Is.EqualTo(0));
|
||||||
Assert.That(newItem, Is.EqualTo("yay"));
|
Assert.That(clientSyncList[index], Is.EqualTo("yay"));
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnInsert = (index) =>
|
clientSyncList.OnInsert = (index) =>
|
||||||
@ -162,18 +158,16 @@ public void TestInsertRange()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSet()
|
public void TestSet()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_SET));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_SET));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(index, Is.EqualTo(1));
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
Assert.That(newItem, Is.EqualTo("yay"));
|
Assert.That(clientSyncList[index], Is.EqualTo("yay"));
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnSet = (index, oldItem) =>
|
clientSyncList.OnSet = (index, oldItem) =>
|
||||||
@ -194,18 +188,16 @@ public void TestSet()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSetNull()
|
public void TestSetNull()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_SET));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_SET));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(index, Is.EqualTo(1));
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
Assert.That(newItem, Is.EqualTo(null));
|
Assert.That(clientSyncList[index], Is.EqualTo(null));
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnSet = (index, oldItem) =>
|
clientSyncList.OnSet = (index, oldItem) =>
|
||||||
@ -222,12 +214,8 @@ public void TestSetNull()
|
|||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
|
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
// clear callback so we don't get called again
|
|
||||||
clientSyncList.Callback = null;
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
// clear handlers so we don't get called again
|
// clear handlers so we don't get called again
|
||||||
|
clientSyncList.OnChange = null;
|
||||||
clientSyncList.OnSet = null;
|
clientSyncList.OnSet = null;
|
||||||
|
|
||||||
serverSyncList[1] = "yay";
|
serverSyncList[1] = "yay";
|
||||||
@ -238,18 +226,15 @@ public void TestSetNull()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRemoveAll()
|
public void TestRemoveAll()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
||||||
Assert.That(index, Is.EqualTo(0));
|
Assert.That(index, Is.EqualTo(0));
|
||||||
Assert.That(oldItem, Is.Not.EqualTo("!"));
|
Assert.That(oldItem, Is.Not.EqualTo("!"));
|
||||||
Assert.That(newItem, Is.EqualTo(default(string)));
|
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnRemove = (index, item) =>
|
clientSyncList.OnRemove = (index, item) =>
|
||||||
@ -278,18 +263,15 @@ public void TestRemoveAllNone()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRemoveAt()
|
public void TestRemoveAt()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(index, Is.EqualTo(1));
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
Assert.That(newItem, Is.EqualTo(default(string)));
|
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnRemove = (index, oldItem) =>
|
clientSyncList.OnRemove = (index, oldItem) =>
|
||||||
@ -309,18 +291,15 @@ public void TestRemoveAt()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRemove()
|
public void TestRemove()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
clientSyncList.OnChange = (op, index, oldItem) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(index, Is.EqualTo(1));
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
Assert.That(newItem, Is.EqualTo(default(string)));
|
|
||||||
};
|
};
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnRemove = (index, oldItem) =>
|
clientSyncList.OnRemove = (index, oldItem) =>
|
||||||
@ -442,19 +421,6 @@ public void SyncListFloatTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackTest()
|
public void CallbackTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_ADD));
|
|
||||||
Assert.That(index, Is.EqualTo(3));
|
|
||||||
Assert.That(oldItem, Is.EqualTo(default(string)));
|
|
||||||
Assert.That(newItem, Is.EqualTo("yay"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnAdd = (index) =>
|
clientSyncList.OnAdd = (index) =>
|
||||||
{
|
{
|
||||||
@ -475,7 +441,6 @@ public void CallbackTest()
|
|||||||
|
|
||||||
serverSyncList.Add("yay");
|
serverSyncList.Add("yay");
|
||||||
SerializeDeltaTo(serverSyncList, clientSyncList);
|
SerializeDeltaTo(serverSyncList, clientSyncList);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -483,18 +448,6 @@ public void CallbackTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackRemoveTest()
|
public void CallbackRemoveTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
|
||||||
Assert.That(newItem, Is.EqualTo(default(string)));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnRemove = (index, oldItem) =>
|
clientSyncList.OnRemove = (index, oldItem) =>
|
||||||
{
|
{
|
||||||
@ -509,12 +462,10 @@ public void CallbackRemoveTest()
|
|||||||
changeActionCalled = true;
|
changeActionCalled = true;
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(index, Is.EqualTo(1));
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
serverSyncList.Remove("World");
|
serverSyncList.Remove("World");
|
||||||
SerializeDeltaTo(serverSyncList, clientSyncList);
|
SerializeDeltaTo(serverSyncList, clientSyncList);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -522,19 +473,6 @@ public void CallbackRemoveTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackRemoveAtTest()
|
public void CallbackRemoveAtTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncList.Callback = (op, index, oldItem, newItem) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_REMOVEAT));
|
|
||||||
Assert.That(index, Is.EqualTo(1));
|
|
||||||
Assert.That(oldItem, Is.EqualTo("World"));
|
|
||||||
Assert.That(newItem, Is.EqualTo(default(string)));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncList.OnRemove = (index, oldItem) =>
|
clientSyncList.OnRemove = (index, oldItem) =>
|
||||||
{
|
{
|
||||||
@ -554,7 +492,6 @@ public void CallbackRemoveAtTest()
|
|||||||
|
|
||||||
serverSyncList.RemoveAt(1);
|
serverSyncList.RemoveAt(1);
|
||||||
SerializeDeltaTo(serverSyncList, clientSyncList);
|
SerializeDeltaTo(serverSyncList, clientSyncList);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
@ -93,17 +93,6 @@ public void TestRemove()
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestClear()
|
public void TestClear()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncSet.Callback = (op, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncHashSet<string>.Operation.OP_CLEAR));
|
|
||||||
Assert.That(clientSyncSet.Count, Is.EqualTo(3));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncSet.OnClear = () =>
|
clientSyncSet.OnClear = () =>
|
||||||
{
|
{
|
||||||
@ -122,7 +111,6 @@ public void TestClear()
|
|||||||
serverSyncSet.Clear();
|
serverSyncSet.Clear();
|
||||||
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
||||||
Assert.That(clientSyncSet, Is.EquivalentTo(new string[] { }));
|
Assert.That(clientSyncSet, Is.EquivalentTo(new string[] { }));
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -141,17 +129,6 @@ public void TestMultSync()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackTest()
|
public void CallbackTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncSet.Callback = (op, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncHashSet<string>.Operation.OP_ADD));
|
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncSet.OnAdd = (item) =>
|
clientSyncSet.OnAdd = (item) =>
|
||||||
{
|
{
|
||||||
@ -169,7 +146,6 @@ public void CallbackTest()
|
|||||||
|
|
||||||
serverSyncSet.Add("yay");
|
serverSyncSet.Add("yay");
|
||||||
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
@ -177,17 +153,6 @@ public void CallbackTest()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackRemoveTest()
|
public void CallbackRemoveTest()
|
||||||
{
|
{
|
||||||
#pragma warning disable 618 // Type or member is obsolete
|
|
||||||
bool called = false;
|
|
||||||
clientSyncSet.Callback = (op, item) =>
|
|
||||||
{
|
|
||||||
called = true;
|
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncHashSet<string>.Operation.OP_REMOVE));
|
|
||||||
Assert.That(item, Is.EqualTo("World"));
|
|
||||||
};
|
|
||||||
#pragma warning restore 618 // Type or member is obsolete
|
|
||||||
|
|
||||||
bool actionCalled = false;
|
bool actionCalled = false;
|
||||||
clientSyncSet.OnRemove = (oldItem) =>
|
clientSyncSet.OnRemove = (oldItem) =>
|
||||||
{
|
{
|
||||||
@ -205,7 +170,6 @@ public void CallbackRemoveTest()
|
|||||||
|
|
||||||
serverSyncSet.Remove("World");
|
serverSyncSet.Remove("World");
|
||||||
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
SerializeDeltaTo(serverSyncSet, clientSyncSet);
|
||||||
Assert.That(called, Is.True);
|
|
||||||
Assert.That(actionCalled, Is.True);
|
Assert.That(actionCalled, Is.True);
|
||||||
Assert.That(changeActionCalled, Is.True);
|
Assert.That(changeActionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user