diff --git a/MLAPI/Data/NetworkingConfiguration.cs b/MLAPI/Data/NetworkingConfiguration.cs index d2027f8..eb043f2 100644 --- a/MLAPI/Data/NetworkingConfiguration.cs +++ b/MLAPI/Data/NetworkingConfiguration.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net; using System.Security.Cryptography; using UnityEngine.Networking; diff --git a/MLAPI/MLAPI.csproj b/MLAPI/MLAPI.csproj index d9cd4d2..12ea40d 100644 --- a/MLAPI/MLAPI.csproj +++ b/MLAPI/MLAPI.csproj @@ -56,6 +56,8 @@ + + diff --git a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs index d9710bb..e8910c9 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using System.IO; using UnityEngine; -using System.Linq; +using MLAPI.NetworkingManagerComponents; namespace MLAPI { @@ -29,6 +28,13 @@ namespace MLAPI return NetworkingManager.singleton.isClient; } } + protected bool isHost + { + get + { + return NetworkingManager.singleton.isHost; + } + } protected NetworkedObject networkedObject { get @@ -62,14 +68,14 @@ namespace MLAPI public int RegisterMessageHandler(string name, Action action) { - int counter = NetworkingManager.singleton.AddIncomingMessageHandler(name, action); + int counter = MessageManager.AddIncomingMessageHandler(name, action); registeredMessageHandlers.Add(name, counter); return counter; } public void DeregisterMessageHandler(string name, int counter) { - NetworkingManager.singleton.RemoveIncomingMessageHandler(name, counter); + MessageManager.RemoveIncomingMessageHandler(name, counter); } private void OnDestroy() @@ -84,7 +90,7 @@ namespace MLAPI { if (isServer) { - NetworkingManager.singleton.InvokeMessageHandlers(messageType, data, -1); + MessageManager.InvokeMessageHandlers(messageType, data, -1); } else { @@ -154,7 +160,7 @@ namespace MLAPI public NetworkedObject GetNetworkedObject(uint networkId) { - return NetworkingManager.singleton.SpawnedObjects[networkId]; + return SpawnManager.spawnedObjects[networkId]; } } } diff --git a/MLAPI/MonoBehaviours/Core/NetworkedObject.cs b/MLAPI/MonoBehaviours/Core/NetworkedObject.cs index 3da11bb..6d77a9e 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkedObject.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkedObject.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using MLAPI.NetworkingManagerComponents; +using UnityEngine; namespace MLAPI { @@ -31,19 +32,19 @@ namespace MLAPI private void OnDestroy() { - NetworkingManager.singleton.OnDestroyObject(NetworkId, false); + SpawnManager.OnDestroyObject(NetworkId, false); } internal bool isSpawned = false; public void Spawn() { - NetworkingManager.singleton.OnSpawnObject(this); + SpawnManager.OnSpawnObject(this); } public void SpawnWithOwnership(int clientId) { - NetworkingManager.singleton.OnSpawnObject(this, clientId); + SpawnManager.OnSpawnObject(this, clientId); } } } diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs index 6f3ad04..aa5c226 100644 --- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs +++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs @@ -1,4 +1,5 @@ using MLAPI.Helper; +using MLAPI.NetworkingManagerComponents; using System; using System.Collections; using System.Collections.Generic; @@ -26,7 +27,7 @@ namespace MLAPI internal HashSet pendingClients; internal bool isServer; internal bool isClient; - internal bool isHost + public bool isHost { get { @@ -35,34 +36,7 @@ namespace MLAPI } private bool isListening; private byte[] messageBuffer; - private Dictionary channels; - private Dictionary messageTypes; - private Dictionary>> messageCallbacks; - private Dictionary messageHandlerCounter; - private Dictionary> releasedMessageHandlerCounters; internal int serverClientId; - internal Dictionary spawnedObjects; - public Dictionary SpawnedObjects - { - get - { - return spawnedObjects; - } - } - private Stack releasedNetworkObjectIds; - private uint networkObjectIdCounter; - private uint GetNetworkObjectId() - { - if (releasedNetworkObjectIds.Count > 0) - { - return releasedNetworkObjectIds.Pop(); - } - else - { - networkObjectIdCounter++; - return networkObjectIdCounter; - } - } public NetworkingConfiguration NetworkConfig; @@ -72,7 +46,7 @@ namespace MLAPI for (int i = 0; i < SpawnablePrefabs.Count; i++) { NetworkedObject netObject = SpawnablePrefabs[i].GetComponentInChildren(); - if(netObject == null) + if (netObject == null) { Debug.LogWarning("MLAPI: All SpawnablePrefabs need a NetworkedObject component. Please add one to the prefab " + SpawnablePrefabs[i].gameObject.name); continue; @@ -81,201 +55,6 @@ namespace MLAPI } } - internal GameObject SpawnObject(int spawnablePrefabIndex, uint networkId, int ownerId) - { - GameObject go = Instantiate(singleton.SpawnablePrefabs[spawnablePrefabIndex]); - NetworkedObject netObject = go.GetComponent(); - if(netObject == null) - { - Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of all spawnable objects"); - netObject = go.AddComponent(); - } - netObject.SpawnablePrefabIndex = spawnablePrefabIndex; - if(singleton.isServer) - { - netObject.NetworkId = singleton.GetNetworkObjectId(); - } - else - { - netObject.NetworkId = networkId; - } - netObject.OwnerClientId = ownerId; - - singleton.spawnedObjects.Add(netObject.NetworkId, netObject); - return go; - } - - internal GameObject SpawnPlayerObject(int clientId, uint networkId) - { - GameObject go = Instantiate(DefaultPlayerPrefab); - NetworkedObject netObject = go.GetComponent(); - if (netObject == null) - { - Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of the player prefab"); - netObject = go.AddComponent(); - } - netObject.OwnerClientId = clientId; - if(isServer) - { - netObject.NetworkId = singleton.GetNetworkObjectId(); - } - else - { - netObject.NetworkId = networkId; - } - netObject.isPlayerObject = true; - connectedClients[clientId].PlayerObject = go; - singleton.spawnedObjects.Add(netObject.NetworkId, netObject); - return go; - } - - internal void OnDestroyObject(uint networkId, bool destroyGameObject) - { - if (!spawnedObjects.ContainsKey(networkId) || !NetworkConfig.HandleObjectSpawning) - return; - GameObject go = spawnedObjects[networkId].gameObject; - if(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 (isHost) - Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray(), -1); - else - Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray()); - } - } - } - if(destroyGameObject) - Destroy(go); - spawnedObjects.Remove(networkId); - } - - internal void OnSpawnObject(NetworkedObject netObject, int? clientOwnerId = null) - { - if (netObject.isSpawned) - { - Debug.LogWarning("MLAPI: Object already spawned"); - return; - } - else if(!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(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 (isHost) - Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray(), -1); - else - Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED", stream.ToArray()); - } - } - - internal void InvokeMessageHandlers(string messageType, byte[] data, int clientId) - { - if(!messageTypes.ContainsKey(messageType) || !messageCallbacks.ContainsKey(messageTypes[messageType])) - return; - - foreach (KeyValuePair> pair in messageCallbacks[messageTypes[messageType]]) - { - pair.Value(clientId, data); - } - } - - internal int AddIncomingMessageHandler(string name, Action action) - { - if(messageTypes.ContainsKey(name)) - { - if(messageCallbacks.ContainsKey(messageTypes[name])) - { - int handlerId = 0; - if (messageHandlerCounter.ContainsKey(messageTypes[name])) - { - if (!releasedMessageHandlerCounters.ContainsKey(messageTypes[name])) - releasedMessageHandlerCounters.Add(messageTypes[name], new Stack()); - - if(releasedMessageHandlerCounters[messageTypes[name]].Count == 0) - { - handlerId = messageHandlerCounter[messageTypes[name]]; - messageHandlerCounter[messageTypes[name]]++; - } - else - { - handlerId = releasedMessageHandlerCounters[messageTypes[name]].Pop(); - } - } - else - { - messageHandlerCounter.Add(messageTypes[name], handlerId + 1); - } - messageCallbacks[messageTypes[name]].Add(handlerId, action); - return handlerId; - } - else - { - messageCallbacks.Add(messageTypes[name], new Dictionary>()); - messageHandlerCounter.Add(messageTypes[name], 1); - messageCallbacks[messageTypes[name]].Add(0, action); - return 0; - } - } - else - { - Debug.LogWarning("MLAPI: The message type " + name + " has not been registered. Please define it in the netConfig"); - return -1; - } - } - - internal void RemoveIncomingMessageHandler(string name, int counter) - { - if (counter == -1) - return; - - if (messageTypes.ContainsKey(name) && messageCallbacks.ContainsKey(messageTypes[name]) && messageCallbacks[messageTypes[name]].ContainsKey(counter)) - { - messageCallbacks[messageTypes[name]].Remove(counter); - if (!releasedMessageHandlerCounters.ContainsKey(messageTypes[name])) - releasedMessageHandlerCounters.Add(messageTypes[name], new Stack()); - releasedMessageHandlerCounters[messageTypes[name]].Push(counter); - } - } - private ConnectionConfig Init(NetworkingConfiguration netConfig) { NetworkConfig = netConfig; @@ -283,20 +62,20 @@ namespace MLAPI pendingClients = new HashSet(); connectedClients = new Dictionary(); messageBuffer = new byte[NetworkConfig.MessageBufferSize]; - channels = new Dictionary(); - messageTypes = new Dictionary(); - messageCallbacks = new Dictionary>>(); - messageHandlerCounter = new Dictionary(); - releasedMessageHandlerCounters = new Dictionary>(); - spawnedObjects = new Dictionary(); - releasedNetworkObjectIds = new Stack(); + MessageManager.channels = new Dictionary(); + MessageManager.messageTypes = new Dictionary(); + MessageManager.messageCallbacks = new Dictionary>>(); + MessageManager.messageHandlerCounter = new Dictionary(); + MessageManager.releasedMessageHandlerCounters = new Dictionary>(); + SpawnManager.spawnedObjects = new Dictionary(); + SpawnManager.releasedNetworkObjectIds = new Stack(); if (NetworkConfig.HandleObjectSpawning) { NetworkedObject[] sceneObjects = FindObjectsOfType(); for (int i = 0; i < sceneObjects.Length; i++) { - uint networkId = GetNetworkObjectId(); - spawnedObjects.Add(networkId, sceneObjects[i]); + uint networkId = SpawnManager.GetNetworkObjectId(); + SpawnManager.spawnedObjects.Add(networkId, sceneObjects[i]); } } @@ -305,11 +84,11 @@ namespace MLAPI //MLAPI channels and messageTypes NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED", QosType.ReliableFragmented); - messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); - messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1); - messageTypes.Add("MLAPI_ADD_OBJECT", 2); - messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3); - messageTypes.Add("MLAPI_DESTROY_OBJECT", 4); + MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); + MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1); + MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2); + MessageManager.messageTypes.Add("MLAPI_CLIENT_DISCONNECT", 3); + MessageManager.messageTypes.Add("MLAPI_DESTROY_OBJECT", 4); HashSet channelNames = new HashSet(); @@ -321,14 +100,14 @@ namespace MLAPI continue; } int channelId = cConfig.AddChannel(pair.Value); - channels.Add(pair.Key, channelId); + MessageManager.channels.Add(pair.Key, channelId); channelNames.Add(pair.Key); } //0-32 are reserved for MLAPI messages ushort messageId = 32; for (ushort i = 0; i < NetworkConfig.MessageTypes.Count; i++) { - messageTypes.Add(NetworkConfig.MessageTypes[i], messageId); + MessageManager.messageTypes.Add(NetworkConfig.MessageTypes[i], messageId); messageId++; } return cConfig; @@ -390,7 +169,7 @@ namespace MLAPI connectedClients.Add(-1, new NetworkedClient() { ClientId = -1 }); if(NetworkConfig.HandleObjectSpawning) { - SpawnPlayerObject(-1, 0); + SpawnManager.SpawnPlayerObject(-1, 0); } } @@ -483,7 +262,7 @@ namespace MLAPI } } - IEnumerator ApprovalTimeout(int clientId) + private IEnumerator ApprovalTimeout(int clientId) { float timeStarted = Time.time; //We yield every frame incase a pending client disconnects and someone else gets its connection id @@ -518,7 +297,7 @@ namespace MLAPI if (messageType >= 32) { //Custom message, invoke all message handlers - foreach (KeyValuePair> pair in messageCallbacks[messageType]) + foreach (KeyValuePair> pair in MessageManager.messageCallbacks[messageType]) { pair.Value(clientId, incommingData); } @@ -583,11 +362,11 @@ namespace MLAPI int prefabId = messageReader.ReadInt32(); if(isPlayerObject) { - SpawnPlayerObject(ownerId, networkId); + SpawnManager.SpawnPlayerObject(ownerId, networkId); } else { - SpawnObject(prefabId, networkId, ownerId); + SpawnManager.SpawnObject(prefabId, networkId, ownerId); } } } @@ -613,11 +392,11 @@ namespace MLAPI if (isPlayerObject) { connectedClients.Add(ownerId, new NetworkedClient() { ClientId = ownerId }); - SpawnPlayerObject(ownerId, networkId); + SpawnManager.SpawnPlayerObject(ownerId, networkId); } else { - SpawnObject(prefabId, networkId, ownerId); + SpawnManager.SpawnObject(prefabId, networkId, ownerId); } } else @@ -653,7 +432,7 @@ namespace MLAPI using (BinaryReader messageReader = new BinaryReader(messageReadStream)) { uint netId = messageReader.ReadUInt32(); - OnDestroyObject(netId, true); + SpawnManager.OnDestroyObject(netId, true); } } } @@ -669,7 +448,7 @@ namespace MLAPI if(isHost && clientId == -1) { //Host trying to send data to it's own client - InvokeMessageHandlers(messageType, data, clientId); + MessageManager.InvokeMessageHandlers(messageType, data, clientId); return; } else if(clientId == -1) @@ -681,14 +460,14 @@ namespace MLAPI { using (BinaryWriter writer = new BinaryWriter(stream)) { - writer.Write(messageTypes[messageType]); + writer.Write(MessageManager.messageTypes[messageType]); writer.Write((ushort)data.Length); writer.Write(data); } //2 bytes for message type and 2 bytes for byte length int size = data.Length + 4; byte[] dataToSend = stream.ToArray(); - NetworkTransport.Send(hostId, clientId, channels[channelName], dataToSend, dataToSend.Length, out error); + NetworkTransport.Send(hostId, clientId, MessageManager.channels[channelName], dataToSend, dataToSend.Length, out error); } } @@ -698,20 +477,20 @@ namespace MLAPI { using (BinaryWriter writer = new BinaryWriter(stream)) { - writer.Write(messageTypes[messageType]); + writer.Write(MessageManager.messageTypes[messageType]); writer.Write((ushort)data.Length); writer.Write(data); } //2 bytes for message type and 2 bytes for byte length int size = data.Length + 4; byte[] dataToSend = stream.ToArray(); - int channel = channels[channelName]; + int channel = MessageManager.channels[channelName]; for (int i = 0; i < clientIds.Length; i++) { int clientId = clientIds[i]; if (isHost && clientId == -1) { - InvokeMessageHandlers(messageType, data, clientId); + MessageManager.InvokeMessageHandlers(messageType, data, clientId); continue; } else if (clientId == -1) @@ -730,20 +509,20 @@ namespace MLAPI { using (BinaryWriter writer = new BinaryWriter(stream)) { - writer.Write(messageTypes[messageType]); + writer.Write(MessageManager.messageTypes[messageType]); writer.Write((ushort)data.Length); writer.Write(data); } //2 bytes for message type and 2 bytes for byte length int size = data.Length + 4; byte[] dataToSend = stream.ToArray(); - int channel = channels[channelName]; + int channel = MessageManager.channels[channelName]; for (int i = 0; i < clientIds.Count; i++) { int clientId = clientIds[i]; if (isHost && clientId == -1) { - InvokeMessageHandlers(messageType, data, clientId); + MessageManager.InvokeMessageHandlers(messageType, data, clientId); continue; } else if (clientId == -1) @@ -762,20 +541,20 @@ namespace MLAPI { using (BinaryWriter writer = new BinaryWriter(stream)) { - writer.Write(messageTypes[messageType]); + writer.Write(MessageManager.messageTypes[messageType]); writer.Write((ushort)data.Length); writer.Write(data); } //2 bytes for message type and 2 bytes for byte length int size = data.Length + 4; byte[] dataToSend = stream.ToArray(); - int channel = channels[channelName]; + int channel = MessageManager.channels[channelName]; foreach (KeyValuePair pair in connectedClients) { int clientId = pair.Key; if(isHost && pair.Key == -1) { - InvokeMessageHandlers(messageType, data, pair.Key); + MessageManager.InvokeMessageHandlers(messageType, data, pair.Key); continue; } else if (clientId == -1) @@ -795,14 +574,14 @@ namespace MLAPI { using (BinaryWriter writer = new BinaryWriter(stream)) { - writer.Write(messageTypes[messageType]); + writer.Write(MessageManager.messageTypes[messageType]); writer.Write((ushort)data.Length); writer.Write(data); } //2 bytes for message type and 2 bytes for byte length int size = data.Length + 4; byte[] dataToSend = stream.ToArray(); - int channel = channels[channelName]; + int channel = MessageManager.channels[channelName]; foreach (KeyValuePair pair in connectedClients) { if (pair.Key == clientIdToIgnore) @@ -810,7 +589,7 @@ namespace MLAPI int clientId = pair.Key; if (isHost && pair.Key == -1) { - InvokeMessageHandlers(messageType, data, clientId); + MessageManager.InvokeMessageHandlers(messageType, data, clientId); continue; } else if (clientId == -1) @@ -879,8 +658,8 @@ namespace MLAPI if(NetworkConfig.HandleObjectSpawning) { - uint networkId = GetNetworkObjectId(); - GameObject go = SpawnPlayerObject(clientId, networkId); + uint networkId = SpawnManager.GetNetworkObjectId(); + GameObject go = SpawnManager.SpawnPlayerObject(clientId, networkId); connectedClients[clientId].PlayerObject = go; } using (MemoryStream writeStream = new MemoryStream()) @@ -899,7 +678,7 @@ namespace MLAPI if (NetworkConfig.HandleObjectSpawning) { int amountOfObjectsToSend = 0; - foreach (KeyValuePair pair in spawnedObjects) + foreach (KeyValuePair pair in SpawnManager.spawnedObjects) { if (pair.Value.ServerOnly) continue; @@ -908,7 +687,7 @@ namespace MLAPI } writer.Write(amountOfObjectsToSend); - foreach (KeyValuePair pair in spawnedObjects) + foreach (KeyValuePair pair in SpawnManager.spawnedObjects) { if (pair.Value.ServerOnly) continue; diff --git a/MLAPI/NetworkingManagerComponents/MessageManager.cs b/MLAPI/NetworkingManagerComponents/MessageManager.cs new file mode 100644 index 0000000..033a45c --- /dev/null +++ b/MLAPI/NetworkingManagerComponents/MessageManager.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace MLAPI.NetworkingManagerComponents +{ + internal static class MessageManager + { + internal static Dictionary channels; + internal static Dictionary messageTypes; + internal static Dictionary>> messageCallbacks; + internal static Dictionary messageHandlerCounter; + internal static Dictionary> releasedMessageHandlerCounters; + + private static NetworkingManager netManager + { + get + { + return NetworkingManager.singleton; + } + } + + internal static void InvokeMessageHandlers(string messageType, byte[] data, int clientId) + { + if (!messageTypes.ContainsKey(messageType) || !messageCallbacks.ContainsKey(messageTypes[messageType])) + return; + + foreach (KeyValuePair> pair in messageCallbacks[messageTypes[messageType]]) + { + pair.Value(clientId, data); + } + } + + internal static int AddIncomingMessageHandler(string name, Action action) + { + if (messageTypes.ContainsKey(name)) + { + if (messageCallbacks.ContainsKey(messageTypes[name])) + { + int handlerId = 0; + if (messageHandlerCounter.ContainsKey(messageTypes[name])) + { + if (!releasedMessageHandlerCounters.ContainsKey(messageTypes[name])) + releasedMessageHandlerCounters.Add(messageTypes[name], new Stack()); + + if (releasedMessageHandlerCounters[messageTypes[name]].Count == 0) + { + handlerId = messageHandlerCounter[messageTypes[name]]; + messageHandlerCounter[messageTypes[name]]++; + } + else + { + handlerId = releasedMessageHandlerCounters[messageTypes[name]].Pop(); + } + } + else + { + messageHandlerCounter.Add(messageTypes[name], handlerId + 1); + } + messageCallbacks[messageTypes[name]].Add(handlerId, action); + return handlerId; + } + else + { + messageCallbacks.Add(messageTypes[name], new Dictionary>()); + messageHandlerCounter.Add(messageTypes[name], 1); + messageCallbacks[messageTypes[name]].Add(0, action); + return 0; + } + } + else + { + Debug.LogWarning("MLAPI: The message type " + name + " has not been registered. Please define it in the netConfig"); + return -1; + } + } + + internal static void RemoveIncomingMessageHandler(string name, int counter) + { + if (counter == -1) + return; + + if (messageTypes.ContainsKey(name) && messageCallbacks.ContainsKey(messageTypes[name]) && messageCallbacks[messageTypes[name]].ContainsKey(counter)) + { + messageCallbacks[messageTypes[name]].Remove(counter); + if (!releasedMessageHandlerCounters.ContainsKey(messageTypes[name])) + releasedMessageHandlerCounters.Add(messageTypes[name], new Stack()); + releasedMessageHandlerCounters[messageTypes[name]].Push(counter); + } + } + } +} diff --git a/MLAPI/NetworkingManagerComponents/SpawnManager.cs b/MLAPI/NetworkingManagerComponents/SpawnManager.cs new file mode 100644 index 0000000..e06b805 --- /dev/null +++ b/MLAPI/NetworkingManagerComponents/SpawnManager.cs @@ -0,0 +1,160 @@ +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace MLAPI.NetworkingManagerComponents +{ + internal static class SpawnManager + { + internal static Dictionary spawnedObjects; + internal static Stack 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(); + if (netObject == null) + { + Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of all spawnable objects"); + netObject = go.AddComponent(); + } + 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(); + if (netObject == null) + { + Debug.LogWarning("MLAPI: Please add a NetworkedObject component to the root of the player prefab"); + netObject = go.AddComponent(); + } + 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()); + } + } + } +}