master
acidicoala 1 year ago
parent b1680fe3d7
commit a2cbf55819
No known key found for this signature in database
GPG Key ID: D24C6065B49C645B

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

@ -4,5 +4,6 @@
<inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true">
<option name="clangTidyChecks" value="-*,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,bugprone-*,abseil-*,cert-*,objc-*,readability-*,clang-analyzer-*,misc-*,-readability-magic-numbers,-bugprone-easily-swappable-parameters,-readability-implicit-bool-conversion,-readability-identifier-length,-readability-named-parameter,-readability-function-cognitive-complexity" />
</inspection_tool>
<inspection_tool class="ConstantFunctionResult" enabled="true" level="INFORMATION" enabled_by_default="true" editorAttributes="INFORMATION_ATTRIBUTES" />
</profile>
</component>

@ -35,8 +35,6 @@ configure_build_config(extra_build_config)
set(
SMOKE_API_SOURCES
src/core/cache.cpp
src/core/cache.hpp
src/core/config.cpp
src/core/config.hpp
src/core/globals.cpp
@ -44,9 +42,11 @@ set(
src/core/macros.hpp
src/core/paths.cpp
src/core/paths.hpp
src/core/steam_types.hpp
src/core/types.hpp
src/smoke_api/smoke_api.cpp
src/smoke_api/smoke_api.hpp
src/smoke_api/app_cache.cpp
src/smoke_api/app_cache.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
@ -73,12 +73,15 @@ set(
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
set(
SMOKE_API_SOURCES ${SMOKE_API_SOURCES}
src/koalageddon/cache.hpp
src/koalageddon/cache.cpp
src/koalageddon/koalageddon.hpp
src/koalageddon/koalageddon.cpp
src/koalageddon/vstdlib.cpp
src/koalageddon/vstdlib.hpp
src/koalageddon/steamclient.cpp
src/koalageddon/steamclient.hpp
src/koalageddon/types.hpp
src/koalageddon/vstdlib.cpp
src/koalageddon/vstdlib.hpp
src/steamclient_virtuals/client_app_manager.cpp
src/steamclient_virtuals/client_apps.cpp
src/steamclient_virtuals/client_inventory.cpp

@ -1 +1 @@
Subproject commit 15d5cfc2e515bc72e47da6c0c563820cff98551f
Subproject commit b076544f304c91859a2260e195846aaaa99e6567

@ -1,82 +0,0 @@
#include <core/cache.hpp>
#include <core/paths.hpp>
#include <koalabox/io.hpp>
#include <koalabox/logger.hpp>
namespace cache {
Cache read_cache_from_disk() {
try {
const auto cache_string = koalabox::io::read_file(paths::get_cache_path());
if (cache_string.empty()) {
return {};
}
return nlohmann::json::parse(cache_string).get<Cache>();
} catch (const Exception& e) {
LOG_WARN("{} -> Failed to read cache from disk: {}", __func__, e.what())
return {};
}
}
void write_cache_to_disk(const Cache& cache) {
try {
const auto cache_string = nlohmann::json(cache).dump(2);
koalabox::io::write_file(paths::get_cache_path(), cache_string);
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to write cache to disk: {}", __func__, e.what())
}
}
Vector<AppId_t> get_dlc_ids(AppId_t app_id) {
const auto cache = read_cache_from_disk();
const auto app_id_str = std::to_string(app_id);
if (cache.apps.contains(app_id_str)) {
return cache.apps.at(app_id_str).dlc_ids;
}
return {};
}
std::optional<koalageddon::KoalageddonConfig> get_koalageddon_config() {
const auto cache = read_cache_from_disk();
if (cache.koalageddon_config.is_null()) {
return std::nullopt;
}
return cache.koalageddon_config.get<koalageddon::KoalageddonConfig>();
}
void save_dlc_ids(AppId_t app_id, const Vector<AppId_t>& dlc_ids) {
LOG_DEBUG("{} -> Caching DLC IDs for the app: {}", __func__, app_id)
auto cache = read_cache_from_disk();
const auto app_id_str = std::to_string(app_id);
if (not cache.apps.contains(app_id_str)) {
cache.apps[app_id_str] = {};
}
cache.apps[app_id_str].dlc_ids = dlc_ids;
write_cache_to_disk(cache);
}
void save_koalageddon_config(const koalageddon::KoalageddonConfig& config) {
LOG_DEBUG("{} -> Caching koalageddon config", __func__)
auto cache = read_cache_from_disk();
cache.koalageddon_config = config;
write_cache_to_disk(cache);
}
}

@ -1,35 +0,0 @@
#pragma once
#include <koalabox/types.hpp>
#include <nlohmann/json.hpp>
#include <koalageddon/koalageddon.hpp>
#include <core/steam_types.hpp>
/**
* This namespace contains utility functions for reading from and writing to cache file on disk.
* All functions are intended to be safe to call, i.e. they should not throw exceptions.
*/
namespace cache {
struct App {
Vector<AppId_t> dlc_ids;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(App, dlc_ids) // NOLINT(misc-const-correctness)
};
struct Cache {
// Key represents App ID
Map<String, App> apps;
nlohmann::json koalageddon_config;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Cache, apps, koalageddon_config) // NOLINT(misc-const-correctness)
};
Vector<AppId_t> get_dlc_ids(AppId_t app_id);
std::optional<koalageddon::KoalageddonConfig> get_koalageddon_config();
void save_dlc_ids(AppId_t app_id, const Vector<AppId_t>& dlc_ids);
void save_koalageddon_config(const koalageddon::KoalageddonConfig& config);
}

@ -1,6 +1,6 @@
#pragma once
#include <nlohmann/json.hpp>
#include <koalabox/types.hpp>
#include <koalabox/core.hpp>
namespace config {
enum class AppStatus {
@ -41,7 +41,7 @@ namespace config {
bool auto_inject_inventory = true;
Vector<uint32_t> extra_inventory_items;
// We have to use general json type here since the library doesn't support std::optional
nlohmann::json koalageddon_config;
Json koalageddon_config;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
Config, $version, // NOLINT(misc-const-correctness)
@ -63,6 +63,8 @@ namespace config {
void init();
AppStatus get_app_status(uint32_t app_id);
DlcStatus get_dlc_status(uint32_t dlc_id);
bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const Function<bool()>& original_function);
}

@ -1,9 +1,11 @@
#include <core/globals.hpp>
namespace globals {
HMODULE smokeapi_handle = nullptr;
HMODULE steamapi_module = nullptr;
HMODULE vstdlib_module = nullptr;
HMODULE steamclient_module = nullptr;
Map<String, uintptr_t> address_map; // NOLINT(cert-err58-cpp)
}

@ -1,5 +1,6 @@
#pragma once
#include <koalabox/types.hpp>
#include <koalabox/core.hpp>
namespace globals {

@ -1,6 +1,6 @@
#pragma once
#include <koalabox/types.hpp>
#include <koalabox/core.hpp>
namespace paths {

@ -1,6 +1,8 @@
#pragma once
#include <cstdint>
#include <koalabox/core.hpp>
#define COMPILE_KOALAGEDDON _WIN64
using AppId_t = uint32_t;
using SteamInventoryResult_t = uint32_t;

@ -0,0 +1,33 @@
#include <koalageddon/cache.hpp>
#include <koalabox/cache.hpp>
#include <koalabox/logger.hpp>
constexpr auto KEY_KG_CONFIG = "koalageddon_config";
namespace koalageddon::cache {
std::optional<KoalageddonConfig> get_koalageddon_config() {
try {
const auto cache = koalabox::cache::read_from_cache(KEY_KG_CONFIG).value();
return cache.at(KEY_KG_CONFIG).get<KoalageddonConfig>();
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to get cached koalageddon config: {}", __func__, e.what())
return std::nullopt;
}
}
bool save_koalageddon_config(const KoalageddonConfig& config) {
try {
LOG_DEBUG("{} -> Caching koalageddon config", __func__)
return koalabox::cache::save_to_cache(KEY_KG_CONFIG, config);
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to cache koalageddon config: {}", __func__, e.what())
return false;
}
}
}

@ -0,0 +1,11 @@
#pragma once
#include <koalageddon/types.hpp>
namespace koalageddon::cache {
std::optional<KoalageddonConfig> get_koalageddon_config();
bool save_koalageddon_config(const KoalageddonConfig& config);
}

@ -1,19 +1,15 @@
#include <koalageddon/koalageddon.hpp>
#include <koalageddon/vstdlib.hpp>
#include <koalageddon/cache.hpp>
#include <build_config.h>
#include <core/cache.hpp>
#include <core/config.hpp>
#include <steam_functions/steam_functions.hpp>
#include <koalabox/dll_monitor.hpp>
#include <koalabox/http_client.hpp>
#include <koalabox/util.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/patcher.hpp>
#include <koalabox/win_util.hpp>
namespace koalageddon {
using namespace koalabox;
KoalageddonConfig config; // NOLINT(cert-err58-cpp)
/**
@ -34,7 +30,7 @@ namespace koalageddon {
try {
// Then try to fetch config from GitHub
const String url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/main/koalageddon/v2/steam.json";
config = http_client::fetch_json(url).get<decltype(config)>();
config = koalabox::http_client::fetch_json(url).get<decltype(config)>();
cache::save_koalageddon_config(config);
@ -46,7 +42,7 @@ namespace koalageddon {
try {
// Then try to get a cached copy of a previously fetched config.
// We expect this unboxing to throw exception if no koalageddon config is present.
config = *cache::get_koalageddon_config();
config = cache::get_koalageddon_config().value();
return "disk cache";
} catch (const Exception& ex) {
@ -66,10 +62,10 @@ namespace koalageddon {
}
).detach();
dll_monitor::init(
koalabox::dll_monitor::init_listener(
{VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& module_handle, const String& name) {
try {
if (util::strings_are_equal(name, VSTDLIB_DLL)) {
if (koalabox::util::strings_are_equal(name, VSTDLIB_DLL)) {
// VStdLib DLL handles Family Sharing functions
globals::vstdlib_module = module_handle;
@ -77,7 +73,7 @@ namespace koalageddon {
if (config::instance.unlock_family_sharing) {
DETOUR_VSTDLIB(Coroutine_Create)
}
} else if (util::strings_are_equal(name, STEAMCLIENT_DLL)) {
} else if (koalabox::util::strings_are_equal(name, STEAMCLIENT_DLL)) {
// SteamClient DLL handles unlocking functions
globals::steamclient_module = module_handle;
@ -86,7 +82,7 @@ namespace koalageddon {
}
if (globals::vstdlib_module != nullptr && globals::steamclient_module != nullptr) {
dll_monitor::shutdown();
koalabox::dll_monitor::shutdown_listener();
}
} catch (const Exception& ex) {
LOG_ERROR(

@ -1,34 +1,8 @@
#pragma once
#include <koalabox/types.hpp>
#include <nlohmann/json.hpp>
#include <koalageddon/types.hpp>
namespace koalageddon {
// Offset values are interpreted according to pointer arithmetic rules, i.e.
// 1 unit offset represents 4 and 8 bytes in 32-bit and 64-bit architectures respectively.
struct KoalageddonConfig {
uint32_t client_engine_steam_client_internal_ordinal = 12;
uint32_t steam_client_internal_interface_selector_ordinal = 18;
uint32_t vstdlib_callback_address_offset = 20;
uint32_t vstdlib_callback_data_offset = 0;
uint32_t vstdlib_callback_interceptor_address_offset = 1;
uint32_t vstdlib_callback_name_offset = 4;
// We do not use *_WITH_DEFAULT macro to ensure that overriding
// the koalageddon config requires definition of all keys
NLOHMANN_DEFINE_TYPE_INTRUSIVE(
KoalageddonConfig, // NOLINT(misc-const-correctness)
client_engine_steam_client_internal_ordinal,
steam_client_internal_interface_selector_ordinal,
vstdlib_callback_address_offset,
vstdlib_callback_data_offset,
vstdlib_callback_interceptor_address_offset,
vstdlib_callback_name_offset
)
};
extern KoalageddonConfig config;

@ -1,4 +1,4 @@
#include <koalabox/types.hpp>
#pragma once
namespace koalageddon::steamclient {

@ -0,0 +1,26 @@
#pragma once
#include <koalabox/core.hpp>
// Offset values are interpreted according to pointer arithmetic rules, i.e.
// 1 unit offset represents 4 and 8 bytes in 32-bit and 64-bit architectures respectively.
struct KoalageddonConfig {
uint32_t client_engine_steam_client_internal_ordinal = 12;
uint32_t steam_client_internal_interface_selector_ordinal = 18;
uint32_t vstdlib_callback_address_offset = 20;
uint32_t vstdlib_callback_data_offset = 0;
uint32_t vstdlib_callback_interceptor_address_offset = 1;
uint32_t vstdlib_callback_name_offset = 4;
// We do not use *_WITH_DEFAULT macro to ensure that overriding
// the koalageddon config requires definition of all keys
NLOHMANN_DEFINE_TYPE_INTRUSIVE(
KoalageddonConfig, // NOLINT(misc-const-correctness)
client_engine_steam_client_internal_ordinal,
steam_client_internal_interface_selector_ordinal,
vstdlib_callback_address_offset,
vstdlib_callback_data_offset,
vstdlib_callback_interceptor_address_offset,
vstdlib_callback_name_offset
)
};

@ -1,5 +1,4 @@
#include <core/macros.hpp>
#include <koalabox/types.hpp>
#include <koalageddon/koalageddon.hpp>
namespace koalageddon::vstdlib {

@ -0,0 +1,60 @@
#include <smoke_api/app_cache.hpp>
#include <core/paths.hpp>
#include <koalabox/cache.hpp>
#include <koalabox/logger.hpp>
struct App {
Vector<AppId_t> dlc_ids;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(App, dlc_ids) // NOLINT(misc-const-correctness)
};
using Apps = Map<String, App>;
constexpr auto KEY_APPS = "apps";
Apps get_cached_apps() {
try {
const auto cache = koalabox::cache::read_from_cache(KEY_APPS).value();
return cache.get<Apps>();
} catch (const Exception& e) {
LOG_WARN("{} -> Failed to get cached apps: {}", __func__, e.what())
return {};
}
}
namespace smoke_api::app_cache {
Vector<AppId_t> get_dlc_ids(AppId_t app_id) {
try {
LOG_DEBUG("{} -> Reading cached DLC IDs for the app: {}", __func__, app_id)
const auto app = get_cached_apps().at(std::to_string(app_id));
return app.dlc_ids;
} catch (const Exception& e) {
return {};
}
}
bool save_dlc_ids(AppId_t app_id, const Vector<AppId_t>& dlc_ids) {
try {
LOG_DEBUG("{} -> Caching DLC IDs for the app: {}", __func__, app_id)
auto apps = get_cached_apps();
apps[std::to_string(app_id)] = {
.dlc_ids = dlc_ids
};
return koalabox::cache::save_to_cache(KEY_APPS, apps);
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to cache DLC IDs fro the app: {}", __func__, app_id)
return false;
}
}
}

@ -0,0 +1,11 @@
#pragma once
#include <core/types.hpp>
namespace smoke_api::app_cache {
Vector<AppId_t> get_dlc_ids(AppId_t app_id);
bool save_dlc_ids(AppId_t app_id, const Vector<AppId_t>& dlc_ids);
}

@ -8,6 +8,7 @@
#include <koalabox/dll_monitor.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/hook.hpp>
#include <koalabox/cache.hpp>
#include <koalabox/loader.hpp>
#include <koalabox/win_util.hpp>
@ -16,65 +17,64 @@
#include <koalageddon/koalageddon.hpp>
#endif
namespace smoke_api {
using namespace koalabox;
void init_proxy_mode() {
LOG_INFO("🔀 Detected proxy mode")
void init_proxy_mode() {
LOG_INFO("🔀 Detected proxy mode")
globals::steamapi_module = koalabox::loader::load_original_library(paths::get_self_path(), STEAMAPI_DLL);
}
globals::steamapi_module = loader::load_original_library(paths::get_self_path(), STEAMAPI_DLL);
}
void init_hook_mode() {
LOG_INFO("🪝 Detected hook mode")
void init_hook_mode() {
LOG_INFO("🪝 Detected hook mode")
koalabox::dll_monitor::init_listener(
STEAMCLIENT_DLL, [](const HMODULE& library) {
globals::steamclient_module = library;
dll_monitor::init(
STEAMCLIENT_DLL, [](const HMODULE& library) {
globals::steamclient_module = library;
DETOUR_STEAMCLIENT(CreateInterface)
DETOUR_STEAMCLIENT(CreateInterface)
koalabox::dll_monitor::shutdown_listener();
}
);
// Hooking steam_api has shown itself to be less desirable than steamclient
// for the reasons outlined below:
//
// Calling original in flat functions will actually call the hooked functions
// because the original function redirects the execution to a function taken
// from self pointer, which would have been hooked by SteamInternal_*Interface
// functions.
//
// Furthermore, turns out that many flat functions share the same body,
// which looks like the following snippet:
//
// mov rax, qword ptr ds:[rcx]
// jmp qword ptr ds:[rax+immediate]
//
// This means that we end up inadvertently hooking unintended functions.
// Given that hooking steam_api has no apparent benefits, but has inherent flaws,
// the support for it has been dropped from this project.
}
dll_monitor::shutdown();
}
);
// Hooking steam_api has shown itself to be less desirable than steamclient
// for the reasons outlined below:
//
// Calling original in flat functions will actually call the hooked functions
// because the original function redirects the execution to a function taken
// from self pointer, which would have been hooked by SteamInternal_*Interface
// functions.
//
// Furthermore, turns out that many flat functions share the same body,
// which looks like the following snippet:
//
// mov rax, qword ptr ds:[rcx]
// jmp qword ptr ds:[rax+immediate]
//
// This means that we end up inadvertently hooking unintended functions.
// Given that hooking steam_api has no apparent benefits, but has inherent flaws,
// the support for it has been dropped from this project.
bool is_valve_steam(const String& exe_name) {
if (not koalabox::util::strings_are_equal(exe_name, "steam.exe")) {
return false;
}
bool is_valve_steam(const String& exe_name) {
if (not util::strings_are_equal(exe_name, "steam.exe")) {
return false;
}
const HMODULE steam_handle = koalabox::win_util::get_module_handle_or_throw(nullptr);
const auto manifest = koalabox::win_util::get_module_manifest(steam_handle);
const HMODULE steam_handle = win_util::get_module_handle_or_throw(nullptr);
const auto manifest = win_util::get_module_manifest(steam_handle);
// Verify that it's steam from valve, and not some other executable coincidentally named steam
// Verify that it's steam from valve, and not some other executable coincidentally named steam
if (!manifest) {
// Steam.exe is expected to have a manifest
return false;
}
if (!manifest) {
// Steam.exe is expected to have a manifest
return false;
}
// Steam.exe manifest is expected to contain this string
return manifest->find("valvesoftware.steam.steam") != String::npos;
}
// Steam.exe manifest is expected to contain this string
return manifest->find("valvesoftware.steam.steam") != String::npos;
}
namespace smoke_api {
void init(HMODULE module_handle) {
try {
@ -82,22 +82,23 @@ namespace smoke_api {
globals::smokeapi_handle = module_handle;
koalabox::cache::init_cache(paths::get_cache_path());
config::init();
if (config::instance.logging) {
logger::init_file_logger(paths::get_log_path());
koalabox::logger::init_file_logger(paths::get_log_path());
}
LOG_INFO("🐨 {} v{}", PROJECT_NAME, PROJECT_VERSION)
const auto exe_path = Path(win_util::get_module_file_name_or_throw(nullptr));
const auto exe_path = Path(koalabox::win_util::get_module_file_name_or_throw(nullptr));
const auto exe_name = exe_path.filename().string();
const auto exe_bitness = util::is_x64() ? 64 : 32;
LOG_DEBUG(R"(Process name: "{}" [{}-bit])", exe_name, exe_bitness)
LOG_DEBUG(R"(Process name: "{}" [{}-bit])", exe_name, BITNESS)
if (hook::is_hook_mode(globals::smokeapi_handle, STEAMAPI_DLL)) {
hook::init(true);
if (koalabox::hook::is_hook_mode(globals::smokeapi_handle, STEAMAPI_DLL)) {
koalabox::hook::init(true);
if (is_valve_steam(exe_name)) {
#ifndef _WIN64
@ -112,14 +113,14 @@ namespace smoke_api {
}
LOG_INFO("🚀 Initialization complete")
} catch (const Exception& ex) {
util::panic(fmt::format("Initialization error: {}", ex.what()));
koalabox::util::panic(fmt::format("Initialization error: {}", ex.what()));
}
}
void shutdown() {
try {
if (globals::steamapi_module != nullptr) {
win_util::free_library(globals::steamapi_module);
koalabox::win_util::free_library(globals::steamapi_module);
}
LOG_INFO("💀 Shutdown complete")

@ -1,5 +1,5 @@
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
#include <steam_impl/steam_apps.hpp>
#include <steam_impl/steam_client.hpp>
#include <steam_impl/steam_inventory.hpp>

@ -1,5 +1,5 @@
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
#include <steam_impl/steam_client.hpp>
#include <koalabox/hook.hpp>

@ -1,8 +1,7 @@
#pragma once
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <koalabox/types.hpp>
#include <core/types.hpp>
// TODO: Refactor into multiple headers

@ -1,16 +1,13 @@
#include <steam_impl/steam_apps.hpp>
#include <koalabox/io.hpp>
#include <koalabox/http_client.hpp>
#include <core/cache.hpp>
#include <smoke_api/app_cache.hpp>
#include <core/config.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/util.hpp>
#include <steam_functions/steam_functions.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
namespace steam_apps {
using namespace koalabox;
/// Steamworks may max GetDLCCount 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 get extra DLC IDs from local config, remote config, or cache.
@ -45,10 +42,10 @@ namespace steam_apps {
try {
// TODO: Refactor into api namespace
const auto url = fmt::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id_str);
const auto json = http_client::fetch_json(url);
const auto json = koalabox::http_client::fetch_json(url);
if (json["success"] != 1) {
throw util::exception("Web API responded with 'success' != 1");
throw koalabox::util::exception("Web API responded with 'success' != 1");
}
for (const auto& dlc: json["dlcs"]) {
@ -68,7 +65,7 @@ namespace steam_apps {
try {
const String url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/main/steam/v1/dlc.json";
const auto json = http_client::fetch_json(url);
const auto json = koalabox::http_client::fetch_json(url);
if (json.contains(app_id_str)) {
dlcs = json[app_id_str].get<decltype(dlcs)>();
@ -91,7 +88,7 @@ namespace steam_apps {
combined_dlcs.insert(github_dlcs.begin(), github_dlcs.end());
// There is no need to insert cached entries if both steam and GitHub requests were successful.
if (!total_success) {
const auto cache_dlcs = cache::get_dlc_ids(app_id);
const auto cache_dlcs = smoke_api::app_cache::get_dlc_ids(app_id);
combined_dlcs.insert(cached_dlcs.begin(), cached_dlcs.end());
}
@ -99,7 +96,7 @@ namespace steam_apps {
cached_dlcs.clear();
cached_dlcs.insert(cached_dlcs.begin(), combined_dlcs.begin(), combined_dlcs.end());
cache::save_dlc_ids(app_id, cached_dlcs);
smoke_api::app_cache::save_dlc_ids(app_id, cached_dlcs);
return total_success;
}

@ -1,5 +1,7 @@
#include <core/steam_types.hpp>
#include <koalabox/types.hpp>
#pragma once
#include <core/types.hpp>
#include <koalabox/core.hpp>
namespace steam_apps {

@ -1,4 +1,6 @@
#include <koalabox/types.hpp>
#pragma once
#include <koalabox/core.hpp>
namespace steam_client {

@ -1,5 +1,7 @@
#include <core/steam_types.hpp>
#include <koalabox/types.hpp>
#pragma once
#include <core/types.hpp>
#include <koalabox/core.hpp>
namespace steam_inventory {

@ -1,5 +1,7 @@
#include <core/steam_types.hpp>
#include <koalabox/types.hpp>
#pragma once
#include <core/types.hpp>
#include <koalabox/core.hpp>
namespace steam_user {

@ -1,5 +1,5 @@
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
#include <steam_impl/steam_apps.hpp>
VIRTUAL(bool) IClientAppManager_IsAppDlcInstalled(PARAMS(AppId_t app_id, AppId_t dlc_id)) {

@ -1,5 +1,5 @@
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
#include <steam_impl/steam_apps.hpp>
VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) {

@ -1,5 +1,5 @@
#include <core/macros.hpp>
#include <core/steam_types.hpp>
#include <core/types.hpp>
#include <steam_impl/steam_inventory.hpp>
#include <steam_functions/steam_functions.hpp>

Loading…
Cancel
Save