From d8fc41f1c4657a762d4827d05d4006348ae53210 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 6 Dec 2024 15:39:36 +0100 Subject: [PATCH 01/14] First step for ControlCore support --- EchoStream.cs | 173 ++++++++++++++++++++++++++++++++++++++++++++ EchoStream.cs.meta | 2 + Messages.cs | 175 ++++++++++++++++++++++++++++++++++++++------- SiteServer.cs | 85 ++++++++++++++++++++++ SiteServer.cs.meta | 2 + 5 files changed, 410 insertions(+), 27 deletions(-) create mode 100644 EchoStream.cs create mode 100644 EchoStream.cs.meta create mode 100644 SiteServer.cs create mode 100644 SiteServer.cs.meta diff --git a/EchoStream.cs b/EchoStream.cs new file mode 100644 index 0000000..c9ae949 --- /dev/null +++ b/EchoStream.cs @@ -0,0 +1,173 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using System.Collections.Concurrent; + +public class EchoStream : Stream { + public override bool CanTimeout { get; } = true; + public override int ReadTimeout { get; set; } = Timeout.Infinite; + public override int WriteTimeout { get; set; } = Timeout.Infinite; + public override bool CanRead { get; } = true; + public override bool CanSeek { get; } = false; + public override bool CanWrite { get; } = true; + + public bool CopyBufferOnWrite { get; set; } = false; + + private readonly object _lock = new object(); + + // Default underlying mechanism for BlockingCollection is ConcurrentQueue, which is what we want + private readonly BlockingCollection _Buffers; + private int _maxQueueDepth = 10; + + private byte[] m_buffer = null; + private int m_offset = 0; + private int m_count = 0; + + private bool m_Closed = false; + private bool m_FinalZero = false; //after the stream is closed, set to true after returning a 0 for read() + public override void Close() { + m_Closed = true; + + // release any waiting writes + _Buffers.CompleteAdding(); + } + + public bool DataAvailable { + get { + return _Buffers.Count > 0; + } + } + + private long _Length = 0L; + public override long Length { + get { + return _Length; + } + } + + private long _Position = 0L; + public override long Position { + get { + return _Position; + } + set { + throw new NotImplementedException(); + } + } + + public EchoStream() : this(10) { + } + + public EchoStream(int maxQueueDepth) { + _maxQueueDepth = maxQueueDepth; + _Buffers = new BlockingCollection(_maxQueueDepth); + } + + // we override the xxxxAsync functions because the default base class shares state between ReadAsync and WriteAsync, which causes a hang if both are called at once + public new Task WriteAsync(byte[] buffer, int offset, int count) { + return Task.Run(() => Write(buffer, offset, count)); + } + + // we override the xxxxAsync functions because the default base class shares state between ReadAsync and WriteAsync, which causes a hang if both are called at once + public new Task ReadAsync(byte[] buffer, int offset, int count) { + return Task.Run(() => { + return Read(buffer, offset, count); + }); + } + + public override void Write(byte[] buffer, int offset, int count) { + if (m_Closed || buffer.Length - offset < count || count <= 0) + return; + + byte[] newBuffer; + if (!CopyBufferOnWrite && offset == 0 && count == buffer.Length) + newBuffer = buffer; + else { + newBuffer = new byte[count]; + System.Buffer.BlockCopy(buffer, offset, newBuffer, 0, count); + } + if (!_Buffers.TryAdd(newBuffer, WriteTimeout)) + throw new TimeoutException("EchoStream Write() Timeout"); + + _Length += count; + } + + public override int Read(byte[] buffer, int offset, int count) { + if (count == 0) + return 0; + lock (_lock) { + if (m_count == 0 && _Buffers.Count == 0) { + if (m_Closed) { + if (!m_FinalZero) { + m_FinalZero = true; + return 0; + } + else { + return -1; + } + } + + if (_Buffers.TryTake(out m_buffer, ReadTimeout)) { + m_offset = 0; + m_count = m_buffer.Length; + } + else { + if (m_Closed) { + if (!m_FinalZero) { + m_FinalZero = true; + return 0; + } + else { + return -1; + } + } + else { + return 0; + } + } + } + + int returnBytes = 0; + while (count > 0) { + if (m_count == 0) { + if (_Buffers.TryTake(out m_buffer, 0)) { + m_offset = 0; + m_count = m_buffer.Length; + } + else + break; + } + + var bytesToCopy = (count < m_count) ? count : m_count; + System.Buffer.BlockCopy(m_buffer, m_offset, buffer, offset, bytesToCopy); + m_offset += bytesToCopy; + m_count -= bytesToCopy; + offset += bytesToCopy; + count -= bytesToCopy; + + returnBytes += bytesToCopy; + } + + _Position += returnBytes; + + return returnBytes; + } + } + + public override int ReadByte() { + byte[] returnValue = new byte[1]; + return (Read(returnValue, 0, 1) <= 0 ? -1 : (int)returnValue[0]); + } + + public override void Flush() { + } + + public override long Seek(long offset, SeekOrigin origin) { + throw new NotImplementedException(); + } + + public override void SetLength(long value) { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/EchoStream.cs.meta b/EchoStream.cs.meta new file mode 100644 index 0000000..063a4f2 --- /dev/null +++ b/EchoStream.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 422516a56cbf14d46aaa0b1bc09115bf \ No newline at end of file diff --git a/Messages.cs b/Messages.cs index b517f4d..acbecad 100644 --- a/Messages.cs +++ b/Messages.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.IO; using System.Net.Sockets; using System.Threading.Tasks; +using System; namespace Passer.Control { @@ -76,16 +77,25 @@ namespace Passer.Control { #region Client public class ClientMsg : IMessage { + public const byte Id = 0xA0; public const byte length = 2; - public byte clientId; + public byte networkId; + public ClientMsg(byte networkId) { + this.networkId = networkId; + } public ClientMsg(byte[] data) : base(data) { } + public override void Deserialize(byte[] data) { base.Deserialize(data); uint ix = 0; - clientId = data[ix++]; + networkId = data[ix]; } + public static bool Send(Client client, byte networkId) { + ClientMsg msg = new(networkId); + return SendMsg(client, msg); + } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) return false; @@ -95,12 +105,12 @@ namespace Passer.Control { if (client.networkId == 0) { client.networkId = (byte)(Client.clients.Count); - NetworkIdMsg.Send(client); + NetworkIdMsg.Send(client, client.networkId); //if (string.IsNullOrEmpty(sceneUrl) == false) //SendModelUrl(client, sceneUrl); } - else if (msg.clientId == 0) { - NetworkIdMsg.Send(client); + else if (msg.networkId == 0) { + NetworkIdMsg.Send(client, client.networkId); //if (string.IsNullOrEmpty(sceneUrl) == false) //SendModelUrl(client, sceneUrl); } @@ -116,20 +126,92 @@ namespace Passer.Control { public class NetworkIdMsg : IMessage { public const byte Id = 0xA1; public const byte length = 2; + public byte networkId; - public static bool Send(Client client) { - byte[] data = new byte[NetworkIdMsg.length]; - data[0] = NetworkIdMsg.Id; - data[1] = client.networkId; - return SendMsg(client, data); + NetworkIdMsg(byte networkId) { + this.networkId = networkId; + } + NetworkIdMsg(byte[] data) : base(data) { } + + public override byte[] Serialize() { + byte[] data = new byte[NetworkIdMsg.length]; + data[0] = NetworkIdMsg.Id; + data[1] = this.networkId; + return data; + } + public override void Deserialize(byte[] data) { + uint ix = 0; + this.networkId = data[ix]; + } + + public static bool Send(Client client, byte networkId) { + NetworkIdMsg msg = new(networkId); + return SendMsg(client, msg); + //byte[] data = new byte[NetworkIdMsg.length]; + //data[0] = NetworkIdMsg.Id; + //data[1] = client.networkId; + //return SendMsg(client, data); } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; + + byte[] buffer = await Receive(dataStream, packetSize); + NetworkIdMsg msg = new(buffer); + client.messageQueue.Enqueue(msg); + return true; + } } - #endregion Network Id + #endregion Network Id - #region Thing + #region Investigate - public class ThingMsg : IMessage { + class InvestigateMsg : IMessage { + public const byte Id = 0x81; + public const byte length = 3; + public byte networkId; + public byte thingId; + + public InvestigateMsg(byte networkId, byte thingId) { + this.networkId = networkId; + this.thingId = thingId; + } + public InvestigateMsg(byte[] data) : base(data) { } + + public override byte[] Serialize() { + byte[] buffer = new byte[InvestigateMsg.length]; + buffer[0] = InvestigateMsg.Id; + buffer[1] = this.networkId; + buffer[2] = this.thingId; + return buffer; + } + public override void Deserialize(byte[] data) { + uint ix = 0; + this.networkId = data[ix++]; + this.thingId = data[ix++]; + } + + public static bool Send(Client client, byte thingId) { + InvestigateMsg msg = new(client.networkId, thingId); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; + + byte[] buffer = await Receive(dataStream, packetSize); + InvestigateMsg msg = new(buffer); + client.messageQueue.Enqueue(msg); + return true; + + } + } + + #endregion Investigate + #region Thing + + public class ThingMsg : IMessage { public const byte length = 4; public const byte Id = 0x80; public byte objectId; @@ -144,13 +226,13 @@ namespace Passer.Control { parentId = data[ix]; } - public static bool Send(Client client, byte networkId, byte thingId, byte thingType) { + public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { byte[] data = new byte[4]; data[0] = ThingMsg.Id; - data[1] = networkId; + data[1] = client.networkId; data[2] = thingId; data[3] = thingType; - data[4] = 0x00; // parent not supported yet + data[4] = parentId; return SendMsg(client, data); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -170,19 +252,39 @@ namespace Passer.Control { #region Name public class NameMsg : IMessage { + public const byte Id = 0x91; // 145 + public const byte length = 3; public byte networkId = 0; - public byte objectId; + public byte thingId; public byte len; public string name; + public NameMsg(byte thingId, string name) { + this.thingId = thingId; + this.name = name; + } public NameMsg(byte[] data) : base(data) { } - public override void Deserialize(byte[] data) { + + public override byte[] Serialize() { + byte[] data = new byte[length + this.name.Length]; + data[0] = NameMsg.Id; + data[1] = this.thingId; + data[2] = (byte)this.name.Length; + for (int ix = 0; ix < this.name.Length; ix++) + data[3 + ix] = (byte)this.name[ix]; + return data; + } + public override void Deserialize(byte[] data) { uint ix = 0; - this.objectId = data[ix++]; + this.thingId = data[ix++]; int strlen = data[ix++]; this.name = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); } + public static bool Send(Client client, byte thingId, string name) { + NameMsg msg = new NameMsg(thingId, name); + return SendMsg(client, msg); + } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { byte[] buffer = await Receive(dataStream, packetSize); NameMsg msg = new(buffer); @@ -198,12 +300,13 @@ namespace Passer.Control { public class ModelUrlMsg : IMessage { public const byte Id = 0x90; // (144) Model URL - public byte objectId; + public byte thingId; public Spherical position; public float scale; public string url; - public ModelUrlMsg(string url, float scale = 1) { + public ModelUrlMsg(byte thingId, string url, float scale = 1) { + this.thingId = thingId; this.url = url; this.scale = scale; this.position = Spherical.zero; @@ -213,7 +316,7 @@ namespace Passer.Control { public override byte[] Serialize() { byte[] data = new byte[this.url.Length + 9]; data[0] = ModelUrlMsg.Id; - data[1] = 0x00; // Thing Id + data[1] = this.thingId; // Thing Id // data[2]..[5] == position 0, 0, 0 data[6] = 0x3C; // Dummy float16 value 1 data[7] = 0x00; @@ -225,15 +328,15 @@ namespace Passer.Control { } public override void Deserialize(byte[] data) { uint ix = 0; - this.objectId = data[ix++]; + this.thingId = data[ix++]; this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); this.scale = LowLevelMessages.ReceiveFloat16(data, ref ix); int strlen = data[ix++]; url = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); } - public static bool Send(Client client, string modelUrl) { - ModelUrlMsg msg = new(modelUrl); + public static bool Send(Client client, byte thingId, string modelUrl) { + ModelUrlMsg msg = new(thingId, modelUrl); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -249,14 +352,28 @@ namespace Passer.Control { #region Pose public class PoseMsg : IMessage { + public const byte Id = 0x10; public const byte length = 3 + 4 + 4; public byte thingId; + public byte poseType; + public const byte Pose_Position = 0x01; + public const byte Pose_Orientation = 0x02; public Spherical position; public Quat32 orientation; - public PoseMsg(byte[] data) : base(data) { } + public PoseMsg(byte thingId, Spherical position, Quat32 orientation) { + this.thingId = thingId; + this.position = position; + this.orientation = orientation; + this.poseType = 0; + if (this.position != null) + this.poseType |= Pose_Position; + if (this.orientation != null) + this.poseType |= Pose_Orientation; + } + public PoseMsg(byte[] data) : base(data) { } public override void Deserialize(byte[] data) { uint ix = 0; @@ -269,6 +386,10 @@ namespace Passer.Control { orientation = LowLevelMessages.ReceiveQuat32(data, ref ix); } + public static bool Send(Client client, byte thingId, Spherical position, Quat32 orientation) { + PoseMsg msg = new(thingId, position, orientation); + return SendMsg(client, msg); + } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) return false; @@ -278,7 +399,6 @@ namespace Passer.Control { client.messageQueue.Enqueue(msg); return true; - } } @@ -339,6 +459,7 @@ namespace Passer.Control { #region Destroy public class DestroyMsg : IMessage { + public const byte Id = 0x20; public const byte length = 2; public byte objectId; diff --git a/SiteServer.cs b/SiteServer.cs new file mode 100644 index 0000000..cd01666 --- /dev/null +++ b/SiteServer.cs @@ -0,0 +1,85 @@ + +using System.IO; +using System.Threading.Tasks; + +namespace Passer.Control { + + public static class SiteServer { + public static async Task ReceiveData(Stream dataStream, Client client) { + while (true) { + byte packetSize = (byte)dataStream.ReadByte(); + if (packetSize == 0xFF) + //Debug.Log("Receive timeout"); + // Timeout + ; + else + await ReceiveData(dataStream, client, packetSize); + } + } + + public static async Task ReceiveData(Stream dataStream, Client client, byte packetSize) { + byte msgId = (byte)dataStream.ReadByte(); + if (msgId == 0xFF) { + // Timeout + return; + } + + bool result = false; + switch (msgId) { + case PoseMsg.Id: // Object Pose (16) + result = await PoseMsg.Receive(dataStream, client, packetSize); + break; + case DestroyMsg.Id: // Destroy object (32) + result = await DestroyMsg.Receive(dataStream, client, packetSize); + break; + case ThingMsg.Id: + result = await ThingMsg.Receive(dataStream, client, packetSize); + break; + case InvestigateMsg.Id: + result = await InvestigateMsg.Receive(dataStream, client, packetSize); + break; + case ModelUrlMsg.Id: // Model URL (144) + result = await BytesMsg.Receive(dataStream, client, packetSize); + break; + case NameMsg.Id: // Object Name (145) + result = await NameMsg.Receive(dataStream, client, packetSize); + break; + case ClientMsg.Id: + result = await ClientMsg.Receive(dataStream, client, packetSize); + break; + case NetworkIdMsg.Id: + result = await NetworkIdMsg.Receive(dataStream, client, packetSize); + break; + //case TextMsg.Id: // Text (176) + // result = await TextMsg.Receive(dataStream, client, packetSize); + // break; + case BytesMsg.Id: + result = await BytesMsg.Receive(dataStream, client, packetSize); + break; + default: + break; + } + if (result == false) { + packetSize = msgId; // skip 1 byte, msgId is possibly a packet size byte + await ReceiveData(dataStream, client, packetSize); + } + } + + public static void ProcessMessage(ISiteServer site, Client client, IMessage msg) { + switch (msg) { + case NetworkIdMsg networkId: + site.ProcessNetworkId(client, networkId); + break; + case ModelUrlMsg modelUrl: + site.ProcessModelUrl(client, modelUrl); + break; + } + } + } + + public interface ISiteServer { + + public void ProcessNetworkId(Client client, NetworkIdMsg networkId); + public void ProcessModelUrl(Client client, ModelUrlMsg modelUrl); + } +} \ No newline at end of file diff --git a/SiteServer.cs.meta b/SiteServer.cs.meta new file mode 100644 index 0000000..02fd171 --- /dev/null +++ b/SiteServer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 53345abb9310d344baa67c19a8d8249f \ No newline at end of file From a48ae12fc2f6d4a99119c128e78bf4b103e607c3 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 6 Dec 2024 16:30:24 +0100 Subject: [PATCH 02/14] ControlCore mostly works (but I don't see a model on the site server yet) --- LowLevelMessages.cs | 41 +++++++++++++++++++++++++++++++++++++++-- Messages.cs | 45 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/LowLevelMessages.cs b/LowLevelMessages.cs index a976ddf..f279dbc 100644 --- a/LowLevelMessages.cs +++ b/LowLevelMessages.cs @@ -1,6 +1,13 @@ using Passer; public class LowLevelMessages { + + public static void SendSpherical(byte[] buffer, ref uint ix, Spherical v) { + SendFloat16(buffer, ref ix, new float16(v.distance)); + SendAngle8(buffer, ref ix, v.horizontal); + SendAngle8(buffer, ref ix, v.vertical); + } + public static Spherical ReceiveSpherical(byte[] data, ref uint ix) { float horizontal = ReceiveAngle8(data, ref ix); float vertical = ReceiveAngle8(data, ref ix); @@ -9,6 +16,23 @@ public class LowLevelMessages { return v; } + public static void SendQuat32(byte[] buffer, ref uint ix, Quat32 q) { + int qx = (int)(q.x * 127 + 128); + int qy = (int)(q.y * 127 + 128); + int qz = (int)(q.z * 127 + 128); + int qw = (int)(q.w * 255); + if (q.w < 0) { + qx = -qx; + qy = -qy; + qz = -qz; + qw = -qw; + } + + buffer[ix++] = (byte)qx; + buffer[ix++] = (byte)qy; + buffer[ix++] = (byte)qz; + buffer[ix++] = (byte)qw; + } public static Quat32 ReceiveQuat32(byte[] data, ref uint ix) { Quat32 q = new( (data[ix++] - 128.0F) / 127.0F, @@ -18,11 +42,26 @@ public class LowLevelMessages { return q; } + public static void SendAngle8(byte[] buffer, ref uint ix, float angle) { + // Normalize angle + while (angle >= 180) + angle -= 360; + while (angle < -180) + angle += 360; + buffer[ix++] = (byte)((angle / 360.0f) * 256.0f); + } + public static float ReceiveAngle8(byte[] data, ref uint ix) { float value = (data[ix++] * 180) / 128.0F; return value; } + public static void SendFloat16(byte[] data, ref uint ix, float16 f) { + ushort binary = f.GetBinary(); + data[ix++] = (byte)(binary >> 8); + data[ix++] = (byte)(binary & 255); + } + public static float ReceiveFloat16(byte[] data, ref uint ix) { ushort value = (ushort)(data[ix++] << 8 | data[ix++]); float16 f16 = new(); @@ -30,6 +69,4 @@ public class LowLevelMessages { float f = f16.toFloat(); return f; } - - } diff --git a/Messages.cs b/Messages.cs index acbecad..b9c7e2b 100644 --- a/Messages.cs +++ b/Messages.cs @@ -62,6 +62,18 @@ namespace Passer.Control { client.udpClient.Send(data, data.Length, client.ipAddress, client.port); return true; } + + public static bool PublishMsg(Client client, IMessage msg) { + return PublishMsg(client, msg.Serialize()); + } + public static bool PublishMsg(Client client, byte[] data) { + if (client == null) + return false; + + client.udpClient.Send(data, data.Length, "127.0.0.1", client.port); + return true; + } + public static async Task Receive(Stream dataStream, byte packetSize) { byte[] buffer = new byte[packetSize - 1]; // without msgId int byteCount = dataStream.Read(buffer, 0, packetSize - 1); @@ -86,7 +98,13 @@ namespace Passer.Control { } public ClientMsg(byte[] data) : base(data) { } - public override void Deserialize(byte[] data) { + public override byte[] Serialize() { + byte[] buffer = new byte[ClientMsg.length]; + buffer[0] = ClientMsg.Id; + buffer[1] = networkId; + return buffer; + } + public override void Deserialize(byte[] data) { base.Deserialize(data); uint ix = 0; networkId = data[ix]; @@ -96,6 +114,10 @@ namespace Passer.Control { ClientMsg msg = new(networkId); return SendMsg(client, msg); } + public static bool Publish(Client client, byte networkId) { + ClientMsg msg = new(networkId); + return PublishMsg(client, msg); + } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) return false; @@ -212,7 +234,7 @@ namespace Passer.Control { #region Thing public class ThingMsg : IMessage { - public const byte length = 4; + public const byte length = 5; public const byte Id = 0x80; public byte objectId; public byte objectType; @@ -227,7 +249,7 @@ namespace Passer.Control { } public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - byte[] data = new byte[4]; + byte[] data = new byte[ThingMsg.length]; data[0] = ThingMsg.Id; data[1] = client.networkId; data[2] = thingId; @@ -370,12 +392,27 @@ namespace Passer.Control { this.poseType = 0; if (this.position != null) this.poseType |= Pose_Position; + else + this.position = new Spherical(0, 0, 0); if (this.orientation != null) this.poseType |= Pose_Orientation; + else + this.orientation = new Quat32(0, 0, 0, 1); } public PoseMsg(byte[] data) : base(data) { } - public override void Deserialize(byte[] data) { + public override byte[] Serialize() { + byte[] buffer = new byte[PoseMsg.length]; + uint ix = 0; + buffer[ix++] = PoseMsg.Id; + buffer[ix++] = this.thingId; + buffer[ix++] = this.poseType; + + LowLevelMessages.SendSpherical(buffer, ref ix, position); + LowLevelMessages.SendQuat32(buffer, ref ix, orientation); + return buffer; + } + public override void Deserialize(byte[] data) { uint ix = 0; thingId = data[ix++]; poseType = data[ix++]; From f35d60369daf41a4fcd987ef8b31bd384b9536ba Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 6 Dec 2024 17:38:17 +0100 Subject: [PATCH 03/14] Further improvements --- LowLevelMessages.cs | 2 +- Messages.cs | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/LowLevelMessages.cs b/LowLevelMessages.cs index f279dbc..43f3eeb 100644 --- a/LowLevelMessages.cs +++ b/LowLevelMessages.cs @@ -3,9 +3,9 @@ using Passer; public class LowLevelMessages { public static void SendSpherical(byte[] buffer, ref uint ix, Spherical v) { - SendFloat16(buffer, ref ix, new float16(v.distance)); SendAngle8(buffer, ref ix, v.horizontal); SendAngle8(buffer, ref ix, v.vertical); + SendFloat16(buffer, ref ix, new float16(v.distance)); } public static Spherical ReceiveSpherical(byte[] data, ref uint ix) { diff --git a/Messages.cs b/Messages.cs index b9c7e2b..f23e497 100644 --- a/Messages.cs +++ b/Messages.cs @@ -231,6 +231,7 @@ namespace Passer.Control { } #endregion Investigate + #region Thing public class ThingMsg : IMessage { @@ -288,13 +289,13 @@ namespace Passer.Control { public NameMsg(byte[] data) : base(data) { } public override byte[] Serialize() { - byte[] data = new byte[length + this.name.Length]; - data[0] = NameMsg.Id; - data[1] = this.thingId; - data[2] = (byte)this.name.Length; + byte[] buffer = new byte[length + this.name.Length]; + buffer[0] = NameMsg.Id; + buffer[1] = this.thingId; + buffer[2] = (byte)this.name.Length; for (int ix = 0; ix < this.name.Length; ix++) - data[3 + ix] = (byte)this.name[ix]; - return data; + buffer[3 + ix] = (byte)this.name[ix]; + return buffer; } public override void Deserialize(byte[] data) { uint ix = 0; @@ -304,7 +305,7 @@ namespace Passer.Control { } public static bool Send(Client client, byte thingId, string name) { - NameMsg msg = new NameMsg(thingId, name); + NameMsg msg = new(thingId, name); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { From 355dd5c1c519cf07cfb6b9f9200f7f7311e68f20 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 6 Dec 2024 17:48:55 +0100 Subject: [PATCH 04/14] Fixed ThingMsg format --- Messages.cs | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Messages.cs b/Messages.cs index f23e497..56518cd 100644 --- a/Messages.cs +++ b/Messages.cs @@ -237,26 +237,39 @@ namespace Passer.Control { public class ThingMsg : IMessage { public const byte length = 5; public const byte Id = 0x80; - public byte objectId; - public byte objectType; + public byte networkId; + public byte thingId; + public byte thingType; public byte parentId; + public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { + this.networkId = networkId; + this.thingId = thingId; + this.thingType = thingType; + this.parentId = parentId; + } public ThingMsg(byte[] data) : base(data) { } - public override void Deserialize(byte[] data) { + + public override byte[] Serialize() { + byte[] data = new byte[ThingMsg.length]; + data[0] = ThingMsg.Id; + data[1] = this.networkId; + data[2] = this.thingId; + data[3] = this.thingType; + data[4] = this.parentId; + return data; + } + public override void Deserialize(byte[] data) { uint ix = 0; - objectId = data[ix++]; - objectType = data[ix++]; - parentId = data[ix]; + this.networkId = data[ix++]; + this.thingId = data[ix++]; + this.thingType = data[ix++]; + this.parentId = data[ix]; } public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - byte[] data = new byte[ThingMsg.length]; - data[0] = ThingMsg.Id; - data[1] = client.networkId; - data[2] = thingId; - data[3] = thingType; - data[4] = parentId; - return SendMsg(client, data); + ThingMsg msg = new(client.networkId, thingId, thingType, parentId); + return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) From fbeed8e80922152c3404fbd5d2b243ae95792ec1 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 10:02:19 +0100 Subject: [PATCH 05/14] Used Client override for processing messages --- Client.cs | 97 +++++++ Client.cs.meta | 2 + Messages.cs | 772 ++++++++++++++++++++++++------------------------- SiteServer.cs | 111 ++++--- 4 files changed, 548 insertions(+), 434 deletions(-) create mode 100644 Client.cs create mode 100644 Client.cs.meta diff --git a/Client.cs b/Client.cs new file mode 100644 index 0000000..e579316 --- /dev/null +++ b/Client.cs @@ -0,0 +1,97 @@ +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Net.Sockets; + +namespace Passer.Control { + + public class Client { + //public ConnectionMethod connection; + public UdpClient udpClient; + public string ipAddress; + public int port; + + public byte networkId; + + public readonly ConcurrentQueue messageQueue = new(); + + public static Client GetClient(string ipAddress, int port) { + foreach (Client c in clients) { + if (c.ipAddress == ipAddress && c.port == port) + return c; + } + return null; + } + static public List clients = new List(); + + public static Client NewClient() { + Client client = new(); + clients.Add(client); + client.networkId = 0; + + return client; + } + + public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { + Client client = NewClient(); + client.ipAddress = null; + client.port = port; + client.udpClient = udpClient; + return client; + } + + public void ProcessMessage(IMessage msg) { + switch (msg) { + case ClientMsg clientMsg: + ProcessClient(clientMsg); + break; + case NetworkIdMsg networkId: + ProcessNetworkId(networkId); + break; + case InvestigateMsg investigate: + ProcessInvestigate(investigate); + break; + case ThingMsg thing: + ProcessThing(thing); + break; + case NameMsg name: + ProcessName(name); + break; + case ModelUrlMsg modelUrl: + ProcessModelUrl(modelUrl); + break; + case PoseMsg pose: + ProcessPose(pose); + break; + case CustomMsg custom: + ProcessCustom(custom); + break; + case TextMsg text: + ProcessText(text); + break; + case DestroyMsg destroy: + ProcessDestroy(destroy); + break; + } + } + + protected virtual void ProcessClient(ClientMsg client) { } + + protected virtual void ProcessNetworkId(NetworkIdMsg networkId) { } + + protected virtual void ProcessInvestigate(InvestigateMsg investigate) { } + + protected virtual void ProcessThing(ThingMsg thing) { } + + protected virtual void ProcessName(NameMsg name) { } + + protected virtual void ProcessModelUrl(ModelUrlMsg modelUrl) { } + + protected virtual void ProcessPose(PoseMsg pose) { } + + protected virtual void ProcessCustom(CustomMsg custom) { } + + protected virtual void ProcessText(TextMsg text) { } + + protected virtual void ProcessDestroy(DestroyMsg destroy) { } + } +} \ No newline at end of file diff --git a/Client.cs.meta b/Client.cs.meta new file mode 100644 index 0000000..c346934 --- /dev/null +++ b/Client.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: db9cd79cff119a9438110ead000031c3 \ No newline at end of file diff --git a/Messages.cs b/Messages.cs index 56518cd..e79554e 100644 --- a/Messages.cs +++ b/Messages.cs @@ -1,212 +1,172 @@ -using System.Collections.Generic; -using System.Collections.Concurrent; using System.IO; -using System.Net.Sockets; using System.Threading.Tasks; -using System; namespace Passer.Control { - public class Client { - //public ConnectionMethod connection; - public UdpClient udpClient; - public string ipAddress; - public int port; + public class IMessage { + public IMessage() { } + public IMessage(byte[] data) { + Deserialize(data); + } - public byte networkId; + public virtual byte[] Serialize() { return null; } + public virtual void Deserialize(byte[] data) { } - public readonly ConcurrentQueue messageQueue = new(); + public static bool SendMsg(Client client, IMessage msg) { + return SendMsg(client, msg.Serialize()); + } + public static bool SendMsg(Client client, byte[] data) { + if (client == null || client.ipAddress == null) + return false; - public static Client GetClient(string ipAddress, int port) { - foreach (Client c in clients) { - if (c.ipAddress == ipAddress && c.port == port) - return c; - } - return null; - } - static public List clients = new List(); - - public static Client NewClient() { - Client client = new(); - clients.Add(client); - client.networkId = 0; - - return client; - } - - public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { - Client client = NewClient(); - client.ipAddress = null; - client.port = port; - client.udpClient = udpClient; - return client; - } - } - - public class IMessage { - public IMessage() { } - public IMessage(byte[] data) { - Deserialize(data); - } - - public virtual byte[] Serialize() { return null; } - public virtual void Deserialize(byte[] data) { } - - public static bool SendMsg(Client client, IMessage msg) { - return SendMsg(client, msg.Serialize()); - } - public static bool SendMsg(Client client, byte[] data) { - if (client == null || client.ipAddress == null) - return false; - - client.udpClient.Send(data, data.Length, client.ipAddress, client.port); - return true; - } + client.udpClient.Send(data, data.Length, client.ipAddress, client.port); + return true; + } public static bool PublishMsg(Client client, IMessage msg) { return PublishMsg(client, msg.Serialize()); } public static bool PublishMsg(Client client, byte[] data) { - if (client == null) - return false; + if (client == null) + return false; client.udpClient.Send(data, data.Length, "127.0.0.1", client.port); - return true; + return true; } - public static async Task Receive(Stream dataStream, byte packetSize) { - byte[] buffer = new byte[packetSize - 1]; // without msgId - int byteCount = dataStream.Read(buffer, 0, packetSize - 1); - while (byteCount < packetSize - 1) { - // not all bytes have been read, wait and try again - await Task.Delay(1); - byteCount += dataStream.Read(buffer, byteCount, packetSize - 1 - byteCount); - } - return buffer; - } - } - - #region Client - - public class ClientMsg : IMessage { - public const byte Id = 0xA0; - public const byte length = 2; - public byte networkId; - - public ClientMsg(byte networkId) { - this.networkId = networkId; - } - public ClientMsg(byte[] data) : base(data) { } - - public override byte[] Serialize() { - byte[] buffer = new byte[ClientMsg.length]; - buffer[0] = ClientMsg.Id; - buffer[1] = networkId; - return buffer; + public static async Task Receive(Stream dataStream, byte packetSize) { + byte[] buffer = new byte[packetSize - 1]; // without msgId + int byteCount = dataStream.Read(buffer, 0, packetSize - 1); + while (byteCount < packetSize - 1) { + // not all bytes have been read, wait and try again + await Task.Delay(1); + byteCount += dataStream.Read(buffer, byteCount, packetSize - 1 - byteCount); + } + return buffer; } - public override void Deserialize(byte[] data) { - base.Deserialize(data); - uint ix = 0; - networkId = data[ix]; - } + } - public static bool Send(Client client, byte networkId) { - ClientMsg msg = new(networkId); - return SendMsg(client, msg); - } - public static bool Publish(Client client, byte networkId) { - ClientMsg msg = new(networkId); - return PublishMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - if (packetSize != length) - return false; + #region Client - byte[] buffer = await Receive(dataStream, packetSize); - ClientMsg msg = new(buffer); + public class ClientMsg : IMessage { + public const byte Id = 0xA0; + public const byte length = 2; + public byte networkId; - if (client.networkId == 0) { - client.networkId = (byte)(Client.clients.Count); - NetworkIdMsg.Send(client, client.networkId); - //if (string.IsNullOrEmpty(sceneUrl) == false) - //SendModelUrl(client, sceneUrl); - } - else if (msg.networkId == 0) { - NetworkIdMsg.Send(client, client.networkId); - //if (string.IsNullOrEmpty(sceneUrl) == false) - //SendModelUrl(client, sceneUrl); - } - - return true; - } - } - - #endregion Client - - #region Network Id - - public class NetworkIdMsg : IMessage { - public const byte Id = 0xA1; - public const byte length = 2; - public byte networkId; - - NetworkIdMsg(byte networkId) { + public ClientMsg(byte networkId) { this.networkId = networkId; } - NetworkIdMsg(byte[] data) : base(data) { } + public ClientMsg(byte[] data) : base(data) { } + + public override byte[] Serialize() { + byte[] buffer = new byte[ClientMsg.length]; + buffer[0] = ClientMsg.Id; + buffer[1] = networkId; + return buffer; + } + public override void Deserialize(byte[] data) { + base.Deserialize(data); + uint ix = 0; + networkId = data[ix]; + } + + public static bool Send(Client client, byte networkId) { + ClientMsg msg = new(networkId); + return SendMsg(client, msg); + } + public static bool Publish(Client client, byte networkId) { + ClientMsg msg = new(networkId); + return PublishMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; + + byte[] buffer = await Receive(dataStream, packetSize); + ClientMsg msg = new(buffer); + + if (client.networkId == 0) { + client.networkId = (byte)(Client.clients.Count); + NetworkIdMsg.Send(client, client.networkId); + //if (string.IsNullOrEmpty(sceneUrl) == false) + //SendModelUrl(client, sceneUrl); + } + else if (msg.networkId == 0) { + NetworkIdMsg.Send(client, client.networkId); + //if (string.IsNullOrEmpty(sceneUrl) == false) + //SendModelUrl(client, sceneUrl); + } + + return true; + } + } + + #endregion Client + + #region Network Id + + public class NetworkIdMsg : IMessage { + public const byte Id = 0xA1; + public const byte length = 2; + public byte networkId; + + NetworkIdMsg(byte networkId) { + this.networkId = networkId; + } + NetworkIdMsg(byte[] data) : base(data) { } public override byte[] Serialize() { byte[] data = new byte[NetworkIdMsg.length]; data[0] = NetworkIdMsg.Id; data[1] = this.networkId; - return data; + return data; } - public override void Deserialize(byte[] data) { - uint ix = 0; - this.networkId = data[ix]; + public override void Deserialize(byte[] data) { + uint ix = 0; + this.networkId = data[ix]; } public static bool Send(Client client, byte networkId) { - NetworkIdMsg msg = new(networkId); - return SendMsg(client, msg); - //byte[] data = new byte[NetworkIdMsg.length]; - //data[0] = NetworkIdMsg.Id; - //data[1] = client.networkId; - //return SendMsg(client, data); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + NetworkIdMsg msg = new(networkId); + return SendMsg(client, msg); + //byte[] data = new byte[NetworkIdMsg.length]; + //data[0] = NetworkIdMsg.Id; + //data[1] = client.networkId; + //return SendMsg(client, data); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) return false; byte[] buffer = await Receive(dataStream, packetSize); NetworkIdMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; + client.messageQueue.Enqueue(msg); + return true; } - } + } #endregion Network Id #region Investigate - class InvestigateMsg : IMessage { + public class InvestigateMsg : IMessage { public const byte Id = 0x81; public const byte length = 3; public byte networkId; public byte thingId; - public InvestigateMsg(byte networkId, byte thingId) { - this.networkId = networkId; - this.thingId = thingId; - } + public InvestigateMsg(byte networkId, byte thingId) { + this.networkId = networkId; + this.thingId = thingId; + } public InvestigateMsg(byte[] data) : base(data) { } public override byte[] Serialize() { - byte[] buffer = new byte[InvestigateMsg.length]; - buffer[0] = InvestigateMsg.Id; - buffer[1] = this.networkId; - buffer[2] = this.thingId; - return buffer; + byte[] buffer = new byte[InvestigateMsg.length]; + buffer[0] = InvestigateMsg.Id; + buffer[1] = this.networkId; + buffer[2] = this.thingId; + return buffer; } public override void Deserialize(byte[] data) { uint ix = 0; @@ -214,11 +174,11 @@ namespace Passer.Control { this.thingId = data[ix++]; } - public static bool Send(Client client, byte thingId) { - InvestigateMsg msg = new(client.networkId, thingId); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + public static bool Send(Client client, byte thingId) { + InvestigateMsg msg = new(client.networkId, thingId); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) return false; @@ -235,20 +195,20 @@ namespace Passer.Control { #region Thing public class ThingMsg : IMessage { - public const byte length = 5; - public const byte Id = 0x80; - public byte networkId; - public byte thingId; - public byte thingType; - public byte parentId; + public const byte length = 5; + public const byte Id = 0x80; + public byte networkId; + public byte thingId; + public byte thingType; + public byte parentId; - public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { - this.networkId = networkId; - this.thingId = thingId; - this.thingType = thingType; - this.parentId = parentId; - } - public ThingMsg(byte[] data) : base(data) { } + public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { + this.networkId = networkId; + this.thingId = thingId; + this.thingType = thingType; + this.parentId = parentId; + } + public ThingMsg(byte[] data) : base(data) { } public override byte[] Serialize() { byte[] data = new byte[ThingMsg.length]; @@ -257,281 +217,303 @@ namespace Passer.Control { data[2] = this.thingId; data[3] = this.thingType; data[4] = this.parentId; - return data; + return data; } public override void Deserialize(byte[] data) { - uint ix = 0; - this.networkId = data[ix++]; - this.thingId = data[ix++]; - this.thingType = data[ix++]; - this.parentId = data[ix]; - } + uint ix = 0; + this.networkId = data[ix++]; + this.thingId = data[ix++]; + this.thingType = data[ix++]; + this.parentId = data[ix]; + } - public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - ThingMsg msg = new(client.networkId, thingId, thingType, parentId); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - if (packetSize != length) - return false; + public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { + ThingMsg msg = new(client.networkId, thingId, thingType, parentId); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; - byte[] buffer = await Receive(dataStream, packetSize); - ThingMsg msg = new(buffer); + byte[] buffer = await Receive(dataStream, packetSize); + ThingMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - } + client.messageQueue.Enqueue(msg); + return true; + } + } - #endregion Thing + #endregion Thing - #region Name + #region Name - public class NameMsg : IMessage { - public const byte Id = 0x91; // 145 - public const byte length = 3; - public byte networkId = 0; - public byte thingId; - public byte len; - public string name; + public class NameMsg : IMessage { + public const byte Id = 0x91; // 145 + public const byte length = 3; + public byte networkId = 0; + public byte thingId; + public byte len; + public string name; - public NameMsg(byte thingId, string name) { - this.thingId = thingId; - this.name = name; - } - public NameMsg(byte[] data) : base(data) { } + public NameMsg(byte thingId, string name) { + this.thingId = thingId; + this.name = name; + } + public NameMsg(byte[] data) : base(data) { } public override byte[] Serialize() { - byte[] buffer = new byte[length + this.name.Length]; - buffer[0] = NameMsg.Id; - buffer[1] = this.thingId; - buffer[2] = (byte)this.name.Length; - for (int ix = 0; ix < this.name.Length; ix++) - buffer[3 + ix] = (byte)this.name[ix]; - return buffer; + byte[] buffer = new byte[length + this.name.Length]; + buffer[0] = NameMsg.Id; + buffer[1] = this.thingId; + buffer[2] = (byte)this.name.Length; + for (int ix = 0; ix < this.name.Length; ix++) + buffer[3 + ix] = (byte)this.name[ix]; + return buffer; } public override void Deserialize(byte[] data) { - uint ix = 0; - this.thingId = data[ix++]; - int strlen = data[ix++]; - this.name = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); - } + uint ix = 0; + this.thingId = data[ix++]; + int strlen = data[ix++]; + this.name = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); + } - public static bool Send(Client client, byte thingId, string name) { - NameMsg msg = new(thingId, name); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - byte[] buffer = await Receive(dataStream, packetSize); - NameMsg msg = new(buffer); + public static bool Send(Client client, byte thingId, string name) { + NameMsg msg = new(thingId, name); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + byte[] buffer = await Receive(dataStream, packetSize); + NameMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - } + client.messageQueue.Enqueue(msg); + return true; + } + } - #endregion + #endregion - #region Model URL + #region Model URL - public class ModelUrlMsg : IMessage { - public const byte Id = 0x90; // (144) Model URL - public byte thingId; - public Spherical position; - public float scale; - public string url; + public class ModelUrlMsg : IMessage { + public const byte Id = 0x90; // (144) Model URL + public byte thingId; + public Spherical position; + public float scale; + public string url; - public ModelUrlMsg(byte thingId, string url, float scale = 1) { - this.thingId = thingId; - this.url = url; - this.scale = scale; - this.position = Spherical.zero; - } - public ModelUrlMsg(byte[] data) : base(data) { } + public ModelUrlMsg(byte thingId, string url, float scale = 1) { + this.thingId = thingId; + this.url = url; + this.scale = scale; + this.position = Spherical.zero; + } + public ModelUrlMsg(byte[] data) : base(data) { } - public override byte[] Serialize() { - byte[] data = new byte[this.url.Length + 9]; - data[0] = ModelUrlMsg.Id; - data[1] = this.thingId; // Thing Id - // data[2]..[5] == position 0, 0, 0 - data[6] = 0x3C; // Dummy float16 value 1 - data[7] = 0x00; + public override byte[] Serialize() { + byte[] data = new byte[this.url.Length + 9]; + data[0] = ModelUrlMsg.Id; + data[1] = this.thingId; // Thing Id + // data[2]..[5] == position 0, 0, 0 + data[6] = 0x3C; // Dummy float16 value 1 + data[7] = 0x00; - data[8] = (byte)url.Length; - for (int ix = 0; ix < this.url.Length; ix++) - data[9 + ix] = (byte)url[ix]; - return data; - } - public override void Deserialize(byte[] data) { - uint ix = 0; - this.thingId = data[ix++]; - this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); - this.scale = LowLevelMessages.ReceiveFloat16(data, ref ix); - int strlen = data[ix++]; - url = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); - } + data[8] = (byte)url.Length; + for (int ix = 0; ix < this.url.Length; ix++) + data[9 + ix] = (byte)url[ix]; + return data; + } + public override void Deserialize(byte[] data) { + uint ix = 0; + this.thingId = data[ix++]; + this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); + this.scale = LowLevelMessages.ReceiveFloat16(data, ref ix); + int strlen = data[ix++]; + url = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); + } - public static bool Send(Client client, byte thingId, string modelUrl) { - ModelUrlMsg msg = new(thingId, modelUrl); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - byte[] buffer = await Receive(dataStream, packetSize); - ModelUrlMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - } + public static bool Send(Client client, byte thingId, string modelUrl) { + ModelUrlMsg msg = new(thingId, modelUrl); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + byte[] buffer = await Receive(dataStream, packetSize); + ModelUrlMsg msg = new(buffer); + client.messageQueue.Enqueue(msg); + return true; + } + } - #endregion Model URL + #endregion Model URL - #region Pose + #region Pose - public class PoseMsg : IMessage { - public const byte Id = 0x10; - public const byte length = 3 + 4 + 4; - public byte thingId; + public class PoseMsg : IMessage { + public const byte Id = 0x10; + public const byte length = 3 + 4 + 4; + public byte thingId; - public byte poseType; - public const byte Pose_Position = 0x01; - public const byte Pose_Orientation = 0x02; + public byte poseType; + public const byte Pose_Position = 0x01; + public const byte Pose_Orientation = 0x02; - public Spherical position; - public Quat32 orientation; + public Spherical position; + public Quat32 orientation; - public PoseMsg(byte thingId, Spherical position, Quat32 orientation) { - this.thingId = thingId; - this.position = position; - this.orientation = orientation; + public PoseMsg(byte thingId, Spherical position, Quat32 orientation) { + this.thingId = thingId; + this.position = position; + this.orientation = orientation; this.poseType = 0; - if (this.position != null) - this.poseType |= Pose_Position; - else - this.position = new Spherical(0, 0, 0); - if (this.orientation != null) - this.poseType |= Pose_Orientation; - else - this.orientation = new Quat32(0, 0, 0, 1); + if (this.position != null) + this.poseType |= Pose_Position; + else + this.position = new Spherical(0, 0, 0); + if (this.orientation != null) + this.poseType |= Pose_Orientation; + else + this.orientation = new Quat32(0, 0, 0, 1); } public PoseMsg(byte[] data) : base(data) { } public override byte[] Serialize() { - byte[] buffer = new byte[PoseMsg.length]; - uint ix = 0; - buffer[ix++] = PoseMsg.Id; - buffer[ix++] = this.thingId; - buffer[ix++] = this.poseType; + byte[] buffer = new byte[PoseMsg.length]; + uint ix = 0; + buffer[ix++] = PoseMsg.Id; + buffer[ix++] = this.thingId; + buffer[ix++] = this.poseType; - LowLevelMessages.SendSpherical(buffer, ref ix, position); - LowLevelMessages.SendQuat32(buffer, ref ix, orientation); - return buffer; + LowLevelMessages.SendSpherical(buffer, ref ix, position); + LowLevelMessages.SendQuat32(buffer, ref ix, orientation); + return buffer; } public override void Deserialize(byte[] data) { - uint ix = 0; - thingId = data[ix++]; - poseType = data[ix++]; + uint ix = 0; + thingId = data[ix++]; + poseType = data[ix++]; - //if ((poseType & Pose_Position) != 0) - position = LowLevelMessages.ReceiveSpherical(data, ref ix); - //if ((poseType & Pose_Orientation) != 0) { - orientation = LowLevelMessages.ReceiveQuat32(data, ref ix); - } + //if ((poseType & Pose_Position) != 0) + position = LowLevelMessages.ReceiveSpherical(data, ref ix); + //if ((poseType & Pose_Orientation) != 0) { + orientation = LowLevelMessages.ReceiveQuat32(data, ref ix); + } - public static bool Send(Client client, byte thingId, Spherical position, Quat32 orientation) { - PoseMsg msg = new(thingId, position, orientation); - return SendMsg(client, msg); - } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - if (packetSize != length) - return false; + public static bool Send(Client client, byte thingId, Spherical position, Quat32 orientation) { + PoseMsg msg = new(thingId, position, orientation); + return SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; - byte[] buffer = await Receive(dataStream, packetSize); - PoseMsg msg = new(buffer); + byte[] buffer = await Receive(dataStream, packetSize); + PoseMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - } + client.messageQueue.Enqueue(msg); + return true; + } + } - #endregion Pose + #endregion Pose - #region Bytes + #region Custom - public class BytesMsg : IMessage { - public const byte Id = 0xB1; - public byte networkId; - public byte thingId; - public byte[] bytes; + public class CustomMsg : IMessage { + public const byte Id = 0xB1; + public byte networkId; + public byte thingId; + public byte[] bytes; - public BytesMsg(byte[] data) : base(data) { } - public BytesMsg(byte networkId, byte thingId, byte[] bytes) : base() { - this.networkId = networkId; - this.thingId = thingId; - this.bytes = bytes; - } - public override byte[] Serialize() { - byte[] buffer = new byte[4 + this.bytes.Length]; - int ix = 0; - buffer[ix++] = BytesMsg.Id; - buffer[ix++] = this.networkId; - buffer[ix++] = this.thingId; - buffer[ix++] = (byte)bytes.Length; - foreach (byte b in bytes) - buffer[ix++] = b; + public CustomMsg(byte[] data) : base(data) { } + public CustomMsg(byte networkId, byte thingId, byte[] bytes) : base() { + this.networkId = networkId; + this.thingId = thingId; + this.bytes = bytes; + } - return buffer; - } - public override void Deserialize(byte[] data) { - //this.bytes = data; - uint ix = 0; - this.thingId = data[ix++]; - this.bytes = new byte[data.Length - ix]; - for (uint bytesIx = 0; ix < data.Length; ix++, bytesIx++) - this.bytes[bytesIx] = data[ix]; - } + public override byte[] Serialize() { + byte[] buffer = new byte[4 + this.bytes.Length]; + int ix = 0; + buffer[ix++] = CustomMsg.Id; + buffer[ix++] = this.networkId; + buffer[ix++] = this.thingId; + buffer[ix++] = (byte)bytes.Length; + foreach (byte b in bytes) + buffer[ix++] = b; + + return buffer; + } + public override void Deserialize(byte[] data) { + uint ix = 0; + this.thingId = data[ix++]; + this.bytes = new byte[data.Length - ix]; + for (uint bytesIx = 0; ix < data.Length; ix++, bytesIx++) + this.bytes[bytesIx] = data[ix]; + } - public static void Send(Client client, byte thingId, byte[] bytes) { - BytesMsg msg = new(client.networkId, thingId, bytes); - SendMsg(client, msg); - } + public static void Send(Client client, byte thingId, byte[] bytes) { + CustomMsg msg = new(client.networkId, thingId, bytes); + SendMsg(client, msg); + } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + byte[] buffer = await Receive(dataStream, packetSize); + CustomMsg msg = new(buffer); + client.messageQueue.Enqueue(msg); + return true; + } + } - // received bytes - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - byte[] buffer = await Receive(dataStream, packetSize); - BytesMsg msg = new(buffer); - client.messageQueue.Enqueue(msg); - return true; - } - } + #endregion Custom - #endregion Bytes + #region Text - #region Destroy + public class TextMsg : IMessage { + public const byte Id = 0xB0; + public string text; - public class DestroyMsg : IMessage { - public const byte Id = 0x20; - public const byte length = 2; - public byte objectId; + public TextMsg(byte[] data) : base(data) { } + public override void Deserialize(byte[] data) { + uint ix = 0; + uint strlen = data[ix++]; + this.text = System.Text.Encoding.UTF8.GetString(data, (int)ix, (int)strlen); + } - public DestroyMsg(byte[] data) : base(data) { } + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + byte[] buffer = await Receive(dataStream, packetSize); + TextMsg msg = new(buffer); - public override void Deserialize(byte[] data) { - objectId = data[0]; - } + client.messageQueue.Enqueue(msg); + return true; + } + } - public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - if (packetSize != length) - return false; + #endregion - byte[] buffer = await Receive(dataStream, packetSize); - DestroyMsg msg = new(buffer); + #region Destroy - client.messageQueue.Enqueue(msg); - return true; - } - } + public class DestroyMsg : IMessage { + public const byte Id = 0x20; + public const byte length = 2; + public byte objectId; + + public DestroyMsg(byte[] data) : base(data) { } + + public override void Deserialize(byte[] data) { + objectId = data[0]; + } + + public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + if (packetSize != length) + return false; + + byte[] buffer = await Receive(dataStream, packetSize); + DestroyMsg msg = new(buffer); + + client.messageQueue.Enqueue(msg); + return true; + } + } - #endregion Destroy + #endregion Destroy } diff --git a/SiteServer.cs b/SiteServer.cs index cd01666..16b0278 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -26,35 +26,35 @@ namespace Passer.Control { bool result = false; switch (msgId) { - case PoseMsg.Id: // Object Pose (16) - result = await PoseMsg.Receive(dataStream, client, packetSize); - break; - case DestroyMsg.Id: // Destroy object (32) - result = await DestroyMsg.Receive(dataStream, client, packetSize); - break; - case ThingMsg.Id: - result = await ThingMsg.Receive(dataStream, client, packetSize); - break; - case InvestigateMsg.Id: - result = await InvestigateMsg.Receive(dataStream, client, packetSize); - break; - case ModelUrlMsg.Id: // Model URL (144) - result = await BytesMsg.Receive(dataStream, client, packetSize); - break; - case NameMsg.Id: // Object Name (145) - result = await NameMsg.Receive(dataStream, client, packetSize); - break; - case ClientMsg.Id: + case ClientMsg.Id: // 0xA0 / 160 result = await ClientMsg.Receive(dataStream, client, packetSize); break; - case NetworkIdMsg.Id: + case NetworkIdMsg.Id: // 0xA1 / 161 result = await NetworkIdMsg.Receive(dataStream, client, packetSize); break; - //case TextMsg.Id: // Text (176) - // result = await TextMsg.Receive(dataStream, client, packetSize); - // break; - case BytesMsg.Id: - result = await BytesMsg.Receive(dataStream, client, packetSize); + case InvestigateMsg.Id: // 0x81 + result = await InvestigateMsg.Receive(dataStream, client, packetSize); + break; + case ThingMsg.Id: // 0x80 / 128 + result = await ThingMsg.Receive(dataStream, client, packetSize); + break; + case NameMsg.Id: // 0x91 / 145 + result = await NameMsg.Receive(dataStream, client, packetSize); + break; + case ModelUrlMsg.Id: // 0x90 / 144 + result = await ModelUrlMsg.Receive(dataStream, client, packetSize); + break; + case PoseMsg.Id: // 0x10 / 16 + result = await PoseMsg.Receive(dataStream, client, packetSize); + break; + case CustomMsg.Id: // 0xB1 / 177 + result = await CustomMsg.Receive(dataStream, client, packetSize); + break; + case TextMsg.Id: // 0xB0 / 176 + result = await TextMsg.Receive(dataStream, client, packetSize); + break; + case DestroyMsg.Id: // 0x20 / 32 + result = await DestroyMsg.Receive(dataStream, client, packetSize); break; default: break; @@ -65,21 +65,54 @@ namespace Passer.Control { } } - public static void ProcessMessage(ISiteServer site, Client client, IMessage msg) { - switch (msg) { - case NetworkIdMsg networkId: - site.ProcessNetworkId(client, networkId); - break; - case ModelUrlMsg modelUrl: - site.ProcessModelUrl(client, modelUrl); - break; - } - } + //public static void ProcessMessage(ISiteServer site, Client client, IMessage msg) { + // client.ProcessMessage(site, client, msg); + // switch (msg) { + // case ClientMsg clientMsg: + // site.ProcessClient(client, clientMsg); + // break; + // case NetworkIdMsg networkId: + // site.ProcessNetworkId(client, networkId); + // break; + // case InvestigateMsg investigate: + // site.ProcessInvestigate(client, investigate); + // break; + // case ThingMsg thing: + // site.ProcessThing(client, thing); + // break; + // case NameMsg name: + // site.ProcessName(client, name); + // break; + // case ModelUrlMsg modelUrl: + // site.ProcessModelUrl(client, modelUrl); + // break; + // case PoseMsg pose: + // site.ProcessPose(client, pose); + // break; + // case CustomMsg custom: + // site.ProcessCustom(client, custom); + // break; + // case TextMsg text: + // site.ProcessText(client, text); + // break; + // case DestroyMsg destroy: + // site.ProcessDestroy(client, destroy); + // break; + // } + //} } - public interface ISiteServer { + //public interface ISiteServer { - public void ProcessNetworkId(Client client, NetworkIdMsg networkId); - public void ProcessModelUrl(Client client, ModelUrlMsg modelUrl); - } + // public void ProcessClient(Client client, ClientMsg clientMsg); + // public void ProcessNetworkId(Client client, NetworkIdMsg networkId); + // public void ProcessInvestigate(Client client, InvestigateMsg investigate); + // public void ProcessThing(Client client, ThingMsg thing); + // public void ProcessName(Client client, NameMsg name); + // public void ProcessModelUrl(Client client, ModelUrlMsg modelUrl); + // public void ProcessPose(Client client, PoseMsg pose); + // public void ProcessCustom(Client client, CustomMsg custom); + // public void ProcessText(Client client, TextMsg text); + // public void ProcessDestroy(Client client, DestroyMsg destroy); + //} } \ No newline at end of file From aebe4c0f8e805259a5aea4a4cb6b72343d73257a Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 12:06:12 +0100 Subject: [PATCH 06/14] Arduino Ant now works. --- Client.cs | 38 +++++++++++++++++++++------------ Messages.cs | 20 +++++++----------- SiteServer.cs | 58 ++------------------------------------------------- 3 files changed, 35 insertions(+), 81 deletions(-) diff --git a/Client.cs b/Client.cs index e579316..823bcf1 100644 --- a/Client.cs +++ b/Client.cs @@ -10,7 +10,7 @@ namespace Passer.Control { public string ipAddress; public int port; - public byte networkId; + public byte networkId = 0; public readonly ConcurrentQueue messageQueue = new(); @@ -23,20 +23,32 @@ namespace Passer.Control { } static public List clients = new List(); - public static Client NewClient() { - Client client = new(); - clients.Add(client); - client.networkId = 0; + //// These static functions are deprecated + //public static Client NewClient() { + // Client client = new(); + // clients.Add(client); + // client.networkId = 0; - return client; - } + // return client; + //} - public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { - Client client = NewClient(); - client.ipAddress = null; - client.port = port; - client.udpClient = udpClient; - return client; + //public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { + // Client client = NewClient(); + // client.ipAddress = null; + // client.port = port; + // client.udpClient = udpClient; + // return client; + //} + + //public Client() { + + //} + + public Client(UdpClient udpClient, int port) { + this.udpClient = udpClient; + this.ipAddress = null; + this.port = port; + clients.Add(this); } public void ProcessMessage(IMessage msg) { diff --git a/Messages.cs b/Messages.cs index e79554e..bae2a19 100644 --- a/Messages.cs +++ b/Messages.cs @@ -195,15 +195,13 @@ namespace Passer.Control { #region Thing public class ThingMsg : IMessage { - public const byte length = 5; + public const byte length = 4; public const byte Id = 0x80; - public byte networkId; public byte thingId; public byte thingType; public byte parentId; - public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { - this.networkId = networkId; + public ThingMsg(byte thingId, byte thingType, byte parentId) { this.thingId = thingId; this.thingType = thingType; this.parentId = parentId; @@ -212,23 +210,22 @@ namespace Passer.Control { public override byte[] Serialize() { byte[] data = new byte[ThingMsg.length]; - data[0] = ThingMsg.Id; - data[1] = this.networkId; - data[2] = this.thingId; - data[3] = this.thingType; - data[4] = this.parentId; + byte ix = 0; + data[ix++] = ThingMsg.Id; + data[ix++] = this.thingId; + data[ix++] = this.thingType; + data[ix] = this.parentId; return data; } public override void Deserialize(byte[] data) { uint ix = 0; - this.networkId = data[ix++]; this.thingId = data[ix++]; this.thingType = data[ix++]; this.parentId = data[ix]; } public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - ThingMsg msg = new(client.networkId, thingId, thingType, parentId); + ThingMsg msg = new(thingId, thingType, parentId); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -250,7 +247,6 @@ namespace Passer.Control { public class NameMsg : IMessage { public const byte Id = 0x91; // 145 public const byte length = 3; - public byte networkId = 0; public byte thingId; public byte len; public string name; diff --git a/SiteServer.cs b/SiteServer.cs index 16b0278..f198299 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -1,4 +1,3 @@ - using System.IO; using System.Threading.Tasks; @@ -8,12 +7,9 @@ namespace Passer.Control { public static async Task ReceiveData(Stream dataStream, Client client) { while (true) { byte packetSize = (byte)dataStream.ReadByte(); - if (packetSize == 0xFF) - //Debug.Log("Receive timeout"); - // Timeout - ; - else + if (packetSize != 0xFF) await ReceiveData(dataStream, client, packetSize); + // else timeout } } @@ -64,55 +60,5 @@ namespace Passer.Control { await ReceiveData(dataStream, client, packetSize); } } - - //public static void ProcessMessage(ISiteServer site, Client client, IMessage msg) { - // client.ProcessMessage(site, client, msg); - // switch (msg) { - // case ClientMsg clientMsg: - // site.ProcessClient(client, clientMsg); - // break; - // case NetworkIdMsg networkId: - // site.ProcessNetworkId(client, networkId); - // break; - // case InvestigateMsg investigate: - // site.ProcessInvestigate(client, investigate); - // break; - // case ThingMsg thing: - // site.ProcessThing(client, thing); - // break; - // case NameMsg name: - // site.ProcessName(client, name); - // break; - // case ModelUrlMsg modelUrl: - // site.ProcessModelUrl(client, modelUrl); - // break; - // case PoseMsg pose: - // site.ProcessPose(client, pose); - // break; - // case CustomMsg custom: - // site.ProcessCustom(client, custom); - // break; - // case TextMsg text: - // site.ProcessText(client, text); - // break; - // case DestroyMsg destroy: - // site.ProcessDestroy(client, destroy); - // break; - // } - //} } - - //public interface ISiteServer { - - // public void ProcessClient(Client client, ClientMsg clientMsg); - // public void ProcessNetworkId(Client client, NetworkIdMsg networkId); - // public void ProcessInvestigate(Client client, InvestigateMsg investigate); - // public void ProcessThing(Client client, ThingMsg thing); - // public void ProcessName(Client client, NameMsg name); - // public void ProcessModelUrl(Client client, ModelUrlMsg modelUrl); - // public void ProcessPose(Client client, PoseMsg pose); - // public void ProcessCustom(Client client, CustomMsg custom); - // public void ProcessText(Client client, TextMsg text); - // public void ProcessDestroy(Client client, DestroyMsg destroy); - //} } \ No newline at end of file From 2e4e4c4693e123ce6e0e11f3a367f46d3505f3d0 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 14:02:32 +0100 Subject: [PATCH 07/14] Multiclient is working --- Client.cs | 8 ++++++++ SiteServer.cs | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Client.cs b/Client.cs index 823bcf1..190c2b2 100644 --- a/Client.cs +++ b/Client.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Collections.Concurrent; using System.Net.Sockets; +using System.IO; namespace Passer.Control { @@ -9,6 +10,7 @@ namespace Passer.Control { public UdpClient udpClient; public string ipAddress; public int port; + public Stream dataStream; public byte networkId = 0; @@ -48,9 +50,15 @@ namespace Passer.Control { this.udpClient = udpClient; this.ipAddress = null; this.port = port; + this.dataStream = new EchoStream(); clients.Add(this); } + public virtual void ProcessMessages() { + while (this.messageQueue.TryDequeue(out IMessage msg)) + ProcessMessage(msg); + } + public void ProcessMessage(IMessage msg) { switch (msg) { case ClientMsg clientMsg: diff --git a/SiteServer.cs b/SiteServer.cs index f198299..24e42b2 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -1,9 +1,29 @@ +using System.Diagnostics; using System.IO; using System.Threading.Tasks; namespace Passer.Control { public static class SiteServer { + //public static async Task ReceiveData() { + // while (true) { + // //foreach (var client in Client.clients) { + + // for (int ix = 0; ix < Client.clients.Count; ix++) { + // if (ix > 0) + // UnityEngine.Debug.Log("Client2 "); + // Client client = Client.clients[ix]; + // if (client == null) + // continue; + + // byte packetSize = (byte)client.dataStream.ReadByte(); + // if (packetSize != 0xFF) + // await ReceiveData(client.dataStream, client, packetSize); + // // else timeout + // } + // } + //} + public static async Task ReceiveData(Stream dataStream, Client client) { while (true) { byte packetSize = (byte)dataStream.ReadByte(); From e9a29f253c2043f754673139d1e1dd7ae1e18ed8 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 16:59:26 +0100 Subject: [PATCH 08/14] Added networkId to all relevant messages --- Client.cs | 34 +++----- LowLevelMessages.cs | 16 ++-- Messages.cs | 200 +++++++++++++++++++++++--------------------- SiteServer.cs | 19 ----- 4 files changed, 124 insertions(+), 145 deletions(-) diff --git a/Client.cs b/Client.cs index 190c2b2..26ad994 100644 --- a/Client.cs +++ b/Client.cs @@ -25,27 +25,6 @@ namespace Passer.Control { } static public List clients = new List(); - //// These static functions are deprecated - //public static Client NewClient() { - // Client client = new(); - // clients.Add(client); - // client.networkId = 0; - - // return client; - //} - - //public static Client NewUDPClient(UdpClient udpClient, string ipAddress, int port) { - // Client client = NewClient(); - // client.ipAddress = null; - // client.port = port; - // client.udpClient = udpClient; - // return client; - //} - - //public Client() { - - //} - public Client(UdpClient udpClient, int port) { this.udpClient = udpClient; this.ipAddress = null; @@ -56,7 +35,7 @@ namespace Passer.Control { public virtual void ProcessMessages() { while (this.messageQueue.TryDequeue(out IMessage msg)) - ProcessMessage(msg); + ProcessMessage(msg); } public void ProcessMessage(IMessage msg) { @@ -91,7 +70,10 @@ namespace Passer.Control { case DestroyMsg destroy: ProcessDestroy(destroy); break; + default: + return; } + ForwardMessage(msg); } protected virtual void ProcessClient(ClientMsg client) { } @@ -113,5 +95,13 @@ namespace Passer.Control { protected virtual void ProcessText(TextMsg text) { } protected virtual void ProcessDestroy(DestroyMsg destroy) { } + + private void ForwardMessage(IMessage thing) { + foreach (Client client in Client.clients) { + if (client == this) + continue; + IMessage.SendMsg(client, thing); + } + } } } \ No newline at end of file diff --git a/LowLevelMessages.cs b/LowLevelMessages.cs index 43f3eeb..abeef3a 100644 --- a/LowLevelMessages.cs +++ b/LowLevelMessages.cs @@ -2,13 +2,13 @@ using Passer; public class LowLevelMessages { - public static void SendSpherical(byte[] buffer, ref uint ix, Spherical v) { + public static void SendSpherical(byte[] buffer, ref byte ix, Spherical v) { SendAngle8(buffer, ref ix, v.horizontal); SendAngle8(buffer, ref ix, v.vertical); SendFloat16(buffer, ref ix, new float16(v.distance)); } - public static Spherical ReceiveSpherical(byte[] data, ref uint ix) { + public static Spherical ReceiveSpherical(byte[] data, ref byte ix) { float horizontal = ReceiveAngle8(data, ref ix); float vertical = ReceiveAngle8(data, ref ix); float distance = ReceiveFloat16(data, ref ix); @@ -16,7 +16,7 @@ public class LowLevelMessages { return v; } - public static void SendQuat32(byte[] buffer, ref uint ix, Quat32 q) { + public static void SendQuat32(byte[] buffer, ref byte ix, Quat32 q) { int qx = (int)(q.x * 127 + 128); int qy = (int)(q.y * 127 + 128); int qz = (int)(q.z * 127 + 128); @@ -33,7 +33,7 @@ public class LowLevelMessages { buffer[ix++] = (byte)qz; buffer[ix++] = (byte)qw; } - public static Quat32 ReceiveQuat32(byte[] data, ref uint ix) { + public static Quat32 ReceiveQuat32(byte[] data, ref byte ix) { Quat32 q = new( (data[ix++] - 128.0F) / 127.0F, (data[ix++] - 128.0F) / 127.0F, @@ -42,7 +42,7 @@ public class LowLevelMessages { return q; } - public static void SendAngle8(byte[] buffer, ref uint ix, float angle) { + public static void SendAngle8(byte[] buffer, ref byte ix, float angle) { // Normalize angle while (angle >= 180) angle -= 360; @@ -51,18 +51,18 @@ public class LowLevelMessages { buffer[ix++] = (byte)((angle / 360.0f) * 256.0f); } - public static float ReceiveAngle8(byte[] data, ref uint ix) { + public static float ReceiveAngle8(byte[] data, ref byte ix) { float value = (data[ix++] * 180) / 128.0F; return value; } - public static void SendFloat16(byte[] data, ref uint ix, float16 f) { + public static void SendFloat16(byte[] data, ref byte ix, float16 f) { ushort binary = f.GetBinary(); data[ix++] = (byte)(binary >> 8); data[ix++] = (byte)(binary & 255); } - public static float ReceiveFloat16(byte[] data, ref uint ix) { + public static float ReceiveFloat16(byte[] data, ref byte ix) { ushort value = (ushort)(data[ix++] << 8 | data[ix++]); float16 f16 = new(); f16.SetBinary(value); diff --git a/Messages.cs b/Messages.cs index bae2a19..dc85d1a 100644 --- a/Messages.cs +++ b/Messages.cs @@ -5,32 +5,32 @@ namespace Passer.Control { public class IMessage { public IMessage() { } - public IMessage(byte[] data) { - Deserialize(data); + public IMessage(byte[] buffer) { + Deserialize(buffer); } public virtual byte[] Serialize() { return null; } - public virtual void Deserialize(byte[] data) { } + public virtual void Deserialize(byte[] buffer) { } public static bool SendMsg(Client client, IMessage msg) { return SendMsg(client, msg.Serialize()); } - public static bool SendMsg(Client client, byte[] data) { + public static bool SendMsg(Client client, byte[] buffer) { if (client == null || client.ipAddress == null) return false; - client.udpClient.Send(data, data.Length, client.ipAddress, client.port); + client.udpClient.Send(buffer, buffer.Length, client.ipAddress, client.port); return true; } public static bool PublishMsg(Client client, IMessage msg) { return PublishMsg(client, msg.Serialize()); } - public static bool PublishMsg(Client client, byte[] data) { + public static bool PublishMsg(Client client, byte[] buffer) { if (client == null) return false; - client.udpClient.Send(data, data.Length, "127.0.0.1", client.port); + client.udpClient.Send(buffer, buffer.Length, "127.0.0.1", client.port); return true; } @@ -56,7 +56,7 @@ namespace Passer.Control { public ClientMsg(byte networkId) { this.networkId = networkId; } - public ClientMsg(byte[] data) : base(data) { } + public ClientMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { byte[] buffer = new byte[ClientMsg.length]; @@ -64,10 +64,10 @@ namespace Passer.Control { buffer[1] = networkId; return buffer; } - public override void Deserialize(byte[] data) { - base.Deserialize(data); + public override void Deserialize(byte[] buffer) { + base.Deserialize(buffer); uint ix = 0; - networkId = data[ix]; + networkId = buffer[ix]; } public static bool Send(Client client, byte networkId) { @@ -88,13 +88,11 @@ namespace Passer.Control { if (client.networkId == 0) { client.networkId = (byte)(Client.clients.Count); NetworkIdMsg.Send(client, client.networkId); - //if (string.IsNullOrEmpty(sceneUrl) == false) - //SendModelUrl(client, sceneUrl); + client.messageQueue.Enqueue(msg); } else if (msg.networkId == 0) { NetworkIdMsg.Send(client, client.networkId); - //if (string.IsNullOrEmpty(sceneUrl) == false) - //SendModelUrl(client, sceneUrl); + client.messageQueue.Enqueue(msg); } return true; @@ -113,26 +111,22 @@ namespace Passer.Control { NetworkIdMsg(byte networkId) { this.networkId = networkId; } - NetworkIdMsg(byte[] data) : base(data) { } + NetworkIdMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { - byte[] data = new byte[NetworkIdMsg.length]; - data[0] = NetworkIdMsg.Id; - data[1] = this.networkId; - return data; + byte[] buffer = new byte[NetworkIdMsg.length]; + buffer[0] = NetworkIdMsg.Id; + buffer[1] = this.networkId; + return buffer; } - public override void Deserialize(byte[] data) { + public override void Deserialize(byte[] buffer) { uint ix = 0; - this.networkId = data[ix]; + this.networkId = buffer[ix]; } public static bool Send(Client client, byte networkId) { NetworkIdMsg msg = new(networkId); return SendMsg(client, msg); - //byte[] data = new byte[NetworkIdMsg.length]; - //data[0] = NetworkIdMsg.Id; - //data[1] = client.networkId; - //return SendMsg(client, data); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { if (packetSize != length) @@ -159,7 +153,7 @@ namespace Passer.Control { this.networkId = networkId; this.thingId = thingId; } - public InvestigateMsg(byte[] data) : base(data) { } + public InvestigateMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { byte[] buffer = new byte[InvestigateMsg.length]; @@ -168,10 +162,10 @@ namespace Passer.Control { buffer[2] = this.thingId; return buffer; } - public override void Deserialize(byte[] data) { + public override void Deserialize(byte[] buffer) { uint ix = 0; - this.networkId = data[ix++]; - this.thingId = data[ix++]; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; } public static bool Send(Client client, byte thingId) { @@ -195,8 +189,9 @@ namespace Passer.Control { #region Thing public class ThingMsg : IMessage { - public const byte length = 4; + public const byte length = 5; public const byte Id = 0x80; + public byte networkId; public byte thingId; public byte thingType; public byte parentId; @@ -206,22 +201,24 @@ namespace Passer.Control { this.thingType = thingType; this.parentId = parentId; } - public ThingMsg(byte[] data) : base(data) { } + public ThingMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { - byte[] data = new byte[ThingMsg.length]; + byte[] buffer = new byte[ThingMsg.length]; byte ix = 0; - data[ix++] = ThingMsg.Id; - data[ix++] = this.thingId; - data[ix++] = this.thingType; - data[ix] = this.parentId; - return data; + buffer[ix++] = ThingMsg.Id; + buffer[ix++] = this.networkId; + buffer[ix++] = this.thingId; + buffer[ix++] = this.thingType; + buffer[ix] = this.parentId; + return buffer; } - public override void Deserialize(byte[] data) { + public override void Deserialize(byte[] buffer) { uint ix = 0; - this.thingId = data[ix++]; - this.thingType = data[ix++]; - this.parentId = data[ix]; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + this.thingType = buffer[ix++]; + this.parentId = buffer[ix]; } public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { @@ -246,7 +243,8 @@ namespace Passer.Control { public class NameMsg : IMessage { public const byte Id = 0x91; // 145 - public const byte length = 3; + public const byte length = 4; + public byte networkId; public byte thingId; public byte len; public string name; @@ -255,22 +253,24 @@ namespace Passer.Control { this.thingId = thingId; this.name = name; } - public NameMsg(byte[] data) : base(data) { } + public NameMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { byte[] buffer = new byte[length + this.name.Length]; - buffer[0] = NameMsg.Id; - buffer[1] = this.thingId; - buffer[2] = (byte)this.name.Length; - for (int ix = 0; ix < this.name.Length; ix++) - buffer[3 + ix] = (byte)this.name[ix]; + byte ix = 0; + buffer[ix++] = NameMsg.Id; + buffer[ix++] = this.networkId; + buffer[ix++] = this.thingId; + buffer[ix++] = (byte)this.name.Length; + for (int nameIx = 0; nameIx < this.name.Length; nameIx++, ix++) + buffer[ix] = (byte)this.name[nameIx]; return buffer; } - public override void Deserialize(byte[] data) { + public override void Deserialize(byte[] buffer) { uint ix = 0; - this.thingId = data[ix++]; - int strlen = data[ix++]; - this.name = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); + this.thingId = buffer[ix++]; + int strlen = buffer[ix++]; + this.name = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); } public static bool Send(Client client, byte thingId, string name) { @@ -292,6 +292,7 @@ namespace Passer.Control { public class ModelUrlMsg : IMessage { public const byte Id = 0x90; // (144) Model URL + public byte networkId; public byte thingId; public Spherical position; public float scale; @@ -303,28 +304,29 @@ namespace Passer.Control { this.scale = scale; this.position = Spherical.zero; } - public ModelUrlMsg(byte[] data) : base(data) { } + public ModelUrlMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { - byte[] data = new byte[this.url.Length + 9]; - data[0] = ModelUrlMsg.Id; - data[1] = this.thingId; // Thing Id - // data[2]..[5] == position 0, 0, 0 - data[6] = 0x3C; // Dummy float16 value 1 - data[7] = 0x00; + byte[] buffer = new byte[this.url.Length + 5]; + byte ix = 0; + buffer[ix++] = ModelUrlMsg.Id; + buffer[ix++] = this.networkId; + buffer[ix++] = this.thingId; // Thing Id + LowLevelMessages.SendFloat16(buffer, ref ix, new float16(1.0f)); - data[8] = (byte)url.Length; - for (int ix = 0; ix < this.url.Length; ix++) - data[9 + ix] = (byte)url[ix]; - return data; + buffer[8] = (byte)url.Length; + for (int urlIx = 0; urlIx < this.url.Length; urlIx++, ix++) + buffer[ix] = (byte)url[urlIx]; + return buffer; } - public override void Deserialize(byte[] data) { - uint ix = 0; - this.thingId = data[ix++]; - this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); - this.scale = LowLevelMessages.ReceiveFloat16(data, ref ix); - int strlen = data[ix++]; - url = System.Text.Encoding.UTF8.GetString(data, (int)ix, strlen); + public override void Deserialize(byte[] buffer) { + byte ix = 0; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + //this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); + this.scale = LowLevelMessages.ReceiveFloat16(buffer, ref ix); + int strlen = buffer[ix++]; + url = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); } public static bool Send(Client client, byte thingId, string modelUrl) { @@ -345,7 +347,8 @@ namespace Passer.Control { public class PoseMsg : IMessage { public const byte Id = 0x10; - public const byte length = 3 + 4 + 4; + public const byte length = 4 + 4 + 4; + public byte networkId; public byte thingId; public byte poseType; @@ -369,12 +372,13 @@ namespace Passer.Control { else this.orientation = new Quat32(0, 0, 0, 1); } - public PoseMsg(byte[] data) : base(data) { } + public PoseMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { byte[] buffer = new byte[PoseMsg.length]; - uint ix = 0; + byte ix = 0; buffer[ix++] = PoseMsg.Id; + buffer[ix++] = this.networkId; buffer[ix++] = this.thingId; buffer[ix++] = this.poseType; @@ -382,15 +386,16 @@ namespace Passer.Control { LowLevelMessages.SendQuat32(buffer, ref ix, orientation); return buffer; } - public override void Deserialize(byte[] data) { - uint ix = 0; - thingId = data[ix++]; - poseType = data[ix++]; + public override void Deserialize(byte[] buffer) { + byte ix = 0; + thingId = buffer[ix++]; + thingId = buffer[ix++]; + poseType = buffer[ix++]; //if ((poseType & Pose_Position) != 0) - position = LowLevelMessages.ReceiveSpherical(data, ref ix); + position = LowLevelMessages.ReceiveSpherical(buffer, ref ix); //if ((poseType & Pose_Orientation) != 0) { - orientation = LowLevelMessages.ReceiveQuat32(data, ref ix); + orientation = LowLevelMessages.ReceiveQuat32(buffer, ref ix); } public static bool Send(Client client, byte thingId, Spherical position, Quat32 orientation) { @@ -419,7 +424,7 @@ namespace Passer.Control { public byte thingId; public byte[] bytes; - public CustomMsg(byte[] data) : base(data) { } + public CustomMsg(byte[] buffer) : base(buffer) { } public CustomMsg(byte networkId, byte thingId, byte[] bytes) : base() { this.networkId = networkId; this.thingId = thingId; @@ -428,7 +433,7 @@ namespace Passer.Control { public override byte[] Serialize() { byte[] buffer = new byte[4 + this.bytes.Length]; - int ix = 0; + byte ix = 0; buffer[ix++] = CustomMsg.Id; buffer[ix++] = this.networkId; buffer[ix++] = this.thingId; @@ -438,15 +443,16 @@ namespace Passer.Control { return buffer; } - public override void Deserialize(byte[] data) { + public override void Deserialize(byte[] buffer) { uint ix = 0; - this.thingId = data[ix++]; - this.bytes = new byte[data.Length - ix]; - for (uint bytesIx = 0; ix < data.Length; ix++, bytesIx++) - this.bytes[bytesIx] = data[ix]; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + byte length = buffer[ix++]; + this.bytes = new byte[length]; + for (uint bytesIx = 0; ix < length; ix++, bytesIx++) + this.bytes[bytesIx] = buffer[ix]; } - public static void Send(Client client, byte thingId, byte[] bytes) { CustomMsg msg = new(client.networkId, thingId, bytes); SendMsg(client, msg); @@ -467,11 +473,11 @@ namespace Passer.Control { public const byte Id = 0xB0; public string text; - public TextMsg(byte[] data) : base(data) { } - public override void Deserialize(byte[] data) { + public TextMsg(byte[] buffer) : base(buffer) { } + public override void Deserialize(byte[] buffer) { uint ix = 0; - uint strlen = data[ix++]; - this.text = System.Text.Encoding.UTF8.GetString(data, (int)ix, (int)strlen); + uint strlen = buffer[ix++]; + this.text = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, (int)strlen); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -490,12 +496,14 @@ namespace Passer.Control { public class DestroyMsg : IMessage { public const byte Id = 0x20; public const byte length = 2; - public byte objectId; + public byte networkId; + public byte thingId; - public DestroyMsg(byte[] data) : base(data) { } + public DestroyMsg(byte[] buffer) : base(buffer) { } - public override void Deserialize(byte[] data) { - objectId = data[0]; + public override void Deserialize(byte[] buffer) { + this.networkId = buffer[0]; + this.thingId = buffer[1]; } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { diff --git a/SiteServer.cs b/SiteServer.cs index 24e42b2..a563bf5 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -1,28 +1,9 @@ -using System.Diagnostics; using System.IO; using System.Threading.Tasks; namespace Passer.Control { public static class SiteServer { - //public static async Task ReceiveData() { - // while (true) { - // //foreach (var client in Client.clients) { - - // for (int ix = 0; ix < Client.clients.Count; ix++) { - // if (ix > 0) - // UnityEngine.Debug.Log("Client2 "); - // Client client = Client.clients[ix]; - // if (client == null) - // continue; - - // byte packetSize = (byte)client.dataStream.ReadByte(); - // if (packetSize != 0xFF) - // await ReceiveData(client.dataStream, client, packetSize); - // // else timeout - // } - // } - //} public static async Task ReceiveData(Stream dataStream, Client client) { while (true) { From 71ca0eb1f8344c0878805580bd0dbe08d8c272fd Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 17:03:30 +0100 Subject: [PATCH 09/14] Fix modelURl message --- Messages.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Messages.cs b/Messages.cs index dc85d1a..5a6c43d 100644 --- a/Messages.cs +++ b/Messages.cs @@ -307,14 +307,14 @@ namespace Passer.Control { public ModelUrlMsg(byte[] buffer) : base(buffer) { } public override byte[] Serialize() { - byte[] buffer = new byte[this.url.Length + 5]; + byte[] buffer = new byte[this.url.Length + 6]; byte ix = 0; buffer[ix++] = ModelUrlMsg.Id; buffer[ix++] = this.networkId; buffer[ix++] = this.thingId; // Thing Id LowLevelMessages.SendFloat16(buffer, ref ix, new float16(1.0f)); - buffer[8] = (byte)url.Length; + buffer[ix++] = (byte)url.Length; for (int urlIx = 0; urlIx < this.url.Length; urlIx++, ix++) buffer[ix] = (byte)url[urlIx]; return buffer; @@ -323,7 +323,6 @@ namespace Passer.Control { byte ix = 0; this.networkId = buffer[ix++]; this.thingId = buffer[ix++]; - //this.position = LowLevelMessages.ReceiveSpherical(data, ref ix); this.scale = LowLevelMessages.ReceiveFloat16(buffer, ref ix); int strlen = buffer[ix++]; url = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); From 6e5b923f978c3ba72acd1575c5e1f5e4792b9e8b Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 17:13:38 +0100 Subject: [PATCH 10/14] Add networkId to msg constructors --- Messages.cs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/Messages.cs b/Messages.cs index 5a6c43d..a24554f 100644 --- a/Messages.cs +++ b/Messages.cs @@ -196,7 +196,7 @@ namespace Passer.Control { public byte thingType; public byte parentId; - public ThingMsg(byte thingId, byte thingType, byte parentId) { + public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { this.thingId = thingId; this.thingType = thingType; this.parentId = parentId; @@ -222,7 +222,7 @@ namespace Passer.Control { } public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - ThingMsg msg = new(thingId, thingType, parentId); + ThingMsg msg = new(client.networkId, thingId, thingType, parentId); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -249,7 +249,8 @@ namespace Passer.Control { public byte len; public string name; - public NameMsg(byte thingId, string name) { + public NameMsg(byte networkId, byte thingId, string name) { + this.networkId = networkId; this.thingId = thingId; this.name = name; } @@ -274,7 +275,7 @@ namespace Passer.Control { } public static bool Send(Client client, byte thingId, string name) { - NameMsg msg = new(thingId, name); + NameMsg msg = new(client.networkId, thingId, name); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -298,7 +299,8 @@ namespace Passer.Control { public float scale; public string url; - public ModelUrlMsg(byte thingId, string url, float scale = 1) { + public ModelUrlMsg(byte networkId, byte thingId, string url, float scale = 1) { + this.networkId = networkId; this.thingId = thingId; this.url = url; this.scale = scale; @@ -329,7 +331,7 @@ namespace Passer.Control { } public static bool Send(Client client, byte thingId, string modelUrl) { - ModelUrlMsg msg = new(thingId, modelUrl); + ModelUrlMsg msg = new(client.networkId, thingId, modelUrl); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -357,7 +359,8 @@ namespace Passer.Control { public Spherical position; public Quat32 orientation; - public PoseMsg(byte thingId, Spherical position, Quat32 orientation) { + public PoseMsg(byte networkId, byte thingId, Spherical position, Quat32 orientation) { + this.networkId = networkId; this.thingId = thingId; this.position = position; this.orientation = orientation; @@ -381,24 +384,24 @@ namespace Passer.Control { buffer[ix++] = this.thingId; buffer[ix++] = this.poseType; - LowLevelMessages.SendSpherical(buffer, ref ix, position); - LowLevelMessages.SendQuat32(buffer, ref ix, orientation); + LowLevelMessages.SendSpherical(buffer, ref ix, this.position); + LowLevelMessages.SendQuat32(buffer, ref ix, this.orientation); return buffer; } public override void Deserialize(byte[] buffer) { byte ix = 0; - thingId = buffer[ix++]; - thingId = buffer[ix++]; - poseType = buffer[ix++]; + this.networkId = buffer[ix++]; + this.thingId = buffer[ix++]; + this.poseType = buffer[ix++]; //if ((poseType & Pose_Position) != 0) - position = LowLevelMessages.ReceiveSpherical(buffer, ref ix); + this.position = LowLevelMessages.ReceiveSpherical(buffer, ref ix); //if ((poseType & Pose_Orientation) != 0) { - orientation = LowLevelMessages.ReceiveQuat32(buffer, ref ix); + this.orientation = LowLevelMessages.ReceiveQuat32(buffer, ref ix); } public static bool Send(Client client, byte thingId, Spherical position, Quat32 orientation) { - PoseMsg msg = new(thingId, position, orientation); + PoseMsg msg = new(client.networkId, thingId, position, orientation); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { From cdd1a7a53f557610553ef3a5325cdc4232350e58 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Dec 2024 17:22:30 +0100 Subject: [PATCH 11/14] Fix name message --- Messages.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Messages.cs b/Messages.cs index a24554f..ecf47f9 100644 --- a/Messages.cs +++ b/Messages.cs @@ -268,7 +268,8 @@ namespace Passer.Control { return buffer; } public override void Deserialize(byte[] buffer) { - uint ix = 0; + byte ix = 0; + this.networkId = buffer[ix++]; this.thingId = buffer[ix++]; int strlen = buffer[ix++]; this.name = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); @@ -405,6 +406,7 @@ namespace Passer.Control { return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { + UnityEngine.Debug.Log("Receive pose"); if (packetSize != length) return false; From 0f0fcfdfbf58244a7878449cabc920a8467d9e50 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 11 Dec 2024 11:29:01 +0100 Subject: [PATCH 12/14] Improved reloading support --- Client.cs | 6 ++++-- Messages.cs | 26 +++++++++++++++++--------- SiteServer.cs | 1 + 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Client.cs b/Client.cs index 26ad994..e54583e 100644 --- a/Client.cs +++ b/Client.cs @@ -47,6 +47,7 @@ namespace Passer.Control { ProcessNetworkId(networkId); break; case InvestigateMsg investigate: + UnityEngine.Debug.Log($"investigate [{investigate.networkId}/{investigate.thingId}]"); ProcessInvestigate(investigate); break; case ThingMsg thing: @@ -96,11 +97,12 @@ namespace Passer.Control { protected virtual void ProcessDestroy(DestroyMsg destroy) { } - private void ForwardMessage(IMessage thing) { + private void ForwardMessage(IMessage msg) { foreach (Client client in Client.clients) { if (client == this) continue; - IMessage.SendMsg(client, thing); + UnityEngine.Debug.Log($"---> {client.ipAddress}"); + IMessage.SendMsg(client, msg); } } } diff --git a/Messages.cs b/Messages.cs index ecf47f9..c0e852b 100644 --- a/Messages.cs +++ b/Messages.cs @@ -19,6 +19,7 @@ namespace Passer.Control { if (client == null || client.ipAddress == null) return false; + //UnityEngine.Debug.Log($"Send msg {buffer[0]} to {client.ipAddress}"); client.udpClient.Send(buffer, buffer.Length, client.ipAddress, client.port); return true; } @@ -168,8 +169,8 @@ namespace Passer.Control { this.thingId = buffer[ix++]; } - public static bool Send(Client client, byte thingId) { - InvestigateMsg msg = new(client.networkId, thingId); + public static bool Send(Client client, byte networkId, byte thingId) { + InvestigateMsg msg = new(networkId, thingId); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -232,6 +233,10 @@ namespace Passer.Control { byte[] buffer = await Receive(dataStream, packetSize); ThingMsg msg = new(buffer); + // Do no process poses with nwid == 0 (== local) + if (msg.networkId == 0) + return true; + client.messageQueue.Enqueue(msg); return true; } @@ -406,13 +411,16 @@ namespace Passer.Control { return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { - UnityEngine.Debug.Log("Receive pose"); if (packetSize != length) return false; byte[] buffer = await Receive(dataStream, packetSize); PoseMsg msg = new(buffer); + // Do no process poses with nwid == 0 (== local) + if (msg.networkId == 0) + return true; + client.messageQueue.Enqueue(msg); return true; } @@ -436,25 +444,25 @@ namespace Passer.Control { } public override byte[] Serialize() { - byte[] buffer = new byte[4 + this.bytes.Length]; + byte[] buffer = new byte[3 + this.bytes.Length]; byte ix = 0; buffer[ix++] = CustomMsg.Id; buffer[ix++] = this.networkId; buffer[ix++] = this.thingId; - buffer[ix++] = (byte)bytes.Length; + //buffer[ix++] = (byte)bytes.Length; foreach (byte b in bytes) buffer[ix++] = b; return buffer; } public override void Deserialize(byte[] buffer) { - uint ix = 0; + byte ix = 0; this.networkId = buffer[ix++]; this.thingId = buffer[ix++]; - byte length = buffer[ix++]; + byte length = (byte)(buffer.Length - ix);//buffer[ix++]; this.bytes = new byte[length]; - for (uint bytesIx = 0; ix < length; ix++, bytesIx++) - this.bytes[bytesIx] = buffer[ix]; + for (uint bytesIx = 0; bytesIx < length; bytesIx++) + this.bytes[bytesIx] = buffer[ix++]; } public static void Send(Client client, byte thingId, byte[] bytes) { diff --git a/SiteServer.cs b/SiteServer.cs index a563bf5..57460f3 100644 --- a/SiteServer.cs +++ b/SiteServer.cs @@ -21,6 +21,7 @@ namespace Passer.Control { return; } + //UnityEngine.Debug.Log($"R {msgId} from {client.ipAddress}"); bool result = false; switch (msgId) { case ClientMsg.Id: // 0xA0 / 160 From 1d2da54a173ec8d09802739784ec05f0fb7f8247 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 11 Dec 2024 14:53:18 +0100 Subject: [PATCH 13/14] ControlCore improvements --- Client.cs | 4 ++-- Messages.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Client.cs b/Client.cs index e54583e..27b474d 100644 --- a/Client.cs +++ b/Client.cs @@ -47,13 +47,13 @@ namespace Passer.Control { ProcessNetworkId(networkId); break; case InvestigateMsg investigate: - UnityEngine.Debug.Log($"investigate [{investigate.networkId}/{investigate.thingId}]"); ProcessInvestigate(investigate); break; case ThingMsg thing: ProcessThing(thing); break; case NameMsg name: + UnityEngine.Debug.Log($"Name [{name.networkId}/{name.thingId}] {name.name}"); ProcessName(name); break; case ModelUrlMsg modelUrl: @@ -101,7 +101,7 @@ namespace Passer.Control { foreach (Client client in Client.clients) { if (client == this) continue; - UnityEngine.Debug.Log($"---> {client.ipAddress}"); + //UnityEngine.Debug.Log($"---> {client.ipAddress}"); IMessage.SendMsg(client, msg); } } diff --git a/Messages.cs b/Messages.cs index c0e852b..59439b0 100644 --- a/Messages.cs +++ b/Messages.cs @@ -234,8 +234,8 @@ namespace Passer.Control { ThingMsg msg = new(buffer); // Do no process poses with nwid == 0 (== local) - if (msg.networkId == 0) - return true; + //if (msg.networkId == 0) + // return true; client.messageQueue.Enqueue(msg); return true; @@ -280,8 +280,8 @@ namespace Passer.Control { this.name = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); } - public static bool Send(Client client, byte thingId, string name) { - NameMsg msg = new(client.networkId, thingId, name); + public static bool Send(Client client, byte networkId, byte thingId, string name) { + NameMsg msg = new(networkId, thingId, name); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -336,8 +336,8 @@ namespace Passer.Control { url = System.Text.Encoding.UTF8.GetString(buffer, (int)ix, strlen); } - public static bool Send(Client client, byte thingId, string modelUrl) { - ModelUrlMsg msg = new(client.networkId, thingId, modelUrl); + public static bool Send(Client client, byte networkId, byte thingId, string modelUrl) { + ModelUrlMsg msg = new(networkId, thingId, modelUrl); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { From 7e80a360274abb6d8f8299cdd2f6ada26bb5ce3c Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 11 Dec 2024 15:23:32 +0100 Subject: [PATCH 14/14] Improved ControlCore --- Client.cs | 2 +- Messages.cs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Client.cs b/Client.cs index 27b474d..c5ca156 100644 --- a/Client.cs +++ b/Client.cs @@ -53,7 +53,7 @@ namespace Passer.Control { ProcessThing(thing); break; case NameMsg name: - UnityEngine.Debug.Log($"Name [{name.networkId}/{name.thingId}] {name.name}"); + //UnityEngine.Debug.Log($"Name [{name.networkId}/{name.thingId}] {name.name}"); ProcessName(name); break; case ModelUrlMsg modelUrl: diff --git a/Messages.cs b/Messages.cs index 59439b0..c49ac02 100644 --- a/Messages.cs +++ b/Messages.cs @@ -171,6 +171,7 @@ namespace Passer.Control { public static bool Send(Client client, byte networkId, byte thingId) { InvestigateMsg msg = new(networkId, thingId); + //UnityEngine.Debug.Log($"Send investigate [{msg.networkId}/{msg.thingId}]"); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -179,6 +180,8 @@ namespace Passer.Control { byte[] buffer = await Receive(dataStream, packetSize); InvestigateMsg msg = new(buffer); + //UnityEngine.Debug.Log($"Receive investigate [{msg.networkId}/{msg.thingId}]"); + client.messageQueue.Enqueue(msg); return true; @@ -198,6 +201,7 @@ namespace Passer.Control { public byte parentId; public ThingMsg(byte networkId, byte thingId, byte thingType, byte parentId) { + this.networkId = networkId; this.thingId = thingId; this.thingType = thingType; this.parentId = parentId; @@ -222,8 +226,9 @@ namespace Passer.Control { this.parentId = buffer[ix]; } - public static bool Send(Client client, byte thingId, byte thingType, byte parentId) { - ThingMsg msg = new(client.networkId, thingId, thingType, parentId); + public static bool Send(Client client, byte networkId, byte thingId, byte thingType, byte parentId) { + ThingMsg msg = new(networkId, thingId, thingType, parentId); + //UnityEngine.Debug.Log($"Send thing [{msg.networkId}/{msg.thingId}]"); return SendMsg(client, msg); } public static async Task Receive(Stream dataStream, Client client, byte packetSize) { @@ -232,6 +237,7 @@ namespace Passer.Control { byte[] buffer = await Receive(dataStream, packetSize); ThingMsg msg = new(buffer); + //UnityEngine.Debug.Log($"Receive thing [{msg.networkId}/{msg.thingId}]"); // Do no process poses with nwid == 0 (== local) //if (msg.networkId == 0)