Added ISteamHTTP

This commit is contained in:
acidicoala
2025-08-27 20:42:08 +05:00
parent 9f51349517
commit dfbd7d00d9
32 changed files with 737 additions and 783 deletions

View File

@@ -4,7 +4,7 @@ on: push
jobs: jobs:
ci: ci:
name: CI name: CI
uses: acidicoala/KoalaBox/.github/workflows/build-and-package.yml@a053502132e51e936820f27b7c99316fdb62b3e4 uses: acidicoala/KoalaBox/.github/workflows/build-and-package.yml@50dba8cafc7ea9523f73be038c80f1eacd1b4f8c
permissions: permissions:
contents: write contents: write
with: with:

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.24) cmake_minimum_required(VERSION 3.24)
project(SmokeAPI VERSION 3.0.0) project(SmokeAPI VERSION 3.1.0)
include(KoalaBox/cmake/KoalaBox.cmake) include(KoalaBox/cmake/KoalaBox.cmake)
@@ -16,6 +16,8 @@ configure_build_config(extra_build_config)
set(SMOKE_API_STATIC_SOURCES set(SMOKE_API_STATIC_SOURCES
static/smoke_api/interfaces/steam_apps.hpp static/smoke_api/interfaces/steam_apps.hpp
static/smoke_api/interfaces/steam_apps.cpp static/smoke_api/interfaces/steam_apps.cpp
static/smoke_api/interfaces/steam_http.hpp
static/smoke_api/interfaces/steam_http.cpp
static/smoke_api/interfaces/steam_inventory.hpp static/smoke_api/interfaces/steam_inventory.hpp
static/smoke_api/interfaces/steam_inventory.cpp static/smoke_api/interfaces/steam_inventory.cpp
static/smoke_api/interfaces/steam_user.hpp static/smoke_api/interfaces/steam_user.hpp
@@ -35,12 +37,11 @@ set(SMOKE_API_SOURCES
${SMOKE_API_STATIC_SOURCES} ${SMOKE_API_STATIC_SOURCES}
src/steam_api/exports/steam_api.cpp src/steam_api/exports/steam_api.cpp
src/steam_api/exports/steam_api.hpp src/steam_api/exports/steam_api.hpp
src/steam_api/exports/steam_api_flat.cpp
src/steam_api/exports/steam_api_internal.cpp
src/steam_api/exports/steam_api_unversioned.cpp src/steam_api/exports/steam_api_unversioned.cpp
src/steam_api/virtuals/isteamapps.cpp src/steam_api/virtuals/isteamapps.cpp
src/steam_api/virtuals/isteamclient.cpp src/steam_api/virtuals/isteamclient.cpp
src/steam_api/virtuals/isteamgameserver.cpp src/steam_api/virtuals/isteamgameserver.cpp
src/steam_api/virtuals/isteamhttp.cpp
src/steam_api/virtuals/isteaminventory.cpp src/steam_api/virtuals/isteaminventory.cpp
src/steam_api/virtuals/isteamuser.cpp src/steam_api/virtuals/isteamuser.cpp
src/steam_api/virtuals/steam_api_virtuals.hpp src/steam_api/virtuals/steam_api_virtuals.hpp
@@ -48,7 +49,7 @@ set(SMOKE_API_SOURCES
src/steam_api/steam_client.cpp src/steam_api/steam_client.cpp
src/steam_api/steam_interface.cpp src/steam_api/steam_interface.cpp
src/steam_api/steam_interface.hpp src/steam_api/steam_interface.hpp
src/steamclient.cpp src/steamclient/steamclient.cpp
src/main.cpp src/main.cpp
src/smoke_api.cpp src/smoke_api.cpp
src/smoke_api.hpp src/smoke_api.hpp
@@ -81,7 +82,8 @@ configure_version_resource(
) )
target_include_directories(SmokeAPI PRIVATE target_include_directories(SmokeAPI PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_BINARY_DIR}") "${CMAKE_CURRENT_BINARY_DIR}"
)
## https://github.com/batterycenter/embed ## https://github.com/batterycenter/embed
CPMAddPackage( CPMAddPackage(

View File

@@ -114,6 +114,7 @@ To use it, simply place it next to the SmokeAPI DLL.
It will be read upon each launch of the game. It will be read upon each launch of the game.
In the absence of the config file, default values specified below will be used. In the absence of the config file, default values specified below will be used.
The configuration file is expected to conform to the JSON standard. The configuration file is expected to conform to the JSON standard.
All options within the config file are optional.
`logging`:: Toggles generation of a `SmokeAPI.log.log` file. `logging`:: Toggles generation of a `SmokeAPI.log.log` file.
+ +
@@ -121,6 +122,12 @@ The configuration file is expected to conform to the JSON standard.
Type::: Boolean Type::: Boolean
Default::: `false` Default::: `false`
`log_steam_http`:: Toggles logging of _SteamHTTP_ traffic.
+
[horizontal]
Type::: Boolean
Default::: `false`
`default_app_status`:: This option sets the default DLC unlocking behaviour. `default_app_status`:: This option sets the default DLC unlocking behaviour.
+ +
[horizontal] [horizontal]
@@ -184,8 +191,9 @@ Default::: `{}`
[source,json] [source,json]
---- ----
{ {
"$version": 3, "$version": 4,
"logging": true, "logging": true,
"log_steam_http": true,
"default_app_status": "unlocked", "default_app_status": "unlocked",
"override_app_status": { "override_app_status": {
"1234": "original", "1234": "original",
@@ -223,7 +231,7 @@ Some games that have a large number of DLCs begin ownership verification by quer
Once the game receives the list, it will go over each item and check the ownership. Once the game receives the list, it will go over each item and check the ownership.
The issue arises from the fact that response from Steamworks SDK may max out at 64, depending on how much unowned DLCs the user has. The issue arises from the fact that response from Steamworks SDK may max out at 64, depending on how much unowned DLCs the user has.
To alleviate this issue, SmokeAPI will make a web request to Steam API for a full list of DLCs, which works well most of the time. To alleviate this issue, SmokeAPI will make a web request to Steam API for a full list of DLCs, which works well most of the time.
Unfortunately, even the web API does not solve all of our problems, because it will only return DLCs that are available in Steam store. Unfortunately, even the web API does not solve all of our problems, because it will return only DLCs that are available in Steam store.
This means that DLCs without a dedicated store offer, such as pre-order DLCs will be left out. This means that DLCs without a dedicated store offer, such as pre-order DLCs will be left out.
That's where the `extra_dlcs` config option comes into play. That's where the `extra_dlcs` config option comes into play.
You can specify those missing DLC IDs there, and SmokeAPI will make them available to the game. You can specify those missing DLC IDs there, and SmokeAPI will make them available to the game.

View File

@@ -1,7 +1,8 @@
{ {
"$schema": "https://raw.githubusercontent.com/acidicoala/SmokeAPI/refs/tags/v3.0.0/res/SmokeAPI.schema.json", "$schema": "https://raw.githubusercontent.com/acidicoala/SmokeAPI/refs/tags/v3.1.0/res/SmokeAPI.schema.json",
"$version": 3, "$version": 4,
"logging": true, "logging": true,
"log_steam_http": true,
"default_app_status": "unlocked", "default_app_status": "unlocked",
"override_app_status": {}, "override_app_status": {},
"override_dlc_status": {}, "override_dlc_status": {},

View File

@@ -12,7 +12,7 @@
"$version": { "$version": {
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,
"default": 3, "default": 4,
"description": "A technical field reserved for tools like GUI config editors. Do not modify this value." "description": "A technical field reserved for tools like GUI config editors. Do not modify this value."
}, },
"logging": { "logging": {
@@ -20,6 +20,11 @@
"default": false, "default": false,
"description": "Toggles generation of a SmokeAPI.log.log file." "description": "Toggles generation of a SmokeAPI.log.log file."
}, },
"log_steam_http": {
"type": "boolean",
"default": false,
"description": "Toggles logging of SteamHTTP traffic"
},
"default_app_status": { "default_app_status": {
"description": "Sets the default DLC unlocking behaviour.", "description": "Sets the default DLC unlocking behaviour.",
"default": "unlocked", "default": "unlocked",
@@ -111,9 +116,10 @@
}, },
"examples": [ "examples": [
{ {
"$schema": "https://raw.githubusercontent.com/acidicoala/SmokeAPI/refs/heads/master/res/SmokeAPI.schema.json", "$schema": "https://raw.githubusercontent.com/acidicoala/SmokeAPI/refs/tags/v3.0.0/res/SmokeAPI.schema.json",
"$version": 3, "$version": 4,
"logging": true, "logging": true,
"log_steam_http": true,
"default_app_status": "unlocked", "default_app_status": "unlocked",
"override_app_status": { "override_app_status": {
"1234": "original", "1234": "original",

View File

@@ -56,6 +56,9 @@ namespace {
} else if(kb::str::eq(library_name, STEAMAPI_DLL)) { } else if(kb::str::eq(library_name, STEAMAPI_DLL)) {
KB_HOOK_DETOUR_MODULE(SteamAPI_RestartAppIfNecessary, module_handle); KB_HOOK_DETOUR_MODULE(SteamAPI_RestartAppIfNecessary, module_handle);
KB_HOOK_DETOUR_MODULE(SteamAPI_Shutdown, module_handle); KB_HOOK_DETOUR_MODULE(SteamAPI_Shutdown, module_handle);
// Note: It is not necessary to hook flat functions or interface accessors
// since the underlying interfaces will be hooked through steamclient.
} }
} }
); );

View File

@@ -4,6 +4,7 @@
constexpr auto STEAM_APPS = "STEAMAPPS_INTERFACE_VERSION"; constexpr auto STEAM_APPS = "STEAMAPPS_INTERFACE_VERSION";
constexpr auto STEAM_CLIENT = "SteamClient"; constexpr auto STEAM_CLIENT = "SteamClient";
constexpr auto STEAM_HTTP = "STEAMHTTP_INTERFACE_VERSION";
constexpr auto STEAM_USER = "SteamUser"; constexpr auto STEAM_USER = "SteamUser";
constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V"; constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V";
constexpr auto STEAM_GAME_SERVER = "SteamGameServer"; constexpr auto STEAM_GAME_SERVER = "SteamGameServer";

View File

@@ -1,321 +0,0 @@
#include <koalabox/logger.hpp>
#include "smoke_api.hpp"
#include "smoke_api/interfaces/steam_apps.hpp"
#include "smoke_api/interfaces/steam_inventory.hpp"
#include "smoke_api/interfaces/steam_user.hpp"
#include "steam_api/steam_client.hpp"
#include "steam_api/steam_interface.hpp"
// ISteamApps
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, const AppId_t dlcID) {
try {
return smoke_api::steam_apps::IsDlcUnlocked(
__func__,
steam_interface::get_app_id(),
dlcID,
MODULE_CALL_CLOSURE(SteamAPI_ISteamApps_BIsSubscribedApp, self, dlcID)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void* self, const AppId_t dlcID) {
try {
return smoke_api::steam_apps::IsDlcUnlocked(
__func__,
steam_interface::get_app_id(),
dlcID,
MODULE_CALL_CLOSURE(SteamAPI_ISteamApps_BIsDlcInstalled, self, dlcID)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(void* self) {
try {
return smoke_api::steam_apps::GetDLCCount(
__func__,
steam_interface::get_app_id(),
MODULE_CALL_CLOSURE(SteamAPI_ISteamApps_GetDLCCount, self)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return 0;
}
}
DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(
void* self,
const int iDLC,
AppId_t* pDlcID,
bool* pbAvailable,
char* pchName,
const int cchNameBufferSize
) {
try {
return smoke_api::steam_apps::GetDLCDataByIndex(
__func__,
steam_interface::get_app_id(),
iDLC,
pDlcID,
pbAvailable,
pchName,
cchNameBufferSize,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamApps_BGetDLCDataByIndex,
self,
iDLC,
pDlcID,
pbAvailable,
pchName,
cchNameBufferSize
),
[&](const AppId_t dlc_id) {
return SteamAPI_ISteamApps_BIsDlcInstalled(self, dlc_id);
}
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
// ISteamClient
DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
void* self,
const HSteamUser hSteamUser,
const HSteamPipe hSteamPipe,
const char* pchVersion
) {
try {
return steam_client::GetGenericInterface(
__func__,
pchVersion,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamClient_GetISteamGenericInterface,
self,
hSteamUser,
hSteamPipe,
pchVersion
)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return nullptr;
}
}
// ISteamInventory
DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
void* self,
const SteamInventoryResult_t resultHandle
) {
return smoke_api::steam_inventory::GetResultStatus(
__func__,
resultHandle,
MODULE_CALL_CLOSURE(SteamAPI_ISteamInventory_GetResultStatus, self, resultHandle)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(
void* self,
SteamItemDef_t* pItemDefIDs,
uint32_t* punItemDefIDsArraySize
) {
return smoke_api::steam_inventory::GetItemDefinitionIDs(
__func__,
pItemDefIDs,
punItemDefIDsArraySize,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_GetItemDefinitionIDs,
self,
pItemDefIDs,
punItemDefIDsArraySize
)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
void* self,
const SteamInventoryResult_t resultHandle,
SteamItemDetails_t* pOutItemsArray,
uint32_t* punOutItemsArraySize
) {
return smoke_api::steam_inventory::GetResultItems(
__func__,
resultHandle,
pOutItemsArray,
punOutItemsArraySize,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_GetResultItems,
self,
resultHandle,
pOutItemsArray,
punOutItemsArraySize
),
[&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) {
MODULE_CALL(
SteamAPI_ISteamInventory_GetItemDefinitionIDs,
self,
pItemDefIDs,
punItemDefIDsArraySize
);
}
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
void* self,
const SteamInventoryResult_t resultHandle,
const uint32_t unItemIndex,
const char* pchPropertyName,
char* pchValueBuffer,
uint32_t* punValueBufferSizeOut
) {
return smoke_api::steam_inventory::GetResultItemProperty(
__func__,
resultHandle,
unItemIndex,
pchPropertyName,
pchValueBuffer,
punValueBufferSizeOut,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_GetResultItemProperty,
self,
resultHandle,
unItemIndex,
pchPropertyName,
pchValueBuffer,
punValueBufferSizeOut
)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
void* self,
const SteamInventoryResult_t resultHandle,
const CSteamID steamIDExpected
) {
return smoke_api::steam_inventory::CheckResultSteamID(
__func__,
resultHandle,
steamIDExpected,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_CheckResultSteamID,
self,
resultHandle,
steamIDExpected
)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
void* self,
SteamInventoryResult_t* pResultHandle
) {
return smoke_api::steam_inventory::GetAllItems(
__func__,
pResultHandle,
MODULE_CALL_CLOSURE(SteamAPI_ISteamInventory_GetAllItems, self, pResultHandle)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
void* self,
SteamInventoryResult_t* pResultHandle,
const SteamItemInstanceID_t* pInstanceIDs,
const uint32_t unCountInstanceIDs
) {
return smoke_api::steam_inventory::GetItemsByID(
__func__,
pResultHandle,
pInstanceIDs,
unCountInstanceIDs,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_GetItemsByID,
self,
pResultHandle,
pInstanceIDs,
unCountInstanceIDs
)
);
}
DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
void* self,
const SteamInventoryResult_t resultHandle,
void* pOutBuffer,
uint32_t* punOutBufferSize
) {
return smoke_api::steam_inventory::SerializeResult(
__func__,
resultHandle,
pOutBuffer,
punOutBufferSize,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamInventory_SerializeResult,
self,
resultHandle,
pOutBuffer,
punOutBufferSize
)
);
}
// ISteamUser
DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp(
void* self,
const CSteamID steamID,
const AppId_t dlcID
) {
try {
return smoke_api::steam_user::UserHasLicenseForApp(
__func__,
steam_interface::get_app_id(),
dlcID,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamUser_UserHasLicenseForApp,
self,
steamID,
dlcID
)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return k_EUserHasLicenseResultDoesNotHaveLicense;
}
}
// ISteamGameServer
DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamGameServer_UserHasLicenseForApp(
void* self,
const CSteamID steamID,
const AppId_t dlcID
) {
try {
return smoke_api::steam_user::UserHasLicenseForApp(
__func__,
steam_interface::get_app_id(),
dlcID,
MODULE_CALL_CLOSURE(
SteamAPI_ISteamGameServer_UserHasLicenseForApp,
self,
steamID,
dlcID
)
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return k_EUserHasLicenseResultDoesNotHaveLicense;
}
}

View File

@@ -1,22 +0,0 @@
#include "smoke_api.hpp"
#include "smoke_api/types.hpp"
#include "steam_api/steam_client.hpp"
DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(
const HSteamUser hSteamUser,
const char* version
) {
return steam_client::GetGenericInterface(
__func__,
version,
MODULE_CALL_CLOSURE(SteamInternal_FindOrCreateUserInterface, hSteamUser, version)
);
}
DLL_EXPORT(void*) SteamInternal_CreateInterface(const char* version) {
return steam_client::GetGenericInterface(
__func__,
version,
MODULE_CALL_CLOSURE(SteamInternal_CreateInterface, version)
);
}

View File

@@ -22,10 +22,14 @@ namespace {
if(not version_map.contains(version_prefix)) { if(not version_map.contains(version_prefix)) {
try { try {
const std::string rdata = kb::win::get_pe_section_data_or_throw( const auto section = kb::win::get_pe_section_or_throw(
smoke_api::steamapi_module, smoke_api::steamapi_module,
".rdata" ".rdata"
); );
const auto rdata = std::string(
reinterpret_cast<const char*>(section.start_address),
section.size
);
const std::regex regex(version_prefix + "\\d{3}"); const std::regex regex(version_prefix + "\\d{3}");
if(std::smatch match; std::regex_search(rdata, match, regex)) { if(std::smatch match; std::regex_search(rdata, match, regex)) {
@@ -50,15 +54,7 @@ namespace {
} }
} }
DLL_EXPORT(void*) SteamClient() { // TODO: Do we really need to proxy them?
static auto version = get_versioned_interface(STEAM_CLIENT, "006");
return steam_client::GetGenericInterface(
__func__,
version,
MODULE_CALL_CLOSURE(SteamClient)
);
}
DLL_EXPORT(void*) SteamApps() { DLL_EXPORT(void*) SteamApps() {
static auto version = get_versioned_interface(STEAM_APPS, "002"); static auto version = get_versioned_interface(STEAM_APPS, "002");
@@ -70,13 +66,23 @@ DLL_EXPORT(void*) SteamApps() {
); );
} }
DLL_EXPORT(void*) SteamUser() { DLL_EXPORT(void*) SteamClient() {
static auto version = get_versioned_interface(STEAM_USER, "012"); static auto version = get_versioned_interface(STEAM_CLIENT, "006");
return steam_client::GetGenericInterface( return steam_client::GetGenericInterface(
__func__, __func__,
version, version,
MODULE_CALL_CLOSURE(SteamUser) MODULE_CALL_CLOSURE(SteamClient)
);
}
DLL_EXPORT(void*) SteamHTTP() {
static auto version = get_versioned_interface(STEAM_HTTP, "003");
return steam_client::GetGenericInterface(
__func__,
version,
MODULE_CALL_CLOSURE(SteamHTTP)
); );
} }
@@ -89,3 +95,13 @@ DLL_EXPORT(void*) SteamInventory() {
MODULE_CALL_CLOSURE(SteamInventory) MODULE_CALL_CLOSURE(SteamInventory)
); );
} }
DLL_EXPORT(void*) SteamUser() {
static auto version = get_versioned_interface(STEAM_USER, "012");
return steam_client::GetGenericInterface(
__func__,
version,
MODULE_CALL_CLOSURE(SteamUser)
);
}

View File

@@ -7,13 +7,18 @@ namespace steam_client {
const std::string& function_name, const std::string& function_name,
const std::string& interface_version, const std::string& interface_version,
const std::function<void*()>& original_function const std::function<void*()>& original_function
) { ) noexcept {
auto* const interface = original_function(); try {
auto* const interface = original_function();
LOG_DEBUG("{} -> '{}' @ {}", function_name, interface_version, interface); LOG_DEBUG("{} -> '{}' @ {}", function_name, interface_version, interface);
steam_interface::hook_virtuals(interface, interface_version); steam_interface::hook_virtuals(interface, interface_version);
return interface; return interface;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: '{}' @ {}", function_name, interface_version, e.what());
return nullptr;
}
} }
} }

View File

@@ -7,5 +7,5 @@ namespace steam_client {
const std::string& function_name, const std::string& function_name,
const std::string& interface_version, const std::string& interface_version,
const std::function<void*()>& original_function const std::function<void*()>& original_function
); ) noexcept;
} }

View File

@@ -25,11 +25,11 @@ namespace {
std::map<std::string, interface_data> get_virtual_hook_map() { std::map<std::string, interface_data> get_virtual_hook_map() {
#define ENTRY(INTERFACE, FUNC) \ #define ENTRY(INTERFACE, FUNC) \
{ \ { \
#FUNC, { \ #FUNC, { \
#INTERFACE "_" #FUNC, reinterpret_cast<uintptr_t>(INTERFACE##_##FUNC) \ #INTERFACE "_" #FUNC, reinterpret_cast<uintptr_t>(INTERFACE##_##FUNC) \
} \ } \
} }
return { return {
{ {
@@ -56,6 +56,17 @@ namespace {
} }
} }
}, },
{
STEAM_HTTP,
interface_data{
.fallback_version = "STEAMHTTP_INTERFACE_VERSION003",
.entry_map = {
ENTRY(ISteamHTTP, GetHTTPResponseBodyData),
ENTRY(ISteamHTTP, GetHTTPStreamingResponseBodyData),
ENTRY(ISteamHTTP, SetHTTPRequestRawPostBody),
}
}
},
{ {
STEAM_USER, STEAM_USER,
interface_data{ interface_data{
@@ -129,7 +140,11 @@ namespace steam_interface {
static std::set<void*> processed_interfaces; static std::set<void*> processed_interfaces;
if(processed_interfaces.contains(interface)) { if(processed_interfaces.contains(interface)) {
LOG_DEBUG("Interface {} at {} has already been processed.", version_string, interface); LOG_DEBUG(
"Interface '{}' at {} has already been processed.",
version_string,
interface
);
return; return;
} }

View File

@@ -4,45 +4,30 @@
#include "steam_api/steam_interface.hpp" #include "steam_api/steam_interface.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp" #include "steam_api/virtuals/steam_api_virtuals.hpp"
VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(const AppId_t dlc_id)) { VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(const AppId_t dlc_id)) noexcept {
try { return smoke_api::steam_apps::IsDlcUnlocked(
return smoke_api::steam_apps::IsDlcUnlocked( __func__,
__func__, steam_interface::get_app_id(),
steam_interface::get_app_id(), dlc_id,
dlc_id, HOOKED_CALL_CLOSURE(ISteamApps_BIsSubscribedApp, ARGS(dlc_id))
HOOKED_CALL_CLOSURE(ISteamApps_BIsSubscribedApp, ARGS(dlc_id)) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
} }
VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(const AppId_t dlc_id)) { VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(const AppId_t dlc_id)) noexcept {
try { return smoke_api::steam_apps::IsDlcUnlocked(
return smoke_api::steam_apps::IsDlcUnlocked( __func__,
__func__, steam_interface::get_app_id(),
steam_interface::get_app_id(), dlc_id,
dlc_id, HOOKED_CALL_CLOSURE(ISteamApps_BIsDlcInstalled, ARGS(dlc_id))
HOOKED_CALL_CLOSURE(ISteamApps_BIsDlcInstalled, ARGS(dlc_id)) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
} }
VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) { VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) noexcept {
try { return smoke_api::steam_apps::GetDLCCount(
return smoke_api::steam_apps::GetDLCCount( __func__,
__func__, steam_interface::get_app_id(),
steam_interface::get_app_id(), HOOKED_CALL_CLOSURE(ISteamApps_GetDLCCount, ARGS())
HOOKED_CALL_CLOSURE(ISteamApps_GetDLCCount, ARGS()) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return 0;
}
} }
VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex( VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(
@@ -53,26 +38,22 @@ VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(
char* pchName, char* pchName,
const int cchNameBufferSize const int cchNameBufferSize
) )
) { ) noexcept {
try { return smoke_api::steam_apps::GetDLCDataByIndex(
return smoke_api::steam_apps::GetDLCDataByIndex( __func__,
__func__, steam_interface::get_app_id(),
steam_interface::get_app_id(), iDLC,
iDLC, p_dlc_id,
p_dlc_id, pbAvailable,
pbAvailable, pchName,
pchName, cchNameBufferSize,
cchNameBufferSize, HOOKED_CALL_CLOSURE(
HOOKED_CALL_CLOSURE( ISteamApps_BGetDLCDataByIndex,
ISteamApps_BGetDLCDataByIndex, ARGS(iDLC, p_dlc_id, pbAvailable, pchName, cchNameBufferSize)
ARGS(iDLC, p_dlc_id, pbAvailable, pchName, cchNameBufferSize) ),
), HOOKED_CALL_CLOSURE(
[&](const AppId_t dlc_id) { ISteamApps_BIsSubscribedApp,
return ISteamApps_BIsDlcInstalled(ARGS(dlc_id)); ARGS(*p_dlc_id)
} )
); );
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
} }

View File

@@ -9,17 +9,12 @@ VIRTUAL(void*) ISteamClient_GetISteamApps(
const HSteamPipe hSteamPipe, const HSteamPipe hSteamPipe,
const char* version const char* version
) )
) { ) noexcept {
try { return steam_client::GetGenericInterface(
return steam_client::GetGenericInterface( __func__,
__func__, version,
version, HOOKED_CALL_CLOSURE(ISteamClient_GetISteamApps, ARGS(hSteamUser, hSteamPipe, version))
HOOKED_CALL_CLOSURE(ISteamClient_GetISteamApps, ARGS(hSteamUser, hSteamPipe, version)) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return nullptr;
}
} }
VIRTUAL(void*) ISteamClient_GetISteamUser( VIRTUAL(void*) ISteamClient_GetISteamUser(
@@ -28,17 +23,12 @@ VIRTUAL(void*) ISteamClient_GetISteamUser(
const HSteamPipe hSteamPipe, const HSteamPipe hSteamPipe,
const char* version const char* version
) )
) { ) noexcept {
try { return steam_client::GetGenericInterface(
return steam_client::GetGenericInterface( __func__,
__func__, version,
version, HOOKED_CALL_CLOSURE(ISteamClient_GetISteamUser, ARGS(hSteamUser, hSteamPipe, version))
HOOKED_CALL_CLOSURE(ISteamClient_GetISteamUser, ARGS(hSteamUser, hSteamPipe, version)) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return nullptr;
}
} }
VIRTUAL(void*) ISteamClient_GetISteamGenericInterface( VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(
@@ -47,20 +37,15 @@ VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(
HSteamPipe hSteamPipe, HSteamPipe hSteamPipe,
const char* pchVersion const char* pchVersion
) )
) { ) noexcept {
try { return steam_client::GetGenericInterface(
return steam_client::GetGenericInterface( __func__,
__func__, pchVersion,
pchVersion, HOOKED_CALL_CLOSURE(
HOOKED_CALL_CLOSURE( ISteamClient_GetISteamGenericInterface,
ISteamClient_GetISteamGenericInterface, ARGS(hSteamUser, hSteamPipe, pchVersion)
ARGS(hSteamUser, hSteamPipe, pchVersion) )
) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return nullptr;
}
} }
VIRTUAL(void*) ISteamClient_GetISteamInventory( VIRTUAL(void*) ISteamClient_GetISteamInventory(
@@ -69,18 +54,13 @@ VIRTUAL(void*) ISteamClient_GetISteamInventory(
const HSteamPipe hSteamPipe, const HSteamPipe hSteamPipe,
const char* pchVersion const char* pchVersion
) )
) { ) noexcept {
try { return steam_client::GetGenericInterface(
return steam_client::GetGenericInterface( __func__,
__func__, pchVersion,
pchVersion, HOOKED_CALL_CLOSURE(
HOOKED_CALL_CLOSURE( ISteamClient_GetISteamInventory,
ISteamClient_GetISteamInventory, ARGS(hSteamUser, hSteamPipe, pchVersion)
ARGS(hSteamUser, hSteamPipe, pchVersion) )
) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return nullptr;
}
} }

View File

@@ -6,16 +6,11 @@
VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp( VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(
PARAMS(const CSteamID steamID, const AppId_t dlc_id) PARAMS(const CSteamID steamID, const AppId_t dlc_id)
) { ) noexcept {
try { return smoke_api::steam_user::UserHasLicenseForApp(
return smoke_api::steam_user::UserHasLicenseForApp( __func__,
__func__, steam_interface::get_app_id(),
steam_interface::get_app_id(), dlc_id,
dlc_id, HOOKED_CALL_CLOSURE(ISteamGameServer_UserHasLicenseForApp, ARGS(steamID, dlc_id))
HOOKED_CALL_CLOSURE(ISteamGameServer_UserHasLicenseForApp, ARGS(steamID, dlc_id)) );
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return k_EUserHasLicenseResultDoesNotHaveLicense;
}
} }

View File

@@ -0,0 +1,66 @@
#include <koalabox/logger.hpp>
#include "smoke_api/interfaces/steam_http.hpp"
#include "steam_api/steam_interface.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"
VIRTUAL(bool) ISteamHTTP_GetHTTPResponseBodyData(
PARAMS(
const HTTPRequestHandle hRequest,
const uint8_t* pBodyDataBuffer,
const uint32_t unBufferSize
)
) noexcept {
return smoke_api::steam_http::GetHTTPResponseBodyData(
__func__,
hRequest,
pBodyDataBuffer,
unBufferSize,
HOOKED_CALL_CLOSURE(
ISteamHTTP_GetHTTPResponseBodyData,
ARGS(hRequest, pBodyDataBuffer, unBufferSize)
)
);
}
VIRTUAL(bool) ISteamHTTP_GetHTTPStreamingResponseBodyData(
PARAMS(
const HTTPRequestHandle hRequest,
const uint32_t cOffset,
const uint8_t* pBodyDataBuffer,
const uint32_t unBufferSize
)
) noexcept {
return smoke_api::steam_http::GetHTTPStreamingResponseBodyData(
__func__,
hRequest,
cOffset,
pBodyDataBuffer,
unBufferSize,
HOOKED_CALL_CLOSURE(
ISteamHTTP_GetHTTPStreamingResponseBodyData,
ARGS(hRequest, cOffset, pBodyDataBuffer, unBufferSize)
)
);
}
VIRTUAL(bool) ISteamHTTP_SetHTTPRequestRawPostBody(
PARAMS(
const HTTPRequestHandle hRequest,
const char* pchContentType,
const uint8_t* pubBody,
const uint32_t unBodyLen
)
) noexcept {
return smoke_api::steam_http::SetHTTPRequestRawPostBody(
__func__,
hRequest,
pchContentType,
pubBody,
unBodyLen,
HOOKED_CALL_CLOSURE(
ISteamHTTP_SetHTTPRequestRawPostBody,
ARGS(hRequest, pchContentType, pubBody, unBodyLen)
)
);
}

View File

@@ -3,7 +3,7 @@
VIRTUAL(EResult) ISteamInventory_GetResultStatus( VIRTUAL(EResult) ISteamInventory_GetResultStatus(
PARAMS(const SteamInventoryResult_t resultHandle) PARAMS(const SteamInventoryResult_t resultHandle)
) { ) noexcept {
return smoke_api::steam_inventory::GetResultStatus( return smoke_api::steam_inventory::GetResultStatus(
__func__, __func__,
resultHandle, resultHandle,
@@ -17,7 +17,7 @@ VIRTUAL(bool) ISteamInventory_GetResultItems(
SteamItemDetails_t* pOutItemsArray, SteamItemDetails_t* pOutItemsArray,
uint32_t* punOutItemsArraySize uint32_t* punOutItemsArraySize
) )
) { ) noexcept {
return smoke_api::steam_inventory::GetResultItems( return smoke_api::steam_inventory::GetResultItems(
__func__, __func__,
resultHandle, resultHandle,
@@ -44,7 +44,7 @@ VIRTUAL(bool) ISteamInventory_GetResultItemProperty(
char* pchValueBuffer, char* pchValueBuffer,
uint32_t* punValueBufferSizeOut uint32_t* punValueBufferSizeOut
) )
) { ) noexcept {
return smoke_api::steam_inventory::GetResultItemProperty( return smoke_api::steam_inventory::GetResultItemProperty(
__func__, __func__,
resultHandle, resultHandle,
@@ -65,7 +65,7 @@ VIRTUAL(bool) ISteamInventory_GetResultItemProperty(
); );
} }
VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) { VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) noexcept {
return smoke_api::steam_inventory::GetAllItems( return smoke_api::steam_inventory::GetAllItems(
__func__, __func__,
pResultHandle, pResultHandle,
@@ -79,7 +79,7 @@ VIRTUAL(bool) ISteamInventory_GetItemsByID(
const SteamItemInstanceID_t* pInstanceIDs, const SteamItemInstanceID_t* pInstanceIDs,
const uint32_t unCountInstanceIDs const uint32_t unCountInstanceIDs
) )
) { ) noexcept {
return smoke_api::steam_inventory::GetItemsByID( return smoke_api::steam_inventory::GetItemsByID(
__func__, __func__,
pResultHandle, pResultHandle,
@@ -98,7 +98,7 @@ VIRTUAL(bool) ISteamInventory_SerializeResult(
void* pOutBuffer, void* pOutBuffer,
uint32_t* punOutBufferSize uint32_t* punOutBufferSize
) )
) { ) noexcept {
return smoke_api::steam_inventory::SerializeResult( return smoke_api::steam_inventory::SerializeResult(
__func__, __func__,
resultHandle, resultHandle,
@@ -116,7 +116,7 @@ VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(
SteamItemDef_t*pItemDefIDs, SteamItemDef_t*pItemDefIDs,
uint32_t* punItemDefIDsArraySize uint32_t* punItemDefIDsArraySize
) )
) { ) noexcept {
return smoke_api::steam_inventory::GetItemDefinitionIDs( return smoke_api::steam_inventory::GetItemDefinitionIDs(
__func__, __func__,
pItemDefIDs, pItemDefIDs,
@@ -130,14 +130,11 @@ VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(
VIRTUAL(bool) ISteamInventory_CheckResultSteamID( VIRTUAL(bool) ISteamInventory_CheckResultSteamID(
PARAMS(const SteamInventoryResult_t resultHandle, CSteamID steamIDExpected) PARAMS(const SteamInventoryResult_t resultHandle, CSteamID steamIDExpected)
) { ) noexcept {
return smoke_api::steam_inventory::CheckResultSteamID( return smoke_api::steam_inventory::CheckResultSteamID(
__func__, __func__,
resultHandle, resultHandle,
steamIDExpected, steamIDExpected,
HOOKED_CALL_CLOSURE( HOOKED_CALL_CLOSURE(ISteamInventory_CheckResultSteamID, ARGS(resultHandle, steamIDExpected))
ISteamInventory_CheckResultSteamID,
ARGS(resultHandle, steamIDExpected)
)
); );
} }

View File

@@ -6,17 +6,11 @@
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp( VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(
PARAMS(const CSteamID steamID, const AppId_t dlc_id) PARAMS(const CSteamID steamID, const AppId_t dlc_id)
) { ) noexcept {
try { return smoke_api::steam_user::UserHasLicenseForApp(
static const auto app_id = steam_interface::get_app_id(); __func__,
return smoke_api::steam_user::UserHasLicenseForApp( steam_interface::get_app_id(),
__func__, dlc_id,
app_id, HOOKED_CALL_CLOSURE(ISteamUser_UserHasLicenseForApp, ARGS(steamID, dlc_id))
dlc_id, );
HOOKED_CALL_CLOSURE(ISteamUser_UserHasLicenseForApp, ARGS(steamID, dlc_id))
);
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return k_EUserHasLicenseResultDoesNotHaveLicense;
}
} }

View File

@@ -3,38 +3,60 @@
#include "smoke_api/types.hpp" #include "smoke_api/types.hpp"
// ISteamApps // ISteamApps
VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t)); VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t)) noexcept;
VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t)); VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t)) noexcept;
VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()); VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) noexcept;
VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(PARAMS(int, AppId_t*, bool*, char*, int)); VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(PARAMS(int, AppId_t*, bool*, char*, int)) noexcept;
// ISteamClient // ISteamClient
VIRTUAL(void*) ISteamClient_GetISteamApps(PARAMS(HSteamUser, HSteamPipe, const char*)); VIRTUAL(void*) ISteamClient_GetISteamApps(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept;
VIRTUAL(void*) ISteamClient_GetISteamUser(PARAMS(HSteamUser, HSteamPipe, const char*)); VIRTUAL(void*) ISteamClient_GetISteamUser(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept;
VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(PARAMS(HSteamUser, HSteamPipe, const char*)); VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(
VIRTUAL(void*) ISteamClient_GetISteamInventory(PARAMS(HSteamUser, HSteamPipe, const char*)); 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_GetHTTPStreamingResponseBodyData(
PARAMS(HTTPRequestHandle, uint32_t, const uint8_t*, uint32_t)
) noexcept;
VIRTUAL(bool) ISteamHTTP_SetHTTPRequestRawPostBody(
PARAMS(HTTPRequestHandle, const char*, const uint8_t*, uint32_t)
) noexcept;
// ISteamInventory // ISteamInventory
VIRTUAL(EResult) ISteamInventory_GetResultStatus(PARAMS(SteamInventoryResult_t)); VIRTUAL(EResult) ISteamInventory_GetResultStatus(PARAMS(SteamInventoryResult_t)) noexcept;
VIRTUAL(bool) ISteamInventory_GetResultItems( VIRTUAL(bool) ISteamInventory_GetResultItems(
PARAMS(SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*) // @formatter:off PARAMS(SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*) // @formatter:off
); // @formatter:on ) noexcept; // @formatter:on
VIRTUAL(bool) ISteamInventory_GetResultItemProperty( VIRTUAL(bool) ISteamInventory_GetResultItemProperty(
PARAMS(SteamInventoryResult_t, uint32_t, const char*, char*, uint32_t*) // @formatter:off PARAMS(SteamInventoryResult_t, uint32_t, const char*, char*, uint32_t*) // @formatter:off
); // @formatter:on ) noexcept; // @formatter:on
VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t*)); VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t*)) noexcept;
VIRTUAL(bool) ISteamInventory_GetItemsByID( VIRTUAL(bool) ISteamInventory_GetItemsByID(
PARAMS(SteamInventoryResult_t*, const SteamItemInstanceID_t*, uint32_t) PARAMS(SteamInventoryResult_t*, const SteamItemInstanceID_t*, uint32_t)
); ) noexcept;
VIRTUAL(bool) ISteamInventory_SerializeResult(PARAMS(SteamInventoryResult_t, void*, uint32_t*)); VIRTUAL(bool) ISteamInventory_SerializeResult(
VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint32_t*)); PARAMS(SteamInventoryResult_t, void*, uint32_t*)
VIRTUAL(bool) ISteamInventory_CheckResultSteamID(PARAMS(SteamInventoryResult_t, CSteamID));
) noexcept;
VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint32_t*)) noexcept;
VIRTUAL(bool) ISteamInventory_CheckResultSteamID(PARAMS(SteamInventoryResult_t, CSteamID)) noexcept;
// ISteamUser // ISteamUser
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t)); VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(
PARAMS(CSteamID, AppId_t)
) noexcept;
// ISteamGameServer // ISteamGameServer
VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp( VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(
PARAMS(CSteamID, AppId_t) PARAMS(CSteamID, AppId_t)
); ) noexcept;

View File

@@ -1,8 +1,8 @@
#include "smoke_api/steamclient/steamclient.hpp" #include "smoke_api/steamclient/steamclient.hpp"
#include "smoke_api.hpp" #include "../smoke_api.hpp"
#include "smoke_api/types.hpp" #include "smoke_api/types.hpp"
#include "steam_api/steam_client.hpp" #include "../steam_api/steam_client.hpp"
/** /**
* SmokeAPI implementation * SmokeAPI implementation

View File

@@ -23,8 +23,9 @@ namespace smoke_api::config {
) )
struct Config { struct Config {
uint32_t $version = 3; uint32_t $version = 4;
bool logging = false; bool logging = false;
bool log_steam_http = false;
AppStatus default_app_status = AppStatus::UNLOCKED; AppStatus default_app_status = AppStatus::UNLOCKED;
std::map<std::string, AppStatus> override_app_status; std::map<std::string, AppStatus> override_app_status;
std::map<std::string, AppStatus> override_dlc_status; std::map<std::string, AppStatus> override_dlc_status;
@@ -32,7 +33,7 @@ namespace smoke_api::config {
bool auto_inject_inventory = true; bool auto_inject_inventory = true;
std::vector<uint32_t> extra_inventory_items; std::vector<uint32_t> extra_inventory_items;
NLOHMANN_DEFINE_TYPE_INTRUSIVE( NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
Config, Config,
$version, $version,
logging, logging,

View File

@@ -85,7 +85,7 @@ namespace smoke_api::steam_apps {
const AppId_t app_id, const AppId_t app_id,
const AppId_t dlc_id, const AppId_t dlc_id,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
try { try {
const auto unlocked = config::is_dlc_unlocked( const auto unlocked = config::is_dlc_unlocked(
app_id, app_id,
@@ -103,7 +103,7 @@ namespace smoke_api::steam_apps {
return unlocked; return unlocked;
} catch(const std::exception& e) { } catch(const std::exception& e) {
LOG_ERROR("Uncaught exception: {}", e.what()); LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what());
return false; return false;
} }
} }
@@ -112,7 +112,7 @@ namespace smoke_api::steam_apps {
const std::string& function_name, const std::string& function_name,
const AppId_t app_id, const AppId_t app_id,
const std::function<int()>& original_function const std::function<int()>& original_function
) { ) noexcept {
try { try {
const auto total_count = [&](int count) { const auto total_count = [&](int count) {
LOG_INFO("{} -> Responding with DLC count: {}", function_name, count); LOG_INFO("{} -> Responding with DLC count: {}", function_name, count);
@@ -139,7 +139,7 @@ namespace smoke_api::steam_apps {
return total_count(static_cast<int>(app_dlcs[app_id].size())); return total_count(static_cast<int>(app_dlcs[app_id].size()));
} catch(const std::exception& e) { } catch(const std::exception& e) {
LOG_ERROR("Uncaught exception: {}", function_name, e.what()); LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what());
return 0; return 0;
} }
} }
@@ -153,8 +153,8 @@ namespace smoke_api::steam_apps {
char* pchName, char* pchName,
const int cchNameBufferSize, const int cchNameBufferSize,
const std::function<bool()>& original_function, const std::function<bool()>& original_function,
const std::function<bool(AppId_t)>& is_originally_unlocked const std::function<bool()>& is_originally_unlocked
) { ) noexcept {
try { try {
LOG_DEBUG("{} -> {}index: {:>3}", function_name, get_app_id_log(app_id), iDLC); LOG_DEBUG("{} -> {}index: {:>3}", function_name, get_app_id_log(app_id), iDLC);
@@ -174,13 +174,7 @@ namespace smoke_api::steam_apps {
const auto output_dlc = [&](const DLC& dlc) { const auto output_dlc = [&](const DLC& dlc) {
// Fill the output pointers // Fill the output pointers
*pDlcId = dlc.get_id(); *pDlcId = dlc.get_id();
*pbAvailable = config::is_dlc_unlocked( *pbAvailable = config::is_dlc_unlocked(app_id, *pDlcId, is_originally_unlocked);
app_id,
*pDlcId,
[&] {
return is_originally_unlocked(*pDlcId);
}
);
auto name = dlc.get_name(); auto name = dlc.get_name();
name = name.substr(0, cchNameBufferSize + 1); name = name.substr(0, cchNameBufferSize + 1);

View File

@@ -2,19 +2,21 @@
#include "smoke_api/types.hpp" #include "smoke_api/types.hpp"
// TODO: Make them all noexcept
namespace smoke_api::steam_apps { namespace smoke_api::steam_apps {
bool IsDlcUnlocked( bool IsDlcUnlocked(
const std::string& function_name, const std::string& function_name,
AppId_t app_id, AppId_t app_id,
AppId_t dlc_id, AppId_t dlc_id,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
int GetDLCCount( int GetDLCCount(
const std::string& function_name, const std::string& function_name,
AppId_t app_id, AppId_t app_id,
const std::function<int()>& original_function const std::function<int()>& original_function
); ) noexcept;
bool GetDLCDataByIndex( bool GetDLCDataByIndex(
const std::string& function_name, const std::string& function_name,
@@ -25,6 +27,6 @@ namespace smoke_api::steam_apps {
char* pchName, char* pchName,
int cchNameBufferSize, int cchNameBufferSize,
const std::function<bool()>& original_function, const std::function<bool()>& original_function,
const std::function<bool(AppId_t)>& is_originally_unlocked const std::function<bool()>& is_originally_unlocked
); ) noexcept;
} }

View File

@@ -0,0 +1,115 @@
#include <koalabox/logger.hpp>
#include "smoke_api/interfaces/steam_http.hpp"
#include "smoke_api/config.hpp"
namespace smoke_api::steam_http {
bool GetHTTPResponseBodyData(
const std::string& function_name,
const HTTPRequestHandle hRequest,
const uint8_t* pBodyDataBuffer,
const uint32_t unBufferSize,
const std::function<bool()>& original_function
) noexcept {
try {
const auto result = original_function();
if(config::instance.log_steam_http) {
const std::string_view buffer =
pBodyDataBuffer && unBufferSize
? std::string_view(
reinterpret_cast<const char*>(pBodyDataBuffer),
unBufferSize
)
: "";
LOG_INFO(
"{} -> handle: {}, size: {}, buffer:\n{}",
function_name,
hRequest,
unBufferSize,
buffer
);
}
return result;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
bool GetHTTPStreamingResponseBodyData(
const std::string& function_name,
const HTTPRequestHandle hRequest,
const uint32_t cOffset,
const uint8_t* pBodyDataBuffer,
const uint32_t unBufferSize,
const std::function<bool()>& original_function
) noexcept {
try {
const auto result = original_function();
if(config::instance.log_steam_http) {
const std::string_view buffer =
pBodyDataBuffer && unBufferSize
? std::string_view(
reinterpret_cast<const char*>(pBodyDataBuffer),
unBufferSize
)
: "";
LOG_INFO(
"{} -> handle: {}, offset: {}, size: {}, buffer:\n{}",
function_name,
hRequest,
cOffset,
unBufferSize,
buffer
);
}
return result;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
bool SetHTTPRequestRawPostBody(
const std::string& function_name,
const HTTPRequestHandle hRequest,
const char* pchContentType,
const uint8_t* pubBody,
const uint32_t unBodyLen,
const std::function<bool()>& original_function
) noexcept {
try {
const auto result = original_function();
if(config::instance.log_steam_http) {
const std::string_view content_type =
pchContentType ? pchContentType : "smoke_api::N/A";
const std::string_view buffer =
pubBody && unBodyLen
? std::string_view(reinterpret_cast<const char*>(pubBody), unBodyLen)
: "";
LOG_INFO(
"{} -> handle: {}, content-type: {}, size: {}, buffer:\n{}",
function_name,
hRequest,
content_type,
unBodyLen,
buffer
);
}
return result;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", __func__, e.what());
return false;
}
}
}

View File

@@ -0,0 +1,31 @@
#pragma once
#include "smoke_api/types.hpp"
namespace smoke_api::steam_http {
bool GetHTTPResponseBodyData(
const std::string& function_name,
HTTPRequestHandle hRequest,
const uint8_t* pBodyDataBuffer,
uint32_t unBufferSize,
const std::function<bool()>& original_function
) noexcept;
bool GetHTTPStreamingResponseBodyData(
const std::string& function_name,
HTTPRequestHandle hRequest,
uint32_t cOffset,
const uint8_t* pBodyDataBuffer,
uint32_t unBufferSize,
const std::function<bool()>& original_function
) noexcept;
bool SetHTTPRequestRawPostBody(
const std::string& function_name,
HTTPRequestHandle hRequest,
const char* pchContentType,
const uint8_t* pubBody,
uint32_t unBodyLen,
const std::function<bool()>& original_function
) noexcept;
}

View File

@@ -8,17 +8,22 @@ namespace smoke_api::steam_inventory {
const std::string& function_name, const std::string& function_name,
const SteamInventoryResult_t resultHandle, const SteamInventoryResult_t resultHandle,
const std::function<EResult()>& original_function const std::function<EResult()>& original_function
) { ) noexcept {
const auto status = original_function(); try {
const auto status = original_function();
LOG_DEBUG( LOG_DEBUG(
"{} -> handle: {}, status: {}", "{} -> handle: {}, status: {}",
function_name, function_name,
resultHandle, resultHandle,
static_cast<int>(status) static_cast<int>(status)
); );
return status; return status;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return EResult::k_EResultFail;
}
} }
bool GetResultItems( bool GetResultItems(
@@ -28,107 +33,112 @@ namespace smoke_api::steam_inventory {
uint32_t* punOutItemsArraySize, uint32_t* punOutItemsArraySize,
const std::function<bool()>& original_function, const std::function<bool()>& original_function,
const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids
) { ) noexcept {
static std::mutex section; try {
const std::lock_guard guard(section); static std::mutex section;
const std::lock_guard guard(section);
const auto success = original_function(); const auto success = original_function();
auto print_item = [](const std::string& tag, const SteamItemDetails_t& item) { auto print_item = [](const std::string& tag, const SteamItemDetails_t& item) {
LOG_DEBUG( LOG_DEBUG(
" [{}] definitionId: {}, itemId: {}, quantity: {}, flags: {}", " [{}] definitionId: {}, itemId: {}, quantity: {}, flags: {}",
tag, tag,
item.m_iDefinition, item.m_iDefinition,
item.m_itemId, item.m_itemId,
item.m_unQuantity, item.m_unQuantity,
item.m_unFlags item.m_unFlags
); );
};
if(not success) {
LOG_DEBUG("{} -> original result is false", function_name);
return success;
}
if(punOutItemsArraySize == nullptr) {
LOG_ERROR("{} -> arraySize pointer is null", function_name);
return success;
}
LOG_DEBUG(
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
function_name,
resultHandle,
reinterpret_cast<void*>(pOutItemsArray),
*punOutItemsArraySize
);
static uint32_t original_count = 0;
const auto injected_count = config::instance.extra_inventory_items.size();
// Automatically get inventory items from steam
static std::vector<SteamItemDef_t> auto_inventory_items;
if(config::instance.auto_inject_inventory) {
static std::once_flag inventory_inject_flag;
std::call_once(
inventory_inject_flag,
[&] {
uint32_t count = 0;
if(get_item_definition_ids(nullptr, &count)) {
auto_inventory_items.resize(count);
get_item_definition_ids(auto_inventory_items.data(), &count);
}
}
);
}
const auto auto_injected_count = auto_inventory_items.size();
if(not pOutItemsArray) {
// If pOutItemsArray is NULL then we must set the array size.
original_count = *punOutItemsArraySize;
*punOutItemsArraySize += auto_injected_count + injected_count;
LOG_DEBUG(
"{} -> Original count: {}, Total count: {}",
function_name,
original_count,
*punOutItemsArraySize
);
} else {
// Otherwise, we modify the array
for(int i = 0; i < original_count; i++) {
print_item("original", pOutItemsArray[i]);
}
static auto new_item = [](SteamItemDef_t id) {
return SteamItemDetails_t{
.m_itemId = id,
.m_iDefinition = id,
.m_unQuantity = 1,
.m_unFlags = 0,
};
}; };
for(int i = 0; i < auto_injected_count; i++) { if(not success) {
auto& item = pOutItemsArray[original_count + i]; LOG_DEBUG("{} -> original result is false", function_name);
const auto item_def_id = auto_inventory_items[i]; return success;
item = new_item(item_def_id);
print_item("auto-injected", item);
} }
for(int i = 0; i < injected_count; i++) { if(punOutItemsArraySize == nullptr) {
auto& item = pOutItemsArray[original_count + auto_injected_count + i]; LOG_ERROR("{} -> arraySize pointer is null", function_name);
const auto item_def_id = config::instance.extra_inventory_items[i]; return success;
item = new_item(item_def_id);
print_item("injected", item);
} }
LOG_DEBUG(
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
function_name,
resultHandle,
reinterpret_cast<void*>(pOutItemsArray),
*punOutItemsArraySize
);
static uint32_t original_count = 0;
const auto injected_count = config::instance.extra_inventory_items.size();
// Automatically get inventory items from steam
static std::vector<SteamItemDef_t> auto_inventory_items;
if(config::instance.auto_inject_inventory) {
static std::once_flag inventory_inject_flag;
std::call_once(
inventory_inject_flag,
[&] {
uint32_t count = 0;
if(get_item_definition_ids(nullptr, &count)) {
auto_inventory_items.resize(count);
get_item_definition_ids(auto_inventory_items.data(), &count);
}
}
);
}
const auto auto_injected_count = auto_inventory_items.size();
if(not pOutItemsArray) {
// If pOutItemsArray is NULL then we must set the array size.
original_count = *punOutItemsArraySize;
*punOutItemsArraySize += auto_injected_count + injected_count;
LOG_DEBUG(
"{} -> Original count: {}, Total count: {}",
function_name,
original_count,
*punOutItemsArraySize
);
} else {
// Otherwise, we modify the array
for(int i = 0; i < original_count; i++) {
print_item("original", pOutItemsArray[i]);
}
static auto new_item = [](SteamItemDef_t id) {
return SteamItemDetails_t{
.m_itemId = id,
.m_iDefinition = id,
.m_unQuantity = 1,
.m_unFlags = 0,
};
};
for(int i = 0; i < auto_injected_count; i++) {
auto& item = pOutItemsArray[original_count + i];
const auto item_def_id = auto_inventory_items[i];
item = new_item(item_def_id);
print_item("auto-injected", item);
}
for(int i = 0; i < injected_count; i++) {
auto& item = pOutItemsArray[original_count + auto_injected_count + i];
const auto item_def_id = config::instance.extra_inventory_items[i];
item = new_item(item_def_id);
print_item("injected", item);
}
}
return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false;
} }
return success;
} }
bool GetResultItemProperty( bool GetResultItemProperty(
@@ -139,47 +149,61 @@ namespace smoke_api::steam_inventory {
const char* pchValueBuffer, const char* pchValueBuffer,
const uint32_t* punValueBufferSizeOut, const uint32_t* punValueBufferSizeOut,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
LOG_DEBUG( try {
"{} -> Handle: {}, Index: {}, Name: '{}'", LOG_DEBUG(
function_name, "{} -> Handle: {}, Index: {}, Name: '{}'",
resultHandle, function_name,
unItemIndex, resultHandle,
// can be empty, in which case steam responds with property list in csv format unItemIndex,
pchPropertyName ? pchPropertyName : "nullptr" // can be empty, in which case steam responds with property list in csv format
); pchPropertyName ? pchPropertyName : "nullptr"
);
const auto success = original_function(); const auto success = original_function();
if(!success) { if(!success) {
LOG_WARN("{} -> Result is false", function_name); LOG_WARN("{} -> Result is false", function_name);
return false;
}
if(
pchValueBuffer && *pchValueBuffer &&
punValueBufferSizeOut && *punValueBufferSizeOut > 0
) {
LOG_DEBUG(
R"({} -> Buffer: "{}")",
function_name,
std::string(pchValueBuffer, *punValueBufferSizeOut - 1)
);
}
return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false; return false;
} }
if(
pchValueBuffer && *pchValueBuffer &&
punValueBufferSizeOut && *punValueBufferSizeOut > 0
) {
LOG_DEBUG(
R"({} -> Buffer: "{}")",
function_name,
std::string(pchValueBuffer, *punValueBufferSizeOut - 1)
);
}
return success;
} }
bool GetAllItems( bool GetAllItems(
const std::string& function_name, const std::string& function_name,
const SteamInventoryResult_t* pResultHandle, const SteamInventoryResult_t* pResultHandle,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
const auto success = original_function(); try {
const auto success = original_function();
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle)); LOG_DEBUG(
"{} -> Handle: {}",
function_name,
reinterpret_cast<const void*>(pResultHandle)
);
return success; return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false;
}
} }
bool GetItemsByID( bool GetItemsByID(
@@ -188,18 +212,23 @@ namespace smoke_api::steam_inventory {
const SteamItemInstanceID_t* pInstanceIDs, const SteamItemInstanceID_t* pInstanceIDs,
const uint32_t unCountInstanceIDs, const uint32_t unCountInstanceIDs,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
const auto success = original_function(); try {
const auto success = original_function();
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle)); LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle));
if(success && pInstanceIDs != nullptr) { if(success && pInstanceIDs != nullptr) {
for(int i = 0; i < unCountInstanceIDs; i++) { for(int i = 0; i < unCountInstanceIDs; i++) {
LOG_DEBUG(" Index: {}, ItemId: {}", i, pInstanceIDs[i]); LOG_DEBUG(" Index: {}, ItemId: {}", i, pInstanceIDs[i]);
}
} }
}
return success; return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false;
}
} }
bool SerializeResult( bool SerializeResult(
@@ -208,22 +237,27 @@ namespace smoke_api::steam_inventory {
void* pOutBuffer, void* pOutBuffer,
uint32_t* punOutBufferSize, uint32_t* punOutBufferSize,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
const auto success = original_function(); try {
const auto success = original_function();
if(pOutBuffer != nullptr) { if(pOutBuffer != nullptr) {
std::string buffer(static_cast<char*>(pOutBuffer), *punOutBufferSize); std::string buffer(static_cast<char*>(pOutBuffer), *punOutBufferSize);
LOG_DEBUG("{} -> Handle: {}, Buffer: '{}'", function_name, resultHandle, buffer); LOG_DEBUG("{} -> Handle: {}, Buffer: '{}'", function_name, resultHandle, buffer);
} else { } else {
LOG_DEBUG( LOG_DEBUG(
"{} -> Handle: {}, Size: '{}'", "{} -> Handle: {}, Size: '{}'",
function_name, function_name,
resultHandle, resultHandle,
*punOutBufferSize *punOutBufferSize
); );
}
return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false;
} }
return success;
} }
bool GetItemDefinitionIDs( bool GetItemDefinitionIDs(
@@ -231,28 +265,33 @@ namespace smoke_api::steam_inventory {
const SteamItemDef_t* pItemDefIDs, const SteamItemDef_t* pItemDefIDs,
uint32_t* punItemDefIDsArraySize, uint32_t* punItemDefIDsArraySize,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
const auto success = original_function(); try {
const auto success = original_function();
if(!success) { if(!success) {
LOG_WARN("{} -> Result is false", function_name); LOG_WARN("{} -> Result is false", function_name);
return false;
}
if(punItemDefIDsArraySize) {
LOG_DEBUG("{} -> Size: {}", function_name, *punItemDefIDsArraySize);
} else {
return success;
}
if(pItemDefIDs) { // Definitions were copied
for(int i = 0; i < *punItemDefIDsArraySize; i++) {
const auto& def = pItemDefIDs[i];
LOG_DEBUG(" Index: {}, ID: {}", i, def);
}
}
return success;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false; return false;
} }
if(punItemDefIDsArraySize) {
LOG_DEBUG("{} -> Size: {}", function_name, *punItemDefIDsArraySize);
} else {
return success;
}
if(pItemDefIDs) { // Definitions were copied
for(int i = 0; i < *punItemDefIDsArraySize; i++) {
const auto& def = pItemDefIDs[i];
LOG_DEBUG(" Index: {}, ID: {}", i, def);
}
}
return success;
} }
bool CheckResultSteamID( bool CheckResultSteamID(
@@ -260,17 +299,22 @@ namespace smoke_api::steam_inventory {
SteamInventoryResult_t resultHandle, SteamInventoryResult_t resultHandle,
CSteamID steamIDExpected, CSteamID steamIDExpected,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) noexcept {
const auto result = original_function(); try {
const auto result = original_function();
LOG_DEBUG( LOG_DEBUG(
"{} -> handle: {}, steamID: {}, original result: {}", "{} -> handle: {}, steamID: {}, original result: {}",
function_name, function_name,
resultHandle, resultHandle,
steamIDExpected, steamIDExpected,
result result
); );
return true; return true;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return false;
}
} }
} }

View File

@@ -7,7 +7,7 @@ namespace smoke_api::steam_inventory {
const std::string& function_name, const std::string& function_name,
SteamInventoryResult_t resultHandle, SteamInventoryResult_t resultHandle,
const std::function<EResult()>& original_function const std::function<EResult()>& original_function
); ) noexcept;
bool GetResultItems( bool GetResultItems(
const std::string& function_name, const std::string& function_name,
@@ -16,7 +16,7 @@ namespace smoke_api::steam_inventory {
uint32_t* punOutItemsArraySize, uint32_t* punOutItemsArraySize,
const std::function<bool()>& original_function, const std::function<bool()>& original_function,
const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids
); ) noexcept;
bool GetResultItemProperty( bool GetResultItemProperty(
const std::string& function_name, const std::string& function_name,
@@ -26,13 +26,13 @@ namespace smoke_api::steam_inventory {
const char* pchValueBuffer, const char* pchValueBuffer,
const uint32_t* punValueBufferSizeOut, const uint32_t* punValueBufferSizeOut,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
bool GetAllItems( bool GetAllItems(
const std::string& function_name, const std::string& function_name,
const SteamInventoryResult_t* pResultHandle, const SteamInventoryResult_t* pResultHandle,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
bool GetItemsByID( bool GetItemsByID(
const std::string& function_name, const std::string& function_name,
@@ -40,7 +40,7 @@ namespace smoke_api::steam_inventory {
const SteamItemInstanceID_t* pInstanceIDs, const SteamItemInstanceID_t* pInstanceIDs,
uint32_t unCountInstanceIDs, uint32_t unCountInstanceIDs,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
bool SerializeResult( bool SerializeResult(
const std::string& function_name, const std::string& function_name,
@@ -48,19 +48,19 @@ namespace smoke_api::steam_inventory {
void* pOutBuffer, void* pOutBuffer,
uint32_t* punOutBufferSize, uint32_t* punOutBufferSize,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
bool GetItemDefinitionIDs( bool GetItemDefinitionIDs(
const std::string& function_name, const std::string& function_name,
const SteamItemDef_t* pItemDefIDs, const SteamItemDef_t* pItemDefIDs,
uint32_t* punItemDefIDsArraySize, uint32_t* punItemDefIDsArraySize,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
bool CheckResultSteamID( bool CheckResultSteamID(
const std::string& function_name, const std::string& function_name,
SteamInventoryResult_t resultHandle, SteamInventoryResult_t resultHandle,
CSteamID steamIDExpected, CSteamID steamIDExpected,
const std::function<bool()>& original_function const std::function<bool()>& original_function
); ) noexcept;
} }

View File

@@ -9,26 +9,31 @@ namespace smoke_api::steam_user {
const AppId_t appId, const AppId_t appId,
const AppId_t dlcId, const AppId_t dlcId,
const std::function<EUserHasLicenseForAppResult()>& original_function const std::function<EUserHasLicenseForAppResult()>& original_function
) { ) noexcept {
const auto result = original_function(); try {
const auto result = original_function();
if(result == k_EUserHasLicenseResultNoAuth) { if(result == k_EUserHasLicenseResultNoAuth) {
LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, dlcId); LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, dlcId);
return result; return result;
}
const auto has_license = config::is_dlc_unlocked(
appId,
dlcId,
[&] {
return result == k_EUserHasLicenseResultHasLicense;
} }
);
LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, dlcId, has_license); const auto has_license = config::is_dlc_unlocked(
appId,
dlcId,
[&] {
return result == k_EUserHasLicenseResultHasLicense;
}
);
return has_license LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, dlcId, has_license);
? k_EUserHasLicenseResultHasLicense
: k_EUserHasLicenseResultDoesNotHaveLicense; return has_license
? k_EUserHasLicenseResultHasLicense
: k_EUserHasLicenseResultDoesNotHaveLicense;
} catch(const std::exception& e) {
LOG_ERROR("{} -> Error: {}", function_name, e.what());
return k_EUserHasLicenseResultDoesNotHaveLicense;
}
} }
} }

View File

@@ -8,5 +8,5 @@ namespace smoke_api::steam_user {
AppId_t appId, AppId_t appId,
AppId_t dlcId, AppId_t dlcId,
const std::function<EUserHasLicenseForAppResult()>& original_function const std::function<EUserHasLicenseForAppResult()>& original_function
); ) noexcept;
} }

View File

@@ -14,11 +14,15 @@
// These macros are meant to be used for callbacks that should return original result // These macros are meant to be used for callbacks that should return original result
#define HOOKED_CALL(FUNC, ...) \ #define HOOKED_CALL(FUNC, ...) \
static const auto _##FUNC = KB_HOOK_GET_HOOKED_FN(FUNC); \ static const auto _##FUNC = KB_HOOK_GET_HOOKED_FN(FUNC); \
return _##FUNC(__VA_ARGS__) return _##FUNC(__VA_ARGS__)
#define HOOKED_CALL_CLOSURE(FUNC, ...) \ #define HOOKED_CALL_CLOSURE(FUNC, ...) \
[&] { HOOKED_CALL(FUNC, __VA_ARGS__); } [&] { HOOKED_CALL(FUNC, __VA_ARGS__); }
#define HOOKED_CALL_RESULT(FUNC, ...) \
static const auto _##FUNC = KB_HOOK_GET_HOOKED_FN(FUNC); \
const auto result = _##FUNC(__VA_ARGS__)
/** /**
* By default, virtual functions are declared with __thiscall * By default, virtual functions are declared with __thiscall
@@ -55,12 +59,19 @@ return _##FUNC(__VA_ARGS__)
using AppId_t = uint32_t; using AppId_t = uint32_t;
using HSteamPipe = uint32_t; using HSteamPipe = uint32_t;
using EResult = uint32_t;
using HSteamUser = uint32_t; using HSteamUser = uint32_t;
using SteamInventoryResult_t = uint32_t; using SteamInventoryResult_t = uint32_t;
using SteamItemInstanceID_t = uint64_t; using SteamItemInstanceID_t = uint64_t;
using SteamItemDef_t = uint32_t; using SteamItemDef_t = uint32_t;
using CSteamID = uint64_t; using CSteamID = uint64_t;
using HTTPRequestHandle = uint32_t;
enum class EResult {
k_EResultNone = 0,
k_EResultOK = 1,
k_EResultFail = 2,
// See all at steamclientpublic.h
};
struct SteamItemDetails_t { struct SteamItemDetails_t {
SteamItemInstanceID_t m_itemId; SteamItemInstanceID_t m_itemId;
@@ -71,10 +82,12 @@ struct SteamItemDetails_t {
// results from UserHasLicenseForApp // results from UserHasLicenseForApp
enum EUserHasLicenseForAppResult { enum EUserHasLicenseForAppResult {
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app // User has a license for specified app
k_EUserHasLicenseResultDoesNotHaveLicense = 1, k_EUserHasLicenseResultHasLicense = 0,
// User does not have a license for the specified app // User does not have a license for the specified app
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated k_EUserHasLicenseResultDoesNotHaveLicense = 1,
// User has not been authenticated
k_EUserHasLicenseResultNoAuth = 2,
}; };
// These aliases exist solely to increase code readability // These aliases exist solely to increase code readability
@@ -87,7 +100,7 @@ using DlcNameMap = std::map<DlcIdKey, DlcNameValue>;
struct App { struct App {
DlcNameMap dlcs; DlcNameMap dlcs;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(App, dlcs) // NOLINT(misc-const-correctness) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(App, dlcs)
}; };
using AppDlcNameMap = std::map<AppIdKey, App>; using AppDlcNameMap = std::map<AppIdKey, App>;
@@ -98,6 +111,8 @@ class DLC {
std::string name; std::string name;
public: public:
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(DLC, appid, name)
explicit DLC() = default; explicit DLC() = default;
explicit DLC(std::string appid, std::string name) : appid{std::move(appid)}, explicit DLC(std::string appid, std::string name) : appid{std::move(appid)},
@@ -115,8 +130,6 @@ public:
return name; return name;
} }
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DLC, appid, name)
static std::vector<DLC> get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_id); static std::vector<DLC> get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_id);
static DlcNameMap get_dlc_map_from_vector(const std::vector<DLC>& dlcs); static DlcNameMap get_dlc_map_from_vector(const std::vector<DLC>& dlcs);