From 432b7d2dc8dfd6deeddf76046c740b5d1947e25f Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 17 Nov 2022 18:22:39 -0800 Subject: [PATCH] Config: Add support for steamid based configurations. This will be useful for keying specific executables to steamids. This is sadly required because a bunch of games end up naming themselves "game.exe" so we can't safely enable thunks for all things shipping a generic name. --- .../Source/Interface/Config/Config.cpp | 16 ++++++---- .../FEXCore/include/FEXCore/Config/Config.h | 4 ++- Source/Common/Config.cpp | 14 +++++++-- Source/Tests/LinuxSyscalls/FileManagement.cpp | 29 +++++++++++++++++-- Source/Tools/FEXGetConfig/Main.cpp | 13 +++++++-- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/External/FEXCore/Source/Interface/Config/Config.cpp b/External/FEXCore/Source/Interface/Config/Config.cpp index 74e7ddc4b..87019a35c 100644 --- a/External/FEXCore/Source/Interface/Config/Config.cpp +++ b/External/FEXCore/Source/Interface/Config/Config.cpp @@ -211,10 +211,12 @@ namespace JSON { static std::map> ConfigLayers; static FEXCore::Config::Layer *Meta{}; - constexpr std::array LoadOrder = { + constexpr std::array LoadOrder = { FEXCore::Config::LayerType::LAYER_GLOBAL_MAIN, FEXCore::Config::LayerType::LAYER_MAIN, + FEXCore::Config::LayerType::LAYER_GLOBAL_STEAM_APP, FEXCore::Config::LayerType::LAYER_GLOBAL_APP, + FEXCore::Config::LayerType::LAYER_LOCAL_STEAM_APP, FEXCore::Config::LayerType::LAYER_LOCAL_APP, FEXCore::Config::LayerType::LAYER_ARGUMENTS, FEXCore::Config::LayerType::LAYER_ENVIRONMENT, @@ -629,7 +631,7 @@ namespace JSON { class AppLoader final : public FEXCore::Config::OptionMapper { public: - explicit AppLoader(const std::string& Filename, bool Global); + explicit AppLoader(const std::string& Filename, FEXCore::Config::LayerType Type); void Load(); private: @@ -681,8 +683,10 @@ namespace JSON { }); } - AppLoader::AppLoader(const std::string& Filename, bool Global) - : FEXCore::Config::OptionMapper(Global ? FEXCore::Config::LayerType::LAYER_GLOBAL_APP : FEXCore::Config::LayerType::LAYER_LOCAL_APP) { + AppLoader::AppLoader(const std::string& Filename, FEXCore::Config::LayerType Type) + : FEXCore::Config::OptionMapper(Type) { + const bool Global = Type == FEXCore::Config::LayerType::LAYER_GLOBAL_STEAM_APP || + Type == FEXCore::Config::LayerType::LAYER_LOCAL_STEAM_APP; Config = FEXCore::Config::GetApplicationConfig(Filename, Global); // Immediately load so we can reload the meta layer @@ -754,8 +758,8 @@ namespace JSON { } } - std::unique_ptr CreateAppLayer(const std::string& Filename, bool Global) { - return std::make_unique(Filename, Global); + std::unique_ptr CreateAppLayer(const std::string& Filename, FEXCore::Config::LayerType Type) { + return std::make_unique(Filename, Type); } std::unique_ptr CreateEnvironmentLayer(char *const _envp[]) { diff --git a/External/FEXCore/include/FEXCore/Config/Config.h b/External/FEXCore/include/FEXCore/Config/Config.h index 8a37e1cbf..5313aad07 100644 --- a/External/FEXCore/include/FEXCore/Config/Config.h +++ b/External/FEXCore/include/FEXCore/Config/Config.h @@ -74,7 +74,9 @@ namespace Handler { LAYER_GLOBAL_MAIN, ///< /usr/share/fex-emu/Config.json by default LAYER_MAIN, LAYER_ARGUMENTS, + LAYER_GLOBAL_STEAM_APP, LAYER_GLOBAL_APP, + LAYER_LOCAL_STEAM_APP, LAYER_LOCAL_APP, LAYER_ENVIRONMENT, LAYER_TOP, @@ -272,7 +274,7 @@ namespace Type { * * @return unique_ptr for that layer */ - FEX_DEFAULT_VISIBILITY std::unique_ptr CreateAppLayer(const std::string& Filename, bool Global); + FEX_DEFAULT_VISIBILITY std::unique_ptr CreateAppLayer(const std::string& Filename, FEXCore::Config::LayerType Type); /** * @brief iCreate an environment configuration loader diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index 6f339c7b6..c4ca8e050 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -109,8 +109,18 @@ namespace FEX::Config { } } - FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, true)); - FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, false)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, FEXCore::Config::LayerType::LAYER_GLOBAL_APP)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, FEXCore::Config::LayerType::LAYER_LOCAL_APP)); + + auto SteamID = getenv("SteamAppId"); + if (SteamID) { + // If a SteamID exists then let's search for Steam application configs as well. + // We want to key off both the SteamAppId number /and/ the executable since we may not want to thunk all binaries. + auto SteamAppName = fmt::format("Steam_{}_{}", SteamID, ProgramName.string()); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(SteamAppName, FEXCore::Config::LayerType::LAYER_GLOBAL_STEAM_APP)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(SteamAppName, FEXCore::Config::LayerType::LAYER_LOCAL_STEAM_APP)); + } + return std::make_pair(Program, ProgramName); } return {}; diff --git a/Source/Tests/LinuxSyscalls/FileManagement.cpp b/Source/Tests/LinuxSyscalls/FileManagement.cpp index d852a86da..0b7ec0e3d 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tests/LinuxSyscalls/FileManagement.cpp @@ -249,17 +249,40 @@ FileManager::FileManager(FEXCore::Context::Context *ctx) } }; - // We try to load ThunksDB from {FEX global config, FEX user config, Defined ThunksConfig option, AppConfig Global, AppConfig Local} + // We try to load ThunksDB from: + // - FEX global config + // - FEX user config + // - Defined ThunksConfig option + // - Steam AppConfig Global + // - AppConfig Global + // - Steam AppConfig Local + // - AppConfig Local // This doesn't support the classic thunks interface. + auto AppName = AppConfigName(); std::vector ConfigPaths { FEXCore::Config::GetConfigFileLocation(true), FEXCore::Config::GetConfigFileLocation(false), ThunkConfigFile, - FEXCore::Config::GetApplicationConfig(AppConfigName(), true), - FEXCore::Config::GetApplicationConfig(AppConfigName(), false), }; + auto SteamID = getenv("SteamAppId"); + if (SteamID) { + // If a SteamID exists then let's search for Steam application configs as well. + // We want to key off both the SteamAppId number /and/ the executable since we may not want to thunk all binaries. + auto SteamAppName = fmt::format("Steam_{}_{}", SteamID, AppName); + + // Steam application configs interleaved with non-steam for priority sorting. + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(SteamAppName, true)); + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(AppName, true)); + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(SteamAppName, false)); + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(AppName, false)); + } + else { + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(AppName, true)); + ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(AppName, false)); + } + for (const auto &Path : ConfigPaths) { std::vector FileData; if (LoadFile(FileData, Path)) { diff --git a/Source/Tools/FEXGetConfig/Main.cpp b/Source/Tools/FEXGetConfig/Main.cpp index 90720b3c0..c83575753 100644 --- a/Source/Tools/FEXGetConfig/Main.cpp +++ b/Source/Tools/FEXGetConfig/Main.cpp @@ -40,8 +40,17 @@ int main(int argc, char **argv, char **envp) { if (Options.is_set_by_user("app")) { // Load the application config if one was provided auto ProgramName = std::filesystem::path(Options["app"]).filename(); - FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, true)); - FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, false)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, FEXCore::Config::LayerType::LAYER_GLOBAL_APP)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(ProgramName, FEXCore::Config::LayerType::LAYER_LOCAL_APP)); + + auto SteamID = getenv("SteamAppId"); + if (SteamID) { + // If a SteamID exists then let's search for Steam application configs as well. + // We want to key off both the SteamAppId number /and/ the executable since we may not want to thunk all binaries. + auto SteamAppName = fmt::format("Steam_{}_{}", SteamID, ProgramName.string()); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(SteamAppName, FEXCore::Config::LayerType::LAYER_GLOBAL_STEAM_APP)); + FEXCore::Config::AddLayer(FEXCore::Config::CreateAppLayer(SteamAppName, FEXCore::Config::LayerType::LAYER_LOCAL_STEAM_APP)); + } } // Reload the meta layer