Search Unity

Question Unity.Services.Lobbies.LobbyServiceException: player is already a member of the lobby

Discussion in 'Lobby' started by moiety_, Jan 25, 2024.

  1. moiety_

    moiety_

    Joined:
    Oct 9, 2019
    Posts:
    10
    Unity.Services.Lobbies.LobbyServiceException: player is already a member of the lobby ---> Unity.Services.Lobbies.Http.HttpException`1[Unity.Services.Lobbies.Models.ErrorStatus]: (409) HTTP/1.1 409 Conflict

    I'm new to UGS and been stuck here for a few days.

    Here's my code for authenticate:
    Code (CSharp):
    1. private static async Task Authenticate()
    2.     {
    3.         var options = new InitializationOptions();
    4.         options.SetProfile("Player" + Random.Range(0,1000));
    5.        
    6.         await UnityServices.InitializeAsync(options);
    7.         await AuthenticationService.Instance.SignInAnonymouslyAsync();
    8.         Debug.Log(AuthenticationService.Instance.PlayerId);
    9.     }
    Here's my code for creating lobby:
    Code (CSharp):
    1. try
    2.         {
    3.             var lobbyOptions = new CreateLobbyOptions
    4.             {
    5.                 IsPrivate = true,
    6.                 Player = GetPlayer()
    7.             };
    8.             Debug.Log("player " + lobbyOptions.Player.Id);
    9.  
    10.             Lobby hostLobby = await LobbyService.Instance.CreateLobbyAsync("lobby", 4, lobbyOptions);
    11.             lobbyMenuScript.Initialized_Host(hostLobby);
    12.             PrintPlayers(hostLobby);
    13.         }
    14.         catch (LobbyServiceException e)
    15.         {
    16.             Debug.Log(e);
    17.         }
    Here's my code for joining lobby:
    Code (CSharp):
    1. try
    2.         {
    3.             string lobbyCode = joinLobbyInp.text;
    4.             var lobbyOptions = new JoinLobbyByCodeOptions()
    5.             {
    6.                 Player = GetPlayer()
    7.             };
    8.             Debug.Log("player " + lobbyOptions.Player.Id);
    9.            
    10.             SetMenuUIsActive(false);
    11.             Lobby joinedLobby = await Lobbies.Instance.JoinLobbyByCodeAsync(lobbyCode, lobbyOptions);
    12.             lobbyMenuScript.Initialized_Joined(joinedLobby);
    13.         }
    14.         catch (LobbyServiceException e)
    15.         {
    16.             Debug.Log(e);
    17.             SetMenuUIsActive(true);
    18.         }
    Here's GetPlayer
    Code (CSharp):
    1.     private Player GetPlayer()
    2.     {
    3.         var player = new Player(AuthenticationService.Instance.PlayerId, data: new Dictionary<string, PlayerDataObject>
    4.         {
    5.             {
    6.                 "playername", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, playerNameInp.text)
    7.             }
    8.         });
    9.        
    10.         return player;
    11.     }
    Previously, I've been using Parrelsync with setting profiles to it's clone arguments. The error still happens.
    I've built it and ran on the same PC, The error still happens.
    I've built it and ran on another PC, The error still happens.
    Now I'm using Multiplayer Play Mode and it still happens.

    Can somebody explain what "player" is in the error because I've checked AuthenticationService.Instance.PlayerId and they're not the same when I'm running a virtual instance in Multiplayer Play Mode.
     
  2. UnityRalahHaddad

    UnityRalahHaddad

    Unity Technologies

    Joined:
    Feb 21, 2022
    Posts:
    10
    Hi Jescaspim
    Thank you for raising this and for providing the code snippets, I was able to reproduce the issue and raised it with the team to look into it, in the meantime, can you try the following:
    • In Multiplayer Playmode, add a new tag to the players - in my code I used "AuthChange"
    • Change your Authenticate method to
    Code (CSharp):
    1. using System.Linq;
    2.     private static async Task Authenticate()
    3.     {
    4. #if UNITY_EDITOR
    5.         var mppmTag = CurrentPlayer.ReadOnlyTags();
    6.         if (mppmTag.Contains("AuthChange"))
    7.         {
    8.             var playerProfile = "Player" + UnityEngine.Random.Range(0, 100);
    9.             AuthenticationService.Instance.SwitchProfile(playerProfile);
    10.         }
    11. #endif
    12.         await AuthenticationService.Instance.SignInAnonymouslyAsync();
    13.         Debug.Log("Player ID:" + AuthenticationService.Instance.PlayerId);
    14.     }
     
  3. moiety_

    moiety_

    Joined:
    Oct 9, 2019
    Posts:
    10
    Still getting the same error. I don't know if it's because I'm using 2023.3.0b4, because the code seem to work on from a year ago tutorials I've seen. Also the package versions I'm using are:
    • Lobby 1.1.2
    • Relay 1.0.2
    • Netcode for Gameobjects 1.7.1
    • Multiplayer Tools 2.1.0
    • Multiplayer Play Mode 1.0.0-pre.3
     
  4. UnityRalahHaddad

    UnityRalahHaddad

    Unity Technologies

    Joined:
    Feb 21, 2022
    Posts:
    10
    Thank you for the additional details, I will try to replicate the issue and come back to you.
    A question that might help, after changing the authenticate code, did you try to deactivate and reactivate the virtual players in Multiplayer Playmode?
     
  5. erickb_unity

    erickb_unity

    Unity Technologies

    Joined:
    Sep 1, 2021
    Posts:
    92
    The player logic looks fine, I ran something a similar test shown below and it worked for me with the same version of Multiplayer Play Mode.

    Few things to be careful around:
    - You can only initialize and process the options once. If you are (or something else is) initializing from anywhere else, options can potentially be ignored.
    - AuthenticationService.Instance.SwitchProfile can be used to avoid that problem prior to Authentication.
    - Make sure each function is only called once. If it's called again, you will get this error.

    I recommend storing and logging/displaying a lot of the information you are tracking to help you debug, like the current Lobby after joining or creating.

    Here's the small test I've done in an empty scene:
    Code (CSharp):
    1.  
    2.  
    3. using System.Threading.Tasks;
    4. using Unity.Services.Authentication;
    5. using Unity.Services.Core;
    6. using Unity.Services.Lobbies;
    7. using Unity.Services.Lobbies.Models;
    8. using UnityEngine;
    9.  
    10. public class Test : MonoBehaviour
    11. {
    12.     string Profile;
    13.     Lobby Lobby;
    14.     string LobbyCode;
    15.  
    16.     private void Start()
    17.     {
    18.         Profile = "Player" + Random.Range(0, 1000);
    19.     }
    20.  
    21.     private void OnGUI()
    22.     {
    23.         GUILayout.Label($"Random Profile: {Profile}");
    24.  
    25.         if (UnityServices.State != ServicesInitializationState.Initialized)
    26.         {
    27.             if (GUILayout.Button("InitializeAsync"))
    28.             {
    29.                 UnityServices.InitializeAsync();
    30.             }
    31.  
    32.             return;
    33.         }
    34.  
    35.         GUILayout.Label($"UnityServices.State {UnityServices.State}");
    36.  
    37.         if (!AuthenticationService.Instance.IsSignedIn)
    38.         {
    39.             if (GUILayout.Button("SignIn"))
    40.             {
    41.                 SignInAnonymouslyAsync();
    42.             }
    43.  
    44.             return;
    45.         }
    46.  
    47.         GUILayout.Label($"AuthenticationService.Instance.Profile: {AuthenticationService.Instance.Profile}");
    48.         GUILayout.Label($"AuthenticationService.Instance.PlayerId: {AuthenticationService.Instance.PlayerId}");
    49.  
    50.         if (Lobby == null)
    51.         {
    52.             if (GUILayout.Button("Create Lobby"))
    53.             {
    54.                 CreateLobbyAsync();
    55.             }
    56.  
    57.             using (new GUILayout.HorizontalScope())
    58.             {
    59.                 LobbyCode = GUILayout.TextField(LobbyCode);
    60.  
    61.                 if (GUILayout.Button("Join Lobby by Code"))
    62.                 {
    63.                     JoinLobbyAsync();
    64.                 }
    65.             }
    66.         }
    67.         else
    68.         {
    69.             GUILayout.Label($"LobbyId: {Lobby.Id}");
    70.             GUILayout.Label($"LobbyCode: {Lobby.LobbyCode}");
    71.         }
    72.     }
    73.  
    74.     public async Task SignInAnonymouslyAsync()
    75.     {
    76.         AuthenticationService.Instance.SwitchProfile(Profile);
    77.         await AuthenticationService.Instance.SignInAnonymouslyAsync();
    78.         Debug.Log(AuthenticationService.Instance.PlayerId);
    79.     }
    80.  
    81.     public async Task CreateLobbyAsync()
    82.     {
    83.         try
    84.         {
    85.             var lobbyOptions = new CreateLobbyOptions
    86.             {
    87.                 IsPrivate = true,
    88.                 Player = new Player(AuthenticationService.Instance.PlayerId)
    89.             };
    90.  
    91.             Debug.Log("player " + lobbyOptions.Player.Id);
    92.  
    93.             Lobby = await LobbyService.Instance.CreateLobbyAsync("lobby", 4, lobbyOptions);
    94.         }
    95.         catch (LobbyServiceException e)
    96.         {
    97.             Debug.Log(e);
    98.         }
    99.     }
    100.  
    101.     public async Task JoinLobbyAsync()
    102.     {
    103.         try
    104.         {
    105.             Lobby = await LobbyService.Instance.JoinLobbyByCodeAsync(LobbyCode);
    106.         }
    107.         catch (LobbyServiceException e)
    108.         {
    109.             Debug.Log(e);
    110.         }
    111.     }
    112.  
    113.     private void OnDestroy()
    114.     {
    115.         if (Lobby != null)
    116.         {
    117.             if (Lobby.HostId == AuthenticationService.Instance.PlayerId)
    118.             {
    119.                 LobbyService.Instance.DeleteLobbyAsync(Lobby.Id);
    120.                 Debug.Log($"Deleted Lobby.");
    121.             }
    122.             else
    123.             {
    124.                 LobbyService.Instance.RemovePlayerAsync(Lobby.Id, AuthenticationService.Instance.PlayerId);
    125.                 Debug.Log($"Left Lobby.");
    126.             }
    127.         }
    128.     }
    129. }
    130.  
     
  6. moiety_

    moiety_

    Joined:
    Oct 9, 2019
    Posts:
    10
    - Make sure each function is only called once. If it's called again, you will get this error.

    Sorry guys, turns out I'm just dumb! Join was being called twice because I did AddListener and also attached it in the editor. It also didn't help that the console was collapsing the debugs and I am blind apparently!

    I got it working now, thanks guys!