f648cb1fd8
* Update the FileIOAlias naming to make the cache, project root and engine root paths more clear The alias of `@root@`, `@assets@`, and `@projectplatformcache@` has been collapsed to `@projectproductassets@` The alias of `@devroot@` and `@engroot@` has been collapsed to `@engroot@` The alias of `@devassets@` and `@projectroot@` has been collapsed to `@projectroot@` Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated use of devassets and devroot properties in python Those properties now use projectroot and engroot Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updating the alias @engroot@ alias path comment in each platform specific LocalFileIO_*.cpp file Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed hardcoded size of 9 for the product asset alias. The ResolvePath function now just appends the @projectproductassets@ alias with the input path Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Remove duplicate @projectproductassets@ check in ProcessFileTreeRequest Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fix for typos in Hydra python test Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated LocalFileIO::Copy call on Windows to use the Unicode aware CopyFileW API Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the AWSMetreicsGemAllocatorFixture to properly suppress asset cache write errors for Test file creation. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed unneeded call to set the @projectproductasstes@ alias at the bottom of the AssetSeedManagerTest SetUp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added a deprecated alias map to the FileIO System When a deprecated alias is accessed, the FileIO System logs an AZ_Error and indicates the alias that should be used Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated python test scripts to use the projectroot binding Retrieving the AutomatedTesting project path based on "<devroot>/AutomatedTesting" has been removed. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated references to devroot and devgame within the codebase The GetAbsoluteDevGameFolderPath functions has been replaced with direct call to AZ::Utils::GetProjectPath The GetAbsoluteDevRootFolderPath functions has been replaced with direct calls to AZ::Utils::GetEnginePath Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated <engroot>/AutomatedTesting references to projectroot Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced references that assumes the project path is <engroot>/AutomatedTesting with <projectroot> in the AutomatedTesting python test Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Correct casing in emfxworkspace file Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed newly added AppendPathParts function Removed the Path constructors which accepts a PathIterable instance The PathIterable isn't safe to return to a user of the Path class as it might be referencing temporary paths supplied via PathView arguments Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed unused parameter warning Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Undid change to the LexicallyProximate function to set the path result to the base path. It needs to return the *this path if the pathResult is empty Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Moved the LocalFileIO ConvertToAbsolutePath implementations to AZ::Utils Fixed the ConvertToAbsolutePath implementation for Unix platforms to use a buffer that is size PATH_MAX(4096 on all our supported Unix platforms). Because the buffer before was AZ::IO::MaxPathLength which as a size of 1024, this was resulting in the Unix `realpath` function smashing the stack when it converts a path to an absolute path that is longer than 1024 characters Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the EditorCore.Tests to attach the AZ Environment to the EditorCore shared library that is statically loaded on launch. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed for DeprecatedAlaisesKeyVisitor Visit function causing the non string_view overloads being hidden causing a hidden base class function warning Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Changed the AWSMetricsGemMock to use a temporary for writing test assets Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the LocalFileIO::ResolvePath function to use HasRootPath to determine if a path starts with a root path such as "D:", "D:/" or "/" IsAbsolute was not the corect check as the path of "D:" is a relative path. To be absolute according to the Windows the path must have a root directory. i.e "D:/" or "D:\" Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed absolute path comment from LocalFile_UnixLike.cpp and LocalFile_Android.cpp FindFiles implementations Updated the ConvertToAlias to supply an AZ::IO::FixedMaxPath Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced usage of the @projectproductassets@ alias with @engroot@ when referring to the LmbrCentral source folder in the CopyDependencyBuilderTest and the SeedBuilderTests Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the ScriptCanvas Upgrade Tool to output backed up files to the Project User Path instead of the engine root Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed whitespacing issues in Application.cpp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Remove unnecessary creation of a FixedMaxPath in the UpgradeTool.cpp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Modified testSeedFolder variable in the SeedBuilderTests to use the @engroot@ alias instead of @projectproductassets@/.. alias when referring to the LmbrCentral Gem source path Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated references to the Project Asset Cache in the PythonTests. Those tests no longer use the logic `azlmbr.paths.projectroot / "Cache" / "pc"` to retrieve a path to the cache root but instead the `azlmbr.paths.projectproductassets` constant Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed the FileIO Deprecated Alias test on Windows Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removing @projectsourceassets@ alias, as it is only used once. Updated the PhysX EditorSystemComponent.cpp to query the ProjectPath form the SettingsRegistry. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced @projectproductassets@ alias with @products@ Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Rollback changes to the PhysX EditorSystemComponent.cpp The changes to use the ProjectPath from the SettingsRegistry has been implemented in PR #4497 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
478 lines
16 KiB
C++
478 lines
16 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
|
|
// Description : handles system cfg
|
|
|
|
|
|
#include "CrySystem_precompiled.h"
|
|
#include "System.h"
|
|
#include <time.h>
|
|
#include "XConsole.h"
|
|
#include "CryFile.h"
|
|
#include "CryPath.h"
|
|
|
|
#include <AzCore/Console/IConsole.h>
|
|
#include <AzCore/Interface/Interface.h>
|
|
#include <AzCore/Utils/Utils.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#undef AZ_RESTRICTED_SECTION
|
|
#define SYSTEMCFG_CPP_SECTION_1 1
|
|
#define SYSTEMCFG_CPP_SECTION_2 2
|
|
#define SYSTEMCFG_CPP_SECTION_3 3
|
|
#endif
|
|
|
|
#if defined(LINUX) || defined(APPLE)
|
|
#include "ILog.h"
|
|
|
|
#endif
|
|
|
|
#ifndef EXE_VERSION_INFO_0
|
|
#define EXE_VERSION_INFO_0 1
|
|
#endif
|
|
|
|
#ifndef EXE_VERSION_INFO_1
|
|
#define EXE_VERSION_INFO_1 0
|
|
#endif
|
|
|
|
#ifndef EXE_VERSION_INFO_2
|
|
#define EXE_VERSION_INFO_2 0
|
|
#endif
|
|
|
|
#ifndef EXE_VERSION_INFO_3
|
|
#define EXE_VERSION_INFO_3 1
|
|
#endif
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMCFG_CPP_SECTION_1
|
|
#include AZ_RESTRICTED_FILE(SystemCFG_cpp)
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SFileVersion& CSystem::GetFileVersion()
|
|
{
|
|
return m_fileVersion;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SFileVersion& CSystem::GetProductVersion()
|
|
{
|
|
return m_productVersion;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SFileVersion& CSystem::GetBuildVersion()
|
|
{
|
|
return m_buildVersion;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#ifndef _RELEASE
|
|
void CSystem::SystemVersionChanged(ICVar* pCVar)
|
|
{
|
|
if (CSystem* pThis = static_cast<CSystem*>(gEnv->pSystem))
|
|
{
|
|
pThis->SetVersionInfo(pCVar->GetString());
|
|
}
|
|
}
|
|
|
|
void CSystem::SetVersionInfo(const char* const szVersion)
|
|
{
|
|
m_fileVersion.Set(szVersion);
|
|
m_productVersion.Set(szVersion);
|
|
m_buildVersion.Set(szVersion);
|
|
CryLog("SetVersionInfo '%s'", szVersion);
|
|
CryLog("FileVersion: %d.%d.%d.%d", m_fileVersion.v[3], m_fileVersion.v[2], m_fileVersion.v[1], m_fileVersion.v[0]);
|
|
CryLog("ProductVersion: %d.%d.%d.%d", m_productVersion.v[3], m_productVersion.v[2], m_productVersion.v[1], m_productVersion.v[0]);
|
|
CryLog("BuildVersion: %d.%d.%d.%d", m_buildVersion.v[3], m_buildVersion.v[2], m_buildVersion.v[1], m_buildVersion.v[0]);
|
|
}
|
|
#endif // #ifndef _RELEASE
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::QueryVersionInfo()
|
|
{
|
|
#ifndef WIN32
|
|
//do we need some other values here?
|
|
m_fileVersion.v[0] = m_productVersion.v[0] = EXE_VERSION_INFO_3;
|
|
m_fileVersion.v[1] = m_productVersion.v[1] = EXE_VERSION_INFO_2;
|
|
m_fileVersion.v[2] = m_productVersion.v[2] = EXE_VERSION_INFO_1;
|
|
m_fileVersion.v[3] = m_productVersion.v[3] = EXE_VERSION_INFO_0;
|
|
m_buildVersion = m_fileVersion;
|
|
#else //WIN32
|
|
char moduleName[_MAX_PATH];
|
|
DWORD dwHandle;
|
|
UINT len;
|
|
|
|
char ver[1024 * 8];
|
|
|
|
AZ::Utils::GetExecutablePath(moduleName, _MAX_PATH); //retrieves the PATH for the current module
|
|
|
|
#ifdef AZ_MONOLITHIC_BUILD
|
|
AZ::Utils::GetExecutablePath(moduleName, _MAX_PATH); //retrieves the PATH for the current module
|
|
#else // AZ_MONOLITHIC_BUILD
|
|
azstrcpy(moduleName, AZ_ARRAY_SIZE(moduleName), "CrySystem.dll"); // we want to version from the system dll
|
|
#endif // AZ_MONOLITHIC_BUILD
|
|
|
|
AZStd::wstring moduleNameW;
|
|
AZStd::to_wstring(moduleNameW, moduleName);
|
|
int verSize = GetFileVersionInfoSizeW(moduleNameW.c_str(), &dwHandle);
|
|
if (verSize > 0)
|
|
{
|
|
GetFileVersionInfoW(moduleNameW.c_str(), dwHandle, 1024 * 8, ver);
|
|
VS_FIXEDFILEINFO* vinfo;
|
|
VerQueryValueW(ver, L"\\", (void**)&vinfo, &len);
|
|
|
|
const uint32 verIndices[4] = {0, 1, 2, 3};
|
|
m_fileVersion.v[verIndices[0]] = m_productVersion.v[verIndices[0]] = vinfo->dwFileVersionLS & 0xFFFF;
|
|
m_fileVersion.v[verIndices[1]] = m_productVersion.v[verIndices[1]] = vinfo->dwFileVersionLS >> 16;
|
|
m_fileVersion.v[verIndices[2]] = m_productVersion.v[verIndices[2]] = vinfo->dwFileVersionMS & 0xFFFF;
|
|
m_fileVersion.v[verIndices[3]] = m_productVersion.v[verIndices[3]] = vinfo->dwFileVersionMS >> 16;
|
|
m_buildVersion = m_fileVersion;
|
|
|
|
struct LANGANDCODEPAGE
|
|
{
|
|
WORD wLanguage;
|
|
WORD wCodePage;
|
|
}* lpTranslate;
|
|
|
|
UINT count = 0;
|
|
wchar_t path[256];
|
|
char* version = NULL;
|
|
|
|
VerQueryValueW(ver, L"\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &count);
|
|
if (lpTranslate != NULL)
|
|
{
|
|
azsnwprintf(path, sizeof(path), L"\\StringFileInfo\\%04x%04x\\InternalName", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
|
|
VerQueryValueW(ver, path, (LPVOID*)&version, &count);
|
|
if (version)
|
|
{
|
|
m_buildVersion.Set(version);
|
|
}
|
|
}
|
|
}
|
|
#endif //WIN32
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::LogVersion()
|
|
{
|
|
// Get time.
|
|
time_t ltime;
|
|
time(<ime);
|
|
|
|
#ifdef AZ_COMPILER_MSVC
|
|
tm today;
|
|
localtime_s(&today, <ime);
|
|
char s[1024];
|
|
strftime(s, 128, "%d %b %y (%H %M %S)", &today);
|
|
#else
|
|
char s[1024];
|
|
auto today = localtime(<ime);
|
|
strftime(s, 128, "%d %b %y (%H %M %S)", today);
|
|
#endif
|
|
|
|
[[maybe_unused]] const SFileVersion& ver = GetFileVersion();
|
|
|
|
CryLogAlways("BackupNameAttachment=\" Build(%d) %s\" -- used by backup system\n", ver.v[0], s); // read by CreateBackupFile()
|
|
|
|
// Use strftime to build a customized time string.
|
|
#ifdef AZ_COMPILER_MSVC
|
|
strftime(s, 128, "Log Started at %c", &today);
|
|
#else
|
|
strftime(s, 128, "Log Started at %c", today);
|
|
#endif
|
|
CryLogAlways("%s", s);
|
|
|
|
CryLogAlways("Built on " __DATE__ " " __TIME__);
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMCFG_CPP_SECTION_2
|
|
#include AZ_RESTRICTED_FILE(SystemCFG_cpp)
|
|
#elif defined(ANDROID)
|
|
CryLogAlways("Running 32 bit Android version API VER:%d", __ANDROID_API__);
|
|
#elif defined(IOS)
|
|
CryLogAlways("Running 64 bit iOS version");
|
|
#elif defined(WIN64)
|
|
CryLogAlways("Running 64 bit Windows version");
|
|
#elif defined(WIN32)
|
|
CryLogAlways("Running 32 bit Windows version");
|
|
#elif defined(LINUX64)
|
|
CryLogAlways("Running 64 bit Linux version");
|
|
#elif defined(LINUX32)
|
|
CryLogAlways("Running 32 bit Linux version");
|
|
#elif defined(MAC)
|
|
CryLogAlways("Running 64 bit Mac version");
|
|
#endif
|
|
#if AZ_LEGACY_CRYSYSTEM_TRAIT_SYSTEMCFG_MODULENAME
|
|
AZ::Utils::GetExecutablePath(s, sizeof(s));
|
|
|
|
// Log EXE filename only if possible (not full EXE path which could contain sensitive info)
|
|
AZStd::string exeName;
|
|
if (AzFramework::StringFunc::Path::GetFullFileName(s, exeName)) {
|
|
CryLogAlways("Executable: %s", exeName.c_str());
|
|
}
|
|
#endif
|
|
|
|
CryLogAlways("FileVersion: %d.%d.%d.%d", m_fileVersion.v[3], m_fileVersion.v[2], m_fileVersion.v[1], m_fileVersion.v[0]);
|
|
#if defined(LY_BUILD)
|
|
CryLogAlways("ProductVersion: %d.%d.%d.%d - Build %d", m_productVersion.v[3], m_productVersion.v[2], m_productVersion.v[1], m_productVersion.v[0], LY_BUILD);
|
|
#else // defined(LY_BUILD)
|
|
CryLogAlways("ProductVersion: %d.%d.%d.%d", m_productVersion.v[3], m_productVersion.v[2], m_productVersion.v[1], m_productVersion.v[0]);
|
|
#endif // defined(LY_BUILD)
|
|
|
|
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMCFG_CPP_SECTION_3
|
|
#include AZ_RESTRICTED_FILE(SystemCFG_cpp)
|
|
#endif
|
|
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
|
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
|
#elif defined(_MSC_VER)
|
|
CryLogAlways("Using Microsoft (tm) C++ Standard Library implementation\n");
|
|
#elif defined(__clang__)
|
|
CryLogAlways("Using CLANG C++ Standard Library implementation\n");
|
|
#elif defined(__GNUC__)
|
|
CryLogAlways("Using GNU C++ Standard Library implementation\n");
|
|
#else
|
|
#error "Please specify C++ STL library"
|
|
#endif
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::LogBuildInfo()
|
|
{
|
|
[[maybe_unused]] auto projectName = AZ::Utils::GetProjectName();
|
|
CryLogAlways("GameName: %s", projectName.c_str());
|
|
CryLogAlways("BuildTime: " __DATE__ " " __TIME__);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::SaveConfiguration()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
static bool ParseSystemConfig(const AZStd::string& strSysConfigFilePath, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
|
|
{
|
|
assert(pSink);
|
|
AZStd::string filename = strSysConfigFilePath;
|
|
if (strlen(PathUtil::GetExt(filename.c_str())) == 0)
|
|
{
|
|
filename = PathUtil::ReplaceExtension(filename, "cfg");
|
|
}
|
|
|
|
CCryFile file;
|
|
AZStd::string filenameLog;
|
|
{
|
|
if (filename[0] == '@')
|
|
{
|
|
// this is used when theres a very specific file to read, like @user@/game.cfg which is read
|
|
// IN ADDITION to the one in the game folder, and afterwards to override values in it.
|
|
// if the file is missing and its already prefixed with an alias, there is no need to look any further.
|
|
if (!(file.Open(filename.c_str(), "rb")))
|
|
{
|
|
if (warnIfMissing)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Config file %s not found!", filename.c_str());
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// otherwise, if the file isn't prefixed with an alias, then its likely one of the convenience mappings
|
|
// to either root or assets/config. this is done so that code can just request a simple file name and get its data
|
|
if (
|
|
!(file.Open(filename.c_str(), "rb")) &&
|
|
!(file.Open((AZStd::string("@products@/") + filename).c_str(), "rb")) &&
|
|
!(file.Open((AZStd::string("@products@/") + filename).c_str(), "rb")) &&
|
|
!(file.Open((AZStd::string("@products@/config/") + filename).c_str(), "rb")) &&
|
|
!(file.Open((AZStd::string("@products@/config/spec/") + filename).c_str(), "rb"))
|
|
)
|
|
{
|
|
if (warnIfMissing)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Config file %s not found!", filename.c_str());
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
AZ::IO::FixedMaxPath resolvedFilePath;
|
|
AZ::IO::FileIOBase::GetInstance()->ResolvePath(resolvedFilePath, file.GetFilename());
|
|
filenameLog = resolvedFilePath.String();
|
|
}
|
|
|
|
INDENT_LOG_DURING_SCOPE();
|
|
|
|
int nLen = static_cast<int>(file.GetLength());
|
|
if (nLen == 0)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Couldn't get length for Config file %s", filename.c_str());
|
|
return false;
|
|
}
|
|
char* sAllText = new char [nLen + 16];
|
|
if (file.ReadRaw(sAllText, nLen) < (size_t)nLen)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Couldn't read Config file %s", filename.c_str());
|
|
return false;
|
|
}
|
|
sAllText[nLen] = '\0';
|
|
sAllText[nLen + 1] = '\0';
|
|
|
|
AZStd::string strGroup; // current group e.g. "[General]"
|
|
|
|
char* strLast = sAllText + nLen;
|
|
char* str = sAllText;
|
|
while (str < strLast)
|
|
{
|
|
char* s = str;
|
|
while (str < strLast && *str != '\n' && *str != '\r')
|
|
{
|
|
str++;
|
|
}
|
|
*str = '\0';
|
|
str++;
|
|
while (str < strLast && (*str == '\n' || *str == '\r'))
|
|
{
|
|
str++;
|
|
}
|
|
|
|
AZStd::string strLine = s;
|
|
AZ::StringFunc::TrimWhiteSpace(strLine, true, true);
|
|
|
|
// detect groups e.g. "[General]" should set strGroup="General"
|
|
{
|
|
size_t size = strLine.size();
|
|
|
|
if (size >= 3)
|
|
{
|
|
if (strLine[0] == '[' && strLine[size - 1] == ']') // currently no comments are allowed to be behind groups
|
|
{
|
|
strGroup = &strLine[1];
|
|
strGroup.resize(size - 2); // remove [ and ]
|
|
continue; // next line
|
|
}
|
|
}
|
|
}
|
|
|
|
//trim all whitespace characters at the beginning and the end of the current line and store its size
|
|
size_t strLineSize = strLine.size();
|
|
|
|
//skip comments, comments start with ";" or "--" but may have preceding whitespace characters
|
|
if (strLineSize > 0)
|
|
{
|
|
if (strLine[0] == ';')
|
|
{
|
|
continue;
|
|
}
|
|
else if (strLine.find("--") == 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
//skip empty lines
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//if line contains a '=' try to read and assign console variable
|
|
AZStd::string::size_type posEq(strLine.find("=", 0));
|
|
if (AZStd::string::npos != posEq)
|
|
{
|
|
AZStd::string stemp;
|
|
AZStd::string strKey(strLine, 0, posEq);
|
|
AZ::StringFunc::TrimWhiteSpace(strKey, true, true);
|
|
|
|
{
|
|
// extract value
|
|
AZStd::string::size_type posValueStart(strLine.find("\"", posEq + 1) + 1);
|
|
AZStd::string::size_type posValueEnd(strLine.rfind('\"'));
|
|
|
|
AZStd::string strValue;
|
|
|
|
if (AZStd::string::npos != posValueStart && AZStd::string::npos != posValueEnd)
|
|
{
|
|
strValue = AZStd::string(strLine, posValueStart, posValueEnd - posValueStart);
|
|
}
|
|
else
|
|
{
|
|
strValue = AZStd::string(strLine, posEq + 1, strLine.size() - (posEq + 1));
|
|
AZ::StringFunc::TrimWhiteSpace(strValue, true, true);
|
|
}
|
|
|
|
{
|
|
// replace '\\\\' with '\\' and '\\\"' with '\"'
|
|
AZ::StringFunc::Replace(strValue, "\\\\", "\\");
|
|
AZ::StringFunc::Replace(strValue, "\\\"", "\"");
|
|
|
|
pSink->OnLoadConfigurationEntry(strKey.c_str(), strValue.c_str(), strGroup.c_str());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gEnv->pLog->LogWithType(ILog::eWarning, "%s -> invalid configuration line: %s", filename.c_str(), strLine.c_str());
|
|
}
|
|
}
|
|
|
|
delete []sAllText;
|
|
|
|
CryLog("Loading Config file %s (%s)", filename.c_str(), filenameLog.c_str());
|
|
|
|
pSink->OnLoadConfigurationEntry_End();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::OnLoadConfigurationEntry(const char* szKey, const char* szValue, [[maybe_unused]] const char* szGroup)
|
|
{
|
|
bool azConsoleProcessed = false;
|
|
auto console = AZ::Interface<AZ::IConsole>::Get();
|
|
if (console)
|
|
{
|
|
AZStd::string command(AZStd::string::format("%s %s", szKey, szValue));
|
|
|
|
azConsoleProcessed = console->PerformCommand(command.c_str());
|
|
}
|
|
|
|
if (!azConsoleProcessed)
|
|
{
|
|
if (!gEnv->pConsole)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (*szKey != 0)
|
|
{
|
|
gEnv->pConsole->LoadConfigVar(szKey, szValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySink* pSink, bool warnIfMissing)
|
|
{
|
|
if (sFilename && strlen(sFilename) > 0)
|
|
{
|
|
if (!pSink)
|
|
{
|
|
pSink = this;
|
|
}
|
|
|
|
ParseSystemConfig(sFilename, pSink, warnIfMissing);
|
|
}
|
|
}
|
|
|