OSSv2 Joining members can't see other member attributes on initial join

We are running OSSv2 and trying to support a lobby setup. The client performs a search for a lobby and after they find the lobby, they attempt to join it. The actual connection portion appears to be working, however, when the client joins, they don’t see any member attributes of the other users. If the other users perform any kind of lobby member update, the changes get propagated to the client correctly.

After investigation, it appears to be a bug in the joining logic.

  1. Host A creates a lobby
  2. Client B searches for the lobby, and adds that search result to their LobbyDataRegistry
    1. Since they are not part of the lobby, the lobby member attributes are not set correctly (at all)
  3. Client B attempts to join the lobby
  4. After it joins the lobby, since the lobby is in its LobbyDataRegistry, it doesn’t automatically update the lobby data

It looks like step 2 is the genesis of the issue since in step 4, it finds the entry w/o any member attributes in the LobbyDataRegistry (which other parts of JoinLobby expect it to)

I was looking for a way to fix the issue, and I found that if in this section of TOnlineAsyncOpHandle<FJoinLobby> FLobbiesEOSGS::JoinLobby(FJoinLobby::Params&& InParams) that originally looks like this:

  // Step 4: Create the lobby data object from the lobby details.
  .Then([this](TOnlineAsyncOp<FJoinLobby>& InAsyncOp)
  {
    TSharedRef<FLobbyDetailsEOS> LobbyDetails = GetOpDataChecked<TSharedRef<FLobbyDetailsEOS>>(InAsyncOp, UE_ONLINE_LOBBY_EOS_KEY_NAME_LOBBY_DETAILS);
    return LobbyDataRegistry->FindOrCreateFromLobbyDetails(InAsyncOp.GetParams().LocalAccountId, LobbyDetails);
  })

I do this instead:

    const TSharedRef<FLobbyDataEOS> &LobbyData = GetOpDataChecked<TSharedRef<FLobbyDataEOS>>(InAsyncOp, UE_ONLINE_LOBBY_EOS_KEY_NAME_LOBBY_DATA);
    LobbyDataRegistry->Unregister(LobbyData->GetLobbyIdHandle()); // (Made this public)

    TSharedRef<FLobbyDetailsEOS> LobbyDetails = GetOpDataChecked<TSharedRef<FLobbyDetailsEOS>>(InAsyncOp, UE_ONLINE_LOBBY_EOS_KEY_NAME_LOBBY_DETAILS);     
    auto Result = LobbyDataRegistry->FindOrCreateFromLobbyDetails(InAsyncOp.GetParams().LocalAccountId, LobbyDetails);     

    TSharedPtr<FLobbyDataEOS> NewLobbyData = LobbyDataRegistry->Find(LobbyDetails->GetInfo()->GetLobbyIdEOS());
    InAsyncOp.Data.Set<TSharedRef<FLobbyDataEOS>>(UE_ONLINE_LOBBY_EOS_KEY_NAME_LOBBY_DATA, NewLobbyData.ToSharedRef());
    return Result;

It removes the lobby from the registry so it can re-add it. I believe this works because the joined user is now part of the lobby, the lobby creation code which calls

TDefaultErrorResultInternal<FLobbyMemberServiceSnapshot> FLobbyDetailsEOS::GetLobbyMemberSnapshot(FAccountId MemberAccountId) const

will correctly update the member attributes.

I was wondering if my understanding of the problem was correct and if this was an acceptable way to fix the issue. Ideally, I wouldn’t have to Unregister the lobby only to re-add it, Instead, it would be better to modify the found lobby in place, but that involved changing more code that I wanted to.

Sorry for the delay here. This does look like a bug. I think your fix is fine in most cases. There is a minor issue I can think of where the reference to the lobby registry would be stale after you unregister the lobby IF you are keeping any references in your code.

I think the real fix is to refresh the lobby in the registry in FLobbyDataRegistryEOS::FindOrCreateFromLobbyDetails. It’s not a trivial change as you mentioned, though.

I’ve reported this issue to our plugin team.

Thanks!