mirror of
https://github.com/Dadechin/Unity-WebSocket.git
synced 2025-07-04 04:14:34 +00:00
224 lines
9.4 KiB
C#
224 lines
9.4 KiB
C#
using FishNet.Connection;
|
|
using FishNet.Managing.Logging;
|
|
using FishNet.Managing.Transporting;
|
|
using FishNet.Object;
|
|
using FishNet.Serializing;
|
|
using FishNet.Transporting;
|
|
using FishNet.Transporting.Multipass;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using GameKit.Dependencies.Utilities;
|
|
using UnityEngine;
|
|
|
|
namespace FishNet.Managing.Server
|
|
{
|
|
public sealed partial class ServerManager : MonoBehaviour
|
|
{
|
|
#region Public.
|
|
/// <summary>
|
|
/// Called when a client is removed from the server using Kick. This is invoked before the client is disconnected.
|
|
/// NetworkConnection when available, clientId, and KickReason are provided.
|
|
/// </summary>
|
|
public event Action<NetworkConnection, int, KickReason> OnClientKick;
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Stores a cache and returns a boolean result.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool StoreTransportCacheAndReturn(List<Transport> cache, bool returnedValue)
|
|
{
|
|
CollectionCaches<Transport>.Store(cache);
|
|
return returnedValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if all server sockets have a local connection state of stopped.
|
|
/// </summary>
|
|
public bool AreAllServersStopped()
|
|
{
|
|
List<Transport> transports = NetworkManager.TransportManager.GetAllTransports(includeMultipass: false);
|
|
|
|
foreach (Transport t in transports)
|
|
{
|
|
if (t.GetConnectionState(server: true) != LocalConnectionState.Stopped)
|
|
return StoreTransportCacheAndReturn(transports, returnedValue: false);
|
|
}
|
|
|
|
return StoreTransportCacheAndReturn(transports, returnedValue: true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if only one server is started.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsOnlyOneServerStarted()
|
|
{
|
|
List<Transport> transports = NetworkManager.TransportManager.GetAllTransports(includeMultipass: false);
|
|
|
|
int startedCount = 0;
|
|
|
|
foreach (Transport t in transports)
|
|
{
|
|
if (t.GetConnectionState(true) == LocalConnectionState.Started)
|
|
startedCount++;
|
|
}
|
|
|
|
return StoreTransportCacheAndReturn(transports, (startedCount == 1));
|
|
}
|
|
|
|
[Obsolete("Use IsOnlyOneServerStarted().")]
|
|
public bool OneServerStarted() => IsOnlyOneServerStarted();
|
|
|
|
|
|
/// <summary>
|
|
/// Returns true if any server socket is in the started state.
|
|
/// </summary>
|
|
/// <param name="excludedTransport">When set the transport will be ignored. This value is only used with Multipass.</param>
|
|
public bool IsAnyServerStarted(Transport excludedTransport)
|
|
{
|
|
List<Transport> transports = NetworkManager.TransportManager.GetAllTransports(includeMultipass: false);
|
|
|
|
foreach (Transport t in transports)
|
|
{
|
|
if (t == excludedTransport)
|
|
continue;
|
|
//Another transport is started, no need to load start scenes again.
|
|
if (t.GetConnectionState(true) == LocalConnectionState.Started)
|
|
return StoreTransportCacheAndReturn(transports, returnedValue: true);
|
|
}
|
|
|
|
return StoreTransportCacheAndReturn(transports, returnedValue: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if any server socket is in the started state.
|
|
/// </summary>
|
|
/// <param name="excludedIndex">When set the transport on this index will be ignored. This value is only used with Multipass.</param>
|
|
public bool IsAnyServerStarted(int excludedIndex = TransportConsts.UNSET_TRANSPORT_INDEX)
|
|
{
|
|
Transport excludedTransport = null;
|
|
if (excludedIndex != TransportConsts.UNSET_TRANSPORT_INDEX)
|
|
{
|
|
if (NetworkManager.TransportManager.Transport is Multipass mp)
|
|
excludedTransport = mp.GetTransport(excludedIndex);
|
|
}
|
|
|
|
return IsAnyServerStarted(excludedTransport);
|
|
}
|
|
|
|
[Obsolete("Use IsAnyServerStarted.")]
|
|
public bool AnyServerStarted(int excludedIndex = TransportConsts.UNSET_TRANSPORT_INDEX) => IsAnyServerStarted(excludedIndex);
|
|
|
|
/// <summary>
|
|
/// Spawns an object over the network. Can only be called on the server.
|
|
/// </summary>
|
|
/// <param name="go">GameObject instance to spawn.</param>
|
|
/// <param name="ownerConnection">Connection to give ownership to.</param>
|
|
public void Spawn(GameObject go, NetworkConnection ownerConnection = null, UnityEngine.SceneManagement.Scene scene = default)
|
|
{
|
|
if (go == null)
|
|
{
|
|
NetworkManager.LogWarning($"GameObject cannot be spawned because it is null.");
|
|
return;
|
|
}
|
|
|
|
NetworkObject nob = go.GetComponent<NetworkObject>();
|
|
Spawn(nob, ownerConnection, scene);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spawns an object over the network. Can only be called on the server.
|
|
/// </summary>
|
|
/// <param name="nob">MetworkObject instance to spawn.</param>
|
|
/// <param name="ownerConnection">Connection to give ownership to.</param>
|
|
public void Spawn(NetworkObject nob, NetworkConnection ownerConnection = null, UnityEngine.SceneManagement.Scene scene = default)
|
|
{
|
|
if (!nob.GetIsSpawnable())
|
|
{
|
|
NetworkManager.LogWarning($"NetworkObject {nob} cannot be spawned because it is not marked as spawnable.");
|
|
return;
|
|
}
|
|
Objects.Spawn(nob, ownerConnection, scene);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Despawns an object over the network. Can only be called on the server.
|
|
/// </summary>
|
|
/// <param name="go">GameObject instance to despawn.</param>
|
|
/// <param name="cacheOnDespawnOverride">Overrides the default DisableOnDespawn value for this single despawn. Scene objects will never be destroyed.</param>
|
|
public void Despawn(GameObject go, DespawnType? despawnType = null)
|
|
{
|
|
if (go == null)
|
|
{
|
|
NetworkManager.LogWarning($"GameObject cannot be despawned because it is null.");
|
|
return;
|
|
}
|
|
|
|
NetworkObject nob = go.GetComponent<NetworkObject>();
|
|
Despawn(nob, despawnType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Despawns an object over the network. Can only be called on the server.
|
|
/// </summary>
|
|
/// <param name="networkObject">NetworkObject instance to despawn.</param>
|
|
/// <param name="despawnType">Despawn override type.</param>
|
|
public void Despawn(NetworkObject networkObject, DespawnType? despawnType = null)
|
|
{
|
|
DespawnType resolvedDespawnType = (!despawnType.HasValue) ? networkObject.GetDefaultDespawnType() : despawnType.Value;
|
|
|
|
Objects.Despawn(networkObject, resolvedDespawnType, asServer: true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kicks a connection immediately while invoking OnClientKick.
|
|
/// </summary>
|
|
/// <param name="conn">Client to kick.</param>
|
|
/// <param name="kickReason">Reason client is being kicked.</param>
|
|
/// <param name="loggingType">How to print logging as.</param>
|
|
/// <param name="log">Optional message to be debug logged.</param>
|
|
public void Kick(NetworkConnection conn, KickReason kickReason, LoggingType loggingType = LoggingType.Common, string log = "")
|
|
{
|
|
if (!conn.IsValid)
|
|
return;
|
|
|
|
OnClientKick?.Invoke(conn, conn.ClientId, kickReason);
|
|
if (conn.IsActive)
|
|
conn.Disconnect(true);
|
|
|
|
if (!string.IsNullOrEmpty(log))
|
|
NetworkManager.Log(loggingType, log);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kicks a connection immediately while invoking OnClientKick.
|
|
/// </summary>
|
|
/// <param name="clientId">ClientId to kick.</param>
|
|
/// <param name="kickReason">Reason client is being kicked.</param>
|
|
/// <param name="loggingType">How to print logging as.</param>
|
|
/// <param name="log">Optional message to be debug logged.</param>
|
|
public void Kick(int clientId, KickReason kickReason, LoggingType loggingType = LoggingType.Common, string log = "")
|
|
{
|
|
OnClientKick?.Invoke(null, clientId, kickReason);
|
|
NetworkManager.TransportManager.Transport.StopConnection(clientId, true);
|
|
if (!string.IsNullOrEmpty(log))
|
|
NetworkManager.Log(loggingType, log);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kicks a connection immediately while invoking OnClientKick.
|
|
/// </summary>
|
|
/// <param name="conn">Client to kick.</param>
|
|
/// <param name="reader">Reader to clear before kicking.</param>
|
|
/// <param name="kickReason">Reason client is being kicked.</param>
|
|
/// <param name="loggingType">How to print logging as.</param>
|
|
/// <param name="log">Optional message to be debug logged.</param>
|
|
public void Kick(NetworkConnection conn, Reader reader, KickReason kickReason, LoggingType loggingType = LoggingType.Common, string log = "")
|
|
{
|
|
reader.Clear();
|
|
Kick(conn, kickReason, loggingType, log);
|
|
}
|
|
}
|
|
} |