642 lines
No EOL
30 KiB
C#
642 lines
No EOL
30 KiB
C#
using System;
|
|
using System.IO;
|
|
using MLAPI.Connection;
|
|
using MLAPI.Logging;
|
|
using MLAPI.SceneManagement;
|
|
using MLAPI.Serialization.Pooled;
|
|
using MLAPI.Spawning;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.SceneManagement;
|
|
using System.Collections.Generic;
|
|
using MLAPI.Configuration;
|
|
using MLAPI.Messaging.Buffering;
|
|
using MLAPI.Profiling;
|
|
using MLAPI.Serialization;
|
|
using Unity.Profiling;
|
|
|
|
namespace MLAPI.Messaging
|
|
{
|
|
internal static class InternalMessageHandler
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
private static ProfilerMarker s_HandleConnectionRequest = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleConnectionRequest)}");
|
|
private static ProfilerMarker s_HandleConnectionApproved = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleConnectionApproved)}");
|
|
private static ProfilerMarker s_HandleAddObject = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleAddObject)}");
|
|
private static ProfilerMarker s_HandleDestroyObject = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleDestroyObject)}");
|
|
private static ProfilerMarker s_HandleSwitchScene = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleSwitchScene)}");
|
|
private static ProfilerMarker s_HandleClientSwitchSceneCompleted = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleClientSwitchSceneCompleted)}");
|
|
private static ProfilerMarker s_HandleChangeOwner = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleChangeOwner)}");
|
|
private static ProfilerMarker s_HandleAddObjects = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleAddObjects)}");
|
|
private static ProfilerMarker s_HandleDestroyObjects = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleDestroyObjects)}");
|
|
private static ProfilerMarker s_HandleTimeSync = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleTimeSync)}");
|
|
private static ProfilerMarker s_HandleNetworkVariableDelta = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleNetworkVariableDelta)}");
|
|
private static ProfilerMarker s_HandleNetworkVariableUpdate = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleNetworkVariableUpdate)}");
|
|
private static ProfilerMarker s_HandleUnnamedMessage = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleUnnamedMessage)}");
|
|
private static ProfilerMarker s_HandleNamedMessage = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleNamedMessage)}");
|
|
private static ProfilerMarker s_HandleNetworkLog = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleNetworkLog)}");
|
|
private static ProfilerMarker s_RpcReceiveQueueItemServerRpc = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(RpcReceiveQueueItem)}.{nameof(RpcQueueContainer.QueueItemType.ServerRpc)}");
|
|
private static ProfilerMarker s_RpcReceiveQueueItemClientRpc = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(RpcReceiveQueueItem)}.{nameof(RpcQueueContainer.QueueItemType.ClientRpc)}");
|
|
#endif
|
|
|
|
internal static void HandleConnectionRequest(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleConnectionRequest.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong configHash = reader.ReadUInt64Packed();
|
|
if (!NetworkManager.Singleton.NetworkConfig.CompareConfig(configHash))
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConfig)} mismatch. The configuration between the server and client does not match");
|
|
}
|
|
|
|
NetworkManager.Singleton.DisconnectClient(clientId);
|
|
return;
|
|
}
|
|
|
|
if (NetworkManager.Singleton.NetworkConfig.ConnectionApproval)
|
|
{
|
|
byte[] connectionBuffer = reader.ReadByteArray();
|
|
NetworkManager.Singleton.InvokeConnectionApproval(connectionBuffer, clientId, (createPlayerObject, playerPrefabHash, approved, position, rotation) => { NetworkManager.Singleton.HandleApproval(clientId, createPlayerObject, playerPrefabHash, approved, position, rotation); });
|
|
}
|
|
else
|
|
{
|
|
NetworkManager.Singleton.HandleApproval(clientId, NetworkManager.Singleton.NetworkConfig.CreatePlayerPrefab, null, true, null, null);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleConnectionRequest.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleConnectionApproved(ulong clientId, Stream stream, float receiveTime)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleConnectionApproved.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
NetworkManager.Singleton.LocalClientId = reader.ReadUInt64Packed();
|
|
|
|
uint sceneIndex = 0;
|
|
Guid sceneSwitchProgressGuid = new Guid();
|
|
|
|
if (NetworkManager.Singleton.NetworkConfig.EnableSceneManagement)
|
|
{
|
|
sceneIndex = reader.ReadUInt32Packed();
|
|
sceneSwitchProgressGuid = new Guid(reader.ReadByteArray());
|
|
}
|
|
|
|
bool sceneSwitch = NetworkManager.Singleton.NetworkConfig.EnableSceneManagement && NetworkSceneManager.HasSceneMismatch(sceneIndex);
|
|
|
|
float netTime = reader.ReadSinglePacked();
|
|
NetworkManager.Singleton.UpdateNetworkTime(clientId, netTime, receiveTime, true);
|
|
|
|
NetworkManager.Singleton.ConnectedClients.Add(NetworkManager.Singleton.LocalClientId, new NetworkClient { ClientId = NetworkManager.Singleton.LocalClientId });
|
|
|
|
|
|
void DelayedSpawnAction(Stream continuationStream)
|
|
{
|
|
using (var continuationReader = PooledNetworkReader.Get(continuationStream))
|
|
{
|
|
if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
|
|
{
|
|
NetworkSpawnManager.DestroySceneObjects();
|
|
}
|
|
else
|
|
{
|
|
NetworkSpawnManager.ClientCollectSoftSyncSceneObjectSweep(null);
|
|
}
|
|
|
|
uint objectCount = continuationReader.ReadUInt32Packed();
|
|
for (int i = 0; i < objectCount; i++)
|
|
{
|
|
bool isPlayerObject = continuationReader.ReadBool();
|
|
ulong networkId = continuationReader.ReadUInt64Packed();
|
|
ulong ownerId = continuationReader.ReadUInt64Packed();
|
|
bool hasParent = continuationReader.ReadBool();
|
|
ulong? parentNetworkId = null;
|
|
|
|
if (hasParent)
|
|
{
|
|
parentNetworkId = continuationReader.ReadUInt64Packed();
|
|
}
|
|
|
|
ulong prefabHash;
|
|
ulong instanceId;
|
|
bool softSync;
|
|
|
|
if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
|
|
{
|
|
softSync = false;
|
|
instanceId = 0;
|
|
prefabHash = continuationReader.ReadUInt64Packed();
|
|
}
|
|
else
|
|
{
|
|
softSync = continuationReader.ReadBool();
|
|
|
|
if (softSync)
|
|
{
|
|
instanceId = continuationReader.ReadUInt64Packed();
|
|
prefabHash = 0;
|
|
}
|
|
else
|
|
{
|
|
prefabHash = continuationReader.ReadUInt64Packed();
|
|
instanceId = 0;
|
|
}
|
|
}
|
|
|
|
Vector3? pos = null;
|
|
Quaternion? rot = null;
|
|
if (continuationReader.ReadBool())
|
|
{
|
|
pos = new Vector3(continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked());
|
|
rot = Quaternion.Euler(continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked(), continuationReader.ReadSinglePacked());
|
|
}
|
|
|
|
var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(softSync, instanceId, prefabHash, parentNetworkId, pos, rot);
|
|
NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerId, continuationStream, false, 0, true, false);
|
|
|
|
Queue<BufferManager.BufferedMessage> bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);
|
|
|
|
// Apply buffered messages
|
|
if (bufferQueue != null)
|
|
{
|
|
while (bufferQueue.Count > 0)
|
|
{
|
|
BufferManager.BufferedMessage message = bufferQueue.Dequeue();
|
|
NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment<byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
|
|
BufferManager.RecycleConsumedBufferedMessage(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
NetworkSpawnManager.CleanDiffedSceneObjects();
|
|
NetworkManager.Singleton.IsConnectedClient = true;
|
|
NetworkManager.Singleton.InvokeOnClientConnectedCallback(NetworkManager.Singleton.LocalClientId);
|
|
}
|
|
}
|
|
|
|
if (sceneSwitch)
|
|
{
|
|
UnityAction<Scene, Scene> onSceneLoaded = null;
|
|
|
|
var continuationBuffer = new NetworkBuffer();
|
|
continuationBuffer.CopyUnreadFrom(stream);
|
|
continuationBuffer.Position = 0;
|
|
|
|
void OnSceneLoadComplete()
|
|
{
|
|
SceneManager.activeSceneChanged -= onSceneLoaded;
|
|
NetworkSceneManager.IsSpawnedObjectsPendingInDontDestroyOnLoad = false;
|
|
DelayedSpawnAction(continuationBuffer);
|
|
}
|
|
|
|
onSceneLoaded = (oldScene, newScene) => { OnSceneLoadComplete(); };
|
|
SceneManager.activeSceneChanged += onSceneLoaded;
|
|
NetworkSceneManager.OnFirstSceneSwitchSync(sceneIndex, sceneSwitchProgressGuid);
|
|
}
|
|
else
|
|
{
|
|
DelayedSpawnAction(stream);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleConnectionApproved.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleAddObject(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleAddObject.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
bool isPlayerObject = reader.ReadBool();
|
|
ulong networkId = reader.ReadUInt64Packed();
|
|
ulong ownerId = reader.ReadUInt64Packed();
|
|
bool hasParent = reader.ReadBool();
|
|
ulong? parentNetworkId = null;
|
|
|
|
if (hasParent)
|
|
{
|
|
parentNetworkId = reader.ReadUInt64Packed();
|
|
}
|
|
|
|
ulong prefabHash;
|
|
ulong instanceId;
|
|
bool softSync;
|
|
|
|
if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync)
|
|
{
|
|
softSync = false;
|
|
instanceId = 0;
|
|
prefabHash = reader.ReadUInt64Packed();
|
|
}
|
|
else
|
|
{
|
|
softSync = reader.ReadBool();
|
|
|
|
if (softSync)
|
|
{
|
|
instanceId = reader.ReadUInt64Packed();
|
|
prefabHash = 0;
|
|
}
|
|
else
|
|
{
|
|
prefabHash = reader.ReadUInt64Packed();
|
|
instanceId = 0;
|
|
}
|
|
}
|
|
|
|
Vector3? pos = null;
|
|
Quaternion? rot = null;
|
|
if (reader.ReadBool())
|
|
{
|
|
pos = new Vector3(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
|
|
rot = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked());
|
|
}
|
|
|
|
bool hasPayload = reader.ReadBool();
|
|
int payLoadLength = hasPayload ? reader.ReadInt32Packed() : 0;
|
|
|
|
var networkObject = NetworkSpawnManager.CreateLocalNetworkObject(softSync, instanceId, prefabHash, parentNetworkId, pos, rot);
|
|
NetworkSpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerId, stream, hasPayload, payLoadLength, true, false);
|
|
|
|
Queue<BufferManager.BufferedMessage> bufferQueue = BufferManager.ConsumeBuffersForNetworkId(networkId);
|
|
|
|
// Apply buffered messages
|
|
if (bufferQueue != null)
|
|
{
|
|
while (bufferQueue.Count > 0)
|
|
{
|
|
BufferManager.BufferedMessage message = bufferQueue.Dequeue();
|
|
NetworkManager.Singleton.HandleIncomingData(message.SenderClientId, message.NetworkChannel, new ArraySegment<byte>(message.NetworkBuffer.GetBuffer(), (int)message.NetworkBuffer.Position, (int)message.NetworkBuffer.Length), message.ReceiveTime, false);
|
|
BufferManager.RecycleConsumedBufferedMessage(message);
|
|
}
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleAddObject.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleDestroyObject(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleDestroyObject.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong networkId = reader.ReadUInt64Packed();
|
|
NetworkSpawnManager.OnDestroyObject(networkId, true);
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleDestroyObject.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleSwitchScene(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleSwitchScene.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
uint sceneIndex = reader.ReadUInt32Packed();
|
|
Guid switchSceneGuid = new Guid(reader.ReadByteArray());
|
|
|
|
var objectBuffer = new NetworkBuffer();
|
|
objectBuffer.CopyUnreadFrom(stream);
|
|
objectBuffer.Position = 0;
|
|
|
|
NetworkSceneManager.OnSceneSwitch(sceneIndex, switchSceneGuid, objectBuffer);
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleSwitchScene.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleClientSwitchSceneCompleted(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleClientSwitchSceneCompleted.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
NetworkSceneManager.OnClientSwitchSceneCompleted(clientId, new Guid(reader.ReadByteArray()));
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleClientSwitchSceneCompleted.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleChangeOwner(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleChangeOwner.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong networkId = reader.ReadUInt64Packed();
|
|
ulong ownerClientId = reader.ReadUInt64Packed();
|
|
|
|
if (NetworkSpawnManager.SpawnedObjects[networkId].OwnerClientId == NetworkManager.Singleton.LocalClientId)
|
|
{
|
|
//We are current owner.
|
|
NetworkSpawnManager.SpawnedObjects[networkId].InvokeBehaviourOnLostOwnership();
|
|
}
|
|
|
|
if (ownerClientId == NetworkManager.Singleton.LocalClientId)
|
|
{
|
|
//We are new owner.
|
|
NetworkSpawnManager.SpawnedObjects[networkId].InvokeBehaviourOnGainedOwnership();
|
|
}
|
|
|
|
NetworkSpawnManager.SpawnedObjects[networkId].OwnerClientId = ownerClientId;
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleChangeOwner.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleAddObjects(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleAddObjects.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ushort objectCount = reader.ReadUInt16Packed();
|
|
|
|
for (int i = 0; i < objectCount; i++)
|
|
{
|
|
HandleAddObject(clientId, stream);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleAddObjects.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleDestroyObjects(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleDestroyObjects.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ushort objectCount = reader.ReadUInt16Packed();
|
|
|
|
for (int i = 0; i < objectCount; i++)
|
|
{
|
|
HandleDestroyObject(clientId, stream);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleDestroyObjects.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleTimeSync(ulong clientId, Stream stream, float receiveTime)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleTimeSync.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
float netTime = reader.ReadSinglePacked();
|
|
NetworkManager.Singleton.UpdateNetworkTime(clientId, netTime, receiveTime);
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleTimeSync.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleNetworkVariableDelta(ulong clientId, Stream stream, Action<ulong, PreBufferPreset> bufferCallback, PreBufferPreset bufferPreset)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkVariableDelta.Begin();
|
|
#endif
|
|
if (!NetworkManager.Singleton.NetworkConfig.EnableNetworkVariable)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_DELTA)} received but {nameof(NetworkConfig.EnableNetworkVariable)} is false");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong networkObjectId = reader.ReadUInt64Packed();
|
|
ushort networkBehaviourIndex = reader.ReadUInt16Packed();
|
|
|
|
if (NetworkSpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
|
|
{
|
|
NetworkBehaviour instance = NetworkSpawnManager.SpawnedObjects[networkObjectId].GetNetworkBehaviourAtOrderIndex(networkBehaviourIndex);
|
|
|
|
if (instance == null)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_DELTA)} message received for a non-existent behaviour. {nameof(networkObjectId)}: {networkObjectId}, {nameof(networkBehaviourIndex)}: {networkBehaviourIndex}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NetworkBehaviour.HandleNetworkVariableDeltas(instance.NetworkVariableFields, stream, clientId, instance);
|
|
}
|
|
}
|
|
else if (NetworkManager.Singleton.IsServer || !NetworkManager.Singleton.NetworkConfig.EnableMessageBuffering)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_DELTA)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta was lost.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_DELTA)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta will be buffered and might be recovered.");
|
|
}
|
|
|
|
bufferCallback(networkObjectId, bufferPreset);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkVariableDelta.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleNetworkVariableUpdate(ulong clientId, Stream stream, Action<ulong, PreBufferPreset> bufferCallback, PreBufferPreset bufferPreset)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkVariableUpdate.Begin();
|
|
#endif
|
|
if (!NetworkManager.Singleton.NetworkConfig.EnableNetworkVariable)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} update received but {nameof(NetworkConfig.EnableNetworkVariable)} is false");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong networkObjectId = reader.ReadUInt64Packed();
|
|
ushort networkBehaviourIndex = reader.ReadUInt16Packed();
|
|
|
|
if (NetworkSpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
|
|
{
|
|
var networkBehaviour = NetworkSpawnManager.SpawnedObjects[networkObjectId].GetNetworkBehaviourAtOrderIndex(networkBehaviourIndex);
|
|
|
|
if (networkBehaviour == null)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent behaviour. {nameof(networkObjectId)}: {networkObjectId}, {nameof(networkBehaviourIndex)}: {networkBehaviourIndex}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NetworkBehaviour.HandleNetworkVariableUpdate(networkBehaviour.NetworkVariableFields, stream, clientId, networkBehaviour);
|
|
}
|
|
}
|
|
else if (NetworkManager.Singleton.IsServer || !NetworkManager.Singleton.NetworkConfig.EnableMessageBuffering)
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta was lost.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
|
{
|
|
NetworkLog.LogWarning($"{nameof(NetworkConstants.NETWORK_VARIABLE_UPDATE)} message received for a non-existent object with {nameof(networkObjectId)}: {networkObjectId}. This delta will be buffered and might be recovered.");
|
|
}
|
|
|
|
bufferCallback(networkObjectId, bufferPreset);
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkVariableUpdate.End();
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts the stream to a PerformanceQueueItem and adds it to the receive queue
|
|
/// </summary>
|
|
/// <param name="clientId"></param>
|
|
/// <param name="stream"></param>
|
|
/// <param name="receiveTime"></param>
|
|
internal static void RpcReceiveQueueItem(ulong clientId, Stream stream, float receiveTime, RpcQueueContainer.QueueItemType queueItemType)
|
|
{
|
|
if (NetworkManager.Singleton.IsServer && clientId == NetworkManager.Singleton.ServerClientId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ProfilerStatManager.RpcsRcvd.Record();
|
|
PerformanceDataManager.Increment(ProfilerConstants.RpcReceived);
|
|
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
switch (queueItemType)
|
|
{
|
|
case RpcQueueContainer.QueueItemType.ServerRpc:
|
|
s_RpcReceiveQueueItemServerRpc.Begin();
|
|
break;
|
|
case RpcQueueContainer.QueueItemType.ClientRpc:
|
|
s_RpcReceiveQueueItemClientRpc.Begin();
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
var rpcQueueContainer = NetworkManager.Singleton.RpcQueueContainer;
|
|
rpcQueueContainer.AddQueueItemToInboundFrame(queueItemType, receiveTime, clientId, (NetworkBuffer)stream);
|
|
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
switch (queueItemType)
|
|
{
|
|
case RpcQueueContainer.QueueItemType.ServerRpc:
|
|
s_RpcReceiveQueueItemServerRpc.End();
|
|
break;
|
|
case RpcQueueContainer.QueueItemType.ClientRpc:
|
|
s_RpcReceiveQueueItemClientRpc.End();
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleUnnamedMessage(ulong clientId, Stream stream)
|
|
{
|
|
PerformanceDataManager.Increment(ProfilerConstants.UnnamedMessageReceived);
|
|
ProfilerStatManager.UnnamedMessage.Record();
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleUnnamedMessage.Begin();
|
|
#endif
|
|
CustomMessagingManager.InvokeUnnamedMessage(clientId, stream);
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleUnnamedMessage.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleNamedMessage(ulong clientId, Stream stream)
|
|
{
|
|
PerformanceDataManager.Increment(ProfilerConstants.NamedMessageReceived);
|
|
ProfilerStatManager.NamedMessage.Record();
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNamedMessage.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
ulong hash = reader.ReadUInt64Packed();
|
|
|
|
CustomMessagingManager.InvokeNamedMessage(hash, clientId, stream);
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNamedMessage.End();
|
|
#endif
|
|
}
|
|
|
|
internal static void HandleNetworkLog(ulong clientId, Stream stream)
|
|
{
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkLog.Begin();
|
|
#endif
|
|
using (var reader = PooledNetworkReader.Get(stream))
|
|
{
|
|
NetworkLog.LogType logType = (NetworkLog.LogType)reader.ReadByte();
|
|
string message = reader.ReadStringPacked();
|
|
|
|
switch (logType)
|
|
{
|
|
case NetworkLog.LogType.Info:
|
|
NetworkLog.LogInfoServerLocal(message, clientId);
|
|
break;
|
|
case NetworkLog.LogType.Warning:
|
|
NetworkLog.LogWarningServerLocal(message, clientId);
|
|
break;
|
|
case NetworkLog.LogType.Error:
|
|
NetworkLog.LogErrorServerLocal(message, clientId);
|
|
break;
|
|
}
|
|
}
|
|
#if DEVELOPMENT_BUILD || UNITY_EDITOR
|
|
s_HandleNetworkLog.End();
|
|
#endif
|
|
}
|
|
}
|
|
} |