quantum-space-buddies/QuantumUNET/QSBNetworkServer.cs

1619 lines
42 KiB
C#
Raw Normal View History

2020-12-04 22:15:41 +00:00
using OWML.Logging;
2020-12-07 21:19:16 +00:00
using QuantumUNET.Components;
using QuantumUNET.Messages;
2020-12-15 16:37:52 +00:00
using QuantumUNET.Transport;
2020-12-02 18:40:38 +00:00
using System;
2020-12-02 12:42:26 +00:00
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
using UnityEngine.Networking;
2020-12-02 18:40:38 +00:00
using UnityEngine.Networking.Types;
2020-12-02 12:42:26 +00:00
2020-12-04 22:14:53 +00:00
namespace QuantumUNET
2020-12-02 12:42:26 +00:00
{
public class QSBNetworkServer
{
private QSBNetworkServer()
{
NetworkTransport.Init();
2020-12-15 09:56:03 +00:00
m_RemoveList = new HashSet<QSBNetworkInstanceId>();
2020-12-02 12:42:26 +00:00
m_ExternalConnections = new HashSet<int>();
2020-12-02 18:40:38 +00:00
m_NetworkScene = new QSBNetworkScene();
2020-12-02 12:42:26 +00:00
m_SimpleServerSimple = new ServerSimpleWrapper(this);
}
2020-12-14 21:58:00 +00:00
public static List<QSBNetworkConnection> localConnections => instance.m_LocalConnectionsFakeList;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static int listenPort => instance.m_SimpleServerSimple.listenPort;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static int serverHostId => instance.m_SimpleServerSimple.serverHostId;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static ReadOnlyCollection<QSBNetworkConnection> connections => instance.m_SimpleServerSimple.connections;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static Dictionary<short, QSBNetworkMessageDelegate> handlers => instance.m_SimpleServerSimple.handlers;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static HostTopology hostTopology => instance.m_SimpleServerSimple.hostTopology;
2020-12-02 12:42:26 +00:00
2020-12-15 09:56:03 +00:00
public static Dictionary<QSBNetworkInstanceId, QSBNetworkIdentity> objects => instance.m_NetworkScene.localObjects;
2020-12-02 12:42:26 +00:00
2020-12-07 21:04:52 +00:00
public static bool dontListen { get; set; }
2020-12-02 12:42:26 +00:00
public static bool useWebSockets
{
get
{
return instance.m_SimpleServerSimple.useWebSockets;
}
set
{
instance.m_SimpleServerSimple.useWebSockets = value;
}
}
internal static QSBNetworkServer instance
{
get
{
if (s_Instance == null)
{
2020-12-02 18:40:38 +00:00
var obj = s_Sync;
2020-12-02 12:42:26 +00:00
lock (obj)
{
if (s_Instance == null)
{
s_Instance = new QSBNetworkServer();
}
}
}
return s_Instance;
}
}
2020-12-07 21:04:52 +00:00
public static bool active { get; private set; }
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static bool localClientActive => instance.m_LocalClientActive;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static int numChannels => instance.m_SimpleServerSimple.hostTopology.DefaultConfig.ChannelCount;
2020-12-02 12:42:26 +00:00
public static float maxDelay
{
get
{
return instance.m_MaxDelay;
}
set
{
instance.InternalSetMaxDelay(value);
}
}
2020-12-14 21:58:00 +00:00
public static Type networkConnectionClass => instance.m_SimpleServerSimple.networkConnectionClass;
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection => instance.m_SimpleServerSimple.SetNetworkConnectionClass<T>();
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static bool Configure(ConnectionConfig config, int maxConnections) => instance.m_SimpleServerSimple.Configure(config, maxConnections);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static bool Configure(HostTopology topology) => instance.m_SimpleServerSimple.Configure(topology);
2020-12-02 12:42:26 +00:00
public static void Reset()
{
NetworkTransport.Shutdown();
NetworkTransport.Init();
s_Instance = null;
2020-12-07 21:04:52 +00:00
active = false;
2020-12-02 12:42:26 +00:00
}
public static void Shutdown()
{
if (s_Instance != null)
{
s_Instance.InternalDisconnectAll();
2020-12-07 21:04:52 +00:00
if (!dontListen)
2020-12-02 12:42:26 +00:00
{
s_Instance.m_SimpleServerSimple.Stop();
}
s_Instance = null;
}
2020-12-07 21:04:52 +00:00
dontListen = false;
active = false;
2020-12-02 12:42:26 +00:00
}
internal void RegisterMessageHandlers()
{
2020-12-13 22:25:23 +00:00
ModConsole.OwmlConsole.WriteLine("Register Message Handlers (NetworkServer)");
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.Ready, new QSBNetworkMessageDelegate(OnClientReadyMessage));
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.Command, new QSBNetworkMessageDelegate(OnCommandMessage));
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.LocalPlayerTransform, new QSBNetworkMessageDelegate(QSBNetworkTransform.HandleTransform));
2020-12-02 18:40:38 +00:00
//m_SimpleServerSimple.RegisterHandlerSafe((short)16, new QSBNetworkMessageDelegate(NetworkTransformChild.HandleChildTransform));
2020-12-13 22:25:23 +00:00
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.RemovePlayer, new QSBNetworkMessageDelegate(OnRemovePlayerMessage));
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.Animation, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationServerMessage));
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.AnimationParameters, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersServerMessage));
m_SimpleServerSimple.RegisterHandlerSafe(QSBMsgType.AnimationTrigger, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerServerMessage));
2020-12-02 18:40:38 +00:00
maxPacketSize = hostTopology.DefaultConfig.PacketSize;
2020-12-02 12:42:26 +00:00
}
2020-12-14 21:58:00 +00:00
public static void ListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId) => instance.InternalListenRelay(relayIp, relayPort, netGuid, sourceId, nodeId);
2020-12-02 12:42:26 +00:00
private void InternalListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId)
{
m_SimpleServerSimple.ListenRelay(relayIp, relayPort, netGuid, sourceId, nodeId);
2020-12-07 21:04:52 +00:00
active = true;
2020-12-02 12:42:26 +00:00
RegisterMessageHandlers();
}
2020-12-14 21:58:00 +00:00
public static bool Listen(int serverPort) => instance.InternalListen(null, serverPort);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static bool Listen(string ipAddress, int serverPort) => instance.InternalListen(ipAddress, serverPort);
2020-12-02 12:42:26 +00:00
internal bool InternalListen(string ipAddress, int serverPort)
{
2020-12-07 21:04:52 +00:00
if (dontListen)
2020-12-02 12:42:26 +00:00
{
m_SimpleServerSimple.Initialize();
}
else if (!m_SimpleServerSimple.Listen(ipAddress, serverPort))
{
return false;
}
2020-12-02 18:40:38 +00:00
maxPacketSize = hostTopology.DefaultConfig.PacketSize;
2020-12-07 21:04:52 +00:00
active = true;
2020-12-02 12:42:26 +00:00
RegisterMessageHandlers();
return true;
}
private void InternalSetMaxDelay(float seconds)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
networkConnection.SetMaxDelay(seconds);
}
}
m_MaxDelay = seconds;
}
internal int AddLocalClient(QSBLocalClient localClient)
{
int result;
if (m_LocalConnectionsFakeList.Count != 0)
{
Debug.LogError("Local Connection already exists");
result = -1;
}
else
{
2020-12-13 22:25:23 +00:00
m_LocalConnection = new QSBULocalConnectionToClient(localClient)
{
connectionId = 0
};
2020-12-02 12:42:26 +00:00
m_SimpleServerSimple.SetConnectionAtIndex(m_LocalConnection);
m_LocalConnectionsFakeList.Add(m_LocalConnection);
m_LocalConnection.InvokeHandlerNoData(32);
result = 0;
}
return result;
}
internal void RemoveLocalClient(QSBNetworkConnection localClientConnection)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < m_LocalConnectionsFakeList.Count; i++)
2020-12-02 12:42:26 +00:00
{
if (m_LocalConnectionsFakeList[i].connectionId == localClientConnection.connectionId)
{
m_LocalConnectionsFakeList.RemoveAt(i);
break;
}
}
if (m_LocalConnection != null)
{
m_LocalConnection.Disconnect();
m_LocalConnection.Dispose();
m_LocalConnection = null;
}
m_LocalClientActive = false;
m_SimpleServerSimple.RemoveConnectionAtIndex(0);
}
2020-12-15 09:56:03 +00:00
internal void SetLocalObjectOnServer(QSBNetworkInstanceId netId, GameObject obj)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log(string.Concat(new object[]
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
"SetLocalObjectOnServer ",
netId,
" ",
obj
}));
2020-12-02 12:42:26 +00:00
m_NetworkScene.SetLocalObject(netId, obj, false, true);
}
internal void ActivateLocalClientScene()
{
if (!m_LocalClientActive)
{
m_LocalClientActive = true;
2020-12-02 18:40:38 +00:00
foreach (var networkIdentity in objects.Values)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (!networkIdentity.IsClient)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log(string.Concat(new object[]
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
"ActivateClientScene ",
networkIdentity.NetId,
" ",
networkIdentity.gameObject
}));
QSBClientScene.SetLocalObject(networkIdentity.NetId, networkIdentity.gameObject);
2020-12-02 12:42:26 +00:00
networkIdentity.OnStartClient();
}
}
}
}
2020-12-04 09:23:27 +00:00
public static bool SendToAll(short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendToAll msgType:" + msgType);
var flag = true;
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
flag &= networkConnection.Send(msgType, msg);
}
}
return flag;
}
2020-12-04 09:23:27 +00:00
private static bool SendToObservers(GameObject contextObj, short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendToObservers id:" + msgType);
var flag = true;
var component = contextObj.GetComponent<QSBNetworkIdentity>();
2020-12-02 12:42:26 +00:00
bool result;
2020-12-02 18:40:38 +00:00
if (component == null || component.Observers == null)
2020-12-02 12:42:26 +00:00
{
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
var count = component.Observers.Count;
for (var i = 0; i < count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = component.Observers[i];
2020-12-02 12:42:26 +00:00
flag &= networkConnection.Send(msgType, msg);
}
result = flag;
}
return result;
}
2020-12-04 09:23:27 +00:00
public static bool SendToReady(GameObject contextObj, short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendToReady id:" + msgType);
2020-12-02 12:42:26 +00:00
bool result;
if (contextObj == null)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null && networkConnection.isReady)
{
networkConnection.Send(msgType, msg);
}
}
result = true;
}
else
{
2020-12-02 18:40:38 +00:00
var flag = true;
var component = contextObj.GetComponent<QSBNetworkIdentity>();
if (component == null || component.Observers == null)
2020-12-02 12:42:26 +00:00
{
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
var count = component.Observers.Count;
for (var j = 0; j < count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection2 = component.Observers[j];
2020-12-02 12:42:26 +00:00
if (networkConnection2.isReady)
{
flag &= networkConnection2.Send(msgType, msg);
}
}
result = flag;
}
}
return result;
}
2020-12-04 09:23:27 +00:00
public static void SendWriterToReady(GameObject contextObj, QSBNetworkWriter writer, int channelId)
2020-12-02 12:42:26 +00:00
{
2020-12-04 21:04:18 +00:00
var arraySegment = writer.AsArraySegment();
2020-12-02 18:40:38 +00:00
if (arraySegment.Count > 32767)
2020-12-02 12:42:26 +00:00
{
throw new UnityException("NetworkWriter used buffer is too big!");
}
2020-12-02 18:40:38 +00:00
SendBytesToReady(contextObj, arraySegment.Array, arraySegment.Count, channelId);
2020-12-02 12:42:26 +00:00
}
public static void SendBytesToReady(GameObject contextObj, byte[] buffer, int numBytes, int channelId)
{
if (contextObj == null)
{
2020-12-02 18:40:38 +00:00
var flag = true;
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null && networkConnection.isReady)
{
if (!networkConnection.SendBytes(buffer, numBytes, channelId))
{
flag = false;
}
}
}
if (!flag)
{
2020-12-04 22:14:53 +00:00
ModConsole.OwmlConsole.WriteLine("SendBytesToReady failed");
2020-12-02 12:42:26 +00:00
}
}
else
{
2020-12-02 18:40:38 +00:00
var component = contextObj.GetComponent<QSBNetworkIdentity>();
2020-12-02 12:42:26 +00:00
try
{
2020-12-02 18:40:38 +00:00
var flag2 = true;
var count = component.Observers.Count;
for (var j = 0; j < count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection2 = component.Observers[j];
2020-12-02 12:42:26 +00:00
if (networkConnection2.isReady)
{
if (!networkConnection2.SendBytes(buffer, numBytes, channelId))
{
flag2 = false;
}
}
}
if (!flag2)
{
2020-12-04 22:14:53 +00:00
ModConsole.OwmlConsole.WriteLine("SendBytesToReady failed for " + contextObj);
2020-12-02 12:42:26 +00:00
}
}
catch (NullReferenceException)
{
2020-12-04 22:14:53 +00:00
ModConsole.OwmlConsole.WriteLine("SendBytesToReady object " + contextObj + " has not been spawned");
2020-12-02 12:42:26 +00:00
}
}
}
public static void SendBytesToPlayer(GameObject player, byte[] buffer, int numBytes, int channelId)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
2020-12-02 18:40:38 +00:00
for (var j = 0; j < networkConnection.PlayerControllers.Count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
if (networkConnection.PlayerControllers[j].IsValid && networkConnection.PlayerControllers[j].Gameobject == player)
2020-12-02 12:42:26 +00:00
{
networkConnection.SendBytes(buffer, numBytes, channelId);
break;
}
}
}
}
}
2020-12-04 09:23:27 +00:00
public static bool SendUnreliableToAll(short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendUnreliableToAll msgType:" + msgType);
var flag = true;
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
flag &= networkConnection.SendUnreliable(msgType, msg);
}
}
return flag;
}
2020-12-04 09:23:27 +00:00
public static bool SendUnreliableToReady(GameObject contextObj, short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendUnreliableToReady id:" + msgType);
2020-12-02 12:42:26 +00:00
bool result;
if (contextObj == null)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null && networkConnection.isReady)
{
networkConnection.SendUnreliable(msgType, msg);
}
}
result = true;
}
else
{
2020-12-02 18:40:38 +00:00
var flag = true;
var component = contextObj.GetComponent<QSBNetworkIdentity>();
var count = component.Observers.Count;
for (var j = 0; j < count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection2 = component.Observers[j];
2020-12-02 12:42:26 +00:00
if (networkConnection2.isReady)
{
flag &= networkConnection2.SendUnreliable(msgType, msg);
}
}
result = flag;
}
return result;
}
2020-12-04 09:23:27 +00:00
public static bool SendByChannelToAll(short msgType, QSBMessageBase msg, int channelId)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendByChannelToAll id:" + msgType);
var flag = true;
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
flag &= networkConnection.SendByChannel(msgType, msg, channelId);
}
}
return flag;
}
2020-12-04 09:23:27 +00:00
public static bool SendByChannelToReady(GameObject contextObj, short msgType, QSBMessageBase msg, int channelId)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server.SendByChannelToReady msgType:" + msgType);
2020-12-02 12:42:26 +00:00
bool result;
if (contextObj == null)
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null && networkConnection.isReady)
{
networkConnection.SendByChannel(msgType, msg, channelId);
}
}
result = true;
}
else
{
2020-12-02 18:40:38 +00:00
var flag = true;
var component = contextObj.GetComponent<QSBNetworkIdentity>();
var count = component.Observers.Count;
for (var j = 0; j < count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection2 = component.Observers[j];
2020-12-02 12:42:26 +00:00
if (networkConnection2.isReady)
{
flag &= networkConnection2.SendByChannel(msgType, msg, channelId);
}
}
result = flag;
}
return result;
}
2020-12-14 21:58:00 +00:00
public static void DisconnectAll() => instance.InternalDisconnectAll();
2020-12-02 12:42:26 +00:00
internal void InternalDisconnectAll()
{
m_SimpleServerSimple.DisconnectAllConnections();
if (m_LocalConnection != null)
{
m_LocalConnection.Disconnect();
m_LocalConnection.Dispose();
m_LocalConnection = null;
}
m_LocalClientActive = false;
}
internal static void Update()
{
2020-12-02 18:40:38 +00:00
if (s_Instance != null)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
s_Instance.InternalUpdate();
2020-12-02 12:42:26 +00:00
}
}
private void UpdateServerObjects()
{
2020-12-02 18:40:38 +00:00
foreach (var networkIdentity in objects.Values)
2020-12-02 12:42:26 +00:00
{
try
{
networkIdentity.UNetUpdate();
}
catch (NullReferenceException)
{
}
catch (MissingReferenceException)
{
}
}
if (m_RemoveListCount++ % 100 == 0)
{
CheckForNullObjects();
}
}
private void CheckForNullObjects()
{
2020-12-02 18:40:38 +00:00
foreach (var networkInstanceId in objects.Keys)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkIdentity = objects[networkInstanceId];
2020-12-02 12:42:26 +00:00
if (networkIdentity == null || networkIdentity.gameObject == null)
{
m_RemoveList.Add(networkInstanceId);
}
}
if (m_RemoveList.Count > 0)
{
2020-12-02 18:40:38 +00:00
foreach (var key in m_RemoveList)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
objects.Remove(key);
2020-12-02 12:42:26 +00:00
}
m_RemoveList.Clear();
}
}
internal void InternalUpdate()
{
m_SimpleServerSimple.Update();
2020-12-07 21:04:52 +00:00
if (dontListen)
2020-12-02 12:42:26 +00:00
{
m_SimpleServerSimple.UpdateConnections();
}
UpdateServerObjects();
}
2020-12-02 18:40:38 +00:00
private void OnConnected(QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("Server accepted client:" + conn.connectionId);
2020-12-02 12:42:26 +00:00
conn.SetMaxDelay(m_MaxDelay);
conn.InvokeHandlerNoData(32);
2020-12-02 18:40:38 +00:00
SendCrc(conn);
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
private void OnDisconnected(QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
conn.InvokeHandlerNoData(33);
2020-12-02 18:40:38 +00:00
for (var i = 0; i < conn.PlayerControllers.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
if (conn.PlayerControllers[i].Gameobject != null)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Player not destroyed when connection disconnected.");
}
}
}
if (LogFilter.logDebug)
{
Debug.Log("Server lost client:" + conn.connectionId);
}
conn.RemoveObservers();
conn.Dispose();
}
2020-12-14 21:58:00 +00:00
private void OnData(QSBNetworkConnection conn, int receivedSize, int channelId) => conn.TransportReceive(m_SimpleServerSimple.messageBuffer, receivedSize, channelId);
2020-12-02 12:42:26 +00:00
private void GenerateConnectError(int error)
{
if (LogFilter.logError)
{
Debug.LogError("UNet Server Connect Error: " + error);
}
GenerateError(null, error);
}
2020-12-02 18:40:38 +00:00
private void GenerateDataError(QSBNetworkConnection conn, int error)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logError)
{
Debug.LogError("UNet Server Data Error: " + (NetworkError)error);
}
GenerateError(conn, error);
}
2020-12-02 18:40:38 +00:00
private void GenerateDisconnectError(QSBNetworkConnection conn, int error)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
"UNet Server Disconnect Error: ",
(NetworkError)error,
" conn:[",
conn,
"]:",
conn.connectionId
}));
}
GenerateError(conn, error);
}
2020-12-02 18:40:38 +00:00
private void GenerateError(QSBNetworkConnection conn, int error)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (handlers.ContainsKey(34))
2020-12-02 12:42:26 +00:00
{
2020-12-14 21:58:00 +00:00
var errorMessage = new QSBErrorMessage
{
errorCode = error
};
2020-12-04 09:23:27 +00:00
var writer = new QSBNetworkWriter();
2020-12-02 12:42:26 +00:00
errorMessage.Serialize(writer);
2020-12-04 09:23:27 +00:00
var reader = new QSBNetworkReader(writer);
2020-12-02 12:42:26 +00:00
conn.InvokeHandler(34, reader, 0);
}
}
2020-12-14 21:58:00 +00:00
public static void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler) => instance.m_SimpleServerSimple.RegisterHandler(msgType, handler);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static void UnregisterHandler(short msgType) => instance.m_SimpleServerSimple.UnregisterHandler(msgType);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static void ClearHandlers() => instance.m_SimpleServerSimple.ClearHandlers();
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static void ClearSpawners() => QSBNetworkScene.ClearSpawners();
2020-12-02 12:42:26 +00:00
public static void GetStatsOut(out int numMsgs, out int numBufferedMsgs, out int numBytes, out int lastBufferedPerSecond)
{
numMsgs = 0;
numBufferedMsgs = 0;
numBytes = 0;
lastBufferedPerSecond = 0;
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
2020-12-14 21:58:00 +00:00
networkConnection.GetStatsOut(out var num, out var num2, out var num3, out var num4);
2020-12-02 12:42:26 +00:00
numMsgs += num;
numBufferedMsgs += num2;
numBytes += num3;
lastBufferedPerSecond += num4;
}
}
}
public static void GetStatsIn(out int numMsgs, out int numBytes)
{
numMsgs = 0;
numBytes = 0;
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
2020-12-14 21:58:00 +00:00
networkConnection.GetStatsIn(out var num, out var num2);
2020-12-02 12:42:26 +00:00
numMsgs += num;
numBytes += num2;
}
}
}
2020-12-04 09:23:27 +00:00
public static void SendToClientOfPlayer(GameObject player, short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
2020-12-02 18:40:38 +00:00
for (var j = 0; j < networkConnection.PlayerControllers.Count; j++)
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
if (networkConnection.PlayerControllers[j].IsValid && networkConnection.PlayerControllers[j].Gameobject == player)
2020-12-02 12:42:26 +00:00
{
networkConnection.Send(msgType, msg);
return;
}
}
}
}
if (LogFilter.logError)
{
Debug.LogError("Failed to send message to player object '" + player.name + ", not found in connection list");
return;
}
}
2020-12-04 09:23:27 +00:00
public static void SendToClient(int connectionId, short msgType, QSBMessageBase msg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (connectionId < connections.Count)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[connectionId];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
networkConnection.Send(msgType, msg);
return;
}
}
if (LogFilter.logError)
{
Debug.LogError("Failed to send message to connection ID '" + connectionId + ", not found in connection list");
}
}
2020-12-14 21:58:00 +00:00
public static bool AddPlayerForConnection(QSBNetworkConnection conn, GameObject player, short playerControllerId) => instance.InternalAddPlayerForConnection(conn, player, playerControllerId);
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
internal bool InternalAddPlayerForConnection(QSBNetworkConnection conn, GameObject playerGameObject, short playerControllerId)
2020-12-02 12:42:26 +00:00
{
bool result;
2020-12-14 21:58:00 +00:00
if (!GetNetworkIdentity(playerGameObject, out var networkIdentity))
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logError)
{
Debug.Log("AddPlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + playerGameObject);
}
result = false;
}
else
{
networkIdentity.Reset();
2020-12-02 18:40:38 +00:00
if (!CheckPlayerControllerIdForConnection(conn, playerControllerId))
2020-12-02 12:42:26 +00:00
{
result = false;
}
else
{
GameObject x = null;
2020-12-14 21:58:00 +00:00
if (conn.GetPlayerController(playerControllerId, out var playerController))
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
x = playerController.Gameobject;
2020-12-02 12:42:26 +00:00
}
if (x != null)
{
if (LogFilter.logError)
{
Debug.Log("AddPlayer: player object already exists for playerControllerId of " + playerControllerId);
}
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
var playerController2 = new QSBPlayerController(playerGameObject, playerControllerId);
2020-12-02 12:42:26 +00:00
conn.SetPlayerController(playerController2);
2020-12-03 11:56:32 +00:00
networkIdentity.SetConnectionToClient(conn, playerController2.PlayerControllerId);
2020-12-02 18:40:38 +00:00
SetClientReady(conn);
2020-12-02 12:42:26 +00:00
if (SetupLocalPlayerForConnection(conn, networkIdentity, playerController2))
{
result = true;
}
else
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"Adding new playerGameObject object netId: ",
2020-12-02 18:40:38 +00:00
playerGameObject.GetComponent<QSBNetworkIdentity>().NetId,
2020-12-02 12:42:26 +00:00
" asset ID ",
2020-12-02 18:40:38 +00:00
playerGameObject.GetComponent<QSBNetworkIdentity>().AssetId
2020-12-02 12:42:26 +00:00
}));
}
2020-12-02 18:40:38 +00:00
FinishPlayerForConnection(conn, networkIdentity, playerGameObject);
if (networkIdentity.LocalPlayerAuthority)
2020-12-02 12:42:26 +00:00
{
networkIdentity.SetClientOwner(conn);
}
result = true;
}
}
}
}
return result;
}
2020-12-02 18:40:38 +00:00
private static bool CheckPlayerControllerIdForConnection(QSBNetworkConnection conn, short playerControllerId)
2020-12-02 12:42:26 +00:00
{
bool result;
if (playerControllerId < 0)
{
if (LogFilter.logError)
{
Debug.LogError("AddPlayer: playerControllerId of " + playerControllerId + " is negative");
}
result = false;
}
else if (playerControllerId > 32)
{
if (LogFilter.logError)
{
Debug.Log(string.Concat(new object[]
{
"AddPlayer: playerControllerId of ",
playerControllerId,
" is too high. max is ",
32
}));
}
result = false;
}
else
{
if (playerControllerId > 16)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("AddPlayer: playerControllerId of " + playerControllerId + " is unusually high");
}
}
result = true;
}
return result;
}
2020-12-02 18:40:38 +00:00
private bool SetupLocalPlayerForConnection(QSBNetworkConnection conn, QSBNetworkIdentity uv, QSBPlayerController newPlayerController)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer SetupLocalPlayerForConnection netID:" + uv.NetId);
2020-12-02 12:42:26 +00:00
bool result;
2020-12-14 21:58:00 +00:00
if (conn is QSBULocalConnectionToClient ulocalConnectionToClient)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer AddPlayer handling ULocalConnectionToClient");
if (uv.NetId.IsEmpty())
2020-12-02 12:42:26 +00:00
{
uv.OnStartServer(true);
}
uv.RebuildObservers(true);
SendSpawnMessage(uv, null);
2020-12-08 09:03:10 +00:00
ulocalConnectionToClient.LocalClient.AddLocalPlayer(newPlayerController);
2020-12-02 12:42:26 +00:00
uv.SetClientOwner(conn);
uv.ForceAuthority(true);
2020-12-03 11:56:32 +00:00
uv.SetLocalPlayer(newPlayerController.PlayerControllerId);
2020-12-02 12:42:26 +00:00
result = true;
}
else
{
result = false;
}
return result;
}
2020-12-02 18:40:38 +00:00
private static void FinishPlayerForConnection(QSBNetworkConnection conn, QSBNetworkIdentity uv, GameObject playerGameObject)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (uv.NetId.IsEmpty())
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Spawn(playerGameObject);
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
conn.Send(4, new QSBOwnerMessage
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
NetId = uv.NetId,
PlayerControllerId = uv.PlayerControllerId
2020-12-02 12:42:26 +00:00
});
}
2020-12-02 18:40:38 +00:00
internal bool InternalReplacePlayerForConnection(QSBNetworkConnection conn, GameObject playerGameObject, short playerControllerId)
2020-12-02 12:42:26 +00:00
{
bool result;
2020-12-14 21:58:00 +00:00
if (!GetNetworkIdentity(playerGameObject, out var networkIdentity))
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logError)
{
Debug.LogError("ReplacePlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + playerGameObject);
}
result = false;
}
2020-12-02 18:40:38 +00:00
else if (!CheckPlayerControllerIdForConnection(conn, playerControllerId))
2020-12-02 12:42:26 +00:00
{
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer ReplacePlayer");
2020-12-14 21:58:00 +00:00
if (conn.GetPlayerController(playerControllerId, out var playerController))
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
playerController.UnetView.SetNotLocalPlayer();
playerController.UnetView.ClearClientOwner();
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
var playerController2 = new QSBPlayerController(playerGameObject, playerControllerId);
2020-12-02 12:42:26 +00:00
conn.SetPlayerController(playerController2);
2020-12-03 11:56:32 +00:00
networkIdentity.SetConnectionToClient(conn, playerController2.PlayerControllerId);
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer ReplacePlayer setup local");
2020-12-02 12:42:26 +00:00
if (SetupLocalPlayerForConnection(conn, networkIdentity, playerController2))
{
result = true;
}
else
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"Replacing playerGameObject object netId: ",
playerGameObject.GetComponent<NetworkIdentity>().netId,
" asset ID ",
playerGameObject.GetComponent<NetworkIdentity>().assetId
}));
}
2020-12-02 18:40:38 +00:00
FinishPlayerForConnection(conn, networkIdentity, playerGameObject);
if (networkIdentity.LocalPlayerAuthority)
2020-12-02 12:42:26 +00:00
{
networkIdentity.SetClientOwner(conn);
}
result = true;
}
}
return result;
}
2020-12-02 18:40:38 +00:00
private static bool GetNetworkIdentity(GameObject go, out QSBNetworkIdentity view)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
view = go.GetComponent<QSBNetworkIdentity>();
2020-12-02 12:42:26 +00:00
bool result;
if (view == null)
{
2020-12-02 18:40:38 +00:00
Debug.LogError("UNET failure. GameObject doesn't have NetworkIdentity.");
2020-12-02 12:42:26 +00:00
result = false;
}
else
{
result = true;
}
return result;
}
2020-12-14 21:58:00 +00:00
public static void SetClientReady(QSBNetworkConnection conn) => instance.SetClientReadyInternal(conn);
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
internal void SetClientReadyInternal(QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logDebug)
{
Debug.Log("SetClientReadyInternal for conn:" + conn.connectionId);
}
if (conn.isReady)
{
if (LogFilter.logDebug)
{
Debug.Log("SetClientReady conn " + conn.connectionId + " already ready");
}
}
else
{
2020-12-02 18:40:38 +00:00
if (conn.PlayerControllers.Count == 0)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logDebug)
{
Debug.LogWarning("Ready with no player object");
}
}
conn.isReady = true;
2020-12-14 21:58:00 +00:00
if (conn is QSBULocalConnectionToClient ulocalConnectionToClient)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer Ready handling ULocalConnectionToClient");
foreach (var networkIdentity in objects.Values)
2020-12-02 12:42:26 +00:00
{
if (networkIdentity != null && networkIdentity.gameObject != null)
{
2020-12-14 21:58:00 +00:00
var flag = networkIdentity.OnCheckObserver(conn);
2020-12-02 12:42:26 +00:00
if (flag)
{
networkIdentity.AddObserver(conn);
}
2020-12-02 18:40:38 +00:00
if (!networkIdentity.IsClient)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.Log("LocalClient.SetSpawnObject calling OnStartClient");
2020-12-02 12:42:26 +00:00
networkIdentity.OnStartClient();
}
}
}
}
else
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"Spawning ",
2020-12-02 18:40:38 +00:00
objects.Count,
2020-12-02 12:42:26 +00:00
" objects for conn ",
conn.connectionId
}));
}
2020-12-14 21:58:00 +00:00
var objectSpawnFinishedMessage = new QSBObjectSpawnFinishedMessage
{
State = 0U
};
2020-12-02 12:42:26 +00:00
conn.Send(12, objectSpawnFinishedMessage);
2020-12-02 18:40:38 +00:00
foreach (var networkIdentity2 in objects.Values)
2020-12-02 12:42:26 +00:00
{
if (networkIdentity2 == null)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Invalid object found in server local object list (null NetworkIdentity).");
}
}
else if (networkIdentity2.gameObject.activeSelf)
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"Sending spawn message for current server objects name='",
networkIdentity2.gameObject.name,
"' netId=",
2020-12-02 18:40:38 +00:00
networkIdentity2.NetId
2020-12-02 12:42:26 +00:00
}));
}
2020-12-14 21:58:00 +00:00
var flag2 = networkIdentity2.OnCheckObserver(conn);
2020-12-02 12:42:26 +00:00
if (flag2)
{
networkIdentity2.AddObserver(conn);
}
}
}
2020-12-03 11:56:32 +00:00
objectSpawnFinishedMessage.State = 1U;
2020-12-02 12:42:26 +00:00
conn.Send(12, objectSpawnFinishedMessage);
}
}
}
2020-12-02 18:40:38 +00:00
internal static void ShowForConnection(QSBNetworkIdentity uv, QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
if (conn.isReady)
{
instance.SendSpawnMessage(uv, conn);
}
}
internal static void HideForConnection(QSBNetworkIdentity uv, QSBNetworkConnection conn)
{
conn.Send(13, new QSBObjectDestroyMessage
{
2020-12-03 11:56:32 +00:00
NetId = uv.NetId
2020-12-02 12:42:26 +00:00
});
}
public static void SetAllClientsNotReady()
{
2020-12-02 18:40:38 +00:00
for (var i = 0; i < connections.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var networkConnection = connections[i];
2020-12-02 12:42:26 +00:00
if (networkConnection != null)
{
2020-12-02 18:40:38 +00:00
SetClientNotReady(networkConnection);
2020-12-02 12:42:26 +00:00
}
}
}
2020-12-14 21:58:00 +00:00
public static void SetClientNotReady(QSBNetworkConnection conn) => instance.InternalSetClientNotReady(conn);
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
internal void InternalSetClientNotReady(QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
if (conn.isReady)
{
if (LogFilter.logDebug)
{
Debug.Log("PlayerNotReady " + conn);
}
conn.isReady = false;
conn.RemoveObservers();
2020-12-04 09:23:27 +00:00
var msg = new QSBNotReadyMessage();
2020-12-02 12:42:26 +00:00
conn.Send(36, msg);
}
}
2020-12-02 18:40:38 +00:00
private static void OnClientReadyMessage(QSBNetworkMessage netMsg)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logDebug)
{
2020-12-03 11:56:32 +00:00
Debug.Log("Default handler for ready message from " + netMsg.Connection);
2020-12-02 12:42:26 +00:00
}
2020-12-03 11:56:32 +00:00
SetClientReady(netMsg.Connection);
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
private static void OnRemovePlayerMessage(QSBNetworkMessage netMsg)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
netMsg.ReadMessage<QSBRemovePlayerMessage>(s_RemovePlayerMessage);
2020-12-14 21:58:00 +00:00
netMsg.Connection.GetPlayerController(s_RemovePlayerMessage.PlayerControllerId, out var playerController);
2020-12-02 12:42:26 +00:00
if (playerController != null)
{
2020-12-03 11:56:32 +00:00
netMsg.Connection.RemovePlayerController(s_RemovePlayerMessage.PlayerControllerId);
Destroy(playerController.Gameobject);
2020-12-02 12:42:26 +00:00
}
else if (LogFilter.logError)
{
2020-12-03 11:56:32 +00:00
Debug.LogError("Received remove player message but could not find the player ID: " + s_RemovePlayerMessage.PlayerControllerId);
2020-12-02 12:42:26 +00:00
}
}
2020-12-02 18:40:38 +00:00
private static void OnCommandMessage(QSBNetworkMessage netMsg)
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var cmdHash = (int)netMsg.Reader.ReadPackedUInt32();
var networkInstanceId = netMsg.Reader.ReadNetworkId();
2020-12-02 18:40:38 +00:00
var gameObject = FindLocalObject(networkInstanceId);
2020-12-02 12:42:26 +00:00
if (gameObject == null)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Instance not found when handling Command message [netId=" + networkInstanceId + "]");
}
}
else
{
2020-12-02 18:40:38 +00:00
var component = gameObject.GetComponent<QSBNetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (component == null)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("NetworkIdentity deleted when handling Command message [netId=" + networkInstanceId + "]");
}
}
else
{
2020-12-02 18:40:38 +00:00
var flag = false;
2020-12-03 11:56:32 +00:00
for (var i = 0; i < netMsg.Connection.PlayerControllers.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var playerController = netMsg.Connection.PlayerControllers[i];
if (playerController.Gameobject != null && playerController.Gameobject.GetComponent<QSBNetworkIdentity>().NetId == component.NetId)
2020-12-02 12:42:26 +00:00
{
flag = true;
break;
}
}
if (!flag)
{
2020-12-03 11:56:32 +00:00
if (component.ClientAuthorityOwner != netMsg.Connection)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Command for object without authority [netId=" + networkInstanceId + "]");
}
return;
}
}
2020-12-02 18:40:38 +00:00
Debug.Log(string.Concat(new object[]
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
"OnCommandMessage for netId=",
networkInstanceId,
" conn=",
2020-12-03 11:56:32 +00:00
netMsg.Connection
2020-12-02 18:40:38 +00:00
}));
2020-12-03 11:56:32 +00:00
component.HandleCommand(cmdHash, netMsg.Reader);
2020-12-02 12:42:26 +00:00
}
}
}
internal void SpawnObject(GameObject obj)
{
2020-12-02 18:40:38 +00:00
if (!active)
2020-12-02 12:42:26 +00:00
{
2020-12-04 22:14:53 +00:00
ModConsole.OwmlConsole.WriteLine("Error - SpawnObject for " + obj + ", NetworkServer is not active. Cannot spawn objects without an active server.");
2020-12-02 12:42:26 +00:00
}
2020-12-14 21:58:00 +00:00
else if (!GetNetworkIdentity(obj, out var networkIdentity))
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Debug.LogError(string.Concat(new object[]
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
"SpawnObject ",
obj,
" has no QSBNetworkIdentity. Please add a NetworkIdentity to ",
obj
}));
2020-12-02 12:42:26 +00:00
}
else
{
networkIdentity.Reset();
networkIdentity.OnStartServer(false);
networkIdentity.RebuildObservers(true);
}
}
2020-12-02 18:40:38 +00:00
internal void SendSpawnMessage(QSBNetworkIdentity uv, QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (!uv.ServerOnly)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (uv.SceneId.IsEmpty())
2020-12-02 12:42:26 +00:00
{
2020-12-14 21:58:00 +00:00
var objectSpawnMessage = new QSBObjectSpawnMessage
{
NetId = uv.NetId,
assetId = uv.AssetId,
Position = uv.transform.position,
Rotation = uv.transform.rotation
};
2020-12-04 09:23:27 +00:00
var networkWriter = new QSBNetworkWriter();
2020-12-02 12:42:26 +00:00
uv.UNetSerializeAllVars(networkWriter);
if (networkWriter.Position > 0)
{
2020-12-03 11:56:32 +00:00
objectSpawnMessage.Payload = networkWriter.ToArray();
2020-12-02 12:42:26 +00:00
}
if (conn != null)
{
conn.Send(3, objectSpawnMessage);
}
else
{
2020-12-02 18:40:38 +00:00
SendToReady(uv.gameObject, 3, objectSpawnMessage);
2020-12-02 12:42:26 +00:00
}
}
else
{
2020-12-14 21:58:00 +00:00
var objectSpawnSceneMessage = new QSBObjectSpawnSceneMessage
{
NetId = uv.NetId,
SceneId = uv.SceneId,
Position = uv.transform.position
};
2020-12-04 09:23:27 +00:00
var networkWriter2 = new QSBNetworkWriter();
2020-12-02 12:42:26 +00:00
uv.UNetSerializeAllVars(networkWriter2);
if (networkWriter2.Position > 0)
{
2020-12-03 11:56:32 +00:00
objectSpawnSceneMessage.Payload = networkWriter2.ToArray();
2020-12-02 12:42:26 +00:00
}
if (conn != null)
{
conn.Send(10, objectSpawnSceneMessage);
}
else
{
2020-12-02 18:40:38 +00:00
SendToReady(uv.gameObject, 3, objectSpawnSceneMessage);
2020-12-02 12:42:26 +00:00
}
}
}
}
2020-12-02 18:40:38 +00:00
public static void DestroyPlayersForConnection(QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (conn.PlayerControllers.Count == 0)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Empty player list given to NetworkServer.Destroy(), nothing to do.");
}
}
else
{
2020-12-02 18:40:38 +00:00
if (conn.ClientOwnedObjects != null)
2020-12-02 12:42:26 +00:00
{
2020-12-15 09:56:03 +00:00
var hashSet = new HashSet<QSBNetworkInstanceId>(conn.ClientOwnedObjects);
2020-12-02 18:40:38 +00:00
foreach (var netId in hashSet)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var gameObject = FindLocalObject(netId);
2020-12-02 12:42:26 +00:00
if (gameObject != null)
{
2020-12-02 18:40:38 +00:00
DestroyObject(gameObject);
2020-12-02 12:42:26 +00:00
}
}
}
2020-12-02 18:40:38 +00:00
for (var i = 0; i < conn.PlayerControllers.Count; i++)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var playerController = conn.PlayerControllers[i];
2020-12-02 12:42:26 +00:00
if (playerController.IsValid)
{
2020-12-03 11:56:32 +00:00
if (!(playerController.UnetView == null))
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
DestroyObject(playerController.UnetView, true);
2020-12-02 12:42:26 +00:00
}
2020-12-03 11:56:32 +00:00
playerController.Gameobject = null;
2020-12-02 12:42:26 +00:00
}
}
2020-12-02 18:40:38 +00:00
conn.PlayerControllers.Clear();
2020-12-02 12:42:26 +00:00
}
}
private static void UnSpawnObject(GameObject obj)
{
if (obj == null)
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer UnspawnObject is null");
2020-12-02 12:42:26 +00:00
}
2020-12-14 21:58:00 +00:00
else if (GetNetworkIdentity(obj, out var uv))
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
UnSpawnObject(uv);
2020-12-02 12:42:26 +00:00
}
}
2020-12-14 21:58:00 +00:00
private static void UnSpawnObject(QSBNetworkIdentity uv) => DestroyObject(uv, false);
2020-12-02 12:42:26 +00:00
private static void DestroyObject(GameObject obj)
{
if (obj == null)
{
2020-12-02 18:40:38 +00:00
Debug.Log("NetworkServer DestroyObject is null");
2020-12-02 12:42:26 +00:00
}
2020-12-14 21:58:00 +00:00
else if (GetNetworkIdentity(obj, out var uv))
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
DestroyObject(uv, true);
2020-12-02 12:42:26 +00:00
}
}
2020-12-02 18:40:38 +00:00
private static void DestroyObject(QSBNetworkIdentity uv, bool destroyServerObject)
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logDebug)
{
2020-12-02 18:40:38 +00:00
Debug.Log("DestroyObject instance:" + uv.NetId);
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
if (objects.ContainsKey(uv.NetId))
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
objects.Remove(uv.NetId);
2020-12-02 12:42:26 +00:00
}
2020-12-02 18:40:38 +00:00
if (uv.ClientAuthorityOwner != null)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
uv.ClientAuthorityOwner.RemoveOwnedObject(uv);
2020-12-02 12:42:26 +00:00
}
2020-12-14 21:58:00 +00:00
var objectDestroyMessage = new QSBObjectDestroyMessage
{
NetId = uv.NetId
};
2020-12-02 18:40:38 +00:00
SendToObservers(uv.gameObject, 1, objectDestroyMessage);
2020-12-02 12:42:26 +00:00
uv.ClearObservers();
2020-12-02 18:40:38 +00:00
if (QSBNetworkClient.active && instance.m_LocalClientActive)
2020-12-02 12:42:26 +00:00
{
uv.OnNetworkDestroy();
2020-12-03 11:56:32 +00:00
QSBClientScene.SetLocalObject(objectDestroyMessage.NetId, null);
2020-12-02 12:42:26 +00:00
}
if (destroyServerObject)
{
2020-12-02 18:40:38 +00:00
UnityEngine.Object.Destroy(uv.gameObject);
2020-12-02 12:42:26 +00:00
}
uv.MarkForReset();
}
2020-12-14 21:58:00 +00:00
public static void ClearLocalObjects() => objects.Clear();
2020-12-02 12:42:26 +00:00
public static void Spawn(GameObject obj)
{
2020-12-02 18:40:38 +00:00
if (VerifyCanSpawn(obj))
2020-12-02 12:42:26 +00:00
{
instance.SpawnObject(obj);
}
}
2020-12-14 21:58:00 +00:00
private static bool CheckForPrefab(GameObject obj) => false;
2020-12-02 12:42:26 +00:00
private static bool VerifyCanSpawn(GameObject obj)
{
bool result;
2020-12-02 18:40:38 +00:00
if (CheckForPrefab(obj))
2020-12-02 12:42:26 +00:00
{
Debug.LogErrorFormat("GameObject {0} is a prefab, it can't be spawned. This will cause errors in builds.", new object[]
{
obj.name
});
result = false;
}
else
{
result = true;
}
return result;
}
public static bool SpawnWithClientAuthority(GameObject obj, GameObject player)
{
2020-12-02 18:40:38 +00:00
var component = player.GetComponent<QSBNetworkIdentity>();
2020-12-02 12:42:26 +00:00
bool result;
if (component == null)
{
Debug.LogError("SpawnWithClientAuthority player object has no NetworkIdentity");
result = false;
}
2020-12-02 18:40:38 +00:00
else if (component.ConnectionToClient == null)
2020-12-02 12:42:26 +00:00
{
Debug.LogError("SpawnWithClientAuthority player object is not a player.");
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
result = SpawnWithClientAuthority(obj, component.ConnectionToClient);
2020-12-02 12:42:26 +00:00
}
return result;
}
public static bool SpawnWithClientAuthority(GameObject obj, QSBNetworkConnection conn)
{
bool result;
if (!conn.isReady)
{
Debug.LogError("SpawnWithClientAuthority NetworkConnection is not ready!");
result = false;
}
else
{
2020-12-02 18:40:38 +00:00
Spawn(obj);
var component = obj.GetComponent<QSBNetworkIdentity>();
result = (!(component == null) && component.IsServer && component.AssignClientAuthority(conn));
2020-12-02 12:42:26 +00:00
}
return result;
}
2020-12-15 09:56:03 +00:00
public static bool SpawnWithClientAuthority(GameObject obj, QSBNetworkHash128 assetId, QSBNetworkConnection conn)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Spawn(obj, assetId);
var component = obj.GetComponent<QSBNetworkIdentity>();
return !(component == null) && component.IsServer && component.AssignClientAuthority(conn);
2020-12-02 12:42:26 +00:00
}
2020-12-15 09:56:03 +00:00
public static void Spawn(GameObject obj, QSBNetworkHash128 assetId)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (VerifyCanSpawn(obj))
2020-12-02 12:42:26 +00:00
{
2020-12-14 21:58:00 +00:00
if (GetNetworkIdentity(obj, out var networkIdentity))
2020-12-02 12:42:26 +00:00
{
networkIdentity.SetDynamicAssetId(assetId);
}
instance.SpawnObject(obj);
}
}
2020-12-14 21:58:00 +00:00
public static void Destroy(GameObject obj) => DestroyObject(obj);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public static void UnSpawn(GameObject obj) => UnSpawnObject(obj);
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
internal bool InvokeBytes(QSBULocalConnectionToServer conn, byte[] buffer, int numBytes, int channelId)
2020-12-02 12:42:26 +00:00
{
2020-12-04 09:23:27 +00:00
var networkReader = new QSBNetworkReader(buffer);
2020-12-02 12:42:26 +00:00
networkReader.ReadInt16();
2020-12-02 18:40:38 +00:00
var num = networkReader.ReadInt16();
2020-12-02 12:42:26 +00:00
bool result;
2020-12-02 18:40:38 +00:00
if (handlers.ContainsKey(num) && m_LocalConnection != null)
2020-12-02 12:42:26 +00:00
{
m_LocalConnection.InvokeHandler(num, networkReader, channelId);
result = true;
}
else
{
result = false;
}
return result;
}
2020-12-04 09:23:27 +00:00
internal bool InvokeHandlerOnServer(QSBULocalConnectionToServer conn, short msgType, QSBMessageBase msg, int channelId)
2020-12-02 12:42:26 +00:00
{
bool result;
2020-12-02 18:40:38 +00:00
if (handlers.ContainsKey(msgType) && m_LocalConnection != null)
2020-12-02 12:42:26 +00:00
{
2020-12-04 09:23:27 +00:00
var writer = new QSBNetworkWriter();
2020-12-02 12:42:26 +00:00
msg.Serialize(writer);
2020-12-04 09:23:27 +00:00
var reader = new QSBNetworkReader(writer);
2020-12-02 12:42:26 +00:00
m_LocalConnection.InvokeHandler(msgType, reader, channelId);
result = true;
}
else
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
"Local invoke: Failed to find local connection to invoke handler on [connectionId=",
conn.connectionId,
"] for MsgId:",
msgType
}));
}
result = false;
}
return result;
}
2020-12-15 09:56:03 +00:00
public static GameObject FindLocalObject(QSBNetworkInstanceId netId) => instance.m_NetworkScene.FindLocalObject(netId);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
private static bool ValidateSceneObject(QSBNetworkIdentity netId) => netId.gameObject.hideFlags != HideFlags.NotEditable && netId.gameObject.hideFlags != HideFlags.HideAndDontSave && !netId.SceneId.IsEmpty();
2020-12-02 12:42:26 +00:00
public static bool SpawnObjects()
{
bool result;
2020-12-02 18:40:38 +00:00
if (!active)
2020-12-02 12:42:26 +00:00
{
result = true;
}
else
{
2020-12-02 18:40:38 +00:00
var objectsOfTypeAll = Resources.FindObjectsOfTypeAll<QSBNetworkIdentity>();
foreach (var networkIdentity in objectsOfTypeAll)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (ValidateSceneObject(networkIdentity))
2020-12-02 12:42:26 +00:00
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"SpawnObjects sceneId:",
2020-12-02 18:40:38 +00:00
networkIdentity.SceneId,
2020-12-02 12:42:26 +00:00
" name:",
networkIdentity.gameObject.name
}));
}
networkIdentity.Reset();
networkIdentity.gameObject.SetActive(true);
}
}
2020-12-02 18:40:38 +00:00
foreach (var networkIdentity2 in objectsOfTypeAll)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (ValidateSceneObject(networkIdentity2))
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
Spawn(networkIdentity2.gameObject);
2020-12-02 12:42:26 +00:00
networkIdentity2.ForceAuthority(true);
}
}
result = true;
}
return result;
}
2020-12-02 18:40:38 +00:00
private static void SendCrc(QSBNetworkConnection targetConnection)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (QSBNetworkCRC.singleton != null)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
if (QSBNetworkCRC.scriptCRCCheck)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
var crcmessage = new QSBCRCMessage();
var list = new List<QSBCRCMessageEntry>();
2020-12-14 21:58:00 +00:00
foreach (var text in QSBNetworkCRC.singleton.scripts.Keys)
2020-12-02 12:42:26 +00:00
{
2020-12-02 18:40:38 +00:00
list.Add(new QSBCRCMessageEntry
2020-12-02 12:42:26 +00:00
{
name = text,
2020-12-02 18:40:38 +00:00
channel = (byte)QSBNetworkCRC.singleton.scripts[text]
2020-12-02 12:42:26 +00:00
});
}
crcmessage.scripts = list.ToArray();
targetConnection.Send(14, crcmessage);
}
}
}
private static volatile QSBNetworkServer s_Instance;
2020-12-02 18:40:38 +00:00
private static object s_Sync = new UnityEngine.Object();
2020-12-02 12:42:26 +00:00
private bool m_LocalClientActive;
2020-12-02 18:40:38 +00:00
private List<QSBNetworkConnection> m_LocalConnectionsFakeList = new List<QSBNetworkConnection>();
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
private QSBULocalConnectionToClient m_LocalConnection = null;
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
private QSBNetworkScene m_NetworkScene;
2020-12-02 12:42:26 +00:00
private HashSet<int> m_ExternalConnections;
private ServerSimpleWrapper m_SimpleServerSimple;
private float m_MaxDelay = 0.1f;
2020-12-15 09:56:03 +00:00
private HashSet<QSBNetworkInstanceId> m_RemoveList;
2020-12-02 12:42:26 +00:00
private int m_RemoveListCount;
private const int k_RemoveListInterval = 100;
internal static ushort maxPacketSize;
2020-12-02 18:40:38 +00:00
private static QSBRemovePlayerMessage s_RemovePlayerMessage = new QSBRemovePlayerMessage();
2020-12-02 12:42:26 +00:00
2020-12-02 18:40:38 +00:00
private class ServerSimpleWrapper : QSBNetworkServerSimple
2020-12-02 12:42:26 +00:00
{
public ServerSimpleWrapper(QSBNetworkServer server)
{
m_Server = server;
}
2020-12-14 21:58:00 +00:00
public override void OnConnectError(int connectionId, byte error) => m_Server.GenerateConnectError(error);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public override void OnDataError(QSBNetworkConnection conn, byte error) => m_Server.GenerateDataError(conn, error);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public override void OnDisconnectError(QSBNetworkConnection conn, byte error) => m_Server.GenerateDisconnectError(conn, error);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public override void OnConnected(QSBNetworkConnection conn) => m_Server.OnConnected(conn);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public override void OnDisconnected(QSBNetworkConnection conn) => m_Server.OnDisconnected(conn);
2020-12-02 12:42:26 +00:00
2020-12-14 21:58:00 +00:00
public override void OnData(QSBNetworkConnection conn, int receivedSize, int channelId) => m_Server.OnData(conn, receivedSize, channelId);
2020-12-02 12:42:26 +00:00
private QSBNetworkServer m_Server;
}
}
2020-12-03 08:28:05 +00:00
}