218 lines
8.3 KiB
C++
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
|
|
}
|
|
|
|
};
|