Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Unity 2022.2 is now available as the latest Tech release.
    Dismiss Notice
  3. We are making some changes to the DOTS forums.
    Dismiss Notice
  4. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

How to use approval check? Password Secured Lobby

Discussion in 'Multiplayer' started by WuffelGames, Oct 14, 2022.

  1. WuffelGames

    WuffelGames

    Joined:
    May 20, 2019
    Posts:
    1
    How can I use NetworkManager.Singleton.ConnectionApprovalCallback the right way? I would like to create a password secured lobby. This is the code in the documentation, but nothing written how to use it.

    Code (CSharp):
    1. using Unity.Netcode;
    2.  
    3. private void Setup()
    4. {
    5.     NetworkManager.Singleton.ConnectionApprovalCallback = ApprovalCheck;
    6.     NetworkManager.Singleton.StartHost();
    7. }
    8.  
    9. private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
    10. {
    11.     // The client identifier to be authenticated
    12.     var clientId = request.ClientNetworkId;
    13.  
    14.     // Additional connection data defined by user code
    15.     var connectionData = request.Payload;
    16.  
    17.     // Your approval logic determines the following values
    18.     response.Approved = true;
    19.     response.CreatePlayerObject = true;
    20.  
    21.     // The prefab hash value of the NetworkPrefab, if null the default NetworkManager player prefab is used
    22.     response.PlayerPrefabHash = null;
    23.  
    24.     // Position to spawn the player object (if null it uses default of Vector3.zero)
    25.     response.Position = Vector3.zero;
    26.  
    27.     // Rotation to spawn the player object (if null it uses the default of Quaternion.identity)
    28.     response.Rotation = Quaternion.identity;
    29.  
    30.     // If additional approval steps are needed, set this to true until the additional steps are complete
    31.     // once it transitions from true to false the connection approval response will be processed.
    32.     response.Pending = false;
    33. }
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    1,644
    var connectionData = request.Payload;

    You'd send your password ... actually, you'd send the hash of a password in the payload (not the password itself because payload transfer is not secure). On the server in the ApprovalCheck you get the hash out of the payload and compare it with the server's password hash. If they match, you set response.Approved to true, otherwise false.

    Before calling StartClient() you would set the payload like so, you can replace PlayerName with PasswordHash:
    Code (CSharp):
    1. private void SetConnectionPayload()
    2. {
    3.     var payload = JsonUtility.ToJson(new ConnectionPayload { PlayerName = _playerName });
    4.     NetworkManager.Singleton.NetworkConfig.ConnectionData = Encoding.ASCII.GetBytes(payload);
    5. }
    And the server does this in ApprovalCheck:
    Code (CSharp):
    1. var payload = JsonUtility.FromJson<ConnectionPayload>(Encoding.ASCII.GetString(request.Payload));
    The transferred struct looks like this:
    Code (CSharp):
    1. [Serializable]
    2. public struct ConnectionPayload
    3. {
    4.    public string PlayerName;
    5. }
     
  3. Maurits_Dijkman

    Maurits_Dijkman

    Joined:
    May 17, 2021
    Posts:
    1
    I tried doing it the way CodeSmile recommended. I pass the password and the player name as a string in the ConnectionPayload.

    When I try to run a host, I get an error saying:
    NullReferenceException: Object reference not set to an instance of an object
    UnityEngine.JsonUtility.FromJson[T] (System.String json) (at <eb9295277491416588c36aeb93a5fb70>:0)

    After some quick debugging I found out that the JSON messes up with the following line:
    var payload = JsonUtility.FromJson<ConnectionPayload>(Encoding.ASCII.GetString(request.Payload));

    This line should transform the request.Payload from a ConnectionApprovalRequest to a ConnectionPayload, but the JSON returns a null.

    Does anyone know how I can solve this?
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    1,644
    Check if the request.Payload isn‘t null to begin with. If it isn‘t log it to see if it matches the field layout of the ConnectionPayload class. Perhaps you serialized a different class to json than the one you try to deserialize the json to. Also make sure Encoding.ASCII (or any other encoding) are the same for both encoding and decoding the json string.
     
    RikuTheFuffs-U likes this.
  5. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    114
    If you print the payload before serializing and before deserializing it, do the two JSON strings match exactly?
     
    Last edited: Nov 22, 2022