RyroNZ / UE4MasterServer

This is a plugin for Unreal Engine 4 that adds server registration, deregistration etc with a master server.

Home Page:http://ryanpost.me

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom Online Subsystem

ughstudios opened this issue · comments

Hey this is really cute,

I'm trying to make my own subsytem where I created my own master server in Socket.IO using javascript/nodejs. However, I'm trying to figure out how to override the JoinSession() FindSession() and CreateSession() functions to search my own socket.io server. How did you do this for yours? Think you could helpp me out? :D

In this file: https://github.com/RyroNZ/UE4MasterServer/blob/master/Plugin/OnlineSubsystemPython/Source/Private/OnlineSessionInterfacePython.cpp

On line 843 you have a JoinSession() method which calls JoinLANSession(). What does this do? It just copies the session info over from the passed session variable? My question about this though is what happens next? Does it then connect to the server? What if I want to connect to an external server? Or are we connecting somewhere else, like do we have to manually call open IP:Port. I want to pass options to my join, so I have something like this:

open ip:port?user_id=siaodjosid&character_id=23491023i

How does JoinSession() work, and how can i still pass my options like I have been?

commented

Hello!

This type of functions can be found in OnlineSessionInterface. To be specific You can found CreateSesion in the header here, in the cpp here and at bottom of the function the communication with server (in this case through HTTP).

This type of functions can be found in OnlineSessionInterface. To be specific You can found CreateSesion in the header here, in the cpp here and at bottom of the function the communication with server (in this case through HTTP).

That makes sense! However, I'm trying to figure out how we would connect to the server. I look through the code, GameModeBase::InitNewPlayer() calls GameSession->RegisterPlayer

Which then calls PlayerState->RegisterPlayerWithSession()

void APlayerState::RegisterPlayerWithSession(bool bWasFromInvite)
{
	if (GetNetMode() != NM_Standalone)
	{
		if (GetUniqueId().IsValid()) // May not be valid if this is was created via DebugCreatePlayer
		{
			// Register the player as part of the session
			const APlayerState* PlayerState = GetDefault<APlayerState>();
			UOnlineEngineInterface::Get()->RegisterPlayer(GetWorld(), PlayerState->SessionName, *GetUniqueId(), bWasFromInvite);
		}
	}

Which calls the local engine interface subsystem and calls registerplayer. SO that means, for your subsystem it would call OnlineSessionInterfacePython::RegisterPlayer()

bool FOnlineSessionPython::RegisterPlayers(FName SessionName, const TArray< TSharedRef<const FUniqueNetId> >& Players, bool bWasInvited)
{
	bool bSuccess = false;
	FNamedOnlineSession* Session = GetNamedSession(SessionName);
	if (Session)
	{
		bSuccess = true;

		for (int32 PlayerIdx=0; PlayerIdx<Players.Num(); PlayerIdx++)
		{
			const TSharedRef<const FUniqueNetId>& PlayerId = Players[PlayerIdx];

			FUniqueNetIdMatcher PlayerMatch(*PlayerId);
			if (Session->RegisteredPlayers.IndexOfByPredicate(PlayerMatch) == INDEX_NONE)
			{
				Session->RegisteredPlayers.Add(PlayerId);
				RegisterVoice(*PlayerId);

				// update number of open connections
				if (Session->NumOpenPublicConnections > 0)
				{
					Session->NumOpenPublicConnections--;
				}
				else if (Session->NumOpenPrivateConnections > 0)
				{
					Session->NumOpenPrivateConnections--;
				}
			}
			else
			{
				RegisterVoice(*PlayerId);
				UE_LOG_ONLINE_SESSION(Log, TEXT("Player %s already registered in session %s"), *PlayerId->ToDebugString(), *SessionName.ToString());
			}			
		}
	}
	else
	{
		UE_LOG_ONLINE_SESSION(Warning, TEXT("No game present to join for session (%s)"), *SessionName.ToString());
	}

	TriggerOnRegisterPlayersCompleteDelegates(SessionName, Players, bSuccess);
	return bSuccess;
}

But this does not seem to actually connect to any dedicated server, it just copies over some variables to our local client, and that's it. After joining the session would we then simply call APlayerController::ClientTravel() and pass our options to the server from here? But this is confusing because this would then in turn call the game mode init functionality. So my question is, when we call JoinSession() what happens? Where do we connect to our server? How does it find the server? Does that make sense?

That makes sense, so th e engine connects to whatever is returned in GetConnectStringFromSessionInfo()?

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();
}

That makes sense, it looks like it's called here, you see ClientTravel

Its been awhile since I looked at this thing but drop a breakpoint there and you’ll see, I think it’s called from ClientTravel or something? From: Daniel Gleason notifications@github.com Sent: Tuesday, June 30, 2020 8:20 AM To: RyroNZ/UE4MasterServer UE4MasterServer@noreply.github.com Cc: Ryan @ SL ryan@somethinglogical.co.nz; Comment comment@noreply.github.com Subject: Re: [RyroNZ/UE4MasterServer] Custom Online Subsystem (#12) That makes sense, so th e engine connects to whatever is returned in GetConnectStringFromSessionInfo()? — You are receiving this because you commented. Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AB3TRALVGSW4P6SFF4G3US3RZDZQRANCNFSM4OLHJPCA.

Yeah I found it, it's called in UJoinSessionCallbackProxy. Very messy system Unreal has! Lots of loops and hoops to go through. Thanks for the help, I think I got it all now.