This commit is contained in:
Mister_Nebula 2020-12-16 09:07:40 +00:00
parent a2120b9018
commit 661c04a987
65 changed files with 2399 additions and 1362 deletions

View File

@ -145,9 +145,15 @@ namespace QSB.Animation
private void OnBecomeUngrounded() => _netAnim.SetTrigger("Ungrounded");
public void SendCrouch(float value = 0) => GlobalMessenger<float>.FireEvent(EventNames.QSBCrouch, value);
public void SendCrouch(float value = 0)
{
GlobalMessenger<float>.FireEvent(EventNames.QSBCrouch, value);
}
public void HandleCrouch(float value) => _crouchSync.CrouchParam.Target = value;
public void HandleCrouch(float value)
{
_crouchSync.CrouchParam.Target = value;
}
private void SuitUp()
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.ConversationSync.Events
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.ConversationSync.Events
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.DialogueConditionSync.Events
{

View File

@ -1,4 +1,4 @@
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.Messaging
{

View File

@ -1,4 +1,4 @@
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.Messaging
{

View File

@ -1,5 +1,5 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using QuantumUNET;
using QuantumUNET.Messages;
namespace QSB.Messaging
{

View File

@ -1,4 +1,4 @@
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.Messaging
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.OrbSync.Events
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.Player.Events
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.Player.Events
{

View File

@ -43,7 +43,6 @@ namespace QSB
public void Awake()
{
base.Awake();
Instance = this;
_lobby = gameObject.AddComponent<QSBNetworkLobby>();

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.TimeSync.Events
{

View File

@ -1,4 +1,4 @@
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.WorldSync.Events
{

View File

@ -1,5 +1,5 @@
using QSB.Messaging;
using QuantumUNET.Transport;
using QuantumUNET;
namespace QSB.WorldSync.Events
{

View File

@ -1,5 +1,4 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using UnityEngine;
namespace QuantumUNET.Components
@ -33,22 +32,22 @@ namespace QuantumUNET.Components
public void SetParameterAutoSend(int index, bool value)
{
if (value)
{
m_ParameterSendBits |= (uint)(1 << index);
}
else
{
m_ParameterSendBits &= (uint)~(1 << index);
}
public bool GetParameterAutoSend(int index)
{
return ((int)m_ParameterSendBits & 1 << index) != 0;
}
public bool GetParameterAutoSend(int index) =>
((int)m_ParameterSendBits & (1 << index)) != 0;
public override void OnStartAuthority() =>
public override void OnStartAuthority()
{
m_ParameterWriter = new QSBNetworkWriter();
}
public void FixedUpdate()
private void FixedUpdate()
{
if (m_ParameterWriter == null)
{
@ -135,10 +134,7 @@ namespace QuantumUNET.Components
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
QSBNetworkServer.SendToReady(gameObject, 41, parametersMessage);
}
}
@ -165,11 +161,14 @@ namespace QuantumUNET.Components
ReadParameters(reader, true);
}
internal void HandleAnimTriggerMsg(int hash) => m_Animator.SetTrigger(hash);
internal void HandleAnimTriggerMsg(int hash)
{
m_Animator.SetTrigger(hash);
}
private void WriteParameters(QSBNetworkWriter writer, bool autoSend)
{
for (var index = 0; index < m_Animator.parameters.Length; ++index)
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
@ -194,7 +193,7 @@ namespace QuantumUNET.Components
private void ReadParameters(QSBNetworkReader reader, bool autoSend)
{
for (var index = 0; index < m_Animator.parameters.Length; ++index)
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
@ -258,7 +257,10 @@ namespace QuantumUNET.Components
m_Animator.Play(stateNameHash, 0, normalizedTime);
}
public void SetTrigger(string triggerName) => SetTrigger(Animator.StringToHash(triggerName));
public void SetTrigger(string triggerName)
{
SetTrigger(Animator.StringToHash(triggerName));
}
public void SetTrigger(int hash)
{
@ -336,16 +338,10 @@ namespace QuantumUNET.Components
netMsg.ReadMessage(AnimationMessage);
var localObject = QSBClientScene.FindLocalObject(AnimationMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
{
return;
}
var reader = new QSBNetworkReader(AnimationMessage.parameters);
component.HandleAnimMsg(AnimationMessage, reader);
}
@ -355,16 +351,10 @@ namespace QuantumUNET.Components
netMsg.ReadMessage(ParametersMessage);
var localObject = QSBClientScene.FindLocalObject(ParametersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
{
return;
}
var reader = new QSBNetworkReader(ParametersMessage.parameters);
component.HandleAnimParamsMsg(ParametersMessage, reader);
}
@ -374,16 +364,10 @@ namespace QuantumUNET.Components
netMsg.ReadMessage(TriggersMessage);
var localObject = QSBClientScene.FindLocalObject(TriggersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
{
return;
}
component.HandleAnimTriggerMsg(TriggersMessage.hash);
}
}

View File

@ -1,6 +1,5 @@
using OWML.Logging;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -133,7 +132,7 @@ namespace QuantumUNET.Components
{
if (m_NetworkBehaviours == null)
{
m_NetworkBehaviours = GetComponents<QSBNetworkBehaviour>();
m_NetworkBehaviours = base.GetComponents<QSBNetworkBehaviour>();
}
}
@ -180,11 +179,11 @@ namespace QuantumUNET.Components
}
}
public void OnDestroy()
private void OnDestroy()
{
if (m_IsServer && QSBNetworkServer.active)
{
QSBNetworkServer.Destroy(gameObject);
QSBNetworkServer.Destroy(base.gameObject);
}
}
@ -234,7 +233,7 @@ namespace QuantumUNET.Components
}
if (QSBNetworkClient.active && QSBNetworkServer.localClientActive)
{
QSBClientScene.SetLocalObject(NetId, gameObject);
QSBClientScene.SetLocalObject(NetId, base.gameObject);
OnStartClient();
}
if (HasAuthority)
@ -254,7 +253,7 @@ namespace QuantumUNET.Components
Debug.Log(string.Concat(new object[]
{
"OnStartClient ",
gameObject,
base.gameObject,
" GUID:",
NetId,
" localPlayerAuthority:",
@ -356,7 +355,7 @@ namespace QuantumUNET.Components
{
if (!LocalPlayerAuthority)
{
Debug.LogError("HandleClientAuthority " + gameObject + " does not have localPlayerAuthority");
Debug.LogError("HandleClientAuthority " + base.gameObject + " does not have localPlayerAuthority");
}
else
{
@ -385,7 +384,7 @@ namespace QuantumUNET.Components
"Found no behaviour for incoming [",
cmdHashHandlerName,
"] on ",
gameObject,
base.gameObject,
", the server and client should have the same NetworkBehaviour instances [netId=",
NetId,
"]."
@ -403,7 +402,7 @@ namespace QuantumUNET.Components
internal void HandleSyncEvent(int cmdHash, QSBNetworkReader reader)
{
if (gameObject == null)
if (base.gameObject == null)
{
var cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(cmdHash);
Debug.LogWarning(string.Concat(new object[]
@ -423,7 +422,7 @@ namespace QuantumUNET.Components
"Found no receiver for incoming [",
cmdHashHandlerName2,
"] on ",
gameObject,
base.gameObject,
", the server and client should have the same NetworkBehaviour instances [netId=",
NetId,
"]."
@ -449,7 +448,7 @@ namespace QuantumUNET.Components
internal void HandleSyncList(int cmdHash, QSBNetworkReader reader)
{
if (gameObject == null)
if (base.gameObject == null)
{
var cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(cmdHash);
Debug.LogWarning(string.Concat(new object[]
@ -469,7 +468,7 @@ namespace QuantumUNET.Components
"Found no receiver for incoming [",
cmdHashHandlerName2,
"] on ",
gameObject,
base.gameObject,
", the server and client should have the same NetworkBehaviour instances [netId=",
NetId,
"]."
@ -495,7 +494,7 @@ namespace QuantumUNET.Components
internal void HandleCommand(int cmdHash, QSBNetworkReader reader)
{
if (gameObject == null)
if (base.gameObject == null)
{
var cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(cmdHash);
Debug.LogWarning(string.Concat(new object[]
@ -515,7 +514,7 @@ namespace QuantumUNET.Components
"Found no receiver for incoming [",
cmdHashHandlerName2,
"] on ",
gameObject,
base.gameObject,
", the server and client should have the same NetworkBehaviour instances [netId=",
NetId,
"]."
@ -541,7 +540,7 @@ namespace QuantumUNET.Components
internal void HandleRPC(int cmdHash, QSBNetworkReader reader)
{
if (gameObject == null)
if (base.gameObject == null)
{
var cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(cmdHash);
Debug.LogWarning(string.Concat(new object[]
@ -561,7 +560,7 @@ namespace QuantumUNET.Components
"Found no receiver for incoming [",
cmdHashHandlerName2,
"] on ",
gameObject,
base.gameObject,
", the server and client should have the same NetworkBehaviour instances [netId=",
NetId,
"]."
@ -628,7 +627,7 @@ namespace QuantumUNET.Components
Debug.LogWarning(string.Concat(new object[]
{
"Large state update of ",
s_UpdateWriter.Position - position,
(int)(s_UpdateWriter.Position - position),
" bytes for netId:",
NetId,
" from script:",
@ -640,7 +639,7 @@ namespace QuantumUNET.Components
if (flag)
{
s_UpdateWriter.FinishMessage();
QSBNetworkServer.SendWriterToReady(gameObject, s_UpdateWriter, j);
QSBNetworkServer.SendWriterToReady(base.gameObject, s_UpdateWriter, j);
}
}
IL_197:
@ -655,7 +654,7 @@ namespace QuantumUNET.Components
{
if (initialState && m_NetworkBehaviours == null)
{
m_NetworkBehaviours = GetComponents<QSBNetworkBehaviour>();
m_NetworkBehaviours = base.GetComponents<QSBNetworkBehaviour>();
}
for (var i = 0; i < m_NetworkBehaviours.Length; i++)
{
@ -669,7 +668,7 @@ namespace QuantumUNET.Components
ModConsole.OwmlConsole.WriteLine($"SetLocalPlayer {localPlayerControllerId}");
IsLocalPlayer = true;
PlayerControllerId = localPlayerControllerId;
var hasAuthority = HasAuthority;
var hasAuthority = this.HasAuthority;
if (LocalPlayerAuthority)
{
HasAuthority = true;
@ -724,7 +723,7 @@ namespace QuantumUNET.Components
{
if (m_Observers == null)
{
Debug.LogError("AddObserver for " + gameObject + " observer list is null");
Debug.LogError("AddObserver for " + base.gameObject + " observer list is null");
}
else if (m_ObserverConnections.Contains(conn.connectionId))
{
@ -733,7 +732,7 @@ namespace QuantumUNET.Components
"Duplicate observer ",
conn.address,
" added for ",
gameObject
base.gameObject
}));
}
else
@ -743,7 +742,7 @@ namespace QuantumUNET.Components
"Added observer ",
conn.address,
" added for ",
gameObject
base.gameObject
}));
m_Observers.Add(conn);
m_ObserverConnections.Add(conn.connectionId);
@ -813,7 +812,7 @@ namespace QuantumUNET.Components
Debug.LogWarning(string.Concat(new object[]
{
"Observer is not ready for ",
gameObject,
base.gameObject,
" ",
networkConnection3
}));
@ -824,7 +823,7 @@ namespace QuantumUNET.Components
Debug.Log(string.Concat(new object[]
{
"New Observer for ",
gameObject,
base.gameObject,
" ",
networkConnection3
}));
@ -840,7 +839,7 @@ namespace QuantumUNET.Components
Debug.Log(string.Concat(new object[]
{
"Removed Observer for ",
gameObject,
base.gameObject,
" ",
networkConnection4
}));
@ -884,12 +883,12 @@ namespace QuantumUNET.Components
}
else if (ClientAuthorityOwner == null)
{
Debug.LogError("RemoveClientAuthority for " + gameObject + " has no clientAuthority owner.");
Debug.LogError("RemoveClientAuthority for " + base.gameObject + " has no clientAuthority owner.");
return false;
}
else if (ClientAuthorityOwner != conn)
{
Debug.LogError("RemoveClientAuthority for " + gameObject + " has different owner.");
Debug.LogError("RemoveClientAuthority for " + base.gameObject + " has different owner.");
return false;
}
ClientAuthorityOwner.RemoveOwnedObject(this);
@ -918,12 +917,12 @@ namespace QuantumUNET.Components
}
else if (ClientAuthorityOwner != null && conn != ClientAuthorityOwner)
{
ModConsole.OwmlConsole.WriteLine("AssignClientAuthority for " + gameObject + " already has an owner. Use RemoveClientAuthority() first.");
ModConsole.OwmlConsole.WriteLine("AssignClientAuthority for " + base.gameObject + " already has an owner. Use RemoveClientAuthority() first.");
return false;
}
else if (conn == null)
{
ModConsole.OwmlConsole.WriteLine("AssignClientAuthority for " + gameObject + " owner cannot be null. Use RemoveClientAuthority() instead.");
ModConsole.OwmlConsole.WriteLine("AssignClientAuthority for " + base.gameObject + " owner cannot be null. Use RemoveClientAuthority() instead.");
return false;
}
ClientAuthorityOwner = conn;

View File

@ -9,7 +9,10 @@ namespace QuantumUNET.Components
public int offsetX;
public int offsetY;
private void Awake() => manager = GetComponent<QSBNetworkManagerUNET>();
private void Awake()
{
manager = GetComponent<QSBNetworkManagerUNET>();
}
private void OnGUI()
{

View File

@ -31,6 +31,7 @@ namespace QuantumUNET.Components
public float packetLossPercentage { get; set; }
public float maxDelay { get; set; } = 0.01f;
public GameObject playerPrefab { get; set; }
public PlayerSpawnMethod playerSpawnMethod { get; set; }
public List<GameObject> spawnPrefabs { get; } = new List<GameObject>();
public QSBNetworkClient client;
public int maxConnections { get; set; } = 4;
@ -40,6 +41,8 @@ namespace QuantumUNET.Components
private GlobalConfig m_GlobalConfig;
private int m_MaxBufferedPackets = 16;
private bool m_AllowFragmentation = true;
private static List<Transform> s_StartPositions = new List<Transform>();
private static int s_StartPositionIndex;
private static QSBAddPlayerMessage s_AddPlayerMessage = new QSBAddPlayerMessage();
private static QSBRemovePlayerMessage s_RemovePlayerMessage = new QSBRemovePlayerMessage();
private static QSBErrorMessage s_ErrorMessage = new QSBErrorMessage();
@ -47,6 +50,14 @@ namespace QuantumUNET.Components
private static QSBNetworkConnection s_ClientReadyConnection;
private static string s_Address;
public List<Transform> startPositions
{
get
{
return s_StartPositions;
}
}
public bool customConfig { get; set; }
public ConnectionConfig connectionConfig
@ -96,7 +107,10 @@ namespace QuantumUNET.Components
}
}
public void Awake() => InitializeSingleton();
private void Awake()
{
InitializeSingleton();
}
private void InitializeSingleton()
{
@ -107,14 +121,14 @@ namespace QuantumUNET.Components
if (singleton != null)
{
Debug.Log("Multiple NetworkManagers detected in the scene. Only one NetworkManager can exist at a time. The duplicate NetworkManager will not be used.");
Destroy(gameObject);
Destroy(base.gameObject);
return;
}
Debug.Log("NetworkManager created singleton (DontDestroyOnLoad)");
singleton = this;
if (Application.isPlaying)
{
DontDestroyOnLoad(gameObject);
DontDestroyOnLoad(base.gameObject);
}
}
else
@ -143,7 +157,10 @@ namespace QuantumUNET.Components
QSBNetworkServer.RegisterHandler(QSBMsgType.Error, new QSBNetworkMessageDelegate(OnServerErrorInternal));
}
public bool StartServer() => StartServer(null, -1);
public bool StartServer()
{
return StartServer(null, -1);
}
private bool StartServer(ConnectionConfig config, int maxConnections)
{
@ -175,18 +192,27 @@ namespace QuantumUNET.Components
if (serverBindToIP && !string.IsNullOrEmpty(serverBindAddress))
{
if (!QSBNetworkServer.Listen(serverBindAddress, networkPort))
{
if (LogFilter.logError)
{
Debug.LogError("StartServer listen on " + serverBindAddress + " failed.");
}
return false;
}
}
else if (!QSBNetworkServer.Listen(networkPort))
{
if (LogFilter.logError)
{
Debug.LogError("StartServer listen failed.");
}
return false;
}
RegisterServerMessages();
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager StartServer port:" + networkPort);
}
isNetworkActive = true;
var name = SceneManager.GetSceneAt(0).name;
if (!string.IsNullOrEmpty(onlineScene) && onlineScene != name && onlineScene != offlineScene)
@ -313,9 +339,15 @@ namespace QuantumUNET.Components
return client;
}
public QSBNetworkClient StartClient() => StartClient(null);
public QSBNetworkClient StartClient()
{
return StartClient(null);
}
public QSBNetworkClient StartClient(ConnectionConfig config) => StartClient(config, 0);
public QSBNetworkClient StartClient(ConnectionConfig config)
{
return StartClient(config, 0);
}
public virtual QSBNetworkClient StartHost(ConnectionConfig config, int maxConnections)
{
@ -353,8 +385,11 @@ namespace QuantumUNET.Components
}
private QSBNetworkClient ConnectLocalClient()
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager StartHost port:" + networkPort);
}
networkAddress = "localhost";
client = QSBClientScene.ConnectLocalServer();
RegisterClientMessages(client);
@ -373,7 +408,10 @@ namespace QuantumUNET.Components
if (QSBNetworkServer.active)
{
OnStopServer();
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager StopServer");
}
isNetworkActive = false;
QSBNetworkServer.Shutdown();
if (!string.IsNullOrEmpty(offlineScene))
@ -387,7 +425,10 @@ namespace QuantumUNET.Components
public void StopClient()
{
OnStopClient();
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager StopClient");
}
isNetworkActive = false;
if (client != null)
{
@ -406,17 +447,25 @@ namespace QuantumUNET.Components
public virtual void ServerChangeScene(string newSceneName)
{
if (string.IsNullOrEmpty(newSceneName))
{
if (LogFilter.logError)
{
Debug.LogError("ServerChangeScene empty scene name");
}
}
else
{
if (LogFilter.logDebug)
{
Debug.Log("ServerChangeScene " + newSceneName);
}
QSBNetworkServer.SetAllClientsNotReady();
networkSceneName = newSceneName;
s_LoadingSceneAsync = SceneManager.LoadSceneAsync(newSceneName);
var msg = new QSBStringMessage(networkSceneName);
QSBNetworkServer.SendToAll(39, msg);
s_StartPositionIndex = 0;
s_StartPositions.Clear();
}
}
@ -431,12 +480,18 @@ namespace QuantumUNET.Components
internal void ClientChangeScene(string newSceneName, bool forceReload)
{
if (string.IsNullOrEmpty(newSceneName))
{
if (LogFilter.logError)
{
Debug.LogError("ClientChangeScene empty scene name");
}
}
else
{
if (LogFilter.logDebug)
{
Debug.Log("ClientChangeScene newSceneName:" + newSceneName + " networkSceneName:" + networkSceneName);
}
if (newSceneName == networkSceneName)
{
if (!forceReload)
@ -494,12 +549,47 @@ namespace QuantumUNET.Components
}
}
public bool IsClientConnected() => client != null && client.isConnected;
public static void RegisterStartPosition(Transform start)
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"RegisterStartPosition: (",
start.gameObject.name,
") ",
start.position
}));
}
s_StartPositions.Add(start);
}
public static void UnRegisterStartPosition(Transform start)
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
"UnRegisterStartPosition: (",
start.gameObject.name,
") ",
start.position
}));
}
s_StartPositions.Remove(start);
}
public bool IsClientConnected()
{
return client != null && client.isConnected;
}
public static void Shutdown()
{
if (!(singleton == null))
{
s_StartPositions.Clear();
s_StartPositionIndex = 0;
s_ClientReadyConnection = null;
singleton.StopHost();
singleton = null;
@ -507,8 +597,11 @@ namespace QuantumUNET.Components
}
internal void OnServerConnectInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerConnectInternal");
}
netMsg.Connection.SetMaxDelay(maxDelay);
if (m_MaxBufferedPackets != 512)
{
@ -533,20 +626,29 @@ namespace QuantumUNET.Components
}
internal void OnServerDisconnectInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerDisconnectInternal");
}
OnServerDisconnect(netMsg.Connection);
}
internal void OnServerReadyMessageInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerReadyMessageInternal");
}
OnServerReady(netMsg.Connection);
}
internal void OnServerAddPlayerMessageInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerAddPlayerMessageInternal");
}
netMsg.ReadMessage<QSBAddPlayerMessage>(s_AddPlayerMessage);
if (s_AddPlayerMessage.msgSize != 0)
{
@ -560,8 +662,11 @@ namespace QuantumUNET.Components
}
internal void OnServerRemovePlayerMessageInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerRemovePlayerMessageInternal");
}
netMsg.ReadMessage<QSBRemovePlayerMessage>(s_RemovePlayerMessage);
netMsg.Connection.GetPlayerController(s_RemovePlayerMessage.PlayerControllerId, out var player);
OnServerRemovePlayer(netMsg.Connection, player);
@ -569,15 +674,21 @@ namespace QuantumUNET.Components
}
internal void OnServerErrorInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnServerErrorInternal");
}
netMsg.ReadMessage<QSBErrorMessage>(s_ErrorMessage);
OnServerError(netMsg.Connection, s_ErrorMessage.errorCode);
}
internal void OnClientConnectInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnClientConnectInternal");
}
netMsg.Connection.SetMaxDelay(maxDelay);
var name = SceneManager.GetSceneAt(0).name;
if (string.IsNullOrEmpty(onlineScene) || onlineScene == offlineScene || name == onlineScene)
@ -592,8 +703,11 @@ namespace QuantumUNET.Components
}
internal void OnClientDisconnectInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnClientDisconnectInternal");
}
if (!string.IsNullOrEmpty(offlineScene))
{
ClientChangeScene(offlineScene, false);
@ -602,22 +716,31 @@ namespace QuantumUNET.Components
}
internal void OnClientNotReadyMessageInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnClientNotReadyMessageInternal");
}
QSBClientScene.SetNotReady();
OnClientNotReady(netMsg.Connection);
}
internal void OnClientErrorInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnClientErrorInternal");
}
netMsg.ReadMessage<QSBErrorMessage>(s_ErrorMessage);
OnClientError(netMsg.Connection, s_ErrorMessage.errorCode);
}
internal void OnClientSceneInternal(QSBNetworkMessage netMsg)
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkManager:OnClientSceneInternal");
}
var newSceneName = netMsg.Reader.ReadString();
if (IsClientConnected() && !QSBNetworkServer.active)
{
@ -633,45 +756,110 @@ namespace QuantumUNET.Components
{
QSBNetworkServer.DestroyPlayersForConnection(conn);
if (conn.LastError != NetworkError.Ok)
{
if (LogFilter.logError)
{
Debug.LogError("ServerDisconnected due to error: " + conn.LastError);
}
}
}
public virtual void OnServerReady(QSBNetworkConnection conn)
{
if (conn.PlayerControllers.Count == 0)
{
if (LogFilter.logDebug)
{
Debug.Log("Ready with no player object");
}
}
QSBNetworkServer.SetClientReady(conn);
}
public virtual void OnServerAddPlayer(QSBNetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader) => OnServerAddPlayerInternal(conn, playerControllerId);
public virtual void OnServerAddPlayer(QSBNetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)
{
OnServerAddPlayerInternal(conn, playerControllerId);
}
public virtual void OnServerAddPlayer(QSBNetworkConnection conn, short playerControllerId) => OnServerAddPlayerInternal(conn, playerControllerId);
public virtual void OnServerAddPlayer(QSBNetworkConnection conn, short playerControllerId)
{
OnServerAddPlayerInternal(conn, playerControllerId);
}
private void OnServerAddPlayerInternal(QSBNetworkConnection conn, short playerControllerId)
{
if (playerPrefab == null)
{
if (LogFilter.logError)
{
ModConsole.OwmlConsole.WriteLine("Error - The PlayerPrefab is empty on the QSBNetworkManager. Please setup a PlayerPrefab object.");
}
}
else if (playerPrefab.GetComponent<QSBNetworkIdentity>() == null)
{
if (LogFilter.logError)
{
ModConsole.OwmlConsole.WriteLine("Error - The PlayerPrefab does not have a QSBNetworkIdentity. Please add a QSBNetworkIdentity to the player prefab.");
}
}
else if (playerControllerId < conn.PlayerControllers.Count && conn.PlayerControllers[playerControllerId].IsValid && conn.PlayerControllers[playerControllerId].Gameobject != null)
{
if (LogFilter.logError)
{
ModConsole.OwmlConsole.WriteLine("Warning - There is already a player at that playerControllerId for this connections.");
}
}
else
{
var player = Instantiate<GameObject>(playerPrefab, Vector3.zero, Quaternion.identity);
var startPosition = GetStartPosition();
GameObject player;
if (startPosition != null)
{
player = Instantiate<GameObject>(playerPrefab, startPosition.position, startPosition.rotation);
}
else
{
player = Instantiate<GameObject>(playerPrefab, Vector3.zero, Quaternion.identity);
}
QSBNetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
}
}
public Transform GetStartPosition()
{
if (s_StartPositions.Count > 0)
{
for (var i = s_StartPositions.Count - 1; i >= 0; i--)
{
if (s_StartPositions[i] == null)
{
s_StartPositions.RemoveAt(i);
}
}
}
Transform result;
if (playerSpawnMethod == PlayerSpawnMethod.Random && s_StartPositions.Count > 0)
{
var index = UnityEngine.Random.Range(0, s_StartPositions.Count);
result = s_StartPositions[index];
}
else if (playerSpawnMethod == PlayerSpawnMethod.RoundRobin && s_StartPositions.Count > 0)
{
if (s_StartPositionIndex >= s_StartPositions.Count)
{
s_StartPositionIndex = 0;
}
var transform = s_StartPositions[s_StartPositionIndex];
s_StartPositionIndex++;
result = transform;
}
else
{
result = null;
}
return result;
}
public virtual void OnServerRemovePlayer(QSBNetworkConnection conn, QSBPlayerController player)
{
if (player.Gameobject != null)
@ -704,10 +892,13 @@ namespace QuantumUNET.Components
{
StopClient();
if (conn.LastError != NetworkError.Ok)
{
if (LogFilter.logError)
{
Debug.LogError("ClientDisconnected due to error: " + conn.LastError);
}
}
}
public virtual void OnClientError(QSBNetworkConnection conn, int errorCode)
{

View File

@ -1,6 +1,5 @@
using OWML.Logging;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using UnityEngine;
using UnityEngine.Networking;
@ -9,22 +8,86 @@ namespace QuantumUNET.Components
public class QSBNetworkTransform : QSBNetworkBehaviour
{
public float SendInterval { get; set; } = 0.1f;
public AxisSyncMode SyncRotationAxis { get; set; } = AxisSyncMode.AxisXYZ;
public CompressionSyncMode RotationSyncCompression { get; set; } = CompressionSyncMode.None;
public bool SyncSpin { get; set; }
public float MovementTheshold { get; set; } = 0.001f;
public float velocityThreshold { get; set; } = 0.0001f;
public float SnapThreshold { get; set; } = 5f;
public float InterpolateRotation { get; set; } = 1f;
public float InterpolateMovement { get; set; } = 1f;
public ClientMoveCallback3D clientMoveCallback3D { get; set; }
public float LastSyncTime { get; private set; }
public Vector3 TargetSyncPosition => m_TargetSyncPosition;
public Vector3 targetSyncVelocity => m_TargetSyncVelocity;
public Quaternion targetSyncRotation3D => m_TargetSyncRotation3D;
public Vector3 TargetSyncPosition
{
get
{
return m_TargetSyncPosition;
}
}
public Vector3 targetSyncVelocity
{
get
{
return m_TargetSyncVelocity;
}
}
public Quaternion targetSyncRotation3D
{
get
{
return m_TargetSyncRotation3D;
}
}
public bool Grounded { get; set; } = true;
public void Awake()
private void OnValidate()
{
if (SendInterval < 0f)
{
SendInterval = 0f;
}
if (SyncRotationAxis < AxisSyncMode.None || SyncRotationAxis > AxisSyncMode.AxisXYZ)
{
SyncRotationAxis = AxisSyncMode.None;
}
if (MovementTheshold < 0f)
{
MovementTheshold = 0f;
}
if (velocityThreshold < 0f)
{
velocityThreshold = 0f;
}
if (SnapThreshold < 0f)
{
SnapThreshold = 0.01f;
}
if (InterpolateRotation < 0f)
{
InterpolateRotation = 0.01f;
}
if (InterpolateMovement < 0f)
{
InterpolateMovement = 0.01f;
}
}
private void Awake()
{
m_PrevPosition = transform.position;
m_PrevRotation = transform.rotation;
@ -34,7 +97,10 @@ namespace QuantumUNET.Components
}
}
public override void OnStartServer() => LastSyncTime = 0f;
public override void OnStartServer()
{
LastSyncTime = 0f;
}
public override bool OnSerialize(QSBNetworkWriter writer, bool initialState)
{
@ -228,9 +294,12 @@ namespace QuantumUNET.Components
component.UnserializeModeTransform(netMsg.Reader, false);
component.LastSyncTime = Time.time;
}
else if (LogFilter.logWarn)
{
ModConsole.OwmlConsole.WriteLine("Warning - HandleTransform netId:" + networkInstanceId + " is not for a valid player");
}
}
}
private static void WriteAngle(QSBNetworkWriter writer, float angle, CompressionSyncMode compression)
{
@ -267,12 +336,12 @@ namespace QuantumUNET.Components
}
else
{
result = reader.ReadInt16();
result = (float)reader.ReadInt16();
}
}
else
{
result = reader.ReadInt16();
result = (float)reader.ReadInt16();
}
}
else
@ -282,8 +351,10 @@ namespace QuantumUNET.Components
return result;
}
public static void SerializeVelocity3D(QSBNetworkWriter writer, Vector3 velocity, CompressionSyncMode compression) =>
public static void SerializeVelocity3D(QSBNetworkWriter writer, Vector3 velocity, CompressionSyncMode compression)
{
writer.Write(velocity);
}
public static void SerializeRotation3D(QSBNetworkWriter writer, Quaternion rot, AxisSyncMode mode, CompressionSyncMode compression)
{
@ -363,7 +434,10 @@ namespace QuantumUNET.Components
}
}
public static Vector3 UnserializeVelocity3D(QSBNetworkReader reader, CompressionSyncMode compression) => reader.ReadVector3();
public static Vector3 UnserializeVelocity3D(QSBNetworkReader reader, CompressionSyncMode compression)
{
return reader.ReadVector3();
}
public static Quaternion UnserializeRotation3D(QSBNetworkReader reader, AxisSyncMode mode, CompressionSyncMode compression)
{
@ -445,11 +519,20 @@ namespace QuantumUNET.Components
return zero;
}
public override int GetNetworkChannel() => 1;
public override int GetNetworkChannel()
{
return 1;
}
public override float GetNetworkSendInterval() => SendInterval;
public override float GetNetworkSendInterval()
{
return SendInterval;
}
public override void OnStartAuthority() => LastSyncTime = 0f;
public override void OnStartAuthority()
{
LastSyncTime = 0f;
}
private Vector3 m_TargetSyncPosition;

View File

@ -1,6 +1,4 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
internal class QSBAddPlayerMessage : QSBMessageBase
{
@ -8,12 +6,6 @@ namespace QuantumUNET.Messages
public int msgSize;
public byte[] msgData;
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(playerControllerId);
writer.WriteBytesAndSize(msgData, msgSize);
}
public override void Deserialize(QSBNetworkReader reader)
{
playerControllerId = reader.ReadInt16();
@ -27,5 +19,11 @@ namespace QuantumUNET.Messages
msgSize = msgData.Length;
}
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(playerControllerId);
writer.WriteBytesAndSize(msgData, msgSize);
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages
@ -10,6 +9,14 @@ namespace QuantumUNET.Messages
public float normalizedTime;
public byte[] parameters;
public override void Deserialize(QSBNetworkReader reader)
{
netId = reader.ReadNetworkId();
stateHash = (int)reader.ReadPackedUInt32();
normalizedTime = reader.ReadSingle();
parameters = reader.ReadBytesAndSize();
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(netId);
@ -24,13 +31,5 @@ namespace QuantumUNET.Messages
writer.WriteBytesAndSize(parameters, parameters.Length);
}
}
public override void Deserialize(QSBNetworkReader reader)
{
netId = reader.ReadNetworkId();
stateHash = (int)reader.ReadPackedUInt32();
normalizedTime = reader.ReadSingle();
parameters = reader.ReadBytesAndSize();
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages

View File

@ -1,6 +1,4 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
internal class QSBCRCMessage : QSBMessageBase
{

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages

View File

@ -1,10 +1,13 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
public class QSBEmptyMessage : QSBMessageBase
{
public override void Serialize(QSBNetworkWriter writer) { }
public override void Deserialize(QSBNetworkReader reader) { }
public override void Deserialize(QSBNetworkReader reader)
{
}
public override void Serialize(QSBNetworkWriter writer)
{
}
}
}

View File

@ -1,13 +1,17 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
public class QSBErrorMessage : QSBMessageBase
{
public override void Deserialize(QSBNetworkReader reader)
{
this.errorCode = (int)reader.ReadUInt16();
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write((ushort)this.errorCode);
}
public int errorCode;
public override void Serialize(QSBNetworkWriter writer) => writer.Write((ushort)errorCode);
public override void Deserialize(QSBNetworkReader reader) => errorCode = reader.ReadUInt16();
}
}

View File

@ -1,11 +1,13 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
public abstract class QSBMessageBase
{
public virtual void Serialize(QSBNetworkWriter writer) { }
public virtual void Deserialize(QSBNetworkReader reader)
{
}
public virtual void Deserialize(QSBNetworkReader reader) { }
public virtual void Serialize(QSBNetworkWriter writer)
{
}
}
}

View File

@ -11,7 +11,7 @@
}
else
{
var text = msgLabels[value];
string text = msgLabels[(int)value];
if (string.IsNullOrEmpty(text))
{
text = "[" + value + "]";

View File

@ -1,10 +1,10 @@
using QuantumUNET.Transport;
using System;
using System;
namespace QuantumUNET.Messages
{
public class QSBNetworkMessage
{
public const int MaxMessageSize = 65535;
public short MsgType;
public QSBNetworkConnection Connection;
public QSBNetworkReader Reader;
@ -17,7 +17,9 @@ namespace QuantumUNET.Messages
return result;
}
public void ReadMessage<TMsg>(TMsg msg) where TMsg : QSBMessageBase =>
public void ReadMessage<TMsg>(TMsg msg) where TMsg : QSBMessageBase
{
msg.Deserialize(Reader);
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages
@ -7,8 +6,14 @@ namespace QuantumUNET.Messages
{
public NetworkInstanceId NetId;
public override void Serialize(QSBNetworkWriter writer) => writer.Write(NetId);
public override void Deserialize(QSBNetworkReader reader)
{
NetId = reader.ReadNetworkId();
}
public override void Deserialize(QSBNetworkReader reader) => NetId = reader.ReadNetworkId();
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
}
}
}

View File

@ -1,13 +1,17 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
internal class QSBObjectSpawnFinishedMessage : QSBMessageBase
{
public uint State;
public override void Serialize(QSBNetworkWriter writer) => writer.WritePackedUInt32(State);
public override void Deserialize(QSBNetworkReader reader)
{
State = reader.ReadPackedUInt32();
}
public override void Deserialize(QSBNetworkReader reader) => State = reader.ReadPackedUInt32();
public override void Serialize(QSBNetworkWriter writer)
{
writer.WritePackedUInt32(State);
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine;
using UnityEngine.Networking;
@ -12,15 +11,6 @@ namespace QuantumUNET.Messages
public byte[] Payload;
public Quaternion Rotation;
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.Write(assetId);
writer.Write(Position);
writer.WriteBytesFull(Payload);
writer.Write(Rotation);
}
public override void Deserialize(QSBNetworkReader reader)
{
NetId = reader.ReadNetworkId();
@ -32,5 +22,14 @@ namespace QuantumUNET.Messages
Rotation = reader.ReadQuaternion();
}
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.Write(assetId);
writer.Write(Position);
writer.WriteBytesFull(Payload);
writer.Write(Rotation);
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine;
using UnityEngine.Networking;
@ -11,14 +10,6 @@ namespace QuantumUNET.Messages
public Vector3 Position;
public byte[] Payload;
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.Write(SceneId);
writer.Write(Position);
writer.WriteBytesFull(Payload);
}
public override void Deserialize(QSBNetworkReader reader)
{
NetId = reader.ReadNetworkId();
@ -26,5 +17,13 @@ namespace QuantumUNET.Messages
Position = reader.ReadVector3();
Payload = reader.ReadBytesAndSize();
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.Write(SceneId);
writer.Write(Position);
writer.WriteBytesFull(Payload);
}
}
}

View File

@ -1,4 +1,3 @@
using QuantumUNET.Transport;
using UnityEngine.Networking;
namespace QuantumUNET.Messages
@ -8,16 +7,16 @@ namespace QuantumUNET.Messages
public NetworkInstanceId NetId;
public short PlayerControllerId;
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.WritePackedUInt32((uint)PlayerControllerId);
}
public override void Deserialize(QSBNetworkReader reader)
{
NetId = reader.ReadNetworkId();
PlayerControllerId = (short)reader.ReadPackedUInt32();
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(NetId);
writer.WritePackedUInt32((uint)PlayerControllerId);
}
}
}

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
namespace QuantumUNET.Messages
{
public class QSBPeerInfoMessage : QSBMessageBase
{
public override void Deserialize(QSBNetworkReader reader)
{
this.connectionId = (int)reader.ReadPackedUInt32();
this.address = reader.ReadString();
this.port = (int)reader.ReadPackedUInt32();
this.isHost = reader.ReadBoolean();
this.isYou = reader.ReadBoolean();
uint num = reader.ReadPackedUInt32();
if (num > 0U)
{
List<QSBPeerInfoPlayer> list = new List<QSBPeerInfoPlayer>();
for (uint num2 = 0U; num2 < num; num2 += 1U)
{
QSBPeerInfoPlayer item;
item.netId = reader.ReadNetworkId();
item.playerControllerId = (short)reader.ReadPackedUInt32();
list.Add(item);
}
this.playerIds = list.ToArray();
}
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.WritePackedUInt32((uint)this.connectionId);
writer.Write(this.address);
writer.WritePackedUInt32((uint)this.port);
writer.Write(this.isHost);
writer.Write(this.isYou);
if (this.playerIds == null)
{
writer.WritePackedUInt32(0U);
}
else
{
writer.WritePackedUInt32((uint)this.playerIds.Length);
for (int i = 0; i < this.playerIds.Length; i++)
{
writer.Write(this.playerIds[i].netId);
writer.WritePackedUInt32((uint)this.playerIds[i].playerControllerId);
}
}
}
public override string ToString()
{
return string.Concat(new object[]
{
"PeerInfo conn:",
this.connectionId,
" addr:",
this.address,
":",
this.port,
" host:",
this.isHost,
" isYou:",
this.isYou
});
}
public int connectionId;
public string address;
public int port;
public bool isHost;
public bool isYou;
public QSBPeerInfoPlayer[] playerIds;
}
}

View File

@ -0,0 +1,30 @@
using UnityEngine.Networking;
namespace QuantumUNET.Messages
{
public class QSBReconnectMessage : QSBMessageBase
{
public int oldConnectionId;
public short playerControllerId;
public NetworkInstanceId netId;
public int msgSize;
public byte[] msgData;
public override void Deserialize(QSBNetworkReader reader)
{
oldConnectionId = (int)reader.ReadPackedUInt32();
playerControllerId = (short)reader.ReadPackedUInt32();
netId = reader.ReadNetworkId();
msgData = reader.ReadBytesAndSize();
msgSize = msgData.Length;
}
public override void Serialize(QSBNetworkWriter writer)
{
writer.WritePackedUInt32((uint)oldConnectionId);
writer.WritePackedUInt32((uint)playerControllerId);
writer.Write(netId);
writer.WriteBytesAndSize(msgData, msgSize);
}
}
}

View File

@ -1,13 +1,17 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
public class QSBRemovePlayerMessage : QSBMessageBase
{
public short PlayerControllerId;
public override void Serialize(QSBNetworkWriter writer) => writer.Write((ushort)PlayerControllerId);
public override void Deserialize(QSBNetworkReader reader)
{
PlayerControllerId = (short)reader.ReadUInt16();
}
public override void Deserialize(QSBNetworkReader reader) => PlayerControllerId = (short)reader.ReadUInt16();
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write((ushort)PlayerControllerId);
}
}
}

View File

@ -1,7 +0,0 @@
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET
{
public delegate GameObject QSBSpawnDelegate(Vector3 position, NetworkHash128 assetId);
}

View File

@ -1,18 +1,26 @@
using QuantumUNET.Transport;
namespace QuantumUNET.Messages
namespace QuantumUNET.Messages
{
public class QSBStringMessage : QSBMessageBase
{
public string value;
public QSBStringMessage()
{
}
public QSBStringMessage(string v)
{
value = v;
this.value = v;
}
public override void Serialize(QSBNetworkWriter writer) => writer.Write(value);
public override void Deserialize(QSBNetworkReader reader)
{
this.value = reader.ReadString();
}
public override void Deserialize(QSBNetworkReader reader) => value = reader.ReadString();
public override void Serialize(QSBNetworkWriter writer)
{
writer.Write(this.value);
}
public string value;
}
}

View File

@ -4,7 +4,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET.Transport
namespace QuantumUNET
{
internal class QSBChannelBuffer : IDisposable
{
@ -98,18 +98,27 @@ namespace QuantumUNET.Transport
result = false;
}
else if (!_currentPacket.IsEmpty() || _pendingPackets.Count > 0)
{
if (LogFilter.logError)
{
Debug.LogError("Cannot set MaxPacketSize after sending data.");
}
result = false;
}
else if (value <= 0)
{
if (LogFilter.logError)
{
Debug.LogError("Cannot set MaxPacketSize less than one.");
}
result = false;
}
else if (value > _maxPacketSize)
{
if (LogFilter.logError)
{
Debug.LogError("Cannot set MaxPacketSize to greater than the existing maximum (" + _maxPacketSize + ").");
}
result = false;
}
else
@ -130,6 +139,8 @@ namespace QuantumUNET.Transport
result = false;
}
else if (value < 0 || value >= 512)
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
@ -138,6 +149,7 @@ namespace QuantumUNET.Transport
". Must be greater than zero and less than ",
512
}));
}
result = false;
}
else
@ -227,13 +239,19 @@ namespace QuantumUNET.Transport
{
bool result;
if (bytesToSend >= 65535)
{
if (LogFilter.logError)
{
Debug.LogError("ChannelBuffer:SendBytes cannot send packet larger than " + ushort.MaxValue + " bytes");
}
result = false;
}
else if (bytesToSend <= 0)
{
if (LogFilter.logError)
{
Debug.LogError("ChannelBuffer:SendBytes cannot send zero bytes");
}
result = false;
}
else if (bytesToSend > _maxPacketSize)
@ -243,6 +261,8 @@ namespace QuantumUNET.Transport
result = SendFragmentBytes(bytes, bytesToSend);
}
else
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
@ -253,6 +273,7 @@ namespace QuantumUNET.Transport
" bytes on channel:",
_channelId
}));
}
result = false;
}
}
@ -272,9 +293,12 @@ namespace QuantumUNET.Transport
else if (_pendingPackets.Count >= _maxPendingPacketCount)
{
if (!_isBroken)
{
if (LogFilter.logError)
{
Debug.LogError("ChannelBuffer buffer limit of " + _pendingPackets.Count + " packets reached.");
}
}
_isBroken = true;
result = false;
}
@ -286,8 +310,11 @@ namespace QuantumUNET.Transport
}
}
else if (!_currentPacket.SendToTransport(_connection, _channelId))
{
if (LogFilter.logError)
{
Debug.Log("ChannelBuffer SendBytes no space on unreliable channel " + _channelId);
}
result = false;
}
else
@ -352,8 +379,11 @@ namespace QuantumUNET.Transport
_pendingPacketCount--;
FreePacket(channelPacket);
if (_isBroken && _pendingPackets.Count < _maxPendingPacketCount / 2)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("ChannelBuffer recovered from overflow but data was lost.");
}
_isBroken = false;
}
}

View File

@ -0,0 +1,82 @@
using System;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET
{
internal struct QSBChannelPacket
{
public QSBChannelPacket(int packetSize, bool isReliable)
{
this.m_Position = 0;
this.m_Buffer = new byte[packetSize];
this.m_IsReliable = isReliable;
}
public void Reset()
{
this.m_Position = 0;
}
public bool IsEmpty()
{
return this.m_Position == 0;
}
public void Write(byte[] bytes, int numBytes)
{
Array.Copy(bytes, 0, this.m_Buffer, this.m_Position, numBytes);
this.m_Position += numBytes;
}
public bool HasSpace(int numBytes)
{
return this.m_Position + numBytes <= this.m_Buffer.Length;
}
public bool SendToTransport(QSBNetworkConnection conn, int channelId)
{
bool result = true;
byte b;
if (!conn.TransportSend(this.m_Buffer, (int)((ushort)this.m_Position), channelId, out b))
{
if (!this.m_IsReliable || b != 4)
{
Debug.LogError(string.Concat(new object[]
{
"Failed to send internal buffer channel:",
channelId,
" bytesToSend:",
this.m_Position
}));
result = false;
}
}
if (b != 0)
{
if (this.m_IsReliable && b == 4)
{
return false;
}
Debug.LogError(string.Concat(new object[]
{
"Send Error: ",
(NetworkError)b,
" channel:",
channelId,
" bytesToSend:",
this.m_Position
}));
result = false;
}
this.m_Position = 0;
return result;
}
private int m_Position;
private byte[] m_Buffer;
private bool m_IsReliable;
}
}

View File

@ -1,6 +1,5 @@
using QuantumUNET.Components;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
@ -9,6 +8,18 @@ namespace QuantumUNET
{
public class QSBClientScene
{
private static bool HasMigrationPending() => reconnectId != -1;
public static void SetReconnectId(int newReconnectId, QSBPeerInfoMessage[] peers)
{
reconnectId = newReconnectId;
s_Peers = peers;
if (LogFilter.logDebug)
{
Debug.Log("ClientScene::SetReconnectId: " + newReconnectId);
}
}
internal static void SetNotReady() => ready = false;
public static List<QSBPlayerController> localPlayers { get; private set; } = new List<QSBPlayerController>();
@ -43,7 +54,7 @@ namespace QuantumUNET
{
player = null;
bool result;
if (playerControllerId >= localPlayers.Count)
if ((int)playerControllerId >= localPlayers.Count)
{
if (LogFilter.logWarn)
{
@ -51,7 +62,7 @@ namespace QuantumUNET
}
result = false;
}
else if (localPlayers[playerControllerId] == null)
else if (localPlayers[(int)playerControllerId] == null)
{
if (LogFilter.logWarn)
{
@ -61,7 +72,7 @@ namespace QuantumUNET
}
else
{
player = localPlayers[playerControllerId];
player = localPlayers[(int)playerControllerId];
result = (player.Gameobject != null);
}
return result;
@ -73,13 +84,13 @@ namespace QuantumUNET
{
Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId : " + playerControllerId);
}
if (playerControllerId >= localPlayers.Count)
if ((int)playerControllerId >= localPlayers.Count)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId higher than expected: " + playerControllerId);
}
while (playerControllerId >= localPlayers.Count)
while ((int)playerControllerId >= localPlayers.Count)
{
localPlayers.Add(new QSBPlayerController());
}
@ -90,7 +101,7 @@ namespace QuantumUNET
PlayerControllerId = playerControllerId,
UnetView = view
};
localPlayers[playerControllerId] = playerController;
localPlayers[(int)playerControllerId] = playerController;
readyConnection.SetPlayerController(playerController);
}
@ -102,11 +113,16 @@ namespace QuantumUNET
{
bool result;
if (playerControllerId < 0)
{
if (LogFilter.logError)
{
Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is negative");
}
result = false;
}
else if (playerControllerId > 32)
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
@ -115,6 +131,7 @@ namespace QuantumUNET
" is too high, max is ",
32
}));
}
result = false;
}
else
@ -126,7 +143,7 @@ namespace QuantumUNET
Debug.LogWarning("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is unusually high");
}
}
while (playerControllerId >= localPlayers.Count)
while ((int)playerControllerId >= localPlayers.Count)
{
localPlayers.Add(new QSBPlayerController());
}
@ -177,7 +194,7 @@ namespace QuantumUNET
var networkWriter = new QSBNetworkWriter();
extraMessage.Serialize(networkWriter);
addPlayerMessage.msgData = networkWriter.ToArray();
addPlayerMessage.msgSize = networkWriter.Position;
addPlayerMessage.msgSize = (int)networkWriter.Position;
}
readyConnection.Send(37, addPlayerMessage);
result = true;
@ -207,8 +224,8 @@ namespace QuantumUNET
};
readyConnection.Send(38, removePlayerMessage);
readyConnection.RemovePlayerController(playerControllerId);
localPlayers[playerControllerId] = new QSBPlayerController();
Object.Destroy(playerController.Gameobject);
localPlayers[(int)playerControllerId] = new QSBPlayerController();
UnityEngine.Object.Destroy(playerController.Gameobject);
result = true;
}
else
@ -329,29 +346,29 @@ namespace QuantumUNET
{
if (localClient)
{
client.RegisterHandlerSafe(1, new QSBNetworkMessageDelegate(OnLocalClientObjectDestroy));
client.RegisterHandlerSafe(13, new QSBNetworkMessageDelegate(OnLocalClientObjectHide));
client.RegisterHandlerSafe(3, new QSBNetworkMessageDelegate(OnLocalClientObjectSpawn));
client.RegisterHandlerSafe(10, new QSBNetworkMessageDelegate(OnLocalClientObjectSpawnScene));
client.RegisterHandlerSafe(15, new QSBNetworkMessageDelegate(OnClientAuthority));
client.RegisterHandlerSafe((short)1, new QSBNetworkMessageDelegate(OnLocalClientObjectDestroy));
client.RegisterHandlerSafe((short)13, new QSBNetworkMessageDelegate(OnLocalClientObjectHide));
client.RegisterHandlerSafe((short)3, new QSBNetworkMessageDelegate(OnLocalClientObjectSpawn));
client.RegisterHandlerSafe((short)10, new QSBNetworkMessageDelegate(OnLocalClientObjectSpawnScene));
client.RegisterHandlerSafe((short)15, new QSBNetworkMessageDelegate(OnClientAuthority));
}
else
{
client.RegisterHandlerSafe(3, new QSBNetworkMessageDelegate(OnObjectSpawn));
client.RegisterHandlerSafe(10, new QSBNetworkMessageDelegate(OnObjectSpawnScene));
client.RegisterHandlerSafe(12, new QSBNetworkMessageDelegate(OnObjectSpawnFinished));
client.RegisterHandlerSafe(1, new QSBNetworkMessageDelegate(OnObjectDestroy));
client.RegisterHandlerSafe(13, new QSBNetworkMessageDelegate(OnObjectDestroy));
client.RegisterHandlerSafe(8, new QSBNetworkMessageDelegate(OnUpdateVarsMessage));
client.RegisterHandlerSafe(4, new QSBNetworkMessageDelegate(OnOwnerMessage));
client.RegisterHandlerSafe(9, new QSBNetworkMessageDelegate(OnSyncListMessage));
client.RegisterHandlerSafe(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
client.RegisterHandlerSafe(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
client.RegisterHandlerSafe(15, new QSBNetworkMessageDelegate(OnClientAuthority));
client.RegisterHandlerSafe((short)3, new QSBNetworkMessageDelegate(OnObjectSpawn));
client.RegisterHandlerSafe((short)10, new QSBNetworkMessageDelegate(OnObjectSpawnScene));
client.RegisterHandlerSafe((short)12, new QSBNetworkMessageDelegate(OnObjectSpawnFinished));
client.RegisterHandlerSafe((short)1, new QSBNetworkMessageDelegate(OnObjectDestroy));
client.RegisterHandlerSafe((short)13, new QSBNetworkMessageDelegate(OnObjectDestroy));
client.RegisterHandlerSafe((short)8, new QSBNetworkMessageDelegate(OnUpdateVarsMessage));
client.RegisterHandlerSafe((short)4, new QSBNetworkMessageDelegate(OnOwnerMessage));
client.RegisterHandlerSafe((short)9, new QSBNetworkMessageDelegate(OnSyncListMessage));
client.RegisterHandlerSafe((short)40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
client.RegisterHandlerSafe((short)41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
client.RegisterHandlerSafe((short)15, new QSBNetworkMessageDelegate(OnClientAuthority));
}
client.RegisterHandlerSafe(2, new QSBNetworkMessageDelegate(OnRPCMessage));
client.RegisterHandlerSafe(7, new QSBNetworkMessageDelegate(OnSyncEventMessage));
client.RegisterHandlerSafe(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
client.RegisterHandlerSafe((short)2, new QSBNetworkMessageDelegate(OnRPCMessage));
client.RegisterHandlerSafe((short)7, new QSBNetworkMessageDelegate(OnSyncEventMessage));
client.RegisterHandlerSafe((short)42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
}
internal static string GetStringForAssetId(NetworkHash128 assetId)
@ -376,11 +393,11 @@ namespace QuantumUNET
public static void RegisterPrefab(GameObject prefab) => QSBNetworkScene.RegisterPrefab(prefab);
public static void RegisterPrefab(GameObject prefab, QSBSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler) => QSBNetworkScene.RegisterPrefab(prefab, spawnHandler, unspawnHandler);
public static void RegisterPrefab(GameObject prefab, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler) => QSBNetworkScene.RegisterPrefab(prefab, spawnHandler, unspawnHandler);
public static void UnregisterPrefab(GameObject prefab) => QSBNetworkScene.UnregisterPrefab(prefab);
public static void RegisterSpawnHandler(NetworkHash128 assetId, QSBSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler) => QSBNetworkScene.RegisterSpawnHandler(assetId, spawnHandler, unspawnHandler);
public static void RegisterSpawnHandler(NetworkHash128 assetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler) => QSBNetworkScene.RegisterSpawnHandler(assetId, spawnHandler, unspawnHandler);
public static void UnregisterSpawnHandler(NetworkHash128 assetId) => QSBNetworkScene.UnregisterSpawnHandler(assetId);
@ -432,7 +449,7 @@ namespace QuantumUNET
}
else if (QSBNetworkScene.GetPrefab(s_ObjectSpawnMessage.assetId, out var original))
{
var gameObject = Object.Instantiate<GameObject>(original, s_ObjectSpawnMessage.Position, s_ObjectSpawnMessage.Rotation);
GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(original, s_ObjectSpawnMessage.Position, s_ObjectSpawnMessage.Rotation);
component = gameObject.GetComponent<QSBNetworkIdentity>();
if (component == null)
{
@ -555,7 +572,7 @@ namespace QuantumUNET
{
if (networkIdentity.SceneId.IsEmpty())
{
Object.Destroy(networkIdentity.gameObject);
UnityEngine.Object.Destroy(networkIdentity.gameObject);
}
else
{
@ -646,7 +663,7 @@ namespace QuantumUNET
}
else if (LogFilter.logWarn)
{
var cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(num);
string cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(num);
Debug.LogWarningFormat("Could not find target object with netId:{0} for RPC call {1}", new object[]
{
networkInstanceId,
@ -794,6 +811,8 @@ namespace QuantumUNET
public const int ReconnectIdHost = 0;
private static QSBPeerInfoMessage[] s_Peers;
private static List<PendingOwner> s_PendingOwnerIds = new List<PendingOwner>();
private struct PendingOwner

View File

@ -1,5 +1,4 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System.Collections.Generic;
using UnityEngine;
@ -15,7 +14,7 @@ namespace QuantumUNET
PostInternalMessage(33);
m_Connected = false;
}
m_AsyncConnect = ConnectState.Disconnected;
m_AsyncConnect = QSBNetworkClient.ConnectState.Disconnected;
m_LocalServer.RemoveLocalClient(m_Connection);
}
@ -32,11 +31,11 @@ namespace QuantumUNET
}
m_LocalServer = QSBNetworkServer.instance;
m_Connection = new QSBULocalConnectionToServer(m_LocalServer);
SetHandlers(m_Connection);
base.SetHandlers(m_Connection);
m_Connection.connectionId = m_LocalServer.AddLocalClient(this);
m_AsyncConnect = ConnectState.Connected;
SetActive(true);
RegisterSystemHandlers(true);
m_AsyncConnect = QSBNetworkClient.ConnectState.Connected;
QSBNetworkClient.SetActive(true);
base.RegisterSystemHandlers(true);
if (generateConnectMsg)
{
PostInternalMessage(32);
@ -109,11 +108,11 @@ namespace QuantumUNET
}
s_InternalMessage.Reader.ReadInt16();
s_InternalMessage.ChannelId = t.channelId;
s_InternalMessage.Connection = connection;
s_InternalMessage.Connection = base.connection;
s_InternalMessage.MsgType = s_InternalMessage.Reader.ReadInt16();
m_Connection.InvokeHandler(s_InternalMessage);
m_FreeMessages.Push(t);
connection.lastMessageTime = Time.time;
base.connection.lastMessageTime = Time.time;
}
m_InternalMsgs = internalMsgs;
m_InternalMsgs.Clear();

198
QuantumUNET/QSBNetBuffer.cs Normal file
View File

@ -0,0 +1,198 @@
using System;
using UnityEngine;
namespace QuantumUNET
{
internal class QSBNetBuffer
{
public QSBNetBuffer()
{
m_Buffer = new byte[64];
}
public QSBNetBuffer(byte[] buffer)
{
m_Buffer = buffer;
}
public uint Position
{
get
{
return m_Pos;
}
}
public int Length
{
get
{
return m_Buffer.Length;
}
}
public byte ReadByte()
{
if ((ulong)m_Pos >= (ulong)((long)m_Buffer.Length))
{
throw new IndexOutOfRangeException("NetworkReader:ReadByte out of range:" + ToString());
}
return m_Buffer[(int)((UIntPtr)(m_Pos++))];
}
public void ReadBytes(byte[] buffer, uint count)
{
if ((ulong)(m_Pos + count) > (ulong)((long)m_Buffer.Length))
{
throw new IndexOutOfRangeException(string.Concat(new object[]
{
"NetworkReader:ReadBytes out of range: (",
count,
") ",
ToString()
}));
}
ushort num = 0;
while ((uint)num < count)
{
buffer[(int)num] = m_Buffer[(int)((UIntPtr)(m_Pos + (uint)num))];
num += 1;
}
m_Pos += count;
}
internal ArraySegment<byte> AsArraySegment()
{
return new ArraySegment<byte>(m_Buffer, 0, (int)m_Pos);
}
public void WriteByte(byte value)
{
WriteCheckForSpace(1);
m_Buffer[(int)((UIntPtr)m_Pos)] = value;
m_Pos += 1U;
}
public void WriteByte2(byte value0, byte value1)
{
WriteCheckForSpace(2);
m_Buffer[(int)((UIntPtr)m_Pos)] = value0;
m_Buffer[(int)((UIntPtr)(m_Pos + 1U))] = value1;
m_Pos += 2U;
}
public void WriteByte4(byte value0, byte value1, byte value2, byte value3)
{
WriteCheckForSpace(4);
m_Buffer[(int)((UIntPtr)m_Pos)] = value0;
m_Buffer[(int)((UIntPtr)(m_Pos + 1U))] = value1;
m_Buffer[(int)((UIntPtr)(m_Pos + 2U))] = value2;
m_Buffer[(int)((UIntPtr)(m_Pos + 3U))] = value3;
m_Pos += 4U;
}
public void WriteByte8(byte value0, byte value1, byte value2, byte value3, byte value4, byte value5, byte value6, byte value7)
{
WriteCheckForSpace(8);
m_Buffer[(int)((UIntPtr)m_Pos)] = value0;
m_Buffer[(int)((UIntPtr)(m_Pos + 1U))] = value1;
m_Buffer[(int)((UIntPtr)(m_Pos + 2U))] = value2;
m_Buffer[(int)((UIntPtr)(m_Pos + 3U))] = value3;
m_Buffer[(int)((UIntPtr)(m_Pos + 4U))] = value4;
m_Buffer[(int)((UIntPtr)(m_Pos + 5U))] = value5;
m_Buffer[(int)((UIntPtr)(m_Pos + 6U))] = value6;
m_Buffer[(int)((UIntPtr)(m_Pos + 7U))] = value7;
m_Pos += 8U;
}
public void WriteBytesAtOffset(byte[] buffer, ushort targetOffset, ushort count)
{
uint num = (uint)(count + targetOffset);
WriteCheckForSpace((ushort)num);
if (targetOffset == 0 && (int)count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)m_Pos);
}
else
{
for (int i = 0; i < (int)count; i++)
{
m_Buffer[(int)targetOffset + i] = buffer[i];
}
}
if (num > m_Pos)
{
m_Pos = num;
}
}
public void WriteBytes(byte[] buffer, ushort count)
{
WriteCheckForSpace(count);
if ((int)count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)m_Pos);
}
else
{
for (int i = 0; i < (int)count; i++)
{
m_Buffer[(int)(checked((IntPtr)(unchecked((ulong)m_Pos + (ulong)((long)i)))))] = buffer[i];
}
}
m_Pos += (uint)count;
}
private void WriteCheckForSpace(ushort count)
{
if ((ulong)(m_Pos + (uint)count) >= (ulong)((long)m_Buffer.Length))
{
int num = (int)Math.Ceiling((double)((float)m_Buffer.Length * 1.5f));
while ((ulong)(m_Pos + (uint)count) >= (ulong)((long)num))
{
num = (int)Math.Ceiling((double)((float)num * 1.5f));
if (num > 134217728)
{
Debug.LogWarning("NetworkBuffer size is " + num + " bytes!");
}
}
byte[] array = new byte[num];
m_Buffer.CopyTo(array, 0);
m_Buffer = array;
}
}
public void FinishMessage()
{
ushort num = (ushort)(m_Pos - 4U);
m_Buffer[0] = (byte)(num & 255);
m_Buffer[1] = (byte)(num >> 8 & 255);
}
public void SeekZero()
{
m_Pos = 0U;
}
public void Replace(byte[] buffer)
{
m_Buffer = buffer;
m_Pos = 0U;
}
public override string ToString()
{
return string.Format("NetBuf sz:{0} pos:{1}", m_Buffer.Length, m_Pos);
}
private byte[] m_Buffer;
private uint m_Pos;
private const int k_InitialSize = 64;
private const float k_GrowthFactor = 1.5f;
private const int k_BufferSizeWarning = 134217728;
}
}

View File

@ -1,6 +1,5 @@
using OWML.Logging;
using QuantumUNET.Components;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
@ -78,7 +77,7 @@ namespace QuantumUNET
}
}
writer.FinishMessage();
QSBNetworkServer.SendWriterToReady(gameObject, writer, channelId);
QSBNetworkServer.SendWriterToReady(base.gameObject, writer, channelId);
}
protected void SendTargetRPCInternal(QSBNetworkConnection conn, QSBNetworkWriter writer, int channelId, string rpcName)
@ -435,7 +434,7 @@ namespace QuantumUNET
Debug.Log(string.Concat(new object[]
{
"SetSyncVar GameObject ",
GetType().Name,
base.GetType().Name,
" bit [",
dirtyBit,
"] netfieldId:",

View File

@ -1,6 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET
{
@ -18,7 +20,13 @@ namespace QuantumUNET
}
}
public Dictionary<string, int> scripts { get; } = new Dictionary<string, int>();
public Dictionary<string, int> scripts
{
get
{
return this.m_Scripts;
}
}
public static bool scriptCRCCheck
{
@ -34,12 +42,12 @@ namespace QuantumUNET
public static void ReinitializeScriptCRCs(Assembly callingAssembly)
{
singleton.scripts.Clear();
foreach (var type in callingAssembly.GetTypes())
singleton.m_Scripts.Clear();
foreach (Type type in callingAssembly.GetTypes())
{
if (type.GetBaseType() == typeof(QSBNetworkBehaviour))
{
var method = type.GetMethod(".cctor", BindingFlags.Static);
MethodInfo method = type.GetMethod(".cctor", BindingFlags.Static);
if (method != null)
{
method.Invoke(null, new object[0]);
@ -48,22 +56,33 @@ namespace QuantumUNET
}
}
public static void RegisterBehaviour(string name, int channel) => singleton.scripts[name] = channel;
public static void RegisterBehaviour(string name, int channel)
{
singleton.m_Scripts[name] = channel;
}
internal static bool Validate(QSBCRCMessageEntry[] scripts, int numChannels) => singleton.ValidateInternal(scripts, numChannels);
internal static bool Validate(QSBCRCMessageEntry[] scripts, int numChannels)
{
return singleton.ValidateInternal(scripts, numChannels);
}
private bool ValidateInternal(QSBCRCMessageEntry[] remoteScripts, int numChannels)
{
bool result;
if (scripts.Count != remoteScripts.Length)
if (this.m_Scripts.Count != remoteScripts.Length)
{
if (LogFilter.logWarn)
{
Debug.LogWarning("Network configuration mismatch detected. The number of networked scripts on the client does not match the number of networked scripts on the server. This could be caused by lazy loading of scripts on the client. This warning can be disabled by the checkbox in NetworkManager Script CRC Check.");
Dump(remoteScripts);
}
this.Dump(remoteScripts);
result = false;
}
else
{
foreach (var crcmessageEntry in remoteScripts)
foreach (QSBCRCMessageEntry crcmessageEntry in remoteScripts)
{
if (LogFilter.logDebug)
{
Debug.Log(string.Concat(new object[]
{
@ -72,10 +91,13 @@ namespace QuantumUNET
" Channel: ",
crcmessageEntry.channel
}));
if (scripts.ContainsKey(crcmessageEntry.name))
}
if (this.m_Scripts.ContainsKey(crcmessageEntry.name))
{
var num = scripts[crcmessageEntry.name];
if (num != crcmessageEntry.channel)
int num = this.m_Scripts[crcmessageEntry.name];
if (num != (int)crcmessageEntry.channel)
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
@ -86,11 +108,14 @@ namespace QuantumUNET
" RemoteChannel: ",
crcmessageEntry.channel
}));
Dump(remoteScripts);
}
this.Dump(remoteScripts);
return false;
}
}
if (crcmessageEntry.channel >= numChannels)
if ((int)crcmessageEntry.channel >= numChannels)
{
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
{
@ -99,7 +124,8 @@ namespace QuantumUNET
" Channel: ",
crcmessageEntry.channel
}));
Dump(remoteScripts);
}
this.Dump(remoteScripts);
return false;
}
}
@ -110,17 +136,17 @@ namespace QuantumUNET
private void Dump(QSBCRCMessageEntry[] remoteScripts)
{
foreach (var text in scripts.Keys)
foreach (string text in this.m_Scripts.Keys)
{
Debug.Log(string.Concat(new object[]
{
"CRC Local Dump ",
text,
" : ",
scripts[text]
this.m_Scripts[text]
}));
}
foreach (var crcmessageEntry in remoteScripts)
foreach (QSBCRCMessageEntry crcmessageEntry in remoteScripts)
{
Debug.Log(string.Concat(new object[]
{
@ -133,6 +159,9 @@ namespace QuantumUNET
}
internal static QSBNetworkCRC s_Singleton;
private Dictionary<string, int> m_Scripts = new Dictionary<string, int>();
private bool m_ScriptCRCCheck;
}
}

View File

@ -1,6 +1,5 @@
using OWML.Logging;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Net;
@ -31,25 +30,82 @@ namespace QuantumUNET
RegisterSystemHandlers(false);
}
public static List<QSBNetworkClient> allClients { get; private set; } = new List<QSBNetworkClient>();
public static List<QSBNetworkClient> allClients
{
get
{
return s_Clients;
}
}
public static bool active { get; private set; }
public static bool active
{
get
{
return s_IsActive;
}
}
internal void SetHandlers(QSBNetworkConnection conn) => conn.SetHandlers(m_MessageHandlers);
internal void SetHandlers(QSBNetworkConnection conn)
{
conn.SetHandlers(m_MessageHandlers);
}
public string serverIp { get; private set; } = "";
public string serverIp
{
get
{
return m_ServerIp;
}
}
public int serverPort { get; private set; }
public int serverPort
{
get
{
return m_ServerPort;
}
}
public QSBNetworkConnection connection => m_Connection;
public QSBNetworkConnection connection
{
get
{
return m_Connection;
}
}
internal int hostId { get; private set; } = -1;
internal int hostId
{
get
{
return m_ClientId;
}
}
public Dictionary<short, QSBNetworkMessageDelegate> handlers => m_MessageHandlers.GetHandlers();
public Dictionary<short, QSBNetworkMessageDelegate> handlers
{
get
{
return m_MessageHandlers.GetHandlers();
}
}
public int numChannels => hostTopology.DefaultConfig.ChannelCount;
public int numChannels
{
get
{
return m_HostTopology.DefaultConfig.ChannelCount;
}
}
public HostTopology hostTopology { get; private set; }
public HostTopology hostTopology
{
get
{
return m_HostTopology;
}
}
public int hostPort
{
@ -71,21 +127,36 @@ namespace QuantumUNET
}
}
public bool isConnected => m_AsyncConnect == ConnectState.Connected;
public bool isConnected
{
get
{
return m_AsyncConnect == ConnectState.Connected;
}
}
public Type networkConnectionClass { get; private set; } = typeof(QSBNetworkConnection);
public Type networkConnectionClass
{
get
{
return m_NetworkConnectionClass;
}
}
public void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection => networkConnectionClass = typeof(T);
public void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection
{
m_NetworkConnectionClass = typeof(T);
}
public bool Configure(ConnectionConfig config, int maxConnections)
{
var topology = new HostTopology(config, maxConnections);
HostTopology topology = new HostTopology(config, maxConnections);
return Configure(topology);
}
public bool Configure(HostTopology topology)
{
hostTopology = topology;
m_HostTopology = topology;
return true;
}
@ -124,16 +195,16 @@ namespace QuantumUNET
QSBClientScene.ClearLocalPlayers();
m_Connection.Disconnect();
m_Connection = null;
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
this.serverPort = serverPort;
m_ClientId = NetworkTransport.AddHost(m_HostTopology, m_HostPort);
m_ServerPort = serverPort;
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
this.serverIp = serverIp;
m_ServerIp = serverIp;
m_AsyncConnect = ConnectState.Resolved;
}
else if (serverIp.Equals("127.0.0.1") || serverIp.Equals("localhost"))
{
this.serverIp = "127.0.0.1";
m_ServerIp = "127.0.0.1";
m_AsyncConnect = ConnectState.Resolved;
}
else
@ -179,7 +250,7 @@ namespace QuantumUNET
QSBClientScene.ClearLocalPlayers();
m_Connection.Disconnect();
m_Connection = null;
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
m_ClientId = NetworkTransport.AddHost(m_HostTopology, m_HostPort);
if (secureTunnelEndPoint == null)
{
if (LogFilter.logError)
@ -200,11 +271,11 @@ namespace QuantumUNET
}
else
{
var fullName = secureTunnelEndPoint.GetType().FullName;
string fullName = secureTunnelEndPoint.GetType().FullName;
if (fullName == "System.Net.IPEndPoint")
{
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
IPEndPoint ipendPoint = (IPEndPoint)secureTunnelEndPoint;
this.Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
result = (m_AsyncConnect != ConnectState.Failed);
}
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint")
@ -218,12 +289,12 @@ namespace QuantumUNET
}
else
{
byte b = 0;
m_RemoteEndPoint = secureTunnelEndPoint;
m_AsyncConnect = ConnectState.Connecting;
byte b;
try
{
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(m_ClientId, m_RemoteEndPoint, 0, out b);
}
catch (Exception arg)
{
@ -245,9 +316,9 @@ namespace QuantumUNET
}
else
{
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(networkConnectionClass);
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(m_NetworkConnectionClass);
m_Connection.SetHandlers(m_MessageHandlers);
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
m_Connection.Initialize(m_ServerIp, m_ClientId, m_ClientConnectionId, m_HostTopology);
result = true;
}
}
@ -266,7 +337,7 @@ namespace QuantumUNET
private static bool IsValidIpV6(string address)
{
foreach (var c in address)
foreach (char c in address)
{
if (c != ':' && (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
{
@ -286,20 +357,20 @@ namespace QuantumUNET
":",
serverPort
}));
this.serverPort = serverPort;
m_ServerPort = serverPort;
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
this.serverIp = serverIp;
m_ServerIp = serverIp;
m_AsyncConnect = ConnectState.Resolved;
}
else if (serverIp.Equals("127.0.0.1") || serverIp.Equals("localhost"))
{
this.serverIp = "127.0.0.1";
m_ServerIp = "127.0.0.1";
m_AsyncConnect = ConnectState.Resolved;
}
else if (serverIp.IndexOf(":") != -1 && IsValidIpV6(serverIp))
{
this.serverIp = serverIp;
m_ServerIp = serverIp;
m_AsyncConnect = ConnectState.Resolved;
}
else
@ -314,7 +385,7 @@ namespace QuantumUNET
public void Connect(EndPoint secureTunnelEndPoint)
{
//bool usePlatformSpecificProtocols = NetworkTransport.DoesEndPointUsePlatformProtocols(secureTunnelEndPoint);
var usePlatformSpecificProtocols = false;
bool usePlatformSpecificProtocols = false;
PrepareForConnect(usePlatformSpecificProtocols);
if (LogFilter.logDebug)
{
@ -338,11 +409,11 @@ namespace QuantumUNET
}
else
{
var fullName = secureTunnelEndPoint.GetType().FullName;
string fullName = secureTunnelEndPoint.GetType().FullName;
if (fullName == "System.Net.IPEndPoint")
{
var ipendPoint = (IPEndPoint)secureTunnelEndPoint;
Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
IPEndPoint ipendPoint = (IPEndPoint)secureTunnelEndPoint;
this.Connect(ipendPoint.Address.ToString(), ipendPoint.Port);
}
else if (fullName != "UnityEngine.XboxOne.XboxOneEndPoint" && fullName != "UnityEngine.PS4.SceEndPoint" && fullName != "UnityEngine.PSVita.SceEndPoint")
{
@ -359,7 +430,7 @@ namespace QuantumUNET
m_AsyncConnect = ConnectState.Connecting;
try
{
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(hostId, m_RemoteEndPoint, 0, out b);
m_ClientConnectionId = NetworkTransport.ConnectEndPoint(m_ClientId, m_RemoteEndPoint, 0, out b);
}
catch (Exception arg)
{
@ -380,36 +451,39 @@ namespace QuantumUNET
}
else
{
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(networkConnectionClass);
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(m_NetworkConnectionClass);
m_Connection.SetHandlers(m_MessageHandlers);
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
m_Connection.Initialize(m_ServerIp, m_ClientId, m_ClientConnectionId, m_HostTopology);
}
}
}
}
private void PrepareForConnect() => PrepareForConnect(false);
private void PrepareForConnect()
{
PrepareForConnect(false);
}
private void PrepareForConnect(bool usePlatformSpecificProtocols)
{
SetActive(true);
RegisterSystemHandlers(false);
if (hostTopology == null)
if (m_HostTopology == null)
{
var connectionConfig = new ConnectionConfig();
ConnectionConfig connectionConfig = new ConnectionConfig();
connectionConfig.AddChannel(QosType.ReliableSequenced);
connectionConfig.AddChannel(QosType.Unreliable);
connectionConfig.UsePlatformSpecificProtocols = usePlatformSpecificProtocols;
hostTopology = new HostTopology(connectionConfig, 8);
m_HostTopology = new HostTopology(connectionConfig, 8);
}
if (m_UseSimulator)
{
var num = (m_SimulatedLatency / 3) - 1;
int num = m_SimulatedLatency / 3 - 1;
if (num < 1)
{
num = 1;
}
var num2 = m_SimulatedLatency * 3;
int num2 = m_SimulatedLatency * 3;
ModConsole.OwmlConsole.WriteLine(string.Concat(new object[]
{
"AddHost Using Simulator ",
@ -417,11 +491,11 @@ namespace QuantumUNET
"/",
num2
}));
hostId = NetworkTransport.AddHostWithSimulator(hostTopology, num, num2, m_HostPort);
m_ClientId = NetworkTransport.AddHostWithSimulator(m_HostTopology, num, num2, m_HostPort);
}
else
{
hostId = NetworkTransport.AddHost(hostTopology, m_HostPort);
m_ClientId = NetworkTransport.AddHost(m_HostTopology, m_HostPort);
}
}
@ -429,8 +503,8 @@ namespace QuantumUNET
{
try
{
var array = Dns.EndGetHostAddresses(ar);
var networkClient = (QSBNetworkClient)ar.AsyncState;
IPAddress[] array = Dns.EndGetHostAddresses(ar);
QSBNetworkClient networkClient = (QSBNetworkClient)ar.AsyncState;
if (array.Length == 0)
{
Debug.LogError("DNS lookup failed for:" + networkClient.m_RequestedServerHost);
@ -438,22 +512,22 @@ namespace QuantumUNET
}
else
{
networkClient.serverIp = array[0].ToString();
networkClient.m_ServerIp = array[0].ToString();
networkClient.m_AsyncConnect = ConnectState.Resolved;
Debug.Log(string.Concat(new string[]
{
"Async DNS Result:",
networkClient.serverIp,
networkClient.m_ServerIp,
" for ",
networkClient.m_RequestedServerHost,
": ",
networkClient.serverIp
networkClient.m_ServerIp
}));
}
}
catch (SocketException ex)
{
var networkClient2 = (QSBNetworkClient)ar.AsyncState;
QSBNetworkClient networkClient2 = (QSBNetworkClient)ar.AsyncState;
Debug.LogError("DNS resolution failed: " + ex.GetErrorCode());
Debug.LogError("Exception:" + ex);
networkClient2.m_AsyncConnect = ConnectState.Failed;
@ -464,7 +538,7 @@ namespace QuantumUNET
{
if (m_UseSimulator)
{
var num = m_SimulatedLatency / 3;
int num = m_SimulatedLatency / 3;
if (num < 1)
{
num = 1;
@ -476,16 +550,18 @@ namespace QuantumUNET
"/",
m_SimulatedLatency
}));
var conf = new ConnectionSimulatorConfig(num, m_SimulatedLatency, num, m_SimulatedLatency, m_PacketLoss);
m_ClientConnectionId = NetworkTransport.ConnectWithSimulator(hostId, serverIp, serverPort, 0, out var b, conf);
ConnectionSimulatorConfig conf = new ConnectionSimulatorConfig(num, m_SimulatedLatency, num, m_SimulatedLatency, m_PacketLoss);
byte b;
m_ClientConnectionId = NetworkTransport.ConnectWithSimulator(m_ClientId, m_ServerIp, m_ServerPort, 0, out b, conf);
}
else
{
m_ClientConnectionId = NetworkTransport.Connect(hostId, serverIp, serverPort, 0, out var b);
byte b;
m_ClientConnectionId = NetworkTransport.Connect(m_ClientId, m_ServerIp, m_ServerPort, 0, out b);
}
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(networkConnectionClass);
m_Connection = (QSBNetworkConnection)Activator.CreateInstance(m_NetworkConnectionClass);
m_Connection.SetHandlers(m_MessageHandlers);
m_Connection.Initialize(serverIp, hostId, m_ClientConnectionId, hostTopology);
m_Connection.Initialize(m_ServerIp, m_ClientId, m_ClientConnectionId, m_HostTopology);
}
public virtual void Disconnect()
@ -497,10 +573,10 @@ namespace QuantumUNET
m_Connection.Disconnect();
m_Connection.Dispose();
m_Connection = null;
if (hostId != -1)
if (m_ClientId != -1)
{
NetworkTransport.RemoveHost(hostId);
hostId = -1;
NetworkTransport.RemoveHost(m_ClientId);
m_ClientId = -1;
}
}
}
@ -669,15 +745,15 @@ namespace QuantumUNET
{
if (LogFilter.logDebug)
{
Debug.Log("Shutting down client " + hostId);
Debug.Log("Shutting down client " + m_ClientId);
}
if (hostId != -1)
if (m_ClientId != -1)
{
NetworkTransport.RemoveHost(hostId);
hostId = -1;
NetworkTransport.RemoveHost(m_ClientId);
m_ClientId = -1;
}
RemoveClient(this);
if (allClients.Count == 0)
if (s_Clients.Count == 0)
{
SetActive(false);
}
@ -685,7 +761,7 @@ namespace QuantumUNET
internal virtual void Update()
{
if (hostId != -1)
if (m_ClientId != -1)
{
switch (m_AsyncConnect)
{
@ -712,11 +788,14 @@ namespace QuantumUNET
m_StatResetTime = (int)Time.time;
}
}
var num = 0;
int num = 0;
byte b;
for (; ; )
{
var networkEventType = NetworkTransport.ReceiveFromHost(hostId, out var num2, out var channelId, m_MsgBuffer, (ushort)m_MsgBuffer.Length, out var numBytes, out b);
int num2;
int channelId;
int numBytes;
NetworkEventType networkEventType = NetworkTransport.ReceiveFromHost(m_ClientId, out num2, out channelId, m_MsgBuffer, (int)((ushort)m_MsgBuffer.Length), out numBytes, out b);
if (m_Connection != null)
{
m_Connection.LastError = (NetworkError)b;
@ -755,7 +834,7 @@ namespace QuantumUNET
{
if (b != 6)
{
GenerateDisconnectError(b);
GenerateDisconnectError((int)b);
}
}
QSBClientScene.HandleClientDisconnect(m_Connection);
@ -779,7 +858,7 @@ namespace QuantumUNET
{
goto Block_17;
}
if (hostId == -1)
if (m_ClientId == -1)
{
goto Block_19;
}
@ -789,10 +868,10 @@ namespace QuantumUNET
}
}
Block_10:
GenerateConnectError(b);
GenerateConnectError((int)b);
return;
Block_11:
GenerateDataError(b);
GenerateDataError((int)b);
return;
Block_17:
if (LogFilter.logDebug)
@ -837,21 +916,19 @@ namespace QuantumUNET
private void GenerateError(int error)
{
var handler = m_MessageHandlers.GetHandler(34);
QSBNetworkMessageDelegate handler = m_MessageHandlers.GetHandler(34);
if (handler == null)
{
handler = m_MessageHandlers.GetHandler(34);
}
if (handler != null)
{
var errorMessage = new QSBErrorMessage
{
errorCode = error
};
var buffer = new byte[200];
var writer = new QSBNetworkWriter(buffer);
QSBErrorMessage errorMessage = new QSBErrorMessage();
errorMessage.errorCode = error;
byte[] buffer = new byte[200];
QSBNetworkWriter writer = new QSBNetworkWriter(buffer);
errorMessage.Serialize(writer);
var reader = new QSBNetworkReader(buffer);
QSBNetworkReader reader = new QSBNetworkReader(buffer);
handler(new QSBNetworkMessage
{
MsgType = 34,
@ -909,13 +986,14 @@ namespace QuantumUNET
public int GetRTT()
{
int result;
if (hostId == -1)
if (m_ClientId == -1)
{
result = 0;
}
else
{
result = NetworkTransport.GetCurrentRTT(hostId, m_ClientConnectionId, out var b);
byte b;
result = NetworkTransport.GetCurrentRTT(m_ClientId, m_ClientConnectionId, out b);
}
return result;
}
@ -923,7 +1001,7 @@ namespace QuantumUNET
internal void RegisterSystemHandlers(bool localClient)
{
QSBClientScene.RegisterSystemHandlers(this, localClient);
RegisterHandlerSafe(14, new QSBNetworkMessageDelegate(OnCRC));
this.RegisterHandlerSafe(14, new QSBNetworkMessageDelegate(OnCRC));
}
private void OnCRC(QSBNetworkMessage netMsg)
@ -932,24 +1010,33 @@ namespace QuantumUNET
QSBNetworkCRC.Validate(s_CRCMessage.scripts, numChannels);
}
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler) => m_MessageHandlers.RegisterHandler(msgType, handler);
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler)
{
m_MessageHandlers.RegisterHandler(msgType, handler);
}
public void RegisterHandlerSafe(short msgType, QSBNetworkMessageDelegate handler) => m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
public void RegisterHandlerSafe(short msgType, QSBNetworkMessageDelegate handler)
{
m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
}
public void UnregisterHandler(short msgType) => m_MessageHandlers.UnregisterHandler(msgType);
public void UnregisterHandler(short msgType)
{
m_MessageHandlers.UnregisterHandler(msgType);
}
public static Dictionary<short, QSBNetworkConnection.PacketStat> GetTotalConnectionStats()
{
var dictionary = new Dictionary<short, QSBNetworkConnection.PacketStat>();
for (var i = 0; i < allClients.Count; i++)
Dictionary<short, QSBNetworkConnection.PacketStat> dictionary = new Dictionary<short, QSBNetworkConnection.PacketStat>();
for (int i = 0; i < s_Clients.Count; i++)
{
var networkClient = allClients[i];
var connectionStats = networkClient.GetConnectionStats();
foreach (var key in connectionStats.Keys)
QSBNetworkClient networkClient = s_Clients[i];
Dictionary<short, QSBNetworkConnection.PacketStat> connectionStats = networkClient.GetConnectionStats();
foreach (short key in connectionStats.Keys)
{
if (dictionary.ContainsKey(key))
{
var packetStat = dictionary[key];
QSBNetworkConnection.PacketStat packetStat = dictionary[key];
packetStat.count += connectionStats[key].count;
packetStat.bytes += connectionStats[key].bytes;
dictionary[key] = packetStat;
@ -963,46 +1050,61 @@ namespace QuantumUNET
return dictionary;
}
internal static void AddClient(QSBNetworkClient client) => allClients.Add(client);
internal static void AddClient(QSBNetworkClient client)
{
s_Clients.Add(client);
}
internal static bool RemoveClient(QSBNetworkClient client) => allClients.Remove(client);
internal static bool RemoveClient(QSBNetworkClient client)
{
return s_Clients.Remove(client);
}
internal static void UpdateClients()
{
for (var i = 0; i < allClients.Count; i++)
for (int i = 0; i < s_Clients.Count; i++)
{
if (allClients[i] != null)
if (s_Clients[i] != null)
{
allClients[i].Update();
s_Clients[i].Update();
}
else
{
allClients.RemoveAt(i);
s_Clients.RemoveAt(i);
}
}
}
public static void ShutdownAll()
{
while (allClients.Count != 0)
while (s_Clients.Count != 0)
{
allClients[0].Shutdown();
s_Clients[0].Shutdown();
}
allClients = new List<QSBNetworkClient>();
active = false;
s_Clients = new List<QSBNetworkClient>();
s_IsActive = false;
QSBClientScene.Shutdown();
}
internal static void SetActive(bool state)
{
if (!active && state)
if (!s_IsActive && state)
{
NetworkTransport.Init();
}
active = state;
s_IsActive = state;
}
private Type m_NetworkConnectionClass = typeof(QSBNetworkConnection);
private const int k_MaxEventsPerFrame = 500;
private static List<QSBNetworkClient> s_Clients = new List<QSBNetworkClient>();
private static bool s_IsActive;
private HostTopology m_HostTopology;
private int m_HostPort;
private bool m_UseSimulator;
@ -1010,6 +1112,13 @@ namespace QuantumUNET
private int m_SimulatedLatency;
private float m_PacketLoss;
private string m_ServerIp = "";
private int m_ServerPort;
private int m_ClientId = -1;
private int m_ClientConnectionId = -1;
private int m_StatResetTime;

View File

@ -1,7 +1,6 @@
using OWML.Logging;
using QuantumUNET.Components;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Text;
@ -48,7 +47,7 @@ namespace QuantumUNET
var bufferSize = packetSize;
if (channelQOS.QOS == QosType.ReliableFragmented || channelQOS.QOS == QosType.UnreliableFragmented)
{
bufferSize = hostTopology.DefaultConfig.FragmentSize * 128;
bufferSize = (int)(hostTopology.DefaultConfig.FragmentSize * 128);
}
m_Channels[i] = new QSBChannelBuffer(this, bufferSize, (byte)i, IsReliableQoS(channelQOS.QOS), IsSequencedQoS(channelQOS.QOS));
}
@ -103,7 +102,8 @@ namespace QuantumUNET
QSBClientScene.HandleClientDisconnect(this);
if (hostId != -1)
{
NetworkTransport.Disconnect(hostId, connectionId, out var b);
byte b;
NetworkTransport.Disconnect(hostId, connectionId, out b);
RemoveObservers();
}
}
@ -182,18 +182,18 @@ namespace QuantumUNET
internal void SetPlayerController(QSBPlayerController player)
{
while (player.PlayerControllerId >= PlayerControllers.Count)
while ((int)player.PlayerControllerId >= PlayerControllers.Count)
{
PlayerControllers.Add(new QSBPlayerController());
}
PlayerControllers[player.PlayerControllerId] = player;
PlayerControllers[(int)player.PlayerControllerId] = player;
}
internal void RemovePlayerController(short playerControllerId)
{
for (var i = PlayerControllers.Count; i >= 0; i--)
{
if (playerControllerId == i && playerControllerId == PlayerControllers[i].PlayerControllerId)
if ((int)playerControllerId == i && playerControllerId == PlayerControllers[i].PlayerControllerId)
{
PlayerControllers[i] = new QSBPlayerController();
return;
@ -263,9 +263,15 @@ namespace QuantumUNET
return SendWriter(m_Writer, channelId);
}
public virtual bool SendBytes(byte[] bytes, int numBytes, int channelId) => CheckChannel(channelId) && m_Channels[channelId].SendBytes(bytes, numBytes);
public virtual bool SendBytes(byte[] bytes, int numBytes, int channelId)
{
return CheckChannel(channelId) && m_Channels[channelId].SendBytes(bytes, numBytes);
}
public virtual bool SendWriter(QSBNetworkWriter writer, int channelId) => CheckChannel(channelId) && m_Channels[channelId].SendWriter(writer);
public virtual bool SendWriter(QSBNetworkWriter writer, int channelId)
{
return CheckChannel(channelId) && m_Channels[channelId].SendWriter(writer);
}
private void LogSend(byte[] bytes)
{
@ -273,7 +279,7 @@ namespace QuantumUNET
var num = networkReader.ReadUInt16();
var num2 = networkReader.ReadUInt16();
var stringBuilder = new StringBuilder();
for (var i = 4; i < 4 + num; i++)
for (var i = 4; i < (int)(4 + num); i++)
{
stringBuilder.AppendFormat("{0:X2}", bytes[i]);
if (i > 150)
@ -342,7 +348,7 @@ namespace QuantumUNET
{
var num = reader.ReadUInt16();
var num2 = reader.ReadInt16();
var array = reader.ReadBytes(num);
var array = reader.ReadBytes((int)num);
var reader2 = new QSBNetworkReader(array);
QSBNetworkMessageDelegate networkMessageDelegate = null;
if (m_MessageHandlersDict.ContainsKey(num2))

View File

@ -5,7 +5,7 @@ using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET.Transport
namespace QuantumUNET
{
public class QSBNetworkReader
{

View File

@ -7,13 +7,21 @@ namespace QuantumUNET
{
internal class QSBNetworkScene
{
private Dictionary<NetworkInstanceId, QSBNetworkIdentity> m_LocalObjects = new Dictionary<NetworkInstanceId, QSBNetworkIdentity>();
internal static Dictionary<NetworkHash128, GameObject> guidToPrefab { get; } = new Dictionary<NetworkHash128, GameObject>();
internal static Dictionary<NetworkHash128, QSBSpawnDelegate> spawnHandlers { get; } = new Dictionary<NetworkHash128, QSBSpawnDelegate>();
internal static Dictionary<NetworkHash128, SpawnDelegate> spawnHandlers { get; } = new Dictionary<NetworkHash128, SpawnDelegate>();
internal static Dictionary<NetworkHash128, UnSpawnDelegate> unspawnHandlers { get; } = new Dictionary<NetworkHash128, UnSpawnDelegate>();
internal Dictionary<NetworkInstanceId, QSBNetworkIdentity> localObjects { get; } = new Dictionary<NetworkInstanceId, QSBNetworkIdentity>();
internal Dictionary<NetworkInstanceId, QSBNetworkIdentity> localObjects
{
get
{
return m_LocalObjects;
}
}
internal void Shutdown()
{
@ -80,7 +88,7 @@ namespace QuantumUNET
if (localObjects.ContainsKey(netId))
{
var networkIdentity = localObjects[netId];
Object.Destroy(networkIdentity.gameObject);
UnityEngine.Object.Destroy(networkIdentity.gameObject);
result = localObjects.Remove(netId);
}
else
@ -90,7 +98,10 @@ namespace QuantumUNET
return result;
}
internal void ClearLocalObjects() => localObjects.Clear();
internal void ClearLocalObjects()
{
localObjects.Clear();
}
internal static void RegisterPrefab(GameObject prefab, NetworkHash128 newAssetId)
{
@ -161,7 +172,7 @@ namespace QuantumUNET
unspawnHandlers.Remove(assetId);
}
internal static void RegisterSpawnHandler(NetworkHash128 assetId, QSBSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
internal static void RegisterSpawnHandler(NetworkHash128 assetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
{
if (spawnHandler == null || unspawnHandler == null)
{
@ -194,7 +205,7 @@ namespace QuantumUNET
}
}
internal static void RegisterPrefab(GameObject prefab, QSBSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
internal static void RegisterPrefab(GameObject prefab, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
{
var component = prefab.GetComponent<QSBNetworkIdentity>();
if (component == null)
@ -216,7 +227,7 @@ namespace QuantumUNET
}
}
internal static bool GetSpawnHandler(NetworkHash128 assetId, out QSBSpawnDelegate handler)
internal static bool GetSpawnHandler(NetworkHash128 assetId, out SpawnDelegate handler)
{
bool result;
if (spawnHandlers.ContainsKey(assetId))
@ -259,7 +270,7 @@ namespace QuantumUNET
{
if (networkIdentity.SceneId.IsEmpty())
{
Object.Destroy(networkIdentity.gameObject);
UnityEngine.Object.Destroy(networkIdentity.gameObject);
}
else
{

View File

@ -1,7 +1,6 @@
using OWML.Logging;
using QuantumUNET.Components;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -22,19 +21,61 @@ namespace QuantumUNET
m_SimpleServerSimple = new ServerSimpleWrapper(this);
}
public static List<QSBNetworkConnection> localConnections => instance.m_LocalConnectionsFakeList;
public static List<QSBNetworkConnection> localConnections
{
get
{
return instance.m_LocalConnectionsFakeList;
}
}
public static int listenPort => instance.m_SimpleServerSimple.listenPort;
public static int listenPort
{
get
{
return instance.m_SimpleServerSimple.listenPort;
}
}
public static int serverHostId => instance.m_SimpleServerSimple.serverHostId;
public static int serverHostId
{
get
{
return instance.m_SimpleServerSimple.serverHostId;
}
}
public static ReadOnlyCollection<QSBNetworkConnection> connections => instance.m_SimpleServerSimple.connections;
public static ReadOnlyCollection<QSBNetworkConnection> connections
{
get
{
return instance.m_SimpleServerSimple.connections;
}
}
public static Dictionary<short, QSBNetworkMessageDelegate> handlers => instance.m_SimpleServerSimple.handlers;
public static Dictionary<short, QSBNetworkMessageDelegate> handlers
{
get
{
return instance.m_SimpleServerSimple.handlers;
}
}
public static HostTopology hostTopology => instance.m_SimpleServerSimple.hostTopology;
public static HostTopology hostTopology
{
get
{
return instance.m_SimpleServerSimple.hostTopology;
}
}
public static Dictionary<NetworkInstanceId, QSBNetworkIdentity> objects => instance.m_NetworkScene.localObjects;
public static Dictionary<NetworkInstanceId, QSBNetworkIdentity> objects
{
get
{
return instance.m_NetworkScene.localObjects;
}
}
public static bool dontListen { get; set; }
@ -71,9 +112,21 @@ namespace QuantumUNET
public static bool active { get; private set; }
public static bool localClientActive => instance.m_LocalClientActive;
public static bool localClientActive
{
get
{
return instance.m_LocalClientActive;
}
}
public static int numChannels => instance.m_SimpleServerSimple.hostTopology.DefaultConfig.ChannelCount;
public static int numChannels
{
get
{
return instance.m_SimpleServerSimple.hostTopology.DefaultConfig.ChannelCount;
}
}
public static float maxDelay
{
@ -87,13 +140,28 @@ namespace QuantumUNET
}
}
public static Type networkConnectionClass => instance.m_SimpleServerSimple.networkConnectionClass;
public static Type networkConnectionClass
{
get
{
return instance.m_SimpleServerSimple.networkConnectionClass;
}
}
public static void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection => instance.m_SimpleServerSimple.SetNetworkConnectionClass<T>();
public static void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection
{
instance.m_SimpleServerSimple.SetNetworkConnectionClass<T>();
}
public static bool Configure(ConnectionConfig config, int maxConnections) => instance.m_SimpleServerSimple.Configure(config, maxConnections);
public static bool Configure(ConnectionConfig config, int maxConnections)
{
return instance.m_SimpleServerSimple.Configure(config, maxConnections);
}
public static bool Configure(HostTopology topology) => instance.m_SimpleServerSimple.Configure(topology);
public static bool Configure(HostTopology topology)
{
return instance.m_SimpleServerSimple.Configure(topology);
}
public static void Reset()
{
@ -132,7 +200,10 @@ namespace QuantumUNET
maxPacketSize = hostTopology.DefaultConfig.PacketSize;
}
public static void ListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId) => instance.InternalListenRelay(relayIp, relayPort, netGuid, sourceId, nodeId);
public static void ListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId)
{
instance.InternalListenRelay(relayIp, relayPort, netGuid, sourceId, nodeId);
}
private void InternalListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId)
{
@ -141,9 +212,15 @@ namespace QuantumUNET
RegisterMessageHandlers();
}
public static bool Listen(int serverPort) => instance.InternalListen(null, serverPort);
public static bool Listen(int serverPort)
{
return instance.InternalListen(null, serverPort);
}
public static bool Listen(string ipAddress, int serverPort) => instance.InternalListen(ipAddress, serverPort);
public static bool Listen(string ipAddress, int serverPort)
{
return instance.InternalListen(ipAddress, serverPort);
}
internal bool InternalListen(string ipAddress, int serverPort)
{
@ -508,7 +585,10 @@ namespace QuantumUNET
return result;
}
public static void DisconnectAll() => instance.InternalDisconnectAll();
public static void DisconnectAll()
{
instance.InternalDisconnectAll();
}
internal void InternalDisconnectAll()
{
@ -610,7 +690,10 @@ namespace QuantumUNET
conn.Dispose();
}
private void OnData(QSBNetworkConnection conn, int receivedSize, int channelId) => conn.TransportReceive(m_SimpleServerSimple.messageBuffer, receivedSize, channelId);
private void OnData(QSBNetworkConnection conn, int receivedSize, int channelId)
{
conn.TransportReceive(m_SimpleServerSimple.messageBuffer, receivedSize, channelId);
}
private void GenerateConnectError(int error)
{
@ -651,10 +734,8 @@ namespace QuantumUNET
{
if (handlers.ContainsKey(34))
{
var errorMessage = new QSBErrorMessage
{
errorCode = error
};
var errorMessage = new QSBErrorMessage();
errorMessage.errorCode = error;
var writer = new QSBNetworkWriter();
errorMessage.Serialize(writer);
var reader = new QSBNetworkReader(writer);
@ -662,13 +743,25 @@ namespace QuantumUNET
}
}
public static void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler) => instance.m_SimpleServerSimple.RegisterHandler(msgType, handler);
public static void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler)
{
instance.m_SimpleServerSimple.RegisterHandler(msgType, handler);
}
public static void UnregisterHandler(short msgType) => instance.m_SimpleServerSimple.UnregisterHandler(msgType);
public static void UnregisterHandler(short msgType)
{
instance.m_SimpleServerSimple.UnregisterHandler(msgType);
}
public static void ClearHandlers() => instance.m_SimpleServerSimple.ClearHandlers();
public static void ClearHandlers()
{
instance.m_SimpleServerSimple.ClearHandlers();
}
public static void ClearSpawners() => QSBNetworkScene.ClearSpawners();
public static void ClearSpawners()
{
QSBNetworkScene.ClearSpawners();
}
public static void GetStatsOut(out int numMsgs, out int numBufferedMsgs, out int numBytes, out int lastBufferedPerSecond)
{
@ -681,7 +774,11 @@ namespace QuantumUNET
var networkConnection = connections[i];
if (networkConnection != null)
{
networkConnection.GetStatsOut(out var num, out var num2, out var num3, out var num4);
int num;
int num2;
int num3;
int num4;
networkConnection.GetStatsOut(out num, out num2, out num3, out num4);
numMsgs += num;
numBufferedMsgs += num2;
numBytes += num3;
@ -699,7 +796,9 @@ namespace QuantumUNET
var networkConnection = connections[i];
if (networkConnection != null)
{
networkConnection.GetStatsIn(out var num, out var num2);
int num;
int num2;
networkConnection.GetStatsIn(out num, out num2);
numMsgs += num;
numBytes += num2;
}
@ -747,12 +846,16 @@ namespace QuantumUNET
}
}
public static bool AddPlayerForConnection(QSBNetworkConnection conn, GameObject player, short playerControllerId) => instance.InternalAddPlayerForConnection(conn, player, playerControllerId);
public static bool AddPlayerForConnection(QSBNetworkConnection conn, GameObject player, short playerControllerId)
{
return instance.InternalAddPlayerForConnection(conn, player, playerControllerId);
}
internal bool InternalAddPlayerForConnection(QSBNetworkConnection conn, GameObject playerGameObject, short playerControllerId)
{
QSBNetworkIdentity networkIdentity;
bool result;
if (!GetNetworkIdentity(playerGameObject, out var networkIdentity))
if (!GetNetworkIdentity(playerGameObject, out networkIdentity))
{
if (LogFilter.logError)
{
@ -769,8 +872,9 @@ namespace QuantumUNET
}
else
{
QSBPlayerController playerController = null;
GameObject x = null;
if (conn.GetPlayerController(playerControllerId, out var playerController))
if (conn.GetPlayerController(playerControllerId, out playerController))
{
x = playerController.Gameobject;
}
@ -859,8 +963,9 @@ namespace QuantumUNET
private bool SetupLocalPlayerForConnection(QSBNetworkConnection conn, QSBNetworkIdentity uv, QSBPlayerController newPlayerController)
{
Debug.Log("NetworkServer SetupLocalPlayerForConnection netID:" + uv.NetId);
var ulocalConnectionToClient = conn as QSBULocalConnectionToClient;
bool result;
if (conn is QSBULocalConnectionToClient ulocalConnectionToClient)
if (ulocalConnectionToClient != null)
{
Debug.Log("NetworkServer AddPlayer handling ULocalConnectionToClient");
if (uv.NetId.IsEmpty())
@ -897,8 +1002,9 @@ namespace QuantumUNET
internal bool InternalReplacePlayerForConnection(QSBNetworkConnection conn, GameObject playerGameObject, short playerControllerId)
{
QSBNetworkIdentity networkIdentity;
bool result;
if (!GetNetworkIdentity(playerGameObject, out var networkIdentity))
if (!GetNetworkIdentity(playerGameObject, out networkIdentity))
{
if (LogFilter.logError)
{
@ -913,7 +1019,8 @@ namespace QuantumUNET
else
{
Debug.Log("NetworkServer ReplacePlayer");
if (conn.GetPlayerController(playerControllerId, out var playerController))
QSBPlayerController playerController;
if (conn.GetPlayerController(playerControllerId, out playerController))
{
playerController.UnetView.SetNotLocalPlayer();
playerController.UnetView.ClearClientOwner();
@ -965,7 +1072,10 @@ namespace QuantumUNET
return result;
}
public static void SetClientReady(QSBNetworkConnection conn) => instance.SetClientReadyInternal(conn);
public static void SetClientReady(QSBNetworkConnection conn)
{
instance.SetClientReadyInternal(conn);
}
internal void SetClientReadyInternal(QSBNetworkConnection conn)
{
@ -990,14 +1100,15 @@ namespace QuantumUNET
}
}
conn.isReady = true;
if (conn is QSBULocalConnectionToClient ulocalConnectionToClient)
var ulocalConnectionToClient = conn as QSBULocalConnectionToClient;
if (ulocalConnectionToClient != null)
{
Debug.Log("NetworkServer Ready handling ULocalConnectionToClient");
foreach (var networkIdentity in objects.Values)
{
if (networkIdentity != null && networkIdentity.gameObject != null)
{
var flag = networkIdentity.OnCheckObserver(conn);
bool flag = networkIdentity.OnCheckObserver(conn);
if (flag)
{
networkIdentity.AddObserver(conn);
@ -1022,10 +1133,8 @@ namespace QuantumUNET
conn.connectionId
}));
}
var objectSpawnFinishedMessage = new QSBObjectSpawnFinishedMessage
{
State = 0U
};
var objectSpawnFinishedMessage = new QSBObjectSpawnFinishedMessage();
objectSpawnFinishedMessage.State = 0U;
conn.Send(12, objectSpawnFinishedMessage);
foreach (var networkIdentity2 in objects.Values)
{
@ -1048,7 +1157,7 @@ namespace QuantumUNET
networkIdentity2.NetId
}));
}
var flag2 = networkIdentity2.OnCheckObserver(conn);
bool flag2 = networkIdentity2.OnCheckObserver(conn);
if (flag2)
{
networkIdentity2.AddObserver(conn);
@ -1089,7 +1198,10 @@ namespace QuantumUNET
}
}
public static void SetClientNotReady(QSBNetworkConnection conn) => instance.InternalSetClientNotReady(conn);
public static void SetClientNotReady(QSBNetworkConnection conn)
{
instance.InternalSetClientNotReady(conn);
}
internal void InternalSetClientNotReady(QSBNetworkConnection conn)
{
@ -1118,7 +1230,8 @@ namespace QuantumUNET
private static void OnRemovePlayerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage<QSBRemovePlayerMessage>(s_RemovePlayerMessage);
netMsg.Connection.GetPlayerController(s_RemovePlayerMessage.PlayerControllerId, out var playerController);
QSBPlayerController playerController = null;
netMsg.Connection.GetPlayerController(s_RemovePlayerMessage.PlayerControllerId, out playerController);
if (playerController != null)
{
netMsg.Connection.RemovePlayerController(s_RemovePlayerMessage.PlayerControllerId);
@ -1189,11 +1302,12 @@ namespace QuantumUNET
internal void SpawnObject(GameObject obj)
{
QSBNetworkIdentity networkIdentity;
if (!active)
{
ModConsole.OwmlConsole.WriteLine("Error - SpawnObject for " + obj + ", NetworkServer is not active. Cannot spawn objects without an active server.");
}
else if (!GetNetworkIdentity(obj, out var networkIdentity))
else if (!GetNetworkIdentity(obj, out networkIdentity))
{
Debug.LogError(string.Concat(new object[]
{
@ -1217,13 +1331,11 @@ namespace QuantumUNET
{
if (uv.SceneId.IsEmpty())
{
var objectSpawnMessage = new QSBObjectSpawnMessage
{
NetId = uv.NetId,
assetId = uv.AssetId,
Position = uv.transform.position,
Rotation = uv.transform.rotation
};
var objectSpawnMessage = new QSBObjectSpawnMessage();
objectSpawnMessage.NetId = uv.NetId;
objectSpawnMessage.assetId = uv.AssetId;
objectSpawnMessage.Position = uv.transform.position;
objectSpawnMessage.Rotation = uv.transform.rotation;
var networkWriter = new QSBNetworkWriter();
uv.UNetSerializeAllVars(networkWriter);
if (networkWriter.Position > 0)
@ -1241,12 +1353,10 @@ namespace QuantumUNET
}
else
{
var objectSpawnSceneMessage = new QSBObjectSpawnSceneMessage
{
NetId = uv.NetId,
SceneId = uv.SceneId,
Position = uv.transform.position
};
var objectSpawnSceneMessage = new QSBObjectSpawnSceneMessage();
objectSpawnSceneMessage.NetId = uv.NetId;
objectSpawnSceneMessage.SceneId = uv.SceneId;
objectSpawnSceneMessage.Position = uv.transform.position;
var networkWriter2 = new QSBNetworkWriter();
uv.UNetSerializeAllVars(networkWriter2);
if (networkWriter2.Position > 0)
@ -1306,25 +1416,30 @@ namespace QuantumUNET
private static void UnSpawnObject(GameObject obj)
{
QSBNetworkIdentity uv;
if (obj == null)
{
Debug.Log("NetworkServer UnspawnObject is null");
}
else if (GetNetworkIdentity(obj, out var uv))
else if (GetNetworkIdentity(obj, out uv))
{
UnSpawnObject(uv);
}
}
private static void UnSpawnObject(QSBNetworkIdentity uv) => DestroyObject(uv, false);
private static void UnSpawnObject(QSBNetworkIdentity uv)
{
DestroyObject(uv, false);
}
private static void DestroyObject(GameObject obj)
{
QSBNetworkIdentity uv;
if (obj == null)
{
Debug.Log("NetworkServer DestroyObject is null");
}
else if (GetNetworkIdentity(obj, out var uv))
else if (GetNetworkIdentity(obj, out uv))
{
DestroyObject(uv, true);
}
@ -1344,10 +1459,8 @@ namespace QuantumUNET
{
uv.ClientAuthorityOwner.RemoveOwnedObject(uv);
}
var objectDestroyMessage = new QSBObjectDestroyMessage
{
NetId = uv.NetId
};
var objectDestroyMessage = new QSBObjectDestroyMessage();
objectDestroyMessage.NetId = uv.NetId;
SendToObservers(uv.gameObject, 1, objectDestroyMessage);
uv.ClearObservers();
if (QSBNetworkClient.active && instance.m_LocalClientActive)
@ -1362,7 +1475,10 @@ namespace QuantumUNET
uv.MarkForReset();
}
public static void ClearLocalObjects() => objects.Clear();
public static void ClearLocalObjects()
{
objects.Clear();
}
public static void Spawn(GameObject obj)
{
@ -1372,7 +1488,10 @@ namespace QuantumUNET
}
}
private static bool CheckForPrefab(GameObject obj) => false;
private static bool CheckForPrefab(GameObject obj)
{
return false;
}
private static bool VerifyCanSpawn(GameObject obj)
{
@ -1441,7 +1560,8 @@ namespace QuantumUNET
{
if (VerifyCanSpawn(obj))
{
if (GetNetworkIdentity(obj, out var networkIdentity))
QSBNetworkIdentity networkIdentity;
if (GetNetworkIdentity(obj, out networkIdentity))
{
networkIdentity.SetDynamicAssetId(assetId);
}
@ -1449,9 +1569,15 @@ namespace QuantumUNET
}
}
public static void Destroy(GameObject obj) => DestroyObject(obj);
public static void Destroy(GameObject obj)
{
DestroyObject(obj);
}
public static void UnSpawn(GameObject obj) => UnSpawnObject(obj);
public static void UnSpawn(GameObject obj)
{
UnSpawnObject(obj);
}
internal bool InvokeBytes(QSBULocalConnectionToServer conn, byte[] buffer, int numBytes, int channelId)
{
@ -1501,7 +1627,10 @@ namespace QuantumUNET
public static GameObject FindLocalObject(NetworkInstanceId netId) => instance.m_NetworkScene.FindLocalObject(netId);
private static bool ValidateSceneObject(QSBNetworkIdentity netId) => netId.gameObject.hideFlags != HideFlags.NotEditable && netId.gameObject.hideFlags != HideFlags.HideAndDontSave && !netId.SceneId.IsEmpty();
private static bool ValidateSceneObject(QSBNetworkIdentity netId)
{
return netId.gameObject.hideFlags != HideFlags.NotEditable && netId.gameObject.hideFlags != HideFlags.HideAndDontSave && !netId.SceneId.IsEmpty();
}
public static bool SpawnObjects()
{
@ -1552,7 +1681,7 @@ namespace QuantumUNET
{
var crcmessage = new QSBCRCMessage();
var list = new List<QSBCRCMessageEntry>();
foreach (var text in QSBNetworkCRC.singleton.scripts.Keys)
foreach (string text in QSBNetworkCRC.singleton.scripts.Keys)
{
list.Add(new QSBCRCMessageEntry
{
@ -1601,17 +1730,35 @@ namespace QuantumUNET
m_Server = server;
}
public override void OnConnectError(int connectionId, byte error) => m_Server.GenerateConnectError(error);
public override void OnConnectError(int connectionId, byte error)
{
m_Server.GenerateConnectError((int)error);
}
public override void OnDataError(QSBNetworkConnection conn, byte error) => m_Server.GenerateDataError(conn, error);
public override void OnDataError(QSBNetworkConnection conn, byte error)
{
m_Server.GenerateDataError(conn, (int)error);
}
public override void OnDisconnectError(QSBNetworkConnection conn, byte error) => m_Server.GenerateDisconnectError(conn, error);
public override void OnDisconnectError(QSBNetworkConnection conn, byte error)
{
m_Server.GenerateDisconnectError(conn, (int)error);
}
public override void OnConnected(QSBNetworkConnection conn) => m_Server.OnConnected(conn);
public override void OnConnected(QSBNetworkConnection conn)
{
m_Server.OnConnected(conn);
}
public override void OnDisconnected(QSBNetworkConnection conn) => m_Server.OnDisconnected(conn);
public override void OnDisconnected(QSBNetworkConnection conn)
{
m_Server.OnDisconnected(conn);
}
public override void OnData(QSBNetworkConnection conn, int receivedSize, int channelId) => m_Server.OnData(conn, receivedSize, channelId);
public override void OnData(QSBNetworkConnection conn, int receivedSize, int channelId)
{
m_Server.OnData(conn, receivedSize, channelId);
}
private QSBNetworkServer m_Server;
}

View File

@ -1,5 +1,4 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@ -13,43 +12,112 @@ namespace QuantumUNET
{
public QSBNetworkServerSimple()
{
connections = new ReadOnlyCollection<QSBNetworkConnection>(m_Connections);
this.m_ConnectionsReadOnly = new ReadOnlyCollection<QSBNetworkConnection>(this.m_Connections);
}
public int listenPort { get; set; }
public int listenPort
{
get
{
return this.m_ListenPort;
}
set
{
this.m_ListenPort = value;
}
}
public int serverHostId { get; set; } = -1;
public int serverHostId
{
get
{
return this.m_ServerHostId;
}
set
{
this.m_ServerHostId = value;
}
}
public HostTopology hostTopology { get; private set; }
public HostTopology hostTopology
{
get
{
return this.m_HostTopology;
}
}
public bool useWebSockets { get; set; }
public bool useWebSockets
{
get
{
return this.m_UseWebSockets;
}
set
{
this.m_UseWebSockets = value;
}
}
public ReadOnlyCollection<QSBNetworkConnection> connections { get; }
public ReadOnlyCollection<QSBNetworkConnection> connections
{
get
{
return this.m_ConnectionsReadOnly;
}
}
public Dictionary<short, QSBNetworkMessageDelegate> handlers => m_MessageHandlers.GetHandlers();
public Dictionary<short, QSBNetworkMessageDelegate> handlers
{
get
{
return this.m_MessageHandlers.GetHandlers();
}
}
public byte[] messageBuffer { get; private set; } = null;
public byte[] messageBuffer
{
get
{
return this.m_MsgBuffer;
}
}
public NetworkReader messageReader { get; private set; } = null;
public NetworkReader messageReader
{
get
{
return this.m_MsgReader;
}
}
public Type networkConnectionClass { get; private set; } = typeof(QSBNetworkConnection);
public Type networkConnectionClass
{
get
{
return this.m_NetworkConnectionClass;
}
}
public void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection => networkConnectionClass = typeof(T);
public void SetNetworkConnectionClass<T>() where T : QSBNetworkConnection
{
this.m_NetworkConnectionClass = typeof(T);
}
public virtual void Initialize()
{
if (!m_Initialized)
if (!this.m_Initialized)
{
m_Initialized = true;
this.m_Initialized = true;
NetworkTransport.Init();
messageBuffer = new byte[65535];
messageReader = new NetworkReader(messageBuffer);
if (hostTopology == null)
this.m_MsgBuffer = new byte[65535];
this.m_MsgReader = new NetworkReader(this.m_MsgBuffer);
if (this.m_HostTopology == null)
{
var connectionConfig = new ConnectionConfig();
ConnectionConfig connectionConfig = new ConnectionConfig();
connectionConfig.AddChannel(QosType.ReliableSequenced);
connectionConfig.AddChannel(QosType.Unreliable);
hostTopology = new HostTopology(connectionConfig, 8);
this.m_HostTopology = new HostTopology(connectionConfig, 8);
}
if (LogFilter.logDebug)
{
@ -60,30 +128,30 @@ namespace QuantumUNET
public bool Configure(ConnectionConfig config, int maxConnections)
{
var topology = new HostTopology(config, maxConnections);
return Configure(topology);
HostTopology topology = new HostTopology(config, maxConnections);
return this.Configure(topology);
}
public bool Configure(HostTopology topology)
{
hostTopology = topology;
this.m_HostTopology = topology;
return true;
}
public bool Listen(string ipAddress, int serverListenPort)
{
Initialize();
listenPort = serverListenPort;
if (useWebSockets)
this.Initialize();
this.m_ListenPort = serverListenPort;
if (this.m_UseWebSockets)
{
serverHostId = NetworkTransport.AddWebsocketHost(hostTopology, serverListenPort, ipAddress);
this.m_ServerHostId = NetworkTransport.AddWebsocketHost(this.m_HostTopology, serverListenPort, ipAddress);
}
else
{
serverHostId = NetworkTransport.AddHost(hostTopology, serverListenPort, ipAddress);
this.m_ServerHostId = NetworkTransport.AddHost(this.m_HostTopology, serverListenPort, ipAddress);
}
bool result;
if (serverHostId == -1)
if (this.m_ServerHostId == -1)
{
result = false;
}
@ -96,7 +164,7 @@ namespace QuantumUNET
"NetworkServerSimple listen: ",
ipAddress,
":",
listenPort
this.m_ListenPort
}));
}
result = true;
@ -104,23 +172,26 @@ namespace QuantumUNET
return result;
}
public bool Listen(int serverListenPort) => Listen(serverListenPort, hostTopology);
public bool Listen(int serverListenPort)
{
return this.Listen(serverListenPort, this.m_HostTopology);
}
public bool Listen(int serverListenPort, HostTopology topology)
{
hostTopology = topology;
Initialize();
listenPort = serverListenPort;
if (useWebSockets)
this.m_HostTopology = topology;
this.Initialize();
this.m_ListenPort = serverListenPort;
if (this.m_UseWebSockets)
{
serverHostId = NetworkTransport.AddWebsocketHost(hostTopology, serverListenPort);
this.m_ServerHostId = NetworkTransport.AddWebsocketHost(this.m_HostTopology, serverListenPort);
}
else
{
serverHostId = NetworkTransport.AddHost(hostTopology, serverListenPort);
this.m_ServerHostId = NetworkTransport.AddHost(this.m_HostTopology, serverListenPort);
}
bool result;
if (serverHostId == -1)
if (this.m_ServerHostId == -1)
{
result = false;
}
@ -128,7 +199,7 @@ namespace QuantumUNET
{
if (LogFilter.logDebug)
{
Debug.Log("NetworkServerSimple listen " + listenPort);
Debug.Log("NetworkServerSimple listen " + this.m_ListenPort);
}
result = true;
}
@ -137,18 +208,19 @@ namespace QuantumUNET
public void ListenRelay(string relayIp, int relayPort, NetworkID netGuid, SourceID sourceId, NodeID nodeId)
{
Initialize();
serverHostId = NetworkTransport.AddHost(hostTopology, listenPort);
this.Initialize();
this.m_ServerHostId = NetworkTransport.AddHost(this.m_HostTopology, this.listenPort);
if (LogFilter.logDebug)
{
Debug.Log("Server Host Slot Id: " + serverHostId);
Debug.Log("Server Host Slot Id: " + this.m_ServerHostId);
}
Update();
NetworkTransport.ConnectAsNetworkHost(serverHostId, relayIp, relayPort, netGuid, sourceId, nodeId, out var b);
m_RelaySlotId = 0;
this.Update();
byte b;
NetworkTransport.ConnectAsNetworkHost(this.m_ServerHostId, relayIp, relayPort, netGuid, sourceId, nodeId, out b);
this.m_RelaySlotId = 0;
if (LogFilter.logDebug)
{
Debug.Log("Relay Slot Id: " + m_RelaySlotId);
Debug.Log("Relay Slot Id: " + this.m_RelaySlotId);
}
}
@ -158,23 +230,35 @@ namespace QuantumUNET
{
Debug.Log("NetworkServerSimple stop ");
}
NetworkTransport.RemoveHost(serverHostId);
serverHostId = -1;
NetworkTransport.RemoveHost(this.m_ServerHostId);
this.m_ServerHostId = -1;
}
internal void RegisterHandlerSafe(short msgType, QSBNetworkMessageDelegate handler) => m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
internal void RegisterHandlerSafe(short msgType, QSBNetworkMessageDelegate handler)
{
m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
}
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler) => m_MessageHandlers.RegisterHandler(msgType, handler);
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler)
{
this.m_MessageHandlers.RegisterHandler(msgType, handler);
}
public void UnregisterHandler(short msgType) => m_MessageHandlers.UnregisterHandler(msgType);
public void UnregisterHandler(short msgType)
{
this.m_MessageHandlers.UnregisterHandler(msgType);
}
public void ClearHandlers() => m_MessageHandlers.ClearMessageHandlers();
public void ClearHandlers()
{
this.m_MessageHandlers.ClearMessageHandlers();
}
public void UpdateConnections()
{
for (var i = 0; i < m_Connections.Count; i++)
for (int i = 0; i < this.m_Connections.Count; i++)
{
var networkConnection = m_Connections[i];
QSBNetworkConnection networkConnection = this.m_Connections[i];
if (networkConnection != null)
{
networkConnection.FlushChannels();
@ -184,12 +268,13 @@ namespace QuantumUNET
public void Update()
{
if (serverHostId != -1)
if (this.m_ServerHostId != -1)
{
NetworkEventType networkEventType;
if (m_RelaySlotId != -1)
if (this.m_RelaySlotId != -1)
{
networkEventType = NetworkTransport.ReceiveRelayEventFromHost(serverHostId, out var b);
byte b;
networkEventType = NetworkTransport.ReceiveRelayEventFromHost(this.m_ServerHostId, out b);
if (networkEventType != NetworkEventType.Nothing)
{
if (LogFilter.logDebug)
@ -214,13 +299,17 @@ namespace QuantumUNET
}
do
{
networkEventType = NetworkTransport.ReceiveFromHost(serverHostId, out var connectionId, out var channelId, messageBuffer, messageBuffer.Length, out var receivedSize, out var b);
byte b;
int connectionId;
int channelId;
int receivedSize;
networkEventType = NetworkTransport.ReceiveFromHost(this.m_ServerHostId, out connectionId, out channelId, this.m_MsgBuffer, this.m_MsgBuffer.Length, out receivedSize, out b);
if (networkEventType != NetworkEventType.Nothing)
{
Debug.Log(string.Concat(new object[]
{
"Server event: host=",
serverHostId,
this.m_ServerHostId,
" event=",
networkEventType,
" error=",
@ -230,15 +319,15 @@ namespace QuantumUNET
switch (networkEventType)
{
case NetworkEventType.DataEvent:
HandleData(connectionId, channelId, receivedSize, b);
this.HandleData(connectionId, channelId, receivedSize, b);
break;
case NetworkEventType.ConnectEvent:
HandleConnect(connectionId, b);
this.HandleConnect(connectionId, b);
break;
case NetworkEventType.DisconnectEvent:
HandleDisconnect(connectionId, b);
this.HandleDisconnect(connectionId, b);
break;
case NetworkEventType.Nothing:
@ -253,39 +342,39 @@ namespace QuantumUNET
}
}
while (networkEventType != NetworkEventType.Nothing);
UpdateConnections();
this.UpdateConnections();
}
}
public QSBNetworkConnection FindConnection(int connectionId)
{
QSBNetworkConnection result;
if (connectionId < 0 || connectionId >= m_Connections.Count)
if (connectionId < 0 || connectionId >= this.m_Connections.Count)
{
result = null;
}
else
{
result = m_Connections[connectionId];
result = this.m_Connections[connectionId];
}
return result;
}
public bool SetConnectionAtIndex(QSBNetworkConnection conn)
{
while (m_Connections.Count <= conn.connectionId)
while (this.m_Connections.Count <= conn.connectionId)
{
m_Connections.Add(null);
this.m_Connections.Add(null);
}
bool result;
if (m_Connections[conn.connectionId] != null)
if (this.m_Connections[conn.connectionId] != null)
{
result = false;
}
else
{
m_Connections[conn.connectionId] = conn;
conn.SetHandlers(m_MessageHandlers);
this.m_Connections[conn.connectionId] = conn;
conn.SetHandlers(this.m_MessageHandlers);
result = true;
}
return result;
@ -294,13 +383,13 @@ namespace QuantumUNET
public bool RemoveConnectionAtIndex(int connectionId)
{
bool result;
if (connectionId < 0 || connectionId >= m_Connections.Count)
if (connectionId < 0 || connectionId >= this.m_Connections.Count)
{
result = false;
}
else
{
m_Connections[connectionId] = null;
this.m_Connections[connectionId] = null;
result = true;
}
return result;
@ -314,21 +403,26 @@ namespace QuantumUNET
}
if (error != 0)
{
OnConnectError(connectionId, error);
this.OnConnectError(connectionId, error);
}
else
{
NetworkTransport.GetConnectionInfo(serverHostId, connectionId, out var networkAddress, out var num, out var networkID, out var nodeID, out var lastError);
var networkConnection = (QSBNetworkConnection)Activator.CreateInstance(networkConnectionClass);
networkConnection.SetHandlers(m_MessageHandlers);
networkConnection.Initialize(networkAddress, serverHostId, connectionId, hostTopology);
string networkAddress;
int num;
NetworkID networkID;
NodeID nodeID;
byte lastError;
NetworkTransport.GetConnectionInfo(this.m_ServerHostId, connectionId, out networkAddress, out num, out networkID, out nodeID, out lastError);
QSBNetworkConnection networkConnection = (QSBNetworkConnection)Activator.CreateInstance(this.m_NetworkConnectionClass);
networkConnection.SetHandlers(this.m_MessageHandlers);
networkConnection.Initialize(networkAddress, this.m_ServerHostId, connectionId, this.m_HostTopology);
networkConnection.LastError = (NetworkError)lastError;
while (m_Connections.Count <= connectionId)
while (this.m_Connections.Count <= connectionId)
{
m_Connections.Add(null);
this.m_Connections.Add(null);
}
m_Connections[connectionId] = networkConnection;
OnConnected(networkConnection);
this.m_Connections[connectionId] = networkConnection;
this.OnConnected(networkConnection);
}
}
@ -338,7 +432,7 @@ namespace QuantumUNET
{
Debug.Log("NetworkServerSimple disconnect client:" + connectionId);
}
var networkConnection = FindConnection(connectionId);
QSBNetworkConnection networkConnection = this.FindConnection(connectionId);
if (networkConnection != null)
{
networkConnection.LastError = (NetworkError)error;
@ -346,7 +440,7 @@ namespace QuantumUNET
{
if (error != 6)
{
m_Connections[connectionId] = null;
this.m_Connections[connectionId] = null;
if (LogFilter.logError)
{
Debug.LogError(string.Concat(new object[]
@ -357,23 +451,23 @@ namespace QuantumUNET
(NetworkError)error
}));
}
OnDisconnectError(networkConnection, error);
this.OnDisconnectError(networkConnection, error);
return;
}
}
networkConnection.Disconnect();
m_Connections[connectionId] = null;
this.m_Connections[connectionId] = null;
if (LogFilter.logDebug)
{
Debug.Log("Server lost client:" + connectionId);
}
OnDisconnected(networkConnection);
this.OnDisconnected(networkConnection);
}
}
private void HandleData(int connectionId, int channelId, int receivedSize, byte error)
{
var networkConnection = FindConnection(connectionId);
QSBNetworkConnection networkConnection = this.FindConnection(connectionId);
if (networkConnection == null)
{
if (LogFilter.logError)
@ -386,19 +480,19 @@ namespace QuantumUNET
networkConnection.LastError = (NetworkError)error;
if (error != 0)
{
OnDataError(networkConnection, error);
this.OnDataError(networkConnection, error);
}
else
{
messageReader.SeekZero();
OnData(networkConnection, receivedSize, channelId);
this.m_MsgReader.SeekZero();
this.OnData(networkConnection, receivedSize, channelId);
}
}
}
public void SendBytesTo(int connectionId, byte[] bytes, int numBytes, int channelId)
{
var networkConnection = FindConnection(connectionId);
QSBNetworkConnection networkConnection = this.FindConnection(connectionId);
if (networkConnection != null)
{
networkConnection.SendBytes(bytes, numBytes, channelId);
@ -407,7 +501,7 @@ namespace QuantumUNET
public void SendWriterTo(int connectionId, QSBNetworkWriter writer, int channelId)
{
var networkConnection = FindConnection(connectionId);
QSBNetworkConnection networkConnection = this.FindConnection(connectionId);
if (networkConnection != null)
{
networkConnection.SendWriter(writer, channelId);
@ -416,19 +510,19 @@ namespace QuantumUNET
public void Disconnect(int connectionId)
{
var networkConnection = FindConnection(connectionId);
QSBNetworkConnection networkConnection = this.FindConnection(connectionId);
if (networkConnection != null)
{
networkConnection.Disconnect();
m_Connections[connectionId] = null;
this.m_Connections[connectionId] = null;
}
}
public void DisconnectAllConnections()
{
for (var i = 0; i < m_Connections.Count; i++)
for (int i = 0; i < this.m_Connections.Count; i++)
{
var networkConnection = m_Connections[i];
QSBNetworkConnection networkConnection = this.m_Connections[i];
if (networkConnection != null)
{
networkConnection.Disconnect();
@ -437,21 +531,58 @@ namespace QuantumUNET
}
}
public virtual void OnConnectError(int connectionId, byte error) => Debug.LogError("OnConnectError error:" + error);
public virtual void OnConnectError(int connectionId, byte error)
{
Debug.LogError("OnConnectError error:" + error);
}
public virtual void OnDataError(QSBNetworkConnection conn, byte error) => Debug.LogError("OnDataError error:" + error);
public virtual void OnDataError(QSBNetworkConnection conn, byte error)
{
Debug.LogError("OnDataError error:" + error);
}
public virtual void OnDisconnectError(QSBNetworkConnection conn, byte error) => Debug.LogError("OnDisconnectError error:" + error);
public virtual void OnDisconnectError(QSBNetworkConnection conn, byte error)
{
Debug.LogError("OnDisconnectError error:" + error);
}
public virtual void OnConnected(QSBNetworkConnection conn) => conn.InvokeHandlerNoData(32);
public virtual void OnConnected(QSBNetworkConnection conn)
{
conn.InvokeHandlerNoData(32);
}
public virtual void OnDisconnected(QSBNetworkConnection conn) => conn.InvokeHandlerNoData(33);
public virtual void OnDisconnected(QSBNetworkConnection conn)
{
conn.InvokeHandlerNoData(33);
}
public virtual void OnData(QSBNetworkConnection conn, int receivedSize, int channelId) => conn.TransportReceive(messageBuffer, receivedSize, channelId);
public virtual void OnData(QSBNetworkConnection conn, int receivedSize, int channelId)
{
conn.TransportReceive(this.m_MsgBuffer, receivedSize, channelId);
}
private bool m_Initialized = false;
private int m_ListenPort;
private int m_ServerHostId = -1;
private int m_RelaySlotId = -1;
private bool m_UseWebSockets;
private byte[] m_MsgBuffer = null;
private NetworkReader m_MsgReader = null;
private Type m_NetworkConnectionClass = typeof(QSBNetworkConnection);
private HostTopology m_HostTopology;
private List<QSBNetworkConnection> m_Connections = new List<QSBNetworkConnection>();
private ReadOnlyCollection<QSBNetworkConnection> m_ConnectionsReadOnly;
private QSBNetworkMessageHandlers m_MessageHandlers = new QSBNetworkMessageHandlers();
}
}

View File

@ -0,0 +1,537 @@
using QuantumUNET.Components;
using QuantumUNET.Messages;
using System;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET
{
public class QSBNetworkWriter
{
public QSBNetworkWriter()
{
this.m_Buffer = new QSBNetBuffer();
if (s_Encoding == null)
{
s_Encoding = new UTF8Encoding();
s_StringWriteBuffer = new byte[32768];
}
}
public QSBNetworkWriter(byte[] buffer)
{
this.m_Buffer = new QSBNetBuffer(buffer);
if (s_Encoding == null)
{
s_Encoding = new UTF8Encoding();
s_StringWriteBuffer = new byte[32768];
}
}
public short Position
{
get
{
return (short)this.m_Buffer.Position;
}
}
public byte[] ToArray()
{
byte[] array = new byte[this.m_Buffer.AsArraySegment().Count];
Array.Copy(this.m_Buffer.AsArraySegment().Array, array, this.m_Buffer.AsArraySegment().Count);
return array;
}
public byte[] AsArray()
{
return this.AsArraySegment().Array;
}
internal ArraySegment<byte> AsArraySegment()
{
return this.m_Buffer.AsArraySegment();
}
public void WritePackedUInt32(uint value)
{
if (value <= 240U)
{
this.Write((byte)value);
}
else if (value <= 2287U)
{
this.Write((byte)((value - 240U) / 256U + 241U));
this.Write((byte)((value - 240U) % 256U));
}
else if (value <= 67823U)
{
this.Write(249);
this.Write((byte)((value - 2288U) / 256U));
this.Write((byte)((value - 2288U) % 256U));
}
else if (value <= 16777215U)
{
this.Write(250);
this.Write((byte)(value & 255U));
this.Write((byte)(value >> 8 & 255U));
this.Write((byte)(value >> 16 & 255U));
}
else
{
this.Write(251);
this.Write((byte)(value & 255U));
this.Write((byte)(value >> 8 & 255U));
this.Write((byte)(value >> 16 & 255U));
this.Write((byte)(value >> 24 & 255U));
}
}
public void WritePackedUInt64(ulong value)
{
if (value <= 240UL)
{
this.Write((byte)value);
}
else if (value <= 2287UL)
{
this.Write((byte)((value - 240UL) / 256UL + 241UL));
this.Write((byte)((value - 240UL) % 256UL));
}
else if (value <= 67823UL)
{
this.Write(249);
this.Write((byte)((value - 2288UL) / 256UL));
this.Write((byte)((value - 2288UL) % 256UL));
}
else if (value <= 16777215UL)
{
this.Write(250);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
}
else if (value <= uint.MaxValue)
{
this.Write(251);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
this.Write((byte)(value >> 24 & 255UL));
}
else if (value <= 1099511627775UL)
{
this.Write(252);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
this.Write((byte)(value >> 24 & 255UL));
this.Write((byte)(value >> 32 & 255UL));
}
else if (value <= 281474976710655UL)
{
this.Write(253);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
this.Write((byte)(value >> 24 & 255UL));
this.Write((byte)(value >> 32 & 255UL));
this.Write((byte)(value >> 40 & 255UL));
}
else if (value <= 72057594037927935UL)
{
this.Write(254);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
this.Write((byte)(value >> 24 & 255UL));
this.Write((byte)(value >> 32 & 255UL));
this.Write((byte)(value >> 40 & 255UL));
this.Write((byte)(value >> 48 & 255UL));
}
else
{
this.Write(byte.MaxValue);
this.Write((byte)(value & 255UL));
this.Write((byte)(value >> 8 & 255UL));
this.Write((byte)(value >> 16 & 255UL));
this.Write((byte)(value >> 24 & 255UL));
this.Write((byte)(value >> 32 & 255UL));
this.Write((byte)(value >> 40 & 255UL));
this.Write((byte)(value >> 48 & 255UL));
this.Write((byte)(value >> 56 & 255UL));
}
}
public void Write(NetworkInstanceId value)
{
this.WritePackedUInt32(value.Value);
}
public void Write(NetworkSceneId value)
{
this.WritePackedUInt32(value.Value);
}
public void Write(char value)
{
this.m_Buffer.WriteByte((byte)value);
}
public void Write(byte value)
{
this.m_Buffer.WriteByte(value);
}
public void Write(sbyte value)
{
this.m_Buffer.WriteByte((byte)value);
}
public void Write(short value)
{
this.m_Buffer.WriteByte2((byte)(value & 255), (byte)(value >> 8 & 255));
}
public void Write(ushort value)
{
this.m_Buffer.WriteByte2((byte)(value & 255), (byte)(value >> 8 & 255));
}
public void Write(int value)
{
this.m_Buffer.WriteByte4((byte)(value & 255), (byte)(value >> 8 & 255), (byte)(value >> 16 & 255), (byte)(value >> 24 & 255));
}
public void Write(uint value)
{
this.m_Buffer.WriteByte4((byte)(value & 255U), (byte)(value >> 8 & 255U), (byte)(value >> 16 & 255U), (byte)(value >> 24 & 255U));
}
public void Write(long value)
{
this.m_Buffer.WriteByte8((byte)(value & 255L), (byte)(value >> 8 & 255L), (byte)(value >> 16 & 255L), (byte)(value >> 24 & 255L), (byte)(value >> 32 & 255L), (byte)(value >> 40 & 255L), (byte)(value >> 48 & 255L), (byte)(value >> 56 & 255L));
}
public void Write(ulong value)
{
this.m_Buffer.WriteByte8((byte)(value & 255UL), (byte)(value >> 8 & 255UL), (byte)(value >> 16 & 255UL), (byte)(value >> 24 & 255UL), (byte)(value >> 32 & 255UL), (byte)(value >> 40 & 255UL), (byte)(value >> 48 & 255UL), (byte)(value >> 56 & 255UL));
}
public void Write(float value)
{
m_Buffer.WriteBytes(BitConverter.GetBytes(value), 4);
}
public void Write(double value)
{
m_Buffer.WriteBytes(BitConverter.GetBytes(value), 8);
}
public void Write(decimal value)
{
int[] bits = decimal.GetBits(value);
this.Write(bits[0]);
this.Write(bits[1]);
this.Write(bits[2]);
this.Write(bits[3]);
}
public void Write(string value)
{
if (value == null)
{
this.m_Buffer.WriteByte2(0, 0);
}
else
{
int byteCount = s_Encoding.GetByteCount(value);
if (byteCount >= 32768)
{
throw new IndexOutOfRangeException("Serialize(string) too long: " + value.Length);
}
this.Write((ushort)byteCount);
int bytes = s_Encoding.GetBytes(value, 0, value.Length, s_StringWriteBuffer, 0);
this.m_Buffer.WriteBytes(s_StringWriteBuffer, (ushort)bytes);
}
}
public void Write(bool value)
{
if (value)
{
this.m_Buffer.WriteByte(1);
}
else
{
this.m_Buffer.WriteByte(0);
}
}
public void Write(byte[] buffer, int count)
{
if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter Write: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
this.m_Buffer.WriteBytes(buffer, (ushort)count);
}
}
public void Write(byte[] buffer, int offset, int count)
{
if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter Write: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
this.m_Buffer.WriteBytesAtOffset(buffer, (ushort)offset, (ushort)count);
}
}
public void WriteBytesAndSize(byte[] buffer, int count)
{
if (buffer == null || count == 0)
{
this.Write(0);
}
else if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter WriteBytesAndSize: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
this.Write((ushort)count);
this.m_Buffer.WriteBytes(buffer, (ushort)count);
}
}
public void WriteBytesFull(byte[] buffer)
{
if (buffer == null)
{
this.Write(0);
}
else if (buffer.Length > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter WriteBytes: buffer is too large (" + buffer.Length + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
this.Write((ushort)buffer.Length);
this.m_Buffer.WriteBytes(buffer, (ushort)buffer.Length);
}
}
public void Write(Vector2 value)
{
this.Write(value.x);
this.Write(value.y);
}
public void Write(Vector3 value)
{
this.Write(value.x);
this.Write(value.y);
this.Write(value.z);
}
public void Write(Vector4 value)
{
this.Write(value.x);
this.Write(value.y);
this.Write(value.z);
this.Write(value.w);
}
public void Write(Color value)
{
this.Write(value.r);
this.Write(value.g);
this.Write(value.b);
this.Write(value.a);
}
public void Write(Color32 value)
{
this.Write(value.r);
this.Write(value.g);
this.Write(value.b);
this.Write(value.a);
}
public void Write(Quaternion value)
{
this.Write(value.x);
this.Write(value.y);
this.Write(value.z);
this.Write(value.w);
}
public void Write(Rect value)
{
this.Write(value.xMin);
this.Write(value.yMin);
this.Write(value.width);
this.Write(value.height);
}
public void Write(Plane value)
{
this.Write(value.normal);
this.Write(value.distance);
}
public void Write(Ray value)
{
this.Write(value.direction);
this.Write(value.origin);
}
public void Write(Matrix4x4 value)
{
this.Write(value.m00);
this.Write(value.m01);
this.Write(value.m02);
this.Write(value.m03);
this.Write(value.m10);
this.Write(value.m11);
this.Write(value.m12);
this.Write(value.m13);
this.Write(value.m20);
this.Write(value.m21);
this.Write(value.m22);
this.Write(value.m23);
this.Write(value.m30);
this.Write(value.m31);
this.Write(value.m32);
this.Write(value.m33);
}
public void Write(NetworkHash128 value)
{
this.Write(value.i0);
this.Write(value.i1);
this.Write(value.i2);
this.Write(value.i3);
this.Write(value.i4);
this.Write(value.i5);
this.Write(value.i6);
this.Write(value.i7);
this.Write(value.i8);
this.Write(value.i9);
this.Write(value.i10);
this.Write(value.i11);
this.Write(value.i12);
this.Write(value.i13);
this.Write(value.i14);
this.Write(value.i15);
}
public void Write(NetworkIdentity value)
{
if (value == null)
{
this.WritePackedUInt32(0U);
}
else
{
this.Write(value.netId);
}
}
public void Write(Transform value)
{
if (value == null || value.gameObject == null)
{
this.WritePackedUInt32(0U);
}
else
{
NetworkIdentity component = value.gameObject.GetComponent<NetworkIdentity>();
if (component != null)
{
this.Write(component.netId);
}
else
{
if (LogFilter.logWarn)
{
Debug.LogWarning("NetworkWriter " + value + " has no NetworkIdentity");
}
this.WritePackedUInt32(0U);
}
}
}
public void Write(GameObject value)
{
if (value == null)
{
this.WritePackedUInt32(0U);
}
else
{
QSBNetworkIdentity component = value.GetComponent<QSBNetworkIdentity>();
if (component != null)
{
this.Write(component.NetId);
}
else
{
if (LogFilter.logWarn)
{
Debug.LogWarning("NetworkWriter " + value + " has no NetworkIdentity");
}
this.WritePackedUInt32(0U);
}
}
}
public void Write(QSBMessageBase msg)
{
msg.Serialize(this);
}
public void SeekZero()
{
this.m_Buffer.SeekZero();
}
public void StartMessage(short msgType)
{
this.SeekZero();
this.m_Buffer.WriteByte2(0, 0);
this.Write(msgType);
}
public void FinishMessage()
{
this.m_Buffer.FinishMessage();
}
private const int k_MaxStringLength = 32768;
private QSBNetBuffer m_Buffer;
private static Encoding s_Encoding;
private static byte[] s_StringWriteBuffer;
}
}

View File

@ -0,0 +1,11 @@
using UnityEngine.Networking;
namespace QuantumUNET
{
public struct QSBPeerInfoPlayer
{
public NetworkInstanceId netId;
public short playerControllerId;
}
}

View File

@ -9,7 +9,6 @@ namespace QuantumUNET
public QSBNetworkIdentity UnetView;
public GameObject Gameobject;
public const int MaxPlayersPerClient = 32;
public bool IsValid => PlayerControllerId != -1;
internal const short kMaxLocalPlayers = 8;
@ -24,6 +23,8 @@ namespace QuantumUNET
PlayerControllerId = playerControllerId;
}
public bool IsValid => PlayerControllerId != -1;
public override string ToString()
{
return string.Format("ID={0} NetworkIdentity NetID={1} Player={2}", new object[]

View File

@ -1,5 +1,4 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
namespace QuantumUNET
{

View File

@ -1,5 +1,4 @@
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using UnityEngine;
using UnityEngine.Networking;
@ -13,14 +12,20 @@ namespace QuantumUNET
m_LocalServer = localServer;
}
public override bool Send(short msgType, QSBMessageBase msg) =>
m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, 0);
public override bool Send(short msgType, QSBMessageBase msg)
{
return m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, 0);
}
public override bool SendUnreliable(short msgType, QSBMessageBase msg) =>
m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, 1);
public override bool SendUnreliable(short msgType, QSBMessageBase msg)
{
return m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, 1);
}
public override bool SendByChannel(short msgType, QSBMessageBase msg, int channelId) =>
m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, channelId);
public override bool SendByChannel(short msgType, QSBMessageBase msg, int channelId)
{
return m_LocalServer.InvokeHandlerOnServer(this, msgType, msg, channelId);
}
public override bool SendBytes(byte[] bytes, int numBytes, int channelId)
{
@ -40,8 +45,10 @@ namespace QuantumUNET
return result;
}
public override bool SendWriter(QSBNetworkWriter writer, int channelId) =>
m_LocalServer.InvokeBytes(this, writer.AsArray(), (short)writer.AsArray().Length, channelId);
public override bool SendWriter(QSBNetworkWriter writer, int channelId)
{
return m_LocalServer.InvokeBytes(this, writer.AsArray(), (int)((short)writer.AsArray().Length), channelId);
}
public override void GetStatsOut(out int numMsgs, out int numBufferedMsgs, out int numBytes, out int lastBufferedPerSecond)
{

32
QuantumUNET/QSBUtility.cs Normal file
View File

@ -0,0 +1,32 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking.Types;
namespace QuantumUNET
{
public class QSBUtility
{
private static readonly Dictionary<NetworkID, NetworkAccessToken> _dictTokens = new Dictionary<NetworkID, NetworkAccessToken>();
public static SourceID GetSourceID()
=> (SourceID)SystemInfo.deviceUniqueIdentifier.GetHashCode();
public static void SetAccessTokenForNetwork(NetworkID netId, NetworkAccessToken accessToken)
{
if (_dictTokens.ContainsKey(netId))
{
_dictTokens.Remove(netId);
}
_dictTokens.Add(netId, accessToken);
}
public static NetworkAccessToken GetAccessTokenForNetwork(NetworkID netId)
{
if (!_dictTokens.TryGetValue(netId, out var result))
{
result = new NetworkAccessToken();
}
return result;
}
}
}

View File

@ -100,8 +100,8 @@
<Compile Include="Messages\QSBAnimationMessage.cs" />
<Compile Include="Messages\QSBAnimationParametersMessage.cs" />
<Compile Include="Messages\QSBAnimationTriggerMessage.cs" />
<Compile Include="Transport\QSBChannelBuffer.cs" />
<Compile Include="Transport\QSBChannelPacket.cs" />
<Compile Include="QSBChannelBuffer.cs" />
<Compile Include="QSBChannelPacket.cs" />
<Compile Include="Messages\QSBClientAuthorityMessage.cs" />
<Compile Include="QSBClientScene.cs" />
<Compile Include="Messages\QSBCRCMessage.cs" />
@ -110,7 +110,7 @@
<Compile Include="Messages\QSBErrorMessage.cs" />
<Compile Include="QSBLocalClient.cs" />
<Compile Include="Messages\QSBMessageBase.cs" />
<Compile Include="Transport\QSBNetBuffer.cs" />
<Compile Include="QSBNetBuffer.cs" />
<Compile Include="Components\QSBNetworkAnimator.cs" />
<Compile Include="QSBNetworkBehaviour.cs" />
<Compile Include="QSBNetworkClient.cs" />
@ -122,25 +122,28 @@
<Compile Include="Messages\QSBNetworkMessage.cs" />
<Compile Include="Messages\QSBNetworkMessageDelegate.cs" />
<Compile Include="QSBNetworkMessageHandlers.cs" />
<Compile Include="Transport\QSBNetworkReader.cs" />
<Compile Include="QSBNetworkReader.cs" />
<Compile Include="QSBNetworkScene.cs" />
<Compile Include="QSBNetworkServer.cs" />
<Compile Include="QSBNetworkServerSimple.cs" />
<Compile Include="Components\QSBNetworkTransform.cs" />
<Compile Include="Transport\QSBNetworkWriter.cs" />
<Compile Include="QSBNetworkWriter.cs" />
<Compile Include="Messages\QSBNotReadyMessage.cs" />
<Compile Include="Messages\QSBObjectDestroyMessage.cs" />
<Compile Include="Messages\QSBObjectSpawnFinishedMessage.cs" />
<Compile Include="Messages\QSBObjectSpawnMessage.cs" />
<Compile Include="Messages\QSBObjectSpawnSceneMessage.cs" />
<Compile Include="Messages\QSBOwnerMessage.cs" />
<Compile Include="Messages\QSBPeerInfoMessage.cs" />
<Compile Include="QSBPeerInfoPlayer.cs" />
<Compile Include="QSBPlayerController.cs" />
<Compile Include="Messages\QSBReadyMessage.cs" />
<Compile Include="Messages\QSBReconnectMessage.cs" />
<Compile Include="Messages\QSBRemovePlayerMessage.cs" />
<Compile Include="Messages\QSBStringMessage.cs" />
<Compile Include="Messages\QSBSpawnDelegate.cs" />
<Compile Include="QSBULocalConnectionToClient.cs" />
<Compile Include="QSBULocalConnectionToServer.cs" />
<Compile Include="QSBUtility.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@ -1,56 +0,0 @@
using System;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET.Transport
{
internal struct QSBChannelPacket
{
private int m_Position;
private byte[] m_Buffer;
private bool m_IsReliable;
public QSBChannelPacket(int packetSize, bool isReliable)
{
m_Position = 0;
m_Buffer = new byte[packetSize];
m_IsReliable = isReliable;
}
public void Reset() => m_Position = 0;
public bool IsEmpty() => m_Position == 0;
public void Write(byte[] bytes, int numBytes)
{
Array.Copy(bytes, 0, m_Buffer, m_Position, numBytes);
m_Position += numBytes;
}
public bool HasSpace(int numBytes) => m_Position + numBytes <= m_Buffer.Length;
public bool SendToTransport(QSBNetworkConnection conn, int channelId)
{
var result = true;
if (!conn.TransportSend(m_Buffer, (ushort)m_Position, channelId, out var b))
{
if (!m_IsReliable || b != 4)
{
Debug.LogError($"Failed to send internal buffer channel:{channelId} bytesToSend:{m_Position}");
result = false;
}
}
if (b != 0)
{
if (m_IsReliable && b == 4)
{
return false;
}
Debug.LogError($"Send Error: {(NetworkError)b} channel:{channelId} bytesToSend:{m_Position}");
result = false;
}
m_Position = 0;
return result;
}
}
}

View File

@ -1,169 +0,0 @@
using System;
using UnityEngine;
namespace QuantumUNET.Transport
{
internal class QSBNetBuffer
{
public QSBNetBuffer()
{
m_Buffer = new byte[64];
}
public QSBNetBuffer(byte[] buffer)
{
m_Buffer = buffer;
}
public uint Position { get; private set; }
public int Length => m_Buffer.Length;
public byte ReadByte()
{
if (Position >= (ulong)m_Buffer.Length)
{
throw new IndexOutOfRangeException("NetworkReader:ReadByte out of range:" + ToString());
}
return m_Buffer[(int)((UIntPtr)(Position++))];
}
public void ReadBytes(byte[] buffer, uint count)
{
if (Position + count > (ulong)m_Buffer.Length)
{
throw new IndexOutOfRangeException(string.Concat(new object[]
{
"NetworkReader:ReadBytes out of range: (",
count,
") ",
ToString()
}));
}
ushort num = 0;
while (num < count)
{
buffer[num] = m_Buffer[(int)((UIntPtr)(Position + num))];
num += 1;
}
Position += count;
}
internal ArraySegment<byte> AsArraySegment() => new ArraySegment<byte>(m_Buffer, 0, (int)Position);
public void WriteByte(byte value)
{
WriteCheckForSpace(1);
m_Buffer[(int)((UIntPtr)Position)] = value;
Position += 1U;
}
public void WriteByte2(byte value0, byte value1)
{
WriteCheckForSpace(2);
m_Buffer[(int)((UIntPtr)Position)] = value0;
m_Buffer[(int)((UIntPtr)(Position + 1U))] = value1;
Position += 2U;
}
public void WriteByte4(byte value0, byte value1, byte value2, byte value3)
{
WriteCheckForSpace(4);
m_Buffer[(int)((UIntPtr)Position)] = value0;
m_Buffer[(int)((UIntPtr)(Position + 1U))] = value1;
m_Buffer[(int)((UIntPtr)(Position + 2U))] = value2;
m_Buffer[(int)((UIntPtr)(Position + 3U))] = value3;
Position += 4U;
}
public void WriteByte8(byte value0, byte value1, byte value2, byte value3, byte value4, byte value5, byte value6, byte value7)
{
WriteCheckForSpace(8);
m_Buffer[(int)((UIntPtr)Position)] = value0;
m_Buffer[(int)((UIntPtr)(Position + 1U))] = value1;
m_Buffer[(int)((UIntPtr)(Position + 2U))] = value2;
m_Buffer[(int)((UIntPtr)(Position + 3U))] = value3;
m_Buffer[(int)((UIntPtr)(Position + 4U))] = value4;
m_Buffer[(int)((UIntPtr)(Position + 5U))] = value5;
m_Buffer[(int)((UIntPtr)(Position + 6U))] = value6;
m_Buffer[(int)((UIntPtr)(Position + 7U))] = value7;
Position += 8U;
}
public void WriteBytesAtOffset(byte[] buffer, ushort targetOffset, ushort count)
{
var num = (uint)(count + targetOffset);
WriteCheckForSpace((ushort)num);
if (targetOffset == 0 && count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)Position);
}
else
{
for (var i = 0; i < count; i++)
{
m_Buffer[targetOffset + i] = buffer[i];
}
}
if (num > Position)
{
Position = num;
}
}
public void WriteBytes(byte[] buffer, ushort count)
{
WriteCheckForSpace(count);
if (count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)Position);
}
else
{
for (var i = 0; i < count; i++)
{
m_Buffer[(int)(checked((IntPtr)(unchecked(Position + (ulong)i))))] = buffer[i];
}
}
Position += count;
}
private void WriteCheckForSpace(ushort count)
{
if (Position + count >= (ulong)m_Buffer.Length)
{
var num = (int)Math.Ceiling(m_Buffer.Length * 1.5f);
while (Position + count >= (ulong)num)
{
num = (int)Math.Ceiling(num * 1.5f);
if (num > 134217728)
{
Debug.LogWarning("NetworkBuffer size is " + num + " bytes!");
}
}
var array = new byte[num];
m_Buffer.CopyTo(array, 0);
m_Buffer = array;
}
}
public void FinishMessage()
{
var num = (ushort)(Position - 4U);
m_Buffer[0] = (byte)(num & 255);
m_Buffer[1] = (byte)((num >> 8) & 255);
}
public void SeekZero() =>
Position = 0U;
public void Replace(byte[] buffer)
{
m_Buffer = buffer;
Position = 0U;
}
public override string ToString() => string.Format("NetBuf sz:{0} pos:{1}", m_Buffer.Length, Position);
private byte[] m_Buffer;
}
}

View File

@ -1,477 +0,0 @@
using QuantumUNET.Components;
using QuantumUNET.Messages;
using System;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace QuantumUNET.Transport
{
public class QSBNetworkWriter
{
public QSBNetworkWriter()
{
m_Buffer = new QSBNetBuffer();
if (s_Encoding == null)
{
s_Encoding = new UTF8Encoding();
s_StringWriteBuffer = new byte[32768];
}
}
public QSBNetworkWriter(byte[] buffer)
{
m_Buffer = new QSBNetBuffer(buffer);
if (s_Encoding == null)
{
s_Encoding = new UTF8Encoding();
s_StringWriteBuffer = new byte[32768];
}
}
public short Position => (short)m_Buffer.Position;
public byte[] ToArray()
{
var array = new byte[m_Buffer.AsArraySegment().Count];
Array.Copy(m_Buffer.AsArraySegment().Array, array, m_Buffer.AsArraySegment().Count);
return array;
}
public byte[] AsArray() => AsArraySegment().Array;
internal ArraySegment<byte> AsArraySegment() => m_Buffer.AsArraySegment();
public void WritePackedUInt32(uint value)
{
if (value <= 240U)
{
Write((byte)value);
}
else if (value <= 2287U)
{
Write((byte)(((value - 240U) / 256U) + 241U));
Write((byte)((value - 240U) % 256U));
}
else if (value <= 67823U)
{
Write(249);
Write((byte)((value - 2288U) / 256U));
Write((byte)((value - 2288U) % 256U));
}
else if (value <= 16777215U)
{
Write(250);
Write((byte)(value & 255U));
Write((byte)((value >> 8) & 255U));
Write((byte)((value >> 16) & 255U));
}
else
{
Write(251);
Write((byte)(value & 255U));
Write((byte)((value >> 8) & 255U));
Write((byte)((value >> 16) & 255U));
Write((byte)((value >> 24) & 255U));
}
}
public void WritePackedUInt64(ulong value)
{
if (value <= 240UL)
{
Write((byte)value);
}
else if (value <= 2287UL)
{
Write((byte)(((value - 240UL) / 256UL) + 241UL));
Write((byte)((value - 240UL) % 256UL));
}
else if (value <= 67823UL)
{
Write(249);
Write((byte)((value - 2288UL) / 256UL));
Write((byte)((value - 2288UL) % 256UL));
}
else if (value <= 16777215UL)
{
Write(250);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
}
else if (value <= uint.MaxValue)
{
Write(251);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
Write((byte)((value >> 24) & 255UL));
}
else if (value <= 1099511627775UL)
{
Write(252);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
Write((byte)((value >> 24) & 255UL));
Write((byte)((value >> 32) & 255UL));
}
else if (value <= 281474976710655UL)
{
Write(253);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
Write((byte)((value >> 24) & 255UL));
Write((byte)((value >> 32) & 255UL));
Write((byte)((value >> 40) & 255UL));
}
else if (value <= 72057594037927935UL)
{
Write(254);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
Write((byte)((value >> 24) & 255UL));
Write((byte)((value >> 32) & 255UL));
Write((byte)((value >> 40) & 255UL));
Write((byte)((value >> 48) & 255UL));
}
else
{
Write(byte.MaxValue);
Write((byte)(value & 255UL));
Write((byte)((value >> 8) & 255UL));
Write((byte)((value >> 16) & 255UL));
Write((byte)((value >> 24) & 255UL));
Write((byte)((value >> 32) & 255UL));
Write((byte)((value >> 40) & 255UL));
Write((byte)((value >> 48) & 255UL));
Write((byte)((value >> 56) & 255UL));
}
}
public void Write(NetworkInstanceId value) => WritePackedUInt32(value.Value);
public void Write(NetworkSceneId value) => WritePackedUInt32(value.Value);
public void Write(char value) => m_Buffer.WriteByte((byte)value);
public void Write(byte value) => m_Buffer.WriteByte(value);
public void Write(sbyte value) => m_Buffer.WriteByte((byte)value);
public void Write(short value) => m_Buffer.WriteByte2((byte)(value & 255), (byte)((value >> 8) & 255));
public void Write(ushort value) => m_Buffer.WriteByte2((byte)(value & 255), (byte)((value >> 8) & 255));
public void Write(int value) => m_Buffer.WriteByte4((byte)(value & 255), (byte)((value >> 8) & 255), (byte)((value >> 16) & 255), (byte)((value >> 24) & 255));
public void Write(uint value) => m_Buffer.WriteByte4((byte)(value & 255U), (byte)((value >> 8) & 255U), (byte)((value >> 16) & 255U), (byte)((value >> 24) & 255U));
public void Write(long value) => m_Buffer.WriteByte8((byte)(value & 255L), (byte)((value >> 8) & 255L), (byte)((value >> 16) & 255L), (byte)((value >> 24) & 255L), (byte)((value >> 32) & 255L), (byte)((value >> 40) & 255L), (byte)((value >> 48) & 255L), (byte)((value >> 56) & 255L));
public void Write(ulong value) => m_Buffer.WriteByte8((byte)(value & 255UL), (byte)((value >> 8) & 255UL), (byte)((value >> 16) & 255UL), (byte)((value >> 24) & 255UL), (byte)((value >> 32) & 255UL), (byte)((value >> 40) & 255UL), (byte)((value >> 48) & 255UL), (byte)((value >> 56) & 255UL));
public void Write(float value) => m_Buffer.WriteBytes(BitConverter.GetBytes(value), 4);
public void Write(double value) => m_Buffer.WriteBytes(BitConverter.GetBytes(value), 8);
public void Write(decimal value)
{
var bits = decimal.GetBits(value);
Write(bits[0]);
Write(bits[1]);
Write(bits[2]);
Write(bits[3]);
}
public void Write(string value)
{
if (value == null)
{
m_Buffer.WriteByte2(0, 0);
}
else
{
var byteCount = s_Encoding.GetByteCount(value);
if (byteCount >= 32768)
{
throw new IndexOutOfRangeException("Serialize(string) too long: " + value.Length);
}
Write((ushort)byteCount);
var bytes = s_Encoding.GetBytes(value, 0, value.Length, s_StringWriteBuffer, 0);
m_Buffer.WriteBytes(s_StringWriteBuffer, (ushort)bytes);
}
}
public void Write(bool value)
{
if (value)
{
m_Buffer.WriteByte(1);
}
else
{
m_Buffer.WriteByte(0);
}
}
public void Write(byte[] buffer, int count)
{
if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter Write: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
m_Buffer.WriteBytes(buffer, (ushort)count);
}
}
public void Write(byte[] buffer, int offset, int count)
{
if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter Write: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
m_Buffer.WriteBytesAtOffset(buffer, (ushort)offset, (ushort)count);
}
}
public void WriteBytesAndSize(byte[] buffer, int count)
{
if (buffer == null || count == 0)
{
Write(0);
}
else if (count > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter WriteBytesAndSize: buffer is too large (" + count + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
Write((ushort)count);
m_Buffer.WriteBytes(buffer, (ushort)count);
}
}
public void WriteBytesFull(byte[] buffer)
{
if (buffer == null)
{
Write(0);
}
else if (buffer.Length > 65535)
{
if (LogFilter.logError)
{
Debug.LogError("NetworkWriter WriteBytes: buffer is too large (" + buffer.Length + ") bytes. The maximum buffer size is 64K bytes.");
}
}
else
{
Write((ushort)buffer.Length);
m_Buffer.WriteBytes(buffer, (ushort)buffer.Length);
}
}
public void Write(Vector2 value)
{
Write(value.x);
Write(value.y);
}
public void Write(Vector3 value)
{
Write(value.x);
Write(value.y);
Write(value.z);
}
public void Write(Vector4 value)
{
Write(value.x);
Write(value.y);
Write(value.z);
Write(value.w);
}
public void Write(Color value)
{
Write(value.r);
Write(value.g);
Write(value.b);
Write(value.a);
}
public void Write(Color32 value)
{
Write(value.r);
Write(value.g);
Write(value.b);
Write(value.a);
}
public void Write(Quaternion value)
{
Write(value.x);
Write(value.y);
Write(value.z);
Write(value.w);
}
public void Write(Rect value)
{
Write(value.xMin);
Write(value.yMin);
Write(value.width);
Write(value.height);
}
public void Write(Plane value)
{
Write(value.normal);
Write(value.distance);
}
public void Write(Ray value)
{
Write(value.direction);
Write(value.origin);
}
public void Write(Matrix4x4 value)
{
Write(value.m00);
Write(value.m01);
Write(value.m02);
Write(value.m03);
Write(value.m10);
Write(value.m11);
Write(value.m12);
Write(value.m13);
Write(value.m20);
Write(value.m21);
Write(value.m22);
Write(value.m23);
Write(value.m30);
Write(value.m31);
Write(value.m32);
Write(value.m33);
}
public void Write(NetworkHash128 value)
{
Write(value.i0);
Write(value.i1);
Write(value.i2);
Write(value.i3);
Write(value.i4);
Write(value.i5);
Write(value.i6);
Write(value.i7);
Write(value.i8);
Write(value.i9);
Write(value.i10);
Write(value.i11);
Write(value.i12);
Write(value.i13);
Write(value.i14);
Write(value.i15);
}
public void Write(QSBNetworkIdentity value)
{
if (value == null)
{
WritePackedUInt32(0U);
}
else
{
Write(value.NetId);
}
}
public void Write(Transform value)
{
if (value == null || value.gameObject == null)
{
WritePackedUInt32(0U);
}
else
{
var component = value.gameObject.GetComponent<QSBNetworkIdentity>();
if (component != null)
{
Write(component.NetId);
}
else
{
if (LogFilter.logWarn)
{
Debug.LogWarning("NetworkWriter " + value + " has no NetworkIdentity");
}
WritePackedUInt32(0U);
}
}
}
public void Write(GameObject value)
{
if (value == null)
{
WritePackedUInt32(0U);
}
else
{
var component = value.GetComponent<QSBNetworkIdentity>();
if (component != null)
{
Write(component.NetId);
}
else
{
if (LogFilter.logWarn)
{
Debug.LogWarning("NetworkWriter " + value + " has no NetworkIdentity");
}
WritePackedUInt32(0U);
}
}
}
public void Write(QSBMessageBase msg) => msg.Serialize(this);
public void SeekZero() => m_Buffer.SeekZero();
public void StartMessage(short msgType)
{
SeekZero();
m_Buffer.WriteByte2(0, 0);
Write(msgType);
}
public void FinishMessage() => m_Buffer.FinishMessage();
private const int k_MaxStringLength = 32768;
private QSBNetBuffer m_Buffer;
private static Encoding s_Encoding;
private static byte[] s_StringWriteBuffer;
}
}

View File

@ -1,6 +1,6 @@
# Quantum Space Buddies - Outer Wilds Online Multiplayer Mod
Quantum Space Buddies (QSB) is a multiplayer mod for Outer Wilds. The mod uses the OWML mod loader and customized UNET code (internally referred to as QNet or QuantumUNET) for networking.
Quantum Space Buddies (QSB) is a multiplayer mod for Outer Wilds. The mod uses the OWML mod loader and customized UNET code (internally referred to as "QuantumUNET") for networking.
**Disclamer - The mod authors (misternebula, AmazingAlek and Raicuparta) take no responsibility for any damages that are caused through opening ports on your network, or connecting to servers. Do not attempt to change your router settings without prior knowledge of what you are doing. Only share your public IP with people you trust, and don't connect to IPs that you do not know the source of. It is good practice to close ports/firewall exceptions after you have finished playing.**