Merge branch 'dev' into tornadoes

This commit is contained in:
JohnCorby 2021-12-06 01:53:32 -08:00
commit b4dde8dc22
5 changed files with 104 additions and 40 deletions

View File

@ -34,19 +34,26 @@ namespace QSB.Events
public abstract bool RequireWorldObjectsReady { get; } public abstract bool RequireWorldObjectsReady { get; }
public void SendEvent(T message) /// used to force set ForId for every sent event
{ protected static uint ForIdOverride = uint.MaxValue;
message.FromId = QSBPlayerManager.LocalPlayerId;
QSBCore.UnityEvents.RunWhen( public void SendEvent(T message) => QSBCore.UnityEvents.RunWhen(
() => PlayerTransformSync.LocalInstance != null, () => PlayerTransformSync.LocalInstance != null,
() => _eventHandler.SendToServer(message)); () =>
} {
message.FromId = LocalPlayerId;
if (ForIdOverride != uint.MaxValue)
{
message.ForId = ForIdOverride;
}
_eventHandler.SendToServer(message);
});
/// <summary> /// <summary>
/// Checks whether the message should be processed by the executing client/server. /// Checks whether the message should be processed by the executing client.
/// </summary> /// </summary>
/// <returns>True if the message should be processed.</returns> /// <returns>True if the message should be processed.</returns>
public virtual bool CheckMessage(bool isServer, T message) public virtual bool CheckMessage(T message)
=> !RequireWorldObjectsReady || WorldObjectManager.AllObjectsReady; => !RequireWorldObjectsReady || WorldObjectManager.AllObjectsReady;
private void OnReceive(bool isServer, T message) private void OnReceive(bool isServer, T message)
@ -59,18 +66,24 @@ namespace QSB.Events
* hub for all events. * hub for all events.
*/ */
if (!CheckMessage(isServer, message))
{
return;
}
if (isServer) if (isServer)
{ {
_eventHandler.SendToAll(message); if (message.OnlySendToHost)
{
_eventHandler.SendToHost(message);
}
else if (message.ForId != uint.MaxValue)
{
_eventHandler.SendTo(message.ForId, message);
}
else
{
_eventHandler.SendToAll(message);
}
return; return;
} }
if (message.OnlySendToHost && !QSBCore.IsHost) if (!CheckMessage(message))
{ {
return; return;
} }
@ -87,8 +100,8 @@ namespace QSB.Events
if (!player.IsReady if (!player.IsReady
&& player.PlayerId != LocalPlayerId && player.PlayerId != LocalPlayerId
&& (player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem) && player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem
&& (message is not PlayerInformationEvent or PlayerReadyEvent)) && this is not PlayerInformationEvent or PlayerReadyEvent)
{ {
DebugLog.ToConsole($"Warning - Got message from player {message.FromId}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning); DebugLog.ToConsole($"Warning - Got message from player {message.FromId}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning);
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync); QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
@ -97,14 +110,14 @@ namespace QSB.Events
try try
{ {
if (message.FromId == QSBPlayerManager.LocalPlayerId || if (QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId))
QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId))
{ {
OnReceiveLocal(QSBCore.IsHost, message); OnReceiveLocal(QSBCore.IsHost, message);
return;
} }
else
OnReceiveRemote(QSBCore.IsHost, message); {
OnReceiveRemote(QSBCore.IsHost, message);
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -1,5 +1,4 @@
using QSB.Events; using QSB.Utility;
using QSB.Utility;
using QuantumUNET; using QuantumUNET;
using QuantumUNET.Components; using QuantumUNET.Components;
using QuantumUNET.Messages; using QuantumUNET.Messages;
@ -58,6 +57,32 @@ namespace QSB.Messaging
QNetworkServer.SendToAll(_eventType, message); QNetworkServer.SendToAll(_eventType, message);
} }
public void SendToHost(T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
QNetworkServer.SendToClient(0, _eventType, message);
}
public void SendTo(uint id, T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
var conn = QNetworkServer.connections.FirstOrDefault(x => x.GetPlayerId() == id);
if (conn == null)
{
DebugLog.ToConsole($"SendTo unknown player! id: {id}, message: {message.GetType().Name}", OWML.Common.MessageType.Error);
return;
}
QNetworkServer.SendToClient(conn.connectionId, _eventType, message);
}
public void SendToServer(T message) public void SendToServer(T message)
{ {
if (!QSBNetworkManager.Instance.IsReady) if (!QSBNetworkManager.Instance.IsReady)

View File

@ -16,16 +16,27 @@ namespace QSB.Messaging
public uint AboutId { get; set; } public uint AboutId { get; set; }
/// <summary> /// <summary>
/// If true, only send this message to the host of the current session /// If true, only send this message to the host of the current session
/// (OnReceiveLocal/Remote is not called on any other client) /// (OnReceiveLocal/Remote is not called on any other client)
/// </summary> /// </summary>
public bool OnlySendToHost { get; set; } public bool OnlySendToHost { get; set; }
/// <summary>
/// The Player ID that this message is for.
/// By default, this is uint.MaxValue,
/// which means this is ignored and the message is sent to all clients
/// </summary>
public uint ForId { get; set; } = uint.MaxValue;
public override void Deserialize(QNetworkReader reader) public override void Deserialize(QNetworkReader reader)
{ {
FromId = reader.ReadUInt32(); FromId = reader.ReadUInt32();
AboutId = reader.ReadUInt32(); AboutId = reader.ReadUInt32();
OnlySendToHost = reader.ReadBoolean(); OnlySendToHost = reader.ReadBoolean();
if (!OnlySendToHost)
{
reader.ReadUInt32();
}
} }
public override void Serialize(QNetworkWriter writer) public override void Serialize(QNetworkWriter writer)
@ -33,6 +44,10 @@ namespace QSB.Messaging
writer.Write(FromId); writer.Write(FromId);
writer.Write(AboutId); writer.Write(AboutId);
writer.Write(OnlySendToHost); writer.Write(OnlySendToHost);
if (!OnlySendToHost)
{
writer.Write(ForId);
}
} }
} }
} }

View File

@ -31,20 +31,31 @@ namespace QSB.Player.Events
public override void OnReceiveRemote(bool isHost, PlayerMessage message) public override void OnReceiveRemote(bool isHost, PlayerMessage message)
{ {
// if host, send worldobject and server states // send response only to the requesting client
ForIdOverride = message.FromId;
if (isHost) try
{ {
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); // if host, send worldobject and server states
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); if (isHost)
{
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState());
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
SendWorldObjectInfo(); if (WorldObjectManager.AllObjectsReady)
{
return; SendWorldObjectInfo();
}
}
// if client, send player and client states
else
{
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
}
}
finally
{
ForIdOverride = uint.MaxValue;
} }
// if client, send player and client states
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
} }
private void SendWorldObjectInfo() private void SendWorldObjectInfo()

View File

@ -20,9 +20,9 @@ namespace QSB.QuantumSync.Events
AuthorityOwner = authorityOwner AuthorityOwner = authorityOwner
}; };
public override bool CheckMessage(bool isServer, QuantumAuthorityMessage message) public override bool CheckMessage(QuantumAuthorityMessage message)
{ {
if (!base.CheckMessage(isServer, message)) if (!base.CheckMessage(message))
{ {
return false; return false;
} }