Skip to content

Commit a209044

Browse files
committed
Added first version of MessagePassthrough
1 parent 1f14ded commit a209044

File tree

5 files changed

+131
-18
lines changed

5 files changed

+131
-18
lines changed

MLAPI/Data/NetworkingConfiguration.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public class NetworkingConfiguration
1111
public ushort ProtocolVersion = 0;
1212
public SortedDictionary<string, QosType> Channels = new SortedDictionary<string, QosType>();
1313
public List<string> MessageTypes = new List<string>();
14+
public List<string> PassthroughMessageTypes = new List<string>();
15+
internal HashSet<ushort> RegisteredPassthroughMessageTypes = new HashSet<ushort>();
1416
public int MessageBufferSize = 65535;
1517
public int MaxMessagesPerFrame = 150;
1618
public int MaxConnections = 100;
@@ -26,6 +28,7 @@ public class NetworkingConfiguration
2628
//Should only be used for dedicated servers and will require the servers RSA keypair being hard coded into clients in order to exchange a AES key
2729
//TODO
2830
public bool EncryptMessages = false;
31+
public bool AllowPassthroughMessages = true;
2932

3033
//Cached config hash
3134
private byte[] ConfigHash = null;
@@ -44,13 +47,20 @@ public byte[] GetConfig(bool cache = true)
4447
writer.Write(pair.Key);
4548
writer.Write((int)pair.Value);
4649
}
50+
MessageTypes.Sort();
51+
PassthroughMessageTypes.Sort();
4752
for (int i = 0; i < MessageTypes.Count; i++)
4853
{
4954
writer.Write(MessageTypes[i]);
5055
}
56+
for (int i = 0; i < PassthroughMessageTypes.Count; i++)
57+
{
58+
writer.Write(PassthroughMessageTypes[i]);
59+
}
5160
writer.Write(HandleObjectSpawning);
5261
writer.Write(CompressMessages);
5362
writer.Write(EncryptMessages);
63+
writer.Write(AllowPassthroughMessages);
5464
}
5565
using(SHA256Managed sha256 = new SHA256Managed())
5666
{

MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,19 @@ protected void SendToServerTarget(string messageType, string channelName, byte[]
126126

127127
protected void SendToLocalClient(string messageType, string channelName, byte[] data)
128128
{
129-
if (!isServer)
129+
if (!isServer && (!NetworkingManager.singleton.NetworkConfig.AllowPassthroughMessages || !NetworkingManager.singleton.NetworkConfig.PassthroughMessageTypes.Contains(messageType)))
130130
{
131-
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
131+
Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType");
132132
return;
133133
}
134134
NetworkingManager.singleton.Send(ownerClientId, messageType, channelName, data);
135135
}
136136

137137
protected void SendToLocalClientTarget(string messageType, string channelName, byte[] data)
138138
{
139-
if (!isServer)
139+
if (!isServer && (!NetworkingManager.singleton.NetworkConfig.AllowPassthroughMessages || !NetworkingManager.singleton.NetworkConfig.PassthroughMessageTypes.Contains(messageType)))
140140
{
141-
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
141+
Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType");
142142
return;
143143
}
144144
NetworkingManager.singleton.Send(ownerClientId, messageType, channelName, data, networkId);
@@ -166,19 +166,19 @@ protected void SendToNonLocalClientsTarget(string messageType, string channelNam
166166

167167
protected void SendToClient(int clientId, string messageType, string channelName, byte[] data)
168168
{
169-
if (!isServer)
169+
if (!isServer && (!NetworkingManager.singleton.NetworkConfig.AllowPassthroughMessages || !NetworkingManager.singleton.NetworkConfig.PassthroughMessageTypes.Contains(messageType)))
170170
{
171-
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
171+
Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType");
172172
return;
173173
}
174174
NetworkingManager.singleton.Send(clientId, messageType, channelName, data);
175175
}
176176

177177
protected void SendToClientTarget(int clientId, string messageType, string channelName, byte[] data)
178178
{
179-
if (!isServer)
179+
if (!isServer && (!NetworkingManager.singleton.NetworkConfig.AllowPassthroughMessages || !NetworkingManager.singleton.NetworkConfig.PassthroughMessageTypes.Contains(messageType)))
180180
{
181-
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
181+
Debug.LogWarning("MLAPI: Invalid Passthrough send. Ensure AllowPassthroughMessages are turned on and that the MessageType " + messageType + " is registered as a passthroughMessageType");
182182
return;
183183
}
184184
NetworkingManager.singleton.Send(clientId, messageType, channelName, data, networkId);

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,17 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
6767
MessageManager.messageHandlerCounter = new Dictionary<ushort, int>();
6868
MessageManager.releasedMessageHandlerCounters = new Dictionary<ushort, Stack<int>>();
6969
MessageManager.targetedMessages = new Dictionary<ushort, Dictionary<uint, List<int>>>();
70+
MessageManager.reverseChannels = new Dictionary<int, string>();
71+
MessageManager.reverseMessageTypes = new Dictionary<ushort, string>();
7072
SpawnManager.spawnedObjects = new Dictionary<uint, NetworkedObject>();
7173
SpawnManager.releasedNetworkObjectIds = new Stack<uint>();
74+
if(NetworkConfig.AllowPassthroughMessages)
75+
{
76+
for (int i = 0; i < NetworkConfig.PassthroughMessageTypes.Count; i++)
77+
{
78+
NetworkConfig.RegisteredPassthroughMessageTypes.Add(MessageManager.messageTypes[NetworkConfig.PassthroughMessageTypes[i]]);
79+
}
80+
}
7281
if (NetworkConfig.HandleObjectSpawning)
7382
{
7483
NetworkedObject[] sceneObjects = FindObjectsOfType<NetworkedObject>();
@@ -104,11 +113,13 @@ private ConnectionConfig Init(NetworkingConfiguration netConfig)
104113
int channelId = cConfig.AddChannel(pair.Value);
105114
MessageManager.channels.Add(pair.Key, channelId);
106115
channelNames.Add(pair.Key);
116+
MessageManager.reverseChannels.Add(channelId, pair.Key);
107117
}
108118
//0-32 are reserved for MLAPI messages
109119
ushort messageId = 32;
110120
for (ushort i = 0; i < NetworkConfig.MessageTypes.Count; i++)
111121
{
122+
MessageManager.reverseMessageTypes.Add(messageId, NetworkConfig.MessageTypes[i]);
112123
MessageManager.messageTypes.Add(NetworkConfig.MessageTypes[i], messageId);
113124
messageId++;
114125
}
@@ -289,7 +300,7 @@ private void Update()
289300
}
290301
break;
291302
case NetworkEventType.DataEvent:
292-
HandleIncomingData(clientId, messageBuffer);
303+
HandleIncomingData(clientId, messageBuffer, channelId);
293304
break;
294305
case NetworkEventType.DisconnectEvent:
295306
if(isServer)
@@ -319,7 +330,7 @@ private IEnumerator ApprovalTimeout(int clientId)
319330
}
320331
}
321332

322-
private void HandleIncomingData(int connectonId, byte[] data)
333+
private void HandleIncomingData(int clientId, byte[] data, int channelId)
323334
{
324335
using(MemoryStream readStream = new MemoryStream(data))
325336
{
@@ -330,6 +341,16 @@ private void HandleIncomingData(int connectonId, byte[] data)
330341
uint targetNetworkId = 0;
331342
if(targeted)
332343
targetNetworkId = reader.ReadUInt32();
344+
bool isPassthrough = reader.ReadBoolean();
345+
346+
int passthroughOrigin = 0;
347+
int passthroughTarget = 0;
348+
349+
if (isPassthrough && isServer)
350+
passthroughTarget = reader.ReadInt32();
351+
else if (isPassthrough && !isServer)
352+
passthroughOrigin = reader.ReadInt32();
353+
333354

334355
//Client tried to send a network message that was not the connection request before he was accepted.
335356
if (isServer && pendingClients.Contains(clientId) && messageType != 0)
@@ -338,8 +359,30 @@ private void HandleIncomingData(int connectonId, byte[] data)
338359
return;
339360
}
340361

362+
341363
ushort bytesToRead = reader.ReadUInt16();
342364
byte[] incommingData = reader.ReadBytes(bytesToRead);
365+
366+
if (isServer && isPassthrough && !NetworkConfig.RegisteredPassthroughMessageTypes.Contains(messageType))
367+
{
368+
Debug.LogWarning("MLAPI: Client " + clientId + " tried to send a passthrough message for a messageType not registered as passthrough");
369+
return;
370+
}
371+
else if(isClient && isPassthrough && !NetworkConfig.RegisteredPassthroughMessageTypes.Contains(messageType))
372+
{
373+
Debug.LogWarning("MLAPI: Server tried to send a passthrough message for a messageType not registered as passthrough");
374+
return;
375+
}
376+
else if(isServer && NetworkConfig.AllowPassthroughMessages && connectedClients.ContainsKey(passthroughTarget))
377+
{
378+
uint? netIdTarget = null;
379+
if (targeted)
380+
netIdTarget = targetNetworkId;
381+
382+
PassthroughSend(passthroughTarget, clientId, messageType, channelId, incommingData, netIdTarget);
383+
return;
384+
}
385+
343386
if (messageType >= 32)
344387
{
345388
//Custom message, invoke all message handlers
@@ -348,14 +391,20 @@ private void HandleIncomingData(int connectonId, byte[] data)
348391
List<int> handlerIds = MessageManager.targetedMessages[messageType][targetNetworkId];
349392
for (int i = 0; i < handlerIds.Count; i++)
350393
{
351-
MessageManager.messageCallbacks[messageType][handlerIds[i]](clientId, incommingData);
394+
if (isPassthrough)
395+
MessageManager.messageCallbacks[messageType][handlerIds[i]](passthroughOrigin, incommingData);
396+
else
397+
MessageManager.messageCallbacks[messageType][handlerIds[i]](clientId, incommingData);
352398
}
353399
}
354400
else
355401
{
356402
foreach (KeyValuePair<int, Action<int, byte[]>> pair in MessageManager.messageCallbacks[messageType])
357403
{
358-
pair.Value(clientId, incommingData);
404+
if (isPassthrough)
405+
pair.Value(passthroughOrigin, incommingData);
406+
else
407+
pair.Value(clientId, incommingData);
359408
}
360409
}
361410
}
@@ -500,6 +549,40 @@ private void HandleIncomingData(int connectonId, byte[] data)
500549
}
501550
}
502551

552+
internal void PassthroughSend(int targetId, int sourceId, ushort messageType, int channelId, byte[] data, uint? networkId = null)
553+
{
554+
if (isHost && targetId == -1)
555+
{
556+
//Host trying to send data to it's own client
557+
if (networkId == null)
558+
MessageManager.InvokeMessageHandlers(MessageManager.reverseMessageTypes[messageType], data, sourceId);
559+
else
560+
MessageManager.InvokeTargetedMessageHandler(MessageManager.reverseMessageTypes[messageType], data, sourceId, networkId.Value);
561+
return;
562+
}
563+
564+
int sizeOfStream = 10;
565+
if (networkId != null)
566+
sizeOfStream += 4;
567+
sizeOfStream += data.Length;
568+
569+
using (MemoryStream stream = new MemoryStream(sizeOfStream))
570+
{
571+
using (BinaryWriter writer = new BinaryWriter(stream))
572+
{
573+
writer.Write(messageType);
574+
writer.Write(networkId != null);
575+
if (networkId != null)
576+
writer.Write(networkId.Value);
577+
writer.Write(true);
578+
writer.Write(sourceId);
579+
writer.Write((ushort)data.Length);
580+
writer.Write(data);
581+
}
582+
NetworkTransport.Send(hostId, targetId, channelId, stream.GetBuffer(), sizeOfStream, out error);
583+
}
584+
}
585+
503586
internal void Send(int clientId, string messageType, string channelName, byte[] data, uint? networkId = null)
504587
{
505588
if(isHost && clientId == -1)
@@ -516,10 +599,19 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
516599
//Client trying to send data to host
517600
clientId = serverClientId;
518601
}
519-
//2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
520-
int sizeOfStream = 5;
602+
603+
bool isPassthrough = (!isServer && clientId != serverClientId && NetworkConfig.AllowPassthroughMessages);
604+
if (isPassthrough && !NetworkConfig.RegisteredPassthroughMessageTypes.Contains(MessageManager.messageTypes[messageType]))
605+
{
606+
Debug.LogWarning("MLAPI: The The MessageType " + messageType + " is not registered as an allowed passthrough message type.");
607+
return;
608+
}
609+
610+
int sizeOfStream = 6;
521611
if (networkId != null)
522612
sizeOfStream += 4;
613+
if (isPassthrough)
614+
sizeOfStream += 4;
523615
sizeOfStream += data.Length;
524616

525617
using (MemoryStream stream = new MemoryStream(sizeOfStream))
@@ -530,17 +622,21 @@ internal void Send(int clientId, string messageType, string channelName, byte[]
530622
writer.Write(networkId != null);
531623
if (networkId != null)
532624
writer.Write(networkId.Value);
625+
writer.Write(isPassthrough);
626+
if (isPassthrough)
627+
writer.Write(clientId);
533628
writer.Write((ushort)data.Length);
534629
writer.Write(data);
535630
}
631+
if (isPassthrough)
632+
clientId = serverClientId;
536633
NetworkTransport.Send(hostId, clientId, MessageManager.channels[channelName], stream.GetBuffer(), sizeOfStream, out error);
537634
}
538635
}
539636

540637
internal void Send(int[] clientIds, string messageType, string channelName, byte[] data, uint? networkId = null)
541638
{
542-
//2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
543-
int sizeOfStream = 5;
639+
int sizeOfStream = 6;
544640
if (networkId != null)
545641
sizeOfStream += 4;
546642
sizeOfStream += data.Length;
@@ -553,6 +649,7 @@ internal void Send(int[] clientIds, string messageType, string channelName, byte
553649
writer.Write(networkId != null);
554650
if (networkId != null)
555651
writer.Write(networkId.Value);
652+
writer.Write(false);
556653
writer.Write((ushort)data.Length);
557654
writer.Write(data);
558655
}
@@ -581,7 +678,7 @@ internal void Send(int[] clientIds, string messageType, string channelName, byte
581678
internal void Send(List<int> clientIds, string messageType, string channelName, byte[] data, uint? networkId = null)
582679
{
583680
//2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
584-
int sizeOfStream = 5;
681+
int sizeOfStream = 6;
585682
if (networkId != null)
586683
sizeOfStream += 4;
587684
sizeOfStream += data.Length;
@@ -594,6 +691,7 @@ internal void Send(List<int> clientIds, string messageType, string channelName,
594691
writer.Write(networkId != null);
595692
if (networkId != null)
596693
writer.Write(networkId.Value);
694+
writer.Write(false);
597695
writer.Write((ushort)data.Length);
598696
writer.Write(data);
599697
}
@@ -622,7 +720,7 @@ internal void Send(List<int> clientIds, string messageType, string channelName,
622720
internal void Send(string messageType, string channelName, byte[] data, uint? networkId = null)
623721
{
624722
//2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
625-
int sizeOfStream = 5;
723+
int sizeOfStream = 6;
626724
if (networkId != null)
627725
sizeOfStream += 4;
628726
sizeOfStream += data.Length;
@@ -635,6 +733,7 @@ internal void Send(string messageType, string channelName, byte[] data, uint? ne
635733
writer.Write(networkId != null);
636734
if (networkId != null)
637735
writer.Write(networkId.Value);
736+
writer.Write(false);
638737
writer.Write((ushort)data.Length);
639738
writer.Write(data);
640739
}
@@ -677,6 +776,7 @@ internal void Send(string messageType, string channelName, byte[] data, int clie
677776
writer.Write(networkId != null);
678777
if (networkId != null)
679778
writer.Write(networkId.Value);
779+
writer.Write(false);
680780
writer.Write((ushort)data.Length);
681781
writer.Write(data);
682782
}

MLAPI/NetworkingManagerComponents/MessageManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ namespace MLAPI.NetworkingManagerComponents
77
internal static class MessageManager
88
{
99
internal static Dictionary<string, int> channels;
10+
internal static Dictionary<int, string> reverseChannels;
1011
internal static Dictionary<string, ushort> messageTypes;
12+
internal static Dictionary<ushort, string> reverseMessageTypes;
1113
internal static Dictionary<ushort, Dictionary<int, Action<int, byte[]>>> messageCallbacks;
1214
internal static Dictionary<ushort, int> messageHandlerCounter;
1315
internal static Dictionary<ushort, Stack<int>> releasedMessageHandlerCounters;

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ It's licenced under the MIT licence :D
2525
* ProtocolVersion to allow making different versions not talk to each other. (done)
2626
* NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc. (done)
2727
* Multiple messages processed every frame with the ability to specify a maximum to prevent freezes in the normal game logic (done)
28+
* Passthrough messages (check the wiki for details)
2829

2930

3031
That's all I can think of right now. But there is more to come, especially if people show intrest in the project.

0 commit comments

Comments
 (0)