mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2026-01-24 21:42:53 -05:00
Improved koalageddon config init
This commit is contained in:
@@ -30,8 +30,6 @@ namespace api {
|
||||
const auto url = fmt::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id);
|
||||
const auto json = koalabox::http_client::fetch_json(url);
|
||||
|
||||
LOG_TRACE("Steam response: \n{}", json.dump(2))
|
||||
|
||||
const auto response = json.get<SteamResponse>();
|
||||
|
||||
if (response.success != 1) {
|
||||
@@ -45,4 +43,17 @@ namespace api {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<koalageddon::KoalageddonConfig> fetch_koalageddon_config() noexcept {
|
||||
try {
|
||||
const String url =
|
||||
"https://raw.githubusercontent.com/acidicoala/public-entitlements/main/koalageddon/v2/steam.json";
|
||||
const auto kg_config_json = koalabox::http_client::fetch_json(url);
|
||||
|
||||
return kg_config_json.get<koalageddon::KoalageddonConfig>();
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("Failed to fetch Koalageddon config from GitHub: {}", e.what())
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/types.hpp>
|
||||
#include <koalageddon/koalageddon.hpp>
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -8,4 +8,6 @@ namespace api {
|
||||
|
||||
std::optional<Vector<DLC>> fetch_dlcs_from_steam(AppId_t app_id) noexcept;
|
||||
|
||||
std::optional<koalageddon::KoalageddonConfig> fetch_koalageddon_config() noexcept;
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace koalageddon::kg_cache {
|
||||
|
||||
std::optional<KoalageddonConfig> get_koalageddon_config() {
|
||||
try {
|
||||
const auto cache = koalabox::cache::read_from_cache(KEY_KG_CONFIG);
|
||||
const auto config_json = koalabox::cache::read_from_cache(KEY_KG_CONFIG);
|
||||
|
||||
return cache[KEY_KG_CONFIG].get<KoalageddonConfig>();
|
||||
return config_json.get<KoalageddonConfig>();
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("Failed to get cached koalageddon config: {}", e.what())
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include <build_config.h>
|
||||
#include <smoke_api/config.hpp>
|
||||
#include <steam_api_exports/steam_api_exports.hpp>
|
||||
#include <core/api.hpp>
|
||||
#include <koalabox/dll_monitor.hpp>
|
||||
#include <koalabox/http_client.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
#include <koalabox/win_util.hpp>
|
||||
|
||||
namespace koalageddon {
|
||||
|
||||
@@ -15,54 +16,76 @@ namespace koalageddon {
|
||||
/**
|
||||
* @return A string representing the source of the config.
|
||||
*/
|
||||
String init_koalageddon_config() {
|
||||
if (!smoke_api::config::instance.koalageddon_config.is_null()) {
|
||||
try {
|
||||
// First try to read a local config override
|
||||
config = smoke_api::config::instance.koalageddon_config.get<decltype(config)>();
|
||||
void init_koalageddon_config() {
|
||||
const auto print_source = [](const String& source) {
|
||||
LOG_INFO("Loaded Koalageddon config from the {}", source)
|
||||
};
|
||||
|
||||
return "local config override";
|
||||
// First try to read a local config override
|
||||
const auto& kg_config = smoke_api::config::instance.koalageddon_config;
|
||||
if (!kg_config.is_null()) {
|
||||
try {
|
||||
config = kg_config.get<decltype(config)>();
|
||||
|
||||
print_source("local config override");
|
||||
return;
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get local koalageddon config: {}", ex.what())
|
||||
}
|
||||
}
|
||||
|
||||
// Then try to get a cached copy of a previously fetched config.
|
||||
try {
|
||||
// Then try to fetch config from GitHub
|
||||
const String url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/main/koalageddon/v2/steam.json";
|
||||
config = koalabox::http_client::fetch_json(url).get<decltype(config)>();
|
||||
|
||||
kg_cache::save_koalageddon_config(config);
|
||||
|
||||
return "GitHub repository";
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get remote koalageddon config: {}", ex.what())
|
||||
}
|
||||
|
||||
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 = kg_cache::get_koalageddon_config().value();
|
||||
|
||||
return "disk cache";
|
||||
print_source("disk cache");
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get cached koalageddon config: {}", ex.what())
|
||||
|
||||
print_source("default config bundled in the binary");
|
||||
|
||||
// Fallback on the default config, to continue execution immediately.
|
||||
config = {};
|
||||
}
|
||||
|
||||
// Finally, fallback on the default config
|
||||
config = {};
|
||||
return "default config bundled in the binary";
|
||||
// Finally, fetch the remote config from GitHub, and inform user about the need to restart Steam,
|
||||
// if a new config has been fetched
|
||||
NEW_THREAD({
|
||||
try {
|
||||
const auto github_config_opt = api::fetch_koalageddon_config();
|
||||
if (!github_config_opt) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto github_config = *github_config_opt;
|
||||
|
||||
kg_cache::save_koalageddon_config(github_config);
|
||||
|
||||
if (github_config == config) {
|
||||
LOG_DEBUG("Fetched Koalageddon config is equal to existing config")
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Fetched a new Koalageddon config")
|
||||
|
||||
::MessageBox(
|
||||
nullptr,
|
||||
TEXT(
|
||||
"SmokeAPI has downloaded an updated config for Koalageddon mode. "
|
||||
"Please restart Steam in order to apply the new Koalageddon config. "
|
||||
),
|
||||
TEXT("SmokeAPI - Koalageddon"),
|
||||
MB_SETFOREGROUND | MB_ICONINFORMATION | MB_OK
|
||||
);
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get remote koalageddon config: {}", ex.what())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
void init() {
|
||||
// TODO: Load cached koalageddon config by default
|
||||
|
||||
std::thread(
|
||||
[]() {
|
||||
const auto kg_config_source = init_koalageddon_config();
|
||||
LOG_INFO("Loaded Koalageddon config from the {}", kg_config_source)
|
||||
}
|
||||
).detach();
|
||||
init_koalageddon_config();
|
||||
|
||||
koalabox::dll_monitor::init_listener(
|
||||
{VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& module_handle, const String& name) {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
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 {
|
||||
class KoalageddonConfig {
|
||||
public:
|
||||
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;
|
||||
@@ -24,6 +25,8 @@ namespace koalageddon {
|
||||
vstdlib_callback_interceptor_address_offset,
|
||||
vstdlib_callback_name_offset
|
||||
)
|
||||
|
||||
bool operator==(const KoalageddonConfig& other) const = default;
|
||||
};
|
||||
|
||||
extern KoalageddonConfig config;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
namespace smoke_api::config {
|
||||
Config instance; // NOLINT(cert-err58-cpp)
|
||||
|
||||
// TODO: Reloading via export
|
||||
void init() {
|
||||
const auto path = paths::get_config_path();
|
||||
|
||||
@@ -15,10 +14,9 @@ namespace smoke_api::config {
|
||||
try {
|
||||
const auto config_str = koalabox::io::read_file(path);
|
||||
|
||||
LOG_DEBUG("Parsing config:\n{}", config_str)
|
||||
|
||||
instance = Json::parse(config_str).get<Config>();
|
||||
|
||||
LOG_DEBUG("Parsed config:\n{}", Json(instance))
|
||||
} catch (const Exception& e) {
|
||||
const auto message = fmt::format("Error parsing config file: {}", e.what());
|
||||
koalabox::util::error_box("SmokeAPI Error", message);
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace smoke_api::config {
|
||||
// We have to use general json type here since the library doesn't support std::optional
|
||||
Json koalageddon_config;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(
|
||||
Config, // NOLINT(misc-const-correctness)
|
||||
$version,
|
||||
logging,
|
||||
|
||||
@@ -54,23 +54,24 @@ void init_hook_mode() {
|
||||
// the support for it has been dropped from this project.
|
||||
}
|
||||
|
||||
bool is_valve_steam(const String& exe_name) {
|
||||
if (exe_name < not_equals > "steam.exe") {
|
||||
bool is_valve_steam(const String& exe_name) noexcept {
|
||||
try {
|
||||
if (exe_name < not_equals > "steam.exe") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that it's steam from valve, and not some other executable coincidentally named steam
|
||||
|
||||
const HMODULE steam_handle = koalabox::win_util::get_module_handle_or_throw(nullptr);
|
||||
const auto manifest = koalabox::win_util::get_module_manifest(steam_handle);
|
||||
|
||||
// Steam.exe manifest is expected to contain this string
|
||||
return manifest < contains > "valvesoftware.steam.steam";
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("{} -> {}", __func__, e.what())
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Steam.exe manifest is expected to contain this string
|
||||
return *manifest < contains > "valvesoftware.steam.steam";
|
||||
}
|
||||
|
||||
namespace smoke_api {
|
||||
@@ -87,7 +88,8 @@ namespace smoke_api {
|
||||
koalabox::logger::init_file_logger(paths::get_log_path());
|
||||
}
|
||||
|
||||
// FIXME: Dynamic timestamp resolution: https://stackoverflow.com/q/17212518
|
||||
// This kind of timestamp is reliable on for CI builds, as it will reflect the compilation
|
||||
// time stamp only when this file gets recompiled.
|
||||
LOG_INFO("🐨 {} v{} | Compiled at '{}'", PROJECT_NAME, PROJECT_VERSION, __TIMESTAMP__)
|
||||
|
||||
koalabox::cache::init_cache(paths::get_cache_path());
|
||||
|
||||
Reference in New Issue
Block a user