From e24a724bf4e3e236c813836de918bce66e479a6d Mon Sep 17 00:00:00 2001 From: Anton Franzluebbers Date: Mon, 24 Jan 2022 19:08:02 -0500 Subject: [PATCH] more error checking, player counts --- Runtime/NetworkObject.cs | 14 ++++-- Runtime/Util/BinaryWriterExtensions.cs | 28 +++++++++++ Runtime/Util/NetworkSerializedObjectStream.cs | 20 +++++--- Runtime/Util/SyncRigidbody.cs | 8 ++-- Runtime/VelNetManager.cs | 47 ++++++++++++++----- Runtime/VelNetPlayer.cs | 6 +-- 6 files changed, 94 insertions(+), 29 deletions(-) diff --git a/Runtime/NetworkObject.cs b/Runtime/NetworkObject.cs index 94bf3a7..5c605ac 100644 --- a/Runtime/NetworkObject.cs +++ b/Runtime/NetworkObject.cs @@ -18,8 +18,8 @@ namespace VelNet [Tooltip("Whether this object's ownership is transferrable. Should be true for player objects.")] public bool ownershipLocked; - public bool IsMine => owner != null && owner.isLocal; - + public bool IsMine => owner?.isLocal ?? false; + /// /// This is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room /// @@ -56,7 +56,14 @@ namespace VelNet } int index = syncedComponents.IndexOf(component); - owner.SendMessage(this, index.ToString(), message, reliable); + if (index < 0) + { + Debug.LogError("WAAAAAAAH. NetworkObject doesn't have a reference to this component.", component); + } + else + { + owner.SendMessage(this, index.ToString(), message, reliable); + } } public void SendBytesToGroup(NetworkComponent component, string group, byte[] message, bool reliable = true) @@ -122,6 +129,7 @@ namespace VelNet { c.networkObject = t; } + PrefabUtility.RecordPrefabInstancePropertyModifications(t); } // make the sceneNetworkId a new unique value diff --git a/Runtime/Util/BinaryWriterExtensions.cs b/Runtime/Util/BinaryWriterExtensions.cs index ed7aba5..f43524d 100644 --- a/Runtime/Util/BinaryWriterExtensions.cs +++ b/Runtime/Util/BinaryWriterExtensions.cs @@ -61,5 +61,33 @@ namespace VelNet return bytes.ToArray(); } + + public static List GetBitmaskValues(this IEnumerable bytes) + { + List l = new List(); + foreach (byte b in bytes) + { + l.AddRange(b.GetBitmaskValues()); + } + + return l; + } + + public static List GetBitmaskValues(this byte b) + { + List l = new List(); + for (int i = 0; i < 8; i++) + { + l.Add(b.GetBitmaskValue(i)); + } + + return l; + } + + public static bool GetBitmaskValue(this byte b, int index) + { + return (b & (1 << index)) != 0; + } + } } \ No newline at end of file diff --git a/Runtime/Util/NetworkSerializedObjectStream.cs b/Runtime/Util/NetworkSerializedObjectStream.cs index a6929f8..161791f 100644 --- a/Runtime/Util/NetworkSerializedObjectStream.cs +++ b/Runtime/Util/NetworkSerializedObjectStream.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.IO; using UnityEngine; using UnityEngine.Serialization; @@ -19,12 +20,19 @@ namespace VelNet { while (true) { - if (IsMine) + try { - using MemoryStream mem = new MemoryStream(); - using BinaryWriter writer = new BinaryWriter(mem); - SendState(writer); - SendBytes(mem.ToArray()); + if (IsMine) + { + using MemoryStream mem = new MemoryStream(); + using BinaryWriter writer = new BinaryWriter(mem); + SendState(writer); + SendBytes(mem.ToArray()); + } + } + catch (Exception e) + { + Debug.LogError(e); } yield return new WaitForSeconds(1f / serializationRateHz); diff --git a/Runtime/Util/SyncRigidbody.cs b/Runtime/Util/SyncRigidbody.cs index 3f65511..5937ff4 100644 --- a/Runtime/Util/SyncRigidbody.cs +++ b/Runtime/Util/SyncRigidbody.cs @@ -16,10 +16,10 @@ namespace VelNet [Tooltip("0 to disable.")] public float teleportAngle; - public bool syncKinematic; - public bool syncGravity; - public bool syncVelocity; - public bool syncAngularVelocity; + public bool syncKinematic = true; + public bool syncGravity = true; + public bool syncVelocity = true; + public bool syncAngularVelocity = true; private Vector3 targetPosition; private Quaternion targetRotation; diff --git a/Runtime/VelNetManager.cs b/Runtime/VelNetManager.cs index 295df6e..8a2e447 100644 --- a/Runtime/VelNetManager.cs +++ b/Runtime/VelNetManager.cs @@ -34,7 +34,6 @@ namespace VelNet private Thread clientReceiveThread; private Thread clientReceiveThreadUDP; public int userid = -1; - public string room; private int messagesReceived = 0; public readonly Dictionary players = new Dictionary(); @@ -63,7 +62,7 @@ namespace VelNet public static Action OnConnectedToServer; public static Action MessageReceived; - public static Action LoggedIn; + public static Action OnLoggedIn; public static Action RoomsReceived; public bool connected; @@ -83,8 +82,23 @@ namespace VelNet public readonly Dictionary> groups = new Dictionary>(); private VelNetPlayer masterPlayer; - public static VelNetPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault(); + public static VelNetPlayer LocalPlayer => instance != null ? instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault() : null; public static bool InRoom => LocalPlayer != null && LocalPlayer.room != "-1" && LocalPlayer.room != ""; + public static string Room => LocalPlayer?.room; + + /// + /// The player count in this room. + /// -1 if not in a room. + /// + public static int PlayerCount => instance.players.Count; + + /// + /// The player count in all rooms. + /// Will include players connected to the server but not in a room? + /// + public static int PlayerCountInAllRooms => PlayerCount; // TODO hook up to actual player count + + public static bool IsConnected => instance != null && instance.connected && instance.udpConnected; // Use this for initialization @@ -151,11 +165,11 @@ namespace VelNet // when you join the server case 0: userid = m.sender; - Debug.Log("joined server"); + Debug.Log("Joined server"); try { - LoggedIn?.Invoke(); + OnLoggedIn?.Invoke(); } // prevent errors in subscribers from breaking our code catch (Exception e) @@ -243,24 +257,24 @@ namespace VelNet // we got a left message, kill it // change ownership of all objects to master List deleteObjects = new List(); - foreach (KeyValuePair kvp in objects) + foreach ((string key, NetworkObject value) in objects) { - if (kvp.Value.owner == players[m.sender]) // the owner is the player that left + if (value.owner == players[m.sender]) // the owner is the player that left { // if this object has locked ownership, delete it - if (kvp.Value.ownershipLocked) + if (value.ownershipLocked) { - deleteObjects.Add(kvp.Value.networkId); + deleteObjects.Add(value.networkId); } // I'm the local master player, so can take ownership immediately else if (me.isLocal && me == masterPlayer) { - TakeOwnership(kvp.Key); + TakeOwnership(key); } // the master player left, so everyone should set the owner null (we should get a new master shortly) else if (players[m.sender] == masterPlayer) { - kvp.Value.owner = null; + value.owner = null; } } } @@ -268,7 +282,16 @@ namespace VelNet // TODO this may check for ownership in the future. We don't need ownership here deleteObjects.ForEach(NetworkDestroy); + VelNetPlayer removedPlayer = players[m.sender]; players.Remove(m.sender); + try + { + OnPlayerLeft?.Invoke(removedPlayer); + } + catch (Exception e) + { + Debug.LogError(e); + } } else { @@ -352,7 +375,7 @@ namespace VelNet private void OnApplicationQuit() { - socketConnection.Close(); + socketConnection?.Close(); } /// diff --git a/Runtime/VelNetPlayer.cs b/Runtime/VelNetPlayer.cs index fae5623..1152432 100644 --- a/Runtime/VelNetPlayer.cs +++ b/Runtime/VelNetPlayer.cs @@ -9,8 +9,6 @@ namespace VelNet public class VelNetPlayer { public int userid; - public string username; - public string room; public bool isLocal; @@ -69,7 +67,7 @@ namespace VelNet switch (sections[0]) { - case "5": //sync update for an object I may own + case "5": // sync update for an object I may own { string objectKey = sections[1]; string identifier = sections[2]; @@ -85,7 +83,7 @@ namespace VelNet break; } - case "6": //I'm trying to take ownership of an object + case "6": // I'm trying to take ownership of an object { string networkId = sections[1];