JD2022-TU1/main/extern/UbiServices/custom/client-sdk/private/ubiservices/facadeInternal.cpp

729 lines
21 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "ubiservices/facadeInternal.h"
#include "ubiservices/core/configs/configpriv.h"
#include "ubiservices/core/debug/assert.h"
#include "ubiservices/core/errors/errorCodes.h"
#include "ubiservices/core/helpers/helpers.h"
#include "ubiservices/core/helpers/facadesManager.h"
#include "ubiservices/core/helpers/instancesManager.h"
#include "ubiservices/core/locks/scopedCS.h"
#include "ubiservices/core/log/remoteLoggerSdk.h"
#if defined(US_ENABLE_ALLOC_STATS)
#include "ubiservices/core/memory/memoryManagement.h"
#endif
#include "ubiservices/core/tasks/asyncResultInternal.h"
#include "ubiservices/facade.h"
#if defined(US_SDK_SERVER)
#include "ubiservices/services/authentication/authenticationClient.h"
#include "ubiservices/services/event/eventClient.h"
#include "ubiservices/services/event/eventClientImpl.h"
#include "ubiservices/services/remoteLog/remoteLogClient.h"
#include "ubiservices/services/remoteLog/remoteLoggerCustom.h"
#endif
#if !defined(US_SDK_SERVER)
#include "ubiservices/services/secondaryStore/sessionManagerStore.h"
#endif
#if defined(US_MODULE_APPLICATION)
#include "ubiservices/services/application/applicationClient.h"
#endif
#include "ubiservices/services/authentication/authenticationClient.h"
#if defined(US_MODULE_BATTLEPASS)
#include "ubiservices/services/battlepass/battlepassClient.h"
#endif
#if defined(US_MODULE_BLOCKLIST)
#include "ubiservices/services/blocklist/blocklistClient.h"
#endif
#if !defined(US_SDK_SERVER)
#include "ubiservices/services/cacheManager.h"
#endif
#if defined(US_MODULE_CHALLENGE)
#include "ubiservices/services/challenge/challengeClient.h"
#endif
#if defined(US_MODULE_CLUB)
#include "ubiservices/services/club/clubClient.h"
#endif // #if defined(US_MODULE_CLUB)
#if defined(US_MODULE_ENTITY)
#include "ubiservices/services/entity/entityClient.h"
#endif
#if defined(US_MODULE_FRIEND)
#include "ubiservices/services/friend/friendClient.h"
#endif
#if defined(US_MODULE_GAMESPLAYED)
#include "ubiservices/services/gamesPlayed/gamesPlayedClient.h"
#endif
#if !defined(US_SDK_SERVER)
#include "ubiservices/services/event/eventClient.h"
#include "ubiservices/services/event/eventClientImpl.h"
#endif //#if !defined(US_SDK_SERVER)
#include "ubiservices/services/http/httpClient.h"
#if defined(US_MODULE_LEADERBOARD)
#include "ubiservices/services/leaderboard/leaderboardClient.h"
#endif
#if defined(US_MODULE_LOCALIZATION)
#include "ubiservices/services/localization/localizationClient.h"
#endif
#if !defined(US_SDK_SERVER)
#include "ubiservices/services/notification/connectionClient.h"
#include "ubiservices/services/notification/notificationClient.h"
#include "ubiservices/services/overlay/overlayClient.h"
#endif // !defined(US_SDK_SERVER)
#if defined(US_MODULE_MATCHMAKING)
#include "ubiservices/services/matchmaking/matchmakingClient.h"
#endif
#if defined(US_MODULE_MODERATION)
#include "ubiservices/services/moderation/moderationClient.h"
#endif
#if defined(US_MODULE_NEWS)
#include "ubiservices/services/news/newsClient.h"
#endif
#include "ubiservices/services/parameters/parametersClient.h"
#if defined(US_MODULE_PLAYERREPORTS)
#include "ubiservices/services/playerReports/playerReportsClient.h"
#endif
#if defined(US_PRIMARY_STORE_ENABLED) || defined(US_PRIMARY_STORE_MOBILE_ENABLED)
#include "ubiservices/services/primaryStore/primaryStoreClient.h"
#endif
#if defined(US_MODULE_RECOMMENDATIONS)
#include "ubiservices/services/recommendations/recommendationsClient.h"
#endif
#if defined(US_ENABLE_UPLAY)
#include "ubiservices/services/uplay/uplayClient.h"
#endif
#if defined(US_MODULE_USER)
#include "ubiservices/services/user/userClient.h"
#endif
#if defined(US_MODULE_VOICECHAT)
#include "ubiservices/services/voicechat/voicechatClient.h"
#endif
#if defined(US_MODULE_PERSONA)
#include "ubiservices/services/persona/personaClient.h"
#endif
#if defined(US_MODULE_PLAYER_ONLINE_STATUS)
#include "ubiservices/services/playerOnlineStatus/playerOnlineStatusClient.h"
#endif
#if defined(US_MODULE_PROFILE)
#include "ubiservices/services/profile/profileClient.h"
#endif
#if !defined(US_SDK_SERVER)
#include "ubiservices/services/populations/populationClient.h"
#include "ubiservices/services/remoteLog/remoteLogClient.h"
#include "ubiservices/services/remoteLog/remoteLoggerCustom.h"
#include "ubiservices/services/secondaryStore/secondaryStoreClient.h"
#endif
#if defined(US_MODULE_SSI)
#include "ubiservices/services/secondaryStoreInstantiation/secondaryStoreInstantiationClient.h"
#endif
#if defined(US_MODULE_STATS)
#include "ubiservices/services/stats/statsClient.h"
#endif
#if defined(US_TARGET_WINDOWS)
#include "ubiservices/services/tLog/tLogClient.h"
#endif
#include "ubiservices/services/userGeneratedContents/userGeneratedContentsClient.h"
#include "ubiservices/services/websocket/websocketClient.h"
#include "ubiservices/sessionManager.h"
#if defined(US_SYSTEM_CHECK_ENABLED)
#define INVALIDATE_CALLED_FACADE_INVALID "The facade instance cannot be used anymore. The invalidate() method has been called."
#endif
#if defined(US_ENABLE_ALLOC_STATS)
struct AllocStatistics g_stats = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#endif
namespace US_NS {;
FacadeInternal::FacadeInternal()
: m_criticalSection(US_NEW(CriticalSection, "FacadeInternal::m_criticalSection", LockMasks::FourthLast))
, m_valid(true)
, m_sessionManager(US_NEW(SessionManager, *this))
, m_remoteLoggerSdk(US_NEW(RemoteLoggerSdk, *this))
, m_remoteLoggerCustom(US_NEW(RemoteLoggerCustom))
, m_owner(nullptr)
{
}
FacadeInternal::~FacadeInternal()
{
deleteMembers();
}
void FacadeInternal::init(Facade* owner)
{
m_owner = owner;
m_sessionManager->init();
}
void FacadeInternal::deleteMembers()
{
// Deletes the clients to terminate all pending jobs (order matters, don't change it).
#if defined(US_PRIMARY_STORE_ENABLED) || defined(US_PRIMARY_STORE_MOBILE_ENABLED)
m_primaryStoreClient.reset();
#endif
#if defined(US_MODULE_SSI)
m_secondaryStoreInstantiationClient.reset();
#endif
#if defined(US_MODULE_STORE)
m_secondaryStoreClient.reset();
#endif
#if defined(US_MODULE_ENTITY)
m_entityClient.reset();
#endif
#if defined(US_MODULE_FRIEND)
m_friendClient.reset();
#endif
#if defined(US_MODULE_CLUB)
m_clubClient.reset();
#endif
#if defined(US_MODULE_LEADERBOARD)
m_leaderboardClient.reset();
#endif
#if defined(US_ENABLE_UPLAY)
m_uplayClient.reset();
#endif
#if defined(US_MODULE_USER)
m_userClient.reset();
#endif
#if defined(US_TARGET_STADIA)
m_overlayClient.reset();
#endif // defined(US_TARGET_STADIA)
#if defined(US_MODULE_APPLICATION)
m_applicationClient.reset();
#endif
#if defined(US_MODULE_NEWS)
m_newsClient.reset();
#endif
#if !defined(US_SDK_SERVER)
m_eventClient.reset();
#if !defined(US_SDK_SERVER)
m_populationsClient.reset();
#endif
#if defined(US_MODULE_PROFILE)
// This service MUST be reset AFTER m_eventClient because it hosts
// an async result call performed during JobEventPostLogin.
// The ~EventClient cancels the call.
m_profileClient.reset();
#endif
m_authenticationClient.reset(); // ...should be deleted after all services
#if !defined(US_SDK_SERVER)
// Reset must be done after the authentication client.
// (however this does not prevent all teardown error cases!)
m_connectionClient.reset();
// Reset must be done after the connection client since jobInitiateConnection uses the notificationClient.
m_notificationClient.reset();
#endif
m_parametersClient.reset();
#endif
m_httpClient.reset();
// Critical sections need to be reset after connection client since JobManageConnection and JobInitiate connection
// are trying to get either the websocket client or the HTTP client
m_criticalSection.reset();
#if !defined(US_SDK_SERVER)
// Delete the event client again since it is called in the post login operations,
// i.e. by the authentication client, and may have been recreated
// TODO: Find a way to avoid this hack. Clients should not be accessible
// (and obviously not recreated) once they have been released.
m_eventClient.reset();
#if !defined(US_SDK_SERVER)
m_sessionManager->resetSessionInfo();
#endif
#endif
}
void FacadeInternal::invalidate()
{
US_LOG(LogLevel::Debug, LogCategory::Core, "Invalidating facade.");
deleteMembers();
// Set the state to invalid after deleting the members prevents ASSERTS.
// By deleting the members, pending calls are canceled. The cancel process
// may call some facade methods e.g. getAuthenticationClient().invalidateSessionInfo()
// which assert if the facade is invalid.
m_valid = false;
}
void FacadeInternal::stopFacade()
{
if (m_eventClient.get() != nullptr && m_eventClient->m_eventClientImpl.get() != nullptr)
{
m_eventClient->m_eventClientImpl->stopClient();
}
}
#if defined(US_SDK_SERVER)
AsyncResult<Empty> FacadeInternal::createSession(const String& secret, const Vector<String>& parametersGroupApplication,
const Vector<String>& parametersGroupSpace)
{
US_PERF_TASK_FUNC();
return getAuthenticationClient().createSession(secret, parametersGroupApplication, parametersGroupSpace);
}
#else
AsyncResult<Empty> FacadeInternal::createSession(const PlayerCredentialsBase& credentials,
const Vector<String>& parametersGroupApplication,
const Vector<String>& parametersGroupSpace,
const EventsParams& eventsParams
, const String& connectionMetaData
#if !defined(US_SDK_SERVER)
, const DynamicPopulationCustomParams& populationParams
#endif
#if defined(US_PRIMARY_STORE_WITHOUT_API)
, const PrimaryStoreParams& primaryStoreParams
#endif
)
{
US_PERF_TASK_FUNC();
AsyncResultInternal<Empty> result("FacadeInternal::createSession");
VALIDATE_SUSPENDED_MODE(result);
return getAuthenticationClient().createSession(credentials, parametersGroupApplication, parametersGroupSpace, eventsParams
#if !defined(US_SDK_SERVER)
, connectionMetaData, populationParams
#endif
#if defined(US_PRIMARY_STORE_WITHOUT_API)
, primaryStoreParams
#endif
);
}
#endif
AsyncResult<Empty> FacadeInternal::deleteSession()
{
US_PERF_TASK_FUNC();
US_ASSERT(m_valid, INVALIDATE_CALLED_FACADE_INVALID);
AsyncResultInternal<Empty> result("FacadeInternal::deleteSession");
VALIDATE_SUSPENDED_MODE(result);
#if !defined(US_SDK_SERVER)
// Clearing the caches here (instead of JobDeleteSession) prevents from instantiating unused clients.
CacheManager::invalidateCaches(*this);
#endif
return getAuthenticationClient().deleteSession();
}
template<class _TClientType>
_TClientType& FacadeInternal::getClient(::std::unique_ptr<_TClientType>& member)
{
US_ASSERT(m_valid, INVALIDATE_CALLED_FACADE_INVALID);
//US_ASSERT(m_criticalSection.get() != nullptr, "FacadeInternal deleted?");
if (member.get() == nullptr)
{
ScopedCS cs(*m_criticalSection);
if (member.get() == nullptr)
{
member.reset(US_NEW(_TClientType, *this));
}
}
return *member;
}
const SessionManager& FacadeInternal::getManager() const
{
return *m_sessionManager;
}
SessionManager& FacadeInternal::getManager()
{
return *m_sessionManager;
}
const Environment FacadeInternal::getDetectedEnvironment() const
{
return m_sessionManager->getDetectedEnvironment(&m_sessionManager->getSessionInfoRO());
}
const RemoteLoggerSdk& FacadeInternal::getRemoteLoggerSdk() const
{
return *m_remoteLoggerSdk;
}
RemoteLoggerSdk& FacadeInternal::getRemoteLoggerSdk()
{
return *m_remoteLoggerSdk;
}
const RemoteLoggerCustom& FacadeInternal::getRemoteLoggerCustom() const
{
return *m_remoteLoggerCustom;
}
RemoteLoggerCustom& FacadeInternal::getRemoteLoggerCustom()
{
return *m_remoteLoggerCustom;
}
/// Client accessors - All flavors (including modules)
#if defined(US_MODULE_APPLICATION)
const ApplicationClient& FacadeInternal::getApplicationClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast< ::std::unique_ptr<ApplicationClient>& >(m_applicationClient));
}
ApplicationClient& FacadeInternal::getApplicationClient()
{
return getClient(m_applicationClient);
}
#endif
const AuthenticationClient& FacadeInternal::getAuthenticationClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast< ::std::unique_ptr<AuthenticationClient>&>(m_authenticationClient));
}
AuthenticationClient& FacadeInternal::getAuthenticationClient()
{
return getClient(m_authenticationClient);
}
#if defined(US_MODULE_BATTLEPASS)
const BattlepassClient& FacadeInternal::getBattlepassClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<BattlepassClient>&>(m_battlepassClient));
}
BattlepassClient& FacadeInternal::getBattlepassClient()
{
return getClient(m_battlepassClient);
}
#endif
#if defined(US_MODULE_BLOCKLIST)
const BlocklistClient& FacadeInternal::getBlocklistClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<BlocklistClient>&>(m_blocklistClient));
}
BlocklistClient& FacadeInternal::getBlocklistClient()
{
return getClient(m_blocklistClient);
}
#endif
#if defined(US_MODULE_CHALLENGE)
const ChallengeClient& FacadeInternal::getChallengeClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<ChallengeClient>&>(m_challengeClient));
}
ChallengeClient& FacadeInternal::getChallengeClient()
{
return getClient(m_challengeClient);
}
#endif
HttpClient& FacadeInternal::getHttpClient()
{
return getClient(m_httpClient);
}
const EventClient& FacadeInternal::getEventClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast< ::std::unique_ptr<EventClient>&>(m_eventClient));
}
EventClient& FacadeInternal::getEventClient()
{
#if defined(US_TARGET_ANDROID) || defined(US_TARGET_IOS)
getClient(m_eventClient);
m_eventClient->init();
return *m_eventClient;
#else
return getClient(m_eventClient);
#endif
}
#if defined(US_MODULE_CLUB)
ClubClient& FacadeInternal::getClubClient()
{
return getClient(m_clubClient);
}
#endif
#if defined(US_MODULE_ENTITY)
EntityClient& FacadeInternal::getEntityClient()
{
return getClient(m_entityClient);
}
#endif
#if defined(US_MODULE_FRIEND)
FriendClient& FacadeInternal::getFriendClient()
{
return getClient(m_friendClient);
}
#endif
#if defined(US_MODULE_GAMESPLAYED)
GamesPlayedClient& FacadeInternal::getGamesPlayedClient()
{
return getClient(m_gamesPlayedClient);
}
#endif
#if defined(US_MODULE_LEADERBOARD)
LeaderboardClient& FacadeInternal::getLeaderboardClient()
{
return getClient(m_leaderboardClient);
}
#endif
#if defined(US_MODULE_LOCALIZATION)
LocalizationClient& FacadeInternal::getLocalizationClient()
{
return getClient(m_localizationClient);
}
#endif
#if defined(US_MODULE_MATCHMAKING)
const MatchmakingClient& FacadeInternal::getMatchmakingClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<MatchmakingClient>&>(m_matchmakingClient));
}
MatchmakingClient& FacadeInternal::getMatchmakingClient()
{
return getClient(m_matchmakingClient);
}
#endif
#if defined(US_MODULE_MODERATION)
const ModerationClient& FacadeInternal::getModerationClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<ModerationClient>&>(m_moderationClient));
}
ModerationClient& FacadeInternal::getModerationClient()
{
return getClient(m_moderationClient);
}
#endif
#if defined(US_MODULE_NEWS)
NewsClient& FacadeInternal::getNewsClient()
{
return getClient(m_newsClient);
}
#endif
const ParametersClient& FacadeInternal::getParametersClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<ParametersClient>&>(m_parametersClient));
}
ParametersClient& FacadeInternal::getParametersClient()
{
return getClient(m_parametersClient);
}
#if defined(US_MODULE_PERSONA)
const PersonaClient& FacadeInternal::getPersonaClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<PersonaClient>&>(m_personaClient));
}
PersonaClient& FacadeInternal::getPersonaClient()
{
return getClient(m_personaClient);
}
#endif
#if defined(US_MODULE_PLAYER_ONLINE_STATUS)
const PlayerOnlineStatusClient& FacadeInternal::getPlayerOnlineStatusClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<PlayerOnlineStatusClient>&>(m_playerOnlineStatusClient));
}
PlayerOnlineStatusClient& FacadeInternal::getPlayerOnlineStatusClient()
{
return getClient(m_playerOnlineStatusClient);
}
#endif
#if defined(US_MODULE_PLAYERREPORTS)
const PlayerReportsClient & FacadeInternal::getPlayerReportsClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<PlayerReportsClient>&>(m_playerReportsClient));
}
PlayerReportsClient & FacadeInternal::getPlayerReportsClient()
{
return getClient(m_playerReportsClient);
}
#endif
#if defined(US_MODULE_PROFILE)
const ProfileClient& FacadeInternal::getProfileClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<ProfileClient>&>(m_profileClient));
}
ProfileClient& FacadeInternal::getProfileClient()
{
return getClient(m_profileClient);
}
#endif
#if defined(US_MODULE_SSI)
SecondaryStoreInstantiationClient& FacadeInternal::getSecondaryStoreInstantiationClient()
{
return getClient(m_secondaryStoreInstantiationClient);
}
#endif
#if defined(US_PRIMARY_STORE_ENABLED) || defined(US_PRIMARY_STORE_MOBILE_ENABLED)
PrimaryStoreClient& FacadeInternal::getPrimaryStoreClient()
{
return getClient(m_primaryStoreClient);
}
#endif
#if defined(US_MODULE_RECOMMENDATIONS)
const RecommendationsClient& FacadeInternal::getRecommendationsClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<RecommendationsClient>&>(m_recommendationsClient));
}
RecommendationsClient& FacadeInternal::getRecommendationsClient()
{
return getClient(m_recommendationsClient);
}
#endif
RemoteLogClient& FacadeInternal::getRemoteLogClient()
{
return getClient(m_remoteLogClient);
}
#if defined(US_MODULE_STATS)
StatsClient& FacadeInternal::getStatsClient()
{
return getClient(m_statsClient);
}
#endif
#if defined(US_MODULE_STORE)
SecondaryStoreClient& FacadeInternal::getSecondaryStoreClient()
{
return getClient(m_secondaryStoreClient);
}
#endif
#if defined(US_MODULE_TLOG) && defined(US_TARGET_WINDOWS)
TLogClient& FacadeInternal::getTLogClient()
{
return getClient(m_tLogClient);
}
#endif
#if defined(US_ENABLE_UPLAY)
UplayClient& FacadeInternal::getUplayClient()
{
return getClient(m_uplayClient);
}
#endif
#if defined(US_MODULE_UGC)
const UserGeneratedContentsClient& FacadeInternal::getUserGeneratedContentsClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<UserGeneratedContentsClient>&>(m_userGeneratedContentsClient));
}
UserGeneratedContentsClient& FacadeInternal::getUserGeneratedContentsClient()
{
return getClient(m_userGeneratedContentsClient);
}
#endif
#if defined(US_MODULE_USER)
UserClient& FacadeInternal::getUserClient()
{
return getClient(m_userClient);
}
#endif
#if defined(US_MODULE_VOICECHAT)
VoicechatClient& FacadeInternal::getVoicechatClient()
{
return getClient(m_voicechatClient);
}
#endif
#if defined(US_TARGET_STADIA)
OverlayClient& FacadeInternal::getOverlayClient()
{
return getClient(m_overlayClient);
}
#endif // defined(US_TARGET_STADIA
/// Client accessors - Client that shouldn't be in Server SDK
#if !defined(US_SDK_SERVER)
ConnectionClient& FacadeInternal::getConnectionClient()
{
return getClient(m_connectionClient);
}
NotificationClient& FacadeInternal::getNotificationClient()
{
return getClient(m_notificationClient);
}
const PopulationClient& FacadeInternal::getPopulationsClient() const
{
return const_cast<FacadeInternal&>(*this).getClient(const_cast<::std::unique_ptr<PopulationClient>&>(m_populationsClient));
}
PopulationClient& FacadeInternal::getPopulationsClient()
{
return getClient(m_populationsClient);
}
WebSocketClient& FacadeInternal::getWebsocketClient()
{
return getClient(m_websocketClient);
}
#endif // !defined(US_SDK_SERVER)
RemoteLoggerCustom& TestRemoteLogClientHelper::getRemoteLoggerCustom(FacadeInternal& facade)
{
return facade.getRemoteLoggerCustom();
}
void TestExtendSessionHelper::reduceSessionDuration(Facade& facade, uint64 expirationTimeMs)
{
facade.m_facadeInternal->getManager().reduceSessionDuration(expirationTimeMs);
}
#if !defined(US_SDK_SERVER)
int32 TestSuspendedModeHelper::getRefCount(const Facade& facade)
{
return facade.m_facadeInternal->getRefCount();
}
int32 TestSuspendedModeHelper::getRefCount(const FacadeInternal& facade)
{
return facade.getRefCount();
}
void TestSuspendedModeHelper::copyRef(SmartPtr<FacadeInternal>& target, const Facade& source)
{
target = source.m_facadeInternal;
}
const HttpHeader& TestSuspendedModeHelper::getRemoteLoggerSdkHeaders(FacadeInternal& facade)
{
return facade.getRemoteLoggerSdk().m_remoteLogSession.getHeaders();
}
#endif
};