bool FOnlineLeaderboardsNull::ReadLeaderboardsForFriends(int32 LocalUserNum, FOnlineLeaderboardReadRef& ReadObject) { TArray< TSharedRef<const FUniqueNetId> > FriendsList; // always add a UniqueNetId for local user check(NullSubsystem); IOnlineIdentityPtr Identity = NullSubsystem->GetIdentityInterface(); if (Identity.IsValid()) { if (Identity->GetUniquePlayerId(LocalUserNum).IsValid()) { FriendsList.Add(Identity->GetUniquePlayerId(LocalUserNum).ToSharedRef()); } } // add all known players FLeaderboardNull* Leaderboard = Leaderboards.Find(ReadObject->LeaderboardName); if (Leaderboard) { for (int32 UserIdx = 0; UserIdx < Leaderboard->Rows.Num(); ++UserIdx) { if (Leaderboard->Rows[UserIdx].PlayerId.IsValid()) { FriendsList.AddUnique(Leaderboard->Rows[UserIdx].PlayerId.ToSharedRef()); } } } return ReadLeaderboards(FriendsList, ReadObject); }
virtual void FireEvent_FlushChatStats() override { if (AnalyticsProvider.IsValid()) { IOnlineIdentityPtr OnlineIdentity = Online::GetIdentityInterface(TEXT("MCP")); if (OnlineIdentity.IsValid()) { TSharedPtr<const FUniqueNetId> UserId = OnlineIdentity->GetUniquePlayerId(0); if (UserId.IsValid()) { auto RecordSocialChatCountsEvents = [=](const TMap<FString, int32>& ChatCounts, const FString& ChatType) { if (ChatCounts.Num()) { TArray<FAnalyticsEventAttribute> Attributes; for (const auto& Pair : ChatCounts) { Attributes.Empty(3); Attributes.Emplace(TEXT("Name"), Pair.Key); Attributes.Emplace(TEXT("Type"), ChatType); Attributes.Emplace(TEXT("Count"), Pair.Value); AnalyticsProvider->RecordEvent("Social.Chat.Counts.2", Attributes); } } }; RecordSocialChatCountsEvents(ChannelChatCounts, TEXT("Channel")); RecordSocialChatCountsEvents(PrivateChatCounts, TEXT("Private")); } } } ChannelChatCounts.Empty(); PrivateChatCounts.Empty(); }
void AShooterPlayerController::GameHasEnded(class AActor* EndGameFocus, bool bIsWinner) { // write stats ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); if (LocalPlayer) { AShooterPlayerState* ShooterPlayerState = Cast<AShooterPlayerState>(PlayerState); if (ShooterPlayerState) { // update local saved profile UShooterPersistentUser* const PersistentUser = GetPersistentUser(); if (PersistentUser) { PersistentUser->AddMatchResult( ShooterPlayerState->GetKills(), ShooterPlayerState->GetDeaths(), ShooterPlayerState->GetNumBulletsFired(), ShooterPlayerState->GetNumRocketsFired(), bIsWinner); PersistentUser->SaveIfDirty(); } // update achievements UpdateAchievementsOnGameEnd(); // update leaderboards IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get(); if(OnlineSub) { IOnlineIdentityPtr Identity = OnlineSub->GetIdentityInterface(); if (Identity.IsValid()) { TSharedPtr<FUniqueNetId> UserId = Identity->GetUniquePlayerId(LocalPlayer->ControllerId); if (UserId.IsValid()) { IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardsInterface(); if (Leaderboards.IsValid()) { FShooterAllTimeMatchResultsWrite WriteObject; WriteObject.SetIntStat(LEADERBOARD_STAT_SCORE, ShooterPlayerState->GetKills()); WriteObject.SetIntStat(LEADERBOARD_STAT_KILLS, ShooterPlayerState->GetKills()); WriteObject.SetIntStat(LEADERBOARD_STAT_DEATHS, ShooterPlayerState->GetDeaths()); WriteObject.SetIntStat(LEADERBOARD_STAT_MATCHESPLAYED, 1); // the call will copy the user id and write object to its own memory Leaderboards->WriteLeaderboards(ShooterPlayerState->SessionName, *UserId, WriteObject); } } } } } } Super::GameHasEnded(EndGameFocus, bIsWinner); }
void AShooterPlayerController::UpdateAchievementProgress( const FString& Id, float Percent ) { ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); if (LocalPlayer) { IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(); if(OnlineSub) { IOnlineIdentityPtr Identity = OnlineSub->GetIdentityInterface(); if (Identity.IsValid()) { TSharedPtr<FUniqueNetId> UserId = Identity->GetUniquePlayerId(LocalPlayer->ControllerId); if (UserId.IsValid()) { IOnlineAchievementsPtr Achievements = OnlineSub->GetAchievementsInterface(); if (Achievements.IsValid() && (!WriteObject.IsValid() || WriteObject->WriteState != EOnlineAsyncTaskState::InProgress)) { WriteObject = MakeShareable(new FOnlineAchievementsWrite()); WriteObject->SetFloatStat(*Id, Percent); FOnlineAchievementsWriteRef WriteObjectRef = WriteObject.ToSharedRef(); Achievements->WriteAchievements(*UserId.Get(), WriteObjectRef); } else { UE_LOG(LogOnline, Warning, TEXT("No valid achievement interface or another write is in progress.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No valid user id for this controller.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No valid identity interface.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No default online subsystem.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No local player, cannot update achievements.")); } }
void AShooterPlayerController::QueryAchievements() { // precache achievements ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); if (LocalPlayer) { IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(); if(OnlineSub) { IOnlineIdentityPtr Identity = OnlineSub->GetIdentityInterface(); if (Identity.IsValid()) { TSharedPtr<FUniqueNetId> UserId = Identity->GetUniquePlayerId(LocalPlayer->ControllerId); if (UserId.IsValid()) { IOnlineAchievementsPtr Achievements = OnlineSub->GetAchievementsInterface(); if (Achievements.IsValid()) { Achievements->QueryAchievements( *UserId.Get(), FOnQueryAchievementsCompleteDelegate::CreateUObject( this, &AShooterPlayerController::OnQueryAchievementsComplete )); } } else { UE_LOG(LogOnline, Warning, TEXT("No valid user id for this controller.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No valid identity interface.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No default online subsystem.")); } } else { UE_LOG(LogOnline, Warning, TEXT("No local player, cannot read achievements.")); } }
void FFriendsMessageManager::Init( FOnFriendsNotification& NotificationDelegate, bool bInCanJointGame ) { // Clear existing data Logout(); FriendsListNotificationDelegate = &NotificationDelegate; bCanJoinGame = bInCanJointGame; bPollForMessages = false; OnlineSubMcp = static_cast< FOnlineSubsystemMcp* >( IOnlineSubsystem::Get( TEXT( "MCP" ) ) ); if (OnlineSubMcp != NULL && OnlineSubMcp->GetIdentityInterface().IsValid() && OnlineSubMcp->GetMessageInterface().IsValid()) { // Add our delegate for the async call OnEnumerateMessagesCompleteDelegate = FOnEnumerateMessagesCompleteDelegate::CreateSP(this, &FFriendsMessageManager::OnEnumerateMessagesComplete); OnReadMessageCompleteDelegate = FOnReadMessageCompleteDelegate::CreateSP(this, &FFriendsMessageManager::OnReadMessageComplete); OnSendMessageCompleteDelegate = FOnSendMessageCompleteDelegate::CreateSP(this, &FFriendsMessageManager::OnSendMessageComplete); OnDeleteMessageCompleteDelegate = FOnDeleteMessageCompleteDelegate::CreateSP(this, &FFriendsMessageManager::OnDeleteMessageComplete); OnlineSubMcp->GetMessageInterface()->AddOnEnumerateMessagesCompleteDelegate(0, OnEnumerateMessagesCompleteDelegate); OnlineSubMcp->GetMessageInterface()->AddOnReadMessageCompleteDelegate(0, OnReadMessageCompleteDelegate); OnlineSubMcp->GetMessageInterface()->AddOnSendMessageCompleteDelegate(0, OnSendMessageCompleteDelegate); OnlineSubMcp->GetMessageInterface()->AddOnDeleteMessageCompleteDelegate(0, OnDeleteMessageCompleteDelegate); IOnlineIdentityPtr OnlineIdentity = OnlineSubMcp->GetIdentityInterface(); TSharedPtr<FUniqueNetId> UserId = OnlineIdentity->GetUniquePlayerId(0); if ( UserId.IsValid() ) { DisplayName = OnlineIdentity->GetUserAccount( *UserId )->GetDisplayName(); } if ( UpdateMessagesTickerDelegate.IsBound() == false ) { UpdateMessagesTickerDelegate = FTickerDelegate::CreateSP( this, &FFriendsMessageManager::Tick ); } ManagerState = EFriendsMessageManagerState::Idle; FTicker::GetCoreTicker().AddTicker( UpdateMessagesTickerDelegate ); } }
bool FOnlineSubsystemImpl::IsLocalPlayer(const FUniqueNetId& UniqueId) const { if (!IsDedicated()) { IOnlineIdentityPtr IdentityInt = GetIdentityInterface(); if (IdentityInt.IsValid()) { for (int32 LocalUserNum = 0; LocalUserNum < MAX_LOCAL_PLAYERS; LocalUserNum++) { TSharedPtr<const FUniqueNetId> LocalUniqueId = IdentityInt->GetUniquePlayerId(LocalUserNum); if (LocalUniqueId.IsValid() && UniqueId == *LocalUniqueId) { return true; } } } } return false; }
bool FOnlineSessionNull::CreateSession(int32 HostingPlayerNum, FName SessionName, const FOnlineSessionSettings& NewSessionSettings) { uint32 Result = E_FAIL; // Check for an existing session FNamedOnlineSession* Session = GetNamedSession(SessionName); if (Session == NULL) { // Create a new session and deep copy the game settings Session = AddNamedSession(SessionName, NewSessionSettings); check(Session); Session->SessionState = EOnlineSessionState::Creating; Session->NumOpenPrivateConnections = NewSessionSettings.NumPrivateConnections; Session->NumOpenPublicConnections = NewSessionSettings.NumPublicConnections; // always start with full public connections, local player will register later Session->HostingPlayerNum = HostingPlayerNum; check(NullSubsystem); IOnlineIdentityPtr Identity = NullSubsystem->GetIdentityInterface(); if (Identity.IsValid()) { Session->OwningUserId = Identity->GetUniquePlayerId(HostingPlayerNum); Session->OwningUserName = Identity->GetPlayerNickname(HostingPlayerNum); } // if did not get a valid one, use just something if (!Session->OwningUserId.IsValid()) { Session->OwningUserId = MakeShareable(new FUniqueNetIdString(FString::Printf(TEXT("%d"), HostingPlayerNum))); Session->OwningUserName = FString(TEXT("NullUser")); } // Unique identifier of this build for compatibility Session->SessionSettings.BuildUniqueId = GetBuildUniqueId(); // Setup the host session info FOnlineSessionInfoNull* NewSessionInfo = new FOnlineSessionInfoNull(); NewSessionInfo->Init(*NullSubsystem); Session->SessionInfo = MakeShareable(NewSessionInfo); Result = UpdateLANStatus(); if (Result != ERROR_IO_PENDING) { // Set the game state as pending (not started) Session->SessionState = EOnlineSessionState::Pending; if (Result != ERROR_SUCCESS) { // Clean up the session info so we don't get into a confused state RemoveNamedSession(SessionName); } else { RegisterLocalPlayers(Session); } } } else { UE_LOG_ONLINE(Warning, TEXT("Cannot create session '%s': session already exists."), *SessionName.ToString()); } if (Result != ERROR_IO_PENDING) { TriggerOnCreateSessionCompleteDelegates(SessionName, (Result == ERROR_SUCCESS) ? true : false); } return Result == ERROR_IO_PENDING || Result == ERROR_SUCCESS; }
void TestUniqueIdRepl(UWorld* InWorld) { bool bSuccess = true; IOnlineIdentityPtr IdentityPtr = Online::GetIdentityInterface(InWorld); if (IdentityPtr.IsValid()) { TSharedPtr<FUniqueNetId> UserId = IdentityPtr->GetUniquePlayerId(0); FUniqueNetIdRepl EmptyIdIn; if (EmptyIdIn.IsValid()) { UE_LOG(LogNet, Warning, TEXT("EmptyId is valid."), *EmptyIdIn->ToString()); bSuccess = false; } FUniqueNetIdRepl ValidIdIn(UserId); if (!ValidIdIn.IsValid() || UserId != ValidIdIn.GetUniqueNetId()) { UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *UserId->ToString(), *ValidIdIn->ToString()); bSuccess = false; } if (bSuccess) { TArray<uint8> Buffer; for (int32 i=0; i<2; i++) { Buffer.Empty(); FMemoryWriter TestWriteUniqueId(Buffer); if (i == 0) { // Normal serialize TestWriteUniqueId << EmptyIdIn; TestWriteUniqueId << ValidIdIn; } else { // Net serialize bool bSuccess = false; EmptyIdIn.NetSerialize(TestWriteUniqueId, NULL, bSuccess); ValidIdIn.NetSerialize(TestWriteUniqueId, NULL, bSuccess); } FMemoryReader TestReadUniqueId(Buffer); FUniqueNetIdRepl EmptyIdOut; TestReadUniqueId << EmptyIdOut; if (EmptyIdOut.GetUniqueNetId().IsValid()) { UE_LOG(LogNet, Warning, TEXT("EmptyId %s should have been invalid"), *EmptyIdOut->ToString()); bSuccess = false; } FUniqueNetIdRepl ValidIdOut; TestReadUniqueId << ValidIdOut; if (*UserId != *ValidIdOut.GetUniqueNetId()) { UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *ValidIdIn->ToString(), *ValidIdOut->ToString()); bSuccess = false; } } } } if (!bSuccess) { UE_LOG(LogNet, Warning, TEXT("TestUniqueIdRepl test failure!")); } }
void UUpdateManager::StartPatchCheck() { ensure(ChecksEnabled()); UGameInstance* GameInstance = GetGameInstance(); check(GameInstance); bool bStarted = false; SetUpdateState(EUpdateState::CheckingForPatch); IOnlineSubsystem* OnlineSubConsole = IOnlineSubsystem::GetByPlatform(); if (OnlineSubConsole) { IOnlineIdentityPtr OnlineIdentityConsole = OnlineSubConsole->GetIdentityInterface(); if (OnlineIdentityConsole.IsValid()) { ULocalPlayer* LP = GameInstance->GetFirstGamePlayer(); if (LP != nullptr) { const int32 ControllerId = LP->GetControllerId(); TSharedPtr<const FUniqueNetId> UserId = OnlineIdentityConsole->GetUniquePlayerId(ControllerId); if (UserId.IsValid()) { bStarted = true; OnlineIdentityConsole->GetUserPrivilege(*UserId, EUserPrivileges::CanPlayOnline, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCheckForPatchComplete, true)); } else { UE_LOG(LogHotfixManager, Warning, TEXT("No valid platform user id when starting patch check!")); } } else { UE_LOG(LogHotfixManager, Warning, TEXT("No local player to perform check!")); } } } else { if (GameInstance->IsDedicatedServerInstance()) { bStarted = true; PatchCheckComplete(EPatchCheckResult::NoPatchRequired); } else { UWorld* World = GetWorld(); IOnlineIdentityPtr IdentityInt = Online::GetIdentityInterface(World); if (IdentityInt.IsValid()) { ULocalPlayer* LP = GameInstance->GetFirstGamePlayer(); if (LP != nullptr) { const int32 ControllerId = LP->GetControllerId(); TSharedPtr<const FUniqueNetId> UserId = IdentityInt->GetUniquePlayerId(ControllerId); if (!bInitialUpdateFinished && !UserId.IsValid()) { // Invalid user for "before title/login" check, underlying code doesn't need a valid user currently UserId = IdentityInt->CreateUniquePlayerId(TEXT("InvalidUser")); } if (UserId.IsValid()) { bStarted = true; IdentityInt->GetUserPrivilege(*UserId, EUserPrivileges::CanPlayOnline, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCheckForPatchComplete, false)); } else { UE_LOG(LogHotfixManager, Warning, TEXT("No valid user id when starting patch check!")); } } else { UE_LOG(LogHotfixManager, Warning, TEXT("No local player to perform check!")); } } } } if (!bStarted) { // Any failure to call GetUserPrivilege will result in completing the flow via this path PatchCheckComplete(EPatchCheckResult::PatchCheckFailure); } }