From e3b4ae659ce917ac13ba8f4e643ec2a81e235018 Mon Sep 17 00:00:00 2001 From: Anton Franzluebbers Date: Tue, 25 Jan 2022 22:50:30 -0500 Subject: [PATCH] correct conversion of messages to binary (maybe) --- Runtime/NetworkObject.cs | 4 +- Runtime/Util/NetworkSerializedObject.cs | 5 +- Runtime/Util/NetworkSerializedObjectStream.cs | 5 +- Runtime/VelNetManager.cs | 46 +++--- Runtime/VelNetPlayer.cs | 135 ++++++++---------- 5 files changed, 93 insertions(+), 102 deletions(-) diff --git a/Runtime/NetworkObject.cs b/Runtime/NetworkObject.cs index 9c09aef..0dd136a 100644 --- a/Runtime/NetworkObject.cs +++ b/Runtime/NetworkObject.cs @@ -79,12 +79,12 @@ namespace VelNet 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 try { - syncedComponents[int.Parse(identifier)].ReceiveBytes(message); + syncedComponents[componentIdx].ReceiveBytes(message); } catch (Exception e) { diff --git a/Runtime/Util/NetworkSerializedObject.cs b/Runtime/Util/NetworkSerializedObject.cs index a645854..7836f2b 100644 --- a/Runtime/Util/NetworkSerializedObject.cs +++ b/Runtime/Util/NetworkSerializedObject.cs @@ -29,7 +29,7 @@ namespace VelNet { try { - if (IsMine) + if (IsMine && enabled) { byte[] newBytes = SendState(); if (hybridOnChangeCompression) @@ -37,14 +37,15 @@ namespace VelNet if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes)) { SendBytes(newBytes); + lastSendTime = Time.timeAsDouble; } } else { SendBytes(newBytes); + lastSendTime = Time.timeAsDouble; } - lastSendTime = Time.timeAsDouble; lastSentBytes = newBytes; } } diff --git a/Runtime/Util/NetworkSerializedObjectStream.cs b/Runtime/Util/NetworkSerializedObjectStream.cs index 7623122..5808afd 100644 --- a/Runtime/Util/NetworkSerializedObjectStream.cs +++ b/Runtime/Util/NetworkSerializedObjectStream.cs @@ -31,7 +31,7 @@ namespace VelNet { try { - if (IsMine) + if (IsMine && enabled) { using MemoryStream mem = new MemoryStream(); using BinaryWriter writer = new BinaryWriter(mem); @@ -43,14 +43,15 @@ namespace VelNet if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes)) { SendBytes(newBytes); + lastSendTime = Time.timeAsDouble; } } else { SendBytes(newBytes); + lastSendTime = Time.timeAsDouble; } - lastSendTime = Time.timeAsDouble; lastSentBytes = newBytes; } } diff --git a/Runtime/VelNetManager.cs b/Runtime/VelNetManager.cs index 670e2c3..9234857 100644 --- a/Runtime/VelNetManager.cs +++ b/Runtime/VelNetManager.cs @@ -412,7 +412,7 @@ namespace VelNet { if (players.ContainsKey(dm.senderId)) { - players[dm.senderId]?.HandleMessage(dm); //todo + players[dm.senderId]?.HandleMessage(dm); } else { @@ -431,7 +431,11 @@ namespace VelNet 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].isSceneObject = true; // needed for special handling when deleted objects.Add(sceneObjects[i].networkId, sceneObjects[i]); @@ -483,13 +487,11 @@ namespace VelNet Debug.Log("On client connect exception " + e); } } - - /// - /// Reads N bytes + + + /// + /// Runs in background clientReceiveThread; Listens for incoming data. /// - /// - /// - /// private static byte[] ReadExact(Stream stream, int N) { byte[] toReturn = new byte[N]; @@ -517,20 +519,16 @@ namespace VelNet { socketConnection = new TcpClient(host, port); socketConnection.NoDelay = true; + // Get a stream object for reading NetworkStream stream = socketConnection.GetStream(); using BinaryReader reader = new BinaryReader(stream); //now we are connected, so add a message to the queue AddMessage(new ConnectedMessage()); - //Join("MyRoom"); - //SendTo(MessageSendType.MESSAGE_OTHERS, Encoding.UTF8.GetBytes("Hello")); - //FormGroup("close", new List { 1 }); - //SendToGroup("close", Encoding.UTF8.GetBytes("HelloGroup")); while (true) { - // Get a stream object for reading //read a byte - byte type = reader.ReadByte(); + byte type = (byte)stream.ReadByte(); switch (type) { @@ -538,7 +536,7 @@ namespace VelNet case 0: { LoginMessage m = new LoginMessage(); - m.userId = reader.ReadInt32(); //not really the sender... + m.userId = GetIntFromBytes(ReadExact(stream, 4)); //not really the sender... AddMessage(m); break; } @@ -547,8 +545,8 @@ namespace VelNet { RoomsMessage m = new RoomsMessage(); m.rooms = new List(); - int N = reader.ReadInt32(); //the size of the payload - byte[] utf8data = reader.ReadBytes(N); + int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload + byte[] utf8data = ReadExact(stream, N); string roomMessage = Encoding.UTF8.GetString(utf8data); @@ -572,9 +570,9 @@ namespace VelNet case 2: { JoinMessage m = new JoinMessage(); - m.userId = reader.ReadInt32(); - int N = reader.ReadByte(); - byte[] utf8data = reader.ReadBytes(N); //the room name, encoded as utf-8 + 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; @@ -583,9 +581,9 @@ namespace VelNet case 3: { DataMessage m = new DataMessage(); - m.senderId = reader.ReadInt32(); - int N = reader.ReadInt32(); //the size of the payload - m.data = reader.ReadBytes(N); //the message + m.senderId = GetIntFromBytes(ReadExact(stream, 4)); + int N = GetIntFromBytes(ReadExact(stream, 4)); //the size of the payload + m.data = ReadExact(stream, N); //the message AddMessage(m); break; } @@ -593,7 +591,7 @@ namespace VelNet case 4: { 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); break; } diff --git a/Runtime/VelNetPlayer.cs b/Runtime/VelNetPlayer.cs index f4fb524..7369dfd 100644 --- a/Runtime/VelNetPlayer.cs +++ b/Runtime/VelNetPlayer.cs @@ -61,93 +61,81 @@ namespace VelNet /// /// These are generally things that come from the "owner" and should be enacted locally, where appropriate /// - /// Overall message encoding: - /// uint16: numMessages - /// for m in numMessages - /// int32: message size (including message type) + /// Message encoding: /// byte: message type /// byte[]: message + /// + /// The length of the byte[] for message is fixed according to the message type /// public void HandleMessage(VelNetManager.DataMessage m) { using MemoryStream mem = new MemoryStream(m.data); using BinaryReader reader = new BinaryReader(mem); - - ushort numMessages = reader.ReadUInt16(); - for (int i = 0; i < numMessages; i++) + //individual message parameters separated by comma + VelNetManager.MessageType messageType = (VelNetManager.MessageType)reader.ReadByte(); + + switch (messageType) { - //individual message parameters separated by comma - int messageLength = reader.ReadInt32(); - 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) + 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 = reader.ReadString(); + byte componentIdx = reader.ReadByte(); + int messageLength = reader.ReadInt32(); + byte[] syncMessage = reader.ReadBytes(messageLength); + if (manager.objects.ContainsKey(objectKey)) { - string objectKey = messageReader.ReadString(); - string identifier = messageReader.ReadString(); - string syncMessage = messageReader.ReadString(); - byte[] messageBytes = Convert.FromBase64String(syncMessage); - 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); } - - break; } - case VelNetManager.MessageType.TakeOwnership: // I'm trying to take ownership of an object - { - string networkId = messageReader.ReadString(); - if (manager.objects.ContainsKey(networkId)) - { - manager.objects[networkId].owner = this; - } - - break; - } - case VelNetManager.MessageType.Instantiate: // I'm trying to instantiate an object - { - string networkId = messageReader.ReadString(); - string prefabName = messageReader.ReadString(); - if (manager.objects.ContainsKey(networkId)) - { - break; //we already have this one, ignore - } - - VelNetManager.SomebodyInstantiatedNetworkObject(networkId, prefabName, this); - - break; - } - case VelNetManager.MessageType.Destroy: // I'm trying to destroy a gameobject I own - { - string networkId = messageReader.ReadString(); - - VelNetManager.NetworkDestroy(networkId); - break; - } - case VelNetManager.MessageType.DeleteSceneObjects: //deleted scene objects - { - int len = messageReader.ReadInt32(); - for (int k = 1; k < len; k++) - { - VelNetManager.NetworkDestroy(messageReader.ReadString()); - } - - break; - } - default: - throw new ArgumentOutOfRangeException(); + break; } + case VelNetManager.MessageType.TakeOwnership: // I'm trying to take ownership of an object + { + string networkId = reader.ReadString(); + + if (manager.objects.ContainsKey(networkId)) + { + manager.objects[networkId].owner = this; + } + + break; + } + case VelNetManager.MessageType.Instantiate: // I'm trying to instantiate an object + { + string networkId = reader.ReadString(); + string prefabName = reader.ReadString(); + if (manager.objects.ContainsKey(networkId)) + { + break; //we already have this one, ignore + } + + VelNetManager.SomebodyInstantiatedNetworkObject(networkId, prefabName, this); + + break; + } + case VelNetManager.MessageType.Destroy: // I'm trying to destroy a gameobject I own + { + string networkId = reader.ReadString(); + + VelNetManager.NetworkDestroy(networkId); + break; + } + case VelNetManager.MessageType.DeleteSceneObjects: //deleted scene objects + { + int len = reader.ReadInt32(); + for (int k = 1; k < len; k++) + { + VelNetManager.NetworkDestroy(reader.ReadString()); + } + + break; + } + default: + throw new ArgumentOutOfRangeException(); } } @@ -165,6 +153,7 @@ namespace VelNet writer.Write((byte)VelNetManager.MessageType.ObjectSync); writer.Write(obj.networkId); writer.Write(componentIdx); + writer.Write(data.Length); writer.Write(data); VelNetManager.SendToGroup(group, mem.ToArray(), reliable); } @@ -176,6 +165,7 @@ namespace VelNet writer.Write((byte)VelNetManager.MessageType.ObjectSync); writer.Write(obj.networkId); writer.Write(componentIdx); + writer.Write(data.Length); writer.Write(data); VelNetManager.SendToRoom(mem.ToArray(), false, reliable); } @@ -190,6 +180,7 @@ namespace VelNet { writer.Write(o); } + VelNetManager.SendToRoom(mem.ToArray()); } @@ -200,7 +191,7 @@ namespace VelNet if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return; // send to all, which will make me delete as well - + using MemoryStream mem = new MemoryStream(); using BinaryWriter writer = new BinaryWriter(mem); writer.Write((byte)VelNetManager.MessageType.Destroy);