Merge branch 'disconnect-fixes' of https://github.com/Raicuparta/quantum-space-buddies into disconnect-fixes

This commit is contained in:
Mister_Nebula 2020-08-19 21:30:41 +01:00
commit 0fe4ed1446
7 changed files with 117 additions and 151 deletions

View File

@ -1,8 +1,6 @@
using QSB.Messaging;
using QSB.Utility;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
namespace QSB.Events
{
@ -20,12 +18,12 @@ namespace QSB.Events
GlobalMessenger<uint, uint[]>.RemoveListener(EventNames.QSBPlayerLeave, Handler);
}
private void Handler(uint id, uint[] objects) => SendEvent(CreateMessage(id, objects));
private void Handler(uint playerId, uint[] netIds) => SendEvent(CreateMessage(playerId, netIds));
private PlayerLeaveMessage CreateMessage(uint id, uint[] objects) => new PlayerLeaveMessage
private PlayerLeaveMessage CreateMessage(uint playerId, uint[] netIds) => new PlayerLeaveMessage
{
AboutId = id,
ObjectIds = objects
AboutId = playerId,
NetIds = netIds
};
public override void OnReceiveRemote(PlayerLeaveMessage message)
@ -33,40 +31,7 @@ namespace QSB.Events
var playerName = PlayerRegistry.GetPlayer(message.AboutId).Name;
DebugLog.ToConsole($"{playerName} disconnected.", OWML.Common.MessageType.Info);
PlayerRegistry.RemovePlayer(message.AboutId);
foreach (var objectId in message.ObjectIds)
{
DestroyObject(objectId);
}
}
private void DestroyObject(uint objectId)
{
DebugLog.ToConsole("Destroying object " + objectId);
var components = Object.FindObjectsOfType<NetworkBehaviour>()
.Where(x => x.netId.Value == objectId);
foreach (var component in components)
{
DebugLog.ToConsole("* For object " + component.GetType().Name);
if (component == null)
{
DebugLog.ToConsole(" * Component is null!");
return;
}
var transformSync = component.GetComponent<TransformSync.TransformSync>();
if (transformSync != null)
{
DebugLog.ToConsole(" * TS is not null - removing from list");
PlayerRegistry.TransformSyncs.Remove(transformSync);
if (transformSync.SyncedTransform != null)
{
DebugLog.ToConsole(" * TS's ST is not null - destroying");
Object.Destroy(transformSync.SyncedTransform.gameObject);
}
}
DebugLog.ToConsole(" * Destroying component's gameobject " + component.gameObject.name);
Object.Destroy(component.gameObject);
}
message.NetIds.ToList().ForEach(netId => QSBNetworkManager.Instance.CleanupNetworkBehaviour(netId));
}
}
}

View File

@ -13,14 +13,14 @@ namespace QSB.Messaging
public MessageHandler(MessageType messageType)
{
_messageType = messageType + 1 + MsgType.Highest;
if (QSBNetworkManager.IsReady)
_messageType = messageType + MsgType.Highest + 1;
if (QSBNetworkManager.Instance.IsReady)
{
Init();
}
else
{
QSBNetworkManager.OnNetworkManagerReady.AddListener(Init);
QSBNetworkManager.Instance.OnNetworkManagerReady += Init;
}
}
@ -32,7 +32,7 @@ namespace QSB.Messaging
public void SendToAll(T message)
{
if (!QSBNetworkManager.IsReady)
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
@ -41,7 +41,7 @@ namespace QSB.Messaging
public void SendToServer(T message)
{
if (!QSBNetworkManager.IsReady)
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}

View File

@ -6,18 +6,18 @@ namespace QSB.Messaging
{
public class PlayerLeaveMessage : PlayerMessage
{
public uint[] ObjectIds { get; set; }
public uint[] NetIds { get; set; }
public override void Deserialize(NetworkReader reader)
{
base.Deserialize(reader);
ObjectIds = reader.ReadString().Split(',').Select(x => Convert.ToUInt32(x)).ToArray();
NetIds = reader.ReadString().Split(',').Select(x => Convert.ToUInt32(x)).ToArray();
}
public override void Serialize(NetworkWriter writer)
{
base.Serialize(writer);
writer.Write(string.Join(",", ObjectIds.Select(x => x.ToString()).ToArray()));
writer.Write(string.Join(",", NetIds.Select(x => x.ToString()).ToArray()));
}
}
}

View File

@ -134,6 +134,7 @@
<Compile Include="Events\EventNames.cs" />
<Compile Include="DeathSync\PlayerDeathEvent.cs" />
<Compile Include="Events\IQSBEvent.cs" />
<Compile Include="QSBNetworkLobby.cs" />
<Compile Include="QSBSceneManager.cs" />
<Compile Include="TimeSync\WakeUpPatches.cs" />
<Compile Include="Tools\PlayerFlashlightEvent.cs" />

68
QSB/QSBNetworkLobby.cs Normal file
View File

@ -0,0 +1,68 @@
using System;
using System.Linq;
using OWML.ModHelper.Events;
using UnityEngine;
using UnityEngine.Networking;
namespace QSB
{
public class QSBNetworkLobby : NetworkBehaviour
{
public bool CanEditName { get; set; }
public string PlayerName { get; private set; }
private readonly string[] _defaultNames = {
"Arkose",
"Chert",
"Esker",
"Hal",
"Hornfels",
"Feldspar",
"Gabbro",
"Galena",
"Gneiss",
"Gossan",
"Marl",
"Mica",
"Moraine",
"Porphy",
"Riebeck",
"Rutile",
"Slate",
"Spinel",
"Tektite",
"Tephra",
"Tuff"
};
private void Awake()
{
PlayerName = GetPlayerName();
CanEditName = true;
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile?.profileName;
return !string.IsNullOrEmpty(profileName)
? profileName
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
}
private void OnGUI()
{
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
if (CanEditName)
{
PlayerName = GUI.TextField(new Rect(60, 10, 145, 20f), PlayerName);
}
else
{
GUI.Label(new Rect(60, 10, 145, 20f), PlayerName);
}
}
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Linq;
using OWML.ModHelper.Events;
using QSB.Animation;
using QSB.DeathSync;
using QSB.Events;
@ -9,51 +8,30 @@ using QSB.TimeSync;
using QSB.TransformSync;
using QSB.Utility;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
namespace QSB
{
public class QSBNetworkManager : NetworkManager
{
public static UnityEvent OnNetworkManagerReady = new UnityEvent();
public static bool IsReady;
private const int MaxConnections = 128;
public static QSBNetworkManager Instance { get; private set; }
public event Action OnNetworkManagerReady;
public bool IsReady { get; private set; }
private QSBNetworkLobby _lobby;
private AssetBundle _assetBundle;
private GameObject _shipPrefab;
private GameObject _cameraPrefab;
private GameObject _probePrefab;
private readonly string[] _defaultNames = {
"Arkose",
"Chert",
"Esker",
"Hal",
"Hornfels",
"Feldspar",
"Gabbro",
"Galena",
"Gneiss",
"Gossan",
"Marl",
"Mica",
"Moraine",
"Porphy",
"Riebeck",
"Rutile",
"Slate",
"Spinel",
"Tektite",
"Tephra",
"Tuff"
};
private string _playerName;
private bool _canEditName;
private void Awake()
{
Instance = this;
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
_assetBundle = QSB.NetworkAssetBundle;
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkplayer.prefab");
@ -74,20 +52,6 @@ namespace QSB
spawnPrefabs.Add(_probePrefab);
ConfigureNetworkManager();
_playerName = GetPlayerName();
_canEditName = true;
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile?.profileName;
return !string.IsNullOrEmpty(profileName)
? profileName
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
}
private void ConfigureNetworkManager()
@ -129,7 +93,7 @@ namespace QSB
WakeUpPatches.AddPatches();
}
_canEditName = false;
_lobby.CanEditName = false;
OnNetworkManagerReady.Invoke();
IsReady = true;
@ -137,7 +101,7 @@ namespace QSB
UnityHelper.Instance.RunWhen(() => PlayerTransformSync.LocalInstance != null, EventList.Init);
UnityHelper.Instance.RunWhen(() => EventList.Ready,
() => GlobalMessenger<string>.FireEvent(EventNames.QSBPlayerJoin, _playerName));
() => GlobalMessenger<string>.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
}
public override void OnStopClient() // Called on the client when closing connection
@ -147,73 +111,49 @@ namespace QSB
Destroy(GetComponent<RespawnOnDeath>());
Destroy(GetComponent<PreventShipDestruction>());
EventList.Reset();
foreach (var player in PlayerRegistry.PlayerList)
{
if (player.HudMarker != null)
{
Destroy(player.HudMarker.transform.parent.gameObject);
}
}
foreach (var connection in NetworkServer.connections.Where(
x => x.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value != PlayerRegistry.LocalPlayerId
))
{
CleanupConnection(connection);
}
_canEditName = true;
PlayerRegistry.PlayerList.ForEach(player => player.HudMarker?.Remove());
NetworkServer.connections.ToList()Where(x => x.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value != PlayerRegistry.LocalPlayerId).ForEach(CleanupConnection);
_lobby.CanEditName = true;
}
public override void OnServerDisconnect(NetworkConnection connection) // Called on the server when any client disconnects
{
var playerId = connection.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value;
var objectIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, playerId, objectIds);
var marker = PlayerRegistry.GetPlayer(playerId).HudMarker;
if (marker != null)
{
Destroy(marker.transform.parent.gameObject);
}
var netIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, playerId, netIds);
PlayerRegistry.GetPlayer(playerId).HudMarker?.Remove();
CleanupConnection(connection);
}
public override void OnStopServer()
{
DebugLog.ToConsole("Server stopped!", OWML.Common.MessageType.Info);
foreach (var connection in NetworkServer.connections)
{
CleanupConnection(connection);
}
NetworkServer.connections.ToList().ForEach(CleanupConnection);
base.OnStopServer();
}
private void CleanupConnection(NetworkConnection connection)
{
var playerId = connection.playerControllers[0].gameObject.GetComponent<PlayerTransformSync>().netId.Value;
var objectIds = connection.clientOwnedObjects.Select(x => x.Value).ToArray();
var playerName = PlayerRegistry.GetPlayer(playerId).Name;
DebugLog.ToConsole($"{playerName} disconnected.", OWML.Common.MessageType.Info);
PlayerRegistry.RemovePlayer(playerId);
foreach (var objectId in objectIds)
{
DestroyObject(objectId);
}
var netIds = connection.clientOwnedObjects.Select(x => x.Value).ToList();
netIds.ForEach(CleanupNetworkBehaviour);
}
private void DestroyObject(uint objectId)
public void CleanupNetworkBehaviour(uint netId)
{
DebugLog.ToConsole("Destroying object " + objectId);
var components = FindObjectsOfType<NetworkBehaviour>()
.Where(x => x.netId.Value == objectId);
foreach (var component in components)
var networkBehaviours = FindObjectsOfType<NetworkBehaviour>()
.Where(x => x.netId.Value == netId);
foreach (var networkBehaviour in networkBehaviours)
{
DebugLog.ToConsole("* For object " + component.GetType().Name);
if (component == null)
if (networkBehaviour == null)
{
DebugLog.ToConsole(" * Component is null!");
return;
continue;
}
var transformSync = component.GetComponent<TransformSync.TransformSync>();
var transformSync = networkBehaviour.GetComponent<TransformSync.TransformSync>();
if (transformSync != null)
{
@ -225,21 +165,7 @@ namespace QSB
Destroy(transformSync.SyncedTransform.gameObject);
}
}
DebugLog.ToConsole(" * Destroying component's gameobject " + component.gameObject.name);
Destroy(component.gameObject);
}
}
private void OnGUI()
{
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
if (_canEditName)
{
_playerName = GUI.TextField(new Rect(60, 10, 145, 20f), _playerName);
}
else
{
GUI.Label(new Rect(60, 10, 145, 20f), _playerName);
Destroy(networkBehaviour.gameObject);
}
}

View File

@ -43,5 +43,11 @@ namespace QSB.TransformSync
base.InitCanvasMarker();
}
public void Remove()
{
Destroy(transform.parent.gameObject);
}
}
}