bool IsPlayerInSessionImpl(IOnlineSession* SessionInt, FName SessionName, const FUniqueNetId& UniqueId) { bool bFound = false; FNamedOnlineSession* Session = SessionInt->GetNamedSession(SessionName); if (Session != NULL) { const bool bIsSessionOwner = *Session->OwningUserId == UniqueId; FUniqueNetIdMatcher PlayerMatch(UniqueId); if (bIsSessionOwner || Session->RegisteredPlayers.FindMatch(PlayerMatch) != INDEX_NONE) { bFound = true; } } return bFound; }
bool FOnlineSessionNull::UnregisterPlayers(FName SessionName, const TArray< TSharedRef<const FUniqueNetId> >& Players) { bool bSuccess = true; FNamedOnlineSession* Session = GetNamedSession(SessionName); if (Session) { for (int32 PlayerIdx=0; PlayerIdx < Players.Num(); PlayerIdx++) { const TSharedRef<const FUniqueNetId>& PlayerId = Players[PlayerIdx]; FUniqueNetIdMatcher PlayerMatch(*PlayerId); int32 RegistrantIndex = Session->RegisteredPlayers.IndexOfByPredicate(PlayerMatch); if (RegistrantIndex != INDEX_NONE) { Session->RegisteredPlayers.RemoveAtSwap(RegistrantIndex); UnregisterVoice(*PlayerId); // update number of open connections if (Session->NumOpenPublicConnections < Session->SessionSettings.NumPublicConnections) { Session->NumOpenPublicConnections++; } else if (Session->NumOpenPrivateConnections < Session->SessionSettings.NumPrivateConnections) { Session->NumOpenPrivateConnections++; } } else { UE_LOG_ONLINE(Warning, TEXT("Player %s is not part of session (%s)"), *PlayerId->ToDebugString(), *SessionName.ToString()); } } } else { UE_LOG_ONLINE(Warning, TEXT("No game present to leave for session (%s)"), *SessionName.ToString()); bSuccess = false; } TriggerOnUnregisterPlayersCompleteDelegates(SessionName, Players, bSuccess); return bSuccess; }
bool FOnlineSessionNull::RegisterPlayers(FName SessionName, const TArray< TSharedRef<const FUniqueNetId> >& Players, bool bWasInvited) { bool bSuccess = false; FNamedOnlineSession* Session = GetNamedSession(SessionName); if (Session) { bSuccess = true; for (int32 PlayerIdx=0; PlayerIdx<Players.Num(); PlayerIdx++) { const TSharedRef<const FUniqueNetId>& PlayerId = Players[PlayerIdx]; FUniqueNetIdMatcher PlayerMatch(*PlayerId); if (Session->RegisteredPlayers.IndexOfByPredicate(PlayerMatch) == INDEX_NONE) { Session->RegisteredPlayers.Add(PlayerId); RegisterVoice(*PlayerId); // update number of open connections if (Session->NumOpenPublicConnections > 0) { Session->NumOpenPublicConnections--; } else if (Session->NumOpenPrivateConnections > 0) { Session->NumOpenPrivateConnections--; } } else { RegisterVoice(*PlayerId); UE_LOG_ONLINE(Log, TEXT("Player %s already registered in session %s"), *PlayerId->ToDebugString(), *SessionName.ToString()); } } } else { UE_LOG_ONLINE(Warning, TEXT("No game present to join for session (%s)"), *SessionName.ToString()); } TriggerOnRegisterPlayersCompleteDelegates(SessionName, Players, bSuccess); return bSuccess; }
TSharedPtr<FVoicePacket> FOnlineVoiceSteam::SerializeRemotePacket(FArchive& Ar) { TSharedPtr<FVoicePacketSteam> NewPacket = MakeShareable(new FVoicePacketSteam()); NewPacket->Serialize(Ar); if (Ar.IsError() == false && NewPacket->GetBufferSize() > 0) { if (!SteamSubsystem->IsDedicated()) { FUniqueNetIdMatcher PlayerMatch(*NewPacket->GetSender()); if (MuteList.IndexOfByPredicate(PlayerMatch) == INDEX_NONE) { VoiceData.RemotePackets.Add(NewPacket); } } return NewPacket; } return NULL; }
TSharedPtr<FVoicePacket> FOnlineVoiceImpl::SerializeRemotePacket(FArchive& Ar) { TSharedPtr<FVoicePacketImpl> NewPacket = MakeShareable(new FVoicePacketImpl()); NewPacket->Serialize(Ar); if (Ar.IsError() == false && NewPacket->GetBufferSize() > 0) { if (!IsRunningDedicatedServer()) { FUniqueNetIdMatcher PlayerMatch(*NewPacket->GetSender()); if (MuteList.FindMatch(PlayerMatch) == INDEX_NONE) { VoiceData.RemotePackets.Add(NewPacket); } } return NewPacket; } return NULL; }
void APartyBeaconHost::Tick(float DeltaTime) { IOnlineSessionPtr SessionsInt = Online::GetSessionInterface(); if (SessionsInt.IsValid()) { FNamedOnlineSession* Session = SessionsInt->GetNamedSession(SessionName); if (Session) { TArray< TSharedPtr<FUniqueNetId> > PlayersToLogout; for (int32 ResIdx=0; ResIdx < Reservations.Num(); ResIdx++) { FPartyReservation& PartyRes = Reservations[ResIdx]; // Determine if we have a client connection for the reservation bool bIsConnectedReservation = false; for (int32 ClientIdx=0; ClientIdx < ClientActors.Num(); ClientIdx++) { APartyBeaconClient* Client = Cast<APartyBeaconClient>(ClientActors[ClientIdx]); if (Client) { const FPartyReservation& ClientRes = Client->GetPendingReservation(); if (ClientRes.PartyLeader == PartyRes.PartyLeader) { bIsConnectedReservation = true; break; } } else { UE_LOG(LogBeacon, Error, TEXT("Missing PartyBeaconClient found in ClientActors array")); ClientActors.RemoveAtSwap(ClientIdx); ClientIdx--; } } // Don't update clients that are still connected if (bIsConnectedReservation) { for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; PlayerEntry.ElapsedTime = 0.0f; } } // Once a client disconnects, update the elapsed time since they were found as a registrant in the game session else { for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; // Determine if the player is the owner of the session const bool bIsSessionOwner = Session->OwningUserId.IsValid() && (*Session->OwningUserId == *PlayerEntry.UniqueId); // Determine if the player member is registered in the game session if (SessionsInt->IsPlayerInSession(SessionName, *PlayerEntry.UniqueId) || // Never timeout the session owner bIsSessionOwner) { FUniqueNetIdMatcher PlayerMatch(*PlayerEntry.UniqueId); int32 FoundIdx = PlayersPendingJoin.FindMatch(PlayerMatch); if (FoundIdx != INDEX_NONE) { UE_LOG(LogBeacon, Display, TEXT("Beacon (%s): pending player %s found in session (%s)."), *GetName(), *PlayerEntry.UniqueId->ToDebugString(), *SessionName.ToString()); // reset elapsed time since found PlayerEntry.ElapsedTime = 0.0f; // also remove from pending join list PlayersPendingJoin.RemoveAtSwap(FoundIdx); } } else { // update elapsed time PlayerEntry.ElapsedTime += DeltaTime; // if the player is pending it's initial join then check against TravelSessionTimeoutSecs instead FUniqueNetIdMatcher PlayerMatch(*PlayerEntry.UniqueId); int32 FoundIdx = PlayersPendingJoin.FindMatch(PlayerMatch); const bool bIsPlayerPendingJoin = FoundIdx != INDEX_NONE; // if the timeout has been exceeded then add to list of players // that need to be logged out from the beacon if ((bIsPlayerPendingJoin && PlayerEntry.ElapsedTime > TravelSessionTimeoutSecs) || (!bIsPlayerPendingJoin && PlayerEntry.ElapsedTime > SessionTimeoutSecs)) { PlayersToLogout.AddUnique(PlayerEntry.UniqueId.GetUniqueNetId()); } } } } } // Logout any players that timed out for (int32 LogoutIdx=0; LogoutIdx < PlayersToLogout.Num(); LogoutIdx++) { bool bFound = false; const TSharedPtr<FUniqueNetId>& UniqueId = PlayersToLogout[LogoutIdx]; float ElapsedSessionTime = 0.f; for (int32 ResIdx=0; ResIdx < Reservations.Num(); ResIdx++) { FPartyReservation& PartyRes = Reservations[ResIdx]; for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; if (*PlayerEntry.UniqueId == *UniqueId) { ElapsedSessionTime = PlayerEntry.ElapsedTime; bFound = true; break; } } if (bFound) { break; } } UE_LOG(LogBeacon, Display, TEXT("Beacon (%s): player logout due to timeout for %s, elapsed time = %0.3f"), *GetName(), *UniqueId->ToDebugString(), ElapsedSessionTime); // Also remove from pending join list PlayersPendingJoin.RemoveSingleSwap(UniqueId); // let the beacon handle the logout and notifications/delegates FUniqueNetIdRepl RemovedId(UniqueId); HandlePlayerLogout(RemovedId); } } } }