2021-12-07 15:56:08 +00:00
using OWML.Common ;
2021-11-20 22:28:08 +00:00
using QSB.ClientServerStateSync ;
2021-12-11 20:06:02 +00:00
using QSB.ClientServerStateSync.Events ;
2020-12-19 12:51:15 +00:00
using QSB.Messaging ;
2020-11-03 21:33:48 +00:00
using QSB.Player ;
2021-11-20 22:28:08 +00:00
using QSB.Player.Events ;
2021-04-11 17:05:02 +01:00
using QSB.Player.TransformSync ;
2020-12-19 12:51:15 +00:00
using QSB.Utility ;
2021-12-04 16:39:37 +00:00
using QSB.WorldSync ;
2020-12-19 12:51:15 +00:00
using QuantumUNET.Components ;
2021-12-07 15:56:08 +00:00
using System ;
2020-08-08 00:08:44 +01:00
2020-12-14 16:24:52 +00:00
namespace QSB.Events
2020-08-08 00:08:44 +01:00
{
2021-11-29 22:26:32 +00:00
public abstract class QSBEvent < T > : BaseQSBEvent where T : PlayerMessage , new ( )
2020-12-02 21:29:53 +00:00
{
2020-12-14 21:20:53 +00:00
public uint LocalPlayerId = > QSBPlayerManager . LocalPlayerId ;
2020-12-14 21:41:56 +01:00
2020-12-02 21:29:53 +00:00
private readonly MessageHandler < T > _eventHandler ;
2020-08-10 14:48:40 +01:00
2020-12-02 21:29:53 +00:00
protected QSBEvent ( )
{
2021-02-12 13:29:01 +00:00
if ( UnitTestDetector . IsInUnitTest )
{
return ;
}
2021-06-18 22:38:32 +01:00
2021-11-29 22:26:32 +00:00
_eventHandler = new MessageHandler < T > ( _msgType + + ) ;
2020-12-14 21:41:56 +01:00
_eventHandler . OnClientReceiveMessage + = message = > OnReceive ( false , message ) ;
_eventHandler . OnServerReceiveMessage + = message = > OnReceive ( true , message ) ;
2020-12-02 21:29:53 +00:00
}
2020-08-10 14:40:06 +01:00
2021-08-08 19:53:55 +01:00
public virtual void OnReceiveRemote ( bool isHost , T message ) { }
public virtual void OnReceiveLocal ( bool isHost , T message ) { }
2020-08-09 09:37:32 +02:00
2021-12-05 11:03:09 +00:00
public abstract bool RequireWorldObjectsReady { get ; }
2021-12-04 16:39:37 +00:00
2021-12-06 00:49:56 -08:00
public void SendEvent ( T message ) = > QSBCore . UnityEvents . RunWhen (
( ) = > PlayerTransformSync . LocalInstance ! = null ,
( ) = >
{
message . FromId = LocalPlayerId ;
2021-12-06 01:57:56 -08:00
if ( QSBEventManager . ForIdOverride ! = uint . MaxValue )
2021-12-06 00:49:56 -08:00
{
2021-12-06 01:57:56 -08:00
message . ForId = QSBEventManager . ForIdOverride ;
2021-12-06 00:49:56 -08:00
}
_eventHandler . SendToServer ( message ) ;
} ) ;
2020-08-15 20:32:58 +01:00
2021-01-30 10:09:27 +00:00
/// <summary>
2021-12-05 23:47:09 -08:00
/// Checks whether the message should be processed by the executing client.
2021-01-30 10:09:27 +00:00
/// </summary>
/// <returns>True if the message should be processed.</returns>
2021-12-05 23:47:09 -08:00
public virtual bool CheckMessage ( T message )
2021-12-05 11:03:09 +00:00
= > ! RequireWorldObjectsReady | | WorldObjectManager . AllObjectsReady ;
2021-01-30 10:09:27 +00:00
2020-12-19 10:56:25 +00:00
private void OnReceive ( bool isServer , T message )
2020-12-02 21:29:53 +00:00
{
2020-12-19 10:56:25 +00:00
/ * Explanation :
* if < isServer > is true , this message has been received on the server * server * .
* Therefore , we don ' t want to do any event handling code - that should be dealt
* with on the server * client * and any other client . So just forward the message
2021-07-31 09:45:07 +01:00
* onto all clients . This way , the server * server * just acts as the distribution
2020-12-19 10:56:25 +00:00
* hub for all events .
* /
2021-01-30 10:09:27 +00:00
2020-12-19 10:56:25 +00:00
if ( isServer )
2020-12-02 21:29:53 +00:00
{
2021-12-05 23:47:09 -08:00
if ( message . OnlySendToHost )
{
2021-12-06 00:02:51 -08:00
_eventHandler . SendToHost ( message ) ;
2021-12-05 23:47:09 -08:00
}
2021-12-06 00:11:55 -08:00
else if ( message . ForId ! = uint . MaxValue )
2021-12-05 23:47:09 -08:00
{
2021-12-06 00:02:51 -08:00
_eventHandler . SendTo ( message . ForId , message ) ;
2021-12-05 23:47:09 -08:00
}
else
{
2021-12-06 00:02:51 -08:00
_eventHandler . SendToAll ( message ) ;
2021-12-05 23:47:09 -08:00
}
2020-12-19 10:56:25 +00:00
return ;
2020-12-02 21:29:53 +00:00
}
2020-08-09 09:17:00 +02:00
2021-12-05 23:47:09 -08:00
if ( ! CheckMessage ( message ) )
2020-12-13 22:25:23 +00:00
{
2020-12-19 10:56:25 +00:00
return ;
2020-12-13 22:25:23 +00:00
}
2020-12-19 10:56:25 +00:00
2020-12-23 12:58:45 +00:00
if ( PlayerTransformSync . LocalInstance = = null | | PlayerTransformSync . LocalInstance . GetComponent < QNetworkIdentity > ( ) = = null )
2020-12-19 12:51:15 +00:00
{
2021-11-20 17:38:00 +00:00
DebugLog . ToConsole ( $"Warning - Tried to handle message of type <{GetType().Name}> before localplayer was established." , MessageType . Warning ) ;
2020-12-19 12:51:15 +00:00
return ;
}
2021-11-20 22:28:08 +00:00
if ( QSBPlayerManager . PlayerExists ( message . FromId ) )
{
var player = QSBPlayerManager . GetPlayer ( message . FromId ) ;
if ( ! player . IsReady
& & player . PlayerId ! = LocalPlayerId
2021-12-05 23:47:09 -08:00
& & player . State is ClientState . AliveInSolarSystem or ClientState . AliveInEye or ClientState . DeadInSolarSystem
2021-12-11 20:06:02 +00:00
& & this is not PlayerInformationEvent
and not PlayerReadyEvent
and not RequestStateResyncEvent
and not ServerStateEvent )
2021-11-20 22:28:08 +00:00
{
2021-12-11 11:47:37 +00:00
DebugLog . ToConsole ( $"Warning - Got message (type:{GetType().Name}) from player {message.FromId}, but they were not ready. Asking for state resync, just in case." , MessageType . Warning ) ;
2021-11-20 22:28:08 +00:00
QSBEventManager . FireEvent ( EventNames . QSBRequestStateResync ) ;
}
}
2021-10-26 14:08:37 +01:00
try
{
2021-12-06 00:02:51 -08:00
if ( QSBPlayerManager . IsBelongingToLocalPlayer ( message . FromId ) )
2021-10-26 14:08:37 +01:00
{
OnReceiveLocal ( QSBCore . IsHost , message ) ;
}
2021-12-06 00:02:51 -08:00
else
{
OnReceiveRemote ( QSBCore . IsHost , message ) ;
}
2021-10-26 14:08:37 +01:00
}
catch ( Exception ex )
2020-12-02 21:29:53 +00:00
{
2021-11-20 17:38:00 +00:00
DebugLog . ToConsole ( $"Error - Exception handling message {GetType().Name} : {ex}" , MessageType . Error ) ;
2020-12-02 21:29:53 +00:00
}
}
}
2021-11-30 18:00:12 -08:00
}