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

218 lines
8.3 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "ubiservices/ubiservices.h"
#include "ubiservices/core/configs/configpriv.h"
#include "ubiservices/core/configs/onlineAccessContext.h"
#include "ubiservices/core/errors/errorCodes.h"
#include "ubiservices/core/helpers/exceptionHandler.h"
#include "ubiservices/core/helpers/helpers.h"
#include "ubiservices/core/helpers/instancesManager.h"
#if defined(US_TARGET_SWITCH)
#include "ubiservices/core/http/httpClientImpl.h"
#elif defined(US_TARGET_PS4) && !defined(US_PS4_USE_PSAPI)
#include <libsysmodule.h>
#include <np_toolkit2.h>
#elif defined(US_PS4_USE_PSAPI) || defined(US_TARGET_PS5)
#include <libsysmodule.h>
#include "ubiservices/core/firstPartyInit/psApi/jsonInitializer.h"
#else
#endif
#include "ubiservices/core/locks/lockChecker.h"
#if defined(US_DLL) && !defined(US_UNITY3D)
#include <ealmemdll.cpp>
#include <eallogdll.cpp>
#endif
namespace US_NS {;
EventLog* g_testEventLog(nullptr); // This is only for test purposes
namespace Ubiservices_BF
{
bool validateAppBuildId(const StringA& invalidChar, const String& applicationBuildId)
{
tchar currentChar[2] = { 0, 0 };
for (StringA::const_iterator it = invalidChar.begin(); it != invalidChar.end(); ++it)
{
currentChar[0] = *it;
if(applicationBuildId.findSubstringNoCase(currentChar) != String::npos)
{
return false;
}
}
return true;
}
#if defined(US_LOCK_RESTRICTIONS_ENABLED) && !defined(US_DLL)
void initLockChecker()
{
// We initialize lock checker as a namespace function to avoid having private includes in the ubiservices.inl file.
LockChecker::createGlobals();
}
#endif
}
ConfigureResult configureSdk(const GameConfig& gameConfig, const SystemConfig& systemConfig)
{
ExceptionHandler::initialize();
if(!gameConfig.m_applicationId.isValid())
{
return ConfigureResult::ApplicationIdNotValid;
}
#if !defined(US_SDK_SERVER)
if (gameConfig.m_gameConfigEvent.m_gameSku.isEmpty())
{
return ConfigureResult::UbisoftGameSkuIsEmpty;
}
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_XONE) || defined(US_TARGET_SWITCH) || defined(US_TARGET_PS5)
#if defined(US_TARGET_PS4) || defined(US_TARGET_PS5)
if (gameConfig.m_gameConfigConsole.m_titleId.isEmpty())
#elif defined(US_TARGET_XONE)
if (gameConfig.m_gameConfigConsole.m_productId.isEmpty())
#elif defined(US_TARGET_SWITCH)
if (gameConfig.m_gameConfigConsole.m_nintendoApplicationId.isEmpty())
#endif
{
return ConfigureResult::ApplicationFirstPartyProductIdIsEmpty;
}
#endif
const char* invalidChar = " <>*%&:\\?";
if (!Ubiservices_BF::validateAppBuildId(invalidChar, gameConfig.m_applicationBuildId))
{
return ConfigureResult::ApplicationBuildIdNotValid;
}
#if defined(US_SDK_SERVER)
// Validate environment
if (gameConfig.m_environment >= Environment::ENUM_COUNT)
{
return ConfigureResult::EnvironmentNotValid;
}
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_PS5) // PS module loading sanity check
{
const int resultLoad = sceSysmoduleIsLoaded(SCE_SYSMODULE_NP_AUTH);
if (resultLoad != SCE_OK)
{
Log::print("First party modules need to be loaded before configureSDK.\n");
return ConfigureResult::FirstPartyModulesNotLoaded;
}
}
#endif
US_ASSERT(InstancesManager::getInstanceNoCheck() == nullptr,
"UbiServices doesn't support incremental initialize/uninitialize pattern.");
#if defined(US_PS4_USE_PSAPI) || defined(US_TARGET_PS5)
if (gameConfig.m_gameConfigConsole.m_clientSecret.isEmpty())
{
US_LOG_WHERE(LogLevel::Error, LogCategory::Authentication, "Error: The clientSecret field of the GameConfigConsole parameter can't be empty if the clientId field is provided.");
}
#endif
InstancesManager::createInstance(gameConfig, systemConfig);
#if defined(US_PS4_USE_PSAPI) || defined(US_TARGET_PS5)
{
std::unique_ptr<sce::Json::Initializer> jsonInitializer;
jsonInitializer.reset(new sce::Json::Initializer);
std::unique_ptr<US_NS::JsonMemAllocator> allocator;
allocator.reset(new US_NS::JsonMemAllocator);
JsonInitializer usJsonInitializer;
// sce::Json::Initializer should have been already initialized by the game
// If it was not, we detect it and return an error
// sce::Json initialization is required to use the PsApi CppWebApi
if (usJsonInitializer.initialize(*jsonInitializer, *allocator) != SCE_JSON_ERROR_MULTIPLEINIT)
{
US_LOG_WHERE(LogLevel::Error, LogCategory::Core, "sce::Json::Initializer need to be initialized before using the SDK");
usJsonInitializer.uninitialize(*jsonInitializer);
return ConfigureResult::FirstPartyJsonHasNotBeenInitialized;
}
}
#endif
if (gameConfig.m_onlineAccessContext == OnlineAccessContext::China_GAAP)
{
US_LOG(LogLevel::Always, LogCategory::Core,
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"!! !!\n"
"!! THE ONLINE CONTEXT FOR CHINA GAAP DOES NOT CONTAIN VALID ENDPOINTS AND SHOULD NOT BE SHIPPED IN RETAIL GAMES !!\n"
"!! !!\n"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
}
return ConfigureResult::Success;
}
UninitializeResult uninitializeSdk()
{
const UninitializeResult releaseComplete = InstancesManager::releaseInstance();
if (releaseComplete == UninitializeResult::Complete)
{
// #if defined(US_TARGET_SWITCH)
// // There is no convenient ways to reset this static variable.
// // It could be initialized/reset in initializeSdk as well
// // (but the implementation is inline and therefore public).
// // This is only required for the automated tests, because of mock tests.
// HttpClientImpl::RequestQueueInfo::m_requestNumber = 0;
// #endif
// In Unity3D, the teardown of EAL makes the application crashes.
// This is due to the fact that the managed object are deleted when the
// garbage collector passes and it will happen after the uninitializeSdk.
#if !defined(US_UNITY3D)
US_DELETE(g_testEventLog); //This is only for test purposes
#if defined(US_LOCK_RESTRICTIONS_ENABLED)
// deleteGlobals() is done when destructing InstanceManager
// Do it there for cases where instanceManager is not created
if (InstancesManager::getInstanceNoCheck() == NULL)
{
LockChecker::deleteGlobals();
}
#endif
EalMemLibShutdown();
EalLogLibShutdown();
#endif
}
return releaseComplete;
}
#if defined(US_DLL) && !defined(US_UNITY3D)
void initializeEal(const eal_log_dll_interface* logInterface, const eal_mem_dll_interface* memInterface)
{
US_ASSERT(logInterface->pEalLogLibInit != nullptr, "The eal log interface must have been populated.");
US_ASSERT(memInterface->pEalMemLibInit != nullptr, "The eal mem interface must have been populated.");
#if defined(EAL_DLL) || defined(EAL_IMPORT_DLL)
EalLogDllInitInterface(*logInterface);
EalMemDllInitInterface(*memInterface);
#else
US_UNUSED(logInterface);
US_UNUSED(memInterface);
#endif
EalLogLibInit();
EalMemLibInit();
}
#endif
void US_DLL_API verifyDefineMismatch(uint32 debugIteratorLevel)
{
#if defined(US_DEBUG) && ((defined(US_TARGET_WINDOWS) && defined(US_DLL))) && defined(US_SYSTEM_CHECK_ENABLED)
const uint32 sdkIteratorLevel = static_cast<uint32>(_ITERATOR_DEBUG_LEVEL);
US_ASSERT(sdkIteratorLevel == debugIteratorLevel, "SDK & engine must have the same iterator debug level."
"Either change your iterator level or change the iterator level with the sdk custom flags.");
#else
US_UNUSED(debugIteratorLevel);
#endif
}
};