Closed ughstudios closed 4 years ago
I should mention that CreateSessionAdvanced works perfectly!
This is how I define my session btw, in my game mode blueprint
The only differences are in here: if (SearchSettings->bIsLanQuery)
bool FOnlineSessionHVS::FindSessions(int32 SearchingPlayerNum, const TSharedRef<FOnlineSessionSearch>& SearchSettings)
{
uint32 Return = ONLINE_FAIL;
// Don't start another search while one is in progress
if (!CurrentSessionSearch.IsValid() && SearchSettings->SearchState != EOnlineAsyncTaskState::InProgress)
{
// Free up previous results
SearchSettings->SearchResults.Empty();
// Copy the search pointer so we can keep it around
CurrentSessionSearch = SearchSettings;
// remember the time at which we started search, as this will be used for a "good enough" ping estimation
SessionSearchStartInSeconds = FPlatformTime::Seconds();
// Check if its a LAN query
if (SearchSettings->bIsLanQuery)
{
Return = FindLANSession();
if (Return == ONLINE_IO_PENDING)
{
SearchSettings->SearchState = EOnlineAsyncTaskState::InProgress;
}
}
else
{
FOnlineSessionSearchResult SearchResult;
TSharedPtr<FOnlineSessionInfoHVS> SessionInfo = MakeShareable(new FOnlineSessionInfoHVS());
TSharedPtr<FInternetAddr> InternetAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
FString IpAddr;
SearchSettings->QuerySettings.Get(FName("IpAddr"), IpAddr);
GLog->Log("OnlineSessionInterfaceHVS::FindSessions IpAddr: " + IpAddr);
bool bSuccessful;
InternetAddress->SetIp(*IpAddr, bSuccessful);
int Port;
SearchSettings->QuerySettings.Get(FName("Port"), Port);
InternetAddress->SetPort(Port);
GLog->Log("OnlineSessionInterfaceHVS::FindSessions SetIp successful?: " + FString::FromInt(bSuccessful));
GLog->Log("InternetAddress ToString(): " + InternetAddress->ToString(true));
SessionInfo->HostAddr = InternetAddress;
FString OptionsOut;
SearchSettings->QuerySettings.Get(FName("Options"), OptionsOut);
GLog->Log("Options : " + OptionsOut);
SessionInfo->Options = OptionsOut;
SearchResult.Session.SessionInfo = SessionInfo;
CurrentSessionSearch->SearchResults.Add(SearchResult);
Return = ONLINE_SUCCESS;
GLog->Log("Successful.");
}
}
else
{
UE_LOG_ONLINE_SESSION(Warning, TEXT("Ignoring game search request while one is pending"));
Return = ONLINE_IO_PENDING;
}
return Return == ONLINE_SUCCESS || Return == ONLINE_IO_PENDING;
}
I should mention that I am using a custom online subsystem and this is my find sessions method.
My custom find sessions method should simply just create a session search object and give it to the search results in CurrentSessionSearch->SearchResults
My JoinSession is exactly the same as the Null Subsystem ( my subsystem was actually copied exactly from the null subsystem but i've set it up to find matches from my custom master server ).
/** Get a resolved connection string from a session info */
static bool GetConnectStringFromSessionInfo(TSharedPtr<FOnlineSessionInfoHVS>& SessionInfo, FString& ConnectInfo, int32 PortOverride=0)
{
bool bSuccess = false;
if (SessionInfo.IsValid())
{
if (SessionInfo->HostAddr.IsValid() && SessionInfo->HostAddr->IsValid())
{
/*if (PortOverride != 0)
{
ConnectInfo = FString::Printf(TEXT("%s:%d"), *SessionInfo->HostAddr->ToString(false), PortOverride);
}
else
{
ConnectInfo = FString::Printf(TEXT("%s"), *SessionInfo->HostAddr->ToString(true));
}*/
ConnectInfo = SessionInfo->HostAddr->ToString(true) + SessionInfo->Options;
bSuccess = true;
}
}
return bSuccess;
}
This is what unreal uses to get the url to pass into ClientTravel()
Then I simply pass the correct stuff into the find sessions function which then essentially, in my overwriten function for my custom subsystem it essentially just takkes these filters and creates a session result for it (to be used to connect). because by the time i'm ready to connect, my game already has the ip, port, and options to connect, but I need to be connected to a session otherwise the voice chat doesn't work lol. Because AGameModeBase::InitNewPlayer() calls GameSession->RegisterPlayer() which calls PlayerState->RegisterServerWithSubsystem, which then will try to get a session locally, if there is one, and then it will call RegisterVoice(), I'm essentially only doing this so I can use the built in voice system over the network, and also because I want to setup team chats. If there is a better way, then let me know.
Figured it out, make sure you have these in your FindSessions() function:
Return = ONLINE_SUCCESS;
SearchSettings->SearchState = EOnlineAsyncTaskState::Done;
TriggerOnFindSessionsCompleteDelegates(true);
Don't forget guys that inside of JoinSessionCallbackProxy.cpp the engine actually calls ClientTravel and gets the connection string from GetResolvedConnectString() which is defined in your OnlineSessionInteface.cpp file
void UJoinSessionCallbackProxy::OnCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
FOnlineSubsystemBPCallHelper Helper(TEXT("JoinSessionCallback"), WorldContextObject);
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
if (Helper.IsValid())
{
auto Sessions = Helper.OnlineSub->GetSessionInterface();
if (Sessions.IsValid())
{
Sessions->ClearOnJoinSessionCompleteDelegate_Handle(DelegateHandle);
if (Result == EOnJoinSessionCompleteResult::Success)
{
// Client travel to the server
FString ConnectString;
if (Sessions->GetResolvedConnectString(NAME_GameSession, ConnectString) && PlayerControllerWeakPtr.IsValid())
{
UE_LOG_ONLINE_SESSION(Log, TEXT("Join session: traveling to %s"), *ConnectString);
PlayerControllerWeakPtr->ClientTravel(ConnectString, TRAVEL_Absolute);
OnSuccess.Broadcast();
return;
}
}
}
}
OnFailure.Broadcast();
}
OnSuccess and OnFailure are never called, only the top execute pin. I even went and did a full debug of the method and went line by line, the FindSessions() method returns true, and is successful, but then the Advanced FindSessions method just simply doesn't run onsuccessful