EOS OnLoginComplete never gets called, even after successful authentication

Hi.

I’ve been trying to implement EOS/EAS into my project, it works, and I can use the Developer Auth Tool or the Account portal to login successfully, client log shows this:

LogEOSSDK: LogEOSAuth: NewUserToken: User ClientId: xyz...mNz AccountId: 55c...bf3 Access[Expires: 2022.01.06-16.05.49 Remaining: 7200.22] Refresh[Expires: 2022-01-06T22:05:49.219Z Remaining: 28800.22] State: Valid
LogEOSSDK: LogEOSAuth: GenerateUserAuth success
LogEOSSDK: LogEOSAuth: login/queryuserinfo success
LogEOSSDK: LogEOSAuth: Login Tasks Complete: 0

But the game instance never calls OnLoginStatusChange or OnLoginComplete.

I added it like this:

Identity->OnLoginStatusChangedDelegates->AddUObject(this, &UEOSGameInstance::OnLoginStatusChanged);
Identity->OnLoginCompleteDelegates->AddUObject(this, &UEOSGameInstance::OnLoginComplete);

Directly after this, there is a call to Identity->Login(0, Credentials); but the event never fires.
EOS events do get called, for example CreateSession send me the notification after it’s complete.
How could I fix this?

I’m not sure if you’ve found a solution to your issue yet, this is a proxy I’ve been using to login with my project that you can take a look at, I must stress I’m new to creating online proxy nodes so I’m not sure if I’m creating the proxy correctly.

If someone with a bit more experience happens to pop by and notices something wrong with the code I would appreciate and pointers.

I hope this helps =)

EOS_LoginProxy.h

#pragma once

#include "CoreMinimal.h"
#include "OnlineSubsystem.h"
#include "Interfaces/OnlineIdentityInterface.h"
#include "Net/OnlineBlueprintCallProxyBase.h"
#include "EOS_LoginProxy.generated.h"

/**
 * 
 */
UCLASS()
class GENESISPLUGIN_API UEOS_LoginProxy : public UOnlineBlueprintCallProxyBase
{
	GENERATED_BODY()
		FDelegateHandle LoginDelegateHandle;

	// Called when the session was created successfully
	UPROPERTY(BlueprintAssignable)
		FEmptyOnlineDelegate OnSuccess;

	// Called when there was an error creating the session
	UPROPERTY(BlueprintAssignable)
		FEmptyOnlineDelegate OnFailure;

	UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject"), Category = "Online|EOS|Networking")
		static UEOS_LoginProxy* EOS_Login(UObject* WorldContextObject, class APlayerController* PlayerController);

	virtual void Activate() override;
	void HandleLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error);

	TWeakObjectPtr<APlayerController> PlayerControllerWeakPtr;
	UObject* WorldContextObject;
	
};

EOS_LoginProxy.cpp

#include "EOS_LoginProxy.h"

UEOS_LoginProxy* UEOS_LoginProxy::EOS_Login(UObject* WorldContextObject, APlayerController* PlayerController)
{
	UEOS_LoginProxy* Proxy = NewObject<UEOS_LoginProxy>();
	Proxy->WorldContextObject = WorldContextObject;
	Proxy->PlayerControllerWeakPtr = PlayerController;

	return Proxy;
}

void UEOS_LoginProxy::Activate()
{
	UE_LOG_ONLINE(Error, TEXT("EOS Login Activated"), "");
	IOnlineSubsystem* OSS = IOnlineSubsystem::Get();
	if (OSS)
	{
		IOnlineIdentityPtr Identity = OSS->GetIdentityInterface();
		if (Identity.IsValid())
		{
			FOnlineAccountCredentials AccountCredentials;
			AccountCredentials.Id = TEXT("");
			AccountCredentials.Token = TEXT("");
			AccountCredentials.Type = TEXT("accountportal");

			LoginDelegateHandle = Identity->AddOnLoginCompleteDelegate_Handle(0, FOnLoginComplete::FDelegate::CreateUObject(this, &UEOS_LoginProxy::HandleLoginComplete));
			Identity->Login(0, AccountCredentials);
		}
		else
		{
			OnFailure.Broadcast();
		}
	}
	else
	{
		OnFailure.Broadcast();
	}
}

void UEOS_LoginProxy::HandleLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error)
{
	if (bWasSuccessful == true)
	{
		OnSuccess.Broadcast();
	}
	else
	{
		OnFailure.Broadcast();

	}

	IOnlineSubsystem* OSS = IOnlineSubsystem::Get();
	if (OSS)
	{
		IOnlineIdentityPtr Identity = OSS->GetIdentityInterface();
		if (Identity.IsValid())
		{
			Identity->ClearOnLoginCompleteDelegate_Handle(LocalUserNum, this->LoginDelegateHandle);
			this->LoginDelegateHandle.Reset();
		}
	}
	UE_LOG_ONLINE(Error, TEXT("EOS Login Complete"), "");
}

And some test functions

bool UEOSLib::EOS_IsLoggedIn(const UObject* WorldContextObject)
{
	IOnlineSubsystem* OSS = IOnlineSubsystem::Get();
	if (OSS)
	{
		IOnlineIdentityPtr Identity = OSS->GetIdentityInterface();
		if (Identity.IsValid())
		{
			switch (Identity->GetLoginStatus(0)) {
			case ELoginStatus::LoggedIn:
				return true;
				break;
			case ELoginStatus::NotLoggedIn:
				return false;
				break;
			default:
				return false;
			}
		}
	}
    return false;
}


FString UEOSLib::EOS_GetPlayerNickName(const UObject* WorldContextObject, int32 LocalUserNum )
{   
	IOnlineSubsystem* OSS = IOnlineSubsystem::Get();
	if (OSS)
	{
		IOnlineIdentityPtr Identity = OSS->GetIdentityInterface();
		if (Identity.IsValid())
		{
			return Identity->GetPlayerNickname(LocalUserNum);
		}
	}
	return "";
}

I have the same issue. I am able to see OnLoginComplete ONLY if I give it the wrong credentials (intentionally). In that case I can see it fail.

If I put the correct credentials in, I get the same LogEOSSDK messages and no callbacks fired.

Anyone finding a solution ?
I have the same issue but even on fail it doesn’t trigger the delegates. Then if I still try to start a session it says that the user is not logged in…

Have you tried running your project using “Launch Game” context or as a Standalone to see if it runs properly there?

Running in Editor appears to trigger a chain of events that cause the EOS SDK to EOS Subsystem callback wrappers to fail to run properly. I’d imagine this is either a bug or unintended by Epic.

Specifically in OnlineSubsystemEOSTypes.h there’s a templated wrapper TEOSCallback that handles the call backs. It pushes notifications back via it’s CallbackImpl method, in side of which is this check:

if (FCallbackBase::ShouldCancelAllCallbacks())
{
	delete CallbackThis;
	return;
}

That early out of the callback, prevents the Online Subsystem from being notified about the callbacks from the EOS SDK and would result in the delegates never firing.

I’ve noticed that FCallbackBase::CancelAllCallbacks() gets called from FOnlineSubsystemEOS::Shutdown(). Which is run when the Subsystems are being reset/restarted for a PIE session.

This can be confirmed by launching your project as a packaged build, using context menu option “Launch Game” or “Standalone Game” in the Play options.

3 Likes

It does help. It’s a workaround.
I will look into fixing the plugin code so I can start it inside the editor (if possible).

I’ve created a PR with the code changes that I found to be necessary to support the testing in Editor flows with EOS: https://github.com/EpicGames/UnrealEngine/pull/8861

Perhaps this will help you locally testing as well? I created a copy of the plugin in my local projects folder to confirm that it functioned as expected.

I’m happy (by seeing your code) that my fix was going in the right direction but didn’t finish it. I will merge you PR into my local plugin to test it too.
Thanks a lot

thx a lot! I used viewport mode firstly and it worked well in 4.27.1. Then recently I updated to 4.27.2, viewport mode not work, so I used “Standalone” or “LaunchGame” mode and it did work according to your answer, that’s the key finally! Oh, and fk ue4 (not really)

You all should stick to testing the client & server with a launcher instead of Play in Editor. Most things work that way. Even if you get login to work inside the editor, it will just do logging in once, and after that you have to restart the whole editor. To fix this, you need to create .bat / .sh files to launch the Editor, and the project with -client / -server and use them.

Example .sh I’m using:

/Users/Shared/Epic\ Games/UE_4.27/Engine/Binaries/Mac/UE4Editor.app/Contents/MacOS/UE4Editor /Users/Shifty/Documents/Unreal\ Projects/MyProject4/MyProject4.uproject MainMenu -game -clientonly -ResX=1280 -ResY=720 -WINDOWED -log

You can do the same thing with server, just change the -game -clientonly to -server. The MainMenu is the name of the map it should load - beware, even if you set the project settings to default a map, you should set the client to the main menu here, and the server to the map of your game for it to work properly.

Bug still here in 5.0.1. Impossible to trigger the event.

This worked.
Instead of creating a bat/sh file you can even use ‘Additional Launch Parameters’

1 Like

It does look like in 5.1 they’ll have a fix for this by ensuring the requesting/owner object of the callback is valid at the point of return.