-
Notifications
You must be signed in to change notification settings - Fork 503
/
ConnectionManager.cs
181 lines (151 loc) · 6.23 KB
/
ConnectionManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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();
}
}
}