added multiple messages for join/left

upm
Kyle Johnsen 2022-01-31 00:58:55 -05:00
parent 743552bd58
commit 0a45a20dec
1 changed files with 181 additions and 105 deletions

View File

@ -14,6 +14,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,
@ -171,6 +182,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
{ {
} }
@ -277,60 +304,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)
@ -338,75 +347,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;
} }
@ -538,12 +581,12 @@ namespace VelNet
{ {
//read a byte //read a byte
MessageSendType type = (MessageSendType)stream.ReadByte(); MessageReceivedType type = (MessageReceivedType)stream.ReadByte();
switch (type) switch (type)
{ {
//login //login
case MessageSendType.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...
@ -551,7 +594,7 @@ namespace VelNet
break; break;
} }
//rooms //rooms
case MessageSendType.MESSAGE_GETROOMS: case MessageReceivedType.ROOM_LIST:
{ {
RoomsMessage m = new RoomsMessage(); RoomsMessage m = new RoomsMessage();
m.rooms = new List<ListedRoom>(); m.rooms = new List<ListedRoom>();
@ -577,7 +620,7 @@ namespace VelNet
break; break;
} }
//joined //joined
case MessageSendType.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));
@ -588,10 +631,7 @@ namespace VelNet
break; break;
} }
//data //data
case MessageSendType.MESSAGE_OTHERS: case MessageReceivedType.DATA_MESSAGE:
// case MessageSendType.MESSAGE_OTHERS_ORDERED:
// case MessageSendType.MESSAGE_ALL:
// case MessageSendType.MESSAGE_ALL_ORDERED:
{ {
DataMessage m = new DataMessage(); DataMessage m = new DataMessage();
m.senderId = GetIntFromBytes(ReadExact(stream, 4)); m.senderId = GetIntFromBytes(ReadExact(stream, 4));
@ -601,13 +641,49 @@ namespace VelNet
break; break;
} }
//new master //new master
case MessageSendType.MESSAGE_ALL: 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;
}
} }
} }
} }