mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-09 09:39:57 +00:00
more
This commit is contained in:
parent
b649090258
commit
799b2d60db
@ -72,9 +72,9 @@ namespace QSB.Animation
|
||||
WriteParameters(m_ParameterWriter, false);
|
||||
animationMessage.parameters = m_ParameterWriter.ToArray();
|
||||
|
||||
if (HasAuthority || ClientScene.readyConnection != null)
|
||||
if (HasAuthority || QSBClientScene.readyConnection != null)
|
||||
{
|
||||
ClientScene.readyConnection.Send(40, animationMessage);
|
||||
QSBClientScene.readyConnection.Send(40, animationMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -130,9 +130,9 @@ namespace QSB.Animation
|
||||
m_ParameterWriter.SeekZero();
|
||||
WriteParameters(m_ParameterWriter, true);
|
||||
parametersMessage.parameters = m_ParameterWriter.ToArray();
|
||||
if (HasAuthority && ClientScene.readyConnection != null)
|
||||
if (HasAuthority && QSBClientScene.readyConnection != null)
|
||||
{
|
||||
ClientScene.readyConnection.Send(41, parametersMessage);
|
||||
QSBClientScene.readyConnection.Send(41, parametersMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -274,7 +274,7 @@ namespace QSB.Animation
|
||||
{
|
||||
return;
|
||||
}
|
||||
var readyConnection = ClientScene.readyConnection;
|
||||
var readyConnection = QSBClientScene.readyConnection;
|
||||
if (readyConnection == null)
|
||||
{
|
||||
return;
|
||||
@ -291,7 +291,7 @@ namespace QSB.Animation
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OnAnimationServerMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationServerMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(AnimationMessage);
|
||||
var localObject = NetworkServer.FindLocalObject(AnimationMessage.netId);
|
||||
@ -305,7 +305,7 @@ namespace QSB.Animation
|
||||
NetworkServer.SendToReady(localObject, 40, AnimationMessage);
|
||||
}
|
||||
|
||||
internal static void OnAnimationParametersServerMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationParametersServerMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(ParametersMessage);
|
||||
var localObject = NetworkServer.FindLocalObject(ParametersMessage.netId);
|
||||
@ -319,7 +319,7 @@ namespace QSB.Animation
|
||||
NetworkServer.SendToReady(localObject, 41, ParametersMessage);
|
||||
}
|
||||
|
||||
internal static void OnAnimationTriggerServerMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationTriggerServerMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(TriggersMessage);
|
||||
var localObject = NetworkServer.FindLocalObject(TriggersMessage.netId);
|
||||
@ -332,10 +332,10 @@ namespace QSB.Animation
|
||||
NetworkServer.SendToReady(localObject, 42, TriggersMessage);
|
||||
}
|
||||
|
||||
internal static void OnAnimationClientMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationClientMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(AnimationMessage);
|
||||
var localObject = ClientScene.FindLocalObject(AnimationMessage.netId);
|
||||
var localObject = QSBClientScene.FindLocalObject(AnimationMessage.netId);
|
||||
if (localObject == null)
|
||||
return;
|
||||
var component = localObject.GetComponent<QSBNetworkAnimator>();
|
||||
@ -345,10 +345,10 @@ namespace QSB.Animation
|
||||
component.HandleAnimMsg(AnimationMessage, reader);
|
||||
}
|
||||
|
||||
internal static void OnAnimationParametersClientMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationParametersClientMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(ParametersMessage);
|
||||
var localObject = ClientScene.FindLocalObject(ParametersMessage.netId);
|
||||
var localObject = QSBClientScene.FindLocalObject(ParametersMessage.netId);
|
||||
if (localObject == null)
|
||||
return;
|
||||
var component = localObject.GetComponent<QSBNetworkAnimator>();
|
||||
@ -358,10 +358,10 @@ namespace QSB.Animation
|
||||
component.HandleAnimParamsMsg(ParametersMessage, reader);
|
||||
}
|
||||
|
||||
internal static void OnAnimationTriggerClientMessage(NetworkMessage netMsg)
|
||||
internal static void OnAnimationTriggerClientMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage(TriggersMessage);
|
||||
var localObject = ClientScene.FindLocalObject(TriggersMessage.netId);
|
||||
var localObject = QSBClientScene.FindLocalObject(TriggersMessage.netId);
|
||||
if (localObject == null)
|
||||
return;
|
||||
var component = localObject.GetComponent<QSBNetworkAnimator>();
|
||||
|
@ -132,6 +132,7 @@
|
||||
<Compile Include="Animation\Events\QSBAnimationTriggerMessage.cs" />
|
||||
<Compile Include="Animation\PlayerHeadRotationSync.cs" />
|
||||
<Compile Include="Animation\QSBNetworkAnimator.cs" />
|
||||
<Compile Include="QSBClientAuthorityMessage.cs" />
|
||||
<Compile Include="ConversationSync\Events\ConversationEvent.cs" />
|
||||
<Compile Include="ConversationSync\Events\ConversationMessage.cs" />
|
||||
<Compile Include="ConversationSync\ConversationPatches.cs" />
|
||||
@ -162,13 +163,29 @@
|
||||
<Compile Include="Patches\QSBPatchManager.cs" />
|
||||
<Compile Include="Player\Events\ServerSendPlayerStatesEvent.cs" />
|
||||
<Compile Include="Player\PlayerSyncObject.cs" />
|
||||
<Compile Include="QSBClientScene.cs" />
|
||||
<Compile Include="QSBInputManager.cs" />
|
||||
<Compile Include="QSBLocalClient.cs" />
|
||||
<Compile Include="QSBNetworkBehaviour.cs" />
|
||||
<Compile Include="QSBNetworkClient.cs" />
|
||||
<Compile Include="QSBNetworkConnection.cs" />
|
||||
<Compile Include="QSBNetworkIdentity.cs" />
|
||||
<Compile Include="QSBNetworkLobby.cs" />
|
||||
<Compile Include="Patches\QSBPatch.cs" />
|
||||
<Compile Include="Patches\QSBPatchTypes.cs" />
|
||||
<Compile Include="QSBNetworkMessage.cs" />
|
||||
<Compile Include="QSBNetworkMessageDelegate.cs" />
|
||||
<Compile Include="QSBNetworkMessageHandlers.cs" />
|
||||
<Compile Include="QSBNetworkScene.cs" />
|
||||
<Compile Include="QSBNetworkServer.cs" />
|
||||
<Compile Include="QSBObjectDestroyMessage.cs" />
|
||||
<Compile Include="QSBObjectSpawnFinishedMessage.cs" />
|
||||
<Compile Include="QSBObjectSpawnMessage.cs" />
|
||||
<Compile Include="QSBObjectSpawnSceneMessage.cs" />
|
||||
<Compile Include="QSBOwnerMessage.cs" />
|
||||
<Compile Include="QSBPlayerController.cs" />
|
||||
<Compile Include="QSBSceneManager.cs" />
|
||||
<Compile Include="QSBUtility.cs" />
|
||||
<Compile Include="TimeSync\TimeSyncType.cs" />
|
||||
<Compile Include="TimeSync\TimeSyncUI.cs" />
|
||||
<Compile Include="TimeSync\WakeUpPatches.cs" />
|
||||
|
27
QSB/QSBClientAuthorityMessage.cs
Normal file
27
QSB/QSBClientAuthorityMessage.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBClientAuthorityMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
netId = reader.ReadNetworkId();
|
||||
authority = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.Write(netId);
|
||||
writer.Write(authority);
|
||||
}
|
||||
|
||||
public NetworkInstanceId netId;
|
||||
|
||||
public bool authority;
|
||||
}
|
||||
}
|
952
QSB/QSBClientScene.cs
Normal file
952
QSB/QSBClientScene.cs
Normal file
@ -0,0 +1,952 @@
|
||||
using QSB.Animation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.Networking.NetworkSystem;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBClientScene
|
||||
{
|
||||
private static bool HasMigrationPending() => reconnectId != -1;
|
||||
|
||||
public static void SetReconnectId(int newReconnectId, PeerInfoMessage[] 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>();
|
||||
|
||||
public static bool ready { get; private set; }
|
||||
|
||||
public static QSBNetworkConnection readyConnection { get; private set; }
|
||||
|
||||
public static int reconnectId { get; private set; } = -1;
|
||||
|
||||
public static Dictionary<NetworkInstanceId, QSBNetworkIdentity> Objects => s_NetworkScene.localObjects;
|
||||
|
||||
public static Dictionary<NetworkHash128, GameObject> Prefabs => QSBNetworkScene.guidToPrefab;
|
||||
|
||||
public static Dictionary<NetworkSceneId, QSBNetworkIdentity> SpawnableObjects { get; private set; }
|
||||
|
||||
internal static void Shutdown()
|
||||
{
|
||||
s_NetworkScene.Shutdown();
|
||||
localPlayers = new List<QSBPlayerController>();
|
||||
s_PendingOwnerIds = new List<PendingOwner>();
|
||||
SpawnableObjects = null;
|
||||
readyConnection = null;
|
||||
ready = false;
|
||||
s_IsSpawnFinished = false;
|
||||
reconnectId = -1;
|
||||
NetworkTransport.Shutdown();
|
||||
NetworkTransport.Init();
|
||||
}
|
||||
|
||||
internal static bool GetPlayerController(short playerControllerId, out QSBPlayerController player)
|
||||
{
|
||||
player = null;
|
||||
bool result;
|
||||
if ((int)playerControllerId >= localPlayers.Count)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.Log("ClientScene::GetPlayer: no local player found for: " + playerControllerId);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else if (localPlayers[(int)playerControllerId] == null)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("ClientScene::GetPlayer: local player is null for: " + playerControllerId);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
player = localPlayers[(int)playerControllerId];
|
||||
result = (player.gameObject != null);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void InternalAddPlayer(QSBNetworkIdentity view, short playerControllerId)
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId : " + playerControllerId);
|
||||
}
|
||||
if ((int)playerControllerId >= localPlayers.Count)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("ClientScene::InternalAddPlayer: playerControllerId higher than expected: " + playerControllerId);
|
||||
}
|
||||
while ((int)playerControllerId >= localPlayers.Count)
|
||||
{
|
||||
localPlayers.Add(new QSBPlayerController());
|
||||
}
|
||||
}
|
||||
var playerController = new QSBPlayerController
|
||||
{
|
||||
gameObject = view.gameObject,
|
||||
playerControllerId = playerControllerId,
|
||||
unetView = view
|
||||
};
|
||||
localPlayers[(int)playerControllerId] = playerController;
|
||||
readyConnection.SetPlayerController(playerController);
|
||||
}
|
||||
|
||||
public static bool AddPlayer(short playerControllerId) => AddPlayer(null, playerControllerId);
|
||||
|
||||
public static bool AddPlayer(QSBNetworkConnection readyConn, short playerControllerId) => AddPlayer(readyConn, playerControllerId, null);
|
||||
|
||||
public static bool AddPlayer(QSBNetworkConnection readyConn, short playerControllerId, MessageBase extraMessage)
|
||||
{
|
||||
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[]
|
||||
{
|
||||
"ClientScene::AddPlayer: playerControllerId of ",
|
||||
playerControllerId,
|
||||
" is too high, max is ",
|
||||
32
|
||||
}));
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playerControllerId > 16)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is unusually high");
|
||||
}
|
||||
}
|
||||
while ((int)playerControllerId >= localPlayers.Count)
|
||||
{
|
||||
localPlayers.Add(new QSBPlayerController());
|
||||
}
|
||||
if (readyConn == null)
|
||||
{
|
||||
if (!ready)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Must call AddPlayer() with a connection the first time to become ready.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ready = true;
|
||||
readyConnection = readyConn;
|
||||
}
|
||||
if (readyConnection.GetPlayerController(playerControllerId, out var playerController))
|
||||
{
|
||||
if (playerController.IsValid && playerController.gameObject != null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " already in use.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::AddPlayer() for ID ",
|
||||
playerControllerId,
|
||||
" called with connection [",
|
||||
readyConnection,
|
||||
"]"
|
||||
}));
|
||||
}
|
||||
if (!HasMigrationPending())
|
||||
{
|
||||
var addPlayerMessage = new AddPlayerMessage
|
||||
{
|
||||
playerControllerId = playerControllerId
|
||||
};
|
||||
if (extraMessage != null)
|
||||
{
|
||||
var networkWriter = new NetworkWriter();
|
||||
extraMessage.Serialize(networkWriter);
|
||||
addPlayerMessage.msgData = networkWriter.ToArray();
|
||||
addPlayerMessage.msgSize = (int)networkWriter.Position;
|
||||
}
|
||||
readyConnection.Send(37, addPlayerMessage);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SendReconnectMessage(extraMessage);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool SendReconnectMessage(MessageBase extraMessage)
|
||||
{
|
||||
bool result;
|
||||
if (!HasMigrationPending())
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::AddPlayer reconnect " + reconnectId);
|
||||
}
|
||||
if (s_Peers == null)
|
||||
{
|
||||
SetReconnectId(-1, null);
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("ClientScene::AddPlayer: reconnecting, but no peers.");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < s_Peers.Length; i++)
|
||||
{
|
||||
var peerInfoMessage = s_Peers[i];
|
||||
if (peerInfoMessage.playerIds != null)
|
||||
{
|
||||
if (peerInfoMessage.connectionId == reconnectId)
|
||||
{
|
||||
for (var j = 0; j < peerInfoMessage.playerIds.Length; j++)
|
||||
{
|
||||
var reconnectMessage = new ReconnectMessage
|
||||
{
|
||||
oldConnectionId = reconnectId,
|
||||
netId = peerInfoMessage.playerIds[j].netId,
|
||||
playerControllerId = peerInfoMessage.playerIds[j].playerControllerId
|
||||
};
|
||||
if (extraMessage != null)
|
||||
{
|
||||
var networkWriter = new NetworkWriter();
|
||||
extraMessage.Serialize(networkWriter);
|
||||
reconnectMessage.msgData = networkWriter.ToArray();
|
||||
reconnectMessage.msgSize = (int)networkWriter.Position;
|
||||
}
|
||||
readyConnection.Send(47, reconnectMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SetReconnectId(-1, null);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool RemovePlayer(short playerControllerId)
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::RemovePlayer() for ID ",
|
||||
playerControllerId,
|
||||
" called with connection [",
|
||||
readyConnection,
|
||||
"]"
|
||||
}));
|
||||
}
|
||||
bool result;
|
||||
if (readyConnection.GetPlayerController(playerControllerId, out var playerController))
|
||||
{
|
||||
var removePlayerMessage = new RemovePlayerMessage
|
||||
{
|
||||
playerControllerId = playerControllerId
|
||||
};
|
||||
readyConnection.Send(38, removePlayerMessage);
|
||||
readyConnection.RemovePlayerController(playerControllerId);
|
||||
localPlayers[(int)playerControllerId] = new QSBPlayerController();
|
||||
UnityEngine.Object.Destroy(playerController.gameObject);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Failed to find player ID " + playerControllerId);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool Ready(QSBNetworkConnection conn)
|
||||
{
|
||||
bool result;
|
||||
if (ready)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("A connection has already been set as ready. There can only be one.");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::Ready() called with connection [" + conn + "]");
|
||||
}
|
||||
if (conn != null)
|
||||
{
|
||||
var msg = new ReadyMessage();
|
||||
conn.Send(35, msg);
|
||||
ready = true;
|
||||
readyConnection = conn;
|
||||
readyConnection.isReady = true;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Ready() called with invalid connection object: conn=null");
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static QSBNetworkClient ConnectLocalServer()
|
||||
{
|
||||
var localClient = new QSBLocalClient();
|
||||
QSBNetworkServer.instance.ActivateLocalClientScene();
|
||||
localClient.InternalConnectLocalServer(true);
|
||||
return localClient;
|
||||
}
|
||||
|
||||
internal static QSBNetworkClient ReconnectLocalServer()
|
||||
{
|
||||
var localClient = new QSBLocalClient();
|
||||
QSBNetworkServer.instance.ActivateLocalClientScene();
|
||||
localClient.InternalConnectLocalServer(false);
|
||||
return localClient;
|
||||
}
|
||||
|
||||
internal static void ClearLocalPlayers() => localPlayers.Clear();
|
||||
|
||||
internal static void HandleClientDisconnect(QSBNetworkConnection conn)
|
||||
{
|
||||
if (readyConnection == conn && ready)
|
||||
{
|
||||
ready = false;
|
||||
readyConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void PrepareToSpawnSceneObjects()
|
||||
{
|
||||
SpawnableObjects = new Dictionary<NetworkSceneId, QSBNetworkIdentity>();
|
||||
foreach (var networkIdentity in Resources.FindObjectsOfTypeAll<QSBNetworkIdentity>())
|
||||
{
|
||||
if (!networkIdentity.gameObject.activeSelf)
|
||||
{
|
||||
if (networkIdentity.gameObject.hideFlags != HideFlags.NotEditable && networkIdentity.gameObject.hideFlags != HideFlags.HideAndDontSave)
|
||||
{
|
||||
if (!networkIdentity.SceneId.IsEmpty())
|
||||
{
|
||||
SpawnableObjects[networkIdentity.SceneId] = networkIdentity;
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::PrepareSpawnObjects sceneId:" + networkIdentity.SceneId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static QSBNetworkIdentity SpawnSceneObject(NetworkSceneId sceneId)
|
||||
{
|
||||
QSBNetworkIdentity result;
|
||||
if (SpawnableObjects.ContainsKey(sceneId))
|
||||
{
|
||||
var networkIdentity = SpawnableObjects[sceneId];
|
||||
SpawnableObjects.Remove(sceneId);
|
||||
result = networkIdentity;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void RegisterSystemHandlers(QSBNetworkClient client, bool localClient)
|
||||
{
|
||||
if (localClient)
|
||||
{
|
||||
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((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((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)
|
||||
{
|
||||
string result;
|
||||
if (QSBNetworkScene.GetPrefab(assetId, out var gameObject))
|
||||
{
|
||||
result = gameObject.name;
|
||||
}
|
||||
else if (QSBNetworkScene.GetSpawnHandler(assetId, out var func))
|
||||
{
|
||||
result = func.GetMethodName();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "unknown";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void RegisterPrefab(GameObject prefab, NetworkHash128 newAssetId) => QSBNetworkScene.RegisterPrefab(prefab, newAssetId);
|
||||
|
||||
public static void RegisterPrefab(GameObject prefab) => QSBNetworkScene.RegisterPrefab(prefab);
|
||||
|
||||
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, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler) => QSBNetworkScene.RegisterSpawnHandler(assetId, spawnHandler, unspawnHandler);
|
||||
|
||||
public static void UnregisterSpawnHandler(NetworkHash128 assetId) => QSBNetworkScene.UnregisterSpawnHandler(assetId);
|
||||
|
||||
public static void ClearSpawners() => QSBNetworkScene.ClearSpawners();
|
||||
|
||||
public static void DestroyAllClientObjects() => s_NetworkScene.DestroyAllClientObjects();
|
||||
|
||||
public static void SetLocalObject(NetworkInstanceId netId, GameObject obj) => s_NetworkScene.SetLocalObject(netId, obj, s_IsSpawnFinished, false);
|
||||
|
||||
public static GameObject FindLocalObject(NetworkInstanceId netId) => s_NetworkScene.FindLocalObject(netId);
|
||||
|
||||
private static void ApplySpawnPayload(QSBNetworkIdentity uv, Vector3 position, byte[] payload, NetworkInstanceId netId, GameObject newGameObject)
|
||||
{
|
||||
if (!uv.gameObject.activeSelf)
|
||||
{
|
||||
uv.gameObject.SetActive(true);
|
||||
}
|
||||
uv.transform.position = position;
|
||||
if (payload != null && payload.Length > 0)
|
||||
{
|
||||
var reader = new NetworkReader(payload);
|
||||
uv.OnUpdateVars(reader, true);
|
||||
}
|
||||
if (!(newGameObject == null))
|
||||
{
|
||||
newGameObject.SetActive(true);
|
||||
uv.SetNetworkInstanceId(netId);
|
||||
SetLocalObject(netId, newGameObject);
|
||||
if (s_IsSpawnFinished)
|
||||
{
|
||||
uv.OnStartClient();
|
||||
CheckForOwner(uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnObjectSpawn(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectSpawnMessage>(s_ObjectSpawnMessage);
|
||||
if (!s_ObjectSpawnMessage.assetId.IsValid())
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("OnObjSpawn netId: " + s_ObjectSpawnMessage.netId + " has invalid asset Id");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Client spawn handler instantiating [netId:",
|
||||
s_ObjectSpawnMessage.netId,
|
||||
" asset ID:",
|
||||
s_ObjectSpawnMessage.assetId,
|
||||
" pos:",
|
||||
s_ObjectSpawnMessage.position,
|
||||
"]"
|
||||
}));
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectSpawnMessage.netId, out var component))
|
||||
{
|
||||
ApplySpawnPayload(component, s_ObjectSpawnMessage.position, s_ObjectSpawnMessage.payload, s_ObjectSpawnMessage.netId, null);
|
||||
}
|
||||
else if (QSBNetworkScene.GetPrefab(s_ObjectSpawnMessage.assetId, out var original))
|
||||
{
|
||||
GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(original, s_ObjectSpawnMessage.position, s_ObjectSpawnMessage.rotation);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Client spawn handler instantiating [netId:",
|
||||
s_ObjectSpawnMessage.netId,
|
||||
" asset ID:",
|
||||
s_ObjectSpawnMessage.assetId,
|
||||
" pos:",
|
||||
s_ObjectSpawnMessage.position,
|
||||
" rotation: ",
|
||||
s_ObjectSpawnMessage.rotation,
|
||||
"]"
|
||||
}));
|
||||
}
|
||||
component = gameObject.GetComponent<QSBNetworkIdentity>();
|
||||
if (component == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Client object spawned for " + s_ObjectSpawnMessage.assetId + " does not have a NetworkIdentity");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component.Reset();
|
||||
ApplySpawnPayload(component, s_ObjectSpawnMessage.position, s_ObjectSpawnMessage.payload, s_ObjectSpawnMessage.netId, gameObject);
|
||||
}
|
||||
}
|
||||
else if (QSBNetworkScene.GetSpawnHandler(s_ObjectSpawnMessage.assetId, out var spawnDelegate))
|
||||
{
|
||||
var gameObject2 = spawnDelegate(s_ObjectSpawnMessage.position, s_ObjectSpawnMessage.assetId);
|
||||
if (gameObject2 == null)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("Client spawn handler for " + s_ObjectSpawnMessage.assetId + " returned null");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component = gameObject2.GetComponent<QSBNetworkIdentity>();
|
||||
if (component == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Client object spawned for " + s_ObjectSpawnMessage.assetId + " does not have a network identity");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component.Reset();
|
||||
component.SetDynamicAssetId(s_ObjectSpawnMessage.assetId);
|
||||
ApplySpawnPayload(component, s_ObjectSpawnMessage.position, s_ObjectSpawnMessage.payload, s_ObjectSpawnMessage.netId, gameObject2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError(string.Concat(new object[]
|
||||
{
|
||||
"Failed to spawn server object, did you forget to add it to the NetworkManager? assetId=",
|
||||
s_ObjectSpawnMessage.assetId,
|
||||
" netId=",
|
||||
s_ObjectSpawnMessage.netId
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnObjectSpawnScene(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectSpawnSceneMessage>(s_ObjectSpawnSceneMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Client spawn scene handler instantiating [netId:",
|
||||
s_ObjectSpawnSceneMessage.netId,
|
||||
" sceneId:",
|
||||
s_ObjectSpawnSceneMessage.sceneId,
|
||||
" pos:",
|
||||
s_ObjectSpawnSceneMessage.position
|
||||
}));
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectSpawnSceneMessage.netId, out var networkIdentity))
|
||||
{
|
||||
ApplySpawnPayload(networkIdentity, s_ObjectSpawnSceneMessage.position, s_ObjectSpawnSceneMessage.payload, s_ObjectSpawnSceneMessage.netId, networkIdentity.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
var networkIdentity2 = SpawnSceneObject(s_ObjectSpawnSceneMessage.sceneId);
|
||||
if (networkIdentity2 == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Spawn scene object not found for " + s_ObjectSpawnSceneMessage.sceneId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Client spawn for [netId:",
|
||||
s_ObjectSpawnSceneMessage.netId,
|
||||
"] [sceneId:",
|
||||
s_ObjectSpawnSceneMessage.sceneId,
|
||||
"] obj:",
|
||||
networkIdentity2.gameObject.name
|
||||
}));
|
||||
}
|
||||
ApplySpawnPayload(networkIdentity2, s_ObjectSpawnSceneMessage.position, s_ObjectSpawnSceneMessage.payload, s_ObjectSpawnSceneMessage.netId, networkIdentity2.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnObjectSpawnFinished(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectSpawnFinishedMessage>(s_ObjectSpawnFinishedMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("SpawnFinished:" + s_ObjectSpawnFinishedMessage.state);
|
||||
}
|
||||
if (s_ObjectSpawnFinishedMessage.state == 0U)
|
||||
{
|
||||
PrepareToSpawnSceneObjects();
|
||||
s_IsSpawnFinished = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var networkIdentity in Objects.Values)
|
||||
{
|
||||
if (!networkIdentity.IsClient)
|
||||
{
|
||||
networkIdentity.OnStartClient();
|
||||
CheckForOwner(networkIdentity);
|
||||
}
|
||||
}
|
||||
s_IsSpawnFinished = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnObjectDestroy(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectDestroyMessage>(s_ObjectDestroyMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::OnObjDestroy netId:" + s_ObjectDestroyMessage.netId);
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectDestroyMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.OnNetworkDestroy();
|
||||
if (!QSBNetworkScene.InvokeUnSpawnHandler(networkIdentity.AssetId, networkIdentity.gameObject))
|
||||
{
|
||||
if (networkIdentity.SceneId.IsEmpty())
|
||||
{
|
||||
UnityEngine.Object.Destroy(networkIdentity.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
networkIdentity.gameObject.SetActive(false);
|
||||
SpawnableObjects[networkIdentity.SceneId] = networkIdentity;
|
||||
}
|
||||
}
|
||||
s_NetworkScene.RemoveLocalObject(s_ObjectDestroyMessage.netId);
|
||||
networkIdentity.MarkForReset();
|
||||
}
|
||||
else if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.LogWarning("Did not find target for destroy message for " + s_ObjectDestroyMessage.netId);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnLocalClientObjectDestroy(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectDestroyMessage>(s_ObjectDestroyMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::OnLocalObjectObjDestroy netId:" + s_ObjectDestroyMessage.netId);
|
||||
}
|
||||
s_NetworkScene.RemoveLocalObject(s_ObjectDestroyMessage.netId);
|
||||
}
|
||||
|
||||
private static void OnLocalClientObjectHide(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectDestroyMessage>(s_ObjectDestroyMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::OnLocalObjectObjHide netId:" + s_ObjectDestroyMessage.netId);
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectDestroyMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.OnSetLocalVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnLocalClientObjectSpawn(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectSpawnMessage>(s_ObjectSpawnMessage);
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectSpawnMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.OnSetLocalVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnLocalClientObjectSpawnScene(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBObjectSpawnSceneMessage>(s_ObjectSpawnSceneMessage);
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ObjectSpawnSceneMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.OnSetLocalVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnUpdateVarsMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
var networkInstanceId = netMsg.reader.ReadNetworkId();
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::OnUpdateVarsMessage ",
|
||||
networkInstanceId,
|
||||
" channel:",
|
||||
netMsg.channelId
|
||||
}));
|
||||
if (s_NetworkScene.GetNetworkIdentity(networkInstanceId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.OnUpdateVars(netMsg.reader, false);
|
||||
}
|
||||
else if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("Did not find target for sync message for " + networkInstanceId);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRPCMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
var num = (int)netMsg.reader.ReadPackedUInt32();
|
||||
var networkInstanceId = netMsg.reader.ReadNetworkId();
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::OnRPCMessage hash:",
|
||||
num,
|
||||
" netId:",
|
||||
networkInstanceId
|
||||
}));
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(networkInstanceId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.HandleRPC(num, netMsg.reader);
|
||||
}
|
||||
else if (LogFilter.logWarn)
|
||||
{
|
||||
string cmdHashHandlerName = QSBNetworkBehaviour.GetCmdHashHandlerName(num);
|
||||
Debug.LogWarningFormat("Could not find target object with netId:{0} for RPC call {1}", new object[]
|
||||
{
|
||||
networkInstanceId,
|
||||
cmdHashHandlerName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSyncEventMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
var cmdHash = (int)netMsg.reader.ReadPackedUInt32();
|
||||
var networkInstanceId = netMsg.reader.ReadNetworkId();
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::OnSyncEventMessage " + networkInstanceId);
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(networkInstanceId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.HandleSyncEvent(cmdHash, netMsg.reader);
|
||||
}
|
||||
else if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("Did not find target for SyncEvent message for " + networkInstanceId);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSyncListMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
var networkInstanceId = netMsg.reader.ReadNetworkId();
|
||||
var cmdHash = (int)netMsg.reader.ReadPackedUInt32();
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log("ClientScene::OnSyncListMessage " + networkInstanceId);
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(networkInstanceId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.HandleSyncList(cmdHash, netMsg.reader);
|
||||
}
|
||||
else if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("Did not find target for SyncList message for " + networkInstanceId);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnClientAuthority(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBClientAuthorityMessage>(s_ClientAuthorityMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::OnClientAuthority for connectionId=",
|
||||
netMsg.conn.connectionId,
|
||||
" netId: ",
|
||||
s_ClientAuthorityMessage.netId
|
||||
}));
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_ClientAuthorityMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.HandleClientAuthority(s_ClientAuthorityMessage.authority);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnOwnerMessage(QSBNetworkMessage netMsg)
|
||||
{
|
||||
netMsg.ReadMessage<QSBOwnerMessage>(s_OwnerMessage);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ClientScene::OnOwnerMessage - connectionId=",
|
||||
netMsg.conn.connectionId,
|
||||
" netId: ",
|
||||
s_OwnerMessage.netId
|
||||
}));
|
||||
}
|
||||
if (netMsg.conn.GetPlayerController(s_OwnerMessage.playerControllerId, out var playerController))
|
||||
{
|
||||
playerController.unetView.SetNotLocalPlayer();
|
||||
}
|
||||
if (s_NetworkScene.GetNetworkIdentity(s_OwnerMessage.netId, out var networkIdentity))
|
||||
{
|
||||
networkIdentity.SetConnectionToServer(netMsg.conn);
|
||||
networkIdentity.SetLocalPlayer(s_OwnerMessage.playerControllerId);
|
||||
InternalAddPlayer(networkIdentity, s_OwnerMessage.playerControllerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var item = new PendingOwner
|
||||
{
|
||||
netId = s_OwnerMessage.netId,
|
||||
playerControllerId = s_OwnerMessage.playerControllerId
|
||||
};
|
||||
s_PendingOwnerIds.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckForOwner(QSBNetworkIdentity uv)
|
||||
{
|
||||
var i = 0;
|
||||
while (i < s_PendingOwnerIds.Count)
|
||||
{
|
||||
var pendingOwner = s_PendingOwnerIds[i];
|
||||
if (pendingOwner.netId == uv.NetId)
|
||||
{
|
||||
uv.SetConnectionToServer(readyConnection);
|
||||
uv.SetLocalPlayer(pendingOwner.playerControllerId);
|
||||
Debug.Log("ClientScene::OnOwnerMessage - player=" + uv.gameObject.name);
|
||||
if (readyConnection.connectionId < 0)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Owner message received on a local client.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
InternalAddPlayer(uv, pendingOwner.playerControllerId);
|
||||
s_PendingOwnerIds.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool s_IsSpawnFinished;
|
||||
|
||||
private static QSBNetworkScene s_NetworkScene = new QSBNetworkScene();
|
||||
|
||||
private static QSBObjectSpawnSceneMessage s_ObjectSpawnSceneMessage = new QSBObjectSpawnSceneMessage();
|
||||
|
||||
private static QSBObjectSpawnFinishedMessage s_ObjectSpawnFinishedMessage = new QSBObjectSpawnFinishedMessage();
|
||||
|
||||
private static QSBObjectDestroyMessage s_ObjectDestroyMessage = new QSBObjectDestroyMessage();
|
||||
|
||||
private static QSBObjectSpawnMessage s_ObjectSpawnMessage = new QSBObjectSpawnMessage();
|
||||
|
||||
private static QSBOwnerMessage s_OwnerMessage = new QSBOwnerMessage();
|
||||
|
||||
private static QSBClientAuthorityMessage s_ClientAuthorityMessage = new QSBClientAuthorityMessage();
|
||||
|
||||
public const int ReconnectIdInvalid = -1;
|
||||
|
||||
public const int ReconnectIdHost = 0;
|
||||
|
||||
private static PeerInfoMessage[] s_Peers;
|
||||
|
||||
private static List<PendingOwner> s_PendingOwnerIds = new List<PendingOwner>();
|
||||
|
||||
private struct PendingOwner
|
||||
{
|
||||
public NetworkInstanceId netId;
|
||||
|
||||
public short playerControllerId;
|
||||
}
|
||||
}
|
||||
}
|
162
QSB/QSBLocalClient.cs
Normal file
162
QSB/QSBLocalClient.cs
Normal file
@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBLocalClient : QSBNetworkClient
|
||||
{
|
||||
public override void Disconnect()
|
||||
{
|
||||
QSBClientScene.HandleClientDisconnect(m_Connection);
|
||||
if (m_Connected)
|
||||
{
|
||||
PostInternalMessage(33);
|
||||
m_Connected = false;
|
||||
}
|
||||
m_AsyncConnect = QSBNetworkClient.ConnectState.Disconnected;
|
||||
m_LocalServer.RemoveLocalClient(m_Connection);
|
||||
}
|
||||
|
||||
internal void InternalConnectLocalServer(bool generateConnectMsg)
|
||||
{
|
||||
if (m_FreeMessages == null)
|
||||
{
|
||||
m_FreeMessages = new Stack<InternalMsg>();
|
||||
for (var i = 0; i < 64; i++)
|
||||
{
|
||||
var t = default(InternalMsg);
|
||||
m_FreeMessages.Push(t);
|
||||
}
|
||||
}
|
||||
m_LocalServer = QSBNetworkServer.instance;
|
||||
m_Connection = new ULocalConnectionToServer(m_LocalServer);
|
||||
base.SetHandlers(m_Connection);
|
||||
m_Connection.connectionId = m_LocalServer.AddLocalClient(this);
|
||||
m_AsyncConnect = QSBNetworkClient.ConnectState.Connected;
|
||||
QSBNetworkClient.SetActive(true);
|
||||
base.RegisterSystemHandlers(true);
|
||||
if (generateConnectMsg)
|
||||
{
|
||||
PostInternalMessage(32);
|
||||
}
|
||||
m_Connected = true;
|
||||
}
|
||||
|
||||
internal override void Update() => ProcessInternalMessages();
|
||||
|
||||
internal void AddLocalPlayer(QSBPlayerController localPlayer)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Local client AddLocalPlayer ",
|
||||
localPlayer.gameObject.name,
|
||||
" conn=",
|
||||
m_Connection.connectionId
|
||||
}));
|
||||
m_Connection.isReady = true;
|
||||
m_Connection.SetPlayerController(localPlayer);
|
||||
var unetView = localPlayer.unetView;
|
||||
if (unetView != null)
|
||||
{
|
||||
QSBClientScene.SetLocalObject(unetView.NetId, localPlayer.gameObject);
|
||||
unetView.SetConnectionToServer(m_Connection);
|
||||
}
|
||||
QSBClientScene.InternalAddPlayer(unetView, localPlayer.playerControllerId);
|
||||
}
|
||||
|
||||
private void PostInternalMessage(byte[] buffer, int channelId)
|
||||
{
|
||||
InternalMsg item;
|
||||
if (m_FreeMessages.Count == 0)
|
||||
{
|
||||
item = default;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = m_FreeMessages.Pop();
|
||||
}
|
||||
item.buffer = buffer;
|
||||
item.channelId = channelId;
|
||||
m_InternalMsgs.Add(item);
|
||||
}
|
||||
|
||||
private void PostInternalMessage(short msgType)
|
||||
{
|
||||
var networkWriter = new NetworkWriter();
|
||||
networkWriter.StartMessage(msgType);
|
||||
networkWriter.FinishMessage();
|
||||
PostInternalMessage(networkWriter.AsArray(), 0);
|
||||
}
|
||||
|
||||
private void ProcessInternalMessages()
|
||||
{
|
||||
if (m_InternalMsgs.Count != 0)
|
||||
{
|
||||
var internalMsgs = m_InternalMsgs;
|
||||
m_InternalMsgs = m_InternalMsgs2;
|
||||
for (var i = 0; i < internalMsgs.Count; i++)
|
||||
{
|
||||
var t = internalMsgs[i];
|
||||
if (s_InternalMessage.reader == null)
|
||||
{
|
||||
s_InternalMessage.reader = new NetworkReader(t.buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_InternalMessage.reader.Replace(t.buffer);
|
||||
}
|
||||
s_InternalMessage.reader.ReadInt16();
|
||||
s_InternalMessage.channelId = t.channelId;
|
||||
s_InternalMessage.conn = base.connection;
|
||||
s_InternalMessage.msgType = s_InternalMessage.reader.ReadInt16();
|
||||
m_Connection.InvokeHandler(s_InternalMessage);
|
||||
m_FreeMessages.Push(t);
|
||||
base.connection.lastMessageTime = Time.time;
|
||||
}
|
||||
m_InternalMsgs = internalMsgs;
|
||||
m_InternalMsgs.Clear();
|
||||
for (var j = 0; j < m_InternalMsgs2.Count; j++)
|
||||
{
|
||||
m_InternalMsgs.Add(m_InternalMsgs2[j]);
|
||||
}
|
||||
m_InternalMsgs2.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal void InvokeHandlerOnClient(short msgType, MessageBase msg, int channelId)
|
||||
{
|
||||
var networkWriter = new NetworkWriter();
|
||||
networkWriter.StartMessage(msgType);
|
||||
msg.Serialize(networkWriter);
|
||||
networkWriter.FinishMessage();
|
||||
InvokeBytesOnClient(networkWriter.AsArray(), channelId);
|
||||
}
|
||||
|
||||
internal void InvokeBytesOnClient(byte[] buffer, int channelId) => PostInternalMessage(buffer, channelId);
|
||||
|
||||
private const int k_InitialFreeMessagePoolSize = 64;
|
||||
|
||||
private List<InternalMsg> m_InternalMsgs = new List<InternalMsg>();
|
||||
|
||||
private readonly List<InternalMsg> m_InternalMsgs2 = new List<InternalMsg>();
|
||||
|
||||
private Stack<InternalMsg> m_FreeMessages;
|
||||
|
||||
private QSBNetworkServer m_LocalServer;
|
||||
|
||||
private bool m_Connected;
|
||||
|
||||
private readonly QSBNetworkMessage s_InternalMessage = new QSBNetworkMessage();
|
||||
|
||||
private struct InternalMsg
|
||||
{
|
||||
internal byte[] buffer;
|
||||
|
||||
internal int channelId;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,8 +15,8 @@ namespace QSB
|
||||
public bool IsLocalPlayer => MyView.IsLocalPlayer;
|
||||
public bool HasAuthority => MyView.HasAuthority;
|
||||
public NetworkInstanceId NetId => MyView.NetId;
|
||||
public NetworkConnection ConnectionToServer => MyView.ConnectionToServer;
|
||||
public NetworkConnection ConnectionToClient => MyView.ConnectionToClient;
|
||||
public QSBNetworkConnection ConnectionToServer => MyView.ConnectionToServer;
|
||||
public QSBNetworkConnection ConnectionToClient => MyView.ConnectionToClient;
|
||||
public short PlayerControllerId => MyView.PlayerControllerId;
|
||||
|
||||
protected uint SyncVarDirtyBits { get; private set; }
|
||||
@ -52,14 +52,14 @@ namespace QSB
|
||||
{
|
||||
Debug.LogWarning("Trying to send command for object without authority.");
|
||||
}
|
||||
else if (ClientScene.readyConnection == null)
|
||||
else if (QSBClientScene.readyConnection == null)
|
||||
{
|
||||
Debug.LogError("Send command attempted with no client running [client=" + ConnectionToServer + "].");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.FinishMessage();
|
||||
ClientScene.readyConnection.SendWriter(writer, channelId);
|
||||
QSBClientScene.readyConnection.SendWriter(writer, channelId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ namespace QSB
|
||||
public virtual void OnStartLocalPlayer() { }
|
||||
public virtual void OnStartAuthority() { }
|
||||
public virtual void OnStopAuthority() { }
|
||||
public virtual bool OnRebuildObservers(HashSet<NetworkConnection> observers, bool initialize) => false;
|
||||
public virtual bool OnRebuildObservers(HashSet<QSBNetworkConnection> observers, bool initialize) => false;
|
||||
public virtual void OnSetLocalVisibility(bool vis) { }
|
||||
public virtual bool OnCheckObserver(NetworkConnection conn) => true;
|
||||
public virtual int GetNetworkChannel() => 0;
|
||||
|
1213
QSB/QSBNetworkClient.cs
Normal file
1213
QSB/QSBNetworkClient.cs
Normal file
File diff suppressed because it is too large
Load Diff
561
QSB/QSBNetworkConnection.cs
Normal file
561
QSB/QSBNetworkConnection.cs
Normal file
@ -0,0 +1,561 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBNetworkConnection : IDisposable
|
||||
{
|
||||
public QSBNetworkConnection()
|
||||
{
|
||||
m_Writer = new NetworkWriter();
|
||||
}
|
||||
|
||||
internal HashSet<QSBNetworkIdentity> VisList { get; } = new HashSet<QSBNetworkIdentity>();
|
||||
|
||||
public List<QSBPlayerController> PlayerControllers { get; } = new List<QSBPlayerController>();
|
||||
|
||||
public HashSet<NetworkInstanceId> ClientOwnedObjects { get; private set; }
|
||||
|
||||
public bool isConnected => hostId != -1;
|
||||
|
||||
public NetworkError LastError { get; internal set; }
|
||||
|
||||
internal Dictionary<short, PacketStat> PacketStats { get; } = new Dictionary<short, PacketStat>();
|
||||
|
||||
public virtual void Initialize(string networkAddress, int networkHostId, int networkConnectionId, HostTopology hostTopology)
|
||||
{
|
||||
m_Writer = new NetworkWriter();
|
||||
address = networkAddress;
|
||||
hostId = networkHostId;
|
||||
connectionId = networkConnectionId;
|
||||
var channelCount = hostTopology.DefaultConfig.ChannelCount;
|
||||
var packetSize = (int)hostTopology.DefaultConfig.PacketSize;
|
||||
if (hostTopology.DefaultConfig.UsePlatformSpecificProtocols && Application.platform != RuntimePlatform.PS4 && Application.platform != RuntimePlatform.PSP2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Platform specific protocols are not supported on this platform");
|
||||
}
|
||||
m_Channels = new ChannelBuffer[channelCount];
|
||||
for (var i = 0; i < channelCount; i++)
|
||||
{
|
||||
var channelQOS = hostTopology.DefaultConfig.Channels[i];
|
||||
var bufferSize = packetSize;
|
||||
if (channelQOS.QOS == QosType.ReliableFragmented || channelQOS.QOS == QosType.UnreliableFragmented)
|
||||
{
|
||||
bufferSize = (int)(hostTopology.DefaultConfig.FragmentSize * 128);
|
||||
}
|
||||
m_Channels[i] = new ChannelBuffer(this, bufferSize, (byte)i, IsReliableQoS(channelQOS.QOS), IsSequencedQoS(channelQOS.QOS));
|
||||
}
|
||||
}
|
||||
|
||||
~QSBNetworkConnection()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!m_Disposed && m_Channels != null)
|
||||
{
|
||||
for (var i = 0; i < m_Channels.Length; i++)
|
||||
{
|
||||
m_Channels[i].Dispose();
|
||||
}
|
||||
}
|
||||
m_Channels = null;
|
||||
if (ClientOwnedObjects != null)
|
||||
{
|
||||
foreach (var netId in ClientOwnedObjects)
|
||||
{
|
||||
var gameObject = NetworkServer.FindLocalObject(netId);
|
||||
if (gameObject != null)
|
||||
{
|
||||
gameObject.GetComponent<QSBNetworkIdentity>().ClearClientOwner();
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientOwnedObjects = null;
|
||||
m_Disposed = true;
|
||||
}
|
||||
|
||||
private static bool IsSequencedQoS(QosType qos) => qos == QosType.ReliableSequenced || qos == QosType.UnreliableSequenced;
|
||||
|
||||
private static bool IsReliableQoS(QosType qos) => qos == QosType.Reliable || qos == QosType.ReliableFragmented || qos == QosType.ReliableSequenced || qos == QosType.ReliableStateUpdate;
|
||||
|
||||
public bool SetChannelOption(int channelId, ChannelOption option, int value) => m_Channels != null && channelId >= 0 && channelId < m_Channels.Length && m_Channels[channelId].SetOption(option, value);
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
address = "";
|
||||
isReady = false;
|
||||
QSBClientScene.HandleClientDisconnect(this);
|
||||
if (hostId != -1)
|
||||
{
|
||||
byte b;
|
||||
NetworkTransport.Disconnect(hostId, connectionId, out b);
|
||||
RemoveObservers();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetHandlers(QSBNetworkMessageHandlers handlers)
|
||||
{
|
||||
m_MessageHandlers = handlers;
|
||||
m_MessageHandlersDict = handlers.GetHandlers();
|
||||
}
|
||||
|
||||
public bool CheckHandler(short msgType) => m_MessageHandlersDict.ContainsKey(msgType);
|
||||
|
||||
public bool InvokeHandlerNoData(short msgType) => InvokeHandler(msgType, null, 0);
|
||||
|
||||
public bool InvokeHandler(short msgType, NetworkReader reader, int channelId)
|
||||
{
|
||||
bool result;
|
||||
if (m_MessageHandlersDict.ContainsKey(msgType))
|
||||
{
|
||||
m_MessageInfo.msgType = msgType;
|
||||
m_MessageInfo.conn = this;
|
||||
m_MessageInfo.reader = reader;
|
||||
m_MessageInfo.channelId = channelId;
|
||||
var networkMessageDelegate = m_MessageHandlersDict[msgType];
|
||||
if (networkMessageDelegate == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("NetworkConnection InvokeHandler no handler for " + msgType);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
networkMessageDelegate(m_MessageInfo);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool InvokeHandler(QSBNetworkMessage netMsg)
|
||||
{
|
||||
bool result;
|
||||
if (m_MessageHandlersDict.ContainsKey(netMsg.msgType))
|
||||
{
|
||||
var networkMessageDelegate = m_MessageHandlersDict[netMsg.msgType];
|
||||
networkMessageDelegate(netMsg);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void HandleFragment(NetworkReader reader, int channelId)
|
||||
{
|
||||
if (channelId >= 0 && channelId < m_Channels.Length)
|
||||
{
|
||||
var channelBuffer = m_Channels[channelId];
|
||||
if (channelBuffer.HandleFragment(reader))
|
||||
{
|
||||
var networkReader = new NetworkReader(channelBuffer.fragmentBuffer.AsArraySegment().Array);
|
||||
networkReader.ReadInt16();
|
||||
var msgType = networkReader.ReadInt16();
|
||||
InvokeHandler(msgType, networkReader, channelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler) => m_MessageHandlers.RegisterHandler(msgType, handler);
|
||||
|
||||
public void UnregisterHandler(short msgType) => m_MessageHandlers.UnregisterHandler(msgType);
|
||||
|
||||
internal void SetPlayerController(QSBPlayerController player)
|
||||
{
|
||||
while ((int)player.playerControllerId >= PlayerControllers.Count)
|
||||
{
|
||||
PlayerControllers.Add(new QSBPlayerController());
|
||||
}
|
||||
PlayerControllers[(int)player.playerControllerId] = player;
|
||||
}
|
||||
|
||||
internal void RemovePlayerController(short playerControllerId)
|
||||
{
|
||||
for (var i = PlayerControllers.Count; i >= 0; i--)
|
||||
{
|
||||
if ((int)playerControllerId == i && playerControllerId == PlayerControllers[i].playerControllerId)
|
||||
{
|
||||
PlayerControllers[i] = new QSBPlayerController();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("RemovePlayer player at playerControllerId " + playerControllerId + " not found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool GetPlayerController(short playerControllerId, out QSBPlayerController playerController)
|
||||
{
|
||||
playerController = null;
|
||||
bool result;
|
||||
if (PlayerControllers.Count > 0)
|
||||
{
|
||||
for (var i = 0; i < PlayerControllers.Count; i++)
|
||||
{
|
||||
if (PlayerControllers[i].IsValid && PlayerControllers[i].playerControllerId == playerControllerId)
|
||||
{
|
||||
playerController = PlayerControllers[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void FlushChannels()
|
||||
{
|
||||
if (m_Channels != null)
|
||||
{
|
||||
for (var i = 0; i < m_Channels.Length; i++)
|
||||
{
|
||||
m_Channels[i].CheckInternalBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMaxDelay(float seconds)
|
||||
{
|
||||
if (m_Channels != null)
|
||||
{
|
||||
for (var i = 0; i < m_Channels.Length; i++)
|
||||
{
|
||||
m_Channels[i].maxDelay = seconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Send(short msgType, MessageBase msg) => SendByChannel(msgType, msg, 0);
|
||||
|
||||
public virtual bool SendUnreliable(short msgType, MessageBase msg) => SendByChannel(msgType, msg, 1);
|
||||
|
||||
public virtual bool SendByChannel(short msgType, MessageBase msg, int channelId)
|
||||
{
|
||||
m_Writer.StartMessage(msgType);
|
||||
msg.Serialize(m_Writer);
|
||||
m_Writer.FinishMessage();
|
||||
return SendWriter(m_Writer, channelId);
|
||||
}
|
||||
|
||||
public virtual bool SendBytes(byte[] bytes, int numBytes, int channelId)
|
||||
{
|
||||
if (logNetworkMessages)
|
||||
{
|
||||
LogSend(bytes);
|
||||
}
|
||||
return CheckChannel(channelId) && m_Channels[channelId].SendBytes(bytes, numBytes);
|
||||
}
|
||||
|
||||
public virtual bool SendWriter(NetworkWriter writer, int channelId)
|
||||
{
|
||||
if (logNetworkMessages)
|
||||
{
|
||||
LogSend(writer.ToArray());
|
||||
}
|
||||
return CheckChannel(channelId) && m_Channels[channelId].SendWriter(writer);
|
||||
}
|
||||
|
||||
private void LogSend(byte[] bytes)
|
||||
{
|
||||
var networkReader = new NetworkReader(bytes);
|
||||
var num = networkReader.ReadUInt16();
|
||||
var num2 = networkReader.ReadUInt16();
|
||||
var stringBuilder = new StringBuilder();
|
||||
for (var i = 4; i < (int)(4 + num); i++)
|
||||
{
|
||||
stringBuilder.AppendFormat("{0:X2}", bytes[i]);
|
||||
if (i > 150)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ConnectionSend con:",
|
||||
connectionId,
|
||||
" bytes:",
|
||||
num,
|
||||
" msgId:",
|
||||
num2,
|
||||
" ",
|
||||
stringBuilder
|
||||
}));
|
||||
}
|
||||
|
||||
private bool CheckChannel(int channelId)
|
||||
{
|
||||
bool result;
|
||||
if (m_Channels == null)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("Channels not initialized sending on id '" + channelId);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else if (channelId < 0 || channelId >= m_Channels.Length)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError(string.Concat(new object[]
|
||||
{
|
||||
"Invalid channel when sending buffered data, '",
|
||||
channelId,
|
||||
"'. Current channel count is ",
|
||||
m_Channels.Length
|
||||
}));
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ResetStats()
|
||||
{
|
||||
}
|
||||
|
||||
protected void HandleBytes(byte[] buffer, int receivedSize, int channelId)
|
||||
{
|
||||
var reader = new NetworkReader(buffer);
|
||||
HandleReader(reader, receivedSize, channelId);
|
||||
}
|
||||
|
||||
protected void HandleReader(NetworkReader reader, int receivedSize, int channelId)
|
||||
{
|
||||
while ((ulong)reader.Position < (ulong)((long)receivedSize))
|
||||
{
|
||||
var num = reader.ReadUInt16();
|
||||
var num2 = reader.ReadInt16();
|
||||
var array = reader.ReadBytes((int)num);
|
||||
var reader2 = new NetworkReader(array);
|
||||
if (logNetworkMessages)
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
for (var i = 0; i < (int)num; i++)
|
||||
{
|
||||
stringBuilder.AppendFormat("{0:X2}", array[i]);
|
||||
if (i > 150)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ConnectionRecv con:",
|
||||
connectionId,
|
||||
" bytes:",
|
||||
num,
|
||||
" msgId:",
|
||||
num2,
|
||||
" ",
|
||||
stringBuilder
|
||||
}));
|
||||
}
|
||||
QSBNetworkMessageDelegate networkMessageDelegate = null;
|
||||
if (m_MessageHandlersDict.ContainsKey(num2))
|
||||
{
|
||||
networkMessageDelegate = m_MessageHandlersDict[num2];
|
||||
}
|
||||
if (networkMessageDelegate == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError(string.Concat(new object[]
|
||||
{
|
||||
"Unknown message ID ",
|
||||
num2,
|
||||
" connId:",
|
||||
connectionId
|
||||
}));
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_NetMsg.msgType = num2;
|
||||
m_NetMsg.reader = reader2;
|
||||
m_NetMsg.conn = this;
|
||||
m_NetMsg.channelId = channelId;
|
||||
networkMessageDelegate(m_NetMsg);
|
||||
lastMessageTime = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetStatsOut(out int numMsgs, out int numBufferedMsgs, out int numBytes, out int lastBufferedPerSecond)
|
||||
{
|
||||
numMsgs = 0;
|
||||
numBufferedMsgs = 0;
|
||||
numBytes = 0;
|
||||
lastBufferedPerSecond = 0;
|
||||
for (var i = 0; i < m_Channels.Length; i++)
|
||||
{
|
||||
var channelBuffer = m_Channels[i];
|
||||
numMsgs += channelBuffer.numMsgsOut;
|
||||
numBufferedMsgs += channelBuffer.numBufferedMsgsOut;
|
||||
numBytes += channelBuffer.numBytesOut;
|
||||
lastBufferedPerSecond += channelBuffer.lastBufferedPerSecond;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetStatsIn(out int numMsgs, out int numBytes)
|
||||
{
|
||||
numMsgs = 0;
|
||||
numBytes = 0;
|
||||
for (var i = 0; i < m_Channels.Length; i++)
|
||||
{
|
||||
var channelBuffer = m_Channels[i];
|
||||
numMsgs += channelBuffer.numMsgsIn;
|
||||
numBytes += channelBuffer.numBytesIn;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("hostId: {0} connectionId: {1} isReady: {2} channel count: {3}", new object[]
|
||||
{
|
||||
hostId,
|
||||
connectionId,
|
||||
isReady,
|
||||
(m_Channels == null) ? 0 : m_Channels.Length
|
||||
});
|
||||
}
|
||||
|
||||
internal void AddToVisList(QSBNetworkIdentity uv)
|
||||
{
|
||||
VisList.Add(uv);
|
||||
QSBNetworkServer.ShowForConnection(uv, this);
|
||||
}
|
||||
|
||||
internal void RemoveFromVisList(QSBNetworkIdentity uv, bool isDestroyed)
|
||||
{
|
||||
VisList.Remove(uv);
|
||||
if (!isDestroyed)
|
||||
{
|
||||
QSBNetworkServer.HideForConnection(uv, this);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveObservers()
|
||||
{
|
||||
foreach (var networkIdentity in VisList)
|
||||
{
|
||||
networkIdentity.RemoveObserverInternal(this);
|
||||
}
|
||||
VisList.Clear();
|
||||
}
|
||||
|
||||
public virtual void TransportReceive(byte[] bytes, int numBytes, int channelId) => HandleBytes(bytes, numBytes, channelId);
|
||||
|
||||
[Obsolete("TransportRecieve has been deprecated. Use TransportReceive instead (UnityUpgradable) -> TransportReceive(*)", false)]
|
||||
public virtual void TransportRecieve(byte[] bytes, int numBytes, int channelId) => TransportReceive(bytes, numBytes, channelId);
|
||||
|
||||
public virtual bool TransportSend(byte[] bytes, int numBytes, int channelId, out byte error) => NetworkTransport.Send(hostId, connectionId, channelId, bytes, numBytes, out error);
|
||||
|
||||
internal void AddOwnedObject(QSBNetworkIdentity obj)
|
||||
{
|
||||
if (ClientOwnedObjects == null)
|
||||
{
|
||||
ClientOwnedObjects = new HashSet<NetworkInstanceId>();
|
||||
}
|
||||
ClientOwnedObjects.Add(obj.NetId);
|
||||
}
|
||||
|
||||
internal void RemoveOwnedObject(QSBNetworkIdentity obj)
|
||||
{
|
||||
if (ClientOwnedObjects != null)
|
||||
{
|
||||
ClientOwnedObjects.Remove(obj.NetId);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OnFragment(QSBNetworkMessage netMsg) => netMsg.conn.HandleFragment(netMsg.reader, netMsg.channelId);
|
||||
|
||||
private ChannelBuffer[] m_Channels;
|
||||
private readonly QSBNetworkMessage m_NetMsg = new QSBNetworkMessage();
|
||||
private NetworkWriter m_Writer;
|
||||
|
||||
private Dictionary<short, QSBNetworkMessageDelegate> m_MessageHandlersDict;
|
||||
|
||||
private QSBNetworkMessageHandlers m_MessageHandlers;
|
||||
private readonly QSBNetworkMessage m_MessageInfo = new QSBNetworkMessage();
|
||||
|
||||
private const int k_MaxMessageLogSize = 150;
|
||||
public int hostId = -1;
|
||||
|
||||
public int connectionId = -1;
|
||||
|
||||
public bool isReady;
|
||||
|
||||
public string address;
|
||||
|
||||
public float lastMessageTime;
|
||||
|
||||
public bool logNetworkMessages = false;
|
||||
private bool m_Disposed;
|
||||
|
||||
public class PacketStat
|
||||
{
|
||||
public PacketStat()
|
||||
{
|
||||
msgType = 0;
|
||||
count = 0;
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
public PacketStat(PacketStat s)
|
||||
{
|
||||
msgType = s.msgType;
|
||||
count = s.count;
|
||||
bytes = s.bytes;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Concat(new object[]
|
||||
{
|
||||
MsgType.MsgTypeToString(msgType),
|
||||
": count=",
|
||||
count,
|
||||
" bytes=",
|
||||
bytes
|
||||
});
|
||||
}
|
||||
|
||||
public short msgType;
|
||||
|
||||
public int count;
|
||||
|
||||
public int bytes;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,12 +15,12 @@ namespace QSB
|
||||
public bool HasAuthority { get; private set; }
|
||||
public NetworkInstanceId NetId { get; private set; }
|
||||
public NetworkSceneId SceneId => m_SceneId;
|
||||
public NetworkConnection ClientAuthorityOwner { get; private set; }
|
||||
public QSBNetworkConnection ClientAuthorityOwner { get; private set; }
|
||||
public NetworkHash128 AssetId => m_AssetId;
|
||||
public bool IsLocalPlayer { get; private set; }
|
||||
public short PlayerControllerId { get; private set; } = -1;
|
||||
public NetworkConnection ConnectionToServer { get; private set; }
|
||||
public NetworkConnection ConnectionToClient { get; private set; }
|
||||
public QSBNetworkConnection ConnectionToServer { get; private set; }
|
||||
public QSBNetworkConnection ConnectionToClient { get; private set; }
|
||||
|
||||
public bool ServerOnly
|
||||
{
|
||||
@ -58,7 +58,7 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetClientOwner(NetworkConnection conn)
|
||||
internal void SetClientOwner(QSBNetworkConnection conn)
|
||||
{
|
||||
if (ClientAuthorityOwner != null)
|
||||
{
|
||||
@ -88,18 +88,18 @@ namespace QSB
|
||||
|
||||
|
||||
|
||||
public ReadOnlyCollection<NetworkConnection> Observers
|
||||
public ReadOnlyCollection<QSBNetworkConnection> Observers
|
||||
{
|
||||
get
|
||||
{
|
||||
ReadOnlyCollection<NetworkConnection> result;
|
||||
ReadOnlyCollection<QSBNetworkConnection> result;
|
||||
if (m_Observers == null)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new ReadOnlyCollection<NetworkConnection>(m_Observers);
|
||||
result = new ReadOnlyCollection<QSBNetworkConnection>(m_Observers);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -154,7 +154,7 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveObserverInternal(NetworkConnection conn)
|
||||
internal void RemoveObserverInternal(QSBNetworkConnection conn)
|
||||
{
|
||||
if (m_Observers != null)
|
||||
{
|
||||
@ -184,7 +184,7 @@ namespace QSB
|
||||
{
|
||||
HasAuthority = true;
|
||||
}
|
||||
m_Observers = new List<NetworkConnection>();
|
||||
m_Observers = new List<QSBNetworkConnection>();
|
||||
m_ObserverConnections = new HashSet<int>();
|
||||
CacheBehaviours();
|
||||
if (NetId.IsEmpty())
|
||||
@ -225,7 +225,7 @@ namespace QSB
|
||||
}
|
||||
if (NetworkClient.active && NetworkServer.localClientActive)
|
||||
{
|
||||
ClientScene.SetLocalObject(NetId, base.gameObject);
|
||||
QSBClientScene.SetLocalObject(NetId, base.gameObject);
|
||||
OnStartClient();
|
||||
}
|
||||
if (HasAuthority)
|
||||
@ -676,9 +676,9 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetConnectionToServer(NetworkConnection conn) => ConnectionToServer = conn;
|
||||
internal void SetConnectionToServer(QSBNetworkConnection conn) => ConnectionToServer = conn;
|
||||
|
||||
internal void SetConnectionToClient(NetworkConnection conn, short newPlayerControllerId)
|
||||
internal void SetConnectionToClient(QSBNetworkConnection conn, short newPlayerControllerId)
|
||||
{
|
||||
PlayerControllerId = newPlayerControllerId;
|
||||
ConnectionToClient = conn;
|
||||
@ -711,7 +711,7 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddObserver(NetworkConnection conn)
|
||||
internal void AddObserver(QSBNetworkConnection conn)
|
||||
{
|
||||
if (m_Observers == null)
|
||||
{
|
||||
@ -742,7 +742,7 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveObserver(NetworkConnection conn)
|
||||
internal void RemoveObserver(QSBNetworkConnection conn)
|
||||
{
|
||||
if (m_Observers != null)
|
||||
{
|
||||
@ -758,8 +758,8 @@ namespace QSB
|
||||
{
|
||||
var flag = false;
|
||||
var flag2 = false;
|
||||
var hashSet = new HashSet<NetworkConnection>();
|
||||
var hashSet2 = new HashSet<NetworkConnection>(m_Observers);
|
||||
var hashSet = new HashSet<QSBNetworkConnection>();
|
||||
var hashSet2 = new HashSet<QSBNetworkConnection>(m_Observers);
|
||||
for (var i = 0; i < m_NetworkBehaviours.Length; i++)
|
||||
{
|
||||
var networkBehaviour = m_NetworkBehaviours[i];
|
||||
@ -769,9 +769,9 @@ namespace QSB
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
for (var j = 0; j < NetworkServer.connections.Count; j++)
|
||||
for (var j = 0; j < QSBNetworkServer.connections.Count; j++)
|
||||
{
|
||||
var networkConnection = NetworkServer.connections[j];
|
||||
var networkConnection = QSBNetworkServer.connections[j];
|
||||
if (networkConnection != null)
|
||||
{
|
||||
if (networkConnection.isReady)
|
||||
@ -780,9 +780,9 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var k = 0; k < NetworkServer.localConnections.Count; k++)
|
||||
for (var k = 0; k < QSBNetworkServer.localConnections.Count; k++)
|
||||
{
|
||||
var networkConnection2 = NetworkServer.localConnections[k];
|
||||
var networkConnection2 = QSBNetworkServer.localConnections[k];
|
||||
if (networkConnection2 != null)
|
||||
{
|
||||
if (networkConnection2.isReady)
|
||||
@ -840,9 +840,9 @@ namespace QSB
|
||||
}
|
||||
if (initialize)
|
||||
{
|
||||
for (var l = 0; l < NetworkServer.localConnections.Count; l++)
|
||||
for (var l = 0; l < QSBNetworkServer.localConnections.Count; l++)
|
||||
{
|
||||
if (!hashSet.Contains(NetworkServer.localConnections[l]))
|
||||
if (!hashSet.Contains(QSBNetworkServer.localConnections[l]))
|
||||
{
|
||||
OnSetLocalVisibility(false);
|
||||
}
|
||||
@ -850,7 +850,7 @@ namespace QSB
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
m_Observers = new List<NetworkConnection>(hashSet);
|
||||
m_Observers = new List<QSBNetworkConnection>(hashSet);
|
||||
m_ObserverConnections.Clear();
|
||||
for (var m = 0; m < m_Observers.Count; m++)
|
||||
{
|
||||
@ -861,7 +861,7 @@ namespace QSB
|
||||
}
|
||||
}
|
||||
|
||||
public bool RemoveClientAuthority(NetworkConnection conn)
|
||||
public bool RemoveClientAuthority(QSBNetworkConnection conn)
|
||||
{
|
||||
bool result;
|
||||
if (!IsServer)
|
||||
@ -889,20 +889,18 @@ namespace QSB
|
||||
ClientAuthorityOwner.GetType().GetMethod("RemoveOwnedObject", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Invoke(ClientAuthorityOwner, new object[] { this });
|
||||
ClientAuthorityOwner = null;
|
||||
ForceAuthority(true);
|
||||
/*
|
||||
conn.Send(15, new ClientAuthorityMessage
|
||||
conn.Send(15, new QSBClientAuthorityMessage
|
||||
{
|
||||
netId = NetId,
|
||||
authority = false
|
||||
});
|
||||
*/
|
||||
clientAuthorityCallback?.Invoke(conn, this, false);
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool AssignClientAuthority(NetworkConnection conn)
|
||||
public bool AssignClientAuthority(QSBNetworkConnection conn)
|
||||
{
|
||||
bool result;
|
||||
if (!IsServer)
|
||||
@ -931,13 +929,11 @@ namespace QSB
|
||||
ClientAuthorityOwner.GetType().GetMethod("AddOwnedObject", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Invoke(ClientAuthorityOwner, new object[] { this });
|
||||
|
||||
ForceAuthority(false);
|
||||
/*
|
||||
conn.Send(15, new ClientAuthorityMessage
|
||||
conn.Send(15, new QSBClientAuthorityMessage
|
||||
{
|
||||
netId = NetId,
|
||||
authority = true
|
||||
});
|
||||
*/
|
||||
clientAuthorityCallback?.Invoke(conn, this, true);
|
||||
result = true;
|
||||
}
|
||||
@ -988,7 +984,7 @@ namespace QSB
|
||||
|
||||
private HashSet<int> m_ObserverConnections;
|
||||
|
||||
private List<NetworkConnection> m_Observers;
|
||||
private List<QSBNetworkConnection> m_Observers;
|
||||
private bool m_Reset = false;
|
||||
|
||||
private static uint s_NextNetworkId = 1U;
|
||||
@ -997,6 +993,6 @@ namespace QSB
|
||||
|
||||
public static ClientAuthorityCallback clientAuthorityCallback;
|
||||
|
||||
public delegate void ClientAuthorityCallback(NetworkConnection conn, QSBNetworkIdentity uv, bool authorityState);
|
||||
public delegate void ClientAuthorityCallback(QSBNetworkConnection conn, QSBNetworkIdentity uv, bool authorityState);
|
||||
}
|
||||
}
|
@ -115,22 +115,22 @@ namespace QSB
|
||||
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
||||
}
|
||||
|
||||
NetworkServer.UnregisterHandler(40);
|
||||
NetworkServer.UnregisterHandler(41);
|
||||
NetworkServer.UnregisterHandler(42);
|
||||
NetworkServer.RegisterHandler(40, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationServerMessage));
|
||||
NetworkServer.RegisterHandler(41, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersServerMessage));
|
||||
NetworkServer.RegisterHandler(42, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerServerMessage));
|
||||
QSBNetworkServer.UnregisterHandler(40);
|
||||
QSBNetworkServer.UnregisterHandler(41);
|
||||
QSBNetworkServer.UnregisterHandler(42);
|
||||
QSBNetworkServer.RegisterHandler(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationServerMessage));
|
||||
QSBNetworkServer.RegisterHandler(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersServerMessage));
|
||||
QSBNetworkServer.RegisterHandler(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerServerMessage));
|
||||
}
|
||||
|
||||
public override void OnServerAddPlayer(NetworkConnection connection, short playerControllerId) // Called on the server when a client joins
|
||||
public override void OnServerAddPlayer(QSBNetworkConnection connection, short playerControllerId) // Called on the server when a client joins
|
||||
{
|
||||
DebugLog.DebugWrite("OnServerAddPlayer", MessageType.Info);
|
||||
base.OnServerAddPlayer(connection, playerControllerId);
|
||||
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
|
||||
NetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
|
||||
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
|
||||
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
|
||||
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
|
||||
}
|
||||
|
||||
public override void OnClientConnect(NetworkConnection connection) // Called on the client when connecting to a server
|
||||
@ -153,11 +153,11 @@ namespace QSB
|
||||
QSBPatchManager.DoPatchType(QSBPatchTypes.OnNonServerClientConnect);
|
||||
singleton.client.UnregisterHandler(40);
|
||||
singleton.client.UnregisterHandler(41);
|
||||
singleton.client.RegisterHandlerSafe(40, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
|
||||
singleton.client.RegisterHandlerSafe(41, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
|
||||
singleton.client.RegisterHandlerSafe(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
|
||||
singleton.client.RegisterHandlerSafe(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
|
||||
}
|
||||
singleton.client.UnregisterHandler(42);
|
||||
singleton.client.RegisterHandlerSafe(42, new NetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
|
||||
singleton.client.RegisterHandlerSafe(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
|
||||
|
||||
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
|
||||
|
||||
@ -201,11 +201,11 @@ namespace QSB
|
||||
_lobby.CanEditName = true;
|
||||
}
|
||||
|
||||
public override void OnServerDisconnect(NetworkConnection connection) // Called on the server when any client disconnects
|
||||
public override void OnServerDisconnect(QSBNetworkConnection connection) // Called on the server when any client disconnects
|
||||
{
|
||||
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
|
||||
var player = connection.GetPlayer();
|
||||
var netIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
|
||||
var netIds = connection.ClientOwnedObjects.Select(x => x.Value).ToArray();
|
||||
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, player.PlayerId, netIds);
|
||||
|
||||
foreach (var item in WorldRegistry.OrbSyncList)
|
||||
@ -230,7 +230,7 @@ namespace QSB
|
||||
QSBEventManager.Reset();
|
||||
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
|
||||
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
||||
NetworkServer.connections.ToList().ForEach(CleanupConnection);
|
||||
QSBNetworkServer.connections.ToList().ForEach(CleanupConnection);
|
||||
|
||||
WorldRegistry.RemoveObjects<QSBOrbSlot>();
|
||||
WorldRegistry.RemoveObjects<QSBElevator>();
|
||||
@ -240,13 +240,13 @@ namespace QSB
|
||||
base.OnStopServer();
|
||||
}
|
||||
|
||||
private void CleanupConnection(NetworkConnection connection)
|
||||
private void CleanupConnection(QSBNetworkConnection connection)
|
||||
{
|
||||
var player = connection.GetPlayer();
|
||||
DebugLog.ToConsole($"{player.Name} disconnected.", MessageType.Info);
|
||||
QSBPlayerManager.RemovePlayer(player.PlayerId);
|
||||
|
||||
var netIds = connection.clientOwnedObjects?.Select(x => x.Value).ToList();
|
||||
var netIds = connection.ClientOwnedObjects?.Select(x => x.Value).ToList();
|
||||
netIds.ForEach(CleanupNetworkBehaviour);
|
||||
}
|
||||
|
||||
|
43
QSB/QSBNetworkMessage.cs
Normal file
43
QSB/QSBNetworkMessage.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBNetworkMessage
|
||||
{
|
||||
public static string Dump(byte[] payload, int sz)
|
||||
{
|
||||
var text = "[";
|
||||
for (var i = 0; i < sz; i++)
|
||||
{
|
||||
text = text + payload[i] + " ";
|
||||
}
|
||||
return text + "]";
|
||||
}
|
||||
|
||||
public TMsg ReadMessage<TMsg>() where TMsg : MessageBase, new()
|
||||
{
|
||||
var result = Activator.CreateInstance<TMsg>();
|
||||
result.Deserialize(reader);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ReadMessage<TMsg>(TMsg msg) where TMsg : MessageBase
|
||||
{
|
||||
msg.Deserialize(reader);
|
||||
}
|
||||
|
||||
public const int MaxMessageSize = 65535;
|
||||
|
||||
public short msgType;
|
||||
|
||||
public QSBNetworkConnection conn;
|
||||
|
||||
public NetworkReader reader;
|
||||
|
||||
public int channelId;
|
||||
}
|
||||
}
|
9
QSB/QSBNetworkMessageDelegate.cs
Normal file
9
QSB/QSBNetworkMessageDelegate.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public delegate void QSBNetworkMessageDelegate(QSBNetworkMessage netMsg);
|
||||
}
|
92
QSB/QSBNetworkMessageHandlers.cs
Normal file
92
QSB/QSBNetworkMessageHandlers.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBNetworkMessageHandlers
|
||||
{
|
||||
internal void RegisterHandlerSafe(short msgType, QSBNetworkMessageDelegate handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
Debug.LogError("RegisterHandlerSafe id:" + msgType + " handler is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"RegisterHandlerSafe id:",
|
||||
msgType,
|
||||
" handler:",
|
||||
handler.GetMethodName()
|
||||
}));
|
||||
if (!this.m_MsgHandlers.ContainsKey(msgType))
|
||||
{
|
||||
this.m_MsgHandlers.Add(msgType, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterHandler(short msgType, QSBNetworkMessageDelegate handler)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
Debug.LogError("RegisterHandler id:" + msgType + " handler is null");
|
||||
}
|
||||
else if (msgType <= 31)
|
||||
{
|
||||
Debug.LogError("RegisterHandler: Cannot replace system message handler " + msgType);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.m_MsgHandlers.ContainsKey(msgType))
|
||||
{
|
||||
Debug.Log("RegisterHandler replacing " + msgType);
|
||||
this.m_MsgHandlers.Remove(msgType);
|
||||
}
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"RegisterHandler id:",
|
||||
msgType,
|
||||
" handler:",
|
||||
handler.GetMethodName()
|
||||
}));
|
||||
this.m_MsgHandlers.Add(msgType, handler);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterHandler(short msgType)
|
||||
{
|
||||
this.m_MsgHandlers.Remove(msgType);
|
||||
}
|
||||
|
||||
internal QSBNetworkMessageDelegate GetHandler(short msgType)
|
||||
{
|
||||
QSBNetworkMessageDelegate result;
|
||||
if (this.m_MsgHandlers.ContainsKey(msgType))
|
||||
{
|
||||
result = this.m_MsgHandlers[msgType];
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal Dictionary<short, QSBNetworkMessageDelegate> GetHandlers()
|
||||
{
|
||||
return this.m_MsgHandlers;
|
||||
}
|
||||
|
||||
internal void ClearMessageHandlers()
|
||||
{
|
||||
this.m_MsgHandlers.Clear();
|
||||
}
|
||||
|
||||
private Dictionary<short, QSBNetworkMessageDelegate> m_MsgHandlers = new Dictionary<short, QSBNetworkMessageDelegate>();
|
||||
}
|
||||
}
|
369
QSB/QSBNetworkScene.cs
Normal file
369
QSB/QSBNetworkScene.cs
Normal file
@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBNetworkScene
|
||||
{
|
||||
internal Dictionary<NetworkInstanceId, QSBNetworkIdentity> localObjects { get; } = new Dictionary<NetworkInstanceId, QSBNetworkIdentity>();
|
||||
|
||||
internal static Dictionary<NetworkHash128, GameObject> guidToPrefab { get; } = new Dictionary<NetworkHash128, GameObject>();
|
||||
|
||||
internal static Dictionary<NetworkHash128, SpawnDelegate> spawnHandlers { get; } = new Dictionary<NetworkHash128, SpawnDelegate>();
|
||||
|
||||
internal static Dictionary<NetworkHash128, UnSpawnDelegate> unspawnHandlers { get; } = new Dictionary<NetworkHash128, UnSpawnDelegate>();
|
||||
|
||||
internal void Shutdown()
|
||||
{
|
||||
this.ClearLocalObjects();
|
||||
ClearSpawners();
|
||||
}
|
||||
|
||||
internal void SetLocalObject(NetworkInstanceId netId, GameObject obj, bool isClient, bool isServer)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"SetLocalObject ",
|
||||
netId,
|
||||
" ",
|
||||
obj
|
||||
}));
|
||||
if (obj == null)
|
||||
{
|
||||
this.localObjects[netId] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
QSBNetworkIdentity networkIdentity = null;
|
||||
if (this.localObjects.ContainsKey(netId))
|
||||
{
|
||||
networkIdentity = this.localObjects[netId];
|
||||
}
|
||||
if (networkIdentity == null)
|
||||
{
|
||||
networkIdentity = obj.GetComponent<QSBNetworkIdentity>();
|
||||
this.localObjects[netId] = networkIdentity;
|
||||
}
|
||||
networkIdentity.UpdateClientServer(isClient, isServer);
|
||||
}
|
||||
}
|
||||
|
||||
internal GameObject FindLocalObject(NetworkInstanceId netId)
|
||||
{
|
||||
if (this.localObjects.ContainsKey(netId))
|
||||
{
|
||||
QSBNetworkIdentity networkIdentity = this.localObjects[netId];
|
||||
if (networkIdentity != null)
|
||||
{
|
||||
return networkIdentity.gameObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal bool GetNetworkIdentity(NetworkInstanceId netId, out QSBNetworkIdentity uv)
|
||||
{
|
||||
bool result;
|
||||
if (this.localObjects.ContainsKey(netId) && this.localObjects[netId] != null)
|
||||
{
|
||||
uv = this.localObjects[netId];
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uv = null;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal bool RemoveLocalObject(NetworkInstanceId netId)
|
||||
{
|
||||
return this.localObjects.Remove(netId);
|
||||
}
|
||||
|
||||
internal bool RemoveLocalObjectAndDestroy(NetworkInstanceId netId)
|
||||
{
|
||||
bool result;
|
||||
if (this.localObjects.ContainsKey(netId))
|
||||
{
|
||||
QSBNetworkIdentity networkIdentity = this.localObjects[netId];
|
||||
UnityEngine.Object.Destroy(networkIdentity.gameObject);
|
||||
result = this.localObjects.Remove(netId);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void ClearLocalObjects()
|
||||
{
|
||||
this.localObjects.Clear();
|
||||
}
|
||||
|
||||
internal static void RegisterPrefab(GameObject prefab, NetworkHash128 newAssetId)
|
||||
{
|
||||
QSBNetworkIdentity component = prefab.GetComponent<QSBNetworkIdentity>();
|
||||
if (component)
|
||||
{
|
||||
component.SetDynamicAssetId(newAssetId);
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Registering prefab '",
|
||||
prefab.name,
|
||||
"' as asset:",
|
||||
component.AssetId
|
||||
}));
|
||||
}
|
||||
guidToPrefab[component.AssetId] = prefab;
|
||||
}
|
||||
else if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Could not register '" + prefab.name + "' since it contains no NetworkIdentity component");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RegisterPrefab(GameObject prefab)
|
||||
{
|
||||
NetworkIdentity component = prefab.GetComponent<NetworkIdentity>();
|
||||
if (component)
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Registering prefab '",
|
||||
prefab.name,
|
||||
"' as asset:",
|
||||
component.assetId
|
||||
}));
|
||||
}
|
||||
guidToPrefab[component.assetId] = prefab;
|
||||
NetworkIdentity[] componentsInChildren = prefab.GetComponentsInChildren<NetworkIdentity>();
|
||||
if (componentsInChildren.Length > 1)
|
||||
{
|
||||
if (LogFilter.logWarn)
|
||||
{
|
||||
Debug.LogWarning("The prefab '" + prefab.name + "' has multiple NetworkIdentity components. There can only be one NetworkIdentity on a prefab, and it must be on the root object.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Could not register '" + prefab.name + "' since it contains no NetworkIdentity component");
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool GetPrefab(NetworkHash128 assetId, out GameObject prefab)
|
||||
{
|
||||
bool result;
|
||||
if (!assetId.IsValid())
|
||||
{
|
||||
prefab = null;
|
||||
result = false;
|
||||
}
|
||||
else if (guidToPrefab.ContainsKey(assetId) && guidToPrefab[assetId] != null)
|
||||
{
|
||||
prefab = guidToPrefab[assetId];
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab = null;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void ClearSpawners()
|
||||
{
|
||||
guidToPrefab.Clear();
|
||||
spawnHandlers.Clear();
|
||||
unspawnHandlers.Clear();
|
||||
}
|
||||
|
||||
public static void UnregisterSpawnHandler(NetworkHash128 assetId)
|
||||
{
|
||||
spawnHandlers.Remove(assetId);
|
||||
unspawnHandlers.Remove(assetId);
|
||||
}
|
||||
|
||||
internal static void RegisterSpawnHandler(NetworkHash128 assetId, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
|
||||
{
|
||||
if (spawnHandler == null || unspawnHandler == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("RegisterSpawnHandler custom spawn function null for " + assetId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"RegisterSpawnHandler asset '",
|
||||
assetId,
|
||||
"' ",
|
||||
spawnHandler.GetMethodName(),
|
||||
"/",
|
||||
unspawnHandler.GetMethodName()
|
||||
}));
|
||||
}
|
||||
spawnHandlers[assetId] = spawnHandler;
|
||||
unspawnHandlers[assetId] = unspawnHandler;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UnregisterPrefab(GameObject prefab)
|
||||
{
|
||||
NetworkIdentity component = prefab.GetComponent<NetworkIdentity>();
|
||||
if (component == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Could not unregister '" + prefab.name + "' since it contains no NetworkIdentity component");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnHandlers.Remove(component.assetId);
|
||||
unspawnHandlers.Remove(component.assetId);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RegisterPrefab(GameObject prefab, SpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
|
||||
{
|
||||
NetworkIdentity component = prefab.GetComponent<NetworkIdentity>();
|
||||
if (component == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("Could not register '" + prefab.name + "' since it contains no NetworkIdentity component");
|
||||
}
|
||||
}
|
||||
else if (spawnHandler == null || unspawnHandler == null)
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("RegisterPrefab custom spawn function null for " + component.assetId);
|
||||
}
|
||||
}
|
||||
else if (!component.assetId.IsValid())
|
||||
{
|
||||
if (LogFilter.logError)
|
||||
{
|
||||
Debug.LogError("RegisterPrefab game object " + prefab.name + " has no prefab. Use RegisterSpawnHandler() instead?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LogFilter.logDebug)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"Registering custom prefab '",
|
||||
prefab.name,
|
||||
"' as asset:",
|
||||
component.assetId,
|
||||
" ",
|
||||
spawnHandler.GetMethodName(),
|
||||
"/",
|
||||
unspawnHandler.GetMethodName()
|
||||
}));
|
||||
}
|
||||
spawnHandlers[component.assetId] = spawnHandler;
|
||||
unspawnHandlers[component.assetId] = unspawnHandler;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool GetSpawnHandler(NetworkHash128 assetId, out SpawnDelegate handler)
|
||||
{
|
||||
bool result;
|
||||
if (spawnHandlers.ContainsKey(assetId))
|
||||
{
|
||||
handler = spawnHandlers[assetId];
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
handler = null;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool InvokeUnSpawnHandler(NetworkHash128 assetId, GameObject obj)
|
||||
{
|
||||
bool result;
|
||||
if (unspawnHandlers.ContainsKey(assetId) && unspawnHandlers[assetId] != null)
|
||||
{
|
||||
UnSpawnDelegate unSpawnDelegate = unspawnHandlers[assetId];
|
||||
unSpawnDelegate(obj);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void DestroyAllClientObjects()
|
||||
{
|
||||
foreach (NetworkInstanceId key in this.localObjects.Keys)
|
||||
{
|
||||
QSBNetworkIdentity networkIdentity = this.localObjects[key];
|
||||
if (networkIdentity != null && networkIdentity.gameObject != null)
|
||||
{
|
||||
if (!InvokeUnSpawnHandler(networkIdentity.AssetId, networkIdentity.gameObject))
|
||||
{
|
||||
if (networkIdentity.SceneId.IsEmpty())
|
||||
{
|
||||
UnityEngine.Object.Destroy(networkIdentity.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
networkIdentity.MarkForReset();
|
||||
networkIdentity.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.ClearLocalObjects();
|
||||
}
|
||||
|
||||
internal void DumpAllClientObjects()
|
||||
{
|
||||
foreach (NetworkInstanceId networkInstanceId in this.localObjects.Keys)
|
||||
{
|
||||
QSBNetworkIdentity networkIdentity = this.localObjects[networkInstanceId];
|
||||
if (networkIdentity != null)
|
||||
{
|
||||
Debug.Log(string.Concat(new object[]
|
||||
{
|
||||
"ID:",
|
||||
networkInstanceId,
|
||||
" OBJ:",
|
||||
networkIdentity.gameObject,
|
||||
" AS:",
|
||||
networkIdentity.AssetId
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("ID:" + networkInstanceId + " OBJ: null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2197
QSB/QSBNetworkServer.cs
Normal file
2197
QSB/QSBNetworkServer.cs
Normal file
File diff suppressed because it is too large
Load Diff
23
QSB/QSBObjectDestroyMessage.cs
Normal file
23
QSB/QSBObjectDestroyMessage.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBObjectDestroyMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
netId = reader.ReadNetworkId();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.Write(netId);
|
||||
}
|
||||
|
||||
public NetworkInstanceId netId;
|
||||
}
|
||||
}
|
23
QSB/QSBObjectSpawnFinishedMessage.cs
Normal file
23
QSB/QSBObjectSpawnFinishedMessage.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBObjectSpawnFinishedMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
state = reader.ReadPackedUInt32();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.WritePackedUInt32(state);
|
||||
}
|
||||
|
||||
public uint state;
|
||||
}
|
||||
}
|
44
QSB/QSBObjectSpawnMessage.cs
Normal file
44
QSB/QSBObjectSpawnMessage.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBObjectSpawnMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
netId = reader.ReadNetworkId();
|
||||
assetId = reader.ReadNetworkHash128();
|
||||
position = reader.ReadVector3();
|
||||
payload = reader.ReadBytesAndSize();
|
||||
uint num = 16U;
|
||||
if ((long)reader.Length - (long)((ulong)reader.Position) >= (long)((ulong)num))
|
||||
{
|
||||
rotation = reader.ReadQuaternion();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.Write(netId);
|
||||
writer.Write(assetId);
|
||||
writer.Write(position);
|
||||
writer.WriteBytesFull(payload);
|
||||
writer.Write(rotation);
|
||||
}
|
||||
|
||||
public NetworkInstanceId netId;
|
||||
|
||||
public NetworkHash128 assetId;
|
||||
|
||||
public Vector3 position;
|
||||
|
||||
public byte[] payload;
|
||||
|
||||
public Quaternion rotation;
|
||||
}
|
||||
}
|
36
QSB/QSBObjectSpawnSceneMessage.cs
Normal file
36
QSB/QSBObjectSpawnSceneMessage.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBObjectSpawnSceneMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
this.netId = reader.ReadNetworkId();
|
||||
this.sceneId = reader.ReadSceneId();
|
||||
this.position = reader.ReadVector3();
|
||||
this.payload = reader.ReadBytesAndSize();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.Write(this.netId);
|
||||
writer.Write(this.sceneId);
|
||||
writer.Write(this.position);
|
||||
writer.WriteBytesFull(this.payload);
|
||||
}
|
||||
|
||||
public NetworkInstanceId netId;
|
||||
|
||||
public NetworkSceneId sceneId;
|
||||
|
||||
public Vector3 position;
|
||||
|
||||
public byte[] payload;
|
||||
}
|
||||
}
|
27
QSB/QSBOwnerMessage.cs
Normal file
27
QSB/QSBOwnerMessage.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
class QSBOwnerMessage : MessageBase
|
||||
{
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
netId = reader.ReadNetworkId();
|
||||
playerControllerId = (short)reader.ReadPackedUInt32();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.Write(netId);
|
||||
writer.WritePackedUInt32((uint)playerControllerId);
|
||||
}
|
||||
|
||||
public NetworkInstanceId netId;
|
||||
|
||||
public short playerControllerId;
|
||||
}
|
||||
}
|
40
QSB/QSBPlayerController.cs
Normal file
40
QSB/QSBPlayerController.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBPlayerController
|
||||
{
|
||||
public QSBPlayerController()
|
||||
{
|
||||
}
|
||||
|
||||
internal QSBPlayerController(GameObject go, short playerControllerId)
|
||||
{
|
||||
gameObject = go;
|
||||
unetView = go.GetComponent<QSBNetworkIdentity>();
|
||||
this.playerControllerId = playerControllerId;
|
||||
}
|
||||
|
||||
public bool IsValid => playerControllerId != -1;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("ID={0} NetworkIdentity NetID={1} Player={2}", new object[]
|
||||
{
|
||||
playerControllerId,
|
||||
(!(unetView != null)) ? "null" : unetView.NetId.ToString(),
|
||||
(!(gameObject != null)) ? "null" : gameObject.name
|
||||
});
|
||||
}
|
||||
|
||||
internal const short kMaxLocalPlayers = 8;
|
||||
|
||||
public short playerControllerId = -1;
|
||||
|
||||
public QSBNetworkIdentity unetView;
|
||||
|
||||
public GameObject gameObject;
|
||||
|
||||
public const int MaxPlayersPerClient = 32;
|
||||
}
|
||||
}
|
65
QSB/QSBUtility.cs
Normal file
65
QSB/QSBUtility.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking.Types;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBUtility
|
||||
{
|
||||
private QSBUtility()
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("This property is unused and should not be referenced in code.", true)]
|
||||
public static bool useRandomSourceID
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static SourceID GetSourceID()
|
||||
{
|
||||
return (SourceID)((long)SystemInfo.deviceUniqueIdentifier.GetHashCode());
|
||||
}
|
||||
|
||||
[Obsolete("This function is unused and should not be referenced in code. Please sign in and setup your project in the editor instead.", true)]
|
||||
public static void SetAppID(AppID newAppID)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("This function is unused and should not be referenced in code. Please sign in and setup your project in the editor instead.", true)]
|
||||
public static AppID GetAppID()
|
||||
{
|
||||
return AppID.Invalid;
|
||||
}
|
||||
|
||||
public static void SetAccessTokenForNetwork(NetworkID netId, NetworkAccessToken accessToken)
|
||||
{
|
||||
if (s_dictTokens.ContainsKey(netId))
|
||||
{
|
||||
s_dictTokens.Remove(netId);
|
||||
}
|
||||
s_dictTokens.Add(netId, accessToken);
|
||||
}
|
||||
|
||||
public static NetworkAccessToken GetAccessTokenForNetwork(NetworkID netId)
|
||||
{
|
||||
NetworkAccessToken result;
|
||||
if (!s_dictTokens.TryGetValue(netId, out result))
|
||||
{
|
||||
result = new NetworkAccessToken();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Dictionary<NetworkID, NetworkAccessToken> s_dictTokens = new Dictionary<NetworkID, NetworkAccessToken>();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user