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 ;
2022-08-28 22:22:19 -07:00
using QSB.Patches ;
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.Runtime.CompilerServices ;
2022-01-14 02:29:42 -08:00
using System.Runtime.Serialization ;
2021-12-10 23:28:42 -08:00
2022-03-02 19:46:33 -08:00
namespace QSB.Messaging ;
public static class QSBMessageManager
2021-12-10 23:28:42 -08:00
{
2022-03-02 19:46:33 -08:00
#region inner workings
2023-08-03 14:55:21 -07:00
internal static readonly Dictionary < int , Type > _types = new ( ) ;
2022-03-02 19:46:33 -08:00
static QSBMessageManager ( )
2021-12-10 23:28:42 -08:00
{
2023-08-03 14:40:47 -07:00
foreach ( var type in typeof ( QSBMessage ) . GetDerivedTypes ( ) )
2022-03-02 19:46:33 -08:00
{
2023-08-03 14:55:21 -07:00
var hash = type . FullName . GetStableHashCode ( ) ;
_types . Add ( hash , type ) ;
2022-03-02 19:46:33 -08:00
// call static constructor of message if needed
2023-08-03 14:40:47 -07:00
RuntimeHelpers . RunClassConstructor ( type . TypeHandle ) ;
2022-03-02 19:46:33 -08:00
}
}
2021-12-10 23:28:42 -08:00
2022-03-02 19:46:33 -08:00
public static void Init ( )
{
NetworkServer . RegisterHandler < Wrapper > ( ( _ , wrapper ) = > OnServerReceive ( wrapper ) ) ;
NetworkClient . RegisterHandler < Wrapper > ( wrapper = > OnClientReceive ( wrapper ) ) ;
}
2021-12-10 23:28:42 -08:00
2022-03-02 19:46:33 -08:00
private static void OnServerReceive ( QSBMessage msg )
{
2023-08-03 14:40:47 -07:00
if ( msg = = null )
{
return ;
}
2022-03-02 19:46:33 -08:00
if ( msg . To = = uint . MaxValue )
2022-02-24 22:04:54 -08:00
{
2022-03-02 19:46:33 -08:00
NetworkServer . SendToAll < Wrapper > ( msg ) ;
}
else if ( msg . To = = 0 )
{
NetworkServer . localConnection . Send < Wrapper > ( msg ) ;
}
else
{
2023-03-08 23:16:07 +00:00
var connection = msg . To . GetNetworkConnection ( ) ;
if ( connection = = default )
{
DebugLog . ToConsole ( $"Warning - Tried to handle message from disconnected(?) player." , MessageType . Warning ) ;
return ;
}
connection . Send < Wrapper > ( msg ) ;
2022-02-24 22:04:54 -08:00
}
2022-03-02 19:46:33 -08:00
}
2021-12-10 23:28:42 -08:00
2022-03-02 19:46:33 -08:00
private static void OnClientReceive ( QSBMessage msg )
{
2023-08-08 16:29:24 -07:00
if ( msg = = null )
{
return ;
}
2022-03-02 19:46:33 -08:00
if ( PlayerTransformSync . LocalInstance = = null )
2021-12-10 23:28:42 -08:00
{
2022-03-02 19:46:33 -08:00
DebugLog . ToConsole ( $"Warning - Tried to handle message {msg} before local player was established." , MessageType . Warning ) ;
return ;
2021-12-21 12:38:43 -08:00
}
2022-03-02 19:46:33 -08:00
if ( QSBPlayerManager . PlayerExists ( msg . From ) )
2021-12-21 12:38:43 -08:00
{
2022-03-02 19:46:33 -08:00
var player = QSBPlayerManager . GetPlayer ( msg . From ) ;
if ( ! player . IsReady
2023-08-03 14:40:47 -07: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 ) )
2022-02-27 04:40:44 -08:00
{
2022-08-13 11:52:26 +01: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);
2022-03-02 19:46:33 -08:00
new RequestStateResyncMessage ( ) . Send ( ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-03-02 19:46:33 -08:00
try
2021-12-10 23:28:42 -08:00
{
2022-03-02 19:46:33 -08:00
if ( ! msg . ShouldReceive )
2021-12-10 23:28:42 -08:00
{
2021-12-11 18:40:20 -08:00
return ;
}
2022-03-02 19:46:33 -08:00
if ( msg . From ! = QSBPlayerManager . LocalPlayerId )
2021-12-10 23:28:42 -08:00
{
2022-08-28 22:22:19 -07:00
QSBPatch . Remote = true ;
2022-03-02 19:46:33 -08:00
msg . OnReceiveRemote ( ) ;
2022-08-28 22:22:19 -07:00
QSBPatch . Remote = false ;
2022-02-27 04:40:44 -08:00
}
2022-03-02 19:46:33 -08:00
else
2022-02-27 04:40:44 -08:00
{
2022-03-02 19:46:33 -08:00
msg . OnReceiveLocal ( ) ;
2021-12-10 23:28:42 -08:00
}
}
2022-03-02 19:46:33 -08:00
catch ( Exception ex )
2021-12-10 23:28:42 -08:00
{
2022-03-02 19:46:33 -08:00
DebugLog . ToConsole ( $"Error - Exception handling message {msg} : {ex}" , MessageType . Error ) ;
2021-12-10 23:28:42 -08:00
}
2022-03-02 19:46:33 -08:00
}
#endregion
2022-02-24 22:04:54 -08:00
2022-03-02 19:46:33 -08:00
public static void Send < M > ( this M msg )
where M : QSBMessage
{
if ( PlayerTransformSync . LocalInstance = = null )
2022-02-27 04:40:44 -08:00
{
2022-03-02 19:46:33 -08:00
DebugLog . ToConsole ( $"Warning - Tried to send message {msg} before local player was established." , MessageType . Warning ) ;
return ;
2022-02-27 04:40:44 -08:00
}
2022-03-02 19:46:33 -08:00
msg . From = QSBPlayerManager . LocalPlayerId ;
NetworkClient . Send < Wrapper > ( msg ) ;
2021-12-10 23:28:42 -08:00
}
2021-12-20 16:35:12 -08:00
2022-03-02 19:46:33 -08:00
public static void SendMessage < T , M > ( this T worldObject , M msg )
where T : IWorldObject
where M : QSBWorldObjectMessage < T >
2021-12-20 16:35:12 -08:00
{
2022-03-02 19:46:33 -08:00
msg . ObjectId = worldObject . ObjectId ;
Send ( msg ) ;
2022-02-24 22:04:54 -08:00
}
2022-03-02 19:46:33 -08:00
}
internal struct Wrapper : NetworkMessage
{
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
2023-07-28 19:49:30 +01:00
public static class ReaderWriterExtensions
2022-03-02 19:46:33 -08:00
{
private static QSBMessage ReadQSBMessage ( this NetworkReader reader )
2022-02-24 22:04:54 -08:00
{
2023-08-03 14:55:21 -07:00
var hash = reader . ReadInt ( ) ;
if ( ! QSBMessageManager . _types . TryGetValue ( hash , out var type ) )
2023-08-03 14:40:47 -07:00
{
2023-08-03 14:55:21 -07:00
DebugLog . DebugWrite ( $"unknown QSBMessage type with hash {hash}" , MessageType . Error ) ;
2023-08-03 14:40:47 -07:00
return null ;
}
2022-03-02 19:46:33 -08:00
var msg = ( QSBMessage ) FormatterServices . GetUninitializedObject ( type ) ;
msg . Deserialize ( reader ) ;
return msg ;
}
2022-02-27 04:40:44 -08:00
2022-03-02 19:46:33 -08:00
private static void WriteQSBMessage ( this NetworkWriter writer , QSBMessage msg )
{
var type = msg . GetType ( ) ;
2023-08-03 14:55:21 -07:00
var hash = type . FullName . GetStableHashCode ( ) ;
writer . WriteInt ( hash ) ;
2022-03-02 19:46:33 -08:00
msg . Serialize ( writer ) ;
2021-12-20 16:35:12 -08:00
}
2023-08-03 14:40:47 -07:00
}