-
Notifications
You must be signed in to change notification settings - Fork 557
refactor: replacing GameNetPortal with state machine [MTT-1742] [MTT-3501] [MTT-3502] #666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
decf8bf
f774161
40f7167
0ab59b2
0382392
2d3b0bb
314f670
385fff2
5263998
fb212ec
f923235
bedb352
6237f47
523e077
ac49f7c
c7eaf27
5a808c0
0461c0b
6b3ac0f
fe1880e
109833d
64f61d1
2516936
40b66e6
7bc15ca
efcc4b8
3912002
d95e29b
a929a1a
aa9b3a3
700b739
c19c1bc
0356b9a
256f0ae
cd56a35
cd7b918
80fd94d
ce0696a
45de54c
9904023
2cf47ba
cb481ab
3e01a71
b7513ab
f0288b6
714d33d
c5f01a8
e4a567a
a35968e
02a4fe4
053d05f
e2b1423
def793d
2db5499
54fc503
f99bd5d
d9ab783
8ee8cfe
e521195
01a0eb2
470fcde
4aca034
51c4ff4
cc84ca9
be3cfff
8f04c12
d37e6e6
afcffbe
29e6e5a
e729b92
37dca8c
9ff4cd6
7303007
d26d52b
87c173d
4e052b4
7498702
f733ae3
b9afaca
30815f7
2d5cd2a
f5debcd
ec046e5
b949e49
de9f67f
d6ee26d
73abe8f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Unity.Collections; | ||
using Unity.Netcode; | ||
using UnityEngine; | ||
using VContainer; | ||
|
||
namespace Unity.Multiplayer.Samples.BossRoom | ||
{ | ||
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; | ||
|
||
[SerializeField] | ||
NetworkManager m_NetworkManager; | ||
public NetworkManager NetworkManager => m_NetworkManager; | ||
|
||
[SerializeField] | ||
NetworkObject m_GameState; | ||
public NetworkObject GameState => m_GameState; | ||
|
||
[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 DisconnectingWithReasonState m_DisconnectingWithReason = new DisconnectingWithReasonState(); | ||
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_DisconnectingWithReason, 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; | ||
} | ||
|
||
void OnDestroy() | ||
{ | ||
NetworkManager.OnClientConnectedCallback -= OnClientConnectedCallback; | ||
NetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback; | ||
NetworkManager.OnServerStarted -= OnServerStarted; | ||
NetworkManager.ConnectionApprovalCallback -= ApprovalCheck; | ||
|
||
} | ||
|
||
internal void ChangeState(ConnectionState nextState) | ||
{ | ||
Debug.Log($"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); | ||
} | ||
|
||
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(); | ||
} | ||
|
||
/// <summary> | ||
/// Registers the message handler for custom named messages. This should only be done once StartClient has been | ||
/// called (start client will initialize NetworkSceneManager and CustomMessagingManager) | ||
/// </summary> | ||
public void RegisterCustomMessages() | ||
{ | ||
NetworkManager.CustomMessagingManager.RegisterNamedMessageHandler(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), ReceiveServerToClientSetDisconnectReason_CustomMessage); | ||
} | ||
|
||
void ReceiveServerToClientSetDisconnectReason_CustomMessage(ulong clientID, FastBufferReader reader) | ||
{ | ||
reader.ReadValueSafe(out ConnectStatus status); | ||
m_CurrentState.OnDisconnectReasonReceived(status); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a DisconnectReason to all connected clients. This should only be done on the server, prior to disconnecting the clients. | ||
/// </summary> | ||
/// <param name="status"> The reason for the upcoming disconnect.</param> | ||
public static void SendServerToAllClientsSetDisconnectReason(ConnectStatus status) | ||
{ | ||
var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp); | ||
writer.WriteValueSafe(status); | ||
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), writer); | ||
} | ||
|
||
/// <summary> | ||
/// Sends a DisconnectReason to the indicated client. This should only be done on the server, prior to disconnecting the client. | ||
/// </summary> | ||
/// <param name="clientID"> id of the client to send to </param> | ||
/// <param name="status"> The reason for the upcoming disconnect.</param> | ||
public static void SendServerToClientSetDisconnectReason(ulong clientID, ConnectStatus status) | ||
{ | ||
var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp); | ||
writer.WriteValueSafe(status); | ||
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), clientID, writer); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.