2020-08-22 18:08:25 +01:00
|
|
|
|
using OWML.Common;
|
2020-09-06 09:07:31 +01:00
|
|
|
|
using OWML.ModHelper.Events;
|
2020-08-22 18:08:25 +01:00
|
|
|
|
using QSB.Animation;
|
2020-08-13 21:46:16 +02:00
|
|
|
|
using QSB.DeathSync;
|
2020-09-17 20:14:55 +01:00
|
|
|
|
using QSB.ElevatorSync;
|
2020-11-03 21:42:14 +00:00
|
|
|
|
using QSB.EventsCore;
|
2020-08-13 19:25:12 +02:00
|
|
|
|
using QSB.GeyserSync;
|
2020-11-20 19:50:31 +00:00
|
|
|
|
using QSB.Instruments;
|
2020-09-04 20:54:34 +01:00
|
|
|
|
using QSB.OrbSync;
|
2020-11-03 21:11:10 +00:00
|
|
|
|
using QSB.Patches;
|
2020-11-03 21:33:48 +00:00
|
|
|
|
using QSB.Player;
|
2020-12-04 22:14:53 +00:00
|
|
|
|
using QuantumUNET;
|
2020-11-03 22:29:23 +00:00
|
|
|
|
using QSB.SectorSync;
|
2020-02-24 19:55:16 +01:00
|
|
|
|
using QSB.TimeSync;
|
2020-02-21 23:36:07 +01:00
|
|
|
|
using QSB.TransformSync;
|
2020-07-30 22:27:14 +02:00
|
|
|
|
using QSB.Utility;
|
2020-09-04 20:57:35 +01:00
|
|
|
|
using QSB.WorldSync;
|
2020-08-21 14:04:13 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
2020-02-21 23:36:07 +01:00
|
|
|
|
using UnityEngine;
|
2020-02-13 20:23:26 +01:00
|
|
|
|
using UnityEngine.Networking;
|
|
|
|
|
|
2020-02-15 20:48:02 +01:00
|
|
|
|
namespace QSB
|
|
|
|
|
{
|
2020-12-02 21:29:53 +00:00
|
|
|
|
public class QSBNetworkManager : QSBNetworkManagerUNET
|
|
|
|
|
{
|
|
|
|
|
private const int MaxConnections = 128;
|
|
|
|
|
private const int MaxBufferedPackets = 64;
|
|
|
|
|
|
|
|
|
|
public static QSBNetworkManager Instance { get; private set; }
|
|
|
|
|
|
|
|
|
|
public event Action OnNetworkManagerReady;
|
2020-12-03 08:28:05 +00:00
|
|
|
|
|
2020-12-02 21:29:53 +00:00
|
|
|
|
public bool IsReady { get; private set; }
|
|
|
|
|
|
|
|
|
|
private QSBNetworkLobby _lobby;
|
|
|
|
|
private AssetBundle _assetBundle;
|
|
|
|
|
private GameObject _shipPrefab;
|
|
|
|
|
private GameObject _cameraPrefab;
|
|
|
|
|
private GameObject _probePrefab;
|
|
|
|
|
public GameObject OrbPrefab;
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
|
{
|
|
|
|
|
Instance = this;
|
|
|
|
|
|
|
|
|
|
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
|
|
|
|
|
_assetBundle = QSB.NetworkAssetBundle;
|
|
|
|
|
|
|
|
|
|
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkplayer.prefab");
|
|
|
|
|
var ident = playerPrefab.AddComponent<QSBNetworkIdentity>();
|
|
|
|
|
ident.LocalPlayerAuthority = true;
|
|
|
|
|
ident.SetValue("m_AssetId", playerPrefab.GetComponent<NetworkIdentity>().assetId);
|
|
|
|
|
ident.SetValue("m_SceneId", playerPrefab.GetComponent<NetworkIdentity>().sceneId);
|
2020-12-04 09:23:27 +00:00
|
|
|
|
Destroy(playerPrefab.GetComponent<NetworkTransform>());
|
|
|
|
|
Destroy(playerPrefab.GetComponent<NetworkIdentity>());
|
|
|
|
|
var transform = playerPrefab.AddComponent<QSBNetworkTransform>();
|
|
|
|
|
transform.SendInterval = 0.1f;
|
|
|
|
|
transform.SyncRotationAxis = QSBNetworkTransform.AxisSyncMode.AxisXYZ;
|
2020-12-02 21:29:53 +00:00
|
|
|
|
playerPrefab.AddComponent<PlayerTransformSync>();
|
|
|
|
|
playerPrefab.AddComponent<AnimationSync>();
|
|
|
|
|
playerPrefab.AddComponent<WakeUpSync>();
|
|
|
|
|
playerPrefab.AddComponent<InstrumentsManager>();
|
|
|
|
|
|
|
|
|
|
_shipPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkship.prefab");
|
|
|
|
|
ident = _shipPrefab.AddComponent<QSBNetworkIdentity>();
|
|
|
|
|
ident.LocalPlayerAuthority = true;
|
|
|
|
|
ident.SetValue("m_AssetId", _shipPrefab.GetComponent<NetworkIdentity>().assetId);
|
|
|
|
|
ident.SetValue("m_SceneId", _shipPrefab.GetComponent<NetworkIdentity>().sceneId);
|
2020-12-04 09:23:27 +00:00
|
|
|
|
Destroy(_shipPrefab.GetComponent<NetworkTransform>());
|
|
|
|
|
Destroy(_shipPrefab.GetComponent<NetworkIdentity>());
|
|
|
|
|
transform = _shipPrefab.AddComponent<QSBNetworkTransform>();
|
|
|
|
|
transform.SendInterval = 0.1f;
|
|
|
|
|
transform.SyncRotationAxis = QSBNetworkTransform.AxisSyncMode.AxisXYZ;
|
2020-12-02 21:29:53 +00:00
|
|
|
|
_shipPrefab.AddComponent<ShipTransformSync>();
|
|
|
|
|
spawnPrefabs.Add(_shipPrefab);
|
|
|
|
|
|
|
|
|
|
_cameraPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkcameraroot.prefab");
|
|
|
|
|
ident = _cameraPrefab.AddComponent<QSBNetworkIdentity>();
|
|
|
|
|
ident.LocalPlayerAuthority = true;
|
|
|
|
|
ident.SetValue("m_AssetId", _cameraPrefab.GetComponent<NetworkIdentity>().assetId);
|
|
|
|
|
ident.SetValue("m_SceneId", _cameraPrefab.GetComponent<NetworkIdentity>().sceneId);
|
2020-12-04 09:23:27 +00:00
|
|
|
|
Destroy(_cameraPrefab.GetComponent<NetworkTransform>());
|
|
|
|
|
Destroy(_cameraPrefab.GetComponent<NetworkIdentity>());
|
|
|
|
|
transform = _cameraPrefab.AddComponent<QSBNetworkTransform>();
|
|
|
|
|
transform.SendInterval = 0.1f;
|
|
|
|
|
transform.SyncRotationAxis = QSBNetworkTransform.AxisSyncMode.AxisXYZ;
|
2020-12-02 21:29:53 +00:00
|
|
|
|
_cameraPrefab.AddComponent<PlayerCameraSync>();
|
|
|
|
|
spawnPrefabs.Add(_cameraPrefab);
|
|
|
|
|
|
|
|
|
|
_probePrefab = _assetBundle.LoadAsset<GameObject>("assets/networkprobe.prefab");
|
|
|
|
|
ident = _probePrefab.AddComponent<QSBNetworkIdentity>();
|
|
|
|
|
ident.LocalPlayerAuthority = true;
|
|
|
|
|
ident.SetValue("m_AssetId", _probePrefab.GetComponent<NetworkIdentity>().assetId);
|
|
|
|
|
ident.SetValue("m_SceneId", _probePrefab.GetComponent<NetworkIdentity>().sceneId);
|
2020-12-04 09:23:27 +00:00
|
|
|
|
Destroy(_probePrefab.GetComponent<NetworkTransform>());
|
|
|
|
|
Destroy(_probePrefab.GetComponent<NetworkIdentity>());
|
|
|
|
|
transform = _probePrefab.AddComponent<QSBNetworkTransform>();
|
|
|
|
|
transform.SendInterval = 0.1f;
|
|
|
|
|
transform.SyncRotationAxis = QSBNetworkTransform.AxisSyncMode.AxisXYZ;
|
2020-12-02 21:29:53 +00:00
|
|
|
|
_probePrefab.AddComponent<PlayerProbeSync>();
|
|
|
|
|
spawnPrefabs.Add(_probePrefab);
|
|
|
|
|
|
|
|
|
|
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
|
|
|
|
|
ident = OrbPrefab.AddComponent<QSBNetworkIdentity>();
|
|
|
|
|
ident.LocalPlayerAuthority = true;
|
|
|
|
|
ident.SetValue("m_AssetId", OrbPrefab.GetComponent<NetworkIdentity>().assetId);
|
|
|
|
|
ident.SetValue("m_SceneId", OrbPrefab.GetComponent<NetworkIdentity>().sceneId);
|
2020-12-04 09:23:27 +00:00
|
|
|
|
Destroy(OrbPrefab.GetComponent<NetworkTransform>());
|
|
|
|
|
Destroy(OrbPrefab.GetComponent<NetworkIdentity>());
|
|
|
|
|
transform = OrbPrefab.AddComponent<QSBNetworkTransform>();
|
|
|
|
|
transform.SendInterval = 0.1f;
|
|
|
|
|
transform.SyncRotationAxis = QSBNetworkTransform.AxisSyncMode.AxisXYZ;
|
2020-12-02 21:29:53 +00:00
|
|
|
|
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
|
|
|
|
|
spawnPrefabs.Add(OrbPrefab);
|
|
|
|
|
|
|
|
|
|
ConfigureNetworkManager();
|
|
|
|
|
QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
=> QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
|
|
|
|
|
|
|
|
|
|
private void OnSceneLoaded(OWScene scene)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("scene loaded");
|
|
|
|
|
OrbManager.Instance.BuildOrbs();
|
|
|
|
|
OrbManager.Instance.QueueBuildSlots();
|
|
|
|
|
WorldRegistry.OldDialogueTrees.Clear();
|
|
|
|
|
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ConfigureNetworkManager()
|
|
|
|
|
{
|
|
|
|
|
networkAddress = QSB.DefaultServerIP;
|
|
|
|
|
networkPort = QSB.Port;
|
|
|
|
|
maxConnections = MaxConnections;
|
|
|
|
|
customConfig = true;
|
|
|
|
|
connectionConfig.AddChannel(QosType.Reliable);
|
|
|
|
|
connectionConfig.AddChannel(QosType.Unreliable);
|
|
|
|
|
this.SetValue("m_MaxBufferedPackets", MaxBufferedPackets);
|
|
|
|
|
channels.Add(QosType.Reliable);
|
|
|
|
|
channels.Add(QosType.Unreliable);
|
|
|
|
|
|
|
|
|
|
DebugLog.DebugWrite("Network Manager ready.", MessageType.Success);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnStartServer()
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnStartServer", MessageType.Info);
|
|
|
|
|
if (WorldRegistry.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
|
|
|
|
|
{
|
|
|
|
|
OrbManager.Instance.QueueBuildOrbs();
|
|
|
|
|
}
|
|
|
|
|
if (WorldRegistry.OldDialogueTrees.Count == 0 && QSBSceneManager.IsInUniverse)
|
|
|
|
|
{
|
|
|
|
|
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnServerAddPlayer(QSBNetworkConnection connection, short playerControllerId) // Called on the server when a client joins
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnServerAddPlayer", MessageType.Info);
|
|
|
|
|
base.OnServerAddPlayer(connection, playerControllerId);
|
|
|
|
|
|
|
|
|
|
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
|
|
|
|
|
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
|
|
|
|
|
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnClientConnect(QSBNetworkConnection connection) // Called on the client when connecting to a server
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnClientConnect", MessageType.Info);
|
|
|
|
|
base.OnClientConnect(connection);
|
|
|
|
|
|
|
|
|
|
gameObject.AddComponent<SectorSync.SectorSync>();
|
|
|
|
|
gameObject.AddComponent<RespawnOnDeath>();
|
|
|
|
|
gameObject.AddComponent<PreventShipDestruction>();
|
|
|
|
|
|
|
|
|
|
if (QSBSceneManager.IsInUniverse)
|
|
|
|
|
{
|
|
|
|
|
QSBSectorManager.Instance.RebuildSectors();
|
|
|
|
|
OrbManager.Instance.QueueBuildSlots();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!QSBNetworkServer.localClientActive)
|
|
|
|
|
{
|
|
|
|
|
QSBPatchManager.DoPatchType(QSBPatchTypes.OnNonServerClientConnect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
|
|
|
|
|
|
|
|
|
|
_lobby.CanEditName = false;
|
|
|
|
|
|
|
|
|
|
OnNetworkManagerReady?.Invoke();
|
|
|
|
|
IsReady = true;
|
|
|
|
|
|
|
|
|
|
QSB.Helper.Events.Unity.RunWhen(() => PlayerTransformSync.LocalInstance != null, QSBEventManager.Init);
|
|
|
|
|
|
|
|
|
|
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
|
|
|
|
|
() => GlobalMessenger<string>.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
|
|
|
|
|
|
|
|
|
|
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
|
|
|
|
|
() => GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnStopClient() // Called on the client when closing connection
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnStopClient", MessageType.Info);
|
|
|
|
|
DebugLog.ToConsole("Disconnecting from server...", MessageType.Info);
|
|
|
|
|
Destroy(GetComponent<SectorSync.SectorSync>());
|
|
|
|
|
Destroy(GetComponent<RespawnOnDeath>());
|
|
|
|
|
Destroy(GetComponent<PreventShipDestruction>());
|
|
|
|
|
QSBEventManager.Reset();
|
|
|
|
|
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
|
|
|
|
|
|
|
|
|
foreach (var player in QSBPlayerManager.PlayerList)
|
|
|
|
|
{
|
|
|
|
|
QSBPlayerManager.GetPlayerNetIds(player).ForEach(CleanupNetworkBehaviour);
|
|
|
|
|
}
|
|
|
|
|
QSBPlayerManager.RemoveAllPlayers();
|
|
|
|
|
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBOrbSlot>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBElevator>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBGeyser>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBSector>();
|
|
|
|
|
WorldRegistry.OrbSyncList.Clear();
|
|
|
|
|
WorldRegistry.OldDialogueTrees.Clear();
|
|
|
|
|
|
|
|
|
|
_lobby.CanEditName = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnServerDisconnect(QSBNetworkConnection connection) // Called on the server when any client disconnects
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
|
|
|
|
|
var player = connection.GetPlayer();
|
|
|
|
|
var netIds = connection.ClientOwnedObjects.Select(x => x.Value).ToArray();
|
|
|
|
|
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, player.PlayerId, netIds);
|
|
|
|
|
|
|
|
|
|
foreach (var item in WorldRegistry.OrbSyncList)
|
|
|
|
|
{
|
|
|
|
|
var identity = item.GetComponent<QSBNetworkIdentity>();
|
|
|
|
|
if (identity.ClientAuthorityOwner == connection)
|
|
|
|
|
{
|
|
|
|
|
identity.RemoveClientAuthority(connection);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
player.HudMarker?.Remove();
|
|
|
|
|
CleanupConnection(connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnStopServer()
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite("OnStopServer", MessageType.Info);
|
|
|
|
|
Destroy(GetComponent<SectorSync.SectorSync>());
|
|
|
|
|
Destroy(GetComponent<RespawnOnDeath>());
|
|
|
|
|
Destroy(GetComponent<PreventShipDestruction>());
|
|
|
|
|
QSBEventManager.Reset();
|
|
|
|
|
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
|
|
|
|
|
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
|
|
|
|
|
QSBNetworkServer.connections.ToList().ForEach(CleanupConnection);
|
|
|
|
|
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBOrbSlot>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBElevator>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBGeyser>();
|
|
|
|
|
WorldRegistry.RemoveObjects<QSBSector>();
|
|
|
|
|
|
|
|
|
|
base.OnStopServer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CleanupConnection(QSBNetworkConnection connection)
|
|
|
|
|
{
|
|
|
|
|
var player = connection.GetPlayer();
|
|
|
|
|
DebugLog.ToConsole($"{player.Name} disconnected.", MessageType.Info);
|
|
|
|
|
QSBPlayerManager.RemovePlayer(player.PlayerId);
|
|
|
|
|
|
|
|
|
|
var netIds = connection.ClientOwnedObjects?.Select(x => x.Value).ToList();
|
|
|
|
|
netIds.ForEach(CleanupNetworkBehaviour);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CleanupNetworkBehaviour(uint netId)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($"Cleaning up netId {netId}");
|
|
|
|
|
// Multiple networkbehaviours can use the same networkidentity (same netId), so get all of them
|
|
|
|
|
var networkBehaviours = FindObjectsOfType<QSBNetworkBehaviour>()
|
|
|
|
|
.Where(x => x != null && x.NetId.Value == netId);
|
|
|
|
|
foreach (var networkBehaviour in networkBehaviours)
|
|
|
|
|
{
|
|
|
|
|
var transformSync = networkBehaviour.GetComponent<TransformSync.TransformSync>();
|
|
|
|
|
|
|
|
|
|
if (transformSync != null)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($" * Removing TransformSync from syncobjects");
|
|
|
|
|
QSBPlayerManager.PlayerSyncObjects.Remove(transformSync);
|
|
|
|
|
if (transformSync.SyncedTransform != null && netId != QSBPlayerManager.LocalPlayerId && !networkBehaviour.HasAuthority)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($" * Destroying {transformSync.SyncedTransform.gameObject.name}");
|
|
|
|
|
Destroy(transformSync.SyncedTransform.gameObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var animationSync = networkBehaviour.GetComponent<AnimationSync>();
|
|
|
|
|
|
|
|
|
|
if (animationSync != null)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($" * Removing AnimationSync from syncobjects");
|
|
|
|
|
QSBPlayerManager.PlayerSyncObjects.Remove(animationSync);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!networkBehaviour.HasAuthority)
|
|
|
|
|
{
|
|
|
|
|
DebugLog.DebugWrite($" * Destroying {networkBehaviour.gameObject.name}");
|
|
|
|
|
Destroy(networkBehaviour.gameObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-22 21:08:10 +00:00
|
|
|
|
}
|