Skip to content

feat: flag to prevent dev and release builds to connect #482

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

Merged
merged 49 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
9b72064
Added flag preventing release and debug build from connecting
LPLafontaineB Feb 14, 2022
b0ad2e1
Made disconnection message specifically about build types
LPLafontaineB Feb 15, 2022
6ef4163
Revert unintentional changes
LPLafontaineB Feb 15, 2022
6ef4f51
Simplified connection approval flow
LPLafontaineB Feb 17, 2022
a8f357d
cleaning up ServerGameNetPortal
LPLafontaineB Feb 17, 2022
18032ff
Adding trailing periods to connection status messages
LPLafontaineB Feb 17, 2022
efab529
fixed KeyNotFoundException
LPLafontaineB Feb 17, 2022
fd37ed5
Further clarified SessionManager's SetupConnectingPlayerSessionData m…
LPLafontaineB Feb 17, 2022
743c00d
Made disconnect reason message clearer for duplicate connection
LPLafontaineB Feb 22, 2022
1bfff8a
Merge branch 'develop' into feature/isdebug-flag-for-connection-approval
LPLafontaineB Feb 24, 2022
0453fab
Added back connection status message
LPLafontaineB Feb 24, 2022
8b5dd8f
Merge branch 'develop' into feature/isdebug-flag-for-connection-approval
LPLafontaineB Mar 7, 2022
3a9f762
Adding new message to popup
LPLafontaineB Mar 7, 2022
98fb25e
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 8, 2022
ef89bab
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 8, 2022
3e25c20
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 8, 2022
6b0fe25
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 8, 2022
31a5ac4
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 8, 2022
2265e49
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
353451f
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
b71e729
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
2654069
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
e2790f4
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
02f7582
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
d775783
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
e01be0c
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 9, 2022
4571d58
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 10, 2022
784f717
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
d7b3f62
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
a95d015
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
0695fa7
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
8d6f523
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
fefa8ae
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 11, 2022
c6bba86
Merge branch 'develop' into feature/isdebug-flag-for-connection-approval
LPLafontaineB Mar 16, 2022
c36d501
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 16, 2022
10db7a9
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 17, 2022
a5db922
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 17, 2022
d12dde6
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 17, 2022
3faa4a2
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 17, 2022
a6d7557
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 18, 2022
2881284
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 18, 2022
6679da2
Added period to GenericDisconnect status message
LPLafontaineB Mar 21, 2022
963212c
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 29, 2022
1f6961b
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 29, 2022
8769ede
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 29, 2022
75f04c3
Merge develop into feature/isdebug-flag-for-connection-approval
netcode-ci-service Mar 29, 2022
1cb555b
simplified GetConnectStatus
LPLafontaineB Mar 29, 2022
7369e12
Merge branch 'feature/isdebug-flag-for-connection-approval' of https:…
LPLafontaineB Mar 29, 2022
0eb928a
Removed obsolete comment
LPLafontaineB Mar 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ void OnConnectStatus(ConnectStatus status)
case ConnectStatus.LoggedInAgain:
PopupPanel.ShowPopupPanel("Connection Failed", "You have logged in elsewhere using the same account.");
break;
case ConnectStatus.IncompatibleBuildType:
PopupPanel.ShowPopupPanel("Connection Failed", "Server and client builds are not compatible. You cannot connect a release build to a development build or an in-editor session.");
break;
case ConnectStatus.GenericDisconnect:
PopupPanel.ShowPopupPanel("Disconnected From Host", "The connection to the host was lost");
PopupPanel.ShowPopupPanel("Disconnected From Host", "The connection to the host was lost.");
break;
default:
Debug.LogWarning($"New ConnectStatus {status} has been added, but no connect message defined for it.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ void ConnectClient()
{
playerId = m_Portal.GetPlayerId(),
clientScene = SceneManager.GetActiveScene().buildIndex,
playerName = m_Portal.PlayerName
playerName = m_Portal.PlayerName,
isDebug = Debug.isDebugBuild
});

var payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum ConnectStatus
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.
IncompatibleBuildType, //client build type is incompatible with server.
}

public enum OnlineMode
Expand All @@ -36,6 +37,7 @@ public class ConnectionPayload
public string playerId;
public int clientScene = -1;
public string playerName;
public bool isDebug;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class ServerGameNetPortal : MonoBehaviour
/// <summary>
/// The active server scene index.
/// </summary>
public int ServerScene { get { return UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex; } }
static int ServerScene => SceneManager.GetActiveScene().buildIndex;

LobbyServiceFacade m_LobbyServiceFacade;

Expand Down Expand Up @@ -164,6 +164,8 @@ void ApprovalCheck(byte[] connectionData, ulong clientId, NetworkManager.Connect
{
if (connectionData.Length > k_MaxConnectPayload)
{
// If connectionData too high, deny immediately to avoid wasting time on the server. This is intended as
// a bit of light protection against DOS attacks that rely on sending silly big buffers of garbage.
connectionApprovedCallback(false, 0, false, null, null);
return;
}
Expand All @@ -178,67 +180,66 @@ void ApprovalCheck(byte[] connectionData, ulong clientId, NetworkManager.Connect
return;
}

string payload = System.Text.Encoding.UTF8.GetString(connectionData);
var payload = System.Text.Encoding.UTF8.GetString(connectionData);
var connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload); // https://docs.unity3d.com/2020.2/Documentation/Manual/JSONSerialization.html

ConnectStatus gameReturnStatus;

// Test for over-capacity connection. This needs to be done asap, to make sure we refuse connections asap and don't spend useless time server side
// on invalid users trying to connect
// todo this is currently still spending too much time server side.
if (m_Portal.NetManager.ConnectedClientsIds.Count >= CharSelectData.k_MaxLobbyPlayers)
{
gameReturnStatus = ConnectStatus.ServerFull;
}
else
{
Debug.Log("Host ApprovalCheck: connecting client with player ID: " + connectionPayload.playerId);

gameReturnStatus = SessionManager<SessionPlayerData>.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId,
new SessionPlayerData(clientId, connectionPayload.playerName, m_Portal.AvatarRegistry.GetRandomAvatar().Guid.ToNetworkGuid(), 0, true))
? ConnectStatus.Success
: ConnectStatus.LoggedInAgain;
}
var gameReturnStatus = GetConnectStatus(connectionPayload);

if (gameReturnStatus == ConnectStatus.Success)
{
int clientScene = connectionPayload.clientScene;
SessionManager<SessionPlayerData>.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId,
new SessionPlayerData(clientId, connectionPayload.playerName, m_Portal.AvatarRegistry.GetRandomAvatar().Guid.ToNetworkGuid(), 0, true));
SendServerToClientConnectResult(clientId, gameReturnStatus);

//Populate our dictionaries with the playerData
m_ClientSceneMap[clientId] = clientScene;
//Populate our client scene map
m_ClientSceneMap[clientId] = connectionPayload.clientScene;

connectionApprovedCallback(true, null, true, Vector3.zero, Quaternion.identity);
// connection approval will create a player object for you
}
else
{
//TODO-FIXME:Netcode Issue #796. We should be able to send a reason and disconnect without a coroutine delay.
//TODO:Netcode: In the future we expect Netcode to allow us to return more information as part of
//the approval callback, so that we can provide more context on a reject. In the meantime we must provide the extra information ourselves,
//and then manually close down the connection.
//TODO:Netcode: In the future we expect Netcode to allow us to return more information as part of the
//approval callback, so that we can provide more context on a reject. In the meantime we must provide
//the extra information ourselves, and then wait a short time before manually close down the connection.
SendServerToClientConnectResult(clientId, gameReturnStatus);
SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
StartCoroutine(WaitToDisconnect(clientId));
StartCoroutine(WaitToDenyApproval(connectionApprovedCallback));
if (m_LobbyServiceFacade.CurrentUnityLobby != null)
{
m_LobbyServiceFacade.RemovePlayerFromLobbyAsync(connectionPayload.playerId, m_LobbyServiceFacade.CurrentUnityLobby.Id, null, null);
}
}
}

IEnumerator WaitToDisconnect(ulong clientId)
ConnectStatus GetConnectStatus(ConnectionPayload connectionPayload)
{
if (m_Portal.NetManager.ConnectedClientsIds.Count >= CharSelectData.k_MaxLobbyPlayers)
{
return ConnectStatus.ServerFull;
}

if (connectionPayload.isDebug != Debug.isDebugBuild)
{
return ConnectStatus.IncompatibleBuildType;
}

return SessionManager<SessionPlayerData>.Instance.IsDuplicateConnection(connectionPayload.playerId) ?
ConnectStatus.LoggedInAgain : ConnectStatus.Success;
}

static IEnumerator WaitToDenyApproval(NetworkManager.ConnectionApprovedDelegate connectionApprovedCallback)
{
yield return new WaitForSeconds(0.5f);
m_Portal.NetManager.DisconnectClient(clientId);
connectionApprovedCallback(false, 0, false, null, null);
}

/// <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 void SendServerToClientSetDisconnectReason(ulong clientID, ConnectStatus status)
static void SendServerToClientSetDisconnectReason(ulong clientID, ConnectStatus status)
{
var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp);
writer.WriteValueSafe(status);
Expand All @@ -250,7 +251,7 @@ public void SendServerToClientSetDisconnectReason(ulong clientID, ConnectStatus
/// </summary>
/// <param name="clientID"> id of the client to send to </param>
/// <param name="status"> the status to pass to the client</param>
public void SendServerToClientConnectResult(ulong clientID, ConnectStatus status)
static void SendServerToClientConnectResult(ulong clientID, ConnectStatus status)
{
var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp);
writer.WriteValueSafe(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,50 +101,51 @@ void Clear()
m_ClientIDToPlayerId.Clear();
}

public bool IsDuplicateConnection(string playerId)
{
return m_ClientData.ContainsKey(playerId) && m_ClientData[playerId].IsConnected;
}

/// <summary>
/// Adds a connecting player's session data if it is a new connection, or updates their session data in case of a reconnection. If the connection is not valid, simply returns false.
/// Adds a connecting player's session data if it is a new connection, or updates their session data in case of a reconnection.
/// </summary>
/// <param name="clientId">This is the clientId that Netcode assigned us on login. It does not persist across multiple logins from the same client. </param>
/// <param name="playerId">This is the playerId that is unique to this client and persists across multiple logins from the same client</param>
/// <param name="sessionPlayerData">The player's initial data</param>
/// <returns>True if the player connection is valid (i.e. not a duplicate connection)</returns>
public bool SetupConnectingPlayerSessionData(ulong clientId, string playerId, T sessionPlayerData)
public void SetupConnectingPlayerSessionData(ulong clientId, string playerId, T sessionPlayerData)
{
bool success = true;
var isReconnecting = false;

//Test for Duplicate Login.
if (m_ClientData.ContainsKey(playerId))
// Test for duplicate connection
if (IsDuplicateConnection(playerId))
{
bool isReconnecting = false;
Debug.LogError($"Player ID {playerId} already exists. This is a duplicate connection. Rejecting this session data.");
return;
}

// If another client is connected with the same playerId
if (m_ClientData[playerId].IsConnected)
{
success = false;
}
else
// If another client exists with the same playerId
if (m_ClientData.ContainsKey(playerId))
{
if (!m_ClientData[playerId].IsConnected)
{
// If this connecting client has the same player Id as a disconnected client, this is a reconnection.
isReconnecting = true;
}

// Reconnecting. Give data from old player to new player
if (isReconnecting)
{
// Update player session data
sessionPlayerData = m_ClientData[playerId];
sessionPlayerData.ClientID = clientId;
sessionPlayerData.IsConnected = true;
}
}

//Populate our dictionaries with the SessionPlayerData
if (success)
// Reconnecting. Give data from old player to new player
if (isReconnecting)
{
m_ClientIDToPlayerId[clientId] = playerId;
m_ClientData[playerId] = sessionPlayerData;
// Update player session data
sessionPlayerData = m_ClientData[playerId];
sessionPlayerData.ClientID = clientId;
sessionPlayerData.IsConnected = true;
}

return success;
//Populate our dictionaries with the SessionPlayerData
m_ClientIDToPlayerId[clientId] = playerId;
m_ClientData[playerId] = sessionPlayerData;
}

public string GetPlayerId(ulong clientId)
Expand Down