more error checking, player counts

upm
Anton Franzluebbers 2022-01-24 19:08:02 -05:00
parent 796037e74f
commit e24a724bf4
6 changed files with 94 additions and 29 deletions

View File

@ -18,8 +18,8 @@ namespace VelNet
[Tooltip("Whether this object's ownership is transferrable. Should be true for player objects.")] [Tooltip("Whether this object's ownership is transferrable. Should be true for player objects.")]
public bool ownershipLocked; public bool ownershipLocked;
public bool IsMine => owner != null && owner.isLocal; public bool IsMine => owner?.isLocal ?? false;
/// <summary> /// <summary>
/// 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 /// 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
/// </summary> /// </summary>
@ -56,7 +56,14 @@ namespace VelNet
} }
int index = syncedComponents.IndexOf(component); 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) public void SendBytesToGroup(NetworkComponent component, string group, byte[] message, bool reliable = true)
@ -122,6 +129,7 @@ namespace VelNet
{ {
c.networkObject = t; c.networkObject = t;
} }
PrefabUtility.RecordPrefabInstancePropertyModifications(t);
} }
// make the sceneNetworkId a new unique value // make the sceneNetworkId a new unique value

View File

@ -61,5 +61,33 @@ namespace VelNet
return bytes.ToArray(); return bytes.ToArray();
} }
public static List<bool> GetBitmaskValues(this IEnumerable<byte> bytes)
{
List<bool> l = new List<bool>();
foreach (byte b in bytes)
{
l.AddRange(b.GetBitmaskValues());
}
return l;
}
public static List<bool> GetBitmaskValues(this byte b)
{
List<bool> l = new List<bool>();
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;
}
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections; using System;
using System.Collections;
using System.IO; using System.IO;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
@ -19,12 +20,19 @@ namespace VelNet
{ {
while (true) while (true)
{ {
if (IsMine) try
{ {
using MemoryStream mem = new MemoryStream(); if (IsMine)
using BinaryWriter writer = new BinaryWriter(mem); {
SendState(writer); using MemoryStream mem = new MemoryStream();
SendBytes(mem.ToArray()); using BinaryWriter writer = new BinaryWriter(mem);
SendState(writer);
SendBytes(mem.ToArray());
}
}
catch (Exception e)
{
Debug.LogError(e);
} }
yield return new WaitForSeconds(1f / serializationRateHz); yield return new WaitForSeconds(1f / serializationRateHz);

View File

@ -16,10 +16,10 @@ namespace VelNet
[Tooltip("0 to disable.")] [Tooltip("0 to disable.")]
public float teleportAngle; public float teleportAngle;
public bool syncKinematic; public bool syncKinematic = true;
public bool syncGravity; public bool syncGravity = true;
public bool syncVelocity; public bool syncVelocity = true;
public bool syncAngularVelocity; public bool syncAngularVelocity = true;
private Vector3 targetPosition; private Vector3 targetPosition;
private Quaternion targetRotation; private Quaternion targetRotation;

View File

@ -34,7 +34,6 @@ namespace VelNet
private Thread clientReceiveThread; private Thread clientReceiveThread;
private Thread clientReceiveThreadUDP; private Thread clientReceiveThreadUDP;
public int userid = -1; public int userid = -1;
public string room;
private int messagesReceived = 0; private int messagesReceived = 0;
public readonly Dictionary<int, VelNetPlayer> players = new Dictionary<int, VelNetPlayer>(); public readonly Dictionary<int, VelNetPlayer> players = new Dictionary<int, VelNetPlayer>();
@ -63,7 +62,7 @@ namespace VelNet
public static Action OnConnectedToServer; public static Action OnConnectedToServer;
public static Action<Message> MessageReceived; public static Action<Message> MessageReceived;
public static Action LoggedIn; public static Action OnLoggedIn;
public static Action<string[], int> RoomsReceived; public static Action<string[], int> RoomsReceived;
public bool connected; public bool connected;
@ -83,8 +82,23 @@ namespace VelNet
public readonly Dictionary<string, List<int>> groups = new Dictionary<string, List<int>>(); public readonly Dictionary<string, List<int>> groups = new Dictionary<string, List<int>>();
private VelNetPlayer masterPlayer; 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 bool InRoom => LocalPlayer != null && LocalPlayer.room != "-1" && LocalPlayer.room != "";
public static string Room => LocalPlayer?.room;
/// <summary>
/// The player count in this room.
/// -1 if not in a room.
/// </summary>
public static int PlayerCount => instance.players.Count;
/// <summary>
/// The player count in all rooms.
/// Will include players connected to the server but not in a room?
/// </summary>
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 // Use this for initialization
@ -151,11 +165,11 @@ namespace VelNet
// when you join the server // when you join the server
case 0: case 0:
userid = m.sender; userid = m.sender;
Debug.Log("joined server"); Debug.Log("Joined server");
try try
{ {
LoggedIn?.Invoke(); OnLoggedIn?.Invoke();
} }
// prevent errors in subscribers from breaking our code // prevent errors in subscribers from breaking our code
catch (Exception e) catch (Exception e)
@ -243,24 +257,24 @@ namespace VelNet
// we got a left message, kill it // we got a left message, kill it
// change ownership of all objects to master // change ownership of all objects to master
List<string> deleteObjects = new List<string>(); List<string> deleteObjects = new List<string>();
foreach (KeyValuePair<string, NetworkObject> 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 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 // I'm the local master player, so can take ownership immediately
else if (me.isLocal && me == masterPlayer) 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) // the master player left, so everyone should set the owner null (we should get a new master shortly)
else if (players[m.sender] == masterPlayer) 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 // TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy); deleteObjects.ForEach(NetworkDestroy);
VelNetPlayer removedPlayer = players[m.sender];
players.Remove(m.sender); players.Remove(m.sender);
try
{
OnPlayerLeft?.Invoke(removedPlayer);
}
catch (Exception e)
{
Debug.LogError(e);
}
} }
else else
{ {
@ -352,7 +375,7 @@ namespace VelNet
private void OnApplicationQuit() private void OnApplicationQuit()
{ {
socketConnection.Close(); socketConnection?.Close();
} }
/// <summary> /// <summary>

View File

@ -9,8 +9,6 @@ namespace VelNet
public class VelNetPlayer public class VelNetPlayer
{ {
public int userid; public int userid;
public string username;
public string room; public string room;
public bool isLocal; public bool isLocal;
@ -69,7 +67,7 @@ namespace VelNet
switch (sections[0]) 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 objectKey = sections[1];
string identifier = sections[2]; string identifier = sections[2];
@ -85,7 +83,7 @@ namespace VelNet
break; 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]; string networkId = sections[1];