correct conversion of messages to binary (maybe)

upm
Anton Franzluebbers 2022-01-25 22:50:30 -05:00
parent a61796e28d
commit e3b4ae659c
5 changed files with 93 additions and 102 deletions

View File

@ -79,12 +79,12 @@ namespace VelNet
VelNetPlayer.SendGroupMessage(this, group, (byte)index, message, reliable); VelNetPlayer.SendGroupMessage(this, group, (byte)index, message, reliable);
} }
public void ReceiveBytes(string identifier, byte[] message) public void ReceiveBytes(byte componentIdx, byte[] message)
{ {
// send the message to the right component // send the message to the right component
try try
{ {
syncedComponents[int.Parse(identifier)].ReceiveBytes(message); syncedComponents[componentIdx].ReceiveBytes(message);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -29,7 +29,7 @@ namespace VelNet
{ {
try try
{ {
if (IsMine) if (IsMine && enabled)
{ {
byte[] newBytes = SendState(); byte[] newBytes = SendState();
if (hybridOnChangeCompression) if (hybridOnChangeCompression)
@ -37,14 +37,15 @@ namespace VelNet
if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes)) if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes))
{ {
SendBytes(newBytes); SendBytes(newBytes);
lastSendTime = Time.timeAsDouble;
} }
} }
else else
{ {
SendBytes(newBytes); SendBytes(newBytes);
lastSendTime = Time.timeAsDouble;
} }
lastSendTime = Time.timeAsDouble;
lastSentBytes = newBytes; lastSentBytes = newBytes;
} }
} }

View File

@ -31,7 +31,7 @@ namespace VelNet
{ {
try try
{ {
if (IsMine) if (IsMine && enabled)
{ {
using MemoryStream mem = new MemoryStream(); using MemoryStream mem = new MemoryStream();
using BinaryWriter writer = new BinaryWriter(mem); using BinaryWriter writer = new BinaryWriter(mem);
@ -43,14 +43,15 @@ namespace VelNet
if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes)) if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes))
{ {
SendBytes(newBytes); SendBytes(newBytes);
lastSendTime = Time.timeAsDouble;
} }
} }
else else
{ {
SendBytes(newBytes); SendBytes(newBytes);
lastSendTime = Time.timeAsDouble;
} }
lastSendTime = Time.timeAsDouble;
lastSentBytes = newBytes; lastSentBytes = newBytes;
} }
} }

View File

@ -412,7 +412,7 @@ namespace VelNet
{ {
if (players.ContainsKey(dm.senderId)) if (players.ContainsKey(dm.senderId))
{ {
players[dm.senderId]?.HandleMessage(dm); //todo players[dm.senderId]?.HandleMessage(dm);
} }
else else
{ {
@ -431,7 +431,11 @@ namespace VelNet
for (int i = 0; i < sceneObjects.Length; i++) for (int i = 0; i < sceneObjects.Length; i++)
{ {
sceneObjects[i].networkId = -1 + "-" + i; if (sceneObjects[i].sceneNetworkId == 0)
{
Debug.LogError("Scene Network ID is 0. Make sure to assign one first.", sceneObjects[i]);
}
sceneObjects[i].networkId = -1 + "-" + sceneObjects[i].sceneNetworkId;
sceneObjects[i].owner = masterPlayer; sceneObjects[i].owner = masterPlayer;
sceneObjects[i].isSceneObject = true; // needed for special handling when deleted sceneObjects[i].isSceneObject = true; // needed for special handling when deleted
objects.Add(sceneObjects[i].networkId, sceneObjects[i]); objects.Add(sceneObjects[i].networkId, sceneObjects[i]);
@ -484,12 +488,10 @@ namespace VelNet
} }
} }
/// <summary> /// <summary>
/// Reads N bytes /// Runs in background clientReceiveThread; Listens for incoming data.
/// </summary> /// </summary>
/// <param name="stream"></param>
/// <param name="N"></param>
/// <returns></returns>
private static byte[] ReadExact(Stream stream, int N) private static byte[] ReadExact(Stream stream, int N)
{ {
byte[] toReturn = new byte[N]; byte[] toReturn = new byte[N];
@ -517,20 +519,16 @@ namespace VelNet
{ {
socketConnection = new TcpClient(host, port); socketConnection = new TcpClient(host, port);
socketConnection.NoDelay = true; socketConnection.NoDelay = true;
// Get a stream object for reading
NetworkStream stream = socketConnection.GetStream(); NetworkStream stream = socketConnection.GetStream();
using BinaryReader reader = new BinaryReader(stream); using BinaryReader reader = new BinaryReader(stream);
//now we are connected, so add a message to the queue //now we are connected, so add a message to the queue
AddMessage(new ConnectedMessage()); AddMessage(new ConnectedMessage());
//Join("MyRoom");
//SendTo(MessageSendType.MESSAGE_OTHERS, Encoding.UTF8.GetBytes("Hello"));
//FormGroup("close", new List<uint> { 1 });
//SendToGroup("close", Encoding.UTF8.GetBytes("HelloGroup"));
while (true) while (true)
{ {
// Get a stream object for reading
//read a byte //read a byte
byte type = reader.ReadByte(); byte type = (byte)stream.ReadByte();
switch (type) switch (type)
{ {
@ -538,7 +536,7 @@ namespace VelNet
case 0: case 0:
{ {
LoginMessage m = new LoginMessage(); LoginMessage m = new LoginMessage();
m.userId = reader.ReadInt32(); //not really the sender... m.userId = GetIntFromBytes(ReadExact(stream, 4)); //not really the sender...
AddMessage(m); AddMessage(m);
break; break;
} }
@ -547,8 +545,8 @@ namespace VelNet
{ {
RoomsMessage m = new RoomsMessage(); RoomsMessage m = new RoomsMessage();
m.rooms = new List<ListedRoom>(); m.rooms = new List<ListedRoom>();
int N = reader.ReadInt32(); //the size of the payload int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload
byte[] utf8data = reader.ReadBytes(N); byte[] utf8data = ReadExact(stream, N);
string roomMessage = Encoding.UTF8.GetString(utf8data); string roomMessage = Encoding.UTF8.GetString(utf8data);
@ -572,9 +570,9 @@ namespace VelNet
case 2: case 2:
{ {
JoinMessage m = new JoinMessage(); JoinMessage m = new JoinMessage();
m.userId = reader.ReadInt32(); m.userId = GetIntFromBytes(ReadExact(stream, 4));
int N = reader.ReadByte(); int N = stream.ReadByte();
byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data); m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m); AddMessage(m);
break; break;
@ -583,9 +581,9 @@ namespace VelNet
case 3: case 3:
{ {
DataMessage m = new DataMessage(); DataMessage m = new DataMessage();
m.senderId = reader.ReadInt32(); m.senderId = GetIntFromBytes(ReadExact(stream, 4));
int N = reader.ReadInt32(); //the size of the payload int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload
m.data = reader.ReadBytes(N); //the message m.data = ReadExact(stream, N); //the message
AddMessage(m); AddMessage(m);
break; break;
} }
@ -593,7 +591,7 @@ namespace VelNet
case 4: case 4:
{ {
ChangeMasterMessage m = new ChangeMasterMessage(); ChangeMasterMessage m = new ChangeMasterMessage();
m.masterId = reader.ReadInt32(); //sender is the new master m.masterId = GetIntFromBytes(ReadExact(stream, 4)); //sender is the new master
AddMessage(m); AddMessage(m);
break; break;
} }

View File

@ -61,44 +61,33 @@ namespace VelNet
/// <summary> /// <summary>
/// These are generally things that come from the "owner" and should be enacted locally, where appropriate /// These are generally things that come from the "owner" and should be enacted locally, where appropriate
/// ///
/// Overall message encoding: /// Message encoding:
/// uint16: numMessages
/// for m in numMessages
/// int32: message size (including message type)
/// byte: message type /// byte: message type
/// byte[]: message /// byte[]: message
///
/// The length of the byte[] for message is fixed according to the message type
/// </summary> /// </summary>
public void HandleMessage(VelNetManager.DataMessage m) public void HandleMessage(VelNetManager.DataMessage m)
{ {
using MemoryStream mem = new MemoryStream(m.data); using MemoryStream mem = new MemoryStream(m.data);
using BinaryReader reader = new BinaryReader(mem); using BinaryReader reader = new BinaryReader(mem);
ushort numMessages = reader.ReadUInt16();
for (int i = 0; i < numMessages; i++)
{
//individual message parameters separated by comma //individual message parameters separated by comma
int messageLength = reader.ReadInt32();
VelNetManager.MessageType messageType = (VelNetManager.MessageType)reader.ReadByte(); VelNetManager.MessageType messageType = (VelNetManager.MessageType)reader.ReadByte();
byte[] message = reader.ReadBytes(messageLength-1);
// make a separate reader to prevent malformed messages from messing us up
using MemoryStream messageMem = new MemoryStream(message);
using BinaryReader messageReader = new BinaryReader(messageMem);
switch (messageType) switch (messageType)
{ {
case VelNetManager.MessageType.ObjectSync: // sync update for an object I may own case VelNetManager.MessageType.ObjectSync: // sync update for an object I may own
{ {
string objectKey = messageReader.ReadString(); string objectKey = reader.ReadString();
string identifier = messageReader.ReadString(); byte componentIdx = reader.ReadByte();
string syncMessage = messageReader.ReadString(); int messageLength = reader.ReadInt32();
byte[] messageBytes = Convert.FromBase64String(syncMessage); byte[] syncMessage = reader.ReadBytes(messageLength);
if (manager.objects.ContainsKey(objectKey)) if (manager.objects.ContainsKey(objectKey))
{ {
if (manager.objects[objectKey].owner == this) if (manager.objects[objectKey].owner == this)
{ {
manager.objects[objectKey].ReceiveBytes(identifier, messageBytes); manager.objects[objectKey].ReceiveBytes(componentIdx, syncMessage);
} }
} }
@ -106,7 +95,7 @@ namespace VelNet
} }
case VelNetManager.MessageType.TakeOwnership: // I'm trying to take ownership of an object case VelNetManager.MessageType.TakeOwnership: // I'm trying to take ownership of an object
{ {
string networkId = messageReader.ReadString(); string networkId = reader.ReadString();
if (manager.objects.ContainsKey(networkId)) if (manager.objects.ContainsKey(networkId))
{ {
@ -117,8 +106,8 @@ namespace VelNet
} }
case VelNetManager.MessageType.Instantiate: // I'm trying to instantiate an object case VelNetManager.MessageType.Instantiate: // I'm trying to instantiate an object
{ {
string networkId = messageReader.ReadString(); string networkId = reader.ReadString();
string prefabName = messageReader.ReadString(); string prefabName = reader.ReadString();
if (manager.objects.ContainsKey(networkId)) if (manager.objects.ContainsKey(networkId))
{ {
break; //we already have this one, ignore break; //we already have this one, ignore
@ -130,17 +119,17 @@ namespace VelNet
} }
case VelNetManager.MessageType.Destroy: // I'm trying to destroy a gameobject I own case VelNetManager.MessageType.Destroy: // I'm trying to destroy a gameobject I own
{ {
string networkId = messageReader.ReadString(); string networkId = reader.ReadString();
VelNetManager.NetworkDestroy(networkId); VelNetManager.NetworkDestroy(networkId);
break; break;
} }
case VelNetManager.MessageType.DeleteSceneObjects: //deleted scene objects case VelNetManager.MessageType.DeleteSceneObjects: //deleted scene objects
{ {
int len = messageReader.ReadInt32(); int len = reader.ReadInt32();
for (int k = 1; k < len; k++) for (int k = 1; k < len; k++)
{ {
VelNetManager.NetworkDestroy(messageReader.ReadString()); VelNetManager.NetworkDestroy(reader.ReadString());
} }
break; break;
@ -149,7 +138,6 @@ namespace VelNet
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
}
public void SetAsMasterPlayer() public void SetAsMasterPlayer()
{ {
@ -165,6 +153,7 @@ namespace VelNet
writer.Write((byte)VelNetManager.MessageType.ObjectSync); writer.Write((byte)VelNetManager.MessageType.ObjectSync);
writer.Write(obj.networkId); writer.Write(obj.networkId);
writer.Write(componentIdx); writer.Write(componentIdx);
writer.Write(data.Length);
writer.Write(data); writer.Write(data);
VelNetManager.SendToGroup(group, mem.ToArray(), reliable); VelNetManager.SendToGroup(group, mem.ToArray(), reliable);
} }
@ -176,6 +165,7 @@ namespace VelNet
writer.Write((byte)VelNetManager.MessageType.ObjectSync); writer.Write((byte)VelNetManager.MessageType.ObjectSync);
writer.Write(obj.networkId); writer.Write(obj.networkId);
writer.Write(componentIdx); writer.Write(componentIdx);
writer.Write(data.Length);
writer.Write(data); writer.Write(data);
VelNetManager.SendToRoom(mem.ToArray(), false, reliable); VelNetManager.SendToRoom(mem.ToArray(), false, reliable);
} }
@ -190,6 +180,7 @@ namespace VelNet
{ {
writer.Write(o); writer.Write(o);
} }
VelNetManager.SendToRoom(mem.ToArray()); VelNetManager.SendToRoom(mem.ToArray());
} }