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 ;
2021-12-23 17:07:29 -08:00
using System ;
2022-01-14 02:29:42 -08:00
using System.Collections.Generic ;
2021-12-23 17:07:29 -08:00
using System.Linq ;
using System.Runtime.CompilerServices ;
2022-01-14 02:29:42 -08:00
using System.Runtime.Serialization ;
2021-12-10 23:28:42 -08:00
2022-02-27 04:40:44 -08:00
namespace QSB.Messaging
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
public static class QSBMessageManager
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
#region inner workings
2021-12-10 23:28:42 -08:00
2022-02-27 04:40:44 -08:00
internal static readonly Type [ ] _types ;
internal static readonly Dictionary < Type , ushort > _typeToId = new ( ) ;
2021-12-10 23:28:42 -08:00
2022-02-27 04:40:44 -08:00
static QSBMessageManager ( )
2022-02-24 22:04:54 -08:00
{
2022-02-27 04:40:44 -08:00
_types = typeof ( QSBMessage ) . GetDerivedTypes ( ) . ToArray ( ) ;
for ( ushort i = 0 ; i < _types . Length ; i + + )
{
_typeToId . Add ( _types [ i ] , i ) ;
// call static constructor of message if needed
RuntimeHelpers . RunClassConstructor ( _types [ i ] . TypeHandle ) ;
}
2022-02-24 22:04:54 -08:00
}
2021-12-10 23:28:42 -08:00
2022-02-27 04:40:44 -08:00
public static void Init ( )
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
NetworkServer . RegisterHandler < Wrapper > ( ( _ , wrapper ) = > OnServerReceive ( wrapper ) ) ;
NetworkClient . RegisterHandler < Wrapper > ( wrapper = > OnClientReceive ( wrapper ) ) ;
2021-12-21 12:38:43 -08:00
}
2022-02-27 04:40:44 -08:00
private static void OnServerReceive ( QSBMessage msg )
2021-12-21 12:38:43 -08:00
{
2022-02-27 04:40:44 -08:00
if ( msg . To = = uint . MaxValue )
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
NetworkServer . SendToAll < Wrapper > ( msg ) ;
}
else if ( msg . To = = 0 )
{
NetworkServer . localConnection . Send < Wrapper > ( msg ) ;
}
else
{
msg . To . GetNetworkConnection ( ) . Send < Wrapper > ( msg ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-02-27 04:40:44 -08:00
private static void OnClientReceive ( QSBMessage msg )
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -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 ;
}
2022-02-27 04:40:44 -08:00
if ( QSBPlayerManager . PlayerExists ( msg . From ) )
2021-12-11 18:40:20 -08:00
{
2022-02-27 04:40:44 -08:00
var player = QSBPlayerManager . GetPlayer ( msg . From ) ;
if ( ! player . IsReady
& & 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 ) )
{
DebugLog . ToConsole ( $"Warning - Got message {msg} from player {msg.From}, but they were not ready. Asking for state resync, just in case." , MessageType . Warning ) ;
new RequestStateResyncMessage ( ) . Send ( ) ;
}
2021-12-10 23:28:42 -08:00
}
2022-02-27 04:40:44 -08:00
try
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
if ( ! msg . ShouldReceive )
{
return ;
}
if ( msg . From ! = QSBPlayerManager . LocalPlayerId )
{
msg . OnReceiveRemote ( ) ;
}
else
{
msg . OnReceiveLocal ( ) ;
}
}
catch ( Exception ex )
{
DebugLog . ToConsole ( $"Error - Exception handling message {msg} : {ex}" , MessageType . Error ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-02-24 22:04:54 -08:00
2022-02-27 04:40:44 -08:00
#endregion
2021-12-10 23:28:42 -08:00
2022-02-27 04:40:44 -08:00
public static void Send < M > ( this M msg )
where M : QSBMessage
2021-12-10 23:28:42 -08:00
{
2022-02-27 04:40:44 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
{
DebugLog . ToConsole ( $"Warning - Tried to send message {msg} before local player was established." , MessageType . Warning ) ;
return ;
}
msg . From = QSBPlayerManager . LocalPlayerId ;
NetworkClient . Send < Wrapper > ( msg ) ;
2021-12-10 23:28:42 -08:00
}
2022-02-24 22:04:54 -08:00
2022-02-27 04:40:44 -08:00
public static void SendMessage < T , M > ( this T worldObject , M msg )
where T : IWorldObject
where M : QSBWorldObjectMessage < T >
{
msg . ObjectId = worldObject . ObjectId ;
Send ( msg ) ;
}
2021-12-10 23:28:42 -08:00
}
2021-12-20 16:35:12 -08:00
2022-02-27 04:40:44 -08:00
internal struct Wrapper : NetworkMessage
2021-12-20 16:35:12 -08:00
{
2022-02-27 04:40:44 -08:00
public QSBMessage Msg ;
2022-02-24 22:04:54 -08:00
2022-02-27 04:40:44 -08:00
public static implicit operator QSBMessage ( Wrapper wrapper ) = > wrapper . Msg ;
public static implicit operator Wrapper ( QSBMessage msg ) = > new ( ) { Msg = msg } ;
2022-02-24 22:04:54 -08:00
}
2022-01-14 02:29:42 -08:00
2022-02-27 04:40:44 -08:00
internal static class ReaderWriterExtensions
2022-02-24 22:04:54 -08:00
{
2022-02-27 04:40:44 -08:00
private static QSBMessage ReadQSBMessage ( this NetworkReader reader )
{
var id = reader . ReadUShort ( ) ;
var type = QSBMessageManager . _types [ id ] ;
var msg = ( QSBMessage ) FormatterServices . GetUninitializedObject ( type ) ;
msg . Deserialize ( reader ) ;
return msg ;
}
private static void WriteQSBMessage ( this NetworkWriter writer , QSBMessage msg )
{
var type = msg . GetType ( ) ;
var id = QSBMessageManager . _typeToId [ type ] ;
writer . Write ( id ) ;
msg . Serialize ( writer ) ;
}
2021-12-20 16:35:12 -08:00
}
2022-02-24 22:04:54 -08:00
}