Passing Options Trhough Join Session Node?

Hi,

How can I pass options to the server when connecting to it using the Join Session node? it only has Player Controller and Session inputs.

Or is there another way of connecting?

Join Session | Unreal Engine Documentation

Thanks :wink:

What exactly are you trying to do? I ask this because you can use the player controller if you want to send some data after joining the session.

@BladeMaster Iā€™d like to ask the player to input a password which would be sent to the server as an option, and compared to the serverā€™s password in the PreLogin event. The PreLogin event will then either allow them to fully connect or kick them.

i wonder if it would be easier to let them, join, then ask for a password. Like a login server.

Then you can pass code to the server, and if its bad, kick them from there.

@Lammosan Yeah, that is an option but itā€™s not the perfect option because if you let them join, theyā€™ll have a player controller assigned, take up space on the server, appear in the player list, and the other players will be notified that they joined etc. Plus, if theyā€™re a hacker they might be able to run some kind of script on the server in that brief moment.

I think that the best thing to do is to check the password in the PreLogin event. I got the ban list to work there so it would be a shame if the password didnā€™t.

Curious. Excellent point, but, if theyre allowed to send a password, is it also not possible for them to run a script from that point?

Its just that you might be asking for too much. I know a login server requires you to log in to the login server, before you actually load into the game. Im betting thats your best bet.

Just force the client into a login place, before it loads any of the identifying information to the rest of the server. Create a bridge to your game, essentially.

Its programming, we can be lazy if we want, but we always pay for it sooner or later.

Do you know if thereā€™s a way to overwrite the Join Session / Join Session Callback Proxy nodes, or at least see how they work and if itā€™s even possible to pass a parameter through them?

I know that passing a parameter is easy with the Open Level node.

Hey, did you have a look at the Beacon system? I have not used it myself but maybe that would work?

Yes you can. All you have to do is override GetResolvedConnectString in your corresponding OSS code, and just attach the password to the ConnectInfo string.

Another option would be to have some sort of object that carries data between levels, for example a LocalPlayer subsystem, and inside PreLogin you pull the data from your subsystem and check against the database if itā€™s correct. More info on how to persist data can be found here.

Thanks for the reply.

Iā€™m using Steam Advanced Sessions and the Join Session Node to join a session.

Node

Where is GetResolvedConnectString located? Is it in the Game Instance? When is it called, after the Join Session function? Does the Join Session function pass information to it? How do I pass my password into it? And how do I get the password out of it in PreLogin?

I know how to override events but Iā€™m still new to C++ and programming in UE4. Would you be so kind as to create a small example that I and others could use and build upon?

Itā€™s part of the OSS youā€™re implementing. At this point I would suggest you leave everything, and learn C++. Then when youā€™re confident with C++, you have to pick up an OSS to implement. By default, you implement the Null Subsystem. If you want to release it on Steam, then you implement Steam OSS. If you want to release on EGS and you want cross play support, then you implement EOS. Once you figured all the previous, go back to my previous answer and you should have a clear vision of what you should do. Also all your questions will be answered if you look into the source code of that function and in general. Relying on UE web docs (and YT tutorials) is a bad habit you should avoid.

Here is what you can do to validade a password before joining a session:

First of all, while creating an advanced session, make an extra setting named ā€œpasswordā€ and set a password (like 123456).

Then on the client side, before joining the session, try to validade the password from the session result like this:

If the password input is equal to the server password setting, then the client will join session.

If you want to change the password later, you can update session like this:

1 Like

Thanks for the detailed answer!

The problem with this approach is that the password is sent to the client. So, all the user has to do is find out which password was sent and gain access to the server. Thatā€™s why Iā€™d like the server to decide whether to accept/decline the connection. That way the password is never sent to the client.

okay, i think i found a decent solution for this. iā€™m not great at networking nor c++, so thereā€™s probably a better way, but if you want players to optionally lock their servers with a password, hereā€™s how i did it:

donā€™t use extra settings in the session nodes for passwords. the check to see if the password is correct will be executed on the client, and that can be bypassed - especially if the server password is in plaintext. youā€™ll want to check if itā€™s correct on the server, and before the player officially joins.

create two new c++ classes. one a child of the LocalPlayer class (which is persistent throughout server travels), and the other a child of the GameModeBase class. name 'em whatever you like.

go to Project Settings->General Settings->Default Classes. set the Local Player Class to the localplayer class you just created. then, reparent the gamemode to your gamemodebase class.

okay, now open up your localplayer class. weā€™re gonna use GetGameLoginOptions to pass an additional string to the login options. this string will be an editable variable called ServerPassword.

UCLASS(BlueprintType)
class DEEPTERROR_API UDeepTerrorLocalPlayer : public ULocalPlayer
{
	GENERATED_BODY()

	virtual FString GetGameLoginOptions() const { return TEXT("Password=" + ServerPassword); }

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	FString ServerPassword;
}

get the localplayer, cast it to your custom localplayer, and set the serverpassword to whatever your password input is before you create a session and join a session. you might want to generate a hash from the string here using the low entry library.

alright, cool. now as a joining client your password is injected into the login options, and as a host you have access to your server password through the localplayer. now, we want to check whether they match.

so, weā€™re gonna override the prelogin function on your new gamemode. this function calls on the server when a player attempts to join your game. the Options string in the function will contain the password we passed through earlier as the client.

ADeepTerrorGameMode.h

virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override;
};

if the ErrorMessage string is not empty, the joining player is rejected from joining the server. so, if the parsed password is the same as the server password, we leave it blank - if not, we set it to a string.

#include "Kismet/GameplayStatics.h" for the handy ParseOption function (so we can find the value for the key ā€œPasswordā€), and #include "ProjectName/YourCustomLocalPlayer.h" so you can cast the localplayer to your own custom localplayer.

ADeepTerrorGameMode.cpp

void ADeepTerrorGameMode::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{

	FString ParsedPassword = UGameplayStatics::ParseOption(Options, TEXT("Password"));
	FString ServerPassword = Cast<UDeepTerrorLocalPlayer>(GetWorld()->GetFirstLocalPlayerFromController())->ServerPassword;

	if (ParsedPassword == ServerPassword) {
		ErrorMessage = "";
	} else {
		ErrorMessage = "Wrong password";
	}

	FGameModeEvents::GameModePreLoginEvent.Broadcast(this, UniqueId, ErrorMessage);
}

and, that should be all! now your password checking is done the server, and everything should be secure. again, iā€™m no expert, iā€™m just developing a relatively simple 4-player listen server co-op game, soā€¦ ya knowā€¦ do your own research.

thank you to @wizardcell for the Unreal Engine Persistent Data Compendium of which i understood at most 20 percent.

1 Like