Implemented ISteamGameServer

This commit is contained in:
acidicoala
2025-08-26 05:07:17 +05:00
parent 902476cb3e
commit 9f84425e4e
59 changed files with 151 additions and 123 deletions

View File

@@ -69,4 +69,5 @@ misc-*,
-readability-named-parameter,
-readability-function-cognitive-complexity,
-*-include-cleaner,
-*-lambda-function-name'
-*-lambda-function-name,
-*-err58-cpp'

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text eol=lf

View File

@@ -40,6 +40,7 @@ set(SMOKE_API_SOURCES
src/steam_api/exports/steam_api_unversioned.cpp
src/steam_api/virtuals/isteamapps.cpp
src/steam_api/virtuals/isteamclient.cpp
src/steam_api/virtuals/isteamgameserver.cpp
src/steam_api/virtuals/isteaminventory.cpp
src/steam_api/virtuals/isteamuser.cpp
src/steam_api/virtuals/steam_api_virtuals.hpp
@@ -82,6 +83,7 @@ target_include_directories(SmokeAPI PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_BINARY_DIR}")
## https://github.com/batterycenter/embed
CPMAddPackage(
URI "gh:batterycenter/embed@1.2.19"
OPTIONS "B_PRODUCTION_MODE ON"

View File

@@ -73,21 +73,21 @@ SmokeAPI supports 2 installation modes: hook mode and proxy mode.
|===
Try installing the unlocker in hook mode first.
If it doesn't work, try installing it in proxy mode.
==== 🪝 Hook mode
=== 🪝 Hook mode
. Download the latest SmokeAPI release zip from {smokeapi_release}.
. From SmokeAPI archive unpack `steam_api.dll` or `steam_api64.dll`, depending on the game bitness, rename it to `version.dll`, and place it next to the game exe file.
==== 🪝 Hook mode (Alternative)
=== 🪝 Hook mode (Alternative)
If a game doesn't load `version.dll`, you can use one of the {koaloader} DLLs that the game does in fact load. For example, assuming that the game loads `d3d9.dll`:
If a game doesn't load `version.dll`, you can use one of the {koaloader} DLLs that the game does in fact load.
For example, assuming that the game loads `winmm.dll`:
. Download the latest Koaloader release zip from https://github.com/acidicoala/Koaloader/releases/latest[Koaloader Releases].
. From Koaloader archive unpack `d3d9.dll` from `d3d9-32` or `d3d9-64`, depending on the game bitness, and place it next to the game exe file.
. From Koaloader archive unpack `winmm.dll` from `winmm-32` or `winmm-64`, depending on the game bitness, and place it next to the game exe file.
. Download the latest SmokeAPI release zip from {smokeapi_release}.
. From SmokeAPI archive unpack `steam_api.dll` or `steam_api64.dll`, depending on the game bitness, rename it to `SmokeAPI.dll`, and place it next to the game exe file.
@@ -265,9 +265,15 @@ For example:
.\build.ps1 64 Release
----
== 🐞 Known issues
* Crashes on startup in Project Winter in hook mode (proxy mode works fine).
== 📚 Open-Source libraries
TODO
* https://github.com/batterycenter/embed[batterycenter/embed]
* https://github.com/bshoshany/thread-pool[bshoshany/thread-pool]
* + https://github.com/acidicoala/Koalabox?tab=readme-ov-file#-open-source-libraries[libraries used by KoalaBox]
== 📄 License

View File

@@ -3,7 +3,6 @@
"$version": 3,
"logging": true,
"default_app_status": "unlocked",
"override_app_id": 0,
"override_app_status": {},
"override_dlc_status": {},
"auto_inject_inventory": true,

View File

@@ -5,6 +5,10 @@
"type": "object",
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string",
"description": "The URI of the JSON Schema used to validate this config."
},
"$version": {
"type": "integer",
"minimum": 0,
@@ -21,12 +25,6 @@
"default": "unlocked",
"$ref": "#/$defs/AppStatus"
},
"override_app_id": {
"type": "integer",
"minimum": 0,
"default": 0,
"description": "Overrides the current app ID (0 means no override)."
},
"override_app_status": {
"type": "object",
"default": {},
@@ -113,6 +111,7 @@
},
"examples": [
{
"$schema": "https://raw.githubusercontent.com/acidicoala/SmokeAPI/refs/heads/master/res/SmokeAPI.schema.json",
"$version": 3,
"logging": true,
"default_app_status": "unlocked",

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main interface for loading and accessing Steamworks API's from the
// Steam client.

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -1,4 +1,4 @@
//====== Copyright Valve Corporation, All rights reserved. ====================
//====== Copyright Valve Corporation, All rights reserved. ====================
//
// Internal low-level access to Steamworks interfaces.
//

View File

@@ -37,19 +37,6 @@
namespace {
namespace kb = koalabox;
namespace fs = std::filesystem;
void override_app_id() {
const auto override_app_id = smoke_api::config::instance.override_app_id;
if(override_app_id == 0) {
return;
}
spdlog::default_logger_raw();
LOG_DEBUG("Overriding app id to {}", override_app_id);
SetEnvironmentVariable(TEXT("SteamAppId"), std::to_wstring(override_app_id).c_str());
}
void init_proxy_mode() {
LOG_INFO("Detected proxy mode");
@@ -61,27 +48,14 @@ namespace {
void init_hook_mode() {
LOG_INFO("Detected hook mode");
kb::hook::init(true);
const std::vector<std::string> target_libraries{STEAMCLIENT_DLL, STEAMAPI_DLL};
kb::dll_monitor::init_listener(
target_libraries,
{STEAMCLIENT_DLL, STEAMAPI_DLL},
[&](const HMODULE& module_handle, const std::string& library_name) {
static auto hook_count = 0U;
if(kb::str::eq(library_name, STEAMCLIENT_DLL)) {
KB_HOOK_DETOUR_MODULE(CreateInterface, module_handle);
hook_count++;
} else if(kb::str::eq(library_name, STEAMAPI_DLL)) {
KB_HOOK_DETOUR_MODULE(SteamAPI_RestartAppIfNecessary, module_handle);
KB_HOOK_DETOUR_MODULE(SteamAPI_Shutdown, module_handle);
hook_count++;
}
if(hook_count == target_libraries.size()) {
kb::dll_monitor::shutdown_listener();
}
}
);
@@ -111,7 +85,8 @@ namespace smoke_api {
LOG_DEBUG("Process name: '{}' [{}-bit]", exe_name, kb::util::BITNESS);
override_app_id();
// We need to hook functions in either mode
kb::hook::init(true);
if(kb::hook::is_hook_mode(module_handle, STEAMAPI_DLL)) {
hook_mode = true;

View File

@@ -6,6 +6,7 @@ constexpr auto STEAM_APPS = "STEAMAPPS_INTERFACE_VERSION";
constexpr auto STEAM_CLIENT = "SteamClient";
constexpr auto STEAM_USER = "SteamUser";
constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V";
constexpr auto STEAM_GAME_SERVER = "SteamGameServer";
// IMPORTANT: DLL_EXPORT is hardcoded in exports_generator.cpp,
// so any name changes here must be reflected there as well.

View File

@@ -5,10 +5,9 @@
#include "smoke_api/config.hpp"
DLL_EXPORT(bool) SteamAPI_RestartAppIfNecessary(const AppId_t unOwnAppID) {
if(smoke_api::config::instance.override_app_id != 0) {
LOG_DEBUG("{} -> {}. Preventing app restart", unOwnAppID, __func__);
return false;
}
LOG_INFO("{} -> unOwnAppID: {}", __func__, unOwnAppID);
// Restart can be suppressed if needed
AUTO_CALL(SteamAPI_RestartAppIfNecessary, unOwnAppID);
}

View File

@@ -9,7 +9,7 @@
// ISteamApps
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, AppId_t dlcID) {
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, const AppId_t dlcID) {
try {
return smoke_api::steam_apps::IsDlcUnlocked(
__func__,
@@ -23,7 +23,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, AppId_t dlcID)
}
}
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void* self, AppId_t dlcID) {
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void* self, const AppId_t dlcID) {
try {
return smoke_api::steam_apps::IsDlcUnlocked(
__func__,
@@ -294,3 +294,28 @@ DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp
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

@@ -2,7 +2,6 @@
#include <map>
#include <koalabox/logger.hpp>
#include <koalabox/util.hpp>
#include <koalabox/win.hpp>
#include "smoke_api.hpp"
@@ -34,7 +33,7 @@ namespace {
return version_map[version_prefix];
}
throw kb::util::exception("No match found for '{}'", version_prefix);
throw std::runtime_error(std::format("No match found for '{}'", version_prefix));
} catch(const std::exception& ex) {
LOG_ERROR(
"Failed to get versioned interface: {}."

View File

@@ -5,7 +5,6 @@
#include <koalabox/hook.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/util.hpp>
#include <koalabox/win.hpp>
#include "smoke_api.hpp"
@@ -67,17 +66,11 @@ namespace {
}
},
{
STEAM_INVENTORY,
STEAM_GAME_SERVER,
interface_data{
.fallback_version = "STEAMINVENTORY_INTERFACE_V003",
.fallback_version = "SteamGameServer015",
.entry_map = {
ENTRY(ISteamInventory, GetResultStatus),
ENTRY(ISteamInventory, GetResultItems),
ENTRY(ISteamInventory, CheckResultSteamID),
ENTRY(ISteamInventory, GetAllItems),
ENTRY(ISteamInventory, GetItemsByID),
ENTRY(ISteamInventory, SerializeResult),
ENTRY(ISteamInventory, GetItemDefinitionIDs),
ENTRY(ISteamGameServer, UserHasLicenseForApp),
}
}
},

View File

@@ -1,6 +1,5 @@
#include <koalabox/logger.hpp>
#include "smoke_api.hpp"
#include "smoke_api/interfaces/steam_apps.hpp"
#include "steam_api/steam_interface.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"

View File

@@ -1,6 +1,5 @@
#include <koalabox/logger.hpp>
#include "smoke_api.hpp"
#include "steam_api/steam_client.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"

View File

@@ -0,0 +1,21 @@
#include <koalabox/logger.hpp>
#include "smoke_api/interfaces/steam_user.hpp"
#include "steam_api/steam_interface.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"
VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(
PARAMS(const CSteamID steamID, const AppId_t dlc_id)
) {
try {
return smoke_api::steam_user::UserHasLicenseForApp(
__func__,
steam_interface::get_app_id(),
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

@@ -1,4 +1,3 @@
#include "smoke_api.hpp"
#include "smoke_api/interfaces/steam_inventory.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"
@@ -130,7 +129,7 @@ VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(
}
VIRTUAL(bool) ISteamInventory_CheckResultSteamID(
PARAMS(SteamInventoryResult_t resultHandle, CSteamID steamIDExpected)
PARAMS(const SteamInventoryResult_t resultHandle, CSteamID steamIDExpected)
) {
return smoke_api::steam_inventory::CheckResultSteamID(
__func__,

View File

@@ -1,6 +1,5 @@
#include <koalabox/logger.hpp>
#include "smoke_api.hpp"
#include "smoke_api/interfaces/steam_user.hpp"
#include "steam_api/steam_interface.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"

View File

@@ -33,3 +33,8 @@ VIRTUAL(bool) ISteamInventory_CheckResultSteamID(PARAMS(SteamInventoryResult_t,
// ISteamUser
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t));
// ISteamGameServer
VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(
PARAMS(CSteamID, AppId_t)
);

View File

@@ -32,7 +32,7 @@ namespace smoke_api::api {
std::optional<std::vector<DLC>> fetch_dlcs_from_steam(const AppId_t app_id) {
try {
// TODO: Communicate directly with Steam servers.
// TODO: Communicate directly with Steam servers?
// ref.: https://github.com/SteamRE/SteamKit
const auto url =
std::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id);

View File

@@ -32,6 +32,9 @@ namespace smoke_api::cache {
}
bool save_dlcs(AppId_t app_id, const std::vector<DLC>& dlcs) noexcept {
static std::mutex section;
const std::lock_guard lock(section);
try {
LOG_DEBUG("Caching DLC IDs for the app: {}", app_id);

View File

@@ -1,7 +1,6 @@
#include <koalabox/config.hpp>
#include <koalabox/io.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/util.hpp>
#include "smoke_api/config.hpp"
@@ -40,6 +39,7 @@ namespace smoke_api::config {
break;
case AppStatus::ORIGINAL:
case AppStatus::UNDEFINED:
default:
is_unlocked = original_function();
break;
}

View File

@@ -14,10 +14,10 @@ namespace smoke_api::config {
AppStatus,
// @formatter:off
{
{AppStatus::UNDEFINED, nullptr},
{AppStatus::ORIGINAL, "original"},
{AppStatus::UNLOCKED, "unlocked"},
{AppStatus::LOCKED, "locked"},
{ AppStatus::UNDEFINED, nullptr },
{ AppStatus::ORIGINAL, "original" },
{ AppStatus::UNLOCKED, "unlocked" },
{ AppStatus::LOCKED, "locked" },
}
// @formatter:on
)
@@ -26,7 +26,6 @@ namespace smoke_api::config {
uint32_t $version = 3;
bool logging = false;
AppStatus default_app_status = AppStatus::UNLOCKED;
uint32_t override_app_id = 0;
std::map<std::string, AppStatus> override_app_status;
std::map<std::string, AppStatus> override_dlc_status;
AppDlcNameMap extra_dlcs;
@@ -35,11 +34,9 @@ namespace smoke_api::config {
NLOHMANN_DEFINE_TYPE_INTRUSIVE(
Config,
// NOLINT(misc-const-correctness)
$version,
logging,
default_app_status,
override_app_id,
override_app_status,
override_dlc_status,
extra_dlcs,

View File

@@ -1,7 +1,6 @@
#include <set>
#include <koalabox/logger.hpp>
#include <koalabox/util.hpp>
#include "smoke_api/interfaces/steam_apps.hpp"
#include "smoke_api/api.hpp"
@@ -88,7 +87,7 @@ namespace smoke_api::steam_apps {
const std::function<bool()>& original_function
) {
try {
const auto unlocked = smoke_api::config::is_dlc_unlocked(
const auto unlocked = config::is_dlc_unlocked(
app_id,
dlc_id,
original_function
@@ -172,10 +171,10 @@ namespace smoke_api::steam_apps {
);
};
const auto inject_dlc = [&](const DLC& dlc) {
const auto output_dlc = [&](const DLC& dlc) {
// Fill the output pointers
*pDlcId = dlc.get_id();
*pbAvailable = smoke_api::config::is_dlc_unlocked(
*pbAvailable = config::is_dlc_unlocked(
app_id,
*pDlcId,
[&] {
@@ -192,7 +191,7 @@ namespace smoke_api::steam_apps {
const auto& dlcs = app_dlcs[app_id];
if(iDLC >= 0 && iDLC < dlcs.size()) {
inject_dlc(dlcs[iDLC]);
output_dlc(dlcs[iDLC]);
print_dlc_info("injected");
return true;
}
@@ -204,7 +203,7 @@ namespace smoke_api::steam_apps {
const auto success = original_function();
if(success) {
*pbAvailable = smoke_api::config::is_dlc_unlocked(
*pbAvailable = config::is_dlc_unlocked(
app_id,
*pDlcId,
[&] {

View File

@@ -59,7 +59,7 @@ namespace smoke_api::steam_inventory {
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
function_name,
resultHandle,
fmt::ptr(pOutItemsArray),
reinterpret_cast<void*>(pOutItemsArray),
*punOutItemsArraySize
);
@@ -140,26 +140,32 @@ namespace smoke_api::steam_inventory {
const uint32_t* punValueBufferSizeOut,
const std::function<bool()>& original_function
) {
const auto common_info = fmt::format(
LOG_DEBUG(
"{} -> Handle: {}, Index: {}, Name: '{}'",
function_name,
resultHandle,
unItemIndex,
pchPropertyName
// can be empty, in which case steam responds with property list in csv format
pchPropertyName ? pchPropertyName : "nullptr"
);
const auto success = original_function();
if(!success) {
LOG_WARN("{}, Result is false", common_info);
LOG_WARN("{} -> Result is false", function_name);
return false;
}
if(
pchValueBuffer && *pchValueBuffer &&
punValueBufferSizeOut && *punValueBufferSizeOut > 0
) {
LOG_DEBUG(
"{}, Buffer: '{}'",
common_info,
R"({} -> Buffer: "{}")",
function_name,
std::string(pchValueBuffer, *punValueBufferSizeOut - 1)
);
}
return success;
}

View File

@@ -4,6 +4,7 @@ project(smoke-api-tools LANGUAGES CXX)
### Thread pool library
## https://github.com/bshoshany/thread-pool
CPMAddPackage(
NAME BS_thread_pool
GITHUB_REPOSITORY bshoshany/thread-pool