Reformat project

This commit is contained in:
acidicoala
2025-08-22 22:01:54 +05:00
parent 28650491b2
commit 29b1f66095
47 changed files with 1085 additions and 781 deletions

View File

@@ -1,30 +1,31 @@
#include <koalabox/http_client.hpp>
#include <koalabox/logger.hpp>
#include "smoke_api/types.hpp"
#include "smoke_api/api.hpp"
#include "smoke_api/types.hpp"
namespace api {
struct SteamResponse {
uint32_t success = 0;
std::vector<DLC> dlcs;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
SteamResponse, success, dlcs
SteamResponse,
success,
dlcs
) // NOLINT(misc-const-correctness)
};
std::optional<std::vector<DLC>> fetch_dlcs_from_github(AppId_t app_id) noexcept {
try {
const auto* url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/"
"main/steam/v2/dlc.json";
constexpr auto url = "https://raw.githubusercontent.com/"
"acidicoala/public-entitlements/main/steam/v2/dlc.json";
const auto json = koalabox::http_client::get_json(url);
const auto response = json.get<AppDlcNameMap>();
return DLC::get_dlcs_from_apps(response, app_id);
} catch (const nlohmann::json::exception& e) {
LOG_ERROR("Failed to fetch dlc list from GitHub: {}", e.what());
} catch(const nlohmann::json::exception& e) {
LOG_ERROR("Failed to fetch DLC list from GitHub: {}", e.what());
return std::nullopt;
}
}
@@ -37,17 +38,16 @@ namespace api {
fmt::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id);
const auto json = koalabox::http_client::get_json(url);
const auto response = json.get<SteamResponse>();
const auto [success, dlcs] = json.get<SteamResponse>();
if (response.success != 1) {
if(success != 1) {
throw std::runtime_error("Web API responded with 'success' != 1");
}
return response.dlcs;
} catch (const std::exception& e) {
return dlcs;
} catch(const std::exception& e) {
LOG_ERROR("Failed to fetch dlc list from Steam: {}", e.what());
return std::nullopt;
}
}
}
}

View File

@@ -3,9 +3,7 @@
#include "smoke_api/types.hpp"
namespace api {
std::optional<std::vector<DLC>> fetch_dlcs_from_github(AppId_t app_id) noexcept;
std::optional<std::vector<DLC>> fetch_dlcs_from_steam(AppId_t app_id) noexcept;
}

View File

@@ -6,20 +6,17 @@
constexpr auto KEY_APPS = "apps";
namespace {
AppDlcNameMap get_cached_apps() noexcept {
try {
return koalabox::cache::get(KEY_APPS).get<AppDlcNameMap>();
} catch (const std::exception& e) {
} catch(const std::exception& e) {
LOG_WARN("Failed to get cached apps: {}", e.what());
return {};
}
}
}
namespace smoke_api::cache {
std::vector<DLC> get_dlcs(AppId_t app_id) noexcept {
try {
LOG_DEBUG("Reading cached DLC IDs for the app: {}", app_id);
@@ -27,7 +24,7 @@ namespace smoke_api::cache {
const auto apps = get_cached_apps();
return DLC::get_dlcs_from_apps(apps, app_id);
} catch (const std::exception& e) {
} catch(const std::exception& e) {
LOG_ERROR("Error reading DLCs from disk cache: ", e.what());
return {};
@@ -43,11 +40,10 @@ namespace smoke_api::cache {
apps[std::to_string(app_id)] = App{.dlcs = DLC::get_dlc_map_from_vector(dlcs)};
return koalabox::cache::put(KEY_APPS, nlohmann::json(apps));
} catch (const std::exception& e) {
} catch(const std::exception& e) {
LOG_ERROR("Error saving DLCs to disk cache: {}", e.what());
return false;
}
}
}
}

View File

@@ -3,9 +3,7 @@
#include "types.hpp"
namespace smoke_api::cache {
std::vector<DLC> get_dlcs(AppId_t app_id) noexcept;
bool save_dlcs(AppId_t app_id, const std::vector<DLC>& dlcs) noexcept;
}

View File

@@ -7,7 +7,6 @@
namespace smoke_api::config {
namespace kb = koalabox;
namespace fs = std::filesystem;
Config instance; // NOLINT(cert-err58-cpp)
@@ -16,22 +15,25 @@ namespace smoke_api::config {
}
bool is_dlc_unlocked(
AppId_t app_id, AppId_t dlc_id, const std::function<bool()>& original_function
AppId_t app_id,
AppId_t dlc_id,
const std::function<bool()>& original_function
) {
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];
}
const auto dlc_id_str = std::to_string(dlc_id);
if (instance.override_dlc_status.contains(dlc_id_str)) {
if(instance.override_dlc_status.contains(dlc_id_str)) {
status = instance.override_dlc_status[dlc_id_str];
}
bool is_unlocked;
switch (status) {
switch(status) {
case AppStatus::UNLOCKED:
is_unlocked = true;
break;
@@ -56,9 +58,12 @@ namespace smoke_api::config {
return is_unlocked;
}
DLL_EXPORT(void) ReloadConfig() {
DLL_EXPORT(void) ReloadConfig
(
)
{
LOG_INFO("Reloading config");
instance = kb::config::parse<Config>();
}
}
}

View File

@@ -3,7 +3,6 @@
#include "smoke_api/types.hpp"
namespace smoke_api::config {
enum class AppStatus {
UNDEFINED,
ORIGINAL,
@@ -11,12 +10,17 @@ namespace smoke_api::config {
LOCKED,
};
NLOHMANN_JSON_SERIALIZE_ENUM(AppStatus, {
{ AppStatus::UNDEFINED, nullptr },
{ AppStatus::ORIGINAL, "original" },
{ AppStatus::UNLOCKED, "unlocked" },
{ AppStatus::LOCKED, "locked" },
})
NLOHMANN_JSON_SERIALIZE_ENUM(
AppStatus,
// @formatter:off
{
{AppStatus::UNDEFINED, nullptr},
{AppStatus::ORIGINAL, "original"},
{AppStatus::UNLOCKED, "unlocked"},
{AppStatus::LOCKED, "locked"},
}
// @formatter:on
)
struct Config {
uint32_t $version = 2;
@@ -30,7 +34,8 @@ namespace smoke_api::config {
std::vector<uint32_t> extra_inventory_items;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(
Config, // NOLINT(misc-const-correctness)
Config,
// NOLINT(misc-const-correctness)
$version,
logging,
default_app_status,
@@ -47,7 +52,13 @@ namespace smoke_api::config {
std::vector<DLC> get_extra_dlcs(AppId_t app_id);
bool is_dlc_unlocked(uint32_t app_id, uint32_t dlc_id, const std::function<bool()>& original_function);
bool is_dlc_unlocked(
uint32_t app_id,
uint32_t dlc_id,
const std::function<bool()>& original_function
);
DLL_EXPORT(void) ReloadConfig();
}
DLL_EXPORT(void) ReloadConfig
(
);
}

View File

@@ -1,6 +1,4 @@
namespace globals {
HMODULE steamapi_module = nullptr;
HMODULE steamclient_module = nullptr;
}

View File

@@ -1,8 +1,6 @@
#pragma once
namespace globals {
extern HMODULE steamclient_module;
extern HMODULE steamapi_module;
}

View File

@@ -10,10 +10,10 @@
#include "build_config.h"
#include "smoke_api/smoke_api.hpp"
#include "exports/steamclient.hpp"
#include "smoke_api/config.hpp"
#include "smoke_api/globals.hpp"
#include "smoke_api/smoke_api.hpp"
// Hooking steam_api has shown itself to be less desirable than steamclient
// for the reasons outlined below:
@@ -37,12 +37,12 @@ namespace {
namespace kb = koalabox;
namespace fs = std::filesystem;
#define DETOUR_STEAMCLIENT(FUNC) \
#define DETOUR_STEAMCLIENT(FUNC) \
kb::hook::detour_or_warn(globals::steamclient_module, #FUNC, reinterpret_cast<uintptr_t>(FUNC));
void override_app_id() {
const auto override_app_id = smoke_api::config::instance.override_app_id;
if (override_app_id == 0) {
if(override_app_id == 0) {
return;
}
@@ -64,15 +64,19 @@ namespace {
kb::hook::init(true);
kb::dll_monitor::init_listener(STEAMCLIENT_DLL, [](const HMODULE& library) {
globals::steamclient_module = library;
kb::dll_monitor::init_listener(
STEAMCLIENT_DLL,
[](const HMODULE& library) {
globals::steamclient_module = library;
DETOUR_STEAMCLIENT(CreateInterface)
DETOUR_STEAMCLIENT(CreateInterface)
kb::dll_monitor::shutdown_listener();
});
kb::dll_monitor::shutdown_listener();
}
);
}
}
namespace smoke_api {
void init(const HMODULE module_handle) {
// FIXME: IMPORTANT! Non ascii paths in directories will result in init errors
@@ -81,7 +85,7 @@ namespace smoke_api {
config::instance = kb::config::parse<config::Config>();
if (config::instance.logging) {
if(config::instance.logging) {
kb::logger::init_file_logger(kb::paths::get_log_path());
}
@@ -96,31 +100,31 @@ namespace smoke_api {
override_app_id();
if (kb::hook::is_hook_mode(module_handle, STEAMAPI_DLL)) {
if(kb::hook::is_hook_mode(module_handle, STEAMAPI_DLL)) {
init_hook_mode();
} else {
init_proxy_mode();
}
LOG_INFO("Initialization complete");
} catch (const std::exception& ex) {
} catch(const std::exception& ex) {
kb::util::panic(fmt::format("Initialization error: {}", ex.what()));
}
}
void shutdown() {
try {
if (globals::steamapi_module != nullptr) {
if(globals::steamapi_module != nullptr) {
kb::win_util::free_library(globals::steamapi_module);
globals::steamapi_module = nullptr;
}
LOG_INFO("Shutdown complete");
} catch (const std::exception& e) {
} catch(const std::exception& e) {
const auto msg = std::format("Shutdown error: {}", e.what());
LOG_ERROR(msg);
}
kb::logger::shutdown();
}
}
}

View File

@@ -1,9 +1,7 @@
#pragma once
namespace smoke_api {
void init(HMODULE module_handle);
void shutdown();
}

View File

@@ -4,10 +4,10 @@ std::vector<DLC> DLC::get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_
std::vector<DLC> dlcs;
const auto app_id_str = std::to_string(app_id);
if (apps.contains(app_id_str)) {
if(apps.contains(app_id_str)) {
const auto& app = apps.at(app_id_str);
for (auto const& [id, name] : app.dlcs) {
for(auto const& [id, name] : app.dlcs) {
dlcs.emplace_back(id, name);
}
}
@@ -18,9 +18,9 @@ std::vector<DLC> DLC::get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_
DlcNameMap DLC::get_dlc_map_from_vector(const std::vector<DLC>& dlcs) {
DlcNameMap map;
for (const auto& dlc : dlcs) {
for(const auto& dlc : dlcs) {
map[dlc.get_id_str()] = dlc.get_name();
}
return map;
}
}

View File

@@ -71,9 +71,6 @@ constexpr auto STEAM_CLIENT = "SteamClient";
constexpr auto STEAM_USER = "SteamUser";
constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V";
// TODO: Delete
constexpr auto CLIENT_ENGINE = "CLIENTENGINE_INTERFACE_VERSION";
using AppId_t = uint32_t;
using SteamInventoryResult_t = uint32_t;
using SteamItemInstanceID_t = uint64_t;
@@ -92,7 +89,7 @@ struct SteamItemDetails_t {
// results from UserHasLicenseForApp
enum EUserHasLicenseForAppResult {
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app
k_EUserHasLicenseResultDoesNotHaveLicense = 1,
// User does not have a license for the specified app
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
@@ -118,11 +115,11 @@ class DLC {
std::string appid;
std::string name;
public:
public:
explicit DLC() = default;
explicit DLC(std::string appid, std::string name)
: appid{std::move(appid)}, name{std::move(name)} {}
explicit DLC(std::string appid, std::string name) : appid{std::move(appid)},
name{std::move(name)} {}
[[nodiscard]] std::string get_id_str() const {
return appid;