2020-12-14 16:06:35 +00:00
using QuantumUNET.Components ;
2020-12-07 21:19:16 +00:00
using QuantumUNET.Messages ;
2020-12-16 09:08:38 +00:00
using QuantumUNET.Transport ;
2020-12-07 21:19:16 +00:00
using System.Collections.Generic ;
2020-12-02 12:42:26 +00:00
using UnityEngine ;
using UnityEngine.Networking ;
2020-12-04 22:14:53 +00:00
namespace QuantumUNET
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
public class QClientScene
2020-12-02 12:42:26 +00:00
{
internal static void SetNotReady ( ) = > ready = false ;
2020-12-23 12:58:45 +00:00
public static List < QPlayerController > localPlayers { get ; private set ; } = new List < QPlayerController > ( ) ;
2020-12-02 12:42:26 +00:00
public static bool ready { get ; private set ; }
2020-12-23 12:58:45 +00:00
public static QNetworkConnection readyConnection { get ; private set ; }
2020-12-02 12:42:26 +00:00
public static int reconnectId { get ; private set ; } = - 1 ;
2021-12-02 19:41:19 -08:00
public static Dictionary < QNetworkInstanceId , QNetworkIdentity > Objects = > s_NetworkScene . localObjects ;
2020-12-02 12:42:26 +00:00
2021-10-13 18:09:16 +01:00
public static Dictionary < int , GameObject > Prefabs = > QNetworkScene . guidToPrefab ;
2020-12-02 12:42:26 +00:00
2021-12-02 19:41:19 -08:00
public static Dictionary < QNetworkSceneId , QNetworkIdentity > SpawnableObjects { get ; private set ; }
2020-12-02 12:42:26 +00:00
internal static void Shutdown ( )
{
s_NetworkScene . Shutdown ( ) ;
2020-12-23 12:58:45 +00:00
localPlayers = new List < QPlayerController > ( ) ;
2020-12-02 12:42:26 +00:00
s_PendingOwnerIds = new List < PendingOwner > ( ) ;
SpawnableObjects = null ;
readyConnection = null ;
ready = false ;
s_IsSpawnFinished = false ;
reconnectId = - 1 ;
NetworkTransport . Shutdown ( ) ;
NetworkTransport . Init ( ) ;
}
2020-12-23 12:58:45 +00:00
internal static bool GetPlayerController ( short playerControllerId , out QPlayerController player )
2020-12-02 12:42:26 +00:00
{
player = null ;
bool result ;
2020-12-16 09:08:38 +00:00
if ( playerControllerId > = localPlayers . Count )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::GetPlayer: no local player found for: {playerControllerId}" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
2020-12-16 09:08:38 +00:00
else if ( localPlayers [ playerControllerId ] = = null )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"ClientScene::GetPlayer: local player is null for: {playerControllerId}" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
else
{
2020-12-16 09:08:38 +00:00
player = localPlayers [ playerControllerId ] ;
2020-12-21 00:50:24 +01:00
result = player . Gameobject ! = null ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2020-12-23 12:58:45 +00:00
internal static void InternalAddPlayer ( QNetworkIdentity view , short playerControllerId )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"ClientScene::InternalAddPlayer: playerControllerId : {playerControllerId}" ) ;
2020-12-16 09:08:38 +00:00
if ( playerControllerId > = localPlayers . Count )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning (
$"ClientScene::InternalAddPlayer: playerControllerId higher than expected: {playerControllerId}" ) ;
2020-12-16 09:08:38 +00:00
while ( playerControllerId > = localPlayers . Count )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
localPlayers . Add ( new QPlayerController ( ) ) ;
2020-12-02 12:42:26 +00:00
}
}
2021-06-18 22:39:21 +01:00
2020-12-23 12:58:45 +00:00
var playerController = new QPlayerController
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
Gameobject = view . gameObject ,
PlayerControllerId = playerControllerId ,
UnetView = view
2020-12-02 12:42:26 +00:00
} ;
2020-12-16 09:08:38 +00:00
localPlayers [ playerControllerId ] = playerController ;
2020-12-02 12:42:26 +00:00
readyConnection . SetPlayerController ( playerController ) ;
}
public static bool AddPlayer ( short playerControllerId ) = > AddPlayer ( null , playerControllerId ) ;
2020-12-23 12:58:45 +00:00
public static bool AddPlayer ( QNetworkConnection readyConn , short playerControllerId ) = > AddPlayer ( readyConn , playerControllerId , null ) ;
2020-12-02 12:42:26 +00:00
2020-12-23 12:58:45 +00:00
public static bool AddPlayer ( QNetworkConnection readyConn , short playerControllerId , QMessageBase extraMessage )
2020-12-02 12:42:26 +00:00
{
bool result ;
if ( playerControllerId < 0 )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"ClientScene::AddPlayer: playerControllerId of {playerControllerId} is negative" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
else if ( playerControllerId > 32 )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"ClientScene::AddPlayer: playerControllerId of {playerControllerId} is too high, max is {32}" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
else
{
if ( playerControllerId > 16 )
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"ClientScene::AddPlayer: playerControllerId of {playerControllerId} is unusually high" ) ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-16 09:08:38 +00:00
while ( playerControllerId > = localPlayers . Count )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
localPlayers . Add ( new QPlayerController ( ) ) ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
if ( readyConn = = null )
{
if ( ! ready )
{
2020-12-18 20:20:54 +00:00
Debug . LogError ( "Must call AddPlayer() with a connection the first time to become ready." ) ;
2020-12-02 12:42:26 +00:00
return false ;
}
}
else
{
ready = true ;
readyConnection = readyConn ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
if ( readyConnection . GetPlayerController ( playerControllerId , out var playerController ) )
{
2020-12-03 11:56:32 +00:00
if ( playerController . IsValid & & playerController . Gameobject ! = null )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"ClientScene::AddPlayer: playerControllerId of {playerControllerId} already in use." ) ;
2020-12-02 12:42:26 +00:00
return false ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::AddPlayer() for ID {playerControllerId} called with connection [{readyConnection}]" ) ;
2020-12-23 12:58:45 +00:00
var addPlayerMessage = new QAddPlayerMessage
2020-12-02 12:42:26 +00:00
{
2020-12-13 22:25:23 +00:00
playerControllerId = playerControllerId
} ;
if ( extraMessage ! = null )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var networkWriter = new QNetworkWriter ( ) ;
2020-12-13 22:25:23 +00:00
extraMessage . Serialize ( networkWriter ) ;
addPlayerMessage . msgData = networkWriter . ToArray ( ) ;
2020-12-16 09:08:38 +00:00
addPlayerMessage . msgSize = networkWriter . Position ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-13 22:25:23 +00:00
readyConnection . Send ( 37 , addPlayerMessage ) ;
result = true ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
public static bool RemovePlayer ( short playerControllerId )
{
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::RemovePlayer() for ID {playerControllerId} called with connection [{readyConnection}]" ) ;
2020-12-02 12:42:26 +00:00
bool result ;
if ( readyConnection . GetPlayerController ( playerControllerId , out var playerController ) )
{
2020-12-23 12:58:45 +00:00
var removePlayerMessage = new QRemovePlayerMessage
2020-12-02 12:42:26 +00:00
{
2020-12-04 09:23:27 +00:00
PlayerControllerId = playerControllerId
2020-12-02 12:42:26 +00:00
} ;
readyConnection . Send ( 38 , removePlayerMessage ) ;
readyConnection . RemovePlayerController ( playerControllerId ) ;
2020-12-23 12:58:45 +00:00
localPlayers [ playerControllerId ] = new QPlayerController ( ) ;
2020-12-16 09:08:38 +00:00
Object . Destroy ( playerController . Gameobject ) ;
2020-12-02 12:42:26 +00:00
result = true ;
}
else
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Failed to find player ID {playerControllerId}" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2020-12-23 12:58:45 +00:00
public static bool Ready ( QNetworkConnection conn )
2020-12-02 12:42:26 +00:00
{
bool result ;
if ( ready )
{
2020-12-18 20:20:54 +00:00
Debug . LogError ( "A connection has already been set as ready. There can only be one." ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
else
{
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::Ready() called with connection [{conn}]" ) ;
2020-12-02 12:42:26 +00:00
if ( conn ! = null )
{
2020-12-23 12:58:45 +00:00
var msg = new QReadyMessage ( ) ;
2020-12-02 12:42:26 +00:00
conn . Send ( 35 , msg ) ;
ready = true ;
readyConnection = conn ;
readyConnection . isReady = true ;
result = true ;
}
else
{
2020-12-18 20:20:54 +00:00
Debug . LogError ( "Ready() called with invalid connection object: conn=null" ) ;
2020-12-02 12:42:26 +00:00
result = false ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2020-12-23 12:58:45 +00:00
public static QNetworkClient ConnectLocalServer ( )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var localClient = new QLocalClient ( ) ;
QNetworkServer . instance . ActivateLocalClientScene ( ) ;
2020-12-02 12:42:26 +00:00
localClient . InternalConnectLocalServer ( true ) ;
return localClient ;
}
2020-12-23 12:58:45 +00:00
internal static QNetworkClient ReconnectLocalServer ( )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var localClient = new QLocalClient ( ) ;
QNetworkServer . instance . ActivateLocalClientScene ( ) ;
2020-12-02 12:42:26 +00:00
localClient . InternalConnectLocalServer ( false ) ;
return localClient ;
}
internal static void ClearLocalPlayers ( ) = > localPlayers . Clear ( ) ;
2020-12-23 12:58:45 +00:00
internal static void HandleClientDisconnect ( QNetworkConnection conn )
2020-12-02 12:42:26 +00:00
{
if ( readyConnection = = conn & & ready )
{
ready = false ;
readyConnection = null ;
}
}
internal static void PrepareToSpawnSceneObjects ( )
{
2021-12-02 19:41:19 -08:00
SpawnableObjects = new Dictionary < QNetworkSceneId , QNetworkIdentity > ( ) ;
2020-12-23 12:58:45 +00:00
foreach ( var networkIdentity in Resources . FindObjectsOfTypeAll < QNetworkIdentity > ( ) )
2020-12-02 12:42:26 +00:00
{
if ( ! networkIdentity . gameObject . activeSelf )
{
2021-11-20 19:55:54 +00:00
if ( networkIdentity . gameObject . hideFlags is not HideFlags . NotEditable and not HideFlags . HideAndDontSave )
2020-12-02 12:42:26 +00:00
{
if ( ! networkIdentity . SceneId . IsEmpty ( ) )
{
SpawnableObjects [ networkIdentity . SceneId ] = networkIdentity ;
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::PrepareSpawnObjects sceneId:{networkIdentity.SceneId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
}
}
}
2021-12-02 19:41:19 -08:00
internal static QNetworkIdentity SpawnSceneObject ( QNetworkSceneId sceneId )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
QNetworkIdentity result ;
2020-12-02 12:42:26 +00:00
if ( SpawnableObjects . ContainsKey ( sceneId ) )
{
var networkIdentity = SpawnableObjects [ sceneId ] ;
SpawnableObjects . Remove ( sceneId ) ;
result = networkIdentity ;
}
else
{
result = null ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2020-12-23 12:58:45 +00:00
internal static void RegisterSystemHandlers ( QNetworkClient client , bool localClient )
2020-12-02 12:42:26 +00:00
{
if ( localClient )
{
2021-04-24 00:10:29 +01:00
client . RegisterHandlerSafe ( QMsgType . ObjectDestroy , OnLocalClientObjectDestroy ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectSpawn , OnLocalClientObjectSpawn ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectSpawnScene , OnLocalClientObjectSpawnScene ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectHide , OnLocalClientObjectHide ) ;
client . RegisterHandlerSafe ( QMsgType . LocalClientAuthority , OnClientAuthority ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2021-04-24 00:10:29 +01:00
client . RegisterHandlerSafe ( QMsgType . ObjectDestroy , OnObjectDestroy ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectSpawn , OnObjectSpawn ) ;
client . RegisterHandlerSafe ( QMsgType . Owner , OnOwnerMessage ) ;
client . RegisterHandlerSafe ( QMsgType . UpdateVars , OnUpdateVarsMessage ) ;
client . RegisterHandlerSafe ( QMsgType . SyncList , OnSyncListMessage ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectSpawnScene , OnObjectSpawnScene ) ;
client . RegisterHandlerSafe ( QMsgType . SpawnFinished , OnObjectSpawnFinished ) ;
client . RegisterHandlerSafe ( QMsgType . ObjectHide , OnObjectDestroy ) ;
client . RegisterHandlerSafe ( QMsgType . LocalClientAuthority , OnClientAuthority ) ;
client . RegisterHandlerSafe ( QMsgType . Animation , QNetworkAnimator . OnAnimationClientMessage ) ;
client . RegisterHandlerSafe ( QMsgType . AnimationParameters , QNetworkAnimator . OnAnimationParametersClientMessage ) ;
2020-12-21 00:50:24 +01:00
}
2021-06-18 22:39:21 +01:00
2021-04-24 00:10:29 +01:00
client . RegisterHandlerSafe ( QMsgType . Rpc , OnRPCMessage ) ;
client . RegisterHandlerSafe ( QMsgType . SyncEvent , OnSyncEventMessage ) ;
client . RegisterHandlerSafe ( QMsgType . AnimationTrigger , QNetworkAnimator . OnAnimationTriggerClientMessage ) ;
2020-12-02 12:42:26 +00:00
}
2021-10-13 18:09:16 +01:00
internal static string GetStringForAssetId ( int assetId )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
if ( QNetworkScene . GetPrefab ( assetId , out var gameObject ) )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
return gameObject . name ;
2020-12-02 12:42:26 +00:00
}
2020-12-21 00:50:24 +01:00
2020-12-23 12:58:45 +00:00
return QNetworkScene . GetSpawnHandler ( assetId , out var func )
2020-12-21 00:50:24 +01:00
? func . GetMethodName ( )
: "unknown" ;
2020-12-02 12:42:26 +00:00
}
2021-10-13 18:09:16 +01:00
public static void RegisterPrefab ( GameObject prefab , int newAssetId ) = > QNetworkScene . RegisterPrefab ( prefab , newAssetId ) ;
2020-12-02 12:42:26 +00:00
2020-12-23 12:58:45 +00:00
public static void RegisterPrefab ( GameObject prefab ) = > QNetworkScene . RegisterPrefab ( prefab ) ;
2020-12-02 12:42:26 +00:00
2021-12-02 19:17:28 -08:00
public static void RegisterPrefab ( GameObject prefab , QSpawnDelegate spawnHandler , QUnSpawnDelegate unspawnHandler ) = > QNetworkScene . RegisterPrefab ( prefab , spawnHandler , unspawnHandler ) ;
2020-12-02 12:42:26 +00:00
2020-12-23 12:58:45 +00:00
public static void UnregisterPrefab ( GameObject prefab ) = > QNetworkScene . UnregisterPrefab ( prefab ) ;
2020-12-02 12:42:26 +00:00
2021-12-02 19:17:28 -08:00
public static void RegisterSpawnHandler ( int assetId , QSpawnDelegate spawnHandler , QUnSpawnDelegate unspawnHandler ) = > QNetworkScene . RegisterSpawnHandler ( assetId , spawnHandler , unspawnHandler ) ;
2020-12-02 12:42:26 +00:00
2021-10-13 18:09:16 +01:00
public static void UnregisterSpawnHandler ( int assetId ) = > QNetworkScene . UnregisterSpawnHandler ( assetId ) ;
2020-12-02 12:42:26 +00:00
2020-12-23 12:58:45 +00:00
public static void ClearSpawners ( ) = > QNetworkScene . ClearSpawners ( ) ;
2020-12-02 12:42:26 +00:00
public static void DestroyAllClientObjects ( ) = > s_NetworkScene . DestroyAllClientObjects ( ) ;
2021-12-02 19:41:19 -08:00
public static void SetLocalObject ( QNetworkInstanceId netId , GameObject obj ) = > s_NetworkScene . SetLocalObject ( netId , obj , s_IsSpawnFinished , false ) ;
2020-12-02 12:42:26 +00:00
2021-12-02 19:41:19 -08:00
public static GameObject FindLocalObject ( QNetworkInstanceId netId ) = > s_NetworkScene . FindLocalObject ( netId ) ;
2020-12-02 12:42:26 +00:00
2021-12-02 19:41:19 -08:00
private static void ApplySpawnPayload ( QNetworkIdentity uv , Vector3 position , byte [ ] payload , QNetworkInstanceId netId , GameObject newGameObject )
2020-12-02 12:42:26 +00:00
{
if ( ! uv . gameObject . activeSelf )
{
uv . gameObject . SetActive ( true ) ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
uv . transform . position = position ;
if ( payload ! = null & & payload . Length > 0 )
{
2020-12-23 12:58:45 +00:00
var reader = new QNetworkReader ( payload ) ;
2020-12-02 12:42:26 +00:00
uv . OnUpdateVars ( reader , true ) ;
}
2021-06-18 22:39:21 +01:00
2020-12-21 00:50:24 +01:00
if ( newGameObject ! = null )
2020-12-02 12:42:26 +00:00
{
newGameObject . SetActive ( true ) ;
uv . SetNetworkInstanceId ( netId ) ;
SetLocalObject ( netId , newGameObject ) ;
if ( s_IsSpawnFinished )
{
uv . OnStartClient ( ) ;
CheckForOwner ( uv ) ;
}
}
}
2020-12-23 12:58:45 +00:00
private static void OnObjectSpawn ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectSpawnMessage ) ;
2021-10-13 18:09:16 +01:00
if ( s_ObjectSpawnMessage . assetId = = 0 )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
Debug . LogError ( $"OnObjSpawn netId: {s_ObjectSpawnMessage.NetId} has invalid asset Id. {s_ObjectSpawnMessage.assetId}" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectSpawnMessage . NetId , out var component ) )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
ApplySpawnPayload ( component , s_ObjectSpawnMessage . Position , s_ObjectSpawnMessage . Payload , s_ObjectSpawnMessage . NetId , null ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-23 12:58:45 +00:00
else if ( QNetworkScene . GetPrefab ( s_ObjectSpawnMessage . assetId , out var original ) )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
var gameObject = Object . Instantiate ( original , s_ObjectSpawnMessage . Position , s_ObjectSpawnMessage . Rotation ) ;
2020-12-23 12:58:45 +00:00
component = gameObject . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Client object spawned for {s_ObjectSpawnMessage.assetId} does not have a NetworkIdentity" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
component . Reset ( ) ;
2020-12-03 11:56:32 +00:00
ApplySpawnPayload ( component , s_ObjectSpawnMessage . Position , s_ObjectSpawnMessage . Payload , s_ObjectSpawnMessage . NetId , gameObject ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
else if ( QNetworkScene . GetSpawnHandler ( s_ObjectSpawnMessage . assetId , out var spawnDelegate ) )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var gameObject2 = spawnDelegate ( s_ObjectSpawnMessage . Position , s_ObjectSpawnMessage . assetId ) ;
2020-12-02 12:42:26 +00:00
if ( gameObject2 = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"Client spawn handler for {s_ObjectSpawnMessage.assetId} returned null" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-23 12:58:45 +00:00
component = gameObject2 . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Client object spawned for {s_ObjectSpawnMessage.assetId} does not have a network identity" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
component . Reset ( ) ;
component . SetDynamicAssetId ( s_ObjectSpawnMessage . assetId ) ;
2020-12-03 11:56:32 +00:00
ApplySpawnPayload ( component , s_ObjectSpawnMessage . Position , s_ObjectSpawnMessage . Payload , s_ObjectSpawnMessage . NetId , gameObject2 ) ;
2020-12-02 12:42:26 +00:00
}
}
}
2020-12-02 18:40:38 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Failed to spawn server object, did you forget to add it to the QSBNetworkManager? assetId={s_ObjectSpawnMessage.assetId} netId={s_ObjectSpawnMessage.NetId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
}
2020-12-23 12:58:45 +00:00
private static void OnObjectSpawnScene ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectSpawnSceneMessage ) ;
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectSpawnSceneMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
ApplySpawnPayload ( networkIdentity , s_ObjectSpawnSceneMessage . Position , s_ObjectSpawnSceneMessage . Payload , s_ObjectSpawnSceneMessage . NetId , networkIdentity . gameObject ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-03 11:56:32 +00:00
var networkIdentity2 = SpawnSceneObject ( s_ObjectSpawnSceneMessage . SceneId ) ;
2020-12-02 12:42:26 +00:00
if ( networkIdentity2 = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Spawn scene object not found for {s_ObjectSpawnSceneMessage.SceneId}" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-21 00:50:24 +01:00
Debug . Log (
$"Client spawn for [netId:{s_ObjectSpawnSceneMessage.NetId}] [sceneId:{s_ObjectSpawnSceneMessage.SceneId}] obj:{networkIdentity2.gameObject.name}" ) ;
2020-12-03 11:56:32 +00:00
ApplySpawnPayload ( networkIdentity2 , s_ObjectSpawnSceneMessage . Position , s_ObjectSpawnSceneMessage . Payload , s_ObjectSpawnSceneMessage . NetId , networkIdentity2 . gameObject ) ;
2020-12-02 12:42:26 +00:00
}
}
}
2020-12-23 12:58:45 +00:00
private static void OnObjectSpawnFinished ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectSpawnFinishedMessage ) ;
Debug . Log ( $"SpawnFinished:{s_ObjectSpawnFinishedMessage.State}" ) ;
2020-12-03 11:56:32 +00:00
if ( s_ObjectSpawnFinishedMessage . State = = 0 U )
2020-12-02 12:42:26 +00:00
{
PrepareToSpawnSceneObjects ( ) ;
s_IsSpawnFinished = false ;
}
else
{
foreach ( var networkIdentity in Objects . Values )
{
if ( ! networkIdentity . IsClient )
{
networkIdentity . OnStartClient ( ) ;
CheckForOwner ( networkIdentity ) ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
s_IsSpawnFinished = true ;
}
}
2020-12-23 12:58:45 +00:00
private static void OnObjectDestroy ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectDestroyMessage ) ;
Debug . Log ( $"ClientScene::OnObjDestroy netId:{s_ObjectDestroyMessage.NetId}" ) ;
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectDestroyMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
networkIdentity . OnNetworkDestroy ( ) ;
2020-12-23 12:58:45 +00:00
if ( ! QNetworkScene . InvokeUnSpawnHandler ( networkIdentity . AssetId , networkIdentity . gameObject ) )
2020-12-02 12:42:26 +00:00
{
if ( networkIdentity . SceneId . IsEmpty ( ) )
{
2020-12-16 09:08:38 +00:00
Object . Destroy ( networkIdentity . gameObject ) ;
2020-12-02 12:42:26 +00:00
}
else
{
networkIdentity . gameObject . SetActive ( false ) ;
SpawnableObjects [ networkIdentity . SceneId ] = networkIdentity ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-03 11:56:32 +00:00
s_NetworkScene . RemoveLocalObject ( s_ObjectDestroyMessage . NetId ) ;
2020-12-02 12:42:26 +00:00
networkIdentity . MarkForReset ( ) ;
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"Did not find target for destroy message for {s_ObjectDestroyMessage.NetId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
private static void OnLocalClientObjectDestroy ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectDestroyMessage ) ;
Debug . Log ( $"ClientScene::OnLocalObjectObjDestroy netId:{s_ObjectDestroyMessage.NetId}" ) ;
2020-12-03 11:56:32 +00:00
s_NetworkScene . RemoveLocalObject ( s_ObjectDestroyMessage . NetId ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-23 12:58:45 +00:00
private static void OnLocalClientObjectHide ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectDestroyMessage ) ;
Debug . Log ( $"ClientScene::OnLocalObjectObjHide netId:{s_ObjectDestroyMessage.NetId}" ) ;
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectDestroyMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
networkIdentity . OnSetLocalVisibility ( false ) ;
}
}
2020-12-23 12:58:45 +00:00
private static void OnLocalClientObjectSpawn ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectSpawnMessage ) ;
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectSpawnMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
networkIdentity . OnSetLocalVisibility ( true ) ;
}
}
2020-12-23 12:58:45 +00:00
private static void OnLocalClientObjectSpawnScene ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ObjectSpawnSceneMessage ) ;
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ObjectSpawnSceneMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
networkIdentity . OnSetLocalVisibility ( true ) ;
}
}
2020-12-23 12:58:45 +00:00
private static void OnUpdateVarsMessage ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var networkInstanceId = netMsg . Reader . ReadNetworkId ( ) ;
2020-12-02 12:42:26 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( networkInstanceId , out var networkIdentity ) )
{
2020-12-03 11:56:32 +00:00
networkIdentity . OnUpdateVars ( netMsg . Reader , false ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"Did not find target for sync message for {networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
private static void OnRPCMessage ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var num = ( int ) netMsg . Reader . ReadPackedUInt32 ( ) ;
var networkInstanceId = netMsg . Reader . ReadNetworkId ( ) ;
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::OnRPCMessage hash:{num} netId:{networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( networkInstanceId , out var networkIdentity ) )
{
2020-12-03 11:56:32 +00:00
networkIdentity . HandleRPC ( num , netMsg . Reader ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( num ) ;
2020-12-21 00:50:24 +01:00
Debug . LogWarningFormat ( "Could not find target object with netId:{0} for RPC call {1}" , networkInstanceId , cmdHashHandlerName ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
private static void OnSyncEventMessage ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var cmdHash = ( int ) netMsg . Reader . ReadPackedUInt32 ( ) ;
var networkInstanceId = netMsg . Reader . ReadNetworkId ( ) ;
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::OnSyncEventMessage {networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( networkInstanceId , out var networkIdentity ) )
{
2020-12-03 11:56:32 +00:00
networkIdentity . HandleSyncEvent ( cmdHash , netMsg . Reader ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"Did not find target for SyncEvent message for {networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
private static void OnSyncListMessage ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
var networkInstanceId = netMsg . Reader . ReadNetworkId ( ) ;
var cmdHash = ( int ) netMsg . Reader . ReadPackedUInt32 ( ) ;
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::OnSyncListMessage {networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( networkInstanceId , out var networkIdentity ) )
{
2020-12-03 11:56:32 +00:00
networkIdentity . HandleSyncList ( cmdHash , netMsg . Reader ) ;
2020-12-02 12:42:26 +00:00
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogWarning ( $"Did not find target for SyncList message for {networkInstanceId}" ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
private static void OnClientAuthority ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_ClientAuthorityMessage ) ;
Debug . Log (
$"ClientScene::OnClientAuthority for connectionId={netMsg.Connection.connectionId} netId: {s_ClientAuthorityMessage.netId}" ) ;
2020-12-02 12:42:26 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_ClientAuthorityMessage . netId , out var networkIdentity ) )
{
networkIdentity . HandleClientAuthority ( s_ClientAuthorityMessage . authority ) ;
}
}
2020-12-23 12:58:45 +00:00
private static void OnOwnerMessage ( QNetworkMessage netMsg )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
netMsg . ReadMessage ( s_OwnerMessage ) ;
Debug . Log (
$"ClientScene::OnOwnerMessage - connectionId={netMsg.Connection.connectionId} netId: {s_OwnerMessage.NetId}" ) ;
2020-12-03 11:56:32 +00:00
if ( netMsg . Connection . GetPlayerController ( s_OwnerMessage . PlayerControllerId , out var playerController ) )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
playerController . UnetView . SetNotLocalPlayer ( ) ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-03 11:56:32 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( s_OwnerMessage . NetId , out var networkIdentity ) )
2020-12-02 12:42:26 +00:00
{
2020-12-03 11:56:32 +00:00
networkIdentity . SetConnectionToServer ( netMsg . Connection ) ;
networkIdentity . SetLocalPlayer ( s_OwnerMessage . PlayerControllerId ) ;
InternalAddPlayer ( networkIdentity , s_OwnerMessage . PlayerControllerId ) ;
2020-12-02 12:42:26 +00:00
}
else
{
var item = new PendingOwner
{
2020-12-03 11:56:32 +00:00
netId = s_OwnerMessage . NetId ,
playerControllerId = s_OwnerMessage . PlayerControllerId
2020-12-02 12:42:26 +00:00
} ;
s_PendingOwnerIds . Add ( item ) ;
}
}
2020-12-23 12:58:45 +00:00
private static void CheckForOwner ( QNetworkIdentity uv )
2020-12-02 12:42:26 +00:00
{
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 ) ;
2020-12-21 00:50:24 +01:00
Debug . Log ( $"ClientScene::OnOwnerMessage - player={uv.gameObject.name}" ) ;
2020-12-02 12:42:26 +00:00
if ( readyConnection . connectionId < 0 )
{
2020-12-18 20:20:54 +00:00
Debug . LogError ( "Owner message received on a local client." ) ;
2020-12-02 12:42:26 +00:00
break ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
InternalAddPlayer ( uv , pendingOwner . playerControllerId ) ;
s_PendingOwnerIds . RemoveAt ( i ) ;
break ;
}
2020-12-21 00:50:24 +01:00
i + + ;
2020-12-02 12:42:26 +00:00
}
}
private static bool s_IsSpawnFinished ;
2021-11-20 19:55:54 +00:00
private static readonly QNetworkScene s_NetworkScene = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QObjectSpawnSceneMessage s_ObjectSpawnSceneMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QObjectSpawnFinishedMessage s_ObjectSpawnFinishedMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QObjectDestroyMessage s_ObjectDestroyMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QObjectSpawnMessage s_ObjectSpawnMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QOwnerMessage s_OwnerMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
2021-11-20 19:55:54 +00:00
private static readonly QClientAuthorityMessage s_ClientAuthorityMessage = new ( ) ;
2020-12-02 12:42:26 +00:00
public const int ReconnectIdInvalid = - 1 ;
public const int ReconnectIdHost = 0 ;
2021-11-20 19:55:54 +00:00
private static List < PendingOwner > s_PendingOwnerIds = new ( ) ;
2020-12-02 12:42:26 +00:00
private struct PendingOwner
{
2021-12-02 19:41:19 -08:00
public QNetworkInstanceId netId ;
2020-12-02 12:42:26 +00:00
public short playerControllerId ;
}
}
}