com.unity.netcode.gameobjects@1.0.0-pre.8
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). ## [1.0.0-pre.8] - 2022-04-27 ### Changed - `unmanaged` structs are no longer universally accepted as RPC parameters because some structs (i.e., structs with pointers in them, such as `NativeList<T>`) can't be supported by the default memcpy struct serializer. Structs that are intended to be serialized across the network must add `INetworkSerializeByMemcpy` to the interface list (i.e., `struct Foo : INetworkSerializeByMemcpy`). This interface is empty and just serves to mark the struct as compatible with memcpy serialization. For external structs you can't edit, you can pass them to RPCs by wrapping them in `ForceNetworkSerializeByMemcpy<T>`. (#1901) ### Removed - Removed `SIPTransport` (#1870) - Removed `ClientNetworkTransform` from the package samples and moved to Boss Room's Utilities package which can be found [here](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/main/Packages/com.unity.multiplayer.samples.coop/Utilities/Net/ClientAuthority/ClientNetworkTransform.cs). ### Fixed - Fixed `NetworkTransform` generating false positive rotation delta checks when rolling over between 0 and 360 degrees. (#1890) - Fixed client throwing an exception if it has messages in the outbound queue when processing the `NetworkEvent.Disconnect` event and is using UTP. (#1884) - Fixed issue during client synchronization if 'ValidateSceneBeforeLoading' returned false it would halt the client synchronization process resulting in a client that was approved but not synchronized or fully connected with the server. (#1883) - Fixed an issue where UNetTransport.StartServer would return success even if the underlying transport failed to start (#854) - Passing generic types to RPCs no longer causes a native crash (#1901) - Fixed an issue where calling `Shutdown` on a `NetworkManager` that was already shut down would cause an immediate shutdown the next time it was started (basically the fix makes `Shutdown` idempotent). (#1877)
This commit is contained in:
@@ -50,7 +50,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnVerifyCanReceive(ulong senderId, Type messageType)
|
||||
public bool OnVerifyCanReceive(ulong senderId, Type messageType, FastBufferReader messageContent, ref NetworkContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -79,6 +79,15 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
protected const uint k_DefaultTickRate = 30;
|
||||
protected abstract int NumberOfClients { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Set this to false to create the clients first.
|
||||
/// Note: If you are using scene placed NetworkObjects or doing any form of scene testing and
|
||||
/// get prefab hash id "soft synchronization" errors, then set this to false and run your test
|
||||
/// again. This is a work-around until we can resolve some issues with NetworkManagerOwner and
|
||||
/// NetworkManager.Singleton.
|
||||
/// </summary>
|
||||
protected bool m_CreateServerFirst = true;
|
||||
|
||||
public enum NetworkManagerInstatiationMode
|
||||
{
|
||||
PerTest, // This will create and destroy new NetworkManagers for each test within a child derived class
|
||||
@@ -108,8 +117,6 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
protected bool m_UseHost = true;
|
||||
protected int m_TargetFrameRate = 60;
|
||||
|
||||
protected NetcodeIntegrationTestHelpers.InstanceTransport m_NetworkTransport = NetcodeIntegrationTestHelpers.InstanceTransport.SIP;
|
||||
|
||||
private NetworkManagerInstatiationMode m_NetworkManagerInstatiationMode;
|
||||
|
||||
private bool m_EnableVerboseDebug;
|
||||
@@ -252,7 +259,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
CreatePlayerPrefab();
|
||||
|
||||
// Create multiple NetworkManager instances
|
||||
if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_NetworkTransport))
|
||||
if (!NetcodeIntegrationTestHelpers.Create(numberOfClients, out NetworkManager server, out NetworkManager[] clients, m_TargetFrameRate, m_CreateServerFirst))
|
||||
{
|
||||
Debug.LogError("Failed to create instances");
|
||||
Assert.Fail("Failed to create instances");
|
||||
@@ -558,6 +565,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
}
|
||||
if (CanDestroyNetworkObject(networkObject))
|
||||
{
|
||||
networkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
// Destroy the GameObject that holds the NetworkObject component
|
||||
Object.DestroyImmediate(networkObject.gameObject);
|
||||
}
|
||||
@@ -668,6 +676,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
var gameObject = new GameObject();
|
||||
gameObject.name = baseName;
|
||||
var networkObject = gameObject.AddComponent<NetworkObject>();
|
||||
networkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(networkObject);
|
||||
var networkPrefab = new NetworkPrefab() { Prefab = gameObject };
|
||||
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(networkPrefab);
|
||||
|
||||
@@ -30,10 +30,16 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
public MessageHandleCheck Check;
|
||||
public bool Result;
|
||||
}
|
||||
internal class MessageReceiveCheckWithResult
|
||||
{
|
||||
public Type CheckType;
|
||||
public bool Result;
|
||||
}
|
||||
|
||||
private class MultiInstanceHooks : INetworkHooks
|
||||
{
|
||||
public Dictionary<Type, List<MessageHandleCheckWithResult>> HandleChecks = new Dictionary<Type, List<MessageHandleCheckWithResult>>();
|
||||
public List<MessageReceiveCheckWithResult> ReceiveChecks = new List<MessageReceiveCheckWithResult>();
|
||||
|
||||
public static bool CheckForMessageOfType<T>(object receivedMessage) where T : INetworkMessage
|
||||
{
|
||||
@@ -50,6 +56,15 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
|
||||
public void OnBeforeReceiveMessage(ulong senderId, Type messageType, int messageSizeBytes)
|
||||
{
|
||||
foreach (var check in ReceiveChecks)
|
||||
{
|
||||
if (check.CheckType == messageType)
|
||||
{
|
||||
check.Result = true;
|
||||
ReceiveChecks.Remove(check);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterReceiveMessage(ulong senderId, Type messageType, int messageSizeBytes)
|
||||
@@ -77,7 +92,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnVerifyCanReceive(ulong senderId, Type messageType)
|
||||
public bool OnVerifyCanReceive(ulong senderId, Type messageType, FastBufferReader messageContent, ref NetworkContext context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -107,12 +122,6 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
|
||||
public static List<NetworkManager> NetworkManagerInstances => s_NetworkManagerInstances;
|
||||
|
||||
public enum InstanceTransport
|
||||
{
|
||||
SIP,
|
||||
UTP
|
||||
}
|
||||
|
||||
internal static IntegrationTestSceneHandler ClientSceneHandler = null;
|
||||
|
||||
/// <summary>
|
||||
@@ -162,20 +171,32 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the correct NetworkTransport, attach it to the game object and return it.
|
||||
/// Default value is SIPTransport.
|
||||
/// </summary>
|
||||
internal static NetworkTransport CreateInstanceTransport(InstanceTransport instanceTransport, GameObject go)
|
||||
public static NetworkManager CreateServer()
|
||||
{
|
||||
switch (instanceTransport)
|
||||
// Create gameObject
|
||||
var go = new GameObject("NetworkManager - Server");
|
||||
|
||||
// Create networkManager component
|
||||
var server = go.AddComponent<NetworkManager>();
|
||||
NetworkManagerInstances.Insert(0, server);
|
||||
|
||||
// Create transport
|
||||
var unityTransport = go.AddComponent<UnityTransport>();
|
||||
// We need to increase this buffer size for tests that spawn a bunch of things
|
||||
unityTransport.MaxPayloadSize = 256000;
|
||||
unityTransport.MaxSendQueueSize = 1024 * 1024;
|
||||
|
||||
// Allow 4 connection attempts that each will time out after 500ms
|
||||
unityTransport.MaxConnectAttempts = 4;
|
||||
unityTransport.ConnectTimeoutMS = 500;
|
||||
|
||||
// Set the NetworkConfig
|
||||
server.NetworkConfig = new NetworkConfig()
|
||||
{
|
||||
case InstanceTransport.SIP:
|
||||
return go.AddComponent<SIPTransport>();
|
||||
default:
|
||||
case InstanceTransport.UTP:
|
||||
return go.AddComponent<UnityTransport>();
|
||||
}
|
||||
// Set transport
|
||||
NetworkTransport = unityTransport
|
||||
};
|
||||
return server;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,24 +206,22 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
/// <param name="server">The server NetworkManager</param>
|
||||
/// <param name="clients">The clients NetworkManagers</param>
|
||||
/// <param name="targetFrameRate">The targetFrameRate of the Unity engine to use while the multi instance helper is running. Will be reset on shutdown.</param>
|
||||
public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, InstanceTransport instanceTransport = InstanceTransport.SIP)
|
||||
/// <param name="serverFirst">This determines if the server or clients will be instantiated first (defaults to server first)</param>
|
||||
public static bool Create(int clientCount, out NetworkManager server, out NetworkManager[] clients, int targetFrameRate = 60, bool serverFirst = true)
|
||||
{
|
||||
s_NetworkManagerInstances = new List<NetworkManager>();
|
||||
CreateNewClients(clientCount, out clients, instanceTransport);
|
||||
|
||||
// Create gameObject
|
||||
var go = new GameObject("NetworkManager - Server");
|
||||
|
||||
// Create networkManager component
|
||||
server = go.AddComponent<NetworkManager>();
|
||||
NetworkManagerInstances.Insert(0, server);
|
||||
|
||||
// Set the NetworkConfig
|
||||
server.NetworkConfig = new NetworkConfig()
|
||||
server = null;
|
||||
if (serverFirst)
|
||||
{
|
||||
// Set transport
|
||||
NetworkTransport = CreateInstanceTransport(instanceTransport, go)
|
||||
};
|
||||
server = CreateServer();
|
||||
}
|
||||
|
||||
CreateNewClients(clientCount, out clients);
|
||||
|
||||
if (!serverFirst)
|
||||
{
|
||||
server = CreateServer();
|
||||
}
|
||||
|
||||
s_OriginalTargetFrameRate = Application.targetFrameRate;
|
||||
Application.targetFrameRate = targetFrameRate;
|
||||
@@ -215,7 +234,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
/// </summary>
|
||||
/// <param name="clientCount">The amount of clients</param>
|
||||
/// <param name="clients"></param>
|
||||
public static bool CreateNewClients(int clientCount, out NetworkManager[] clients, InstanceTransport instanceTransport = InstanceTransport.SIP)
|
||||
public static bool CreateNewClients(int clientCount, out NetworkManager[] clients)
|
||||
{
|
||||
clients = new NetworkManager[clientCount];
|
||||
var activeSceneName = SceneManager.GetActiveScene().name;
|
||||
@@ -226,11 +245,14 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
// Create networkManager component
|
||||
clients[i] = go.AddComponent<NetworkManager>();
|
||||
|
||||
// Create transport
|
||||
var unityTransport = go.AddComponent<UnityTransport>();
|
||||
|
||||
// Set the NetworkConfig
|
||||
clients[i].NetworkConfig = new NetworkConfig()
|
||||
{
|
||||
// Set transport
|
||||
NetworkTransport = CreateInstanceTransport(instanceTransport, go)
|
||||
NetworkTransport = unityTransport
|
||||
};
|
||||
}
|
||||
|
||||
@@ -273,7 +295,10 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
// Destroy the network manager instances
|
||||
foreach (var networkManager in NetworkManagerInstances)
|
||||
{
|
||||
Object.DestroyImmediate(networkManager.gameObject);
|
||||
if (networkManager.gameObject != null)
|
||||
{
|
||||
Object.Destroy(networkManager.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkManagerInstances.Clear();
|
||||
@@ -697,7 +722,35 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
/// </summary>
|
||||
/// <param name="result">The result. If null, it will fail if the predicate is not met</param>
|
||||
/// <param name="timeout">The max time in seconds to wait for</param>
|
||||
internal static IEnumerator WaitForMessageOfType<T>(NetworkManager toBeReceivedBy, ResultWrapper<bool> result = null, float timeout = 0.5f) where T : INetworkMessage
|
||||
internal static IEnumerator WaitForMessageOfTypeReceived<T>(NetworkManager toBeReceivedBy, ResultWrapper<bool> result = null, float timeout = 0.5f) where T : INetworkMessage
|
||||
{
|
||||
var hooks = s_Hooks[toBeReceivedBy];
|
||||
var check = new MessageReceiveCheckWithResult { CheckType = typeof(T) };
|
||||
hooks.ReceiveChecks.Add(check);
|
||||
if (result == null)
|
||||
{
|
||||
result = new ResultWrapper<bool>();
|
||||
}
|
||||
|
||||
var startTime = Time.realtimeSinceStartup;
|
||||
|
||||
while (!check.Result && Time.realtimeSinceStartup - startTime < timeout)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
var res = check.Result;
|
||||
result.Result = res;
|
||||
|
||||
Assert.True(result.Result, $"Expected message {typeof(T).Name} was not received within {timeout}s.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for a message of the given type to be received
|
||||
/// </summary>
|
||||
/// <param name="result">The result. If null, it will fail if the predicate is not met</param>
|
||||
/// <param name="timeout">The max time in seconds to wait for</param>
|
||||
internal static IEnumerator WaitForMessageOfTypeHandled<T>(NetworkManager toBeReceivedBy, ResultWrapper<bool> result = null, float timeout = 0.5f) where T : INetworkMessage
|
||||
{
|
||||
var hooks = s_Hooks[toBeReceivedBy];
|
||||
if (!hooks.HandleChecks.ContainsKey(typeof(T)))
|
||||
@@ -712,7 +765,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
}
|
||||
yield return ExecuteWaitForHook(check, result, timeout);
|
||||
|
||||
Assert.True(result.Result, $"Expected message {typeof(T).Name} was not received within {timeout}s.");
|
||||
Assert.True(result.Result, $"Expected message {typeof(T).Name} was not handled within {timeout}s.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -721,7 +774,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
/// <param name="requirement">Called for each received message to check if it's the right one</param>
|
||||
/// <param name="result">The result. If null, it will fail if the predicate is not met</param>
|
||||
/// <param name="timeout">The max time in seconds to wait for</param>
|
||||
internal static IEnumerator WaitForMessageMeetingRequirement<T>(NetworkManager toBeReceivedBy, MessageHandleCheck requirement, ResultWrapper<bool> result = null, float timeout = DefaultTimeout)
|
||||
internal static IEnumerator WaitForMessageMeetingRequirementHandled<T>(NetworkManager toBeReceivedBy, MessageHandleCheck requirement, ResultWrapper<bool> result = null, float timeout = DefaultTimeout)
|
||||
{
|
||||
var hooks = s_Hooks[toBeReceivedBy];
|
||||
if (!hooks.HandleChecks.ContainsKey(typeof(T)))
|
||||
@@ -736,7 +789,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
}
|
||||
yield return ExecuteWaitForHook(check, result, timeout);
|
||||
|
||||
Assert.True(result.Result, $"Expected message meeting user requirements was not received within {timeout}s.");
|
||||
Assert.True(result.Result, $"Expected message meeting user requirements was not handled within {timeout}s.");
|
||||
}
|
||||
|
||||
private static IEnumerator ExecuteWaitForHook(MessageHandleCheckWithResult check, ResultWrapper<bool> result, float timeout)
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using NUnit.Framework;
|
||||
using Unity.Netcode.Transports.UTP;
|
||||
|
||||
namespace Unity.Netcode.TestHelpers.Runtime
|
||||
{
|
||||
@@ -67,11 +68,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
|
||||
Debug.Log($"{nameof(NetworkManager)} Instantiated.");
|
||||
|
||||
// NOTE: For now we only use SIPTransport for tests until UnityTransport
|
||||
// has been verified working in nightly builds
|
||||
// TODO-MTT-2486: Provide support for other transports once tested and verified
|
||||
// working on consoles.
|
||||
var sipTransport = NetworkManagerGameObject.AddComponent<SIPTransport>();
|
||||
var unityTransport = NetworkManagerGameObject.AddComponent<UnityTransport>();
|
||||
if (networkConfig == null)
|
||||
{
|
||||
networkConfig = new NetworkConfig
|
||||
@@ -81,7 +78,7 @@ namespace Unity.Netcode.TestHelpers.Runtime
|
||||
}
|
||||
|
||||
NetworkManagerObject.NetworkConfig = networkConfig;
|
||||
NetworkManagerObject.NetworkConfig.NetworkTransport = sipTransport;
|
||||
NetworkManagerObject.NetworkConfig.NetworkTransport = unityTransport;
|
||||
|
||||
// Starts the network manager in the mode specified
|
||||
StartNetworkManagerMode(managerMode);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d764f651f0e54e8281952933cc49be97
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,267 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Netcode.TestHelpers.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// SIPTransport (SIngleProcessTransport)
|
||||
/// is a NetworkTransport designed to be used with multiple network instances in a single process
|
||||
/// it's designed for the netcode in a way where no networking stack has to be available
|
||||
/// it's designed for testing purposes and it's not designed with speed in mind
|
||||
/// </summary>
|
||||
public class SIPTransport : TestingNetworkTransport
|
||||
{
|
||||
private struct Event
|
||||
{
|
||||
public NetworkEvent Type;
|
||||
public ulong ConnectionId;
|
||||
public ArraySegment<byte> Data;
|
||||
}
|
||||
|
||||
private class Peer
|
||||
{
|
||||
public ulong ConnectionId;
|
||||
public SIPTransport Transport;
|
||||
public Queue<Event> IncomingBuffer = new Queue<Event>();
|
||||
}
|
||||
|
||||
private readonly Dictionary<ulong, Peer> m_Peers = new Dictionary<ulong, Peer>();
|
||||
private ulong m_ClientsCounter = 1;
|
||||
|
||||
private static Peer s_Server;
|
||||
private Peer m_LocalConnection;
|
||||
|
||||
public override ulong ServerClientId => 0;
|
||||
public ulong LocalClientId;
|
||||
|
||||
public override void DisconnectLocalClient()
|
||||
{
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
// Inject local disconnect
|
||||
m_LocalConnection.IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Disconnect,
|
||||
ConnectionId = m_LocalConnection.ConnectionId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
|
||||
if (s_Server != null && m_LocalConnection != null)
|
||||
{
|
||||
// Remove the connection
|
||||
s_Server.Transport.m_Peers.Remove(m_LocalConnection.ConnectionId);
|
||||
}
|
||||
|
||||
if (m_LocalConnection.ConnectionId == ServerClientId)
|
||||
{
|
||||
StopServer();
|
||||
}
|
||||
|
||||
// Remove the local connection
|
||||
m_LocalConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called by server
|
||||
public override void DisconnectRemoteClient(ulong clientId)
|
||||
{
|
||||
if (m_Peers.ContainsKey(clientId))
|
||||
{
|
||||
// Inject disconnect into remote
|
||||
m_Peers[clientId].IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Disconnect,
|
||||
ConnectionId = clientId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
|
||||
// Inject local disconnect
|
||||
m_LocalConnection.IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Disconnect,
|
||||
ConnectionId = clientId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
|
||||
// Remove the local connection on remote
|
||||
m_Peers[clientId].Transport.m_LocalConnection = null;
|
||||
|
||||
// Remove connection on server
|
||||
m_Peers.Remove(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
public override ulong GetCurrentRtt(ulong clientId)
|
||||
{
|
||||
// Always returns 50ms
|
||||
return 50;
|
||||
}
|
||||
|
||||
public override void Initialize(NetworkManager networkManager = null)
|
||||
{
|
||||
}
|
||||
|
||||
private void StopServer()
|
||||
{
|
||||
s_Server = null;
|
||||
m_Peers.Remove(ServerClientId);
|
||||
m_LocalConnection = null;
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
// Inject disconnects to all the remotes
|
||||
foreach (KeyValuePair<ulong, Peer> onePeer in m_Peers)
|
||||
{
|
||||
onePeer.Value.IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Disconnect,
|
||||
ConnectionId = LocalClientId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
}
|
||||
|
||||
if (m_LocalConnection != null && m_LocalConnection.ConnectionId == ServerClientId)
|
||||
{
|
||||
StopServer();
|
||||
}
|
||||
|
||||
|
||||
// TODO: Cleanup
|
||||
}
|
||||
|
||||
public override bool StartClient()
|
||||
{
|
||||
if (s_Server == null)
|
||||
{
|
||||
// No server
|
||||
Debug.LogError("No server");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
// Already connected
|
||||
Debug.LogError("Already connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate an Id for the server that represents this client
|
||||
ulong serverConnectionId = ++s_Server.Transport.m_ClientsCounter;
|
||||
LocalClientId = serverConnectionId;
|
||||
|
||||
// Create local connection
|
||||
m_LocalConnection = new Peer()
|
||||
{
|
||||
ConnectionId = serverConnectionId,
|
||||
Transport = this,
|
||||
IncomingBuffer = new Queue<Event>()
|
||||
};
|
||||
|
||||
// Add the server as a local connection
|
||||
m_Peers.Add(ServerClientId, s_Server);
|
||||
|
||||
// Add local connection as a connection on the server
|
||||
s_Server.Transport.m_Peers.Add(serverConnectionId, m_LocalConnection);
|
||||
|
||||
// Sends a connect message to the server
|
||||
s_Server.Transport.m_LocalConnection.IncomingBuffer.Enqueue(new Event()
|
||||
{
|
||||
Type = NetworkEvent.Connect,
|
||||
ConnectionId = serverConnectionId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
|
||||
// Send a local connect message
|
||||
m_LocalConnection.IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Connect,
|
||||
ConnectionId = ServerClientId,
|
||||
Data = new ArraySegment<byte>()
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool StartServer()
|
||||
{
|
||||
if (s_Server != null)
|
||||
{
|
||||
// Can only have one server
|
||||
Debug.LogError("Server already started");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
// Already connected
|
||||
Debug.LogError("Already connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create local connection
|
||||
m_LocalConnection = new Peer()
|
||||
{
|
||||
ConnectionId = ServerClientId,
|
||||
Transport = this,
|
||||
IncomingBuffer = new Queue<Event>()
|
||||
};
|
||||
|
||||
// Set the local connection as the server
|
||||
s_Server = m_LocalConnection;
|
||||
|
||||
m_Peers.Add(ServerClientId, s_Server);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Send(ulong clientId, ArraySegment<byte> payload, NetworkDelivery networkDelivery)
|
||||
{
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
// Create copy since netcode wants the byte array back straight after the method call.
|
||||
// Hard on GC.
|
||||
byte[] copy = new byte[payload.Count];
|
||||
Buffer.BlockCopy(payload.Array, payload.Offset, copy, 0, payload.Count);
|
||||
|
||||
if (m_Peers.ContainsKey(clientId))
|
||||
{
|
||||
m_Peers[clientId].IncomingBuffer.Enqueue(new Event
|
||||
{
|
||||
Type = NetworkEvent.Data,
|
||||
ConnectionId = m_LocalConnection.ConnectionId,
|
||||
Data = new ArraySegment<byte>(copy)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
|
||||
{
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
if (m_LocalConnection.IncomingBuffer.Count == 0)
|
||||
{
|
||||
clientId = 0;
|
||||
payload = new ArraySegment<byte>();
|
||||
receiveTime = 0;
|
||||
return NetworkEvent.Nothing;
|
||||
}
|
||||
|
||||
var peerEvent = m_LocalConnection.IncomingBuffer.Dequeue();
|
||||
|
||||
clientId = peerEvent.ConnectionId;
|
||||
payload = peerEvent.Data;
|
||||
receiveTime = 0;
|
||||
|
||||
return peerEvent.Type;
|
||||
}
|
||||
|
||||
clientId = 0;
|
||||
payload = new ArraySegment<byte>();
|
||||
receiveTime = 0;
|
||||
return NetworkEvent.Nothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fd1b14eba874a189f13f12d343c331c
|
||||
timeCreated: 1620145176
|
||||
Reference in New Issue
Block a user