130 lines
3.7 KiB
C#
Raw Normal View History

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;
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-12-14 16:24:52 +00:00
namespace QSB.Events
{
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
public abstract bool RequireWorldObjectsReady { get; }
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>
/// 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>
public virtual bool CheckMessage(T message)
=> !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
{
if (message.OnlySendToHost)
{
2021-12-06 00:02:51 -08:00
_eventHandler.SendToHost(message);
}
else if (message.ForId != uint.MaxValue)
{
2021-12-06 00:02:51 -08:00
_eventHandler.SendTo(message.ForId, message);
}
else
{
2021-12-06 00:02:51 -08:00
_eventHandler.SendToAll(message);
}
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
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
{
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
&& 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
{
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
{
DebugLog.ToConsole($"Error - Exception handling message {GetType().Name} : {ex}", MessageType.Error);
2020-12-02 21:29:53 +00:00
}
}
}
}