Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

241 lines
8.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "OnlineIdentityGoogle.h"
#include "OnlineSubsystemGooglePrivate.h"
#include "Interfaces/OnlineExternalUIInterface.h"
#include "GoogleHelper.h"
#include "Misc/ConfigCacheIni.h"
FOnlineIdentityGoogle::FOnlineIdentityGoogle(FOnlineSubsystemGoogle* InSubsystem)
: FOnlineIdentityGoogleCommon(InSubsystem)
, bAllowSilentSignIn(false)
{
GConfig->GetBool(TEXT("OnlineSubsystemGoogle.OnlineIdentityGoogle"), TEXT("bAllowedSilentSignIn"), bAllowSilentSignIn, GEngineIni);
// Setup permission scope fields
GConfig->GetArray(TEXT("OnlineSubsystemGoogle.OnlineIdentityGoogle"), TEXT("ScopeFields"), ScopeFields, GEngineIni);
// always required login access fields
ScopeFields.AddUnique(TEXT(GOOGLE_PERM_PUBLIC_PROFILE));
}
FOnlineIdentityGoogle::~FOnlineIdentityGoogle()
{
}
bool FOnlineIdentityGoogle::Init()
{
if (ShouldRequestOfflineAccess())
{
NSString *ServerClientId = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GIDServerClientID"];
UE_CLOG_ONLINE_IDENTITY([ServerClientId length] == 0, Warning, TEXT("ServerClientId not found in config. Server Auth Code won't be requested"));
}
GoogleHelper = [[FGoogleHelper alloc] init];
FOnGoogleSignInCompleteDelegate OnSignInDelegate;
OnSignInDelegate.BindRaw(this, &FOnlineIdentityGoogle::OnSignInComplete);
[GoogleHelper AddOnGoogleSignInComplete: OnSignInDelegate];
FOnGoogleSignOutCompleteDelegate OnSignOutDelegate;
OnSignOutDelegate.BindRaw(this, &FOnlineIdentityGoogle::OnSignOutComplete);
[GoogleHelper AddOnGoogleSignOutComplete: OnSignOutDelegate];
return true;
}
void FOnlineIdentityGoogle::OnSignInComplete(const FGoogleSignInData& InSignInData)
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("OnSignInComplete %s"), ToString(InSignInData.Response));
if (LoginCompletionDelegate.IsBound())
{
LoginCompletionDelegate.ExecuteIfBound(InSignInData.Response, InSignInData.AuthToken);
LoginCompletionDelegate.Unbind();
}
}
void FOnlineIdentityGoogle::OnSignOutComplete(const FGoogleSignOutData& InSignOutData)
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("OnSignOutComplete %s"), ToString(InSignOutData.Response));
ensure(LogoutCompletionDelegate.IsBound());
LogoutCompletionDelegate.ExecuteIfBound(InSignOutData.Response);
LogoutCompletionDelegate.Unbind();
}
bool FOnlineIdentityGoogle::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials)
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("FOnlineIdentityGoogle::Login"));
bool bTriggeredLogin = false;
bool bPendingOp = LoginCompletionDelegate.IsBound() || LogoutCompletionDelegate.IsBound();
if (!bPendingOp)
{
ELoginStatus::Type LoginStatus = GetLoginStatus(LocalUserNum);
if (LoginStatus == ELoginStatus::NotLoggedIn)
{
PendingLoginRequestCb PendingLoginFn = [this, LocalUserNum](bool bWasSuccessful)
{
if (bWasSuccessful)
{
NSMutableArray* Permissions = [[NSMutableArray alloc] initWithCapacity:ScopeFields.Num()];
for (int32 ScopeIdx = 0; ScopeIdx < ScopeFields.Num(); ScopeIdx++)
{
NSString* ScopeStr = [NSString stringWithFString:ScopeFields[ScopeIdx]];
[Permissions addObject: ScopeStr];
}
LoginCompletionDelegate = FOnInternalLoginComplete::CreateLambda([this, LocalUserNum](EGoogleLoginResponse InResponseCode, const FAuthTokenGoogle& InAccessToken)
{
if (InResponseCode == EGoogleLoginResponse::RESPONSE_OK)
{
Login(LocalUserNum, InAccessToken, FOnLoginCompleteDelegate::CreateRaw(this, &FOnlineIdentityGoogle::OnAccessTokenLoginComplete));
}
else
{
FString ErrorStr;
if (InResponseCode == EGoogleLoginResponse::RESPONSE_CANCELED)
{
ErrorStr = LOGIN_CANCELLED;
}
else
{
ErrorStr = FString::Printf(TEXT("Login failure %s"), ToString(InResponseCode));
}
OnLoginAttemptComplete(LocalUserNum, ErrorStr);
}
});
[GoogleHelper Login: Permissions attemptSilentSignIn: bAllowSilentSignIn];
}
else
{
const FString ErrorStr = TEXT("Error retrieving discovery service");
OnLoginAttemptComplete(LocalUserNum, ErrorStr);
}
};
bTriggeredLogin = true;
RetrieveDiscoveryDocument(MoveTemp(PendingLoginFn));
}
else
{
TriggerOnLoginCompleteDelegates(LocalUserNum, true, *GetUniquePlayerId(LocalUserNum), TEXT("Already logged in"));
}
}
else
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("FOnlineIdentityGoogle::Login Operation already in progress!"));
FString ErrorStr = FString::Printf(TEXT("Operation already in progress"));
TriggerOnLoginCompleteDelegates(LocalUserNum, false, *FUniqueNetIdGoogle::EmptyId(), ErrorStr);
}
return bTriggeredLogin;
}
void FOnlineIdentityGoogle::Login(int32 LocalUserNum, const FAuthTokenGoogle& InToken, const FOnLoginCompleteDelegate& InCompletionDelegate)
{
FOnProfileRequestComplete ProfileCompletionDelegate = FOnProfileRequestComplete::CreateLambda([this, InCompletionDelegate](int32 ProfileLocalUserNum, bool bWasSuccessful, const FString& ErrorStr)
{
if (bWasSuccessful)
{
InCompletionDelegate.ExecuteIfBound(ProfileLocalUserNum, bWasSuccessful, *GetUniquePlayerId(ProfileLocalUserNum), ErrorStr);
}
else
{
InCompletionDelegate.ExecuteIfBound(ProfileLocalUserNum, bWasSuccessful, *FUniqueNetIdGoogle::EmptyId(), ErrorStr);
}
});
ProfileRequest(LocalUserNum, InToken, ProfileCompletionDelegate);
}
void FOnlineIdentityGoogle::OnAccessTokenLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UniqueId, const FString& Error)
{
OnLoginAttemptComplete(LocalUserNum, Error);
}
void FOnlineIdentityGoogle::OnLoginAttemptComplete(int32 LocalUserNum, const FString& ErrorStr)
{
const FString ErrorStrCopy(ErrorStr);
if (GetLoginStatus(LocalUserNum) == ELoginStatus::LoggedIn)
{
UE_LOG_ONLINE_IDENTITY(Display, TEXT("Google login was successful"));
FUniqueNetIdPtr UserId = GetUniquePlayerId(LocalUserNum);
check(UserId.IsValid());
GoogleSubsystem->ExecuteNextTick([this, UserId, LocalUserNum, ErrorStrCopy]()
{
TriggerOnLoginCompleteDelegates(LocalUserNum, true, *UserId, ErrorStrCopy);
TriggerOnLoginStatusChangedDelegates(LocalUserNum, ELoginStatus::NotLoggedIn, ELoginStatus::LoggedIn, *UserId);
});
}
else
{
GoogleSubsystem->ExecuteNextTick([this, LocalUserNum, ErrorStrCopy]()
{
TriggerOnLoginCompleteDelegates(LocalUserNum, false, *FUniqueNetIdGoogle::EmptyId(), ErrorStrCopy);
});
}
}
bool FOnlineIdentityGoogle::Logout(int32 LocalUserNum)
{
bool bTriggeredLogout = false;
ELoginStatus::Type LoginStatus = GetLoginStatus(LocalUserNum);
bool bPendingOp = LoginCompletionDelegate.IsBound() || LogoutCompletionDelegate.IsBound();
if (!bPendingOp)
{
if (LoginStatus == ELoginStatus::LoggedIn)
{
LogoutCompletionDelegate = FOnInternalLogoutComplete::CreateLambda([this, LocalUserNum](EGoogleLoginResponse InResponseCode)
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("FOnInternalLogoutComplete %s"), ToString(InResponseCode));
FUniqueNetIdPtr UserId = GetUniquePlayerId(LocalUserNum);
if (UserId.IsValid())
{
// remove cached user account
UserAccounts.Remove(UserId->ToString());
}
else
{
UserId = FUniqueNetIdGoogle::EmptyId();
}
// remove cached user id
UserIds.Remove(LocalUserNum);
GoogleSubsystem->ExecuteNextTick([this, UserId, LocalUserNum]()
{
TriggerOnLogoutCompleteDelegates(LocalUserNum, true);
TriggerOnLoginStatusChangedDelegates(LocalUserNum, ELoginStatus::LoggedIn, ELoginStatus::NotLoggedIn, *UserId);
});
});
bTriggeredLogout = true;
[GoogleHelper Logout];
}
else
{
UE_LOG_ONLINE_IDENTITY(Warning, TEXT("No logged in user found for LocalUserNum=%d."), LocalUserNum);
}
}
else
{
UE_LOG_ONLINE_IDENTITY(Warning, TEXT("FOnlineIdentityGoogle::Logout - Operation already in progress"));
}
if (!bTriggeredLogout)
{
UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("FOnlineIdentityGoogle::Logout didn't trigger logout"));
GoogleSubsystem->ExecuteNextTick([this, LocalUserNum]()
{
TriggerOnLogoutCompleteDelegates(LocalUserNum, false);
});
}
return bTriggeredLogout;
}