You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.2 KiB
C#
182 lines
6.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.BossRoom.Utils;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UUnity.BossRoom.ConnectionManagement;
|
|
using VContainer;
|
|
|
|
namespace Unity.BossRoom.ConnectionManagement
|
|
{
|
|
public enum ConnectStatus
|
|
{
|
|
Undefined,
|
|
Success, //client successfully connected. This may also be a successful reconnect.
|
|
ServerFull, //can't join, server is already at capacity.
|
|
LoggedInAgain, //logged in on a separate client, causing this one to be kicked out.
|
|
UserRequestedDisconnect, //Intentional Disconnect triggered by the user.
|
|
GenericDisconnect, //server disconnected, but no specific reason given.
|
|
Reconnecting, //client lost connection and is attempting to reconnect.
|
|
IncompatibleBuildType, //client build type is incompatible with server.
|
|
HostEndedSession, //host intentionally ended the session.
|
|
StartHostFailed, // server failed to bind
|
|
StartClientFailed // failed to connect to server and/or invalid network endpoint
|
|
}
|
|
|
|
public struct ReconnectMessage
|
|
{
|
|
public int CurrentAttempt;
|
|
public int MaxAttempt;
|
|
|
|
public ReconnectMessage(int currentAttempt, int maxAttempt)
|
|
{
|
|
CurrentAttempt = currentAttempt;
|
|
MaxAttempt = maxAttempt;
|
|
}
|
|
}
|
|
|
|
public struct ConnectionEventMessage : INetworkSerializeByMemcpy
|
|
{
|
|
public ConnectStatus ConnectStatus;
|
|
public FixedPlayerName PlayerName;
|
|
}
|
|
|
|
[Serializable]
|
|
public class ConnectionPayload
|
|
{
|
|
public string playerId;
|
|
public string playerName;
|
|
public bool isDebug;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This state machine handles connection through the NetworkManager. It is responsible for listening to
|
|
/// NetworkManger callbacks and other outside calls and redirecting them to the current ConnectionState object.
|
|
/// </summary>
|
|
public class ConnectionManager : MonoBehaviour
|
|
{
|
|
ConnectionState m_CurrentState;
|
|
|
|
[Inject]
|
|
NetworkManager m_NetworkManager;
|
|
public NetworkManager NetworkManager => m_NetworkManager;
|
|
|
|
[SerializeField]
|
|
int m_NbReconnectAttempts = 2;
|
|
|
|
public int NbReconnectAttempts => m_NbReconnectAttempts;
|
|
|
|
[Inject]
|
|
IObjectResolver m_Resolver;
|
|
|
|
public int MaxConnectedPlayers = 8;
|
|
|
|
internal readonly OfflineState m_Offline = new OfflineState();
|
|
internal readonly ClientConnectingState m_ClientConnecting = new ClientConnectingState();
|
|
internal readonly ClientConnectedState m_ClientConnected = new ClientConnectedState();
|
|
internal readonly ClientReconnectingState m_ClientReconnecting = new ClientReconnectingState();
|
|
internal readonly StartingHostState m_StartingHost = new StartingHostState();
|
|
internal readonly HostingState m_Hosting = new HostingState();
|
|
|
|
void Awake()
|
|
{
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
List<ConnectionState> states = new() { m_Offline, m_ClientConnecting, m_ClientConnected, m_ClientReconnecting, m_StartingHost, m_Hosting };
|
|
foreach (var connectionState in states)
|
|
{
|
|
m_Resolver.Inject(connectionState);
|
|
}
|
|
|
|
m_CurrentState = m_Offline;
|
|
|
|
NetworkManager.OnClientConnectedCallback += OnClientConnectedCallback;
|
|
NetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback;
|
|
NetworkManager.OnServerStarted += OnServerStarted;
|
|
NetworkManager.ConnectionApprovalCallback += ApprovalCheck;
|
|
NetworkManager.OnTransportFailure += OnTransportFailure;
|
|
NetworkManager.OnServerStopped += OnServerStopped;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
NetworkManager.OnClientConnectedCallback -= OnClientConnectedCallback;
|
|
NetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback;
|
|
NetworkManager.OnServerStarted -= OnServerStarted;
|
|
NetworkManager.ConnectionApprovalCallback -= ApprovalCheck;
|
|
NetworkManager.OnTransportFailure -= OnTransportFailure;
|
|
NetworkManager.OnServerStopped -= OnServerStopped;
|
|
}
|
|
|
|
internal void ChangeState(ConnectionState nextState)
|
|
{
|
|
Debug.Log($"{name}: Changed connection state from {m_CurrentState.GetType().Name} to {nextState.GetType().Name}.");
|
|
|
|
if (m_CurrentState != null)
|
|
{
|
|
m_CurrentState.Exit();
|
|
}
|
|
m_CurrentState = nextState;
|
|
m_CurrentState.Enter();
|
|
}
|
|
|
|
void OnClientDisconnectCallback(ulong clientId)
|
|
{
|
|
m_CurrentState.OnClientDisconnect(clientId);
|
|
}
|
|
|
|
void OnClientConnectedCallback(ulong clientId)
|
|
{
|
|
m_CurrentState.OnClientConnected(clientId);
|
|
}
|
|
|
|
void OnServerStarted()
|
|
{
|
|
m_CurrentState.OnServerStarted();
|
|
}
|
|
|
|
void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
|
|
{
|
|
m_CurrentState.ApprovalCheck(request, response);
|
|
}
|
|
|
|
void OnTransportFailure()
|
|
{
|
|
m_CurrentState.OnTransportFailure();
|
|
}
|
|
|
|
void OnServerStopped(bool _) // we don't need this parameter as the ConnectionState already carries the relevant information
|
|
{
|
|
m_CurrentState.OnServerStopped();
|
|
}
|
|
|
|
public void StartClientLobby(string playerName)
|
|
{
|
|
m_CurrentState.StartClientLobby(playerName);
|
|
}
|
|
|
|
public void StartClientIp(string playerName, string ipaddress, int port)
|
|
{
|
|
m_CurrentState.StartClientIP(playerName, ipaddress, port);
|
|
}
|
|
|
|
public void StartHostLobby(string playerName)
|
|
{
|
|
m_CurrentState.StartHostLobby(playerName);
|
|
}
|
|
|
|
public void StartHostIp(string playerName, string ipaddress, int port)
|
|
{
|
|
m_CurrentState.StartHostIP(playerName, ipaddress, port);
|
|
}
|
|
|
|
public void RequestShutdown()
|
|
{
|
|
m_CurrentState.OnUserRequestedShutdown();
|
|
}
|
|
}
|
|
}
|