diff --git a/post_build/README.experimental_steamclient.md b/post_build/README.experimental_steamclient.md index 3a4b3129..c5a840f4 100644 --- a/post_build/README.experimental_steamclient.md +++ b/post_build/README.experimental_steamclient.md @@ -83,6 +83,11 @@ This dll is meant to be injected during **startup** only, it must **not** be pla Some apps verify the existence of this dll, either on disk, or inside their memory space, that's why this dll exists. It is **NOT** recommended to ignore this dll. +## Recommended path for apps/games +Some apps check if their **root folder** is inside `steamapps/common`, so it is recommended to create this directory `steamapps/common` and put the app's **folder** there. +Example: `~/my apps/steamapps/common/my app/` +Example: `D:\my apps\steamapps\common\my app\` + ## Mods paths (source-engine games on Windows) On Windows, the registry key `SourceModInstallPath` is changed to the folder containing the loader. ``` @@ -95,4 +100,4 @@ New value: This affects source-engine mods ## Linux -On Linux, you may need to set the environment variable `PROTON_DISABLE_LSTEAMCLIENT=1` when running `steamclient_loader.exe`, depending on the Proton variant you are using (e.g. Proton GE run through Lutris or UMU needs it). \ No newline at end of file +On Linux, you may need to set the environment variable `PROTON_DISABLE_LSTEAMCLIENT=1` when running `steamclient_loader.exe`, depending on the Proton variant you are using (e.g. Proton GE run through Lutris or UMU needs it). diff --git a/tools/steamclient_loader/win/ColdClientLoader.cpp b/tools/steamclient_loader/win/ColdClientLoader.cpp index fe16d94b..2a02fef2 100644 --- a/tools/steamclient_loader/win/ColdClientLoader.cpp +++ b/tools/steamclient_loader/win/ColdClientLoader.cpp @@ -403,7 +403,7 @@ static void cleanup_registry_hkcs() -static void set_steam_env_vars(const std::string &AppId) +static void set_steam_env_vars() { SetEnvironmentVariableA("SteamAppId", AppId.c_str()); SetEnvironmentVariableA("SteamGameId", AppId.c_str()); @@ -420,6 +420,55 @@ static void set_steam_env_vars(const std::string &AppId) } +static void read_steam_settings_appid() +{ + static const auto try_read_file = [](const std::filesystem::path &appid_file) -> std::string { + try { + if (!common_helpers::file_exist(appid_file)) return {}; + + auto fr = std::ifstream(appid_file, std::ios::in | std::ios::binary); + if (!fr) return {}; + + std::string content{}; + std::getline(fr, content); + fr.close(); + + return common_helpers::string_strip(content); + } catch(...) {} + + return {}; + }; + + const auto steam_settings_folder = std::filesystem::u8path("steam_settings"); + const auto current_folder = std::filesystem::u8path(pe_helpers::get_current_exe_path()); + const auto exe_folder = std::filesystem::u8path(ExeFile).parent_path(); + const auto exe_run_dir_folder = std::filesystem::u8path(ExeRunDir); + const std::vector search_folders { + current_folder / steam_settings_folder, + exe_folder / steam_settings_folder, + exe_run_dir_folder / steam_settings_folder, + + current_folder, + exe_folder, + exe_run_dir_folder, + }; + + for (const auto &folder : search_folders) { + + const auto appid_file = folder / std::filesystem::u8path("steam_appid.txt"); + const auto content = try_read_file(appid_file); + if (!content.empty()) { + AppId = content; + logger.write( + "Read appid file '%s', content '%s'", + appid_file.u8string().c_str(), AppId.c_str() + ); + return; + } + } +} + + int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow) { IniFile = pe_helpers::get_current_exe_path() + std::filesystem::u8path(pe_helpers::get_current_exe_name()).stem().u8string() + ".ini"; @@ -624,20 +673,24 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance } if (PersistentMode != 2) { - if (AppId.size() && AppId[0]) { - try { - (void)std::stoul(AppId); - } catch(...) { - logger.write("AppId is not a valid number"); - MessageBoxA(NULL, "AppId is not a valid number.", "ColdClientLoader", MB_ICONERROR); + if (AppId.empty()) { + read_steam_settings_appid(); + if (AppId.empty()) { + logger.write("You forgot to set the AppId"); + MessageBoxA(NULL, "You forgot to set the AppId.", "ColdClientLoader", MB_ICONERROR); return 1; } - set_steam_env_vars(AppId); - } else { - logger.write("You forgot to set the AppId"); - MessageBoxA(NULL, "You forgot to set the AppId.", "ColdClientLoader", MB_ICONERROR); + } + + try { + (void)std::stoul(AppId); + } catch(...) { + logger.write("AppId is not a valid number"); + MessageBoxA(NULL, "AppId is not a valid number.", "ColdClientLoader", MB_ICONERROR); return 1; } + + set_steam_env_vars(); } else { // steam://run/ constexpr const static wchar_t STEAM_LAUNCH_CMD_1[] = L"-- \"steam://run/"; constexpr const static wchar_t STEAM_LAUNCH_CMD_2[] = L"-- \"steam://rungameid/"; @@ -658,7 +711,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance } if (AppId.size()) { - set_steam_env_vars(AppId); + set_steam_env_vars(); logger.write("persistent mode 2 will use app id = " + AppId); } else { logger.write("persistent mode 2 didn't find app id"); diff --git a/tools/steamclient_loader/win/ColdClientLoader.ini b/tools/steamclient_loader/win/ColdClientLoader.ini index bb9bdd75..d416e21d 100644 --- a/tools/steamclient_loader/win/ColdClientLoader.ini +++ b/tools/steamclient_loader/win/ColdClientLoader.ini @@ -1,16 +1,23 @@ # modified version of ColdClientLoader originally by Rat431 [SteamClient] # path to game exe, absolute or relative to the loader -Exe=game.exe +Exe=steamapps\common\game_folder\game.exe # empty means the folder of the exe ExeRunDir= # any additional args to pass, ex: -dx11, also any args passed to the loader will be passed to the app ExeCommandLine= -# IMPORTANT, unless [Persistence] Mode=2 +# Steam ID of the app, unless [Persistence] Mode=2 +# if this is empty the loader will try to read the file "steam_appid.txt" from the following folders in order: +# /steam_settings/ +# /steam_settings/ +# /steam_settings/ +# +# / +# / +# / AppId= -# path to the steamclient dlls, both must be set, -# absolute paths or relative to the loader +# path to the steamclient dlls, both must be set, absolute paths or relative to the loader directory SteamClientDll=steamclient.dll SteamClient64Dll=steamclient64.dll