diff --git a/CMakeLists.txt b/CMakeLists.txt index 52ce7d3..3c26029 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(SMOKE_API_SOURCES src/steam_api/virtuals/isteamhttp.cpp src/steam_api/virtuals/isteaminventory.cpp src/steam_api/virtuals/isteamuser.cpp + src/steam_api/virtuals/isteamutils.cpp src/steam_api/virtuals/steam_api_virtuals.hpp src/steam_api/steam_client.hpp src/steam_api/steam_client.cpp diff --git a/KoalaBox b/KoalaBox index dbe840c..30227ef 160000 --- a/KoalaBox +++ b/KoalaBox @@ -1 +1 @@ -Subproject commit dbe840c569f7b78881fb90bdd765d553e8ed5084 +Subproject commit 30227ef32ec22b64a4140095cd3a3849bfd9be98 diff --git a/src/smoke_api/smoke_api.cpp b/src/smoke_api/smoke_api.cpp index 2d99e7b..6932236 100644 --- a/src/smoke_api/smoke_api.cpp +++ b/src/smoke_api/smoke_api.cpp @@ -16,6 +16,7 @@ #include "smoke_api/config.hpp" #include "smoke_api/steamclient/steamclient.hpp" #include "steam_api/steam_interfaces.hpp" +#include "steam_api/virtuals/steam_api_virtuals.hpp" #include "build_config.h" @@ -179,14 +180,46 @@ namespace smoke_api { } AppId_t get_app_id() { + static AppId_t app_id = 0; + if(app_id) { + return app_id; // cached value + } + try { - const auto* const app_id_str = std::getenv("SteamAppId"); - if(app_id_str == nullptr) { - LOG_WARN("No SteamAppId is set in current environment"); + if(const auto app_id_str = kb::util::get_env("SteamAppId")) { + app_id = std::stoi(*app_id_str); + LOG_DEBUG("Found AppID from environment: {}", app_id); + + return app_id; + } + } catch(std::exception&) { + LOG_WARN("No SteamAppId in environment. Falling back to ISteamUtils::GetAppID."); + } + + // TODO: Then try to read steam_appid.txt here. SteamAppId env var is not available when it's present. + + try { + DECLARE_ARGS(); + + THIS = CreateInterface("SteamClient007", nullptr); + if(!THIS) { + LOG_ERROR("Failed to create SteamClient interface"); return 0; } - static auto app_id = std::stoi(app_id_str); + THIS = ISteamClient_GetISteamGenericInterface(ARGS(1, 1, "SteamUtils002")); + if(!THIS) { + LOG_ERROR("Failed to get SteamUtils interface"); + return 0; + } + + app_id = ISteamUtils_GetAppID(ARGS()); + if(!app_id) { + LOG_ERROR("ISteamUtils::GetAppID returned 0"); + return 0; + } + + LOG_DEBUG("Found AppID from ISteamUtils: {}", app_id); return app_id; } catch(const std::exception& e) { LOG_ERROR("Failed to get app id: {}", e.what()); diff --git a/src/smoke_api/smoke_api.hpp b/src/smoke_api/smoke_api.hpp index bbba2fb..5eb4dd2 100644 --- a/src/smoke_api/smoke_api.hpp +++ b/src/smoke_api/smoke_api.hpp @@ -6,6 +6,7 @@ constexpr auto STEAM_APPS = "STEAMAPPS_INTERFACE_VERSION"; constexpr auto STEAM_CLIENT = "SteamClient"; constexpr auto STEAM_HTTP = "STEAMHTTP_INTERFACE_VERSION"; constexpr auto STEAM_USER = "SteamUser"; +constexpr auto STEAM_UTILS = "SteamUtils"; constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V"; constexpr auto STEAM_GAME_SERVER = "SteamGameServer"; diff --git a/src/steam_api/steam_interfaces.cpp b/src/steam_api/steam_interfaces.cpp index a7d95d5..cc467be 100644 --- a/src/steam_api/steam_interfaces.cpp +++ b/src/steam_api/steam_interfaces.cpp @@ -4,12 +4,12 @@ #include #include +#include "koalabox/lib.hpp" + +#include "smoke_api/steamclient/steamclient.hpp" #include "steam_api/steam_interfaces.hpp" - -#include "koalabox/lib.hpp" #include "smoke_api/smoke_api.hpp" -#include "smoke_api/steamclient/steamclient.hpp" #include "virtuals/steam_api_virtuals.hpp" namespace { @@ -104,6 +104,15 @@ namespace { } } }, + { + STEAM_UTILS, + interface_data_t{ + .fallback_version = "SteamUtils009", + .entry_map = { + ENTRY(ISteamUtils, GetAppID), + } + } + }, }; } @@ -210,7 +219,9 @@ namespace steam_interfaces { const auto prefixes = std::views::keys(virtual_hook_map) | std::ranges::to(); const auto CreateInterface$ = KB_MOD_GET_FUNC(steamclient_handle, CreateInterface); - const auto* const THIS = CreateInterface$(steam_client_interface_version.c_str(), nullptr); + + DECLARE_ARGS(); + THIS = CreateInterface$(steam_client_interface_version.c_str(), nullptr); hook_virtuals(THIS, steam_client_interface_version); const auto interface_lookup = read_interface_lookup(); @@ -234,7 +245,6 @@ namespace steam_interfaces { continue; } - DECLARE_EDX(); const auto* const interface_ptr = ISteamClient_GetISteamGenericInterface( ARGS(steam_user, steam_pipe, interface_version.c_str()) ); diff --git a/src/steam_api/steam_interfaces.hpp b/src/steam_api/steam_interfaces.hpp index 6fa5ebc..0c483bf 100644 --- a/src/steam_api/steam_interfaces.hpp +++ b/src/steam_api/steam_interfaces.hpp @@ -1,6 +1,6 @@ #pragma once -#include "smoke_api/types.hpp" +#include namespace steam_interfaces { void hook_virtuals(const void* interface_ptr, const std::string& version_string); diff --git a/src/steam_api/virtuals/isteamutils.cpp b/src/steam_api/virtuals/isteamutils.cpp new file mode 100644 index 0000000..cab05bb --- /dev/null +++ b/src/steam_api/virtuals/isteamutils.cpp @@ -0,0 +1,9 @@ +#include + +#include "smoke_api/smoke_api.hpp" +#include "smoke_api/interfaces/steam_user.hpp" +#include "steam_api/virtuals/steam_api_virtuals.hpp" + +VIRTUAL(AppId_t) ISteamUtils_GetAppID(PARAMS()) noexcept { + SWAPPED_CALL(THIS, ISteamUtils_GetAppID, ARGS()); +} diff --git a/src/steam_api/virtuals/steam_api_virtuals.hpp b/src/steam_api/virtuals/steam_api_virtuals.hpp index b481475..3730566 100644 --- a/src/steam_api/virtuals/steam_api_virtuals.hpp +++ b/src/steam_api/virtuals/steam_api_virtuals.hpp @@ -11,21 +11,11 @@ VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(PARAMS(int, AppId_t*, bool*, char*, // ISteamClient VIRTUAL(void*) ISteamClient_GetISteamApps(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept; VIRTUAL(void*) ISteamClient_GetISteamUser(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept; -VIRTUAL(void*) ISteamClient_GetISteamGenericInterface( - PARAMS(HSteamUser, HSteamPipe, const char*) - - -) noexcept; -VIRTUAL(void*) ISteamClient_GetISteamInventory( - PARAMS(HSteamUser, HSteamPipe, const char*) - - -) noexcept; +VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept; +VIRTUAL(void*) ISteamClient_GetISteamInventory(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept; // ISteamHTTP -VIRTUAL(bool) ISteamHTTP_GetHTTPResponseBodyData( - PARAMS(HTTPRequestHandle, const uint8_t*, uint32_t) -) noexcept; +VIRTUAL(bool) ISteamHTTP_GetHTTPResponseBodyData(PARAMS(HTTPRequestHandle, const uint8_t*, uint32_t)) noexcept; VIRTUAL(bool) ISteamHTTP_GetHTTPStreamingResponseBodyData( PARAMS(HTTPRequestHandle, uint32_t, const uint8_t*, uint32_t) ) noexcept; @@ -38,7 +28,6 @@ VIRTUAL(EResult) ISteamInventory_GetResultStatus(PARAMS(SteamInventoryResult_t)) VIRTUAL(bool) ISteamInventory_GetResultItems( PARAMS(SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*) // @formatter:off ) noexcept; // @formatter:on - VIRTUAL(bool) ISteamInventory_GetResultItemProperty( PARAMS(SteamInventoryResult_t, uint32_t, const char*, char*, uint32_t*) // @formatter:off ) noexcept; // @formatter:on @@ -46,20 +35,15 @@ VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t*)) noexc VIRTUAL(bool) ISteamInventory_GetItemsByID( PARAMS(SteamInventoryResult_t*, const SteamItemInstanceID_t*, uint32_t) ) noexcept; -VIRTUAL(bool) ISteamInventory_SerializeResult( - PARAMS(SteamInventoryResult_t, void*, uint32_t*) - - -) noexcept; +VIRTUAL(bool) ISteamInventory_SerializeResult(PARAMS(SteamInventoryResult_t, void*, uint32_t*)) noexcept; VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint32_t*)) noexcept; VIRTUAL(bool) ISteamInventory_CheckResultSteamID(PARAMS(SteamInventoryResult_t, CSteamID)) noexcept; // ISteamUser -VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp( - PARAMS(CSteamID, AppId_t) -) noexcept; +VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t)) noexcept; + +// ISteamUtils +VIRTUAL(AppId_t) ISteamUtils_GetAppID(PARAMS()) noexcept; // ISteamGameServer -VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp( - PARAMS(CSteamID, AppId_t) -) noexcept; +VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t)) noexcept; diff --git a/static/smoke_api/types.hpp b/static/smoke_api/types.hpp index 4daa087..ffad415 100644 --- a/static/smoke_api/types.hpp +++ b/static/smoke_api/types.hpp @@ -46,12 +46,12 @@ #define PARAMS(...) const void* RCX __VA_OPT__(,) __VA_ARGS__ #define ARGS(...) RCX __VA_OPT__(,) __VA_ARGS__ #define THIS RCX -#define DECLARE_EDX() +#define DECLARE_ARGS() const void* RCX = nullptr; #else #define PARAMS(...) const void* ECX, const void* EDX __VA_OPT__(,) __VA_ARGS__ #define ARGS(...) ECX, EDX __VA_OPT__(,) __VA_ARGS__ #define THIS ECX -#define DECLARE_EDX() const void* EDX = nullptr; +#define DECLARE_ARGS() const void* ECX = nullptr; const void* EDX = nullptr; #endif using AppId_t = uint32_t; @@ -112,8 +112,9 @@ public: explicit DLC() = default; - explicit DLC(std::string appid, std::string name) : appid{std::move(appid)}, - name{std::move(name)} {} + explicit DLC(std::string appid, std::string name) + : appid{std::move(appid)}, + name{std::move(name)} {} [[nodiscard]] std::string get_id_str() const { return appid;