2022-01-13 20:52:04 -08:00
using Mirror ;
using OWML.Common ;
2021-12-11 00:15:59 -08:00
using QSB.ClientServerStateSync ;
2021-12-23 13:57:33 -08:00
using QSB.ClientServerStateSync.Messages ;
2021-12-10 23:28:42 -08:00
using QSB.Player ;
2021-12-23 13:49:47 -08:00
using QSB.Player.Messages ;
2021-12-11 00:15:59 -08:00
using QSB.Player.TransformSync ;
2021-12-10 23:28:42 -08:00
using QSB.Utility ;
using QSB.WorldSync ;
using QuantumUNET ;
using QuantumUNET.Components ;
using QuantumUNET.Messages ;
2021-12-23 17:07:29 -08:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2022-01-13 20:52:04 -08:00
using System.Reflection ;
2021-12-23 17:07:29 -08:00
using System.Runtime.CompilerServices ;
2021-12-26 18:57:07 -08:00
using System.Runtime.Serialization ;
2021-12-10 23:28:42 -08:00
namespace QSB.Messaging
{
public static class QSBMessageManager
{
#region inner workings
2022-01-13 20:52:04 -08:00
private static readonly Type [ ] _types ;
2021-12-10 23:28:42 -08:00
static QSBMessageManager ( )
{
2022-01-13 20:52:04 -08:00
_types = typeof ( QSBMessageRaw ) . GetDerivedTypes ( )
2021-12-21 12:38:43 -08:00
. Concat ( typeof ( QSBMessage ) . GetDerivedTypes ( ) )
. ToArray ( ) ;
2022-01-13 20:52:04 -08:00
foreach ( var type in _types )
2021-12-10 23:28:42 -08:00
{
2021-12-23 13:06:18 -08:00
// call static constructor of message if needed
2022-01-13 20:52:04 -08:00
RuntimeHelpers . RunClassConstructor ( type . TypeHandle ) ;
2021-12-10 23:28:42 -08:00
}
}
public static void Init ( )
{
2022-01-13 20:52:04 -08:00
DebugLog . DebugWrite ( "REGISTERING MESSAGES" ) ;
var NetworkServer_RegisterHandlerSafe = typeof ( NetworkServer ) . GetMethod ( nameof ( NetworkServer . RegisterHandlerSafe ) ) ;
var NetworkClient_RegisterHandlerSafe = typeof ( NetworkClient ) . GetMethod ( nameof ( NetworkClient . RegisterHandlerSafe ) ) ;
var OnServerReceiveRaw = typeof ( QSBMessageManager ) . GetMethod ( nameof ( QSBMessageManager . OnServerReceiveRaw ) ) ;
var OnClientReceiveRaw = typeof ( QSBMessageManager ) . GetMethod ( nameof ( QSBMessageManager . OnClientReceiveRaw ) ) ;
var OnServerReceive = typeof ( QSBMessageManager ) . GetMethod ( nameof ( QSBMessageManager . OnServerReceive ) ) ;
var OnClientReceive = typeof ( QSBMessageManager ) . GetMethod ( nameof ( QSBMessageManager . OnClientReceive ) ) ;
foreach ( var type in _types )
2021-12-10 23:28:42 -08:00
{
2022-01-13 20:52:04 -08:00
MethodInfo OnServerReceive2 ;
MethodInfo OnClientReceive2 ;
2021-12-21 12:38:43 -08:00
if ( typeof ( QSBMessageRaw ) . IsAssignableFrom ( type ) )
{
2022-01-13 20:52:04 -08:00
OnServerReceive2 = OnServerReceiveRaw ;
OnClientReceive2 = OnClientReceiveRaw ;
2021-12-21 12:38:43 -08:00
}
else
{
2022-01-13 20:52:04 -08:00
OnServerReceive2 = OnServerReceive ;
OnClientReceive2 = OnClientReceive ;
2021-12-21 12:38:43 -08:00
}
2022-01-13 20:52:04 -08:00
var serverHandler = OnServerReceive2 . MakeGenericMethod ( type ) . CreateDelegate ( typeof ( Action < > ) ) ;
var clientHandler = OnClientReceive2 . MakeGenericMethod ( type ) . CreateDelegate ( typeof ( Action < > ) ) ;
DebugLog . DebugWrite ( $"server handler = {serverHandler}" ) ;
DebugLog . DebugWrite ( $"client handler = {clientHandler}" ) ;
NetworkServer_RegisterHandlerSafe . MakeGenericMethod ( type ) . Invoke ( null , new object [ ] { serverHandler } ) ;
NetworkClient_RegisterHandlerSafe . MakeGenericMethod ( type ) . Invoke ( null , new object [ ] { clientHandler } ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-01-13 20:52:04 -08:00
private static void OnServerReceiveRaw < T > ( T msg )
where T : QSBMessageRaw
2021-12-21 12:38:43 -08:00
{
2022-01-13 20:52:04 -08:00
NetworkServer . SendToAll ( msg ) ;
2021-12-21 12:38:43 -08:00
}
2022-01-13 20:52:04 -08:00
private static void OnClientReceiveRaw < T > ( T msg )
where T : QSBMessageRaw
2021-12-10 23:28:42 -08:00
{
2021-12-21 12:38:43 -08:00
msg . OnReceive ( ) ;
}
2022-01-13 20:52:04 -08:00
private static void OnServerReceive < T > ( T msg )
where T : QSBMessage
2021-12-21 12:38:43 -08:00
{
if ( msg . To = = uint . MaxValue )
2021-12-10 23:28:42 -08:00
{
2022-01-13 20:52:04 -08:00
NetworkServer . SendToAll ( msg ) ;
2021-12-21 12:38:43 -08:00
}
else if ( msg . To = = 0 )
{
2022-01-13 20:52:04 -08:00
NetworkServer . localConnection . Send ( msg ) ;
2021-12-10 23:28:42 -08:00
}
else
{
2022-01-13 20:52:04 -08:00
var conn = NetworkServer . connections . Values . FirstOrDefault ( x = > msg . To = = x . identity . netId ) ;
2021-12-21 12:38:43 -08:00
if ( conn = = null )
{
DebugLog . ToConsole ( $"SendTo unknown player! id: {msg.To}, message: {msg}" , MessageType . Error ) ;
return ;
}
2022-01-01 22:19:10 +00:00
2022-01-13 20:52:04 -08:00
conn . Send ( msg ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-01-13 20:52:04 -08:00
private static void OnClientReceive < T > ( T msg )
where T : QSBMessage
2021-12-10 23:28:42 -08:00
{
2021-12-11 18:40:20 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
2021-12-10 23:28:42 -08:00
{
2021-12-20 16:35:12 -08:00
DebugLog . ToConsole ( $"Warning - Tried to handle message {msg} before local player was established." , MessageType . Warning ) ;
2021-12-11 18:40:20 -08:00
return ;
}
2021-12-21 12:38:43 -08:00
if ( QSBPlayerManager . PlayerExists ( msg . From ) )
2021-12-11 18:40:20 -08:00
{
2021-12-21 12:38:43 -08:00
var player = QSBPlayerManager . GetPlayer ( msg . From ) ;
if ( ! player . IsReady
2021-12-26 18:57:07 -08:00
& & player . PlayerId ! = QSBPlayerManager . LocalPlayerId
& & player . State is ClientState . AliveInSolarSystem or ClientState . AliveInEye or ClientState . DeadInSolarSystem
& & msg is not ( PlayerInformationMessage or PlayerReadyMessage or RequestStateResyncMessage or ServerStateMessage ) )
2021-12-11 00:15:59 -08:00
{
2021-12-21 12:38:43 -08:00
DebugLog . ToConsole ( $"Warning - Got message {msg} from player {msg.From}, but they were not ready. Asking for state resync, just in case." , MessageType . Warning ) ;
2021-12-22 18:20:53 -08:00
new RequestStateResyncMessage ( ) . Send ( ) ;
2021-12-11 00:15:59 -08:00
}
2021-12-11 18:40:20 -08:00
}
2021-12-11 00:15:59 -08:00
2021-12-11 18:40:20 -08:00
try
{
2021-12-21 12:38:43 -08:00
if ( ! msg . ShouldReceive )
{
return ;
}
if ( msg . From ! = QSBPlayerManager . LocalPlayerId )
{
msg . OnReceiveRemote ( ) ;
}
else
{
msg . OnReceiveLocal ( ) ;
}
2021-12-10 23:28:42 -08:00
}
catch ( Exception ex )
{
2021-12-11 19:02:34 -08:00
DebugLog . ToConsole ( $"Error - Exception handling message {msg} : {ex}" , MessageType . Error ) ;
2021-12-10 23:28:42 -08:00
}
}
#endregion
2021-12-21 12:38:43 -08:00
public static void SendRaw < M > ( this M msg )
2021-12-26 18:57:07 -08:00
where M : QSBMessageRaw
2021-12-21 12:38:43 -08:00
{
2022-01-13 20:52:04 -08:00
NetworkClient . Send ( msg ) ;
2021-12-21 12:38:43 -08:00
}
2022-01-13 20:52:04 -08:00
public static void ServerSendRaw < M > ( this M msg , NetworkConnectionToClient conn )
2021-12-26 18:57:07 -08:00
where M : QSBMessageRaw
2021-12-22 14:32:11 -08:00
{
2022-01-13 20:52:04 -08:00
conn . Send ( msg ) ;
2021-12-22 14:32:11 -08:00
}
2021-12-21 12:38:43 -08:00
public static void Send < M > ( this M msg )
2021-12-26 18:57:07 -08:00
where M : QSBMessage
2021-12-10 23:28:42 -08:00
{
2021-12-20 16:35:12 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
2021-12-11 19:02:34 -08:00
{
2021-12-20 16:35:12 -08:00
DebugLog . ToConsole ( $"Warning - Tried to send message {msg} before local player was established." , MessageType . Warning ) ;
2021-12-11 19:02:34 -08:00
return ;
}
2021-12-21 12:38:43 -08:00
msg . From = QSBPlayerManager . LocalPlayerId ;
2022-01-13 20:52:04 -08:00
NetworkClient . Send ( msg ) ;
2021-12-10 23:28:42 -08:00
}
2021-12-20 15:39:50 -08:00
public static void SendMessage < T , M > ( this T worldObject , M msg )
2021-12-10 23:28:42 -08:00
where T : IWorldObject
2021-12-26 18:57:07 -08:00
where M : QSBWorldObjectMessage < T >
2021-12-10 23:28:42 -08:00
{
2021-12-20 15:39:50 -08:00
msg . ObjectId = worldObject . ObjectId ;
Send ( msg ) ;
2021-12-10 23:28:42 -08:00
}
}
2021-12-20 16:35:12 -08:00
/// <summary>
2021-12-21 12:38:43 -08:00
/// message that will be sent to every client. <br/>
/// no checks are performed on the message. it is just sent and received.
2021-12-20 16:35:12 -08:00
/// </summary>
2022-01-13 20:52:04 -08:00
public abstract class QSBMessageRaw : NetworkMessage
2021-12-20 16:35:12 -08:00
{
public abstract void OnReceive ( ) ;
public override string ToString ( ) = > GetType ( ) . Name ;
}
2021-12-10 23:28:42 -08:00
}