From e08cf014d1d55c6fbf02a3ca6d7aacbab9536314 Mon Sep 17 00:00:00 2001 From: acidicoala <67734819+acidicoala@users.noreply.github.com> Date: Sat, 23 Aug 2025 21:26:49 +0500 Subject: [PATCH] Refactored types --- CMakeLists.txt | 16 +- KoalaBox | 2 +- README.adoc | 2 +- docs/building_from_source.md | 3 - docs/tools.md | 3 - res/SmokeAPI.config.json | 1 + res/SmokeAPI.schema.json | 145 ++++++++++++++++++ src/smoke_api.cpp | 2 +- src/smoke_api.hpp | 7 - src/steam_api/virtuals/steam_api_virtuals.hpp | 35 ----- src/steamclient.cpp | 16 ++ src/steamclient/steamclient.cpp | 15 -- src/steamclient/steamclient.hpp | 5 - static/smoke_api/config.hpp | 2 +- .../smoke_api/interfaces/steam_inventory.cpp | 6 +- static/smoke_api/interfaces/steam_user.cpp | 2 +- static/smoke_api/steamclient/steamclient.hpp | 5 + static/smoke_api/types.hpp | 52 ++++++- tools/README.md | 13 ++ 19 files changed, 243 insertions(+), 89 deletions(-) delete mode 100644 docs/building_from_source.md delete mode 100644 docs/tools.md create mode 100644 res/SmokeAPI.schema.json create mode 100644 src/steamclient.cpp delete mode 100644 src/steamclient/steamclient.cpp delete mode 100644 src/steamclient/steamclient.hpp create mode 100644 static/smoke_api/steamclient/steamclient.hpp create mode 100644 tools/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bd7aa3..3b1fef4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(SMOKE_API_STATIC_SOURCES static/smoke_api/config.cpp static/smoke_api/types.hpp static/smoke_api/types.cpp + static/smoke_api/steamclient/steamclient.hpp ) set(SMOKE_API_SOURCES @@ -45,8 +46,7 @@ set(SMOKE_API_SOURCES src/steam_api/steam_client.cpp src/steam_api/steam_interface.cpp src/steam_api/steam_interface.hpp - src/steamclient/steamclient.cpp - src/steamclient/steamclient.hpp + src/steamclient.cpp src/main.cpp src/smoke_api.cpp src/smoke_api.hpp @@ -62,7 +62,7 @@ add_library(SmokeAPI_interface INTERFACE) #target_compile_options(SmokeAPI_interface PUBLIC /std:c++latest) target_include_directories(SmokeAPI_interface INTERFACE - "$" + "$" ) target_link_libraries(SmokeAPI_interface INTERFACE KoalaBox $) @@ -71,7 +71,7 @@ target_link_libraries(SmokeAPI_interface INTERFACE KoalaBox $ - -#include "steamclient.hpp" - -#include "smoke_api.hpp" -#include "smoke_api/types.hpp" -#include "steam_api/steam_client.hpp" - -C_DECL(void*) CreateInterface(const char* interface_string, int* out_result) { - return steam_client::GetGenericInterface( - __func__, - interface_string, - HOOKED_CALL_CLOSURE(CreateInterface, interface_string, out_result) - ); -} diff --git a/src/steamclient/steamclient.hpp b/src/steamclient/steamclient.hpp deleted file mode 100644 index bb54c16..0000000 --- a/src/steamclient/steamclient.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#define C_DECL(TYPE) extern "C" __declspec(noinline) TYPE __cdecl - -C_DECL(void*) CreateInterface(const char* interface_string, int* out_result); diff --git a/static/smoke_api/config.hpp b/static/smoke_api/config.hpp index 4c4fdf1..5a357ca 100644 --- a/static/smoke_api/config.hpp +++ b/static/smoke_api/config.hpp @@ -23,7 +23,7 @@ namespace smoke_api::config { ) struct Config { - uint32_t $version = 2; + uint32_t $version = 3; bool logging = false; AppStatus default_app_status = AppStatus::UNLOCKED; uint32_t override_app_id = 0; diff --git a/static/smoke_api/interfaces/steam_inventory.cpp b/static/smoke_api/interfaces/steam_inventory.cpp index efd2320..320beda 100644 --- a/static/smoke_api/interfaces/steam_inventory.cpp +++ b/static/smoke_api/interfaces/steam_inventory.cpp @@ -64,11 +64,11 @@ namespace smoke_api::steam_inventory { ); static uint32_t original_count = 0; - const auto injected_count = smoke_api::config::instance.extra_inventory_items.size(); + const auto injected_count = config::instance.extra_inventory_items.size(); // Automatically get inventory items from steam static std::vector auto_inventory_items; - if(smoke_api::config::instance.auto_inject_inventory) { + if(config::instance.auto_inject_inventory) { static std::once_flag inventory_inject_flag; std::call_once( inventory_inject_flag, @@ -120,7 +120,7 @@ namespace smoke_api::steam_inventory { for(int i = 0; i < injected_count; i++) { auto& item = pOutItemsArray[original_count + auto_injected_count + i]; - const auto item_def_id = smoke_api::config::instance.extra_inventory_items[i]; + const auto item_def_id = config::instance.extra_inventory_items[i]; item = new_item(item_def_id); diff --git a/static/smoke_api/interfaces/steam_user.cpp b/static/smoke_api/interfaces/steam_user.cpp index 52c3d9e..5a0c1c0 100644 --- a/static/smoke_api/interfaces/steam_user.cpp +++ b/static/smoke_api/interfaces/steam_user.cpp @@ -17,7 +17,7 @@ namespace smoke_api::steam_user { return result; } - const auto has_license = smoke_api::config::is_dlc_unlocked( + const auto has_license = config::is_dlc_unlocked( appId, dlcId, [&] { diff --git a/static/smoke_api/steamclient/steamclient.hpp b/static/smoke_api/steamclient/steamclient.hpp new file mode 100644 index 0000000..68d0afa --- /dev/null +++ b/static/smoke_api/steamclient/steamclient.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include "smoke_api/types.hpp" + +C_DECL(void*) CreateInterface(const char* interface_version, int* out_result); diff --git a/static/smoke_api/types.hpp b/static/smoke_api/types.hpp index eb4473f..fc671d2 100644 --- a/static/smoke_api/types.hpp +++ b/static/smoke_api/types.hpp @@ -6,12 +6,52 @@ #include -// TODO: Replace with direct call -#define GET_ORIGINAL_HOOKED_FUNCTION(FUNC) \ - static const auto FUNC##_o = koalabox::hook::get_original_hooked_function(#FUNC, FUNC); +#include -#define DETOUR_ADDRESS(FUNC, ADDRESS) \ - koalabox::hook::detour_or_warn(ADDRESS, #FUNC, reinterpret_cast(FUNC)); +#define VIRTUAL(TYPE) __declspec(noinline) TYPE __fastcall // NOLINT(*-macro-parentheses) +#define C_DECL(TYPE) extern "C" __declspec(noinline) TYPE __cdecl + +// These macros are meant to be used for callbacks that should return original result + +#define HOOKED_CALL(FUNC, ...) \ +static const auto _##FUNC = KB_HOOK_GET_HOOKED_FN(FUNC); \ +return _##FUNC(__VA_ARGS__) + +#define HOOKED_CALL_CLOSURE(FUNC, ...) \ +[&] { HOOKED_CALL(FUNC, __VA_ARGS__); } + +/** + * By default, virtual functions are declared with __thiscall + * convention, which is normal since they are class members. + * But it presents an issue for us, since we cannot pass *this + * pointer as a function argument. This is because *this + * pointer is passed via register ECX in __thiscall + * convention. Hence, to resolve this issue we declare virtual + * hooked functions with __fastcall convention, to trick + * the compiler into reading ECX & EDX registers as 1st + * and 2nd function arguments respectively. Similarly, __fastcall + * makes the compiler push the first argument into the ECX register, + * which mimics the __thiscall calling convention. Register EDX + * is not used anywhere in this case, but we still pass it along + * to conform to the __fastcall convention. This all applies + * to the x86 architecture. + * + * In x86-64 however, there is only one calling convention, + * so __fastcall is simply ignored. However, RDX in this case + * will store the 1st actual argument to the function, so we + * have to omit it from the function signature. + * + * The macros below implement the above-mentioned considerations. + */ +#ifdef _WIN64 +#define PARAMS(...) const void *RCX, __VA_ARGS__ +#define ARGS(...) RCX, __VA_ARGS__ +#define THIS RCX +#else +#define PARAMS(...) const void *ECX, const void *EDX, __VA_ARGS__ +#define ARGS(...) ECX, EDX, __VA_ARGS__ +#define THIS ECX +#endif using AppId_t = uint32_t; using HSteamPipe = uint32_t; @@ -80,4 +120,4 @@ public: static std::vector get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_id); static DlcNameMap get_dlc_map_from_vector(const std::vector& dlcs); -}; \ No newline at end of file +}; diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..055ea14 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,13 @@ +# SmokeAPI tools + +## Steamworks Downloader + +A simple tool for downloading Steamworks SDK archive from the public GitHub repository +[cdn](https://github.com/acidicoala/cdn/tree/main/valve) +and unzipping headers and binaries into the main project for subsequent processing. + +## Steamworks Parser + +A more sophisticated tool that parses Steamworks SDK C++ headers +in order to build an [interface lookup map](../res/interface_lookup.json), +which is used by SmokeAPI to lookup function ordinals for specific interface versions.