void FOnlineAchievementsGameCircle::WriteAchievements( const FUniqueNetId& PlayerId, FOnlineAchievementsWriteRef& WriteObject, const FOnAchievementsWrittenDelegate& Delegate ) { if (AndroidSubsystem->GetCallbackManager() == nullptr || AndroidSubsystem->GetIdentityGameCircle()->GetLoginStatus(0) != ELoginStatus::LoggedIn) { WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } for (FStatPropertyArray::TConstIterator It(WriteObject->Properties); It; ++It) { // Access the stat and the value. const FVariantData& Stat = It.Value(); // Create an achievement object which should be reported to the server. const FString AchievementId(It.Key().ToString()); float PercentComplete = 0.0f; // Setup the percentage complete with the value we are writing from the variant type switch (Stat.GetType()) { case EOnlineKeyValuePairDataType::Int32: { int32 Value; Stat.GetValue(Value); PercentComplete = (float)Value; break; } case EOnlineKeyValuePairDataType::Float: { float Value; Stat.GetValue(Value); PercentComplete = Value; break; } default: { UE_LOG(LogOnline, Error, TEXT("FOnlineAchievementsGameCircle Trying to write an achievement with incompatible format. Not a float or int")); break; } } AmazonGames::AchievementsClientInterface::updateProgress(FOnlineSubsystemGameCircle::ConvertFStringToStdString(AchievementId).c_str(), PercentComplete, new FOnlineUpdateProgressCallback(AndroidSubsystem)); } Delegate.ExecuteIfBound(PlayerId, true); }
void FOnlineAchievementsSteam::OnWriteAchievementsComplete(const FUniqueNetIdSteam& PlayerId, bool bWasSuccessful, FOnlineAchievementsWritePtr& WriteObject, const FOnAchievementsWrittenDelegate& Delegate) { // write object should be valid check(WriteObject.IsValid()); // if write completed successfully, unlock the achievements (and update their cache) if (bWasSuccessful) { TArray<FOnlineAchievement> * PlayerAch = PlayerAchievements.Find(PlayerId); check(PlayerAch); // were we writing for a non-existing player? if (NULL != PlayerAch && WriteObject.IsValid()) { // treat each achievement as unlocked const int32 AchNum = PlayerAch->Num(); for (FStatPropertyArray::TConstIterator It(WriteObject->Properties); It; ++It) { const FString AchievementId = It.Key().ToString(); for (int32 AchIdx = 0; AchIdx < AchNum; ++AchIdx) { if ((*PlayerAch)[ AchIdx ].Id == AchievementId) { // Update and trigger the callback (*PlayerAch)[ AchIdx ].Progress = 100.0; TriggerOnAchievementUnlockedDelegates(PlayerId, (*PlayerAch)[ AchIdx ].Id); break; } } } } } Delegate.ExecuteIfBound(PlayerId, bWasSuccessful); }
void FOnlineAchievementsNull::WriteAchievements(const FUniqueNetId& PlayerId, FOnlineAchievementsWriteRef& WriteObject, const FOnAchievementsWrittenDelegate& Delegate) { if (!ReadAchievementsFromConfig()) { // we don't have achievements WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } FUniqueNetIdString NullId(PlayerId); const TArray<FOnlineAchievement> * PlayerAch = PlayerAchievements.Find(NullId); if (NULL == PlayerAch) { // achievements haven't been read for a player WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } // treat each achievement as unlocked const int32 AchNum = PlayerAch->Num(); for (FStatPropertyArray::TConstIterator It(WriteObject->Properties); It; ++It) { const FString AchievementId = It.Key().ToString(); for (int32 AchIdx = 0; AchIdx < AchNum; ++AchIdx) { if ((*PlayerAch)[ AchIdx ].Id == AchievementId) { TriggerOnAchievementUnlockedDelegates(PlayerId, AchievementId); break; } } } WriteObject->WriteState = EOnlineAsyncTaskState::Done; Delegate.ExecuteIfBound(PlayerId, true); };
void FOnlineAchievementsSteam::WriteAchievements(const FUniqueNetId& PlayerId, FOnlineAchievementsWriteRef& WriteObject, const FOnAchievementsWrittenDelegate& Delegate) { if (!bHaveConfiguredAchievements) { // we don't have achievements UE_LOG_ONLINE(Warning, TEXT("Steam achievements have not been configured in .ini")); WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } FUniqueNetIdSteam SteamId(PlayerId); // check if this is our player (cannot report for someone else) if (SteamUser() == NULL || SteamUser()->GetSteamID() != SteamId) { // we don't have achievements UE_LOG_ONLINE(Warning, TEXT("Cannot report Steam achievements for non-local player %s"), *PlayerId.ToString()); WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } const TArray<FOnlineAchievement> * PlayerAch = PlayerAchievements.Find(SteamId); if (NULL == PlayerAch) { // achievements haven't been read for a player UE_LOG_ONLINE(Warning, TEXT("Steam achievements have not been read for player %s"), *PlayerId.ToString()); WriteObject->WriteState = EOnlineAsyncTaskState::Failed; Delegate.ExecuteIfBound(PlayerId, false); return; } const int32 AchNum = PlayerAch->Num(); for (FStatPropertyArray::TConstIterator It(WriteObject->Properties); It; ++It) { const FString AchievementId = It.Key().ToString(); UE_LOG_ONLINE(Verbose, TEXT("WriteObject AchievementId: '%s'"), *AchievementId); for (int32 AchIdx = 0; AchIdx < AchNum; ++AchIdx) { if ((*PlayerAch)[ AchIdx ].Id == AchievementId) { // do not unlock it now, but after a successful write #if !UE_BUILD_SHIPPING float Value = 0.0f; It.Value().GetValue(Value); if (Value <= 0.0f) { UE_LOG_ONLINE(Verbose, TEXT("Resetting achievement '%s'"), *AchievementId); SteamUserStats()->ClearAchievement(TCHAR_TO_UTF8(*AchievementId)); } else { #endif // !UE_BUILD_SHIPPING UE_LOG_ONLINE(Verbose, TEXT("Setting achievement '%s'"), *AchievementId); SteamUserStats()->SetAchievement(TCHAR_TO_UTF8(*AchievementId)); #if !UE_BUILD_SHIPPING } #endif // !UE_BUILD_SHIPPING break; } } } StatsInt->WriteAchievementsInternal(SteamId, WriteObject, Delegate); };