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.
- Host A creates a lobby
- Client B searches for the lobby, and adds that search result to their LobbyDataRegistry
- Since they are not part of the lobby, the lobby member attributes are not set correctly (at all)
- Client B attempts to join the lobby
- 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.