main
Anton Franzluebbers 2022-01-31 17:03:22 -05:00
commit bdf531829b
1 changed files with 182 additions and 111 deletions

View File

@ -15,6 +15,17 @@ namespace VelNet
[AddComponentMenu("VelNet/VelNet Manager")] [AddComponentMenu("VelNet/VelNet Manager")]
public class VelNetManager : MonoBehaviour public class VelNetManager : MonoBehaviour
{ {
public enum MessageReceivedType
{
LOGGED_IN = 0,
ROOM_LIST = 1,
PLAYER_JOINED = 2,
DATA_MESSAGE = 3,
MASTER_MESSAGE = 4,
YOU_JOINED = 5,
PLAYER_LEFT = 6,
YOU_LEFT = 7
}
public enum MessageSendType public enum MessageSendType
{ {
MESSAGE_OTHERS_ORDERED = 7, MESSAGE_OTHERS_ORDERED = 7,
@ -27,14 +38,6 @@ namespace VelNet
MESSAGE_GROUP = 5, MESSAGE_GROUP = 5,
MESSAGE_SETGROUP = 6 MESSAGE_SETGROUP = 6
}; };
public enum MessageReceiveType
{
MESSAGE_LOGIN = 0,
MESSAGE_GETROOMS = 1,
MESSAGE_JOINROOM = 2,
MESSAGE_DATA = 3,
MESSAGE_MASTER_CLIENT = 4,
};
public enum MessageType : byte public enum MessageType : byte
{ {
@ -176,6 +179,22 @@ namespace VelNet
public int masterId; public int masterId;
} }
public class YouJoinedMessage: Message
{
public List<int> ids;
public string room;
}
public class PlayerLeftMessage: Message
{
public int userId;
public string room;
}
public class YouLeftMessage: Message
{
public string room;
}
public class ConnectedMessage : Message public class ConnectedMessage : Message
{ {
} }
@ -282,60 +301,42 @@ namespace VelNet
break; break;
} }
case JoinMessage jm: case YouJoinedMessage jm:
{
if (userid == jm.userId) //this is us
{ {
string oldRoom = LocalPlayer?.room;
// we clear the list, but will recreate as we get messages from people in our room // we clear the list, but will recreate as we get messages from people in our room
players.Clear(); players.Clear();
masterPlayer = null; masterPlayer = null;
if (jm.room != "")
foreach(int playerId in jm.ids)
{ {
VelNetPlayer player = new VelNetPlayer VelNetPlayer player = new VelNetPlayer
{ {
isLocal = true, isLocal = playerId == userid,
userid = jm.userId, room = jm.room,
room = jm.room userid = playerId
}; };
players.Add(player.userid, player);
players.Add(userid, player);
try
{
OnJoinedRoom?.Invoke(jm.room);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
} }
// we just left a room
else try
{ {
// delete all networkobjects that aren't sceneobjects or are null now Debug.Log(jm.room);
objects OnJoinedRoom?.Invoke(jm.room);
.Where(kvp => kvp.Value == null || !kvp.Value.isSceneObject) }
.Select(o => o.Key) // prevent errors in subscribers from breaking our code
.ToList().ForEach(NetworkDestroy); catch (Exception e)
{
// then remove references to the ones that are left Debug.LogError(e);
objects.Clear(); }
// empty all the groups
foreach (string group in instance.groups.Keys)
{
SetupMessageGroup(group, new List<int>());
}
instance.groups.Clear();
foreach(KeyValuePair<int,VelNetPlayer> kvp in players)
{
try try
{ {
OnLeftRoom?.Invoke(oldRoom); OnPlayerJoined?.Invoke(kvp.Value);
} }
// prevent errors in subscribers from breaking our code // prevent errors in subscribers from breaking our code
catch (Exception e) catch (Exception e)
@ -343,75 +344,109 @@ namespace VelNet
Debug.LogError(e); Debug.LogError(e);
} }
} }
break;
} }
else case YouLeftMessage lm:
{
string oldRoom = LocalPlayer?.room;
// delete all networkobjects that aren't sceneobjects or are null now
objects
.Where(kvp => kvp.Value == null || !kvp.Value.isSceneObject)
.Select(o => o.Key)
.ToList().ForEach(NetworkDestroy);
// then remove references to the ones that are left
objects.Clear();
// empty all the groups
foreach (string group in instance.groups.Keys)
{
SetupMessageGroup(group, new List<int>());
}
instance.groups.Clear();
try
{
OnLeftRoom?.Invoke(oldRoom);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
}
case PlayerLeftMessage lm:
{ {
VelNetPlayer me = players[userid]; VelNetPlayer me = players[userid];
// we got a left message, kill it
if (me.room != jm.room) // change ownership of all objects to master
List<string> deleteObjects = new List<string>();
foreach (KeyValuePair<string, NetworkObject> kvp in objects)
{ {
// we got a left message, kill it if (kvp.Value.owner == players[lm.userId]) // the owner is the player that left
// change ownership of all objects to master
List<string> deleteObjects = new List<string>();
foreach (KeyValuePair<string, NetworkObject> kvp in objects)
{ {
if (kvp.Value.owner == players[jm.userId]) // the owner is the player that left // if this object has locked ownership, delete it
if (kvp.Value.ownershipLocked)
{ {
// if this object has locked ownership, delete it deleteObjects.Add(kvp.Value.networkId);
if (kvp.Value.ownershipLocked) }
{ // I'm the local master player, so can take ownership immediately
deleteObjects.Add(kvp.Value.networkId); else if (me.isLocal && me == masterPlayer)
} {
// I'm the local master player, so can take ownership immediately TakeOwnership(kvp.Key);
else if (me.isLocal && me == masterPlayer) }
{ // the master player left, so everyone should set the owner null (we should get a new master shortly)
TakeOwnership(kvp.Key); else if (players[lm.userId] == masterPlayer)
} {
// the master player left, so everyone should set the owner null (we should get a new master shortly) kvp.Value.owner = null;
else if (players[jm.userId] == masterPlayer)
{
kvp.Value.owner = null;
}
} }
} }
// TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy);
VelNetPlayer leftPlayer = players[jm.userId];
players.Remove(jm.userId);
try
{
OnPlayerLeft?.Invoke(leftPlayer);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
} }
else
// TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy);
VelNetPlayer leftPlayer = players[lm.userId];
players.Remove(lm.userId);
try
{ {
// we got a join message, create it OnPlayerLeft?.Invoke(leftPlayer);
VelNetPlayer player = new VelNetPlayer
{
isLocal = false,
room = jm.room,
userid = jm.userId
};
players.Add(jm.userId, player);
try
{
OnPlayerJoined?.Invoke(player);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
} }
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
} }
case JoinMessage jm:
{
// we got a join message, create it
VelNetPlayer player = new VelNetPlayer
{
isLocal = false,
room = jm.room,
userid = jm.userId
};
players.Add(jm.userId, player);
try
{
OnPlayerJoined?.Invoke(player);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break; break;
} }
@ -543,12 +578,12 @@ namespace VelNet
{ {
//read a byte //read a byte
MessageReceiveType type = (MessageReceiveType)stream.ReadByte(); MessageReceivedType type = (MessageReceivedType)stream.ReadByte();
switch (type) switch (type)
{ {
//login //login
case MessageReceiveType.MESSAGE_LOGIN: case MessageReceivedType.LOGGED_IN:
{ {
LoginMessage m = new LoginMessage(); LoginMessage m = new LoginMessage();
m.userId = GetIntFromBytes(ReadExact(stream, 4)); //not really the sender... m.userId = GetIntFromBytes(ReadExact(stream, 4)); //not really the sender...
@ -556,7 +591,7 @@ namespace VelNet
break; break;
} }
//rooms //rooms
case MessageReceiveType.MESSAGE_GETROOMS: case MessageReceivedType.ROOM_LIST:
{ {
RoomsMessage m = new RoomsMessage(); RoomsMessage m = new RoomsMessage();
m.rooms = new List<ListedRoom>(); m.rooms = new List<ListedRoom>();
@ -582,7 +617,7 @@ namespace VelNet
break; break;
} }
//joined //joined
case MessageReceiveType.MESSAGE_JOINROOM: case MessageReceivedType.PLAYER_JOINED:
{ {
JoinMessage m = new JoinMessage(); JoinMessage m = new JoinMessage();
m.userId = GetIntFromBytes(ReadExact(stream, 4)); m.userId = GetIntFromBytes(ReadExact(stream, 4));
@ -593,7 +628,7 @@ namespace VelNet
break; break;
} }
//data //data
case MessageReceiveType.MESSAGE_DATA: case MessageReceivedType.DATA_MESSAGE:
{ {
DataMessage m = new DataMessage(); DataMessage m = new DataMessage();
m.senderId = GetIntFromBytes(ReadExact(stream, 4)); m.senderId = GetIntFromBytes(ReadExact(stream, 4));
@ -603,13 +638,49 @@ namespace VelNet
break; break;
} }
//new master //new master
case MessageReceiveType.MESSAGE_MASTER_CLIENT: case MessageReceivedType.MASTER_MESSAGE:
{ {
ChangeMasterMessage m = new ChangeMasterMessage(); ChangeMasterMessage m = new ChangeMasterMessage();
m.masterId = GetIntFromBytes(ReadExact(stream, 4)); //sender is the new master m.masterId = GetIntFromBytes(ReadExact(stream, 4)); //sender is the new master
AddMessage(m); AddMessage(m);
break; break;
} }
case MessageReceivedType.YOU_JOINED:
{
YouJoinedMessage m = new YouJoinedMessage();
int N = GetIntFromBytes(ReadExact(stream, 4));
m.ids = new List<int>();
for(int i = 0; i < N; i++)
{
m.ids.Add(GetIntFromBytes(ReadExact(stream, 4)));
}
N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m);
break;
}
case MessageReceivedType.PLAYER_LEFT:
{
PlayerLeftMessage m = new PlayerLeftMessage();
m.userId = GetIntFromBytes(ReadExact(stream, 4));
int N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m);
break;
}
case MessageReceivedType.YOU_LEFT:
{
YouLeftMessage m = new YouLeftMessage();
int N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m);
break;
}
} }
} }
} }
@ -1003,4 +1074,4 @@ namespace VelNet
return true; return true;
} }
} }
} }