2020-12-07 21:19:16 +00:00
using QuantumUNET.Components ;
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
internal class QNetworkScene
2020-12-02 12:42:26 +00:00
{
2021-10-13 18:09:16 +01:00
internal static Dictionary < int , GameObject > guidToPrefab { get ; } = new Dictionary < int , GameObject > ( ) ;
internal static Dictionary < int , QSpawnDelegate > spawnHandlers { get ; } = new Dictionary < int , QSpawnDelegate > ( ) ;
internal static Dictionary < int , UnSpawnDelegate > unspawnHandlers { get ; } = new Dictionary < int , UnSpawnDelegate > ( ) ;
2020-12-23 12:58:45 +00:00
internal Dictionary < NetworkInstanceId , QNetworkIdentity > localObjects { get ; } = new Dictionary < NetworkInstanceId , QNetworkIdentity > ( ) ;
2020-12-02 20:43:16 +00:00
2020-12-02 12:42:26 +00:00
internal void Shutdown ( )
{
2020-12-07 21:04:52 +00:00
ClearLocalObjects ( ) ;
2020-12-02 12:42:26 +00:00
ClearSpawners ( ) ;
}
2020-12-16 08:57:15 +00:00
internal void SetLocalObject ( NetworkInstanceId netId , GameObject obj , bool isClient , bool isServer )
2020-12-02 12:42:26 +00:00
{
if ( obj = = null )
{
2020-12-07 21:04:52 +00:00
localObjects [ netId ] = null ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-23 12:58:45 +00:00
QNetworkIdentity networkIdentity = null ;
2020-12-07 21:04:52 +00:00
if ( localObjects . ContainsKey ( netId ) )
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
networkIdentity = localObjects [ netId ] ;
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 ( networkIdentity = = null )
{
2020-12-23 12:58:45 +00:00
networkIdentity = obj . GetComponent < QNetworkIdentity > ( ) ;
2020-12-07 21:04:52 +00:00
localObjects [ netId ] = networkIdentity ;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
networkIdentity . UpdateClientServer ( isClient , isServer ) ;
}
}
2020-12-16 08:57:15 +00:00
internal GameObject FindLocalObject ( NetworkInstanceId netId )
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
if ( localObjects . ContainsKey ( netId ) )
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects [ netId ] ;
2020-12-02 12:42:26 +00:00
if ( networkIdentity ! = null )
{
return networkIdentity . gameObject ;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return null ;
}
2020-12-23 12:58:45 +00:00
internal bool GetNetworkIdentity ( NetworkInstanceId netId , out QNetworkIdentity uv )
2020-12-02 12:42:26 +00:00
{
bool result ;
2020-12-02 20:43:16 +00:00
if ( localObjects . ContainsKey ( netId ) & & localObjects [ netId ] ! = null )
2020-12-02 12:42:26 +00:00
{
2020-12-02 20:43:16 +00:00
uv = localObjects [ netId ] ;
2020-12-02 12:42:26 +00:00
result = true ;
}
else
{
uv = null ;
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2021-08-29 16:46:11 +01:00
internal bool RemoveLocalObject ( NetworkInstanceId netId )
= > localObjects . Remove ( netId ) ;
2020-12-02 12:42:26 +00:00
2020-12-16 08:57:15 +00:00
internal bool RemoveLocalObjectAndDestroy ( NetworkInstanceId netId )
2020-12-02 12:42:26 +00:00
{
bool result ;
2020-12-07 21:04:52 +00:00
if ( localObjects . ContainsKey ( netId ) )
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects [ netId ] ;
2020-12-16 09:08:38 +00:00
Object . Destroy ( networkIdentity . gameObject ) ;
2020-12-07 21:04:52 +00:00
result = localObjects . Remove ( netId ) ;
2020-12-02 12:42:26 +00:00
}
else
{
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2021-08-29 16:46:11 +01:00
internal void ClearLocalObjects ( )
= > localObjects . Clear ( ) ;
2020-12-02 12:42:26 +00:00
2021-10-13 18:09:16 +01:00
internal static void RegisterPrefab ( GameObject prefab , int newAssetId )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var component = prefab . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component )
{
component . SetDynamicAssetId ( newAssetId ) ;
guidToPrefab [ component . AssetId ] = prefab ;
}
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 . LogError ( $"Could not register '{prefab.name}' since it contains no NetworkIdentity component" ) ;
2020-12-02 12:42:26 +00:00
}
}
internal static void RegisterPrefab ( GameObject prefab )
{
2020-12-23 12:58:45 +00:00
var component = prefab . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component )
{
2020-12-02 20:43:16 +00:00
guidToPrefab [ component . AssetId ] = prefab ;
2020-12-07 21:04:52 +00:00
var componentsInChildren = prefab . GetComponentsInChildren < NetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( componentsInChildren . Length > 1 )
{
2020-12-21 00:50:24 +01:00
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." ) ;
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 . LogError ( $"Could not register '{prefab.name}' since it contains no NetworkIdentity component" ) ;
2020-12-02 12:42:26 +00:00
}
}
2021-10-13 18:09:16 +01:00
internal static bool GetPrefab ( int assetId , out GameObject prefab )
2020-12-02 12:42:26 +00:00
{
bool result ;
2021-10-13 18:09:16 +01:00
if ( assetId = = 0 )
2020-12-02 12:42:26 +00:00
{
prefab = null ;
result = false ;
}
else if ( guidToPrefab . ContainsKey ( assetId ) & & guidToPrefab [ assetId ] ! = null )
{
prefab = guidToPrefab [ assetId ] ;
result = true ;
}
else
{
prefab = null ;
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
internal static void ClearSpawners ( )
{
guidToPrefab . Clear ( ) ;
spawnHandlers . Clear ( ) ;
unspawnHandlers . Clear ( ) ;
}
2021-10-13 18:09:16 +01:00
public static void UnregisterSpawnHandler ( int assetId )
2020-12-02 12:42:26 +00:00
{
spawnHandlers . Remove ( assetId ) ;
unspawnHandlers . Remove ( assetId ) ;
}
2021-10-13 18:09:16 +01:00
internal static void RegisterSpawnHandler ( int assetId , QSpawnDelegate spawnHandler , UnSpawnDelegate unspawnHandler )
2020-12-02 12:42:26 +00:00
{
if ( spawnHandler = = null | | unspawnHandler = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"RegisterSpawnHandler custom spawn function null for {assetId}" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
spawnHandlers [ assetId ] = spawnHandler ;
unspawnHandlers [ assetId ] = unspawnHandler ;
}
}
internal static void UnregisterPrefab ( GameObject prefab )
{
2020-12-23 12:58:45 +00:00
var component = prefab . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Could not unregister '{prefab.name}' since it contains no NetworkIdentity component" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-02 20:43:16 +00:00
spawnHandlers . Remove ( component . AssetId ) ;
unspawnHandlers . Remove ( component . AssetId ) ;
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
internal static void RegisterPrefab ( GameObject prefab , QSpawnDelegate spawnHandler , UnSpawnDelegate unspawnHandler )
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var component = prefab . GetComponent < QNetworkIdentity > ( ) ;
2020-12-02 12:42:26 +00:00
if ( component = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"Could not register '{prefab.name}' since it contains no NetworkIdentity component" ) ;
2020-12-02 12:42:26 +00:00
}
else if ( spawnHandler = = null | | unspawnHandler = = null )
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"RegisterPrefab custom spawn function null for {component.AssetId}" ) ;
2020-12-02 12:42:26 +00:00
}
2021-10-13 18:09:16 +01:00
else if ( component . AssetId = = 0 )
2020-12-02 12:42:26 +00:00
{
2020-12-21 00:50:24 +01:00
Debug . LogError ( $"RegisterPrefab game object {prefab.name} has no prefab. Use RegisterSpawnHandler() instead?" ) ;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-02 20:43:16 +00:00
spawnHandlers [ component . AssetId ] = spawnHandler ;
unspawnHandlers [ component . AssetId ] = unspawnHandler ;
2020-12-02 12:42:26 +00:00
}
}
2021-10-13 18:09:16 +01:00
internal static bool GetSpawnHandler ( int assetId , out QSpawnDelegate handler )
2020-12-02 12:42:26 +00:00
{
bool result ;
if ( spawnHandlers . ContainsKey ( assetId ) )
{
handler = spawnHandlers [ assetId ] ;
result = true ;
}
else
{
handler = null ;
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
2021-10-13 18:09:16 +01:00
internal static bool InvokeUnSpawnHandler ( int assetId , GameObject obj )
2020-12-02 12:42:26 +00:00
{
bool result ;
if ( unspawnHandlers . ContainsKey ( assetId ) & & unspawnHandlers [ assetId ] ! = null )
{
2020-12-07 21:04:52 +00:00
var unSpawnDelegate = unspawnHandlers [ assetId ] ;
2020-12-02 12:42:26 +00:00
unSpawnDelegate ( obj ) ;
result = true ;
}
else
{
result = false ;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result ;
}
internal void DestroyAllClientObjects ( )
{
2020-12-07 21:04:52 +00:00
foreach ( var key in localObjects . Keys )
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects [ key ] ;
2020-12-02 12:42:26 +00:00
if ( networkIdentity ! = null & & networkIdentity . gameObject ! = null )
{
if ( ! InvokeUnSpawnHandler ( networkIdentity . AssetId , networkIdentity . gameObject ) )
{
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 . MarkForReset ( ) ;
networkIdentity . gameObject . SetActive ( false ) ;
}
}
}
}
2021-06-18 22:39:21 +01:00
2020-12-07 21:04:52 +00:00
ClearLocalObjects ( ) ;
2020-12-02 12:42:26 +00:00
}
}
}