mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2026-01-26 06:22:51 -05:00
Initial commit
This commit is contained in:
268
src/steam_impl/steam_apps.cpp
Normal file
268
src/steam_impl/steam_apps.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
#include <smoke_api/smoke_api.hpp>
|
||||
#include <steam_impl/steam_impl.hpp>
|
||||
|
||||
#include <koalabox/io.hpp>
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
|
||||
using namespace smoke_api;
|
||||
|
||||
constexpr auto max_dlc = 64;
|
||||
|
||||
Vector<AppId_t> cached_dlcs;
|
||||
int original_dlc_count = 0;
|
||||
|
||||
Path get_cache_path() {
|
||||
static const auto path = self_directory / "SmokeAPI.cache.json";
|
||||
return path;
|
||||
}
|
||||
|
||||
void read_from_cache(const String& app_id_str) {
|
||||
try {
|
||||
const auto text = io::read_file(get_cache_path());
|
||||
if (text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto json = nlohmann::json::parse(text);
|
||||
|
||||
cached_dlcs = json[app_id_str]["dlc"].get<decltype(cached_dlcs)>();
|
||||
|
||||
logger->debug("Read {} DLCs from cache", cached_dlcs.size());
|
||||
} catch (const Exception& ex) {
|
||||
logger->error("Error reading DLCs from cache: {}", ex.what());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void save_to_cache(const String& app_id_str) {
|
||||
try {
|
||||
logger->debug("Saving {} DLCs to cache", cached_dlcs.size());
|
||||
|
||||
const nlohmann::json json = {
|
||||
{app_id_str, {
|
||||
{"dlc", cached_dlcs}
|
||||
}}
|
||||
};
|
||||
|
||||
io::write_file(get_cache_path(), json.dump(2));
|
||||
} catch (const Exception& ex) {
|
||||
logger->error("Error saving DLCs to cache: {}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
void fetch_and_cache_dlcs() {
|
||||
uint32_t app_id;
|
||||
try {
|
||||
app_id = steam_functions::get_app_id_or_throw();
|
||||
logger->info("Detected App ID: {}", app_id);
|
||||
} catch (const Exception& ex) {
|
||||
logger->error("Failed to get app ID: {}", ex.what());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto app_id_str = std::to_string(app_id);
|
||||
|
||||
const auto fetch_from_steam = [&]() {
|
||||
const auto url = fmt::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id_str);
|
||||
const auto res = cpr::Get(cpr::Url{url});
|
||||
|
||||
if (res.status_code != cpr::status::HTTP_OK) {
|
||||
throw util::exception(
|
||||
"Steam Web API didn't responded with HTTP_OK result. Code: {}, Error: {},\n"
|
||||
"Headers:\n{}\nBody:\n{}",
|
||||
res.status_code, (int) res.error.code, res.raw_header, res.text
|
||||
);
|
||||
}
|
||||
|
||||
const auto json = nlohmann::json::parse(res.text);
|
||||
|
||||
|
||||
if (json["success"] != 1) {
|
||||
throw util::exception("Web API responded with 'success': 1.");
|
||||
}
|
||||
|
||||
Vector<AppId_t> dlcs;
|
||||
|
||||
for (const auto& dlc: json["dlcs"]) {
|
||||
const auto app_id = dlc["appid"].get<String>();
|
||||
dlcs.emplace_back(std::stoi(app_id));
|
||||
}
|
||||
|
||||
return dlcs;
|
||||
};
|
||||
|
||||
const auto fetch_from_github = [&]() {
|
||||
const String url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/main/steam/v1/dlc.json";
|
||||
const auto res = cpr::Get(cpr::Url{url});
|
||||
|
||||
if (res.status_code != cpr::status::HTTP_OK) {
|
||||
throw util::exception(
|
||||
"Github Web API didn't responded with HTTP_OK result. Code: {}, Error: {},\n"
|
||||
"Headers:\n{}\nBody:\n{}",
|
||||
res.status_code, (int) res.error.code, res.raw_header, res.text
|
||||
);
|
||||
}
|
||||
|
||||
const auto json = nlohmann::json::parse(res.text);
|
||||
|
||||
if (json.contains(app_id_str)) {
|
||||
return json[app_id_str].get<decltype(cached_dlcs)>();
|
||||
}
|
||||
|
||||
return Vector<AppId_t>{};
|
||||
};
|
||||
|
||||
try {
|
||||
read_from_cache(app_id_str);
|
||||
|
||||
auto list1 = fetch_from_steam();
|
||||
auto list2 = fetch_from_github();
|
||||
list1.insert(list1.end(), list2.begin(), list2.end());
|
||||
Set<AppId_t> fetched_dlcs(list1.begin(), list1.end());
|
||||
|
||||
if (fetched_dlcs.size() > cached_dlcs.size()) {
|
||||
cached_dlcs = Vector<AppId_t>(fetched_dlcs.begin(), fetched_dlcs.end());
|
||||
}
|
||||
|
||||
save_to_cache(app_id_str);
|
||||
} catch (const Exception& ex) {
|
||||
logger->error("Failed to fetch DLC: {}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace steam_apps{
|
||||
|
||||
bool IsSubscribedApp(const String& function_name, AppId_t appID) {
|
||||
const auto subscribed = should_unlock(appID);
|
||||
|
||||
logger->info("{} -> App ID: {}, Subscribed: {}", function_name, appID, subscribed);
|
||||
|
||||
return subscribed;
|
||||
}
|
||||
|
||||
bool IsDlcInstalled(const String& function_name, AppId_t appID) {
|
||||
const auto installed = should_unlock(appID);
|
||||
|
||||
logger->info("{} -> App ID: {}, Installed: {}", function_name, appID, installed);
|
||||
|
||||
return installed;
|
||||
}
|
||||
|
||||
int GetDLCCount(const String& function_name, const std::function<int()>& original_function) {
|
||||
static std::mutex section;
|
||||
std::lock_guard<std::mutex> guard(section);
|
||||
|
||||
// Compute count only once
|
||||
static int total_count = [&]() {
|
||||
original_dlc_count = original_function();
|
||||
logger->debug("{} -> Original DLC count: {}", function_name, original_dlc_count);
|
||||
|
||||
const auto injected_count = static_cast<int>(config.dlc_ids.size());
|
||||
logger->debug("{} -> Injected DLC count: {}", function_name, injected_count);
|
||||
|
||||
if (original_dlc_count < max_dlc) {
|
||||
// Steamworks may max out this value at 64, depending on how much unowned DLCs the user has.
|
||||
// Despite this limit, some games with more than 64 DLCs still keep using this method.
|
||||
// This means we have to fetch full list of IDs from web api.
|
||||
|
||||
return original_dlc_count + injected_count;
|
||||
}
|
||||
|
||||
logger->debug("Game has {} or more DLCs. Fetching DLCs from a web API.", max_dlc);
|
||||
fetch_and_cache_dlcs();
|
||||
|
||||
const auto fetched_count = static_cast<int>(cached_dlcs.size());
|
||||
logger->debug("{} -> Fetched/cached DLC count: {}", function_name, fetched_count);
|
||||
|
||||
return fetched_count + injected_count;
|
||||
}();
|
||||
|
||||
logger->info("{} -> Responding with DLC count: {}", function_name, total_count);
|
||||
|
||||
return total_count;
|
||||
}
|
||||
|
||||
bool GetDLCDataByIndex(
|
||||
const String& function_name,
|
||||
int iDLC,
|
||||
AppId_t* pAppID,
|
||||
bool* pbAvailable,
|
||||
char* pchName,
|
||||
int cchNameBufferSize,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto print_dlc_info = [&](const String& tag) {
|
||||
logger->info(
|
||||
"{} -> [{}] index: {}, App ID: {}, available: {}, name: '{}'",
|
||||
function_name, tag, iDLC, *pAppID, *pbAvailable, pchName
|
||||
);
|
||||
};
|
||||
|
||||
const auto fill_dlc_info = [&](const AppId_t id) {
|
||||
*pAppID = id;
|
||||
*pbAvailable = should_unlock(id);
|
||||
|
||||
auto name = fmt::format("DLC #{} with ID: {} ", iDLC, id);
|
||||
name = name.substr(0, cchNameBufferSize);
|
||||
*name.rbegin() = '\0';
|
||||
memcpy_s(pchName, cchNameBufferSize, name.c_str(), name.size());
|
||||
};
|
||||
|
||||
const auto inject_dlc = [&](const int index) {
|
||||
if (index >= config.dlc_ids.size()) {
|
||||
logger->error("{} -> Out of bounds injected index: {}", function_name, index);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto app_id = config.dlc_ids[index];
|
||||
fill_dlc_info(app_id);
|
||||
print_dlc_info("injected");
|
||||
return true;
|
||||
};
|
||||
|
||||
// Original response
|
||||
if (cached_dlcs.empty()) {
|
||||
// Original DLC index
|
||||
if (iDLC < original_dlc_count) {
|
||||
const auto success = original_function();
|
||||
|
||||
if (success) {
|
||||
*pbAvailable = should_unlock(*pAppID);
|
||||
print_dlc_info("original");
|
||||
} else {
|
||||
logger->warn("{} -> original function failed for index: {}", function_name, iDLC);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// Injected DLC index (after original)
|
||||
const auto index = iDLC - original_dlc_count;
|
||||
return inject_dlc(index);
|
||||
}
|
||||
|
||||
// Cached response
|
||||
const auto total_size = cached_dlcs.size() + config.dlc_ids.size();
|
||||
if (iDLC < 0 or iDLC >= total_size) {
|
||||
logger->error(
|
||||
"{} -> Game accessed out of bounds DLC index: {}. Total size: {}",
|
||||
function_name, iDLC, total_size
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cached index
|
||||
if (iDLC < cached_dlcs.size()) {
|
||||
const auto app_id = cached_dlcs[iDLC];
|
||||
fill_dlc_info(app_id);
|
||||
print_dlc_info("cached");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Injected DLC index (after cached)
|
||||
|
||||
const auto index = iDLC - static_cast<int>(cached_dlcs.size());
|
||||
return inject_dlc(index);
|
||||
}
|
||||
}
|
||||
21
src/steam_impl/steam_client.cpp
Normal file
21
src/steam_impl/steam_client.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <steam_impl/steam_impl.hpp>
|
||||
|
||||
namespace steam_client{
|
||||
|
||||
void* GetGenericInterface(
|
||||
const String& function_name,
|
||||
const String& interface_version,
|
||||
const std::function<void*()>& original_function
|
||||
) {
|
||||
logger->debug("{} -> Version: '{}'", function_name, interface_version);
|
||||
|
||||
auto* const interface = original_function();
|
||||
|
||||
logger->debug("{} -> Result: {}", function_name, fmt::ptr(interface));
|
||||
|
||||
steam_functions::hook_virtuals(interface, interface_version);
|
||||
|
||||
return interface;
|
||||
}
|
||||
|
||||
}
|
||||
116
src/steam_impl/steam_impl.hpp
Normal file
116
src/steam_impl/steam_impl.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <steam_functions/steam_functions.hpp>
|
||||
|
||||
using namespace koalabox;
|
||||
|
||||
namespace steam_apps {
|
||||
|
||||
bool IsSubscribedApp(const String& function_name, AppId_t appID);
|
||||
|
||||
bool IsDlcInstalled(const String& function_name, AppId_t appID);
|
||||
|
||||
int GetDLCCount(const String& function_name, const std::function<int()>& original_function);
|
||||
|
||||
bool GetDLCDataByIndex(
|
||||
const String& function_name,
|
||||
int iDLC,
|
||||
AppId_t* pAppID,
|
||||
bool* pbAvailable,
|
||||
char* pchName,
|
||||
int cchNameBufferSize,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
namespace steam_user {
|
||||
|
||||
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
||||
const String& function_name,
|
||||
AppId_t appID,
|
||||
const std::function<EUserHasLicenseForAppResult()>& original_function
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
namespace steam_client {
|
||||
|
||||
void* GetGenericInterface(
|
||||
const String& function_name,
|
||||
const String& interface_version,
|
||||
const std::function<void*()>& original_function
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
namespace steam_inventory {
|
||||
|
||||
EResult GetResultStatus(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
const std::function<EResult()>& original_function
|
||||
);
|
||||
|
||||
bool GetResultItems(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
SteamItemDetails_t* pOutItemsArray,
|
||||
uint32_t* punOutItemsArraySize,
|
||||
const std::function<bool()>& original_function,
|
||||
const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids
|
||||
);
|
||||
|
||||
bool GetResultItemProperty(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
uint32_t unItemIndex,
|
||||
const char* pchPropertyName,
|
||||
char* pchValueBuffer,
|
||||
const uint32_t* punValueBufferSizeOut,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool GetAllItems(
|
||||
const String& function_name,
|
||||
const SteamInventoryResult_t* pResultHandle,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool GetItemsByID(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t* pResultHandle,
|
||||
const SteamItemInstanceID_t* pInstanceIDs,
|
||||
uint32_t unCountInstanceIDs,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool SerializeResult(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
void* pOutBuffer,
|
||||
uint32_t* punOutBufferSize,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool GetItemDefinitionIDs(
|
||||
const String& function_name,
|
||||
const SteamItemDef_t* pItemDefIDs,
|
||||
uint32_t* punItemDefIDsArraySize,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool GetItemDefinitionProperty(
|
||||
const String& function_name,
|
||||
SteamItemDef_t iDefinition,
|
||||
const char* pchPropertyName,
|
||||
char* pchValueBuffer,
|
||||
const uint32_t* punValueBufferSizeOut,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
|
||||
bool CheckResultSteamID(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
CSteamID steamIDExpected,
|
||||
const std::function<bool()>& original_function
|
||||
);
|
||||
}
|
||||
258
src/steam_impl/steam_inventory.cpp
Normal file
258
src/steam_impl/steam_inventory.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
#include <steam_impl/steam_impl.hpp>
|
||||
#include <smoke_api/smoke_api.hpp>
|
||||
|
||||
namespace steam_inventory {
|
||||
|
||||
EResult GetResultStatus(
|
||||
const String& function_name,
|
||||
const SteamInventoryResult_t resultHandle,
|
||||
const std::function<EResult()>& original_function
|
||||
) {
|
||||
const auto status = original_function();
|
||||
|
||||
logger->debug("{} -> handle: {}, status: {}", function_name, resultHandle, (int) status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool GetResultItems(
|
||||
const String& function_name,
|
||||
const SteamInventoryResult_t resultHandle,
|
||||
SteamItemDetails_t* pOutItemsArray,
|
||||
uint32_t* punOutItemsArraySize,
|
||||
const std::function<bool()>& original_function,
|
||||
const std::function<bool(SteamItemDef_t*, uint32_t*)>& get_item_definition_ids
|
||||
) {
|
||||
static std::mutex section;
|
||||
std::lock_guard<std::mutex> guard(section);
|
||||
|
||||
const auto success = original_function();
|
||||
|
||||
auto print_item = [](const String& tag, const SteamItemDetails_t& item) {
|
||||
logger->debug(
|
||||
" [{}] definitionId: {}, itemId: {}, quantity: {}, flags: {}",
|
||||
tag, item.m_iDefinition, item.m_itemId, item.m_unQuantity, item.m_unFlags
|
||||
);
|
||||
};
|
||||
|
||||
if (not success) {
|
||||
logger->debug("{} -> original result is false", function_name);
|
||||
return success;
|
||||
}
|
||||
|
||||
if (punOutItemsArraySize == nullptr) {
|
||||
logger->error("{} -> arraySize pointer is null", function_name);
|
||||
return success;
|
||||
}
|
||||
|
||||
logger->debug(
|
||||
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
|
||||
function_name, resultHandle, fmt::ptr(pOutItemsArray), *punOutItemsArraySize
|
||||
);
|
||||
|
||||
static uint32_t original_count = 0;
|
||||
const auto injected_count = smoke_api::config.inventory_items.size();
|
||||
|
||||
// Automatically get inventory items from steam
|
||||
static Vector<SteamItemDef_t> auto_inventory_items;
|
||||
if (smoke_api::config.auto_inject_inventory) {
|
||||
static std::once_flag flag;
|
||||
std::call_once(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;
|
||||
logger->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 = smoke_api::config.inventory_items[i];
|
||||
|
||||
item = new_item(item_def_id);
|
||||
|
||||
print_item("injected", item);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GetResultItemProperty(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
uint32_t unItemIndex,
|
||||
const char* pchPropertyName,
|
||||
char* pchValueBuffer,
|
||||
const uint32_t* punValueBufferSizeOut,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
if (!success) {
|
||||
logger->warn("{} -> result is false", function_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger->debug(
|
||||
"{} -> handle: {}, index: {}, propertyName: '{}', buffer: {}",
|
||||
function_name, resultHandle, unItemIndex, pchPropertyName,
|
||||
String(pchValueBuffer, *punValueBufferSizeOut - 1)
|
||||
);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GetAllItems(
|
||||
const String& function_name,
|
||||
const SteamInventoryResult_t* pResultHandle,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
logger->debug("{} -> handle: {}", function_name, fmt::ptr(pResultHandle));
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool GetItemsByID(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t* pResultHandle,
|
||||
const SteamItemInstanceID_t* pInstanceIDs,
|
||||
const uint32_t unCountInstanceIDs,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
logger->trace("{} -> handle: {}", function_name, fmt::ptr(pResultHandle));
|
||||
|
||||
if (success && pInstanceIDs != nullptr) {
|
||||
for (int i = 0; i < unCountInstanceIDs; i++) {
|
||||
logger->trace(" index: {}, itemId: {}", i, pInstanceIDs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SerializeResult(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
void* pOutBuffer,
|
||||
uint32_t* punOutBufferSize,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
if (pOutBuffer != nullptr) {
|
||||
String buffer((char*) pOutBuffer, *punOutBufferSize);
|
||||
logger->debug("{} -> handle: {}, buffer: '{}'", function_name, resultHandle, buffer);
|
||||
} else {
|
||||
logger->debug("{} -> handle: {}, size: '{}'", function_name, resultHandle, *punOutBufferSize);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GetItemDefinitionIDs(
|
||||
const String& function_name,
|
||||
const SteamItemDef_t* pItemDefIDs,
|
||||
uint32_t* punItemDefIDsArraySize,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
if (!success) {
|
||||
logger->warn("{} -> result is false", function_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (punItemDefIDsArraySize) {
|
||||
logger->debug("{} -> size: '{}'", function_name, *punItemDefIDsArraySize);
|
||||
}
|
||||
|
||||
if (pItemDefIDs) { // Definitions were copied
|
||||
for (int i = 0; i < *punItemDefIDsArraySize; i++) {
|
||||
const auto& def = pItemDefIDs[i];
|
||||
logger->debug(" Definition index: '{}', ID: {}", i, def);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool GetItemDefinitionProperty(
|
||||
const String& function_name,
|
||||
SteamItemDef_t iDefinition,
|
||||
const char* pchPropertyName,
|
||||
char* pchValueBuffer,
|
||||
const uint32_t* punValueBufferSizeOut,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto success = original_function();
|
||||
|
||||
if (!success) {
|
||||
logger->warn("{} -> result is false", function_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger->debug(
|
||||
"{} -> Definition ID: {}, name: '{}', buffer: '{}'",
|
||||
function_name, iDefinition, pchPropertyName, String(pchValueBuffer, *punValueBufferSizeOut - 1)
|
||||
);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CheckResultSteamID(
|
||||
const String& function_name,
|
||||
SteamInventoryResult_t resultHandle,
|
||||
CSteamID steamIDExpected,
|
||||
const std::function<bool()>& original_function
|
||||
) {
|
||||
const auto result = original_function();
|
||||
|
||||
logger->debug(
|
||||
"{} -> handle: {}, steamID: {}, original result: {}",
|
||||
function_name, resultHandle, steamIDExpected, result
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
27
src/steam_impl/steam_user.cpp
Normal file
27
src/steam_impl/steam_user.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <steam_impl/steam_impl.hpp>
|
||||
#include <smoke_api/smoke_api.hpp>
|
||||
|
||||
namespace steam_user {
|
||||
|
||||
EUserHasLicenseForAppResult UserHasLicenseForApp(
|
||||
const String& function_name,
|
||||
AppId_t appID,
|
||||
const std::function<EUserHasLicenseForAppResult()>& original_function
|
||||
) {
|
||||
const auto result = original_function();
|
||||
|
||||
if (result == k_EUserHasLicenseResultNoAuth) {
|
||||
logger->warn("{} -> App ID: {}, Result: NoAuth", function_name, appID);
|
||||
return result;
|
||||
}
|
||||
|
||||
const auto has_license = smoke_api::should_unlock(appID);
|
||||
|
||||
logger->info("{} -> App ID: {}, HasLicense: {}", function_name, appID, has_license);
|
||||
|
||||
return has_license
|
||||
? k_EUserHasLicenseResultHasLicense
|
||||
: k_EUserHasLicenseResultDoesNotHaveLicense;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user