mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Add new base path for user data and config
Refactor more path resolution to Platform2.cpp
This commit is contained in:
@@ -21,11 +21,11 @@
|
||||
#include "core/Path.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "OpenRCT2.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/Platform2.h"
|
||||
#include "PlatformEnvironment.h"
|
||||
#include "Version.h"
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
class PlatformEnvironment final : public IPlatformEnvironment
|
||||
@@ -36,7 +36,7 @@ private:
|
||||
public:
|
||||
PlatformEnvironment(DIRBASE_VALUES basePaths)
|
||||
{
|
||||
for (sint32 i = 0; i < 4; i++)
|
||||
for (sint32 i = 0; i < DIRBASE_COUNT; i++)
|
||||
{
|
||||
_basePath[i] = basePaths[i];
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
break;
|
||||
case DIRBASE::OPENRCT2:
|
||||
case DIRBASE::USER:
|
||||
case DIRBASE::CONFIG:
|
||||
directoryName = DirectoryNamesOpenRCT2[(size_t)did];
|
||||
break;
|
||||
}
|
||||
@@ -68,21 +69,10 @@ public:
|
||||
|
||||
std::string GetFilePath(PATHID pathid) const override
|
||||
{
|
||||
const utf8 * fileName = FileNames[(size_t)pathid];
|
||||
const utf8 * basePath = _basePath[(size_t)DIRBASE::USER].c_str();
|
||||
if (pathid == PATHID::MP_DAT)
|
||||
{
|
||||
basePath = _basePath[(size_t)DIRBASE::RCT1].c_str();
|
||||
}
|
||||
else if (pathid == PATHID::SCORES_RCT2)
|
||||
{
|
||||
basePath = _basePath[(size_t)DIRBASE::RCT2].c_str();
|
||||
}
|
||||
|
||||
utf8 path[260];
|
||||
String::Set(path, sizeof(path), basePath);
|
||||
Path::Append(path, sizeof(path), fileName);
|
||||
return std::string(path);
|
||||
auto dirbase = GetDefaultBaseDirectory(pathid);
|
||||
auto basePath = GetDirectoryPath(dirbase);
|
||||
auto fileName = FileNames[(size_t)pathid];
|
||||
return Path::Combine(basePath, fileName);
|
||||
}
|
||||
|
||||
void SetBasePath(DIRBASE base, const std::string &path) override
|
||||
@@ -94,6 +84,30 @@ private:
|
||||
static const char * DirectoryNamesRCT2[];
|
||||
static const char * DirectoryNamesOpenRCT2[];
|
||||
static const char * FileNames[];
|
||||
|
||||
static DIRBASE GetDefaultBaseDirectory(PATHID pathid)
|
||||
{
|
||||
switch (pathid)
|
||||
{
|
||||
case PATHID::CONFIG:
|
||||
case PATHID::CONFIG_KEYBOARD:
|
||||
return DIRBASE::CONFIG;
|
||||
case PATHID::CACHE_OBJECTS:
|
||||
case PATHID::CACHE_TRACKS:
|
||||
case PATHID::CACHE_SCENARIOS:
|
||||
return DIRBASE::CACHE;
|
||||
case PATHID::MP_DAT:
|
||||
return DIRBASE::RCT1;
|
||||
case PATHID::SCORES_RCT2:
|
||||
return DIRBASE::RCT2;
|
||||
case PATHID::NETWORK_GROUPS:
|
||||
case PATHID::NETWORK_SERVERS:
|
||||
case PATHID::NETWORK_USERS:
|
||||
case PATHID::SCORES:
|
||||
case PATHID::SCORES_LEGACY:
|
||||
return DIRBASE::USER;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment(DIRBASE_VALUES basePaths)
|
||||
@@ -103,32 +117,36 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment(DIRBASE_VALUES basePa
|
||||
|
||||
IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment()
|
||||
{
|
||||
utf8 userPath[MAX_PATH];
|
||||
platform_resolve_openrct_data_path();
|
||||
platform_resolve_user_data_path();
|
||||
platform_get_user_directory(userPath, nullptr, sizeof(userPath));
|
||||
if (!platform_ensure_directory_exists(userPath))
|
||||
{
|
||||
Console::Error::WriteLine("Could not create user directory '%s' (do you have write access to your documents folder?)", userPath);
|
||||
return nullptr;
|
||||
}
|
||||
platform_get_exe_path(gExePath, sizeof(gExePath));
|
||||
log_verbose("Setting exe path to %s", gExePath);
|
||||
|
||||
config_set_defaults();
|
||||
if (!config_open_default())
|
||||
{
|
||||
config_save_default();
|
||||
}
|
||||
|
||||
utf8 path[260];
|
||||
std::string basePaths[4];
|
||||
std::string basePaths[DIRBASE_COUNT];
|
||||
basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path);
|
||||
basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path);
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path);
|
||||
platform_get_user_directory(path, nullptr, sizeof(path));
|
||||
basePaths[(size_t)DIRBASE::USER] = std::string(path);
|
||||
basePaths[(size_t)DIRBASE::OPENRCT2] = Platform::GetInstallPath();
|
||||
basePaths[(size_t)DIRBASE::USER] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_DATA), "openrct2");
|
||||
basePaths[(size_t)DIRBASE::CONFIG] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CONFIG), "openrct2");
|
||||
basePaths[(size_t)DIRBASE::CACHE] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CACHE), "openrct2");
|
||||
|
||||
// Override paths that have been specified via the command line
|
||||
if (!String::IsNullOrEmpty(gCustomRCT2DataPath))
|
||||
{
|
||||
basePaths[(size_t)DIRBASE::RCT2] = gCustomRCT2DataPath;
|
||||
}
|
||||
if (!String::IsNullOrEmpty(gCustomOpenrctDataPath))
|
||||
{
|
||||
basePaths[(size_t)DIRBASE::OPENRCT2] = gCustomOpenrctDataPath;
|
||||
}
|
||||
if (!String::IsNullOrEmpty(gCustomUserDataPath))
|
||||
{
|
||||
basePaths[(size_t)DIRBASE::USER] = gCustomUserDataPath;
|
||||
basePaths[(size_t)DIRBASE::CONFIG] = gCustomUserDataPath;
|
||||
basePaths[(size_t)DIRBASE::CACHE] = gCustomUserDataPath;
|
||||
}
|
||||
|
||||
IPlatformEnvironment * env = OpenRCT2::CreatePlatformEnvironment(basePaths);
|
||||
|
||||
@@ -137,6 +155,8 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment()
|
||||
log_verbose("DIRBASE::RCT2 : %s", env->GetDirectoryPath(DIRBASE::RCT2).c_str());
|
||||
log_verbose("DIRBASE::OPENRCT2: %s", env->GetDirectoryPath(DIRBASE::OPENRCT2).c_str());
|
||||
log_verbose("DIRBASE::USER : %s", env->GetDirectoryPath(DIRBASE::USER).c_str());
|
||||
log_verbose("DIRBASE::CONFIG : %s", env->GetDirectoryPath(DIRBASE::CONFIG).c_str());
|
||||
log_verbose("DIRBASE::CACHE : %s", env->GetDirectoryPath(DIRBASE::CACHE).c_str());
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ namespace OpenRCT2
|
||||
RCT2, // Base directory for original RollerCoaster Tycoon 2 content.
|
||||
OPENRCT2, // Base directory for OpenRCT2 installation.
|
||||
USER, // Base directory for OpenRCT2 user content.
|
||||
CONFIG, // Base directory for OpenRCT2 configuration.
|
||||
CACHE, // Base directory for OpenRCT2 cache files.
|
||||
};
|
||||
constexpr sint32 DIRBASE_COUNT = 4;
|
||||
constexpr sint32 DIRBASE_COUNT = 6;
|
||||
using DIRBASE_VALUES = std::string[DIRBASE_COUNT];
|
||||
|
||||
enum class DIRID
|
||||
|
||||
@@ -253,6 +253,7 @@ private:
|
||||
try
|
||||
{
|
||||
log_verbose("FileIndex:Writing index: '%s'", _indexPath.c_str());
|
||||
Path::CreateDirectory(Path::GetDirectory(_indexPath));
|
||||
auto fs = FileStream(_indexPath, FILE_MODE_WRITE);
|
||||
|
||||
// Write header
|
||||
|
||||
@@ -79,6 +79,11 @@ namespace Path
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void CreateDirectory(const std::string &path)
|
||||
{
|
||||
platform_ensure_directory_exists(path.c_str());
|
||||
}
|
||||
|
||||
std::string GetFileName(const std::string &path)
|
||||
{
|
||||
return GetFileName(path.c_str());
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Path
|
||||
std::string GetDirectory(const std::string &path);
|
||||
utf8 * GetDirectory(const utf8 * path);
|
||||
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path);
|
||||
void CreateDirectory(const std::string &path);
|
||||
std::string GetFileName(const std::string &path);
|
||||
const utf8 * GetFileName(const utf8 * path);
|
||||
std::string GetFileNameWithoutExtension(const std::string &path);
|
||||
|
||||
@@ -14,8 +14,18 @@
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include "Platform2.h"
|
||||
#include <cstring>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "Platform2.h"
|
||||
#include "platform.h"
|
||||
|
||||
namespace Platform
|
||||
@@ -24,4 +34,131 @@ namespace Platform
|
||||
{
|
||||
return platform_get_ticks();
|
||||
}
|
||||
|
||||
std::string GetEnvironmentVariable(const std::string &name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
auto wname = String::ToUtf16(name);
|
||||
wchar_t wvalue[MAX_PATH];
|
||||
GetEnvironmentVariableW(wname.c_str(), wvalue, sizeof(wvalue));
|
||||
return String::ToUtf8(wvalue);
|
||||
#else
|
||||
return String::ToStd(getenv(name.c_str()));
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string GetEnvironmentPath(const char * name)
|
||||
{
|
||||
auto value = getenv(name);
|
||||
if (value == nullptr)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto colon = std::strchr(value, ':');
|
||||
if (colon == nullptr)
|
||||
{
|
||||
return std::string(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string(value, colon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder)
|
||||
{
|
||||
switch (folder)
|
||||
{
|
||||
// We currently store everything under Documents/OpenRCT2
|
||||
case SPECIAL_FOLDER::USER_CACHE:
|
||||
case SPECIAL_FOLDER::USER_CONFIG:
|
||||
case SPECIAL_FOLDER::USER_DATA:
|
||||
{
|
||||
wchar_t wpath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, nullptr, 0, wpath)))
|
||||
{
|
||||
return ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFolderPath(SPECIAL_FOLDER::USER_HOME);
|
||||
}
|
||||
}
|
||||
case SPECIAL_FOLDER::USER_HOME:
|
||||
{
|
||||
wchar_t wpath[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE | CSIDL_FLAG_CREATE, nullptr, 0, wpath)))
|
||||
{
|
||||
return ToUtf8(std::wstring(wpath));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try default environment variables
|
||||
auto homedrive = GetEnvironmentVariable("HOMEDRIVE");
|
||||
auto homepath = GetEnvironmentVariable("HOMEPATH");
|
||||
if (!homedrive.empty() && !homepath.empty())
|
||||
{
|
||||
return Path::Combine(homedrive, homepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "C:\\";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder)
|
||||
{
|
||||
switch (folder)
|
||||
{
|
||||
case SPECIAL_FOLDER::USER_CACHE:
|
||||
{
|
||||
auto path = GetEnvironmentPath("XDG_CACHE_HOME");
|
||||
if (path.empty())
|
||||
{
|
||||
auto home = GetFolderPath(SPECIAL_FOLDER::USER_HOME);
|
||||
path = Path::Combine(home, ".cache");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
case SPECIAL_FOLDER::USER_CONFIG:
|
||||
{
|
||||
auto path = GetEnvironmentPath("XDG_CONFIG_HOME");
|
||||
if (path.empty())
|
||||
{
|
||||
auto home = GetFolderPath(SPECIAL_FOLDER::USER_HOME);
|
||||
path = Path::Combine(home, ".config");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
case SPECIAL_FOLDER::USER_DATA:
|
||||
{
|
||||
auto path = GetEnvironmentPath("XDG_DATA_HOME");
|
||||
if (path.empty())
|
||||
{
|
||||
auto home = GetFolderPath(SPECIAL_FOLDER::USER_HOME);
|
||||
path = Path::Combine(home, ".local/share");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
case SPECIAL_FOLDER::USER_HOME:
|
||||
return getpwuid(getuid())->pw_dir;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string GetInstallPath()
|
||||
{
|
||||
utf8 path[260];
|
||||
platform_resolve_openrct_data_path();
|
||||
platform_get_openrct_data_path(path, sizeof(path));
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,23 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include "../common.h"
|
||||
|
||||
enum class SPECIAL_FOLDER
|
||||
{
|
||||
USER_CACHE,
|
||||
USER_CONFIG,
|
||||
USER_DATA,
|
||||
USER_HOME,
|
||||
};
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
uint32 GetTicks();
|
||||
std::string GetEnvironmentVariable(const std::string &name);
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder);
|
||||
std::string GetInstallPath();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user