mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-21 09:39:56 +00:00
Merge branch 'dev' into initial-eye-stuff
This commit is contained in:
commit
a75ecf143e
@ -1,10 +0,0 @@
|
||||
namespace QSB.Events
|
||||
{
|
||||
public abstract class BaseQSBEvent : IQSBEvent
|
||||
{
|
||||
internal static int _msgType;
|
||||
|
||||
public abstract void SetupListener();
|
||||
public abstract void CloseListener();
|
||||
}
|
||||
}
|
@ -1,129 +1,99 @@
|
||||
using OWML.Common;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.ClientServerStateSync.Events;
|
||||
using JetBrains.Annotations;
|
||||
using OWML.Utils;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Events;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Transport;
|
||||
using System;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Events
|
||||
{
|
||||
public abstract class QSBEvent<T> : BaseQSBEvent where T : PlayerMessage, new()
|
||||
public abstract class QSBEvent<T> : IQSBEvent where T : PlayerMessage, new()
|
||||
{
|
||||
public uint LocalPlayerId => QSBPlayerManager.LocalPlayerId;
|
||||
|
||||
private readonly MessageHandler<T> _eventHandler;
|
||||
[UsedImplicitly]
|
||||
private Type _messageType => typeof(T);
|
||||
|
||||
[UsedImplicitly]
|
||||
private readonly int _msgType;
|
||||
|
||||
protected QSBEvent()
|
||||
{
|
||||
if (UnitTestDetector.IsInUnitTest)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_eventHandler = new MessageHandler<T>(_msgType++);
|
||||
_eventHandler.OnClientReceiveMessage += message => OnReceive(false, message);
|
||||
_eventHandler.OnServerReceiveMessage += message => OnReceive(true, message);
|
||||
_msgType = QSBEventManager._eventList.Count;
|
||||
}
|
||||
|
||||
public abstract void SetupListener();
|
||||
public abstract void CloseListener();
|
||||
|
||||
[UsedImplicitly]
|
||||
public virtual void OnReceiveRemote(bool isHost, T message) { }
|
||||
|
||||
[UsedImplicitly]
|
||||
public virtual void OnReceiveLocal(bool isHost, T message) { }
|
||||
|
||||
public abstract bool RequireWorldObjectsReady { get; }
|
||||
|
||||
public void SendEvent(T message) => QSBCore.UnityEvents.RunWhen(
|
||||
() => PlayerTransformSync.LocalInstance != null,
|
||||
() =>
|
||||
public void SendEvent(T message)
|
||||
{
|
||||
message.FromId = LocalPlayerId;
|
||||
if (QSBEventManager.ForIdOverride != uint.MaxValue)
|
||||
{
|
||||
message.ForId = QSBEventManager.ForIdOverride;
|
||||
}
|
||||
if (message.OnlySendToHost)
|
||||
{
|
||||
message.FromId = LocalPlayerId;
|
||||
if (QSBEventManager.ForIdOverride != uint.MaxValue)
|
||||
{
|
||||
message.ForId = QSBEventManager.ForIdOverride;
|
||||
DebugLog.ToConsole($"Warning - {typeof(T).Name} is OnlySendToHost, but we are trying to ForIdOverride!");
|
||||
}
|
||||
_eventHandler.SendToServer(message);
|
||||
});
|
||||
message.ForId = 0;
|
||||
}
|
||||
new QSBEventRelay
|
||||
{
|
||||
To = message.ForId,
|
||||
Event = this,
|
||||
Message = message
|
||||
}.Send();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the message should be processed by the executing client.
|
||||
/// </summary>
|
||||
/// <returns>True if the message should be processed.</returns>
|
||||
[UsedImplicitly]
|
||||
public virtual bool CheckMessage(T message)
|
||||
=> !RequireWorldObjectsReady || WorldObjectManager.AllObjectsReady;
|
||||
}
|
||||
|
||||
private void OnReceive(bool isServer, T message)
|
||||
internal class QSBEventRelay : QSBMessage
|
||||
{
|
||||
public IQSBEvent Event;
|
||||
public PlayerMessage Message;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
/* 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
|
||||
* onto all clients. This way, the server *server* just acts as the distribution
|
||||
* hub for all events.
|
||||
*/
|
||||
|
||||
if (isServer)
|
||||
{
|
||||
if (message.OnlySendToHost)
|
||||
{
|
||||
_eventHandler.SendToHost(message);
|
||||
}
|
||||
else if (message.ForId != uint.MaxValue)
|
||||
{
|
||||
_eventHandler.SendTo(message.ForId, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
_eventHandler.SendToAll(message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckMessage(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerTransformSync.LocalInstance == null || PlayerTransformSync.LocalInstance.GetComponent<QNetworkIdentity>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to handle message of type <{GetType().Name}> before localplayer was established.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
&& this is not PlayerInformationEvent
|
||||
and not PlayerReadyEvent
|
||||
and not RequestStateResyncEvent
|
||||
and not ServerStateEvent)
|
||||
{
|
||||
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);
|
||||
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId))
|
||||
{
|
||||
OnReceiveLocal(QSBCore.IsHost, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnReceiveRemote(QSBCore.IsHost, message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Exception handling message {GetType().Name} : {ex}", MessageType.Error);
|
||||
}
|
||||
base.Serialize(writer);
|
||||
var msgType = Event.GetValue<int>("_msgType");
|
||||
writer.Write(msgType);
|
||||
Message.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
var msgType = reader.ReadInt32();
|
||||
Event = QSBEventManager._eventList[msgType];
|
||||
var messageType = Event.GetValue<Type>("_messageType");
|
||||
Message = (PlayerMessage)Activator.CreateInstance(messageType);
|
||||
Message.Deserialize(reader);
|
||||
}
|
||||
|
||||
protected override bool ShouldReceive => Event.Invoke<bool>("CheckMessage", Message);
|
||||
protected override void OnReceiveRemote() => Event.Invoke("OnReceiveRemote", QSBCore.IsHost, Message);
|
||||
protected override void OnReceiveLocal() => Event.Invoke("OnReceiveLocal", QSBCore.IsHost, Message);
|
||||
|
||||
public override string ToString() => Event.GetType().Name;
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,8 @@
|
||||
using OWML.Common;
|
||||
using QSB.Anglerfish.Events;
|
||||
using QSB.Animation.NPC.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.AuthoritySync;
|
||||
using QSB.CampfireSync.Events;
|
||||
using QSB.ClientServerStateSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
using QSB.DeathSync.Events;
|
||||
using QSB.ElevatorSync.Events;
|
||||
using QSB.EyeOfTheUniverse.InstrumentSync.Event;
|
||||
using QSB.GeyserSync.Events;
|
||||
using QSB.ItemSync.Events;
|
||||
using QSB.JellyfishSync.Events;
|
||||
using QSB.LogSync.Events;
|
||||
using QSB.MeteorSync.Events;
|
||||
using QSB.OrbSync.Events;
|
||||
using QSB.Player.Events;
|
||||
using QSB.QuantumSync.Events;
|
||||
using QSB.RespawnSync.Events;
|
||||
using QSB.RoastingSync.Events;
|
||||
using QSB.SatelliteSync.Events;
|
||||
using QSB.SaveSync.Events;
|
||||
using QSB.ShipSync.Events;
|
||||
using QSB.ShipSync.Events.Component;
|
||||
using QSB.ShipSync.Events.Hull;
|
||||
using QSB.StatueSync.Events;
|
||||
using QSB.TimeSync.Events;
|
||||
using QSB.Tools.FlashlightTool.Events;
|
||||
using QSB.Tools.ProbeLauncherTool.Events;
|
||||
using QSB.Tools.ProbeTool.Events;
|
||||
using QSB.Tools.SignalscopeTool.Events;
|
||||
using QSB.Tools.SignalscopeTool.FrequencySync.Events;
|
||||
using QSB.Tools.TranslatorTool.Events;
|
||||
using QSB.Tools.TranslatorTool.TranslationSync.Events;
|
||||
using QSB.TornadoSync.Events;
|
||||
using QSB.Utility;
|
||||
using QSB.Utility.Events;
|
||||
using QSB.ZeroGCaveSync.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Events
|
||||
{
|
||||
@ -45,99 +10,15 @@ namespace QSB.Events
|
||||
{
|
||||
public static bool Ready { get; private set; }
|
||||
|
||||
private static List<IQSBEvent> _eventList = new();
|
||||
private static readonly Type[] _types = typeof(IQSBEvent).GetDerivedTypes().ToArray();
|
||||
internal static readonly List<IQSBEvent> _eventList = new();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
BaseQSBEvent._msgType = 0;
|
||||
_eventList = new List<IQSBEvent>
|
||||
foreach (var type in _types)
|
||||
{
|
||||
// Player
|
||||
new PlayerReadyEvent(),
|
||||
new PlayerJoinEvent(),
|
||||
new PlayerSuitEvent(),
|
||||
new PlayerFlashlightEvent(),
|
||||
new PlayerSignalscopeEvent(),
|
||||
new PlayerTranslatorEvent(),
|
||||
new EquipProbeLauncherEvent(),
|
||||
new PlayerProbeEvent(),
|
||||
new PlayerDeathEvent(),
|
||||
new RequestStateResyncEvent(),
|
||||
new PlayerInformationEvent(),
|
||||
new ChangeAnimTypeEvent(),
|
||||
new ServerTimeEvent(),
|
||||
new PlayerEntangledEvent(),
|
||||
new PlayerKickEvent(),
|
||||
new EnterExitRoastingEvent(),
|
||||
new MarshmallowEventEvent(),
|
||||
new AnimationTriggerEvent(),
|
||||
new PlayerRespawnEvent(),
|
||||
new ProbeStartRetrieveEvent(),
|
||||
new RetrieveProbeEvent(),
|
||||
new LaunchProbeEvent(),
|
||||
new PlayerRetrieveProbeEvent(),
|
||||
new PlayerLaunchProbeEvent(),
|
||||
new EndLoopEvent(),
|
||||
new StartLoopEvent(),
|
||||
new ServerStateEvent(),
|
||||
new ClientStateEvent(),
|
||||
new DebugEvent(),
|
||||
new SatelliteProjectorEvent(),
|
||||
new SatelliteProjectorSnapshotEvent(),
|
||||
new LaunchCodesEvent(),
|
||||
new RequestGameStateEvent(),
|
||||
new GameStateEvent(),
|
||||
// World Objects
|
||||
new ElevatorEvent(),
|
||||
new GeyserEvent(),
|
||||
new OrbDragEvent(),
|
||||
new OrbSlotEvent(),
|
||||
new SocketStateChangeEvent(),
|
||||
new MultiStateChangeEvent(),
|
||||
new SetAsTranslatedEvent(),
|
||||
new QuantumShuffleEvent(),
|
||||
new MoonStateChangeEvent(),
|
||||
new EnterLeaveEvent(),
|
||||
new QuantumAuthorityEvent(),
|
||||
new DropItemEvent(),
|
||||
new SocketItemEvent(),
|
||||
new MoveToCarryEvent(),
|
||||
new StartStatueEvent(),
|
||||
new CampfireStateEvent(),
|
||||
new AnglerChangeStateEvent(),
|
||||
new MeteorPreLaunchEvent(),
|
||||
new MeteorLaunchEvent(),
|
||||
new MeteorSpecialImpactEvent(),
|
||||
new FragmentDamageEvent(),
|
||||
new FragmentResyncEvent(),
|
||||
new JellyfishRisingEvent(),
|
||||
new TornadoFormStateEvent(),
|
||||
new GatherInstrumentEvent(),
|
||||
// Conversation/dialogue/exploration
|
||||
new ConversationEvent(),
|
||||
new ConversationStartEndEvent(),
|
||||
new DialogueConditionEvent(),
|
||||
new RevealFactEvent(),
|
||||
new IdentifyFrequencyEvent(),
|
||||
new IdentifySignalEvent(),
|
||||
new NpcAnimationEvent(),
|
||||
new AuthQueueEvent(),
|
||||
new EnterRemoteDialogueEvent(),
|
||||
// Ship
|
||||
new FlyShipEvent(),
|
||||
new HatchEvent(),
|
||||
new FunnelEnableEvent(),
|
||||
new HullImpactEvent(),
|
||||
new HullDamagedEvent(),
|
||||
new HullChangeIntegrityEvent(),
|
||||
new HullRepairedEvent(),
|
||||
new HullRepairTickEvent(),
|
||||
new ComponentDamagedEvent(),
|
||||
new ComponentRepairedEvent(),
|
||||
new ComponentRepairTickEvent(),
|
||||
new SatelliteNodeRepairTick(),
|
||||
new SatelliteNodeRepaired()
|
||||
};
|
||||
_eventList.Add((IQSBEvent)Activator.CreateInstance(type));
|
||||
}
|
||||
|
||||
if (UnitTestDetector.IsInUnitTest)
|
||||
{
|
||||
@ -155,13 +36,14 @@ namespace QSB.Events
|
||||
{
|
||||
Ready = false;
|
||||
_eventList.ForEach(ev => ev.CloseListener());
|
||||
_eventList = new List<IQSBEvent>();
|
||||
_eventList.Clear();
|
||||
}
|
||||
|
||||
public static void FireEvent(string eventName)
|
||||
{
|
||||
if (!QSBCore.IsInMultiplayer)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to send event {eventName} while not connected to/hosting server.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,108 +0,0 @@
|
||||
using QSB.Utility;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Messages;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace QSB.Messaging
|
||||
{
|
||||
public class MessageHandler<T> where T : QMessageBase, new()
|
||||
{
|
||||
public event Action<T> OnClientReceiveMessage;
|
||||
public event Action<T> OnServerReceiveMessage;
|
||||
|
||||
private readonly short _eventType;
|
||||
|
||||
public MessageHandler(int msgType)
|
||||
{
|
||||
|
||||
_eventType = (short)(msgType + QMsgType.Highest + 1);
|
||||
if (_eventType >= short.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole($"Hey, uh, maybe don't create 32,767 events? You really should never be seeing this." +
|
||||
$"If you are, something has either gone terrible wrong or QSB somehow needs more events that classes in Outer Wilds." +
|
||||
$"In either case, I guess something has gone terribly wrong...", OWML.Common.MessageType.Error);
|
||||
}
|
||||
|
||||
if (QSBNetworkManager.Instance.IsReady)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
QSBNetworkManager.Instance.OnNetworkManagerReady += Init;
|
||||
}
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (QNetworkServer.handlers.Keys.Contains(_eventType))
|
||||
{
|
||||
QNetworkServer.handlers.Remove(_eventType);
|
||||
QNetworkManager.singleton.client.handlers.Remove(_eventType);
|
||||
}
|
||||
|
||||
QNetworkServer.RegisterHandler(_eventType, OnServerReceiveMessageHandler);
|
||||
QNetworkManager.singleton.client.RegisterHandler(_eventType, OnClientReceiveMessageHandler);
|
||||
}
|
||||
|
||||
public void SendToAll(T message)
|
||||
{
|
||||
if (!QSBNetworkManager.Instance.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!QSBNetworkManager.Instance.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkManager.singleton.client.Send(_eventType, message);
|
||||
}
|
||||
|
||||
private void OnClientReceiveMessageHandler(QNetworkMessage netMsg)
|
||||
{
|
||||
var message = netMsg.ReadMessage<T>();
|
||||
OnClientReceiveMessage?.SafeInvoke(message);
|
||||
}
|
||||
|
||||
private void OnServerReceiveMessageHandler(QNetworkMessage netMsg)
|
||||
{
|
||||
var message = netMsg.ReadMessage<T>();
|
||||
OnServerReceiveMessage?.SafeInvoke(message);
|
||||
}
|
||||
}
|
||||
}
|
103
QSB/Messaging/QSBMessage.cs
Normal file
103
QSB/Messaging/QSBMessage.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using QSB.Player;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Messaging
|
||||
{
|
||||
public abstract class QSBMessage : QSBMessageRaw
|
||||
{
|
||||
/// set automatically when sending a message
|
||||
public uint From;
|
||||
/// <summary>
|
||||
/// uint.MaxValue = send to everyone <br/>
|
||||
/// 0 = send to host
|
||||
/// </summary>
|
||||
public uint To = uint.MaxValue;
|
||||
|
||||
/// call the base method when overriding
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
writer.Write(From);
|
||||
writer.Write(To);
|
||||
}
|
||||
|
||||
/// call the base method when overriding
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
From = reader.ReadUInt32();
|
||||
To = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
public sealed override void OnReceive()
|
||||
{
|
||||
if (ShouldReceive)
|
||||
{
|
||||
if (From != QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
OnReceiveRemote();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnReceiveLocal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// checked before calling either OnReceive
|
||||
protected virtual bool ShouldReceive => true;
|
||||
protected virtual void OnReceiveRemote() { }
|
||||
protected virtual void OnReceiveLocal() { }
|
||||
}
|
||||
|
||||
|
||||
public abstract class QSBBoolMessage : QSBMessage
|
||||
{
|
||||
public bool Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class QSBFloatMessage : QSBMessage
|
||||
{
|
||||
public float Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class QSBEnumMessage<E> : QSBMessage where E : Enum
|
||||
{
|
||||
public E Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)(object)Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = (E)(object)reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
168
QSB/Messaging/QSBMessageManager.cs
Normal file
168
QSB/Messaging/QSBMessageManager.cs
Normal file
@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OWML.Common;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.ClientServerStateSync.Events;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Events;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Messages;
|
||||
|
||||
namespace QSB.Messaging
|
||||
{
|
||||
public static class QSBMessageManager
|
||||
{
|
||||
#region inner workings
|
||||
|
||||
private static readonly Dictionary<short, Type> _msgTypeToType = new();
|
||||
private static readonly Dictionary<Type, short> _typeToMsgType = new();
|
||||
|
||||
static QSBMessageManager()
|
||||
{
|
||||
var types = typeof(QSBMessageRaw).GetDerivedTypes().ToArray();
|
||||
for (var i = 0; i < types.Length; i++)
|
||||
{
|
||||
var msgType = (short)(QMsgType.Highest + 1 + i);
|
||||
if (msgType >= short.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole("Hey, uh, maybe don't create 32,767 events? You really should never be seeing this." +
|
||||
"If you are, something has either gone terrible wrong or QSB somehow needs more events that classes in Outer Wilds." +
|
||||
"In either case, I guess something has gone terribly wrong...", MessageType.Error);
|
||||
}
|
||||
|
||||
_msgTypeToType.Add(msgType, types[i]);
|
||||
_typeToMsgType.Add(types[i], msgType);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
foreach (var msgType in _msgTypeToType.Keys)
|
||||
{
|
||||
QNetworkServer.RegisterHandlerSafe(msgType, OnServerReceive);
|
||||
QNetworkManager.singleton.client.RegisterHandlerSafe(msgType, OnClientReceive);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnServerReceive(QNetworkMessage netMsg)
|
||||
{
|
||||
var msgType = netMsg.MsgType;
|
||||
var msg = (QSBMessageRaw)Activator.CreateInstance(_msgTypeToType[msgType]);
|
||||
netMsg.ReadMessage(msg);
|
||||
|
||||
if (msg is QSBMessage m)
|
||||
{
|
||||
if (m.To == uint.MaxValue)
|
||||
{
|
||||
QNetworkServer.SendToAll(msgType, m);
|
||||
}
|
||||
else if (m.To == 0)
|
||||
{
|
||||
OnReceive(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
var conn = QNetworkServer.connections.FirstOrDefault(x => m.To == x.GetPlayerId());
|
||||
if (conn == null)
|
||||
{
|
||||
DebugLog.ToConsole($"SendTo unknown player! id: {m.To}, message: {m}", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
conn.Send(msgType, m);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QNetworkServer.SendToAll(msgType, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnClientReceive(QNetworkMessage netMsg)
|
||||
{
|
||||
var msgType = netMsg.MsgType;
|
||||
var msg = (QSBMessageRaw)Activator.CreateInstance(_msgTypeToType[msgType]);
|
||||
netMsg.ReadMessage(msg);
|
||||
|
||||
OnReceive(msg);
|
||||
}
|
||||
|
||||
private static void OnReceive(QSBMessageRaw msg)
|
||||
{
|
||||
if (PlayerTransformSync.LocalInstance == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to handle message {msg} before local player was established.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg is QSBMessage m)
|
||||
{
|
||||
if (QSBPlayerManager.PlayerExists(m.From))
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(m.From);
|
||||
|
||||
if (!player.IsReady
|
||||
&& player.PlayerId != QSBPlayerManager.LocalPlayerId
|
||||
&& player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem
|
||||
&& m is not QSBEventRelay { Event: PlayerInformationEvent or PlayerReadyEvent or RequestStateResyncEvent or ServerStateEvent })
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Got message {m} from player {m.From}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning);
|
||||
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
msg.OnReceive();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Exception handling message {msg} : {ex}", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public static void Send<M>(this M msg)
|
||||
where M : QSBMessageRaw, new()
|
||||
{
|
||||
if (PlayerTransformSync.LocalInstance == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to send message {msg} before local player was established.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg is QSBMessage m)
|
||||
{
|
||||
m.From = QSBPlayerManager.LocalPlayerId;
|
||||
}
|
||||
|
||||
var msgType = _typeToMsgType[typeof(M)];
|
||||
QNetworkManager.singleton.client.Send(msgType, msg);
|
||||
}
|
||||
|
||||
public static void SendMessage<T, M>(this T worldObject, M msg)
|
||||
where T : IWorldObject
|
||||
where M : QSBWorldObjectMessage<T>, new()
|
||||
{
|
||||
msg.ObjectId = worldObject.ObjectId;
|
||||
Send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// message that will be sent to every client
|
||||
/// </summary>
|
||||
public abstract class QSBMessageRaw : QMessageBase
|
||||
{
|
||||
public abstract void OnReceive();
|
||||
public override string ToString() => GetType().Name;
|
||||
}
|
||||
}
|
92
QSB/Messaging/QSBWorldObjectMessage.cs
Normal file
92
QSB/Messaging/QSBWorldObjectMessage.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Messaging
|
||||
{
|
||||
public abstract class QSBWorldObjectMessage<T> : QSBMessage where T : IWorldObject
|
||||
{
|
||||
public int ObjectId;
|
||||
public T WorldObject { get; private set; }
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(ObjectId);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
ObjectId = reader.ReadInt32();
|
||||
}
|
||||
|
||||
protected override bool ShouldReceive
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!WorldObjectManager.AllObjectsReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldObject = QSBWorldSync.GetWorldFromId<T>(ObjectId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract class QSBBoolWorldObjectMessage<T> : QSBWorldObjectMessage<T> where T : IWorldObject
|
||||
{
|
||||
public bool Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class QSBFloatWorldObjectMessage<T> : QSBWorldObjectMessage<T> where T : IWorldObject
|
||||
{
|
||||
public float Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class QSBEnumWorldObjectMessage<T, E> : QSBWorldObjectMessage<T>
|
||||
where T : IWorldObject
|
||||
where E : Enum
|
||||
{
|
||||
public E Value;
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)(object)Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Value = (E)(object)reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +1,9 @@
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Anglerfish.Patches;
|
||||
using QSB.Animation.NPC.Patches;
|
||||
using QSB.Animation.Patches;
|
||||
using QSB.CampfireSync.Patches;
|
||||
using QSB.ConversationSync.Patches;
|
||||
using QSB.DeathSync.Patches;
|
||||
using QSB.EchoesOfTheEye.LightSensorSync.Patches;
|
||||
using QSB.ElevatorSync.Patches;
|
||||
using QSB.EyeOfTheUniverse.InstrumentSync.Patches;
|
||||
using QSB.GeyserSync.Patches;
|
||||
using QSB.Inputs.Patches;
|
||||
using QSB.ItemSync.Patches;
|
||||
using QSB.JellyfishSync.Patches;
|
||||
using QSB.LogSync.Patches;
|
||||
using QSB.MeteorSync.Patches;
|
||||
using QSB.OrbSync.Patches;
|
||||
using QSB.Player.Patches;
|
||||
using QSB.PoolSync.Patches;
|
||||
using QSB.QuantumSync.Patches;
|
||||
using QSB.RoastingSync.Patches;
|
||||
using QSB.SatelliteSync.Patches;
|
||||
using QSB.ShipSync.Patches;
|
||||
using QSB.StatueSync.Patches;
|
||||
using QSB.TimeSync.Patches;
|
||||
using QSB.Tools.ProbeLauncherTool.Patches;
|
||||
using QSB.Tools.SignalscopeTool.FrequencySync.Patches;
|
||||
using QSB.Tools.TranslatorTool.TranslationSync.Patches;
|
||||
using QSB.TornadoSync.Patches;
|
||||
using QSB.Utility;
|
||||
using QSB.ZeroGCaveSync.Patches;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.Patches
|
||||
{
|
||||
@ -41,52 +12,17 @@ namespace QSB.Patches
|
||||
public static event Action<QSBPatchTypes> OnPatchType;
|
||||
public static event Action<QSBPatchTypes> OnUnpatchType;
|
||||
|
||||
private static List<QSBPatch> _patchList = new();
|
||||
private static List<QSBPatchTypes> _patchedTypes = new();
|
||||
private static readonly List<QSBPatch> _patchList = new();
|
||||
private static readonly List<QSBPatchTypes> _patchedTypes = new();
|
||||
|
||||
public static Dictionary<QSBPatchTypes, Harmony> TypeToInstance = new();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
_patchList = new List<QSBPatch>
|
||||
foreach (var type in typeof(QSBPatch).GetDerivedTypes())
|
||||
{
|
||||
new ConversationPatches(),
|
||||
new DeathPatches(),
|
||||
new ElevatorPatches(),
|
||||
new OrbPatches(),
|
||||
new LogPatches(),
|
||||
new QuantumVisibilityPatches(),
|
||||
new ServerQuantumPatches(),
|
||||
new ClientQuantumPatches(),
|
||||
new FrequencyPatches(),
|
||||
new SpiralPatches(),
|
||||
new QuantumPatches(),
|
||||
new ItemPatches(),
|
||||
new StatuePatches(),
|
||||
new GeyserPatches(),
|
||||
new PoolPatches(),
|
||||
new CampfirePatches(),
|
||||
new RoastingPatches(),
|
||||
new PlayerPatches(),
|
||||
new PlayerAnimationPatches(),
|
||||
new CharacterAnimationPatches(),
|
||||
new ShipPatches(),
|
||||
new InputPatches(),
|
||||
new TimePatches(),
|
||||
new MapPatches(),
|
||||
new LauncherPatches(),
|
||||
new SolanumPatches(),
|
||||
new SatelliteProjectorPatches(),
|
||||
new LightSensorPatches(),
|
||||
new AnglerPatches(),
|
||||
new MeteorClientPatches(),
|
||||
new MeteorServerPatches(),
|
||||
new JellyfishPatches(),
|
||||
new TravelerControllerPatches(),
|
||||
new ZeroGCavePatches(),
|
||||
new TornadoPatches(),
|
||||
new QuantumInstrumentPatches()
|
||||
};
|
||||
_patchList.Add((QSBPatch)Activator.CreateInstance(type));
|
||||
}
|
||||
|
||||
TypeToInstance = new Dictionary<QSBPatchTypes, Harmony>
|
||||
{
|
||||
|
@ -1,36 +1,16 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.ModHelper.Input;
|
||||
using QSB.Anglerfish;
|
||||
using QSB.Animation.NPC;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.EchoesOfTheEye.AirlockSync;
|
||||
using QSB.EchoesOfTheEye.LightSensorSync;
|
||||
using QSB.ElevatorSync;
|
||||
using QSB.EyeOfTheUniverse.InstrumentSync;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.Inputs;
|
||||
using QSB.ItemSync;
|
||||
using QSB.JellyfishSync;
|
||||
using QSB.Menus;
|
||||
using QSB.MeteorSync;
|
||||
using QSB.OrbSync;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.PoolSync;
|
||||
using QSB.QuantumSync;
|
||||
using QSB.RespawnSync;
|
||||
using QSB.SatelliteSync;
|
||||
using QSB.SectorSync;
|
||||
using QSB.ShipSync;
|
||||
using QSB.StatueSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Tools.ProbeLauncherTool;
|
||||
using QSB.Tools.TranslatorTool.TranslationSync;
|
||||
using QSB.TornadoSync;
|
||||
using QSB.Utility;
|
||||
using QSB.ZeroGCaveSync;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
using System.Linq;
|
||||
@ -125,27 +105,10 @@ namespace QSB
|
||||
gameObject.AddComponent<StatueManager>();
|
||||
|
||||
// WorldObject managers
|
||||
gameObject.AddComponent<QuantumManager>();
|
||||
gameObject.AddComponent<SpiralManager>();
|
||||
gameObject.AddComponent<ElevatorManager>();
|
||||
gameObject.AddComponent<GeyserManager>();
|
||||
gameObject.AddComponent<OrbManager>();
|
||||
gameObject.AddComponent<QSBSectorManager>();
|
||||
gameObject.AddComponent<ItemManager>();
|
||||
gameObject.AddComponent<PoolManager>();
|
||||
gameObject.AddComponent<CampfireManager>();
|
||||
gameObject.AddComponent<CharacterAnimManager>();
|
||||
gameObject.AddComponent<ShipManager>();
|
||||
gameObject.AddComponent<ProbeLauncherManager>();
|
||||
gameObject.AddComponent<LightSensorManager>();
|
||||
gameObject.AddComponent<AirlockManager>();
|
||||
gameObject.AddComponent<AnglerManager>();
|
||||
gameObject.AddComponent<MeteorManager>();
|
||||
gameObject.AddComponent<JellyfishManager>();
|
||||
gameObject.AddComponent<ZeroGCaveManager>();
|
||||
gameObject.AddComponent<TornadoManager>();
|
||||
gameObject.AddComponent<ConversationManager>();
|
||||
gameObject.AddComponent<QuantumInstrumentManager>();
|
||||
foreach (var type in typeof(WorldObjectManager).GetDerivedTypes())
|
||||
{
|
||||
gameObject.AddComponent(type);
|
||||
}
|
||||
|
||||
DebugBoxManager.Init();
|
||||
|
||||
|
@ -6,6 +6,7 @@ using QSB.ClientServerStateSync;
|
||||
using QSB.DeathSync;
|
||||
using QSB.Events;
|
||||
using QSB.JellyfishSync.TransformSync;
|
||||
using QSB.Messaging;
|
||||
using QSB.OrbSync.TransformSync;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
@ -165,6 +166,7 @@ namespace QSB
|
||||
OnClientConnected?.SafeInvoke();
|
||||
|
||||
QSBEventManager.Init();
|
||||
QSBMessageManager.Init();
|
||||
|
||||
gameObject.AddComponent<RespawnOnDeath>();
|
||||
gameObject.AddComponent<ServerStateManager>();
|
||||
|
@ -145,6 +145,9 @@ namespace QSB.Utility
|
||||
multiDelegate.GetInvocationList().ToList().ForEach(dl => dl.DynamicInvoke(args));
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetDerivedTypes(this Type type) => type.Assembly.GetTypes()
|
||||
.Where(x => !x.IsInterface && !x.IsAbstract && type.IsAssignableFrom(x));
|
||||
|
||||
// OW
|
||||
|
||||
public static Vector3 GetRelativeAngularVelocity(this OWRigidbody baseBody, OWRigidbody relativeBody)
|
||||
|
@ -1,41 +0,0 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using QSB.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace QSBTests
|
||||
{
|
||||
[TestClass]
|
||||
public class EventTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void CheckUnreferencedEvents()
|
||||
{
|
||||
var qsbAssembly = Assembly.Load("QSB");
|
||||
var allEventTypes = qsbAssembly
|
||||
.GetTypes()
|
||||
.Where(x => typeof(IQSBEvent).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract);
|
||||
|
||||
QSBEventManager.Init();
|
||||
var eventInstances = (List<IQSBEvent>)typeof(QSBEventManager)
|
||||
.GetField("_eventList", BindingFlags.NonPublic | BindingFlags.Static)
|
||||
.GetValue(typeof(QSBEventManager));
|
||||
|
||||
var failedTypes = new List<Type>();
|
||||
foreach (var type in allEventTypes)
|
||||
{
|
||||
if (!eventInstances.Any(x => x.GetType() == type))
|
||||
{
|
||||
failedTypes.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedTypes.Count > 0)
|
||||
{
|
||||
Assert.Fail(string.Join(", ", failedTypes.Select(x => x.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using QSB.Patches;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace QSBTests
|
||||
{
|
||||
[TestClass]
|
||||
public class PatchTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void CheckUnreferencedPatches()
|
||||
{
|
||||
var qsbAssembly = Assembly.Load("QSB");
|
||||
var allPatchTypes = qsbAssembly
|
||||
.GetTypes()
|
||||
.Where(x => typeof(QSBPatch).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract);
|
||||
|
||||
QSBPatchManager.Init();
|
||||
var patchInstances = (List<QSBPatch>)typeof(QSBPatchManager)
|
||||
.GetField("_patchList", BindingFlags.NonPublic | BindingFlags.Static)
|
||||
.GetValue(typeof(QSBPatchManager));
|
||||
|
||||
var failedTypes = new List<Type>();
|
||||
foreach (var type in allPatchTypes)
|
||||
{
|
||||
if (!patchInstances.Any(x => x.GetType() == type))
|
||||
{
|
||||
failedTypes.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedTypes.Count > 0)
|
||||
{
|
||||
Assert.Fail(string.Join(", ", failedTypes.Select(x => x.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -631,14 +631,12 @@ namespace QuantumUNET.Components
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var networkConnection2 in QNetworkServer.localConnections)
|
||||
var networkConnection2 = QNetworkServer.localConnection;
|
||||
if (networkConnection2 != null)
|
||||
{
|
||||
if (networkConnection2 != null)
|
||||
if (networkConnection2.isReady)
|
||||
{
|
||||
if (networkConnection2.isReady)
|
||||
{
|
||||
AddObserver(networkConnection2);
|
||||
}
|
||||
AddObserver(networkConnection2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -674,12 +672,10 @@ namespace QuantumUNET.Components
|
||||
|
||||
if (initialize)
|
||||
{
|
||||
foreach (var connection in QNetworkServer.localConnections)
|
||||
var connection = QNetworkServer.localConnection;
|
||||
if (!hashSet.Contains(connection))
|
||||
{
|
||||
if (!hashSet.Contains(connection))
|
||||
{
|
||||
OnSetLocalVisibility(false);
|
||||
}
|
||||
OnSetLocalVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace QuantumUNET
|
||||
}
|
||||
|
||||
m_AsyncConnect = ConnectState.Disconnected;
|
||||
m_LocalServer.RemoveLocalClient(m_Connection);
|
||||
m_LocalServer.RemoveLocalClient();
|
||||
}
|
||||
|
||||
internal void InternalConnectLocalServer(bool generateConnectMsg)
|
||||
|
@ -22,7 +22,7 @@ namespace QuantumUNET
|
||||
m_SimpleServerSimple = new ServerSimpleWrapper(this);
|
||||
}
|
||||
|
||||
public static List<QNetworkConnection> localConnections => instance.m_LocalConnectionsFakeList;
|
||||
public static QNetworkConnection localConnection => instance.m_LocalConnection;
|
||||
|
||||
public static int listenPort => instance.m_SimpleServerSimple.listenPort;
|
||||
|
||||
@ -151,7 +151,7 @@ namespace QuantumUNET
|
||||
internal int AddLocalClient(QLocalClient localClient)
|
||||
{
|
||||
int result;
|
||||
if (m_LocalConnectionsFakeList.Count != 0)
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
QLog.Error("Local Connection already exists");
|
||||
result = -1;
|
||||
@ -163,7 +163,6 @@ namespace QuantumUNET
|
||||
connectionId = 0
|
||||
};
|
||||
m_SimpleServerSimple.SetConnectionAtIndex(m_LocalConnection);
|
||||
m_LocalConnectionsFakeList.Add(m_LocalConnection);
|
||||
m_LocalConnection.InvokeHandlerNoData(32);
|
||||
result = 0;
|
||||
}
|
||||
@ -171,17 +170,8 @@ namespace QuantumUNET
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void RemoveLocalClient(QNetworkConnection localClientConnection)
|
||||
internal void RemoveLocalClient()
|
||||
{
|
||||
for (var i = 0; i < m_LocalConnectionsFakeList.Count; i++)
|
||||
{
|
||||
if (m_LocalConnectionsFakeList[i].connectionId == localClientConnection.connectionId)
|
||||
{
|
||||
m_LocalConnectionsFakeList.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_LocalConnection != null)
|
||||
{
|
||||
m_LocalConnection.Disconnect();
|
||||
@ -1351,8 +1341,6 @@ namespace QuantumUNET
|
||||
|
||||
private bool m_LocalClientActive;
|
||||
|
||||
private readonly List<QNetworkConnection> m_LocalConnectionsFakeList = new();
|
||||
|
||||
private QULocalConnectionToClient m_LocalConnection;
|
||||
|
||||
private readonly QNetworkScene m_NetworkScene;
|
||||
|
Loading…
x
Reference in New Issue
Block a user