Force NetworkMessage as struct everywhere

This commit is contained in:
vis2k 2020-09-29 10:25:22 +02:00
parent 6baaa1d75e
commit 5e2a968abb
5 changed files with 49 additions and 27 deletions

View File

@ -14,7 +14,7 @@ public void SetHostname(string hostname)
public ChatWindow chatWindow;
public class CreatePlayerMessage : NetworkMessage
public struct CreatePlayerMessage : NetworkMessage
{
public string name;

View File

@ -16,7 +16,8 @@ namespace Mirror
// (probably even shorter)
public static class MessagePacker
{
public static int GetId<T>() where T : NetworkMessage
public static int GetId<T>()
where T : struct, NetworkMessage
{
return GetId(typeof(T));
}
@ -32,13 +33,14 @@ public static int GetId(Type type)
// pack message before sending
// -> NetworkWriter passed as arg so that we can use .ToArraySegment
// and do an allocation free send before recycling it.
public static void Pack<T>(T message, NetworkWriter writer) where T : NetworkMessage
public static void Pack<T>(T message, NetworkWriter writer)
where T : struct, NetworkMessage
{
// if it is a value type, just use typeof(T) to avoid boxing
// this works because value types cannot be derived
// if it is a reference type (for example IMessageBase),
// ask the message for the real type
int msgType = GetId(default(T) != null ? typeof(T) : message.GetType());
int msgType = GetId(typeof(T));
writer.WriteUInt16((ushort)msgType);
// serialize message into writer
@ -46,7 +48,8 @@ public static void Pack<T>(T message, NetworkWriter writer) where T : NetworkMes
}
// unpack a message we received
public static T Unpack<T>(byte[] data) where T : NetworkMessage, new()
public static T Unpack<T>(byte[] data)
where T : struct, NetworkMessage
{
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(data))
{
@ -83,7 +86,7 @@ public static bool UnpackMessage(NetworkReader messageReader, out int msgType)
}
internal static NetworkMessageDelegate MessageHandler<T, C>(Action<C, T> handler, bool requireAuthenication)
where T : NetworkMessage, new()
where T : struct, NetworkMessage
where C : NetworkConnection
=> (conn, reader, channelId) =>
{
@ -112,7 +115,7 @@ internal static NetworkMessageDelegate MessageHandler<T, C>(Action<C, T> handler
// if it is a value type, just use defult(T)
// otherwise allocate a new instance
message = default(T) != null ? default(T) : new T();
message = default(T);
message.Deserialize(reader);
}
catch (Exception exception)

View File

@ -172,7 +172,8 @@ static void RemoveTransportHandlers()
/// <param name="message"></param>
/// <param name="channelId"></param>
/// <returns>True if message was sent.</returns>
public static bool Send<T>(T message, int channelId = Channels.DefaultReliable) where T : NetworkMessage
public static bool Send<T>(T message, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
if (connection != null)
{
@ -215,7 +216,8 @@ internal static void RegisterSystemHandlers()
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void RegisterHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void RegisterHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
int msgType = MessagePacker.GetId<T>();
if (handlers.ContainsKey(msgType))
@ -232,7 +234,8 @@ internal static void RegisterSystemHandlers()
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void RegisterHandler<T>(Action<T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void RegisterHandler<T>(Action<T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
RegisterHandler((NetworkConnection _, T value) => { handler(value); }, requireAuthentication);
}
@ -244,7 +247,8 @@ internal static void RegisterSystemHandlers()
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
int msgType = MessagePacker.GetId<T>();
handlers[msgType] = MessagePacker.MessageHandler(handler, requireAuthentication);
@ -257,7 +261,8 @@ internal static void RegisterSystemHandlers()
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void ReplaceHandler<T>(Action<T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void ReplaceHandler<T>(Action<T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
ReplaceHandler((NetworkConnection _, T value) => { handler(value); }, requireAuthentication);
}
@ -266,7 +271,8 @@ internal static void RegisterSystemHandlers()
/// Unregisters a network message handler.
/// </summary>
/// <typeparam name="T">The message type to unregister.</typeparam>
public static bool UnregisterHandler<T>() where T : NetworkMessage
public static bool UnregisterHandler<T>()
where T : struct, NetworkMessage
{
// use int to minimize collisions
int msgType = MessagePacker.GetId<T>();

View File

@ -132,7 +132,8 @@ internal void SetHandlers(Dictionary<int, NetworkMessageDelegate> handlers)
/// <param name="msg">The message to send.</param>
/// <param name="channelId">The transport layer channel to send on.</param>
/// <returns></returns>
public bool Send<T>(T msg, int channelId = Channels.DefaultReliable) where T : NetworkMessage
public bool Send<T>(T msg, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
@ -221,7 +222,8 @@ internal bool InvokeHandler(int msgType, NetworkReader reader, int channelId)
/// <typeparam name="T">The message type to unregister.</typeparam>
/// <param name="msg">The message object to process.</param>
/// <returns>Returns true if the handler was successfully invoked</returns>
public bool InvokeHandler<T>(T msg, int channelId) where T : NetworkMessage
public bool InvokeHandler<T>(T msg, int channelId)
where T : struct, NetworkMessage
{
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
@ -229,7 +231,7 @@ public bool InvokeHandler<T>(T msg, int channelId) where T : NetworkMessage
// this works because value types cannot be derived
// if it is a reference type (for example IMessageBase),
// ask the message for the real type
int msgType = MessagePacker.GetId(default(T) != null ? typeof(T) : msg.GetType());
int msgType = MessagePacker.GetId(typeof(T));
MessagePacker.Pack(msg, writer);
ArraySegment<byte> segment = writer.ToArraySegment();

View File

@ -199,7 +199,8 @@ public static bool RemoveConnection(int connectionId)
/// <param name="identity"></param>
/// <param name="msg"></param>
/// <param name="channelId"></param>
static void SendToObservers<T>(NetworkIdentity identity, T msg, int channelId = Channels.DefaultReliable) where T : NetworkMessage
static void SendToObservers<T>(NetworkIdentity identity, T msg, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
// Debug.Log("Server.SendToObservers id:" + typeof(T));
@ -238,7 +239,8 @@ static void SendToObservers<T>(NetworkIdentity identity, T msg, int channelId =
/// <param name="channelId">Transport channel to use</param>
/// <param name="sendToReadyOnly">Indicates if only ready clients should receive the message</param>
/// <returns></returns>
public static bool SendToAll<T>(T msg, int channelId = Channels.DefaultReliable, bool sendToReadyOnly = false) where T : NetworkMessage
public static bool SendToAll<T>(T msg, int channelId = Channels.DefaultReliable, bool sendToReadyOnly = false)
where T : struct, NetworkMessage
{
if (!active)
{
@ -285,7 +287,8 @@ public static bool SendToAll<T>(T msg, int channelId = Channels.DefaultReliable,
/// <param name="msg">Message</param>
/// <param name="channelId">Transport channel to use</param>
/// <returns></returns>
public static bool SendToReady<T>(T msg, int channelId = Channels.DefaultReliable) where T : NetworkMessage
public static bool SendToReady<T>(T msg, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
if (!active)
{
@ -306,7 +309,8 @@ public static bool SendToReady<T>(T msg, int channelId = Channels.DefaultReliabl
/// <param name="includeOwner">Should the owner of the object be included</param>
/// <param name="channelId">Transport channel to use</param>
/// <returns></returns>
public static bool SendToReady<T>(NetworkIdentity identity, T msg, bool includeOwner = true, int channelId = Channels.DefaultReliable) where T : NetworkMessage
public static bool SendToReady<T>(NetworkIdentity identity, T msg, bool includeOwner = true, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
// Debug.Log("Server.SendToReady msgType:" + typeof(T));
@ -352,7 +356,8 @@ public static bool SendToReady<T>(NetworkIdentity identity, T msg, bool includeO
/// <param name="msg">Message</param>
/// <param name="channelId">Transport channel to use</param>
/// <returns></returns>
public static bool SendToReady<T>(NetworkIdentity identity, T msg, int channelId) where T : NetworkMessage
public static bool SendToReady<T>(NetworkIdentity identity, T msg, int channelId)
where T : struct, NetworkMessage
{
return SendToReady(identity, msg, true, channelId);
}
@ -525,7 +530,8 @@ static void OnError(int connectionId, Exception exception)
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void RegisterHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void RegisterHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
int msgType = MessagePacker.GetId<T>();
if (handlers.ContainsKey(msgType))
@ -542,7 +548,8 @@ static void OnError(int connectionId, Exception exception)
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void RegisterHandler<T>(Action<T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void RegisterHandler<T>(Action<T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
RegisterHandler<T>((_, value) => { handler(value); }, requireAuthentication);
}
@ -554,7 +561,8 @@ static void OnError(int connectionId, Exception exception)
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void ReplaceHandler<T>(Action<NetworkConnection, T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
int msgType = MessagePacker.GetId<T>();
handlers[msgType] = MessagePacker.MessageHandler(handler, requireAuthentication);
@ -567,7 +575,8 @@ static void OnError(int connectionId, Exception exception)
/// <typeparam name="T">Message type</typeparam>
/// <param name="handler">Function handler which will be invoked when this message type is received.</param>
/// <param name="requireAuthentication">True if the message requires an authenticated connection</param>
public static void ReplaceHandler<T>(Action<T> handler, bool requireAuthentication = true) where T : NetworkMessage, new()
public static void ReplaceHandler<T>(Action<T> handler, bool requireAuthentication = true)
where T : struct, NetworkMessage
{
ReplaceHandler<T>((_, value) => { handler(value); }, requireAuthentication);
}
@ -576,7 +585,8 @@ static void OnError(int connectionId, Exception exception)
/// Unregisters a handler for a particular message type.
/// </summary>
/// <typeparam name="T">Message type</typeparam>
public static void UnregisterHandler<T>() where T : NetworkMessage
public static void UnregisterHandler<T>()
where T : struct, NetworkMessage
{
int msgType = MessagePacker.GetId<T>();
handlers.Remove(msgType);
@ -596,7 +606,8 @@ public static void ClearHandlers()
/// <typeparam name="T">Message type</typeparam>
/// <param name="identity"></param>
/// <param name="msg"></param>
public static void SendToClientOfPlayer<T>(NetworkIdentity identity, T msg, int channelId = Channels.DefaultReliable) where T : NetworkMessage
public static void SendToClientOfPlayer<T>(NetworkIdentity identity, T msg, int channelId = Channels.DefaultReliable)
where T : struct, NetworkMessage
{
if (identity != null)
{