1
0
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:
Ted John
2017-11-28 20:57:34 +00:00
parent f52544d607
commit dcb92a466d
7 changed files with 215 additions and 37 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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