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
namespace QSB.Messaging
{
public static class QSBMessageManager
{
#region inner workings
2022-01-14 02:29:42 -08:00
internal static readonly Type [ ] _types ;
2022-01-21 21:36:33 -08:00
internal static readonly Dictionary < Type , ushort > _typeToId = new ( ) ;
2021-12-10 23:28:42 -08:00
static QSBMessageManager ( )
{
2022-01-14 02:29:42 -08:00
_types = typeof ( QSBMessage ) . GetDerivedTypes ( ) . ToArray ( ) ;
for ( ushort i = 0 ; i < _types . Length ; i + + )
2021-12-10 23:28:42 -08:00
{
2022-01-14 02:29:42 -08:00
_typeToId . Add ( _types [ i ] , i ) ;
2021-12-23 13:06:18 -08:00
// call static constructor of message if needed
2022-01-14 02:29:42 -08:00
RuntimeHelpers . RunClassConstructor ( _types [ i ] . TypeHandle ) ;
2021-12-10 23:28:42 -08:00
}
}
public static void Init ( )
{
2022-01-14 02:29:42 -08:00
NetworkServer . RegisterHandler < Wrapper > ( ( _ , wrapper ) = > OnServerReceive ( wrapper ) ) ;
2022-01-21 21:36:33 -08:00
NetworkClient . RegisterHandler < Wrapper > ( wrapper = > OnClientReceive ( wrapper ) ) ;
2021-12-21 12:38:43 -08:00
}
2022-01-21 21:36:33 -08:00
private static void OnServerReceive ( QSBMessage msg )
2021-12-21 12:38:43 -08:00
{
if ( msg . To = = uint . MaxValue )
2021-12-10 23:28:42 -08:00
{
2022-01-21 21:36:33 -08:00
NetworkServer . SendToAll < Wrapper > ( msg ) ;
2021-12-21 12:38:43 -08:00
}
else if ( msg . To = = 0 )
{
2022-01-21 21:36:33 -08:00
NetworkServer . localConnection . Send < Wrapper > ( msg ) ;
2021-12-10 23:28:42 -08:00
}
else
{
2022-01-14 21:18:05 -08:00
var conn = NetworkServer . connections . Values . FirstOrDefault ( x = > msg . To = = x . GetPlayerId ( ) ) ;
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-21 21:36:33 -08:00
conn . Send < Wrapper > ( msg ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-01-14 02:29:42 -08:00
private static void OnClientReceive ( QSBMessage msg )
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 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-21 21:36:33 -08:00
NetworkClient . Send < Wrapper > ( 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
2022-01-14 02:29:42 -08:00
internal struct Wrapper : NetworkMessage
2021-12-20 16:35:12 -08:00
{
2022-01-21 21:36:33 -08:00
public QSBMessage Msg ;
public static implicit operator QSBMessage ( Wrapper wrapper ) = > wrapper . Msg ;
public static implicit operator Wrapper ( QSBMessage msg ) = > new ( ) { Msg = msg } ;
2022-01-14 02:29:42 -08:00
}
2022-01-13 22:38:53 -08:00
2022-01-14 02:29:42 -08:00
internal static class ReaderWriterExtensions
{
2022-01-21 21:36:33 -08:00
private static QSBMessage ReadQSBMessage ( this NetworkReader reader )
2022-01-14 02:29:42 -08:00
{
2022-01-21 21:36:33 -08:00
var id = reader . ReadUShort ( ) ;
var type = QSBMessageManager . _types [ id ] ;
var msg = ( QSBMessage ) FormatterServices . GetUninitializedObject ( type ) ;
msg . Deserialize ( reader ) ;
return msg ;
2022-01-14 02:29:42 -08:00
}
2022-01-21 21:36:33 -08:00
private static void WriteQSBMessage ( this NetworkWriter writer , QSBMessage msg )
2022-01-14 02:29:42 -08:00
{
2022-01-21 21:36:33 -08:00
var type = msg . GetType ( ) ;
var id = QSBMessageManager . _typeToId [ type ] ;
writer . Write ( id ) ;
msg . Serialize ( writer ) ;
2022-01-14 02:29:42 -08:00
}
2021-12-20 16:35:12 -08:00
}
2021-12-10 23:28:42 -08:00
}