161 lines
6.1 KiB
C#

using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace MLAPI.NetworkingManagerComponents
{
internal static class SpawnManager
{
internal static Dictionary<uint, NetworkedObject> spawnedObjects;
internal static Stack<uint> releasedNetworkObjectIds;
private static uint networkObjectIdCounter;
internal static uint GetNetworkObjectId()
{
if (releasedNetworkObjectIds.Count > 0)
{
return releasedNetworkObjectIds.Pop();
}
else
{
networkObjectIdCounter++;
return networkObjectIdCounter;
}
}
private static NetworkingManager netManager
{
get
{
return NetworkingManager.singleton;
}
}
internal static GameObject SpawnObject(int spawnablePrefabIndex, uint networkId, int ownerId)
{
GameObject go = MonoBehaviour.Instantiate(netManager.SpawnablePrefabs[spawnablePrefabIndex]);
NetworkedObject netObject = go.GetComponent<NetworkedObject>();
if (netObject == null)
{
Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of all spawnable objects");
netObject = go.AddComponent<NetworkedObject>();
}
netObject.SpawnablePrefabIndex = spawnablePrefabIndex;
if (netManager.isServer)
{
netObject.NetworkId = GetNetworkObjectId();
}
else
{
netObject.NetworkId = networkId;
}
netObject.OwnerClientId = ownerId;
spawnedObjects.Add(netObject.NetworkId, netObject);
return go;
}
internal static GameObject SpawnPlayerObject(int clientId, uint networkId)
{
GameObject go = MonoBehaviour.Instantiate(netManager.DefaultPlayerPrefab);
NetworkedObject netObject = go.GetComponent<NetworkedObject>();
if (netObject == null)
{
Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of the player prefab");
netObject = go.AddComponent<NetworkedObject>();
}
netObject.OwnerClientId = clientId;
if (NetworkingManager.singleton.isServer)
{
netObject.NetworkId = GetNetworkObjectId();
}
else
{
netObject.NetworkId = networkId;
}
netObject.isPlayerObject = true;
netManager.connectedClients[clientId].PlayerObject = go;
spawnedObjects.Add(netObject.NetworkId, netObject);
return go;
}
internal static void OnDestroyObject(uint networkId, bool destroyGameObject)
{
if (!spawnedObjects.ContainsKey(networkId) || !netManager.NetworkConfig.HandleObjectSpawning)
return;
GameObject go = spawnedObjects[networkId].gameObject;
if (netManager.isServer)
{
releasedNetworkObjectIds.Push(networkId);
if (!spawnedObjects[networkId].ServerOnly)
{
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(networkId);
}
//If we are host, send to everyone except ourselves. Otherwise, send to all
if (netManager.isHost)
netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray(), -1);
else
netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray());
}
}
}
if (destroyGameObject)
MonoBehaviour.Destroy(go);
spawnedObjects.Remove(networkId);
}
internal static void OnSpawnObject(NetworkedObject netObject, int? clientOwnerId = null)
{
if (netObject.isSpawned)
{
Debug.LogWarning("MLAPI: Object already spawned");
return;
}
else if (!netManager.isServer)
{
Debug.LogWarning("MLAPI: Only server can spawn objects");
return;
}
else if (netObject.SpawnablePrefabIndex == -1)
{
Debug.LogWarning("MLAPI: Invalid prefab index");
return;
}
else if (netObject.ServerOnly)
{
Debug.LogWarning("MLAPI: Server only objects does not have to be spawned");
return;
}
else if (netManager.NetworkConfig.HandleObjectSpawning)
{
Debug.LogWarning("MLAPI: NetworkingConfiguration is set to not handle object spawning");
return;
}
uint netId = GetNetworkObjectId();
spawnedObjects.Add(netId, netObject);
netObject.isSpawned = true;
if (clientOwnerId != null)
netObject.OwnerClientId = (int)clientOwnerId;
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(false);
writer.Write(netObject.NetworkId);
writer.Write(netObject.OwnerClientId);
writer.Write(netObject.SpawnablePrefabIndex);
}
//If we are host, send to everyone except ourselves. Otherwise, send to all
if (netManager.isHost)
netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray(), -1);
else
netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray());
}
}
}
}