Skip to content

Commit dd87f98

Browse files
committed
Optimized Attribute messaging system
1 parent f4a167b commit dd87f98

File tree

9 files changed

+105
-24
lines changed

9 files changed

+105
-24
lines changed

MLAPI/Attributes/ClientRpc.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace MLAPI.Attributes
88
[AttributeUsage(AttributeTargets.Method)]
99
public class ClientRpc : Attribute
1010
{
11-
11+
public string channelName = "MLAPI_INTERNAL";
1212
}
1313
}

MLAPI/Attributes/Command.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace MLAPI.Attributes
88
[AttributeUsage(AttributeTargets.Method)]
99
public class Command : Attribute
1010
{
11-
11+
public string channelName = "MLAPI_INTERNAL";
1212
}
1313
}

MLAPI/Attributes/TargetRpc.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace MLAPI.Attributes
88
[AttributeUsage(AttributeTargets.Method)]
99
public class TargetRpc : Attribute
1010
{
11-
11+
public string channelName = "MLAPI_INTERNAL";
1212
}
1313
}

MLAPI/Data/AttributeMessageMode.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace MLAPI.Data
2+
{
3+
public enum AttributeMessageMode
4+
{
5+
Disabled,
6+
WovenTwoByte,
7+
WovenFourByte,
8+
WovenEightByte
9+
}
10+
}

MLAPI/Data/Cache.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,28 @@ internal static class Cache
88
internal static Dictionary<string, ulong> messageAttributeHashes = new Dictionary<string, ulong>();
99
internal static Dictionary<ulong, string> messageAttributeNames = new Dictionary<ulong, string>();
1010

11-
internal static ulong GetMessageAttributeHash(string name)
11+
internal static ulong GetMessageAttributeHash(string name, AttributeMessageMode mode)
1212
{
1313
if (messageAttributeHashes.ContainsKey(name))
1414
return messageAttributeHashes[name];
1515

16-
ulong value = PrimitiveHasher.GetULongHash(name);
16+
ulong value = 0;
17+
switch (mode)
18+
{
19+
case AttributeMessageMode.WovenTwoByte:
20+
value = PrimitiveHasher.GetUShortHash(name);
21+
break;
22+
case AttributeMessageMode.WovenFourByte:
23+
value = PrimitiveHasher.GetUIntHash(name);
24+
break;
25+
case AttributeMessageMode.WovenEightByte:
26+
value = PrimitiveHasher.GetULongHash(name);
27+
break;
28+
case AttributeMessageMode.Disabled:
29+
value = 0;
30+
break;
31+
}
32+
1733
messageAttributeHashes.Add(name, value);
1834
messageAttributeNames.Add(value, name);
1935
return value;
@@ -27,12 +43,28 @@ internal static string GetAttributeMethodName(ulong hash)
2743
return string.Empty;
2844
}
2945

30-
internal static void RegisterMessageAttributeName(string name)
46+
internal static void RegisterMessageAttributeName(string name, AttributeMessageMode mode)
3147
{
3248
if (messageAttributeHashes.ContainsKey(name))
3349
return;
3450

35-
ulong value = PrimitiveHasher.GetULongHash(name);
51+
ulong value = 0;
52+
switch (mode)
53+
{
54+
case AttributeMessageMode.WovenTwoByte:
55+
value = PrimitiveHasher.GetUShortHash(name);
56+
break;
57+
case AttributeMessageMode.WovenFourByte:
58+
value = PrimitiveHasher.GetUIntHash(name);
59+
break;
60+
case AttributeMessageMode.WovenEightByte:
61+
value = PrimitiveHasher.GetULongHash(name);
62+
break;
63+
case AttributeMessageMode.Disabled:
64+
value = 0;
65+
break;
66+
}
67+
3668
messageAttributeHashes.Add(name, value);
3769
messageAttributeNames.Add(value, name);
3870
}

MLAPI/Data/NetworkConfig.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ public class NetworkConfig
137137
/// If your logic uses the NetwokrTime, this should probably be turned off. If however it's needed to maximize accuracy, this is recommended to be turned on
138138
/// </summary>
139139
public bool EnableTimeResync = false;
140+
/// <summary>
141+
/// Decides how many bytes to use for Attribute messaging. Leave this to 2 bytes unless you are facing hash collisions
142+
/// </summary>
143+
public AttributeMessageMode AttributeMessageMode = AttributeMessageMode.Disabled;
140144

141145
internal string ToBase64()
142146
{
@@ -190,6 +194,7 @@ internal string ToBase64()
190194
writer.WriteBool(AllowPassthroughMessages);
191195
writer.WriteBool(EnableSceneSwitching);
192196
writer.WriteBool(EnableTimeResync);
197+
writer.WriteBits((byte)AttributeMessageMode, 3);
193198

194199
return Convert.ToBase64String(writer.Finalize());
195200
}
@@ -270,6 +275,7 @@ internal void FromBase64(string base64)
270275
AllowPassthroughMessages = reader.ReadBool();
271276
EnableSceneSwitching = reader.ReadBool();
272277
EnableTimeResync = reader.ReadBool();
278+
AttributeMessageMode = (AttributeMessageMode)reader.ReadBits(3);
273279
}
274280
}
275281

@@ -319,17 +325,15 @@ public byte[] GetConfig(bool cache = true)
319325
writer.WriteBool(AllowPassthroughMessages);
320326
writer.WriteBool(EnableSceneSwitching);
321327
writer.WriteBool(SignKeyExchange);
328+
writer.WriteBits((byte)AttributeMessageMode, 3);
322329

323-
//using (SHA256Managed sha256 = new SHA256Managed())
324-
//{
325-
// Returns a 160 bit / 20 byte / 5 int checksum of the config
326-
if (cache)
327-
{
328-
ConfigHash = MessageDigest.SHA1_Opt(writer.Finalize()).ToArray(); //sha256.ComputeHash(writer.Finalize());
329-
return ConfigHash;
330-
}
331-
return MessageDigest.SHA1_Opt(writer.Finalize()).ToArray(); //sha256.ComputeHash(writer.Finalize());
332-
//}
330+
// Returns a 160 bit / 20 byte / 5 int checksum of the config
331+
if (cache)
332+
{
333+
ConfigHash = MessageDigest.SHA1_Opt(writer.Finalize()).ToArray();
334+
return ConfigHash;
335+
}
336+
return MessageDigest.SHA1_Opt(writer.Finalize()).ToArray();
333337
}
334338
}
335339

MLAPI/MLAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<Compile Include="Attributes\TargetRpc.cs" />
7676
<Compile Include="Data\Cache.cs" />
7777
<Compile Include="Data\Channel.cs" />
78+
<Compile Include="Data\AttributeMessageMode.cs" />
7879
<Compile Include="Data\Transports\ChannelType.cs" />
7980
<Compile Include="Data\FieldType.cs" />
8081
<Compile Include="Attributes\SyncedVar.cs" />

MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ public virtual void OnLostOwnership()
141141
}
142142

143143
internal Dictionary<string, MethodInfo> cachedMethods = new Dictionary<string, MethodInfo>();
144+
internal Dictionary<string, string> messageChannelName = new Dictionary<string, string>();
144145

145146
/// <summary>
146147
/// Called when a new client connects
@@ -183,15 +184,24 @@ public virtual void OnSetLocalVisibility(bool visible)
183184

184185
private void CacheAttributedMethods()
185186
{
187+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
188+
return;
189+
186190
MethodInfo[] methods = GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
187191
for (int i = 0; i < methods.Length; i++)
188192
{
189193
if (methods[i].IsDefined(typeof(Command), true) || methods[i].IsDefined(typeof(ClientRpc), true) || methods[i].IsDefined(typeof(TargetRpc), true))
190194
{
191-
Data.Cache.RegisterMessageAttributeName(methods[i].Name);
195+
Data.Cache.RegisterMessageAttributeName(methods[i].Name, NetworkingManager.singleton.NetworkConfig.AttributeMessageMode);
192196
if (!cachedMethods.ContainsKey(methods[i].Name))
193197
cachedMethods.Add(methods[i].Name, methods[i]);
194198
}
199+
if (methods[i].IsDefined(typeof(Command), true) && !messageChannelName.ContainsKey(methods[i].Name))
200+
messageChannelName.Add(methods[i].Name, ((Command[])methods[i].GetCustomAttributes(typeof(Command), true))[0].channelName);
201+
if (methods[i].IsDefined(typeof(ClientRpc), true) && !messageChannelName.ContainsKey(methods[i].Name))
202+
messageChannelName.Add(methods[i].Name, ((ClientRpc[])methods[i].GetCustomAttributes(typeof(ClientRpc), true))[0].channelName);
203+
if (methods[i].IsDefined(typeof(TargetRpc), true) && !messageChannelName.ContainsKey(methods[i].Name))
204+
messageChannelName.Add(methods[i].Name, ((TargetRpc[])methods[i].GetCustomAttributes(typeof(TargetRpc), true))[0].channelName);
195205
}
196206
}
197207

@@ -217,8 +227,13 @@ protected void InvokeCommand(string methodName, params object[] methodParams)
217227
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid Command name. Command methods have to start with Cmd");
218228
return;
219229
}
230+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
231+
{
232+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Calling InvokeCommand is not allowed when AttributeMessageMode is set to disabled");
233+
return;
234+
}
220235

221-
ulong hash = Data.Cache.GetMessageAttributeHash(methodName);
236+
ulong hash = Data.Cache.GetMessageAttributeHash(methodName, NetworkingManager.singleton.NetworkConfig.AttributeMessageMode);
222237
using (BitWriter writer = BitWriter.Get())
223238
{
224239
writer.WriteUInt(networkId);
@@ -232,7 +247,7 @@ protected void InvokeCommand(string methodName, params object[] methodParams)
232247
FieldTypeHelper.WriteFieldType(writer, methodParams[i], fieldType);
233248
}
234249

235-
InternalMessageHandler.Send(NetworkingManager.singleton.NetworkConfig.NetworkTransport.ServerNetId, "MLAPI_COMMAND", "MLAPI_INTERNAL", writer, null);
250+
InternalMessageHandler.Send(NetworkingManager.singleton.NetworkConfig.NetworkTransport.ServerNetId, "MLAPI_COMMAND", messageChannelName[methodName], writer, null);
236251
}
237252
}
238253

@@ -253,8 +268,13 @@ protected void InvokeClientRpc(string methodName, params object[] methodParams)
253268
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid Command name. Command methods have to start with Cmd");
254269
return;
255270
}
271+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
272+
{
273+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Calling InvokeClientRpc is not allowed when AttributeMessageMode is set to disabled");
274+
return;
275+
}
256276

257-
ulong hash = Data.Cache.GetMessageAttributeHash(methodName);
277+
ulong hash = Data.Cache.GetMessageAttributeHash(methodName, NetworkingManager.singleton.NetworkConfig.AttributeMessageMode);
258278
using (BitWriter writer = BitWriter.Get())
259279
{
260280
writer.WriteUInt(networkId);
@@ -268,7 +288,7 @@ protected void InvokeClientRpc(string methodName, params object[] methodParams)
268288
writer.WriteBits((byte)fieldType, 5);
269289
FieldTypeHelper.WriteFieldType(writer, methodParams[i], fieldType);
270290
}
271-
InternalMessageHandler.Send("MLAPI_RPC", "MLAPI_INTERNAL", writer, networkId);
291+
InternalMessageHandler.Send("MLAPI_RPC", messageChannelName[methodName], writer, networkId);
272292
}
273293
}
274294

@@ -289,8 +309,13 @@ protected void InvokeTargetRpc(string methodName, params object[] methodParams)
289309
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Invalid Command name. Command methods have to start with Cmd");
290310
return;
291311
}
312+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
313+
{
314+
if (LogHelper.CurrentLogLevel <= LogLevel.Normal) LogHelper.LogWarning("Calling InvokeTargetRpc is not allowed when AttributeMessageMode is set to disabled");
315+
return;
316+
}
292317

293-
ulong hash = Data.Cache.GetMessageAttributeHash(methodName);
318+
ulong hash = Data.Cache.GetMessageAttributeHash(methodName, NetworkingManager.singleton.NetworkConfig.AttributeMessageMode);
294319
using (BitWriter writer = BitWriter.Get())
295320
{
296321
writer.WriteUInt(networkId);
@@ -303,7 +328,7 @@ protected void InvokeTargetRpc(string methodName, params object[] methodParams)
303328
writer.WriteBits((byte)fieldType, 5);
304329
FieldTypeHelper.WriteFieldType(writer, methodParams[i], fieldType);
305330
}
306-
InternalMessageHandler.Send(ownerClientId, "MLAPI_RPC", "MLAPI_INTERNAL", writer, networkId);
331+
InternalMessageHandler.Send(ownerClientId, "MLAPI_RPC", messageChannelName[methodName], writer, networkId);
307332
}
308333
}
309334

MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ internal static void HandleTimeSync(uint clientId, BitReader reader, int channel
370370

371371
internal static void HandleCommand(uint clientId, BitReader reader, int channelId)
372372
{
373+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
374+
return;
375+
373376
uint networkId = reader.ReadUInt();
374377
ushort orderId = reader.ReadUShort();
375378
ulong hash = reader.ReadULong();
@@ -386,6 +389,9 @@ internal static void HandleCommand(uint clientId, BitReader reader, int channelI
386389

387390
internal static void HandleRpc(uint clientId, BitReader reader, int channelId)
388391
{
392+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
393+
return;
394+
389395
uint networkId = reader.ReadUInt();
390396
ushort orderId = reader.ReadUShort();
391397
ulong hash = reader.ReadULong();
@@ -400,6 +406,9 @@ internal static void HandleRpc(uint clientId, BitReader reader, int channelId)
400406

401407
internal static void HandleTargetRpc(uint clientId, BitReader reader, int channelId)
402408
{
409+
if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled)
410+
return;
411+
403412
uint networkId = reader.ReadUInt();
404413
ushort orderId = reader.ReadUShort();
405414
ulong hash = reader.ReadULong();

0 commit comments

Comments
 (0)