I work on a game project for some friends, and they have the issue that the lobby browser widget when it calls the find session function using the OnlineSubsystemSteam it only returns lobbies on the same download region, we have tried a multitude of things, and I am not really fluent in C++ so its a bit of a chore, especially when working on something this complex but I just really want to help get it sorted.
This is where we set up the filters to create the query
/**
* Create and trigger the lobby query from the defined search settings
*/
void FOnlineAsyncTaskSteamFindLobbiesBase::CreateQuery()
{
check(SteamMatchmakingPtr);
SteamMatchmakingPtr->AddRequestLobbyListDistanceFilter(ELobbyDistanceFilter::k_ELobbyDistanceFilterWorldwide); // might as well put this here, not that it will make a difference xD
// Maximum results to return
if (SearchSettings->MaxSearchResults > 0)
{
SteamMatchmakingPtr->AddRequestLobbyListResultCountFilter(SearchSettings->MaxSearchResults);
}
#ifdef SEARCH_PLAYERSLOTS
{
int32 PlayerSlots = 0;
if (SearchSettings->QuerySettings.Get(SEARCH_PLAYERSLOTS, PlayerSlots) && PlayerSlots > 0)
{
SteamMatchmakingPtr->AddRequestLobbyListFilterSlotsAvailable(PlayerSlots);
}
}
#endif
// Distance of search result from searching client
SteamMatchmakingPtr->AddRequestLobbyListDistanceFilter(k_ELobbyDistanceFilterWorldwide); // changed it from default to worlwide but for some reason has no affect
for (FSearchParams::TConstIterator It(SearchSettings->QuerySettings.SearchParams); It; ++It)
{
const FName Key = It.Key();
const FOnlineSessionSearchParam& SearchParam = It.Value();
// Game server keys are skipped
if (Key == SEARCH_DEDICATED_ONLY || Key == SETTING_MAPNAME || Key == SEARCH_EMPTY_SERVERS_ONLY || Key == SEARCH_SECURE_SERVERS_ONLY || Key == SEARCH_PRESENCE)
{
continue;
}
#ifdef SEARCH_PLAYERSLOTS
if (Key == SEARCH_PLAYERSLOTS)
continue;
#endif
FString KeyStr;
if (SessionKeyToSteamKey(Key, SearchParam.Data, KeyStr))
{
if (SearchParam.ComparisonOp == EOnlineComparisonOp::Near)
{
//Near filters don't actually filter out values, they just influence how the results are sorted. You can specify multiple near filters, with the first near filter influencing the most, and the last near filter influencing the least.
switch(SearchParam.Data.GetType())
{
case EOnlineKeyValuePairDataType::Int32:
{
int32 Value;
SearchParam.Data.GetValue(Value);
SteamMatchmakingPtr->AddRequestLobbyListNearValueFilter(TCHAR_TO_UTF8(*KeyStr), Value);
break;
}
default:
UE_LOG_ONLINE(Warning, TEXT("Unable to set search parameter %s"), *SearchParam.ToString());
break;
}
}
else
{
switch(SearchParam.Data.GetType())
{
case EOnlineKeyValuePairDataType::Int32:
{
int32 Value;
SearchParam.Data.GetValue(Value);
SteamMatchmakingPtr->AddRequestLobbyListNumericalFilter(TCHAR_TO_UTF8(*KeyStr), Value, ToSteamLobbyCompareOp(SearchParam.ComparisonOp));
break;
}
case EOnlineKeyValuePairDataType::Float:
{
// @TODO ONLINE - Equality works, but rest untested
SteamMatchmakingPtr->AddRequestLobbyListStringFilter(TCHAR_TO_UTF8(*KeyStr), TCHAR_TO_UTF8(*SearchParam.Data.ToString()), ToSteamLobbyCompareOp(SearchParam.ComparisonOp));
break;
}
case EOnlineKeyValuePairDataType::String:
{
FString Value;
SearchParam.Data.GetValue(Value);
if (!Value.IsEmpty())
{
SteamMatchmakingPtr->AddRequestLobbyListStringFilter(TCHAR_TO_UTF8(*KeyStr), TCHAR_TO_UTF8(*Value), ToSteamLobbyCompareOp(SearchParam.ComparisonOp));
}
else
{
UE_LOG_ONLINE(Warning, TEXT("Empty search parameter %s: %s"), *Key.ToString(), *SearchParam.ToString());
}
break;
}
default:
UE_LOG_ONLINE(Warning, TEXT("Unable to set search parameter %s: %s"), *Key.ToString(), *SearchParam.ToString());
break;
}
}
}
else
{
UE_LOG_ONLINE(Warning, TEXT("Unsupported search setting %s %s of type %s"), *Key.ToString(), *SearchParam.ToString(), EOnlineComparisonOp::ToString(SearchParam.ComparisonOp));
}
}
}
This is where we actually request the lobby list
/**
* Give the async task time to do its work
* Can only be called on the async task manager thread
*/
void FOnlineAsyncTaskSteamFindLobbiesBase::Tick()
{
ISteamUtils* SteamUtilsPtr = SteamUtils();
check(SteamUtilsPtr);
switch (FindLobbiesState)
{
case EFindLobbiesState::Init:
{
// Don't try to search if the network device is broken
if (ISocketSubsystem::Get()->HasNetworkDevice())
{
// Make sure they are logged in to play online
if (SteamUser()->BLoggedOn())
{
UE_LOG_ONLINE(Verbose, TEXT("Starting search for Internet games..."));
// Setup the filters
CreateQuery();
// Start the async search
CallbackHandle = SteamMatchmakingPtr->RequestLobbyList();
}
else
{
UE_LOG_ONLINE(Warning, TEXT("You must be logged in to an online profile to search for internet games"));
}
}
else
{
UE_LOG_ONLINE(Warning, TEXT("Can't search for an internet game without a network connection"));
}
if (CallbackHandle == k_uAPICallInvalid)
{
bWasSuccessful = false;
FindLobbiesState = EFindLobbiesState::Finished;
}
else
{
FindLobbiesState = EFindLobbiesState::RequestLobbyList;
}
break;
}
case EFindLobbiesState::RequestLobbyList:
{
// Poll for completion status
bool bFailedCall = false;
if (SteamUtilsPtr->IsAPICallCompleted(CallbackHandle, &bFailedCall))
{
bool bFailedResult;
// Retrieve the callback data from the request
bool bSuccessCallResult = SteamUtilsPtr->GetAPICallResult(CallbackHandle, &CallbackResults, sizeof(CallbackResults), CallbackResults.k_iCallback, &bFailedResult);
bWasSuccessful = bSuccessCallResult && !bFailedCall && !bFailedResult;
if (bWasSuccessful)
{
// Trigger the lobby data requests
int32 NumLobbies = (int32)CallbackResults.m_nLobbiesMatching;
for (int32 LobbyIdx = 0; LobbyIdx < NumLobbies; LobbyIdx++)
{
LobbyIDs.Add(SteamMatchmakingPtr->GetLobbyByIndex(LobbyIdx));
}
FindLobbiesState = EFindLobbiesState::RequestLobbyData;
}
else
{
FindLobbiesState = EFindLobbiesState::Finished;
}
}
break;
}
case EFindLobbiesState::RequestLobbyData:
{
bWasSuccessful = true;
for (CSteamID LobbyId : LobbyIDs)
{
if (!SteamMatchmakingPtr->RequestLobbyData(LobbyId))
{
bWasSuccessful = false;
FindLobbiesState = EFindLobbiesState::Finished;
break;
}
}
if (bWasSuccessful)
{
FindLobbiesState = EFindLobbiesState::WaitForRequestLobbyData;
}
break;
}
case EFindLobbiesState::WaitForRequestLobbyData:
{
FOnlineSessionSteamPtr SessionInt = StaticCastSharedPtr<FOnlineSessionSteam>(Subsystem->GetSessionInterface());
// Waiting for the lobby updates to fill in
if (LobbyIDs.Num() == SessionInt->PendingSearchLobbyIds.Num())
{
FindLobbiesState = EFindLobbiesState::Finished;
}
// Fallback timeout in case we don't hear from Steam
else if (GetElapsedTime() >= ASYNC_TASK_TIMEOUT)
{
bWasSuccessful = false;
FindLobbiesState = EFindLobbiesState::Finished;
}
break;
}
case EFindLobbiesState::Finished:
{
bIsComplete = true;
break;
}
default:
{
UE_LOG_ONLINE(Warning, TEXT("Unexpected state %d reached in FOnlineAsyncTaskSteamFindLobbiesBase::Tick, ending task."), (int32)FindLobbiesState);
bWasSuccessful = false;
FindLobbiesState = EFindLobbiesState::Finished;
break;
}
}
}
We tried to use
SteamMatchmakingPtr->AddRequestLobbyListDistanceFilter(ELobbyDistanceFilter::k_ELobbyDistanceFilterWorldwide);
Hoping that it would expand the search radius, but evidently it seems to have no affect, we still have lobbies showing up for the same download region as specified in the steam client, however still nothing outside of said region.
If you need anymore context/code/information, let me know!