2024-02-19 21:00:36 +03:00

668 lines
33 KiB
C#

// base class for networking tests to make things easier.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
namespace Mirror.Tests
{
// inherited by MirrorEditModeTest / MirrorPlayModeTest
// to call SetUp/TearDown by [SetUp]/[UnitySetUp] as needed
public abstract class MirrorTest
{
// keep track of networked GameObjects so we don't have to clean them
// up manually each time.
// CreateNetworked() adds to the list automatically.
public List<GameObject> instantiated;
// we usually need the memory transport
public GameObject holder;
public MemoryTransport transport;
public virtual void SetUp()
{
instantiated = new List<GameObject>();
// need a holder GO. with name for easier debugging.
holder = new GameObject("MirrorTest.holder");
// need a transport to send & receive
Transport.activeTransport = transport = holder.AddComponent<MemoryTransport>();
}
public virtual void TearDown()
{
NetworkClient.Shutdown();
NetworkServer.Shutdown();
// some tests might modify NetworkServer.connections without ever
// starting the server.
// NetworkServer.Shutdown() only clears connections if it was started.
// so let's do it manually for proper test cleanup here.
NetworkServer.connections.Clear();
foreach (GameObject go in instantiated)
if (go != null)
GameObject.DestroyImmediate(go);
GameObject.DestroyImmediate(transport.gameObject);
Transport.activeTransport = null;
NetworkManager.singleton = null;
}
// create a tracked GameObject for tests without Networkidentity
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateGameObject(out GameObject go)
{
go = new GameObject();
// track
instantiated.Add(go);
}
// create GameObject + MonoBehaviour<T>
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateGameObject<T>(out GameObject go, out T component)
where T : MonoBehaviour
{
CreateGameObject(out go);
component = go.AddComponent<T>();
}
// create GameObject + NetworkIdentity
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateNetworked(out GameObject go, out NetworkIdentity identity)
{
go = new GameObject();
identity = go.AddComponent<NetworkIdentity>();
// Awake is only called in play mode.
// call manually for initialization.
identity.Awake();
// track
instantiated.Add(go);
}
// create GameObject + NetworkIdentity + NetworkBehaviour<T>
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateNetworked<T>(out GameObject go, out NetworkIdentity identity, out T component)
where T : NetworkBehaviour
{
go = new GameObject();
identity = go.AddComponent<NetworkIdentity>();
component = go.AddComponent<T>();
// always set syncinterval = 0 for immediate testing
component.syncInterval = 0;
// Awake is only called in play mode.
// call manually for initialization.
identity.Awake();
// track
instantiated.Add(go);
}
// create GameObject + NetworkIdentity + 2x NetworkBehaviour<T>
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateNetworked<T, U>(out GameObject go, out NetworkIdentity identity, out T componentA, out U componentB)
where T : NetworkBehaviour
where U : NetworkBehaviour
{
go = new GameObject();
identity = go.AddComponent<NetworkIdentity>();
componentA = go.AddComponent<T>();
componentB = go.AddComponent<U>();
// always set syncinterval = 0 for immediate testing
componentA.syncInterval = 0;
componentB.syncInterval = 0;
// Awake is only called in play mode.
// call manually for initialization.
identity.Awake();
// track
instantiated.Add(go);
}
// create GameObject + NetworkIdentity + 2x NetworkBehaviour<T>
// add to tracker list if needed (useful for cleanups afterwards)
protected void CreateNetworked<T, U, V>(out GameObject go, out NetworkIdentity identity, out T componentA, out U componentB, out V componentC)
where T : NetworkBehaviour
where U : NetworkBehaviour
where V : NetworkBehaviour
{
go = new GameObject();
identity = go.AddComponent<NetworkIdentity>();
componentA = go.AddComponent<T>();
componentB = go.AddComponent<U>();
componentC = go.AddComponent<V>();
// always set syncinterval = 0 for immediate testing
componentA.syncInterval = 0;
componentB.syncInterval = 0;
componentC.syncInterval = 0;
// Awake is only called in play mode.
// call manually for initialization.
identity.Awake();
// track
instantiated.Add(go);
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
protected void CreateNetworkedAndSpawn(out GameObject go, out NetworkIdentity identity, NetworkConnectionToClient ownerConnection = null)
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
CreateNetworked(out go, out identity);
// spawn
NetworkServer.Spawn(go, ownerConnection);
ProcessMessages();
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawn(
out GameObject serverGO, out NetworkIdentity serverIdentity,
out GameObject clientGO, out NetworkIdentity clientIdentity,
NetworkConnectionToClient ownerConnection = null)
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity);
CreateNetworked(out clientGO, out clientIdentity);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// spawn
NetworkServer.Spawn(serverGO, ownerConnection);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
Debug.Assert(clientIdentity.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
// make sure the client really spawned it.
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
protected void CreateNetworkedAndSpawn<T>(out GameObject go, out NetworkIdentity identity, out T component, NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
CreateNetworked(out go, out identity, out component);
// spawn
NetworkServer.Spawn(go, ownerConnection);
ProcessMessages();
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
Debug.Assert(component.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawn<T>(
out GameObject serverGO, out NetworkIdentity serverIdentity, out T serverComponent,
out GameObject clientGO, out NetworkIdentity clientIdentity, out T clientComponent,
NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity, out serverComponent);
CreateNetworked(out clientGO, out clientIdentity, out clientComponent);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// spawn
NetworkServer.Spawn(serverGO, ownerConnection);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
Debug.Assert(clientComponent.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
// make sure the client really spawned it.
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
protected void CreateNetworkedAndSpawn<T, U>(out GameObject go, out NetworkIdentity identity, out T componentA, out U componentB, NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
where U : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
CreateNetworked(out go, out identity, out componentA, out componentB);
// spawn
NetworkServer.Spawn(go, ownerConnection);
ProcessMessages();
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
{
Debug.Assert(componentA.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(componentB.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
}
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawn<T, U>(
out GameObject serverGO, out NetworkIdentity serverIdentity, out T serverComponentA, out U serverComponentB,
out GameObject clientGO, out NetworkIdentity clientIdentity, out T clientComponentA, out U clientComponentB,
NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
where U : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity, out serverComponentA, out serverComponentB);
CreateNetworked(out clientGO, out clientIdentity, out clientComponentA, out clientComponentB);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// spawn
NetworkServer.Spawn(serverGO, ownerConnection);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
{
Debug.Assert(clientComponentA.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(clientComponentB.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
}
// make sure the client really spawned it.
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
protected void CreateNetworkedAndSpawn<T, U, V>(out GameObject go, out NetworkIdentity identity, out T componentA, out U componentB, out V componentC, NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
where U : NetworkBehaviour
where V : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
CreateNetworked(out go, out identity, out componentA, out componentB, out componentC);
// spawn
NetworkServer.Spawn(go, ownerConnection);
ProcessMessages();
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
{
Debug.Assert(componentA.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(componentB.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(componentC.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
}
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN
// => ownerConnection can be NetworkServer.localConnection if needed.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawn<T, U, V>(
out GameObject serverGO, out NetworkIdentity serverIdentity, out T serverComponentA, out U serverComponentB, out V serverComponentC,
out GameObject clientGO, out NetworkIdentity clientIdentity, out T clientComponentA, out U clientComponentB, out V clientComponentC,
NetworkConnectionToClient ownerConnection = null)
where T : NetworkBehaviour
where U : NetworkBehaviour
where V : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity, out serverComponentA, out serverComponentB, out serverComponentC);
CreateNetworked(out clientGO, out clientIdentity, out clientComponentA, out clientComponentB, out clientComponentC);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// spawn
NetworkServer.Spawn(serverGO, ownerConnection);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// double check that we have authority if we passed an owner connection
if (ownerConnection != null)
{
Debug.Assert(clientComponentA.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(clientComponentB.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
Debug.Assert(clientComponentC.hasAuthority == true, $"Behaviour Had Wrong Authority when spawned, This means that the test is broken and will give the wrong results");
}
// make sure the client really spawned it.
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN PLAYER.
// often times, we really need a player object for the client to receive
// certain messages.
protected void CreateNetworkedAndSpawnPlayer(out GameObject go, out NetworkIdentity identity, NetworkConnectionToClient ownerConnection)
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create a networked object
CreateNetworked(out go, out identity);
// add as player & process spawn message on client.
NetworkServer.AddPlayerForConnection(ownerConnection, go);
ProcessMessages();
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN PLAYER.
// often times, we really need a player object for the client to receive
// certain messages.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawnPlayer(
out GameObject serverGO, out NetworkIdentity serverIdentity,
out GameObject clientGO, out NetworkIdentity clientIdentity,
NetworkConnectionToClient ownerConnection)
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity);
CreateNetworked(out clientGO, out clientIdentity);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// IMPORTANT: OnSpawn finds 'sceneId' in .spawnableObjects.
// only those who are ConsiderForSpawn() are in there.
// for scene objects to be considered, they need to be disabled.
// (it'll be active by the time we return here)
clientGO.SetActive(false);
// add as player & process spawn message on client.
NetworkServer.AddPlayerForConnection(ownerConnection, serverGO);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// make sure the client really spawned it.
Assert.That(clientGO.activeSelf, Is.True);
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
// double check that client object's isClient is really true!
// previously a test magically failed because isClient was false
// even though it should've been true!
Assert.That(clientIdentity.isClient, Is.True);
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN PLAYER.
// often times, we really need a player object for the client to receive
// certain messages.
protected void CreateNetworkedAndSpawnPlayer<T>(out GameObject go, out NetworkIdentity identity, out T component, NetworkConnectionToClient ownerConnection)
where T : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create a networked object
CreateNetworked(out go, out identity, out component);
// add as player & process spawn message on client.
NetworkServer.AddPlayerForConnection(ownerConnection, go);
ProcessMessages();
}
// create GameObject + NetworkIdentity + NetworkBehaviour & SPAWN PLAYER.
// often times, we really need a player object for the client to receive
// certain messages.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawnPlayer<T>(
out GameObject serverGO, out NetworkIdentity serverIdentity, out T serverComponent,
out GameObject clientGO, out NetworkIdentity clientIdentity, out T clientComponent,
NetworkConnectionToClient ownerConnection)
where T : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity, out serverComponent);
CreateNetworked(out clientGO, out clientIdentity, out clientComponent);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// IMPORTANT: OnSpawn finds 'sceneId' in .spawnableObjects.
// only those who are ConsiderForSpawn() are in there.
// for scene objects to be considered, they need to be disabled.
// (it'll be active by the time we return here)
clientGO.SetActive(false);
// add as player & process spawn message on client.
NetworkServer.AddPlayerForConnection(ownerConnection, serverGO);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// make sure the client really spawned it.
Assert.That(clientGO.activeSelf, Is.True);
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// create GameObject + NetworkIdentity + NetworkBehaviours & SPAWN PLAYER.
// often times, we really need a player object for the client to receive
// certain messages.
// => returns objects from client and from server.
// will be same in host mode.
protected void CreateNetworkedAndSpawnPlayer<T, U>(
out GameObject serverGO, out NetworkIdentity serverIdentity, out T serverComponentA, out U serverComponentB,
out GameObject clientGO, out NetworkIdentity clientIdentity, out T clientComponentA, out U clientComponentB,
NetworkConnectionToClient ownerConnection)
where T : NetworkBehaviour
where U : NetworkBehaviour
{
// server & client need to be active before spawning
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// create one on server, one on client
// (spawning has to find it on client, it doesn't create it)
CreateNetworked(out serverGO, out serverIdentity, out serverComponentA, out serverComponentB);
CreateNetworked(out clientGO, out clientIdentity, out clientComponentA, out clientComponentB);
// give both a scene id and register it on client for spawnables
clientIdentity.sceneId = serverIdentity.sceneId = (ulong)serverGO.GetHashCode();
NetworkClient.spawnableObjects[clientIdentity.sceneId] = clientIdentity;
// IMPORTANT: OnSpawn finds 'sceneId' in .spawnableObjects.
// only those who are ConsiderForSpawn() are in there.
// for scene objects to be considered, they need to be disabled.
// (it'll be active by the time we return here)
clientGO.SetActive(false);
// add as player & process spawn message on client.
NetworkServer.AddPlayerForConnection(ownerConnection, serverGO);
ProcessMessages();
// double check isServer/isClient. avoids debugging headaches.
Assert.That(serverIdentity.isServer, Is.True);
Assert.That(clientIdentity.isClient, Is.True);
// make sure the client really spawned it.
Assert.That(clientGO.activeSelf, Is.True);
Assert.That(NetworkClient.spawned.ContainsKey(serverIdentity.netId));
}
// fully connect client to local server
// gives out the server's connection to client for convenience if needed
protected void ConnectClientBlocking(out NetworkConnectionToClient connectionToClient)
{
NetworkClient.Connect("127.0.0.1");
UpdateTransport();
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
connectionToClient = NetworkServer.connections.Values.First();
// set isSpawnFinished flag.
// so that any Spawn() calls will call OnStartClient and set isClient=true
// for the client objects.
// otherwise this would only happen after AddPlayerForConnection.
// but not all tests have a player.
NetworkClient.isSpawnFinished = true;
}
// fully connect client to local server & authenticate
protected void ConnectClientBlockingAuthenticated(out NetworkConnectionToClient connectionToClient)
{
ConnectClientBlocking(out connectionToClient);
// authenticate server & client connections
connectionToClient.isAuthenticated = true;
NetworkClient.connection.isAuthenticated = true;
}
// fully connect client to local server & authenticate & set read
protected void ConnectClientBlockingAuthenticatedAndReady(out NetworkConnectionToClient connectionToClient)
{
ConnectClientBlocking(out connectionToClient);
// authenticate server & client connections
connectionToClient.isAuthenticated = true;
NetworkClient.connection.isAuthenticated = true;
// set ready
NetworkClient.Ready();
ProcessMessages();
Assert.That(connectionToClient.isReady, Is.True);
}
// fully connect HOST client to local server
// sets NetworkServer.localConnection / NetworkClient.connection.
protected void ConnectHostClientBlocking()
{
NetworkClient.ConnectHost();
NetworkClient.ConnectLocalServer();
UpdateTransport();
Assert.That(NetworkServer.connections.Count, Is.EqualTo(1));
// set isSpawnFinished flag.
// so that any Spawn() calls will call OnStartClient and set isClient=true
// for the client objects.
// otherwise this would only happen after AddPlayerForConnection.
// but not all tests have a player.
NetworkClient.isSpawnFinished = true;
}
// fully connect client to local server & authenticate & set read
protected void ConnectHostClientBlockingAuthenticatedAndReady()
{
ConnectHostClientBlocking();
// authenticate server & client connections
NetworkServer.localConnection.isAuthenticated = true;
NetworkClient.connection.isAuthenticated = true;
// set ready
NetworkClient.Ready();
ProcessMessages();
Assert.That(NetworkServer.localConnection.isReady, Is.True);
}
protected void UpdateTransport()
{
transport.ClientEarlyUpdate();
transport.ServerEarlyUpdate();
}
protected void ProcessMessages()
{
// server & client need to be active
Debug.Assert(NetworkClient.active, "NetworkClient needs to be active before spawning.");
Debug.Assert(NetworkServer.active, "NetworkServer needs to be active before spawning.");
// update server & client so batched messages are flushed
NetworkClient.NetworkLateUpdate();
NetworkServer.NetworkLateUpdate();
// update transport so sent messages are received
UpdateTransport();
}
// helper function to create local connection pair
protected void CreateLocalConnectionPair(out LocalConnectionToClient connectionToClient, out LocalConnectionToServer connectionToServer)
{
connectionToClient = new LocalConnectionToClient();
connectionToServer = new LocalConnectionToServer();
connectionToClient.connectionToServer = connectionToServer;
connectionToServer.connectionToClient = connectionToClient;
}
}
}