bool FOnlineIdentityGooglePlay::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { bool bStartedLogin = false; if (bLoggedIn) { // already logged in so just report all is ok! // Now logged in bStartedLogin = true; static const int32 MAX_TEXT_LINE_LEN = 32; TCHAR Line[MAX_TEXT_LINE_LEN + 1] = { 0 }; int32 Len = FCString::Snprintf(Line, MAX_TEXT_LINE_LEN, TEXT("%d"), LocalUserNum); const FString PlayerId(Line); UniqueNetId = MakeShareable(new FUniqueNetIdString(PlayerId)); TriggerOnLoginCompleteDelegates(LocalUserNum, true, *UniqueNetId, TEXT("")); } else if (!PendingConnectRequest.IsConnectionPending) { // Kick the login sequence... bStartedLogin = true; PendingConnectRequest.IsConnectionPending = true; } else { TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdString(TEXT("")), FString("Already trying to login")); } return bStartedLogin; }
bool FOnlineIdentitySteam::AutoLogin(int32 LocalUserNum) { if (!IsRunningDedicatedServer()) { // Double check they are properly logged in if (SteamUserPtr != NULL && // Login is handled by steam SteamUserPtr->BLoggedOn()) { // Login changed delegate TriggerOnLoginChangedDelegates(LocalUserNum); // Login completion delegate FString AuthToken = GetAuthToken(LocalUserNum); TriggerOnLoginCompleteDelegates(LocalUserNum, true, FUniqueNetIdSteam(SteamUserPtr->GetSteamID()), TEXT("")); return true; } TriggerOnLoginCompleteDelegates(0, false, FUniqueNetIdSteam(0), TEXT("AutoLogin failed. Not logged in or no connection.")); return false; } else { // Autologin for dedicated servers happens via session creation in the GameServerAPI LogOnAnonymous() return false; } }
bool FOnlineIdentityNull::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { FString ErrorStr; TSharedPtr<FUserOnlineAccountNull> UserAccountPtr; // valid local player index if (LocalUserNum < 0 || LocalUserNum >= MAX_LOCAL_PLAYERS) { ErrorStr = FString::Printf(TEXT("Invalid LocalUserNum=%d"), LocalUserNum); } else if (AccountCredentials.Id.IsEmpty()) { ErrorStr = FString::Printf(TEXT("Invalid account id=%s"), *AccountCredentials.Id); } else { TSharedPtr<FUniqueNetId>* UserId = UserIds.Find(LocalUserNum); if (UserId == NULL) { FString RandomUserId = GenerateRandomUserId(LocalUserNum); FUniqueNetIdString NewUserId(RandomUserId); UserAccountPtr = MakeShareable(new FUserOnlineAccountNull(RandomUserId)); UserAccountPtr->UserAttributes.Add(TEXT("id"), RandomUserId); // update/add cached entry for user UserAccounts.Add(NewUserId, UserAccountPtr.ToSharedRef()); // keep track of user ids for local users UserIds.Add(LocalUserNum, UserAccountPtr->GetUserId()); } else { const FUniqueNetIdString* UniqueIdStr = (FUniqueNetIdString*)(UserId->Get()); TSharedRef<FUserOnlineAccountNull>* TempPtr = UserAccounts.Find(*UniqueIdStr); check(TempPtr); UserAccountPtr = *TempPtr; } } if (!ErrorStr.IsEmpty()) { UE_LOG_ONLINE(Warning, TEXT("Login request failed. %s"), *ErrorStr); TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdString(), ErrorStr); return false; } TriggerOnLoginCompleteDelegates(LocalUserNum, true, *UserAccountPtr->GetUserId(), ErrorStr); return true; }
bool FOnlineIdentityAmazon::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { bool bWasSuccessful = false; if (!bHasLoginOutstanding && AmazonEndpoint.Len() && RedirectUrl.Len() && ClientId.Len()) { State = FString::FromInt(FMath::Rand() % 100000); const FString& Command = FString::Printf(TEXT("%s?scope=profile&response_type=code&redirect_uri=%s&client_id=%s&state=%s"), *AmazonEndpoint, *RedirectUrl, *ClientId, *State); // This should open the browser with the command as the URL bHasLoginOutstanding = bWasSuccessful = FPlatformMisc::OsExecute(TEXT("open"), *Command); if (!bWasSuccessful) { UE_LOG(LogOnline, Error, TEXT("RegisterUser() : Failed to execute command %s "), *Command); } else { // keep track of local user requesting registration LocalUserNumPendingLogin = LocalUserNum; } } else { UE_LOG(LogOnline, Error, TEXT("RegisterUser() : OnlineSubsystemAmazon is improperly configured in DefaultEngine.ini")); } if (!bWasSuccessful) { TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdString(TEXT("")), FString(TEXT("RegisterUser() failed"))); } return bWasSuccessful; }
void FOnlineIdentityAmazon::TickLogin(float DeltaTime) { if (bHasLoginOutstanding) { LastCheckElapsedTime += DeltaTime; TotalCheckElapsedTime += DeltaTime; // See if enough time has elapsed in order to check for completion if (LastCheckElapsedTime > 1.f || // Do one last check if we're getting ready to time out TotalCheckElapsedTime > MaxCheckElapsedTime) { LastCheckElapsedTime = 0.f; FString Title; if (FPlatformMisc::GetWindowTitleMatchingText(TEXT("accessToken"), Title)) { bHasLoginOutstanding = false; FUserOnlineAccountAmazon User; if (ParseLoginResults(Title, User)) { TSharedRef<FUserOnlineAccountAmazon> UserRef(new FUserOnlineAccountAmazon(User.UserId, User.SecretKey, User.AuthTicket)); UserAccounts.Add(User.UserId, UserRef); TriggerOnLoginCompleteDelegates(LocalUserNumPendingLogin, true, *UserRef->GetUserId(), FString()); } else { TriggerOnLoginCompleteDelegates(LocalUserNumPendingLogin, false, FUniqueNetIdString(TEXT("")), FString(TEXT("RegisterUser() failed to parse the user registration results"))); } } // Trigger the delegate if we hit the timeout limit else if (TotalCheckElapsedTime > MaxCheckElapsedTime) { bHasLoginOutstanding = false; TriggerOnLoginCompleteDelegates(LocalUserNumPendingLogin, false, FUniqueNetIdString(TEXT("")), FString(TEXT("RegisterUser() timed out without getting the data"))); } } // Reset our time trackers if we are done ticking for now if (!bHasLoginOutstanding) { LastCheckElapsedTime = 0.f; TotalCheckElapsedTime = 0.f; } } }
void FOnlineIdentityGooglePlay::OnLoginCompleted(const int playerID, const gpg::AuthStatus errorCode) { static const int32 MAX_TEXT_LINE_LEN = 32; TCHAR Line[MAX_TEXT_LINE_LEN + 1] = { 0 }; int32 Len = FCString::Snprintf(Line, MAX_TEXT_LINE_LEN, TEXT("%d"), playerID); UniqueNetId = MakeShareable(new FUniqueNetIdString(Line)); bLoggedIn = errorCode == gpg::AuthStatus::VALID; TriggerOnLoginCompleteDelegates(playerID, bLoggedIn, *UniqueNetId, TEXT("")); PendingConnectRequest.IsConnectionPending = false; }
bool FOnlineIdentityIOS::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { UE_LOG(LogOnline, Verbose, TEXT("FOnlineIdentityIOS::Login")); bool bStartedLogin = false; if( GetLocalGameCenterUser() && GetLocalGameCenterUser().isAuthenticated ) { // Login was handled by gamecenter FString PlayerId( ANSI_TO_TCHAR( [GetLocalGameCenterUser().playerID cStringUsingEncoding:NSASCIIStringEncoding] ) ); UniqueNetId = MakeShareable( new FUniqueNetIdString( PlayerId ) ); TriggerOnLoginCompleteDelegates(LocalUserNum, true, *UniqueNetId, TEXT("")); bStartedLogin = true; }
bool FOnlineIdentitySteam::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { FString ErrorStr; if (LocalUserNum < MAX_LOCAL_PLAYERS) { // Double check they are properly logged in if (SteamUserPtr != NULL && // Login is handled by steam SteamUserPtr->BLoggedOn()) { // Login changed delegate TriggerOnLoginChangedDelegates(LocalUserNum); // Login completion delegate TriggerOnLoginCompleteDelegates(LocalUserNum, true, FUniqueNetIdSteam(SteamUserPtr->GetSteamID()), TEXT("")); return true; } else { // User is not currently logged into Steam ErrorStr = TEXT("Not logged in or no connection."); } } else { // Requesting a local user is always invalid ErrorStr = FString::Printf(TEXT("Invalid user %d"),LocalUserNum); } if (!ErrorStr.IsEmpty()) { UE_LOG_ONLINE(Warning, TEXT("Failed Steam login. %s"), *ErrorStr); TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdSteam(0), ErrorStr); } return false; }
bool FOnlineIdentityLeet::Login(int32 LocalUserNum, const FOnlineAccountCredentials& AccountCredentials) { UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::Login")); FString ErrorStr; if (bHasLoginOutstanding) { ErrorStr = FString::Printf(TEXT("Registration already pending for user %d"), LocalUserNumPendingLogin); } else if (!(LoginUrl.Len() && LoginRedirectUrl.Len() && ClientId.Len())) { ErrorStr = FString::Printf(TEXT("OnlineSubsystemLeet is improperly configured in DefaultEngine.ini LeetEndpoint=%s RedirectUrl=%s ClientId=%s"), *LoginUrl, *LoginRedirectUrl, *ClientId); } else { // random number to represent client generated state for verification on login State = FString::FromInt(FMath::Rand() % 100000); // auth url to spawn in browser const FString& Command = FString::Printf(TEXT("%s?redirect_uri=%s&client_id=%s&state=%s&response_type=token"), *LoginUrl, *LoginRedirectUrl, *ClientId, *State); UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::Login - %s"), *LoginUrl); // This should open the browser with the command as the URL if (FPlatformMisc::OsExecute(TEXT("open"), *Command)) { // keep track of local user requesting registration LocalUserNumPendingLogin = LocalUserNum; bHasLoginOutstanding = true; } else { ErrorStr = FString::Printf(TEXT("Failed to execute command %s"), *Command); } } if (!ErrorStr.IsEmpty()) { UE_LOG(LogOnline, Error, TEXT("RegisterUser() failed: %s"), *ErrorStr); TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdString(TEXT("")), ErrorStr); return false; } return true; }
/** * Ticks the registration process handling timeouts, etc. * * @param DeltaTime the amount of time that has elapsed since last tick */ void FOnlineIdentityLeet::TickLogin(float DeltaTime) { if (bHasLoginOutstanding) { //UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::TickLogin bHasLoginOutstanding")); LastCheckElapsedTime += DeltaTime; TotalCheckElapsedTime += DeltaTime; // See if enough time has elapsed in order to check for completion if (LastCheckElapsedTime > 1.f || // Do one last check if we're getting ready to time out TotalCheckElapsedTime > MaxCheckElapsedTime) { LastCheckElapsedTime = 0.f; FString Title; // Find the browser window we spawned which should now be titled with the redirect url if (FPlatformMisc::GetWindowTitleMatchingText(*LoginRedirectUrl, Title)) { UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::TickLogin GetWindowTitleMatchingText")); bHasLoginOutstanding = false; // Parse access token from the login redirect url FString AccessToken; if (FParse::Value(*Title, TEXT("access_token="), AccessToken) && !AccessToken.IsEmpty()) { UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::TickLogin Found access_token")); // strip off any url parameters and just keep the token itself FString AccessTokenOnly; if (AccessToken.Split(TEXT("&"), &AccessTokenOnly, NULL)) { AccessToken = AccessTokenOnly; } // kick off http request to get user info with the new token TSharedRef<class IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest(); LoginUserRequests.Add(&HttpRequest.Get(), FPendingLoginUser(LocalUserNumPendingLogin, AccessToken)); FString MeUrl = TEXT("https://leetsandbox.appspot.com/me?access_token=`token"); HttpRequest->OnProcessRequestComplete().BindRaw(this, &FOnlineIdentityLeet::MeUser_HttpRequestComplete); HttpRequest->SetURL(MeUrl.Replace(TEXT("`token"), *AccessToken, ESearchCase::IgnoreCase)); HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json")); HttpRequest->SetVerb(TEXT("GET")); HttpRequest->ProcessRequest(); } else { TriggerOnLoginCompleteDelegates(LocalUserNumPendingLogin, false, FUniqueNetIdString(TEXT("")), FString(TEXT("RegisterUser() failed to parse the user registration results"))); } } // Trigger the delegate if we hit the timeout limit else if (TotalCheckElapsedTime > MaxCheckElapsedTime) { bHasLoginOutstanding = false; TriggerOnLoginCompleteDelegates(LocalUserNumPendingLogin, false, FUniqueNetIdString(TEXT("")), FString(TEXT("RegisterUser() timed out without getting the data"))); } } // Reset our time trackers if we are done ticking for now if (!bHasLoginOutstanding) { LastCheckElapsedTime = 0.f; TotalCheckElapsedTime = 0.f; } } }
void FOnlineIdentityLeet::MeUser_HttpRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) { UE_LOG_ONLINE(Display, TEXT("FOnlineIdentityLeet::MeUser_HttpRequestComplete")); bool bResult = false; FString ResponseStr, ErrorStr; FUserOnlineAccountLeet User; FPendingLoginUser PendingRegisterUser = LoginUserRequests.FindRef(HttpRequest.Get()); // Remove the request from list of pending entries LoginUserRequests.Remove(HttpRequest.Get()); if (bSucceeded && HttpResponse.IsValid()) { ResponseStr = HttpResponse->GetContentAsString(); if (EHttpResponseCodes::IsOk(HttpResponse->GetResponseCode())) { UE_LOG(LogOnline, Verbose, TEXT("RegisterUser request complete. url=%s code=%d response=%s"), *HttpRequest->GetURL(), HttpResponse->GetResponseCode(), *ResponseStr); if (User.FromJson(ResponseStr)) { if (!User.UserId.IsEmpty()) { // copy and construct the unique id TSharedRef<FUserOnlineAccountLeet> UserRef(new FUserOnlineAccountLeet(User)); UserRef->UserIdPtr = MakeShareable(new FUniqueNetIdString(User.UserId)); // update/add cached entry for user UserAccounts.Add(User.UserId, UserRef); // update the access token UserRef->AuthTicket = PendingRegisterUser.AccessToken; // keep track of user ids for local users UserIds.Add(PendingRegisterUser.LocalUserNum, UserRef->GetUserId()); bResult = true; } else { ErrorStr = FString::Printf(TEXT("Missing user id. payload=%s"), *ResponseStr); } } else { ErrorStr = FString::Printf(TEXT("Invalid response payload=%s"), *ResponseStr); } } else { ErrorStr = FString::Printf(TEXT("Invalid response. code=%d error=%s"), HttpResponse->GetResponseCode(), *ResponseStr); } } else { ErrorStr = TEXT("No response"); } if (!ErrorStr.IsEmpty()) { UE_LOG(LogOnline, Warning, TEXT("RegisterUser request failed. %s"), *ErrorStr); } TriggerOnLoginCompleteDelegates(PendingRegisterUser.LocalUserNum, bResult, FUniqueNetIdString(User.UserId), ErrorStr); }