mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2025-12-05 21:15:39 -05:00
Added ReloadConfig
This commit is contained in:
@@ -87,6 +87,7 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
|||||||
src/koalageddon/steamclient/client_apps.cpp
|
src/koalageddon/steamclient/client_apps.cpp
|
||||||
src/koalageddon/steamclient/client_inventory.cpp
|
src/koalageddon/steamclient/client_inventory.cpp
|
||||||
src/koalageddon/steamclient/client_user.cpp
|
src/koalageddon/steamclient/client_user.cpp
|
||||||
|
src/koalageddon/steamclient/client_utils.cpp
|
||||||
src/koalageddon/steamclient/steamclient.cpp
|
src/koalageddon/steamclient/steamclient.cpp
|
||||||
src/koalageddon/steamclient/steamclient.hpp
|
src/koalageddon/steamclient/steamclient.hpp
|
||||||
)
|
)
|
||||||
|
|||||||
2
KoalaBox
2
KoalaBox
Submodule KoalaBox updated: db8cea415e...17c39229db
@@ -4,6 +4,10 @@
|
|||||||
"unlock_family_sharing": true,
|
"unlock_family_sharing": true,
|
||||||
"default_app_status": "unlocked",
|
"default_app_status": "unlocked",
|
||||||
"override_app_status": {
|
"override_app_status": {
|
||||||
|
"1234": "original",
|
||||||
|
"4321": "unlocked"
|
||||||
|
},
|
||||||
|
"override_dlc_status": {
|
||||||
"1234": "original",
|
"1234": "original",
|
||||||
"4321": "unlocked",
|
"4321": "unlocked",
|
||||||
"5678": "locked"
|
"5678": "locked"
|
||||||
|
|||||||
@@ -94,11 +94,6 @@ enum EUserHasLicenseForAppResult {
|
|||||||
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
|
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
|
||||||
};
|
};
|
||||||
|
|
||||||
class ISteamClient;
|
|
||||||
class ISteamApps;
|
|
||||||
class ISteamUser;
|
|
||||||
class ISteamInventory;
|
|
||||||
|
|
||||||
// These aliases exist solely to increase code readability
|
// These aliases exist solely to increase code readability
|
||||||
|
|
||||||
using AppIdKey = String;
|
using AppIdKey = String;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include <koalabox/logger.hpp>
|
#include <koalabox/logger.hpp>
|
||||||
|
|
||||||
namespace koalageddon {
|
namespace koalageddon {
|
||||||
const void* client_app_manager_interface = nullptr;
|
|
||||||
|
|
||||||
KoalageddonConfig config; // NOLINT(cert-err58-cpp)
|
KoalageddonConfig config; // NOLINT(cert-err58-cpp)
|
||||||
|
|
||||||
@@ -56,6 +55,8 @@ namespace koalageddon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
|
// TODO: Load cached koalageddon config by default
|
||||||
|
|
||||||
std::thread(
|
std::thread(
|
||||||
[]() {
|
[]() {
|
||||||
const auto kg_config_source = init_koalageddon_config();
|
const auto kg_config_source = init_koalageddon_config();
|
||||||
|
|||||||
@@ -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;
|
extern KoalageddonConfig config;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <steam_impl/steam_apps.hpp>
|
#include <steam_impl/steam_apps.hpp>
|
||||||
#include <koalageddon/koalageddon.hpp>
|
|
||||||
#include <koalageddon/steamclient/steamclient.hpp>
|
#include <koalageddon/steamclient/steamclient.hpp>
|
||||||
|
|
||||||
VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) {
|
VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) {
|
||||||
@@ -32,8 +31,9 @@ VIRTUAL(bool) IClientApps_BGetDLCDataByIndex(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
[&](AppId_t dlc_id) {
|
[&](AppId_t dlc_id) {
|
||||||
if (koalageddon::client_app_manager_interface) {
|
const auto* app_manager_interface = koalageddon::steamclient::interface_name_to_address_map["IClientAppManager"];
|
||||||
IClientAppManager_IsAppDlcInstalled(koalageddon::client_app_manager_interface, EDX, appID, dlc_id);
|
if (app_manager_interface) {
|
||||||
|
IClientAppManager_IsAppDlcInstalled(app_manager_interface, EDX, appID, dlc_id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#include <koalageddon/steamclient/steamclient.hpp>
|
#include <koalageddon/steamclient/steamclient.hpp>
|
||||||
#include <steam_impl/steam_apps.hpp>
|
#include <steam_impl/steam_apps.hpp>
|
||||||
|
|
||||||
VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t app_id)) {
|
VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t dlc_id)) {
|
||||||
return steam_apps::IsDlcUnlocked(__func__, 0, app_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)
|
GET_ORIGINAL_HOOKED_FUNCTION(IClientUser_BIsSubscribedApp)
|
||||||
|
|
||||||
return IClientUser_BIsSubscribedApp_o(ARGS(app_id));
|
return IClientUser_BIsSubscribedApp_o(ARGS(dlc_id));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/koalageddon/steamclient/client_utils.cpp
Normal file
7
src/koalageddon/steamclient/client_utils.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include <koalageddon/steamclient/steamclient.hpp>
|
||||||
|
|
||||||
|
VIRTUAL(AppId_t) IClientUtils_GetAppID(PARAMS()) {
|
||||||
|
GET_ORIGINAL_HOOKED_FUNCTION(IClientUtils_GetAppID)
|
||||||
|
|
||||||
|
return IClientUtils_GetAppID_o(ARGS());
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
namespace koalageddon::steamclient {
|
namespace koalageddon::steamclient {
|
||||||
using namespace koalabox;
|
using namespace koalabox;
|
||||||
|
|
||||||
|
Map<String, void*> interface_name_to_address_map; // NOLINT(cert-err58-cpp)
|
||||||
|
|
||||||
struct InstructionContext {
|
struct InstructionContext {
|
||||||
std::optional<ZydisRegister> base_register;
|
std::optional<ZydisRegister> base_register;
|
||||||
std::optional<String> function_name;
|
std::optional<String> function_name;
|
||||||
@@ -24,6 +26,14 @@ namespace koalageddon::steamclient {
|
|||||||
ZydisDecoder decoder = {};
|
ZydisDecoder decoder = {};
|
||||||
ZydisFormatter formatter = {};
|
ZydisFormatter formatter = {};
|
||||||
|
|
||||||
|
void construct_ordinal_map( // NOLINT(misc-no-recursion)
|
||||||
|
const String& target_interface,
|
||||||
|
Map<String, uint32_t>& map,
|
||||||
|
uintptr_t start_address,
|
||||||
|
Set<uintptr_t>& visited_addresses,
|
||||||
|
InstructionContext context
|
||||||
|
);
|
||||||
|
|
||||||
#define HOOK_FUNCTION(INTERFACE, FUNC) hook::swap_virtual_func_or_throw( \
|
#define HOOK_FUNCTION(INTERFACE, FUNC) hook::swap_virtual_func_or_throw( \
|
||||||
globals::address_map, \
|
globals::address_map, \
|
||||||
interface, \
|
interface, \
|
||||||
@@ -34,18 +44,20 @@ namespace koalageddon::steamclient {
|
|||||||
|
|
||||||
#define SELECTOR_IMPLEMENTATION(INTERFACE, FUNC_BODY) \
|
#define SELECTOR_IMPLEMENTATION(INTERFACE, FUNC_BODY) \
|
||||||
DLL_EXPORT(void) INTERFACE##_Selector( \
|
DLL_EXPORT(void) INTERFACE##_Selector( \
|
||||||
const void* interface, \
|
void* interface, \
|
||||||
const void* arg2, \
|
void* arg2, \
|
||||||
const void* arg3, \
|
void* arg3, \
|
||||||
const void* arg4 \
|
void* arg4 \
|
||||||
) { \
|
) { \
|
||||||
CALL_ONCE(FUNC_BODY) \
|
CALL_ONCE({ \
|
||||||
|
interface_name_to_address_map[#INTERFACE] = interface; \
|
||||||
|
[&]()FUNC_BODY(); \
|
||||||
|
}) \
|
||||||
GET_ORIGINAL_HOOKED_FUNCTION(INTERFACE##_Selector) \
|
GET_ORIGINAL_HOOKED_FUNCTION(INTERFACE##_Selector) \
|
||||||
INTERFACE##_Selector_o(interface, arg2, arg3, arg4); \
|
INTERFACE##_Selector_o(interface, arg2, arg3, arg4); \
|
||||||
}
|
}
|
||||||
|
|
||||||
SELECTOR_IMPLEMENTATION(IClientAppManager, {
|
SELECTOR_IMPLEMENTATION(IClientAppManager, {
|
||||||
koalageddon::client_app_manager_interface = interface;
|
|
||||||
HOOK_FUNCTION(IClientAppManager, IsAppDlcInstalled)
|
HOOK_FUNCTION(IClientAppManager, IsAppDlcInstalled)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -69,6 +81,36 @@ namespace koalageddon::steamclient {
|
|||||||
HOOK_FUNCTION(IClientUser, BIsSubscribedApp)
|
HOOK_FUNCTION(IClientUser, BIsSubscribedApp)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
SELECTOR_IMPLEMENTATION(IClientUtils, {
|
||||||
|
HOOK_FUNCTION(IClientUtils, GetAppID)
|
||||||
|
})
|
||||||
|
|
||||||
|
#define CONSTRUCT_ORDINAL_MAP(INTERFACE) \
|
||||||
|
Set<uintptr_t> 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) {
|
uintptr_t get_absolute_address(ZydisDecodedInstruction instruction, uintptr_t address) {
|
||||||
const auto operand = instruction.operands[0];
|
const auto operand = instruction.operands[0];
|
||||||
|
|
||||||
@@ -86,9 +128,9 @@ namespace koalageddon::steamclient {
|
|||||||
const auto& operand = instruction.operands[0];
|
const auto& operand = instruction.operands[0];
|
||||||
|
|
||||||
return instruction.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
return instruction.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
||||||
operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
operand.visibility == ZYDIS_OPERAND_VISIBILITY_EXPLICIT &&
|
operand.visibility == ZYDIS_OPERAND_VISIBILITY_EXPLICIT &&
|
||||||
operand.encoding == ZYDIS_OPERAND_ENCODING_SIMM16_32_32;
|
operand.encoding == ZYDIS_OPERAND_ENCODING_SIMM16_32_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<String> get_string_argument(const ZydisDecodedInstruction& instruction) {
|
std::optional<String> get_string_argument(const ZydisDecodedInstruction& instruction) {
|
||||||
@@ -142,9 +184,9 @@ namespace koalageddon::steamclient {
|
|||||||
|
|
||||||
const auto is_mov_base_esp = [](const ZydisDecodedInstruction& instruction) {
|
const auto is_mov_base_esp = [](const ZydisDecodedInstruction& instruction) {
|
||||||
return instruction.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instruction.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instruction.operand_count == 2 &&
|
instruction.operand_count == 2 &&
|
||||||
instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instruction.operands[1].reg.value == ZYDIS_REGISTER_ESP;
|
instruction.operands[1].reg.value == ZYDIS_REGISTER_ESP;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize with a dummy previous instruction
|
// Initialize with a dummy previous instruction
|
||||||
@@ -169,8 +211,8 @@ namespace koalageddon::steamclient {
|
|||||||
// Save base register
|
// Save base register
|
||||||
context.base_register = instruction.operands[0].reg.value;
|
context.base_register = instruction.operands[0].reg.value;
|
||||||
} else if (is_push_immediate(last_instruction) &&
|
} else if (is_push_immediate(last_instruction) &&
|
||||||
is_push_immediate(instruction) &&
|
is_push_immediate(instruction) &&
|
||||||
!context.function_name) {
|
!context.function_name) {
|
||||||
// The very first 2 consecutive pushes indicate interface and function names.
|
// The very first 2 consecutive pushes indicate interface and function names.
|
||||||
// However, subsequent pushes may contain irrelevant strings.
|
// However, subsequent pushes may contain irrelevant strings.
|
||||||
const auto push_string_1 = get_string_argument(last_instruction);
|
const auto push_string_1 = get_string_argument(last_instruction);
|
||||||
@@ -183,7 +225,7 @@ namespace koalageddon::steamclient {
|
|||||||
context.function_name = push_string_1;
|
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
|
// Bail early to avoid duplicate work
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -199,7 +241,7 @@ namespace koalageddon::steamclient {
|
|||||||
// But not continue forward, in order to avoid duplicate processing
|
// But not continue forward, in order to avoid duplicate processing
|
||||||
return;
|
return;
|
||||||
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP &&
|
} 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
|
// On unconditional jump we should recurse as well
|
||||||
const auto jump_destination = get_absolute_address(instruction, current_address);
|
const auto jump_destination = get_absolute_address(instruction, current_address);
|
||||||
|
|
||||||
@@ -304,22 +346,6 @@ namespace koalageddon::steamclient {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONSTRUCT_ORDINAL_MAP(INTERFACE) \
|
|
||||||
Set<uintptr_t> 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)
|
void process_interface_selector( // NOLINT(misc-no-recursion)
|
||||||
const uintptr_t start_address,
|
const uintptr_t start_address,
|
||||||
Set<uintptr_t>& visited_addresses
|
Set<uintptr_t>& visited_addresses
|
||||||
@@ -360,12 +386,7 @@ namespace koalageddon::steamclient {
|
|||||||
if (interface_name_opt) {
|
if (interface_name_opt) {
|
||||||
const auto& interface_name = *interface_name_opt;
|
const auto& interface_name = *interface_name_opt;
|
||||||
|
|
||||||
LOG_DEBUG("Detected interface: '{}'", interface_name)
|
detour_interface_selector(interface_name, function_selector_address);
|
||||||
|
|
||||||
DETOUR_SELECTOR(IClientAppManager)
|
|
||||||
DETOUR_SELECTOR(IClientApps)
|
|
||||||
DETOUR_SELECTOR(IClientInventory)
|
|
||||||
DETOUR_SELECTOR(IClientUser)
|
|
||||||
}
|
}
|
||||||
} else if (instruction.meta.category == ZYDIS_CATEGORY_COND_BR) {
|
} else if (instruction.meta.category == ZYDIS_CATEGORY_COND_BR) {
|
||||||
const auto jump_taken_destination = get_absolute_address(instruction, current_address);
|
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")
|
LOG_TRACE("Breaking recursion due to unconditional branch")
|
||||||
return;
|
return;
|
||||||
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP &&
|
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP &&
|
||||||
operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
operand.mem.scale == sizeof(uintptr_t) &&
|
operand.mem.scale == sizeof(uintptr_t) &&
|
||||||
operand.mem.disp.has_displacement
|
operand.mem.disp.has_displacement
|
||||||
) {
|
) {
|
||||||
// Special handling for jump tables. Guaranteed to be present in the interface selector.
|
// Special handling for jump tables. Guaranteed to be present in the interface selector.
|
||||||
const auto* table = (uintptr_t*) operand.mem.disp.value;
|
const auto* table = (uintptr_t*) operand.mem.disp.value;
|
||||||
@@ -433,4 +454,5 @@ namespace koalageddon::steamclient {
|
|||||||
Set<uintptr_t> visited_addresses;
|
Set<uintptr_t> visited_addresses;
|
||||||
process_interface_selector(interface_selector_address, visited_addresses);
|
process_interface_selector(interface_selector_address, visited_addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,14 @@ VIRTUAL(bool) IClientInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint
|
|||||||
// IClientUser
|
// IClientUser
|
||||||
VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t));
|
VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t));
|
||||||
|
|
||||||
|
// IClientUtils
|
||||||
|
VIRTUAL(AppId_t) IClientUtils_GetAppID(PARAMS());
|
||||||
|
|
||||||
namespace koalageddon::steamclient {
|
namespace koalageddon::steamclient {
|
||||||
|
|
||||||
|
/// We need this interface in other IClient* functions in order to call other functions
|
||||||
|
extern Map<String, void*> interface_name_to_address_map;
|
||||||
|
|
||||||
void process_client_engine(uintptr_t interface);
|
void process_client_engine(uintptr_t interface);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,25 +13,34 @@ namespace smoke_api::config {
|
|||||||
|
|
||||||
if (exists(path)) {
|
if (exists(path)) {
|
||||||
try {
|
try {
|
||||||
instance = Json::parse(koalabox::io::read_file(path)).get<Config>();
|
const auto config_str = koalabox::io::read_file(path);
|
||||||
|
|
||||||
|
LOG_DEBUG("Parsing config:\n{}", config_str)
|
||||||
|
|
||||||
|
instance = Json::parse(config_str).get<Config>();
|
||||||
|
|
||||||
} catch (const Exception& e) {
|
} 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<bool()>& original_function) {
|
Vector<DLC> get_extra_dlcs(AppId_t app_id) {
|
||||||
const auto app_id_str = std::to_string(app_id);
|
return DLC::get_dlcs_from_apps(instance.extra_dlcs, app_id);
|
||||||
const auto dlc_id_str = std::to_string(dlc_id);
|
}
|
||||||
|
|
||||||
|
bool is_dlc_unlocked(AppId_t app_id, AppId_t dlc_id, const Function<bool()>& original_function) {
|
||||||
auto status = instance.default_app_status;
|
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)) {
|
if (instance.override_app_status.contains(app_id_str)) {
|
||||||
status = instance.override_app_status[app_id_str];
|
status = instance.override_app_status[app_id_str];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.override_app_status.contains(dlc_id_str)) {
|
const auto dlc_id_str = std::to_string(dlc_id);
|
||||||
status = instance.override_app_status[dlc_id_str];
|
if (instance.override_dlc_status.contains(dlc_id_str)) {
|
||||||
|
status = instance.override_dlc_status[dlc_id_str];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_unlocked;
|
bool is_unlocked;
|
||||||
@@ -47,15 +56,18 @@ namespace smoke_api::config {
|
|||||||
is_unlocked = original_function();
|
is_unlocked = original_function();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_TRACE(
|
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
|
app_id_str, dlc_id_str, Json(status).dump(), original_function(), is_unlocked
|
||||||
)
|
)
|
||||||
|
|
||||||
return is_unlocked;
|
return is_unlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<DLC> get_extra_dlcs(AppId_t app_id) {
|
DLL_EXPORT(void) ReloadConfig() {
|
||||||
return DLC::get_dlcs_from_apps(instance.extra_dlcs, app_id);
|
LOG_INFO("Reloading config")
|
||||||
|
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace smoke_api::config {
|
|||||||
bool unlock_family_sharing = true;
|
bool unlock_family_sharing = true;
|
||||||
AppStatus default_app_status = AppStatus::UNLOCKED;
|
AppStatus default_app_status = AppStatus::UNLOCKED;
|
||||||
Map<String, AppStatus> override_app_status;
|
Map<String, AppStatus> override_app_status;
|
||||||
|
Map<String, AppStatus> override_dlc_status;
|
||||||
AppDlcNameMap extra_dlcs;
|
AppDlcNameMap extra_dlcs;
|
||||||
bool auto_inject_inventory = true;
|
bool auto_inject_inventory = true;
|
||||||
Vector<uint32_t> extra_inventory_items;
|
Vector<uint32_t> extra_inventory_items;
|
||||||
@@ -38,6 +39,7 @@ namespace smoke_api::config {
|
|||||||
unlock_family_sharing,
|
unlock_family_sharing,
|
||||||
default_app_status,
|
default_app_status,
|
||||||
override_app_status,
|
override_app_status,
|
||||||
|
override_dlc_status,
|
||||||
extra_dlcs,
|
extra_dlcs,
|
||||||
auto_inject_inventory,
|
auto_inject_inventory,
|
||||||
extra_inventory_items,
|
extra_inventory_items,
|
||||||
@@ -49,7 +51,7 @@ namespace smoke_api::config {
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const Function<bool()>& original_function);
|
|
||||||
|
|
||||||
Vector<DLC> get_extra_dlcs(AppId_t app_id);
|
Vector<DLC> get_extra_dlcs(AppId_t app_id);
|
||||||
|
|
||||||
|
bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const Function<bool()>& original_function);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,4 +128,5 @@ namespace smoke_api {
|
|||||||
LOG_ERROR("Shutdown error: {}", ex.what())
|
LOG_ERROR("Shutdown error: {}", ex.what())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,26 +3,27 @@
|
|||||||
#include <core/types.hpp>
|
#include <core/types.hpp>
|
||||||
|
|
||||||
// Flat
|
// Flat
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps*, AppId_t);
|
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void*, AppId_t);
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps*, AppId_t);
|
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void*, AppId_t);
|
||||||
DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps*);
|
DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(void*);
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(ISteamApps*, int, AppId_t*, bool*, char*, int);
|
DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(void*, 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(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(void*, HSteamUser, HSteamPipe, const char*);
|
||||||
DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(ISteamInventory*, SteamInventoryResult_t);
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
|
DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(void*, SteamInventoryResult_t);
|
||||||
ISteamInventory*, SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(void*, SteamInventoryResult_t, SteamItemDetails_t*, uint32_t*);
|
||||||
);
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
|
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_CheckResultSteamID(void*, SteamInventoryResult_t, CSteamID);
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(ISteamInventory*, SteamInventoryResult_t*);
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(void*, SteamInventoryResult_t*);
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
|
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_SerializeResult(void*, SteamInventoryResult_t, void*, uint32_t*);
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(ISteamInventory*, SteamItemDef_t*, uint32_t*);
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(void*, SteamItemDef_t*, uint32_t*);
|
||||||
|
|
||||||
|
DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp(void*, CSteamID, AppId_t);
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser, const char*);
|
DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser, const char*);
|
||||||
|
|||||||
@@ -3,30 +3,31 @@
|
|||||||
#include <steam_impl/steam_client.hpp>
|
#include <steam_impl/steam_client.hpp>
|
||||||
#include <steam_impl/steam_inventory.hpp>
|
#include <steam_impl/steam_inventory.hpp>
|
||||||
#include <steam_impl/steam_user.hpp>
|
#include <steam_impl/steam_user.hpp>
|
||||||
|
#include <steam_impl/steam_impl.hpp>
|
||||||
|
|
||||||
// ISteamApps
|
// 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(
|
return steam_apps::IsDlcUnlocked(
|
||||||
__func__, 0, appID, [&]() {
|
__func__, 0, dlcID, [&]() {
|
||||||
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsSubscribedApp)
|
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(
|
return steam_apps::IsDlcUnlocked(
|
||||||
__func__, 0, appID, [&]() {
|
__func__, 0, dlcID, [&]() {
|
||||||
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsDlcInstalled)
|
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(
|
return steam_apps::GetDLCCount(
|
||||||
__func__, 0, [&]() {
|
__func__, 0, [&]() {
|
||||||
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_GetDLCCount)
|
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(
|
DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(
|
||||||
ISteamApps* self,
|
void* self,
|
||||||
int iDLC,
|
int iDLC,
|
||||||
AppId_t* pDlcID,
|
AppId_t* pDlcID,
|
||||||
bool* pbAvailable,
|
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
|
// ISteamClient
|
||||||
|
|
||||||
DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
|
DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
|
||||||
ISteamClient* self,
|
void* self,
|
||||||
HSteamUser hSteamUser,
|
HSteamUser hSteamUser,
|
||||||
HSteamPipe hSteamPipe,
|
HSteamPipe hSteamPipe,
|
||||||
const char* pchVersion
|
const char* pchVersion
|
||||||
@@ -95,7 +80,7 @@ DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
|
|||||||
// ISteamInventory
|
// ISteamInventory
|
||||||
|
|
||||||
DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
|
DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t resultHandle
|
SteamInventoryResult_t resultHandle
|
||||||
) {
|
) {
|
||||||
return steam_inventory::GetResultStatus(
|
return steam_inventory::GetResultStatus(
|
||||||
@@ -108,7 +93,7 @@ DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t resultHandle,
|
SteamInventoryResult_t resultHandle,
|
||||||
SteamItemDetails_t* pOutItemsArray,
|
SteamItemDetails_t* pOutItemsArray,
|
||||||
uint32_t* punOutItemsArraySize
|
uint32_t* punOutItemsArraySize
|
||||||
@@ -129,7 +114,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t resultHandle,
|
SteamInventoryResult_t resultHandle,
|
||||||
uint32_t unItemIndex,
|
uint32_t unItemIndex,
|
||||||
const char* pchPropertyName,
|
const char* pchPropertyName,
|
||||||
@@ -148,7 +133,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t resultHandle,
|
SteamInventoryResult_t resultHandle,
|
||||||
CSteamID steamIDExpected
|
CSteamID steamIDExpected
|
||||||
) {
|
) {
|
||||||
@@ -162,7 +147,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t* pResultHandle
|
SteamInventoryResult_t* pResultHandle
|
||||||
) {
|
) {
|
||||||
return steam_inventory::GetAllItems(
|
return steam_inventory::GetAllItems(
|
||||||
@@ -175,7 +160,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t* pResultHandle,
|
SteamInventoryResult_t* pResultHandle,
|
||||||
const SteamItemInstanceID_t* pInstanceIDs,
|
const SteamItemInstanceID_t* pInstanceIDs,
|
||||||
uint32_t unCountInstanceIDs
|
uint32_t unCountInstanceIDs
|
||||||
@@ -190,7 +175,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamInventoryResult_t resultHandle,
|
SteamInventoryResult_t resultHandle,
|
||||||
void* pOutBuffer,
|
void* pOutBuffer,
|
||||||
uint32_t* punOutBufferSize
|
uint32_t* punOutBufferSize
|
||||||
@@ -205,7 +190,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(
|
DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(
|
||||||
ISteamInventory* self,
|
void* self,
|
||||||
SteamItemDef_t* pItemDefIDs,
|
SteamItemDef_t* pItemDefIDs,
|
||||||
uint32_t* punItemDefIDsArraySize
|
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);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include <steam_api_virtuals/steam_api_virtuals.hpp>
|
#include <steam_api_virtuals/steam_api_virtuals.hpp>
|
||||||
#include <steam_impl/steam_user.hpp>
|
#include <steam_impl/steam_user.hpp>
|
||||||
|
#include <steam_impl/steam_impl.hpp>
|
||||||
|
|
||||||
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t appID)) {
|
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t dlcID)) {
|
||||||
return steam_user::UserHasLicenseForApp(
|
return steam_user::UserHasLicenseForApp(
|
||||||
__func__, appID, [&]() {
|
__func__, steam_impl::get_app_id_or_throw(), dlcID, [&]() {
|
||||||
GET_ORIGINAL_HOOKED_FUNCTION(ISteamUser_UserHasLicenseForApp)
|
GET_ORIGINAL_HOOKED_FUNCTION(ISteamUser_UserHasLicenseForApp)
|
||||||
|
|
||||||
return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, appID));
|
return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, dlcID));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,4 +193,5 @@ namespace steam_apps {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace steam_inventory {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: investigate if we can get app id in koalageddon mode
|
|
||||||
bool GetResultItems(
|
bool GetResultItems(
|
||||||
const String& function_name,
|
const String& function_name,
|
||||||
const SteamInventoryResult_t resultHandle,
|
const SteamInventoryResult_t resultHandle,
|
||||||
|
|||||||
@@ -6,23 +6,24 @@ namespace steam_user {
|
|||||||
|
|
||||||
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
||||||
const String& function_name,
|
const String& function_name,
|
||||||
AppId_t appID,
|
AppId_t appId,
|
||||||
|
AppId_t dlcId,
|
||||||
const Function<EUserHasLicenseForAppResult()>& original_function
|
const Function<EUserHasLicenseForAppResult()>& original_function
|
||||||
) {
|
) {
|
||||||
const auto result = original_function();
|
const auto result = original_function();
|
||||||
|
|
||||||
if (result == k_EUserHasLicenseResultNoAuth) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto has_license = smoke_api::config::is_dlc_unlocked(
|
const auto has_license = smoke_api::config::is_dlc_unlocked(
|
||||||
0, appID, [&]() {
|
appId, dlcId, [&]() {
|
||||||
return result == k_EUserHasLicenseResultHasLicense;
|
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
|
return has_license
|
||||||
? k_EUserHasLicenseResultHasLicense
|
? k_EUserHasLicenseResultHasLicense
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <core/types.hpp>
|
#include <core/types.hpp>
|
||||||
#include <koalabox/core.hpp>
|
|
||||||
|
|
||||||
namespace steam_user {
|
namespace steam_user {
|
||||||
|
|
||||||
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
||||||
const String& function_name,
|
const String& function_name,
|
||||||
AppId_t appID,
|
AppId_t appId,
|
||||||
|
AppId_t dlcId,
|
||||||
const Function<EUserHasLicenseForAppResult()>& original_function
|
const Function<EUserHasLicenseForAppResult()>& original_function
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user