From edd785cfcfa381a3c7fa5d008ba39fa8e156ce06 Mon Sep 17 00:00:00 2001 From: acidicoala <67734819+acidicoala@users.noreply.github.com> Date: Wed, 11 Jan 2023 01:35:14 +0300 Subject: [PATCH] Added ReloadConfig --- CMakeLists.txt | 1 + KoalaBox | 2 +- res/SmokeAPI.config.json | 4 + src/core/types.hpp | 5 - src/koalageddon/koalageddon.cpp | 3 +- src/koalageddon/koalageddon.hpp | 3 - src/koalageddon/steamclient/client_apps.cpp | 6 +- src/koalageddon/steamclient/client_user.cpp | 10 +- src/koalageddon/steamclient/client_utils.cpp | 7 ++ src/koalageddon/steamclient/steamclient.cpp | 104 +++++++++++-------- src/koalageddon/steamclient/steamclient.hpp | 6 ++ src/smoke_api/config.cpp | 32 ++++-- src/smoke_api/config.hpp | 6 +- src/smoke_api/smoke_api.cpp | 1 + src/steam_api_exports/steam_api_exports.hpp | 33 +++--- src/steam_api_exports/steam_api_flat.cpp | 67 ++++++------ src/steam_api_virtuals/isteamuser.cpp | 7 +- src/steam_impl/steam_apps.cpp | 1 + src/steam_impl/steam_inventory.cpp | 1 - src/steam_impl/steam_user.cpp | 9 +- src/steam_impl/steam_user.hpp | 4 +- 21 files changed, 184 insertions(+), 128 deletions(-) create mode 100644 src/koalageddon/steamclient/client_utils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5975e23..929888e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 4) src/koalageddon/steamclient/client_apps.cpp src/koalageddon/steamclient/client_inventory.cpp src/koalageddon/steamclient/client_user.cpp + src/koalageddon/steamclient/client_utils.cpp src/koalageddon/steamclient/steamclient.cpp src/koalageddon/steamclient/steamclient.hpp ) diff --git a/KoalaBox b/KoalaBox index db8cea4..17c3922 160000 --- a/KoalaBox +++ b/KoalaBox @@ -1 +1 @@ -Subproject commit db8cea415e62ffbd8e5eea10189a9f28844c1fb9 +Subproject commit 17c39229db33c908e958e9c733cefdfc46204b17 diff --git a/res/SmokeAPI.config.json b/res/SmokeAPI.config.json index 36ec107..37f83a9 100644 --- a/res/SmokeAPI.config.json +++ b/res/SmokeAPI.config.json @@ -4,6 +4,10 @@ "unlock_family_sharing": true, "default_app_status": "unlocked", "override_app_status": { + "1234": "original", + "4321": "unlocked" + }, + "override_dlc_status": { "1234": "original", "4321": "unlocked", "5678": "locked" diff --git a/src/core/types.hpp b/src/core/types.hpp index b2c4a8e..49a6acc 100644 --- a/src/core/types.hpp +++ b/src/core/types.hpp @@ -94,11 +94,6 @@ enum EUserHasLicenseForAppResult { k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated }; -class ISteamClient; -class ISteamApps; -class ISteamUser; -class ISteamInventory; - // These aliases exist solely to increase code readability using AppIdKey = String; diff --git a/src/koalageddon/koalageddon.cpp b/src/koalageddon/koalageddon.cpp index 737254f..eeef08c 100644 --- a/src/koalageddon/koalageddon.cpp +++ b/src/koalageddon/koalageddon.cpp @@ -9,7 +9,6 @@ #include namespace koalageddon { - const void* client_app_manager_interface = nullptr; KoalageddonConfig config; // NOLINT(cert-err58-cpp) @@ -56,6 +55,8 @@ namespace koalageddon { } void init() { + // TODO: Load cached koalageddon config by default + std::thread( []() { const auto kg_config_source = init_koalageddon_config(); diff --git a/src/koalageddon/koalageddon.hpp b/src/koalageddon/koalageddon.hpp index 8790c9e..1a3cdf4 100644 --- a/src/koalageddon/koalageddon.hpp +++ b/src/koalageddon/koalageddon.hpp @@ -26,9 +26,6 @@ namespace koalageddon { ) }; - /// We need this interface in other IClient* functions in order to query original DLC status - extern const void* client_app_manager_interface; - extern KoalageddonConfig config; void init(); diff --git a/src/koalageddon/steamclient/client_apps.cpp b/src/koalageddon/steamclient/client_apps.cpp index f143494..2d1cbf8 100644 --- a/src/koalageddon/steamclient/client_apps.cpp +++ b/src/koalageddon/steamclient/client_apps.cpp @@ -1,5 +1,4 @@ #include -#include #include VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) { @@ -32,8 +31,9 @@ VIRTUAL(bool) IClientApps_BGetDLCDataByIndex( ); }, [&](AppId_t dlc_id) { - if (koalageddon::client_app_manager_interface) { - IClientAppManager_IsAppDlcInstalled(koalageddon::client_app_manager_interface, EDX, appID, dlc_id); + const auto* app_manager_interface = koalageddon::steamclient::interface_name_to_address_map["IClientAppManager"]; + if (app_manager_interface) { + IClientAppManager_IsAppDlcInstalled(app_manager_interface, EDX, appID, dlc_id); return true; } diff --git a/src/koalageddon/steamclient/client_user.cpp b/src/koalageddon/steamclient/client_user.cpp index 0881226..93f37a7 100644 --- a/src/koalageddon/steamclient/client_user.cpp +++ b/src/koalageddon/steamclient/client_user.cpp @@ -1,10 +1,14 @@ #include #include -VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t app_id)) { - return steam_apps::IsDlcUnlocked(__func__, 0, app_id, [&]() { +VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t dlc_id)) { + const auto* utils_interface = koalageddon::steamclient::interface_name_to_address_map["IClientUtils"]; + + const auto app_id = utils_interface ? IClientUtils_GetAppID(utils_interface, EDX) : 0; + + return steam_apps::IsDlcUnlocked(__func__, app_id, dlc_id, [&]() { GET_ORIGINAL_HOOKED_FUNCTION(IClientUser_BIsSubscribedApp) - return IClientUser_BIsSubscribedApp_o(ARGS(app_id)); + return IClientUser_BIsSubscribedApp_o(ARGS(dlc_id)); }); } diff --git a/src/koalageddon/steamclient/client_utils.cpp b/src/koalageddon/steamclient/client_utils.cpp new file mode 100644 index 0000000..5a7839d --- /dev/null +++ b/src/koalageddon/steamclient/client_utils.cpp @@ -0,0 +1,7 @@ +#include + +VIRTUAL(AppId_t) IClientUtils_GetAppID(PARAMS()) { + GET_ORIGINAL_HOOKED_FUNCTION(IClientUtils_GetAppID) + + return IClientUtils_GetAppID_o(ARGS()); +} diff --git a/src/koalageddon/steamclient/steamclient.cpp b/src/koalageddon/steamclient/steamclient.cpp index b776e34..1c53abc 100644 --- a/src/koalageddon/steamclient/steamclient.cpp +++ b/src/koalageddon/steamclient/steamclient.cpp @@ -10,6 +10,8 @@ namespace koalageddon::steamclient { using namespace koalabox; + Map interface_name_to_address_map; // NOLINT(cert-err58-cpp) + struct InstructionContext { std::optional base_register; std::optional function_name; @@ -24,6 +26,14 @@ namespace koalageddon::steamclient { ZydisDecoder decoder = {}; ZydisFormatter formatter = {}; + void construct_ordinal_map( // NOLINT(misc-no-recursion) + const String& target_interface, + Map& map, + uintptr_t start_address, + Set& visited_addresses, + InstructionContext context + ); + #define HOOK_FUNCTION(INTERFACE, FUNC) hook::swap_virtual_func_or_throw( \ globals::address_map, \ interface, \ @@ -34,18 +44,20 @@ namespace koalageddon::steamclient { #define SELECTOR_IMPLEMENTATION(INTERFACE, FUNC_BODY) \ DLL_EXPORT(void) INTERFACE##_Selector( \ - const void* interface, \ - const void* arg2, \ - const void* arg3, \ - const void* arg4 \ + void* interface, \ + void* arg2, \ + void* arg3, \ + void* arg4 \ ) { \ - CALL_ONCE(FUNC_BODY) \ + CALL_ONCE({ \ + interface_name_to_address_map[#INTERFACE] = interface; \ + [&]()FUNC_BODY(); \ + }) \ GET_ORIGINAL_HOOKED_FUNCTION(INTERFACE##_Selector) \ INTERFACE##_Selector_o(interface, arg2, arg3, arg4); \ } SELECTOR_IMPLEMENTATION(IClientAppManager, { - koalageddon::client_app_manager_interface = interface; HOOK_FUNCTION(IClientAppManager, IsAppDlcInstalled) }) @@ -69,6 +81,36 @@ namespace koalageddon::steamclient { HOOK_FUNCTION(IClientUser, BIsSubscribedApp) }) + SELECTOR_IMPLEMENTATION(IClientUtils, { + HOOK_FUNCTION(IClientUtils, GetAppID) + }) + +#define CONSTRUCT_ORDINAL_MAP(INTERFACE) \ + Set nested_visited_addresses; \ + construct_ordinal_map( \ + #INTERFACE, \ + ordinal_map[#INTERFACE], \ + function_selector_address, \ + nested_visited_addresses, \ + {} \ + ); + +#define DETOUR_SELECTOR(INTERFACE) \ + if(interface_name == #INTERFACE){ \ + CONSTRUCT_ORDINAL_MAP(INTERFACE) \ + DETOUR_ADDRESS(INTERFACE##_Selector, function_selector_address) \ + } + + void detour_interface_selector(const String& interface_name, uintptr_t function_selector_address) { + LOG_DEBUG("Detected interface: '{}'", interface_name) + + DETOUR_SELECTOR(IClientAppManager) + DETOUR_SELECTOR(IClientApps) + DETOUR_SELECTOR(IClientInventory) + DETOUR_SELECTOR(IClientUser) + DETOUR_SELECTOR(IClientUtils) + } + uintptr_t get_absolute_address(ZydisDecodedInstruction instruction, uintptr_t address) { const auto operand = instruction.operands[0]; @@ -86,9 +128,9 @@ namespace koalageddon::steamclient { const auto& operand = instruction.operands[0]; return instruction.mnemonic == ZYDIS_MNEMONIC_PUSH && - operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE && - operand.visibility == ZYDIS_OPERAND_VISIBILITY_EXPLICIT && - operand.encoding == ZYDIS_OPERAND_ENCODING_SIMM16_32_32; + operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + operand.visibility == ZYDIS_OPERAND_VISIBILITY_EXPLICIT && + operand.encoding == ZYDIS_OPERAND_ENCODING_SIMM16_32_32; } std::optional get_string_argument(const ZydisDecodedInstruction& instruction) { @@ -142,9 +184,9 @@ namespace koalageddon::steamclient { const auto is_mov_base_esp = [](const ZydisDecodedInstruction& instruction) { return instruction.mnemonic == ZYDIS_MNEMONIC_MOV && - instruction.operand_count == 2 && - instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instruction.operands[1].reg.value == ZYDIS_REGISTER_ESP; + instruction.operand_count == 2 && + instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + instruction.operands[1].reg.value == ZYDIS_REGISTER_ESP; }; // Initialize with a dummy previous instruction @@ -169,8 +211,8 @@ namespace koalageddon::steamclient { // Save base register context.base_register = instruction.operands[0].reg.value; } else if (is_push_immediate(last_instruction) && - is_push_immediate(instruction) && - !context.function_name) { + is_push_immediate(instruction) && + !context.function_name) { // The very first 2 consecutive pushes indicate interface and function names. // However, subsequent pushes may contain irrelevant strings. const auto push_string_1 = get_string_argument(last_instruction); @@ -183,7 +225,7 @@ namespace koalageddon::steamclient { context.function_name = push_string_1; } - if (map.contains(*context.function_name)) { + if (context.function_name && map.contains(*context.function_name)) { // Bail early to avoid duplicate work return; } @@ -199,7 +241,7 @@ namespace koalageddon::steamclient { // But not continue forward, in order to avoid duplicate processing return; } else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP && - instruction.operands[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) { + instruction.operands[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) { // On unconditional jump we should recurse as well const auto jump_destination = get_absolute_address(instruction, current_address); @@ -304,22 +346,6 @@ namespace koalageddon::steamclient { return std::nullopt; } -#define CONSTRUCT_ORDINAL_MAP(INTERFACE) \ - Set nested_visited_addresses; \ - construct_ordinal_map( \ - #INTERFACE, \ - ordinal_map[#INTERFACE], \ - function_selector_address, \ - nested_visited_addresses, \ - {} \ - ); - -#define DETOUR_SELECTOR(INTERFACE) \ - if(interface_name == #INTERFACE){ \ - CONSTRUCT_ORDINAL_MAP(INTERFACE) \ - DETOUR_ADDRESS(INTERFACE##_Selector, function_selector_address) \ - } - void process_interface_selector( // NOLINT(misc-no-recursion) const uintptr_t start_address, Set& visited_addresses @@ -360,12 +386,7 @@ namespace koalageddon::steamclient { if (interface_name_opt) { const auto& interface_name = *interface_name_opt; - LOG_DEBUG("Detected interface: '{}'", interface_name) - - DETOUR_SELECTOR(IClientAppManager) - DETOUR_SELECTOR(IClientApps) - DETOUR_SELECTOR(IClientInventory) - DETOUR_SELECTOR(IClientUser) + detour_interface_selector(interface_name, function_selector_address); } } else if (instruction.meta.category == ZYDIS_CATEGORY_COND_BR) { const auto jump_taken_destination = get_absolute_address(instruction, current_address); @@ -386,9 +407,9 @@ namespace koalageddon::steamclient { LOG_TRACE("Breaking recursion due to unconditional branch") return; } else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP && - operand.type == ZYDIS_OPERAND_TYPE_MEMORY && - operand.mem.scale == sizeof(uintptr_t) && - operand.mem.disp.has_displacement + operand.type == ZYDIS_OPERAND_TYPE_MEMORY && + operand.mem.scale == sizeof(uintptr_t) && + operand.mem.disp.has_displacement ) { // Special handling for jump tables. Guaranteed to be present in the interface selector. const auto* table = (uintptr_t*) operand.mem.disp.value; @@ -433,4 +454,5 @@ namespace koalageddon::steamclient { Set visited_addresses; process_interface_selector(interface_selector_address, visited_addresses); } + } diff --git a/src/koalageddon/steamclient/steamclient.hpp b/src/koalageddon/steamclient/steamclient.hpp index 152a1e4..bcf388f 100644 --- a/src/koalageddon/steamclient/steamclient.hpp +++ b/src/koalageddon/steamclient/steamclient.hpp @@ -26,8 +26,14 @@ VIRTUAL(bool) IClientInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint // IClientUser VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t)); +// IClientUtils +VIRTUAL(AppId_t) IClientUtils_GetAppID(PARAMS()); + namespace koalageddon::steamclient { + /// We need this interface in other IClient* functions in order to call other functions + extern Map interface_name_to_address_map; + void process_client_engine(uintptr_t interface); } diff --git a/src/smoke_api/config.cpp b/src/smoke_api/config.cpp index 060352a..ee824a2 100644 --- a/src/smoke_api/config.cpp +++ b/src/smoke_api/config.cpp @@ -13,25 +13,34 @@ namespace smoke_api::config { if (exists(path)) { try { - instance = Json::parse(koalabox::io::read_file(path)).get(); + const auto config_str = koalabox::io::read_file(path); + + LOG_DEBUG("Parsing config:\n{}", config_str) + + instance = Json::parse(config_str).get(); + } catch (const Exception& e) { - koalabox::util::panic("Error parsing config: {}", e.what()); + const auto message = fmt::format("Error parsing config file: {}", e.what()); + koalabox::util::error_box("SmokeAPI Error", message); } } } - bool is_dlc_unlocked(AppId_t app_id, AppId_t dlc_id, const Function& original_function) { - const auto app_id_str = std::to_string(app_id); - const auto dlc_id_str = std::to_string(dlc_id); + Vector get_extra_dlcs(AppId_t app_id) { + return DLC::get_dlcs_from_apps(instance.extra_dlcs, app_id); + } + bool is_dlc_unlocked(AppId_t app_id, AppId_t dlc_id, const Function& original_function) { auto status = instance.default_app_status; + const auto app_id_str = std::to_string(app_id); if (instance.override_app_status.contains(app_id_str)) { status = instance.override_app_status[app_id_str]; } - if (instance.override_app_status.contains(dlc_id_str)) { - status = instance.override_app_status[dlc_id_str]; + const auto dlc_id_str = std::to_string(dlc_id); + if (instance.override_dlc_status.contains(dlc_id_str)) { + status = instance.override_dlc_status[dlc_id_str]; } bool is_unlocked; @@ -47,15 +56,18 @@ namespace smoke_api::config { is_unlocked = original_function(); break; } + LOG_TRACE( - "App ID: {}, DLC ID: {}, Status: {}, Original: {}, Is Unlocked: {}", + "App ID: {}, DLC ID: {}, Status: {}, Original: {}, Unlocked: {}", app_id_str, dlc_id_str, Json(status).dump(), original_function(), is_unlocked ) return is_unlocked; } - Vector get_extra_dlcs(AppId_t app_id) { - return DLC::get_dlcs_from_apps(instance.extra_dlcs, app_id); + DLL_EXPORT(void) ReloadConfig() { + LOG_INFO("Reloading config") + + init(); } } diff --git a/src/smoke_api/config.hpp b/src/smoke_api/config.hpp index e7f9fcd..f12fe28 100644 --- a/src/smoke_api/config.hpp +++ b/src/smoke_api/config.hpp @@ -25,6 +25,7 @@ namespace smoke_api::config { bool unlock_family_sharing = true; AppStatus default_app_status = AppStatus::UNLOCKED; Map override_app_status; + Map override_dlc_status; AppDlcNameMap extra_dlcs; bool auto_inject_inventory = true; Vector extra_inventory_items; @@ -38,6 +39,7 @@ namespace smoke_api::config { unlock_family_sharing, default_app_status, override_app_status, + override_dlc_status, extra_dlcs, auto_inject_inventory, extra_inventory_items, @@ -49,7 +51,7 @@ namespace smoke_api::config { void init(); - bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const Function& original_function); - Vector get_extra_dlcs(AppId_t app_id); + + bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const Function& original_function); } diff --git a/src/smoke_api/smoke_api.cpp b/src/smoke_api/smoke_api.cpp index 700b629..9e56528 100644 --- a/src/smoke_api/smoke_api.cpp +++ b/src/smoke_api/smoke_api.cpp @@ -128,4 +128,5 @@ namespace smoke_api { LOG_ERROR("Shutdown error: {}", ex.what()) } } + } diff --git a/src/steam_api_exports/steam_api_exports.hpp b/src/steam_api_exports/steam_api_exports.hpp index 175d533..60e1176 100644 --- a/src/steam_api_exports/steam_api_exports.hpp +++ b/src/steam_api_exports/steam_api_exports.hpp @@ -3,26 +3,27 @@ #include // Flat -DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps*, AppId_t); -DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps*, AppId_t); -DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps*); -DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(ISteamApps*, int, AppId_t*, bool*, char*, int); -DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp(ISteamUser*, CSteamID, AppId_t); -DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(ISteamClient*, HSteamUser, HSteamPipe, const char*); -DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(ISteamInventory*, SteamInventoryResult_t); -DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems( - ISteamInventory*, SteamInventoryResult_t, SteamItemDetails_t*, uint32_t* -); +DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void*, AppId_t); +DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void*, AppId_t); +DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(void*); +DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(void*, int, AppId_t*, bool*, char*, int); + +DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(void*, HSteamUser, HSteamPipe, const char*); + +DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(void*, SteamInventoryResult_t); +DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(void*, SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*); DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty( - ISteamInventory*, SteamInventoryResult_t, uint32_t, const char*, char*, uint32_t* + void*, SteamInventoryResult_t, uint32_t, const char*, char*, uint32_t* ); -DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(ISteamInventory*, SteamInventoryResult_t, CSteamID); -DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(ISteamInventory*, SteamInventoryResult_t*); +DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(void*, SteamInventoryResult_t, CSteamID); +DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(void*, SteamInventoryResult_t*); DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID( - ISteamInventory*, SteamInventoryResult_t*, const SteamItemInstanceID_t*, uint32_t + void*, SteamInventoryResult_t*, const SteamItemInstanceID_t*, uint32_t ); -DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(ISteamInventory*, SteamInventoryResult_t, void*, uint32_t*); -DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(ISteamInventory*, SteamItemDef_t*, uint32_t*); +DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(void*, SteamInventoryResult_t, void*, uint32_t*); +DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(void*, SteamItemDef_t*, uint32_t*); + +DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp(void*, CSteamID, AppId_t); // Internal DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser, const char*); diff --git a/src/steam_api_exports/steam_api_flat.cpp b/src/steam_api_exports/steam_api_flat.cpp index e5c225a..f173c59 100644 --- a/src/steam_api_exports/steam_api_flat.cpp +++ b/src/steam_api_exports/steam_api_flat.cpp @@ -3,30 +3,31 @@ #include #include #include +#include // ISteamApps -DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps* self, AppId_t appID) { +DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, AppId_t dlcID) { return steam_apps::IsDlcUnlocked( - __func__, 0, appID, [&]() { + __func__, 0, dlcID, [&]() { GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsSubscribedApp) - return SteamAPI_ISteamApps_BIsSubscribedApp_o(self, appID); + return SteamAPI_ISteamApps_BIsSubscribedApp_o(self, dlcID); } ); } -DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps* self, AppId_t appID) { +DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void* self, AppId_t dlcID) { return steam_apps::IsDlcUnlocked( - __func__, 0, appID, [&]() { + __func__, 0, dlcID, [&]() { GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsDlcInstalled) - return SteamAPI_ISteamApps_BIsDlcInstalled_o(self, appID); + return SteamAPI_ISteamApps_BIsDlcInstalled_o(self, dlcID); } ); } -DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps* self) { +DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(void* self) { return steam_apps::GetDLCCount( __func__, 0, [&]() { GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_GetDLCCount) @@ -37,7 +38,7 @@ DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps* self) { } DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex( - ISteamApps* self, + void* self, int iDLC, AppId_t* pDlcID, bool* pbAvailable, @@ -59,26 +60,10 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex( ); } -// ISteamUser - -DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp( - ISteamUser* self, - CSteamID steamID, - AppId_t appID -) { - return steam_user::UserHasLicenseForApp( - __func__, appID, [&]() { - GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamUser_UserHasLicenseForApp) - - return SteamAPI_ISteamUser_UserHasLicenseForApp_o(self, steamID, appID); - } - ); -} - // ISteamClient DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface( - ISteamClient* self, + void* self, HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion @@ -95,7 +80,7 @@ DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface( // ISteamInventory DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus( - ISteamInventory* self, + void* self, SteamInventoryResult_t resultHandle ) { return steam_inventory::GetResultStatus( @@ -108,7 +93,7 @@ DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems( - ISteamInventory* self, + void* self, SteamInventoryResult_t resultHandle, SteamItemDetails_t* pOutItemsArray, uint32_t* punOutItemsArraySize @@ -129,7 +114,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty( - ISteamInventory* self, + void* self, SteamInventoryResult_t resultHandle, uint32_t unItemIndex, const char* pchPropertyName, @@ -148,7 +133,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID( - ISteamInventory* self, + void* self, SteamInventoryResult_t resultHandle, CSteamID steamIDExpected ) { @@ -162,7 +147,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems( - ISteamInventory* self, + void* self, SteamInventoryResult_t* pResultHandle ) { return steam_inventory::GetAllItems( @@ -175,7 +160,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID( - ISteamInventory* self, + void* self, SteamInventoryResult_t* pResultHandle, const SteamItemInstanceID_t* pInstanceIDs, uint32_t unCountInstanceIDs @@ -190,7 +175,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult( - ISteamInventory* self, + void* self, SteamInventoryResult_t resultHandle, void* pOutBuffer, uint32_t* punOutBufferSize @@ -205,7 +190,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult( } DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs( - ISteamInventory* self, + void* self, SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize ) { @@ -217,3 +202,19 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs( } ); } + +// ISteamUser + +DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp( + void* self, + CSteamID steamID, + AppId_t dlcID +) { + return steam_user::UserHasLicenseForApp( + __func__, steam_impl::get_app_id_or_throw(), dlcID, [&]() { + GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamUser_UserHasLicenseForApp) + + return SteamAPI_ISteamUser_UserHasLicenseForApp_o(self, steamID, dlcID); + } + ); +} diff --git a/src/steam_api_virtuals/isteamuser.cpp b/src/steam_api_virtuals/isteamuser.cpp index e6eda64..c317452 100644 --- a/src/steam_api_virtuals/isteamuser.cpp +++ b/src/steam_api_virtuals/isteamuser.cpp @@ -1,12 +1,13 @@ #include #include +#include -VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t appID)) { +VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t dlcID)) { return steam_user::UserHasLicenseForApp( - __func__, appID, [&]() { + __func__, steam_impl::get_app_id_or_throw(), dlcID, [&]() { GET_ORIGINAL_HOOKED_FUNCTION(ISteamUser_UserHasLicenseForApp) - return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, appID)); + return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, dlcID)); } ); } diff --git a/src/steam_impl/steam_apps.cpp b/src/steam_impl/steam_apps.cpp index f1cfe96..d7acbfb 100644 --- a/src/steam_impl/steam_apps.cpp +++ b/src/steam_impl/steam_apps.cpp @@ -193,4 +193,5 @@ namespace steam_apps { return false; } } + } diff --git a/src/steam_impl/steam_inventory.cpp b/src/steam_impl/steam_inventory.cpp index 02c70d9..233793d 100644 --- a/src/steam_impl/steam_inventory.cpp +++ b/src/steam_impl/steam_inventory.cpp @@ -16,7 +16,6 @@ namespace steam_inventory { return status; } - // TODO: investigate if we can get app id in koalageddon mode bool GetResultItems( const String& function_name, const SteamInventoryResult_t resultHandle, diff --git a/src/steam_impl/steam_user.cpp b/src/steam_impl/steam_user.cpp index 3f68320..cbadc41 100644 --- a/src/steam_impl/steam_user.cpp +++ b/src/steam_impl/steam_user.cpp @@ -6,23 +6,24 @@ namespace steam_user { EUserHasLicenseForAppResult UserHasLicenseForApp( const String& function_name, - AppId_t appID, + AppId_t appId, + AppId_t dlcId, const Function& original_function ) { const auto result = original_function(); if (result == k_EUserHasLicenseResultNoAuth) { - LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, appID) + LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, dlcId) return result; } const auto has_license = smoke_api::config::is_dlc_unlocked( - 0, appID, [&]() { + appId, dlcId, [&]() { return result == k_EUserHasLicenseResultHasLicense; } ); - LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, appID, has_license) + LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, dlcId, has_license) return has_license ? k_EUserHasLicenseResultHasLicense diff --git a/src/steam_impl/steam_user.hpp b/src/steam_impl/steam_user.hpp index 247ad7c..12c33cc 100644 --- a/src/steam_impl/steam_user.hpp +++ b/src/steam_impl/steam_user.hpp @@ -1,13 +1,13 @@ #pragma once #include -#include namespace steam_user { EUserHasLicenseForAppResult UserHasLicenseForApp( const String& function_name, - AppId_t appID, + AppId_t appId, + AppId_t dlcId, const Function& original_function );