Merge branch 'optionalglobalism' into 'master'

Remove global config on Windows

Closes #8434

See merge request OpenMW/openmw!4762
This commit is contained in:
Alexei Kotov 2025-07-26 23:25:55 +03:00
commit ed32e4405a
6 changed files with 31 additions and 58 deletions

View File

@ -781,7 +781,6 @@ void OMW::Engine::prepareEngine()
const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt"; const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt";
const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt"; const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt";
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
std::filesystem::path userGameControllerdb; std::filesystem::path userGameControllerdb;
if (std::filesystem::exists(userdefault)) if (std::filesystem::exists(userdefault))
@ -790,9 +789,13 @@ void OMW::Engine::prepareEngine()
std::filesystem::path gameControllerdb; std::filesystem::path gameControllerdb;
if (std::filesystem::exists(localdefault)) if (std::filesystem::exists(localdefault))
gameControllerdb = localdefault; gameControllerdb = localdefault;
else if (std::filesystem::exists(globaldefault)) else if (!mCfgMgr.getGlobalPath().empty())
gameControllerdb = globaldefault; {
// else if it doesn't exist, pass in an empty string const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
if (std::filesystem::exists(globaldefault))
gameControllerdb = globaldefault;
}
// else if it doesn't exist, pass in an empty path
// gui needs our shaders path before everything else // gui needs our shaders path before everything else
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders"); mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");

View File

@ -18,37 +18,33 @@ namespace Files
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
namespace
{
#if defined(_WIN32) || defined(__WINDOWS__) #if defined(_WIN32) || defined(__WINDOWS__)
static const char* const applicationName = "OpenMW"; constexpr auto applicationName = "OpenMW";
#else #else
static const char* const applicationName = "openmw"; constexpr auto applicationName = "openmw";
#endif #endif
static constexpr auto localToken = u8"?local?"; using GetPath = const std::filesystem::path& (Files::FixedPath<>::*)() const;
static constexpr auto userConfigToken = u8"?userconfig?"; constexpr std::array<std::pair<std::u8string_view, GetPath>, 4> sTokenMappings = {
static constexpr auto userDataToken = u8"?userdata?"; std::make_pair(u8"?local?", &FixedPath<>::getLocalPath),
static constexpr auto globalToken = u8"?global?"; std::make_pair(u8"?userconfig?", &FixedPath<>::getUserConfigPath),
std::make_pair(u8"?userdata?", &FixedPath<>::getUserDataPath),
std::make_pair(u8"?global?", &FixedPath<>::getGlobalDataPath),
};
}
ConfigurationManager::ConfigurationManager(bool silent) ConfigurationManager::ConfigurationManager(bool silent)
: mFixedPath(applicationName) : mFixedPath(applicationName)
, mSilent(silent) , mSilent(silent)
{ {
setupTokensMapping();
// Initialize with fixed paths, will be overridden in `readConfiguration`. // Initialize with fixed paths, will be overridden in `readConfiguration`.
mUserDataPath = mFixedPath.getUserDataPath(); mUserDataPath = mFixedPath.getUserDataPath();
mScreenshotPath = mFixedPath.getUserDataPath() / "screenshots"; mScreenshotPath = mFixedPath.getUserDataPath() / "screenshots";
} }
ConfigurationManager::~ConfigurationManager() {} ConfigurationManager::~ConfigurationManager() = default;
void ConfigurationManager::setupTokensMapping()
{
mTokensMapping.insert(std::make_pair(localToken, &FixedPath<>::getLocalPath));
mTokensMapping.insert(std::make_pair(userConfigToken, &FixedPath<>::getUserConfigPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::getUserDataPath));
mTokensMapping.insert(std::make_pair(globalToken, &FixedPath<>::getGlobalDataPath));
}
static bool hasReplaceConfig(const bpo::variables_map& variables) static bool hasReplaceConfig(const bpo::variables_map& variables)
{ {
@ -74,7 +70,7 @@ namespace Files
std::optional<bpo::variables_map> config = loadConfig(mFixedPath.getLocalPath(), description); std::optional<bpo::variables_map> config = loadConfig(mFixedPath.getLocalPath(), description);
if (config) if (config)
mActiveConfigPaths.push_back(mFixedPath.getLocalPath()); mActiveConfigPaths.push_back(mFixedPath.getLocalPath());
else else if (!mFixedPath.getGlobalConfigPath().empty())
{ {
mActiveConfigPaths.push_back(mFixedPath.getGlobalConfigPath()); mActiveConfigPaths.push_back(mFixedPath.getGlobalConfigPath());
config = loadConfig(mFixedPath.getGlobalConfigPath(), description); config = loadConfig(mFixedPath.getGlobalConfigPath(), description);
@ -305,15 +301,18 @@ namespace Files
const auto pos = str.find('?', 1); const auto pos = str.find('?', 1);
if (pos != std::u8string::npos && pos != 0) if (pos != std::u8string::npos && pos != 0)
{ {
auto tokenIt = mTokensMapping.find(str.substr(0, pos + 1)); std::u8string_view view(str);
if (tokenIt != mTokensMapping.end()) auto token = view.substr(0, pos + 1);
auto found = std::find_if(
sTokenMappings.begin(), sTokenMappings.end(), [&](const auto& item) { return item.first == token; });
if (found != sTokenMappings.end())
{ {
auto tempPath(((mFixedPath).*(tokenIt->second))()); auto tempPath(((mFixedPath).*(found->second))());
if (pos < str.length() - 1) if (!tempPath.empty() && pos < view.length() - 1)
{ {
// There is something after the token, so we should // There is something after the token, so we should
// append it to the path // append it to the path
tempPath /= str.substr(pos + 1, str.length() - pos); tempPath /= view.substr(pos + 1, view.length() - pos);
} }
path = std::move(tempPath); path = std::move(tempPath);

View File

@ -62,17 +62,12 @@ namespace Files
private: private:
typedef Files::FixedPath<> FixedPathType; typedef Files::FixedPath<> FixedPathType;
typedef const std::filesystem::path& (FixedPathType::*path_type_f)() const;
typedef std::map<std::u8string, path_type_f> TokensMappingContainer;
std::optional<boost::program_options::variables_map> loadConfig( std::optional<boost::program_options::variables_map> loadConfig(
const std::filesystem::path& path, const boost::program_options::options_description& description) const; const std::filesystem::path& path, const boost::program_options::options_description& description) const;
void addExtraConfigDirs( void addExtraConfigDirs(
std::stack<std::filesystem::path>& dirs, const boost::program_options::variables_map& variables) const; std::stack<std::filesystem::path>& dirs, const boost::program_options::variables_map& variables) const;
void setupTokensMapping();
std::vector<std::filesystem::path> mActiveConfigPaths; std::vector<std::filesystem::path> mActiveConfigPaths;
FixedPathType mFixedPath; FixedPathType mFixedPath;
@ -80,8 +75,6 @@ namespace Files
std::filesystem::path mUserDataPath; std::filesystem::path mUserDataPath;
std::filesystem::path mScreenshotPath; std::filesystem::path mScreenshotPath;
TokensMappingContainer mTokensMapping;
bool mSilent; bool mSilent;
}; };

View File

@ -8,21 +8,11 @@
namespace Files namespace Files
{ {
inline QString getLocalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getLocalPath() / openmwCfgFile);
}
inline QString getUserConfigPathQString(const Files::ConfigurationManager& cfgMgr) inline QString getUserConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{ {
return Files::pathToQString(cfgMgr.getUserConfigPath() / openmwCfgFile); return Files::pathToQString(cfgMgr.getUserConfigPath() / openmwCfgFile);
} }
inline QString getGlobalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getGlobalPath() / openmwCfgFile);
}
inline QStringList getActiveConfigPathsQString(const Files::ConfigurationManager& cfgMgr) inline QStringList getActiveConfigPathsQString(const Files::ConfigurationManager& cfgMgr)
{ {
const auto& activePaths = cfgMgr.getActiveConfigPaths(); const auto& activePaths = cfgMgr.getActiveConfigPaths();

View File

@ -54,19 +54,7 @@ namespace Files
{ {
// The concept of a global config path is absurd on Windows. // The concept of a global config path is absurd on Windows.
// Always use local config instead. // Always use local config instead.
// The virtual base class requires that we provide this, though. return {};
std::filesystem::path globalPath = std::filesystem::current_path();
PWSTR cString;
HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &cString);
if (SUCCEEDED(result))
globalPath = std::filesystem::path(cString);
else
Log(Debug::Error) << "Error " << result << " when getting Program Files path";
CoTaskMemFree(cString);
return globalPath / mName;
} }
std::filesystem::path WindowsPath::getLocalPath() const std::filesystem::path WindowsPath::getLocalPath() const

View File

@ -34,7 +34,7 @@ namespace Files
std::filesystem::path getUserDataPath() const; std::filesystem::path getUserDataPath() const;
/** /**
* \brief Returns "X:\Program Files\" * \brief Returns an empty path
* *
* \return std::filesystem::path * \return std::filesystem::path
*/ */