2020-12-23 13:48:31 +00:00
using QuantumUNET.Logging ;
2020-12-07 21:19:16 +00:00
using QuantumUNET.Messages ;
2020-12-16 09:08:38 +00:00
using QuantumUNET.Transport ;
2020-12-02 21:23:01 +00:00
using System ;
2020-12-02 09:51:53 +00:00
using System.Collections.Generic ;
using System.Collections.ObjectModel ;
using UnityEngine ;
2020-12-16 08:45:58 +00:00
using UnityEngine.Networking ;
2020-12-02 09:51:53 +00:00
2020-12-07 21:19:16 +00:00
namespace QuantumUNET.Components
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
public sealed class QNetworkIdentity : MonoBehaviour
2020-12-02 09:51:53 +00:00
{
public bool IsClient { get ; private set ; }
2020-12-23 12:58:45 +00:00
public bool IsServer = > m_IsServer & & QNetworkServer . active & & m_IsServer ;
2020-12-02 09:51:53 +00:00
public bool HasAuthority { get ; private set ; }
2020-12-16 08:57:15 +00:00
public NetworkInstanceId NetId { get ; private set ; }
2020-12-16 08:45:58 +00:00
public NetworkSceneId SceneId = > m_SceneId ;
2020-12-23 12:58:45 +00:00
public QNetworkConnection ClientAuthorityOwner { get ; private set ; }
2020-12-16 08:45:58 +00:00
public NetworkHash128 AssetId = > m_AssetId ;
2020-12-02 09:51:53 +00:00
public bool IsLocalPlayer { get ; private set ; }
public short PlayerControllerId { get ; private set ; } = - 1 ;
2020-12-23 12:58:45 +00:00
public QNetworkConnection ConnectionToServer { get ; private set ; }
public QNetworkConnection ConnectionToClient { get ; private set ; }
public QNetworkIdentity RootIdentity { get ; private set ; }
public List < QNetworkIdentity > SubIdentities { get ; private set ; } = new List < QNetworkIdentity > ( ) ;
2020-12-02 09:51:53 +00:00
public bool ServerOnly
{
2020-12-18 20:28:22 +00:00
get = > m_ServerOnly ;
set = > m_ServerOnly = value ;
2020-12-02 09:51:53 +00:00
}
public bool LocalPlayerAuthority
{
2020-12-18 20:28:22 +00:00
get = > m_LocalPlayerAuthority ;
set = > m_LocalPlayerAuthority = value ;
2020-12-02 09:51:53 +00:00
}
2021-06-19 11:26:05 +01:00
public QNetworkBehaviour [ ] GetNetworkBehaviours ( )
2021-05-07 14:58:37 +01:00
= > m_NetworkBehaviours ;
2020-12-23 12:58:45 +00:00
public void SetRootIdentity ( QNetworkIdentity newRoot )
2020-12-12 18:14:04 +00:00
{
if ( RootIdentity ! = null )
{
RootIdentity . RemoveSubIdentity ( this ) ;
}
2021-06-18 22:39:21 +01:00
2020-12-12 18:14:04 +00:00
RootIdentity = newRoot ;
RootIdentity . AddSubIndentity ( this ) ;
}
2020-12-23 12:58:45 +00:00
internal void AddSubIndentity ( QNetworkIdentity identityToAdd )
2020-12-12 18:14:04 +00:00
= > SubIdentities . Add ( identityToAdd ) ;
2020-12-23 12:58:45 +00:00
internal void RemoveSubIdentity ( QNetworkIdentity identityToRemove )
2020-12-12 18:14:04 +00:00
= > SubIdentities . Remove ( identityToRemove ) ;
2020-12-16 08:45:58 +00:00
internal void SetDynamicAssetId ( NetworkHash128 newAssetId )
2020-12-02 09:51:53 +00:00
{
if ( ! m_AssetId . IsValid ( ) | | m_AssetId . Equals ( newAssetId ) )
{
m_AssetId = newAssetId ;
}
else
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"SetDynamicAssetId object already has an assetId <{m_AssetId}>" ) ;
2020-12-02 09:51:53 +00:00
}
}
2020-12-23 12:58:45 +00:00
internal void SetClientOwner ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( ClientAuthorityOwner ! = null )
{
2020-12-31 12:10:55 +00:00
QLog . Error ( "SetClientOwner m_ClientAuthorityOwner already set!" ) ;
2020-12-02 09:51:53 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
ClientAuthorityOwner = conn ;
2020-12-02 18:40:38 +00:00
ClientAuthorityOwner . AddOwnedObject ( this ) ;
2020-12-02 09:51:53 +00:00
}
internal void ClearClientOwner ( ) = > ClientAuthorityOwner = null ;
internal void ForceAuthority ( bool authority )
{
if ( HasAuthority ! = authority )
{
HasAuthority = authority ;
if ( authority )
{
OnStartAuthority ( ) ;
}
else
{
OnStopAuthority ( ) ;
}
}
}
2020-12-23 12:58:45 +00:00
public ReadOnlyCollection < QNetworkConnection > Observers
2020-12-02 09:51:53 +00:00
{
get
{
2020-12-23 12:58:45 +00:00
ReadOnlyCollection < QNetworkConnection > result ;
2020-12-02 09:51:53 +00:00
if ( m_Observers = = null )
{
result = null ;
}
else
{
2020-12-23 12:58:45 +00:00
result = new ReadOnlyCollection < QNetworkConnection > ( m_Observers ) ;
2020-12-02 09:51:53 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
return result ;
}
}
2020-12-16 08:57:15 +00:00
internal static NetworkInstanceId GetNextNetworkId ( )
2020-12-02 09:51:53 +00:00
{
var value = s_NextNetworkId ;
s_NextNetworkId + = 1 U ;
2020-12-16 08:57:15 +00:00
return new NetworkInstanceId ( value ) ;
2020-12-02 09:51:53 +00:00
}
private void CacheBehaviours ( )
{
if ( m_NetworkBehaviours = = null )
{
2020-12-23 12:58:45 +00:00
m_NetworkBehaviours = GetComponents < QNetworkBehaviour > ( ) ;
2020-12-02 09:51:53 +00:00
}
}
internal static void AddNetworkId ( uint id )
{
if ( id > = s_NextNetworkId )
{
s_NextNetworkId = id + 1 U ;
}
}
2020-12-16 08:57:15 +00:00
internal void SetNetworkInstanceId ( NetworkInstanceId newNetId )
2020-12-02 09:51:53 +00:00
{
NetId = newNetId ;
if ( newNetId . Value = = 0 U )
{
m_IsServer = false ;
}
}
2020-12-16 08:45:58 +00:00
public void ForceSceneId ( int newSceneId ) = > m_SceneId = new NetworkSceneId ( ( uint ) newSceneId ) ;
2020-12-02 09:51:53 +00:00
internal void UpdateClientServer ( bool isClientFlag , bool isServerFlag )
{
2020-12-21 00:50:24 +01:00
IsClient = IsClient | | isClientFlag ;
m_IsServer = m_IsServer | | isServerFlag ;
2020-12-02 09:51:53 +00:00
}
internal void SetNotLocalPlayer ( )
{
IsLocalPlayer = false ;
2020-12-23 12:58:45 +00:00
if ( ! QNetworkServer . active | | ! QNetworkServer . localClientActive )
2020-12-02 09:51:53 +00:00
{
HasAuthority = false ;
}
}
2020-12-23 12:58:45 +00:00
internal void RemoveObserverInternal ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( m_Observers ! = null )
{
m_Observers . Remove ( conn ) ;
m_ObserverConnections . Remove ( conn . connectionId ) ;
}
}
2020-12-16 09:08:38 +00:00
public void OnDestroy ( )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
if ( m_IsServer & & QNetworkServer . active )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
QNetworkServer . Destroy ( gameObject ) ;
2020-12-02 09:51:53 +00:00
}
}
internal void OnStartServer ( bool allowNonZeroNetId )
{
if ( ! m_IsServer )
{
m_IsServer = true ;
if ( m_LocalPlayerAuthority )
{
HasAuthority = false ;
}
else
{
HasAuthority = true ;
}
2021-06-18 22:39:21 +01:00
2020-12-23 12:58:45 +00:00
m_Observers = new List < QNetworkConnection > ( ) ;
2020-12-02 09:51:53 +00:00
m_ObserverConnections = new HashSet < int > ( ) ;
CacheBehaviours ( ) ;
if ( NetId . IsEmpty ( ) )
{
NetId = GetNextNetworkId ( ) ;
}
else if ( ! allowNonZeroNetId )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Object has non-zero netId {NetId} for {gameObject}" ) ;
2020-12-02 09:51:53 +00:00
return ;
}
2021-06-18 22:39:21 +01:00
2020-12-23 12:58:45 +00:00
QNetworkServer . instance . SetLocalObjectOnServer ( NetId , gameObject ) ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
try
{
networkBehaviour . OnStartServer ( ) ;
}
catch ( Exception ex )
{
2020-12-31 12:10:55 +00:00
QLog . FatalError ( $"Exception in OnStartServer:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
2021-06-18 22:39:21 +01:00
2020-12-23 12:58:45 +00:00
if ( QNetworkClient . active & & QNetworkServer . localClientActive )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
QClientScene . SetLocalObject ( NetId , gameObject ) ;
2020-12-02 09:51:53 +00:00
OnStartClient ( ) ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( HasAuthority )
{
OnStartAuthority ( ) ;
}
}
}
internal void OnStartClient ( )
{
if ( ! IsClient )
{
IsClient = true ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
CacheBehaviours ( ) ;
2020-12-31 12:10:55 +00:00
QLog . Debug ( $"OnStartClient {gameObject} GUID:{NetId} localPlayerAuthority:{LocalPlayerAuthority}" ) ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
{
2020-12-02 09:51:53 +00:00
try
{
networkBehaviour . PreStartClient ( ) ;
networkBehaviour . OnStartClient ( ) ;
}
catch ( Exception ex )
{
2020-12-31 12:10:55 +00:00
QLog . FatalError ( $"Exception in OnStartClient:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
}
internal void OnStartAuthority ( )
{
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
try
{
networkBehaviour . OnStartAuthority ( ) ;
}
catch ( Exception ex )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Exception in OnStartAuthority:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
}
internal void OnStopAuthority ( )
{
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
try
{
networkBehaviour . OnStopAuthority ( ) ;
}
catch ( Exception ex )
{
2020-12-31 12:10:55 +00:00
QLog . FatalError ( $"Exception in OnStopAuthority:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
}
internal void OnSetLocalVisibility ( bool vis )
{
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
try
{
networkBehaviour . OnSetLocalVisibility ( vis ) ;
}
catch ( Exception ex )
{
2020-12-31 12:10:55 +00:00
QLog . FatalError ( $"Exception in OnSetLocalVisibility:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
}
2020-12-23 12:58:45 +00:00
internal bool OnCheckObserver ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
try
{
if ( ! networkBehaviour . OnCheckObserver ( conn ) )
{
return false ;
}
}
catch ( Exception ex )
{
2020-12-31 12:10:55 +00:00
QLog . FatalError ( $"Exception in OnCheckObserver:{ex.Message} {ex.StackTrace}" ) ;
2020-12-02 09:51:53 +00:00
}
}
2020-12-21 00:50:24 +01:00
2020-12-02 09:51:53 +00:00
return true ;
}
2020-12-23 12:58:45 +00:00
internal void UNetSerializeAllVars ( QNetworkWriter writer )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
networkBehaviour . OnSerialize ( writer , true ) ;
}
}
internal void HandleClientAuthority ( bool authority )
{
if ( ! LocalPlayerAuthority )
{
2020-12-31 12:10:55 +00:00
QLog . Error ( $"HandleClientAuthority {gameObject} does not have localPlayerAuthority" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
ForceAuthority ( authority ) ;
}
}
2020-12-23 12:58:45 +00:00
private bool GetInvokeComponent ( int cmdHash , Type invokeClass , out QNetworkBehaviour invokeComponent )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
QNetworkBehaviour networkBehaviour = null ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour2 in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
if ( networkBehaviour2 . GetType ( ) = = invokeClass | | networkBehaviour2 . GetType ( ) . IsSubclassOf ( invokeClass ) )
{
networkBehaviour = networkBehaviour2 ;
break ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
bool result ;
if ( networkBehaviour = = null )
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . FatalError (
2020-12-21 00:50:24 +01:00
$"Found no behaviour for incoming [{cmdHashHandlerName}] on {gameObject}, the server and client should have the same NetworkBehaviour instances [netId={NetId}]." ) ;
2020-12-02 09:51:53 +00:00
invokeComponent = null ;
result = false ;
}
else
{
invokeComponent = networkBehaviour ;
result = true ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
return result ;
}
2020-12-23 12:58:45 +00:00
internal void HandleSyncEvent ( int cmdHash , QNetworkReader reader )
2020-12-02 09:51:53 +00:00
{
2020-12-16 09:08:38 +00:00
if ( gameObject = = null )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"SyncEvent [{cmdHashHandlerName}] received for deleted object [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
2020-12-23 12:58:45 +00:00
else if ( ! QNetworkBehaviour . GetInvokerForHashSyncEvent ( cmdHash , out var invokeClass , out var cmdDelegate ) )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName2 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . FatalError (
2020-12-21 00:50:24 +01:00
$"Found no receiver for incoming [{cmdHashHandlerName2}] on {gameObject}, the server and client should have the same NetworkBehaviour instances [netId={NetId}]." ) ;
2020-12-02 09:51:53 +00:00
}
else if ( ! GetInvokeComponent ( cmdHash , invokeClass , out var obj ) )
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName3 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"SyncEvent [{cmdHashHandlerName3}] handler not found [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
cmdDelegate ( obj , reader ) ;
}
}
2020-12-23 12:58:45 +00:00
internal void HandleSyncList ( int cmdHash , QNetworkReader reader )
2020-12-02 09:51:53 +00:00
{
2020-12-16 09:08:38 +00:00
if ( gameObject = = null )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"SyncList [{cmdHashHandlerName}] received for deleted object [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
2020-12-23 12:58:45 +00:00
else if ( ! QNetworkBehaviour . GetInvokerForHashSyncList ( cmdHash , out var invokeClass , out var cmdDelegate ) )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName2 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . FatalError (
2020-12-21 00:50:24 +01:00
$"Found no receiver for incoming [{cmdHashHandlerName2}] on {gameObject}, the server and client should have the same NetworkBehaviour instances [netId={NetId}]." ) ;
2020-12-02 09:51:53 +00:00
}
else if ( ! GetInvokeComponent ( cmdHash , invokeClass , out var obj ) )
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName3 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"SyncList [{cmdHashHandlerName3}] handler not found [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
cmdDelegate ( obj , reader ) ;
}
}
2020-12-23 12:58:45 +00:00
internal void HandleCommand ( int cmdHash , QNetworkReader reader )
2020-12-02 09:51:53 +00:00
{
2020-12-16 09:08:38 +00:00
if ( gameObject = = null )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Command [{cmdHashHandlerName}] received for deleted object [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
2020-12-23 12:58:45 +00:00
else if ( ! QNetworkBehaviour . GetInvokerForHashCommand ( cmdHash , out var invokeClass , out var cmdDelegate ) )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName2 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . FatalError (
2020-12-21 00:50:24 +01:00
$"Found no receiver for incoming [{cmdHashHandlerName2}] on {gameObject}, the server and client should have the same NetworkBehaviour instances [netId={NetId}]." ) ;
2020-12-02 09:51:53 +00:00
}
else if ( ! GetInvokeComponent ( cmdHash , invokeClass , out var obj ) )
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName3 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Command [{cmdHashHandlerName3}] handler not found [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
cmdDelegate ( obj , reader ) ;
}
}
2020-12-23 12:58:45 +00:00
internal void HandleRPC ( int cmdHash , QNetworkReader reader )
2020-12-02 09:51:53 +00:00
{
2020-12-16 09:08:38 +00:00
if ( gameObject = = null )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"ClientRpc [{cmdHashHandlerName}] received for deleted object [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
2020-12-23 12:58:45 +00:00
else if ( ! QNetworkBehaviour . GetInvokerForHashClientRpc ( cmdHash , out var invokeClass , out var cmdDelegate ) )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName2 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . FatalError (
2020-12-21 00:50:24 +01:00
$"Found no receiver for incoming [{cmdHashHandlerName2}] on {gameObject}, the server and client should have the same NetworkBehaviour instances [netId={NetId}]." ) ;
2020-12-02 09:51:53 +00:00
}
else if ( ! GetInvokeComponent ( cmdHash , invokeClass , out var obj ) )
{
2020-12-23 12:58:45 +00:00
var cmdHashHandlerName3 = QNetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"ClientRpc [{cmdHashHandlerName3}] handler not found [netId={NetId}]" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
cmdDelegate ( obj , reader ) ;
}
}
internal void UNetUpdate ( )
{
var num = 0 U ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
var dirtyChannel = networkBehaviour . GetDirtyChannel ( ) ;
if ( dirtyChannel ! = - 1 )
{
num | = 1 U < < dirtyChannel ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( num ! = 0 U )
{
var j = 0 ;
2020-12-23 12:58:45 +00:00
while ( j < QNetworkServer . numChannels )
2020-12-02 09:51:53 +00:00
{
if ( ( num & ( 1 U < < j ) ) ! = 0 U )
{
2021-05-03 20:13:03 +01:00
s_UpdateWriter . StartMessage ( QMsgType . UpdateVars ) ;
2020-12-02 09:51:53 +00:00
s_UpdateWriter . Write ( NetId ) ;
var flag = false ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
var position = s_UpdateWriter . Position ;
2020-12-21 00:50:24 +01:00
if ( networkBehaviour . GetDirtyChannel ( ) ! = j )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
networkBehaviour . OnSerialize ( s_UpdateWriter , false ) ;
2020-12-02 09:51:53 +00:00
}
else
{
2020-12-21 00:50:24 +01:00
if ( networkBehaviour . OnSerialize ( s_UpdateWriter , false ) )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
networkBehaviour . ClearAllDirtyBits ( ) ;
2020-12-02 09:51:53 +00:00
flag = true ;
}
2021-06-18 22:39:21 +01:00
2020-12-23 12:58:45 +00:00
var maxPacketSize = QNetworkServer . maxPacketSize ;
2020-12-02 09:51:53 +00:00
if ( s_UpdateWriter . Position - position > maxPacketSize )
{
2020-12-31 12:10:55 +00:00
QLog . Warning (
2020-12-21 00:50:24 +01:00
$"Large state update of {s_UpdateWriter.Position - position} bytes for netId:{NetId} from script:{networkBehaviour}" ) ;
2020-12-02 09:51:53 +00:00
}
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( flag )
{
s_UpdateWriter . FinishMessage ( ) ;
2020-12-23 12:58:45 +00:00
QNetworkServer . SendWriterToReady ( gameObject , s_UpdateWriter , j ) ;
2020-12-02 09:51:53 +00:00
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
j + + ;
}
}
}
2020-12-23 12:58:45 +00:00
internal void OnUpdateVars ( QNetworkReader reader , bool initialState )
2020-12-02 09:51:53 +00:00
{
if ( initialState & & m_NetworkBehaviours = = null )
{
2020-12-23 12:58:45 +00:00
m_NetworkBehaviours = GetComponents < QNetworkBehaviour > ( ) ;
2020-12-02 09:51:53 +00:00
}
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
networkBehaviour . OnDeserialize ( reader , initialState ) ;
}
}
internal void SetLocalPlayer ( short localPlayerControllerId )
{
IsLocalPlayer = true ;
PlayerControllerId = localPlayerControllerId ;
2020-12-16 09:08:38 +00:00
var hasAuthority = HasAuthority ;
2020-12-02 09:51:53 +00:00
if ( LocalPlayerAuthority )
{
HasAuthority = true ;
}
2021-06-18 22:39:21 +01:00
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
networkBehaviour . OnStartLocalPlayer ( ) ;
if ( LocalPlayerAuthority & & ! hasAuthority )
{
networkBehaviour . OnStartAuthority ( ) ;
}
}
}
2020-12-23 12:58:45 +00:00
internal void SetConnectionToServer ( QNetworkConnection conn ) = > ConnectionToServer = conn ;
2020-12-02 09:51:53 +00:00
2020-12-23 12:58:45 +00:00
internal void SetConnectionToClient ( QNetworkConnection conn , short newPlayerControllerId )
2020-12-02 09:51:53 +00:00
{
PlayerControllerId = newPlayerControllerId ;
ConnectionToClient = conn ;
}
internal void OnNetworkDestroy ( )
{
var num = 0 ;
while ( m_NetworkBehaviours ! = null & & num < m_NetworkBehaviours . Length )
{
var networkBehaviour = m_NetworkBehaviours [ num ] ;
networkBehaviour . OnNetworkDestroy ( ) ;
num + + ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
m_IsServer = false ;
}
internal void ClearObservers ( )
{
if ( m_Observers ! = null )
{
var count = m_Observers . Count ;
for ( var i = 0 ; i < count ; i + + )
{
var networkConnection = m_Observers [ i ] ;
2020-12-02 18:40:38 +00:00
networkConnection . RemoveFromVisList ( this , true ) ;
2020-12-02 09:51:53 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
m_Observers . Clear ( ) ;
m_ObserverConnections . Clear ( ) ;
}
}
2020-12-23 12:58:45 +00:00
internal void AddObserver ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( m_Observers = = null )
{
2020-12-31 12:10:55 +00:00
QLog . Error ( $"AddObserver for {gameObject} observer list is null" ) ;
2020-12-02 09:51:53 +00:00
}
else if ( m_ObserverConnections . Contains ( conn . connectionId ) )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Duplicate observer {conn.address} added for {gameObject}" ) ;
2020-12-02 09:51:53 +00:00
}
else
{
2020-12-31 12:10:55 +00:00
QLog . Debug ( $"Added observer {conn.address} added for {gameObject}" ) ;
2020-12-02 09:51:53 +00:00
m_Observers . Add ( conn ) ;
m_ObserverConnections . Add ( conn . connectionId ) ;
2020-12-02 18:40:38 +00:00
conn . AddToVisList ( this ) ;
2020-12-02 09:51:53 +00:00
}
}
2020-12-23 12:58:45 +00:00
internal void RemoveObserver ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( m_Observers ! = null )
{
m_Observers . Remove ( conn ) ;
m_ObserverConnections . Remove ( conn . connectionId ) ;
2020-12-02 18:40:38 +00:00
conn . RemoveFromVisList ( this , true ) ;
2020-12-02 09:51:53 +00:00
}
}
public void RebuildObservers ( bool initialize )
{
if ( m_Observers ! = null )
{
var flag = false ;
var flag2 = false ;
2020-12-23 12:58:45 +00:00
var hashSet = new HashSet < QNetworkConnection > ( ) ;
var hashSet2 = new HashSet < QNetworkConnection > ( m_Observers ) ;
2020-12-21 00:50:24 +01:00
foreach ( var networkBehaviour in m_NetworkBehaviours )
2020-12-02 09:51:53 +00:00
{
flag2 | = networkBehaviour . OnRebuildObservers ( hashSet , initialize ) ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( ! flag2 )
{
if ( initialize )
{
2020-12-23 12:58:45 +00:00
foreach ( var networkConnection in QNetworkServer . connections )
2020-12-02 09:51:53 +00:00
{
if ( networkConnection ! = null )
{
if ( networkConnection . isReady )
{
AddObserver ( networkConnection ) ;
}
}
}
2020-12-21 00:50:24 +01:00
2020-12-23 12:58:45 +00:00
foreach ( var networkConnection2 in QNetworkServer . localConnections )
2020-12-02 09:51:53 +00:00
{
if ( networkConnection2 ! = null )
{
if ( networkConnection2 . isReady )
{
AddObserver ( networkConnection2 ) ;
}
}
}
}
}
else
{
foreach ( var networkConnection3 in hashSet )
{
if ( networkConnection3 ! = null )
{
if ( ! networkConnection3 . isReady )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Observer is not ready for {gameObject} {networkConnection3}" ) ;
2020-12-02 09:51:53 +00:00
}
else if ( initialize | | ! hashSet2 . Contains ( networkConnection3 ) )
{
2020-12-02 18:40:38 +00:00
networkConnection3 . AddToVisList ( this ) ;
2020-12-23 13:48:31 +00:00
QLog . Log ( $"New Observer for {gameObject} {networkConnection3}" ) ;
2020-12-02 09:51:53 +00:00
flag = true ;
}
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
foreach ( var networkConnection4 in hashSet2 )
{
if ( ! hashSet . Contains ( networkConnection4 ) )
{
2020-12-02 18:40:38 +00:00
networkConnection4 . RemoveFromVisList ( this , true ) ;
2020-12-23 13:48:31 +00:00
QLog . Log ( $"Removed Observer for {gameObject} {networkConnection4}" ) ;
2020-12-02 09:51:53 +00:00
flag = true ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( initialize )
{
2020-12-23 12:58:45 +00:00
foreach ( var connection in QNetworkServer . localConnections )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
if ( ! hashSet . Contains ( connection ) )
2020-12-02 09:51:53 +00:00
{
OnSetLocalVisibility ( false ) ;
}
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 09:51:53 +00:00
if ( flag )
{
2020-12-23 12:58:45 +00:00
m_Observers = new List < QNetworkConnection > ( hashSet ) ;
2020-12-02 09:51:53 +00:00
m_ObserverConnections . Clear ( ) ;
2020-12-21 00:50:24 +01:00
foreach ( var observer in m_Observers )
2020-12-02 09:51:53 +00:00
{
2020-12-21 00:50:24 +01:00
m_ObserverConnections . Add ( observer . connectionId ) ;
2020-12-02 09:51:53 +00:00
}
}
}
}
}
2020-12-23 12:58:45 +00:00
public bool RemoveClientAuthority ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( ! IsServer )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Cannot remove authority on client-side. (NetId:{NetId}, Gameobject:{gameObject.name})" ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( ConnectionToClient ! = null )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( "RemoveClientAuthority cannot remove authority for a player object" ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( ClientAuthorityOwner = = null )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"RemoveClientAuthority for {gameObject} has no clientAuthority owner." ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( ClientAuthorityOwner ! = conn )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"RemoveClientAuthority for {gameObject} has different owner." ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-04 09:23:27 +00:00
ClientAuthorityOwner . RemoveOwnedObject ( this ) ;
ClientAuthorityOwner = null ;
ForceAuthority ( true ) ;
2020-12-23 12:58:45 +00:00
conn . Send ( 15 , new QClientAuthorityMessage
2020-12-02 09:51:53 +00:00
{
2020-12-04 09:23:27 +00:00
netId = NetId ,
authority = false
} ) ;
clientAuthorityCallback ? . Invoke ( conn , this , false ) ;
return true ;
2020-12-02 09:51:53 +00:00
}
2020-12-23 12:58:45 +00:00
public bool AssignClientAuthority ( QNetworkConnection conn )
2020-12-02 09:51:53 +00:00
{
if ( ! IsServer )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Cannot assign authority on client-side. (NetId:{NetId}, Gameobject:{gameObject.name})" ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( ! LocalPlayerAuthority )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"Cannot assign authority on object without LocalPlayerAuthority. (NetId:{NetId}, Gameobject:{gameObject.name})" ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( ClientAuthorityOwner ! = null & & conn ! = ClientAuthorityOwner )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"AssignClientAuthority for {gameObject} already has an owner. Use RemoveClientAuthority() first." ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
else if ( conn = = null )
{
2020-12-31 12:10:55 +00:00
QLog . Warning ( $"AssignClientAuthority for {gameObject} owner cannot be null. Use RemoveClientAuthority() instead." ) ;
2020-12-04 09:23:27 +00:00
return false ;
2020-12-02 09:51:53 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-04 09:23:27 +00:00
ClientAuthorityOwner = conn ;
ClientAuthorityOwner . AddOwnedObject ( this ) ;
2020-12-02 09:51:53 +00:00
2020-12-04 09:23:27 +00:00
ForceAuthority ( false ) ;
2020-12-23 12:58:45 +00:00
conn . Send ( 15 , new QClientAuthorityMessage
2020-12-04 09:23:27 +00:00
{
netId = NetId ,
authority = true
} ) ;
clientAuthorityCallback ? . Invoke ( conn , this , true ) ;
return true ;
2020-12-02 09:51:53 +00:00
}
internal void MarkForReset ( ) = > m_Reset = true ;
internal void Reset ( )
{
if ( m_Reset )
{
m_Reset = false ;
m_IsServer = false ;
IsClient = false ;
HasAuthority = false ;
2020-12-16 08:57:15 +00:00
NetId = ( NetworkInstanceId ) typeof ( NetworkInstanceId ) . GetField ( "Zero" , System . Reflection . BindingFlags . Static ) . GetValue ( null ) ;
2020-12-02 09:51:53 +00:00
IsLocalPlayer = false ;
ConnectionToServer = null ;
ConnectionToClient = null ;
PlayerControllerId = - 1 ;
m_NetworkBehaviours = null ;
ClearObservers ( ) ;
ClientAuthorityOwner = null ;
}
}
2020-12-04 22:14:53 +00:00
public static void UNetStaticUpdate ( )
2020-12-02 09:51:53 +00:00
{
2020-12-23 12:58:45 +00:00
QNetworkServer . Update ( ) ;
QNetworkClient . UpdateClients ( ) ;
QNetworkManager . UpdateScene ( ) ;
2020-12-02 09:51:53 +00:00
}
[SerializeField]
2020-12-16 08:45:58 +00:00
private NetworkSceneId m_SceneId ;
2020-12-02 09:51:53 +00:00
[SerializeField]
2020-12-16 08:45:58 +00:00
private NetworkHash128 m_AssetId ;
2020-12-02 09:51:53 +00:00
[SerializeField]
private bool m_ServerOnly ;
[SerializeField]
private bool m_LocalPlayerAuthority ;
2020-12-03 08:28:05 +00:00
2020-12-02 09:51:53 +00:00
private bool m_IsServer ;
2020-12-12 18:14:04 +00:00
2020-12-23 12:58:45 +00:00
private QNetworkBehaviour [ ] m_NetworkBehaviours ;
2020-12-02 09:51:53 +00:00
private HashSet < int > m_ObserverConnections ;
2020-12-23 12:58:45 +00:00
private List < QNetworkConnection > m_Observers ;
2020-12-12 18:14:04 +00:00
2020-12-21 00:50:24 +01:00
private bool m_Reset ;
2020-12-02 09:51:53 +00:00
private static uint s_NextNetworkId = 1 U ;
2020-12-23 12:58:45 +00:00
private static readonly QNetworkWriter s_UpdateWriter = new QNetworkWriter ( ) ;
2020-12-02 09:51:53 +00:00
public static ClientAuthorityCallback clientAuthorityCallback ;
2020-12-23 12:58:45 +00:00
public delegate void ClientAuthorityCallback ( QNetworkConnection conn , QNetworkIdentity uv , bool authorityState ) ;
2020-12-02 09:51:53 +00:00
}
}