3 Commits

Author SHA1 Message Date
acidicoala
3bd112c8f4 Refactored version check 2026-01-17 12:06:19 +05:00
acidicoala
7b54b4bc7b Added null checks 2026-01-14 19:34:00 +05:00
acidicoala
077096b7ed renew steamapi_handle 2026-01-12 04:10:43 +05:00
8 changed files with 62 additions and 33 deletions

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.24)
project(SmokeAPI VERSION 4.1.1)
project(SmokeAPI VERSION 4.1.3)
include(KoalaBox/cmake/KoalaBox.cmake)
add_subdirectory(KoalaBox)

View File

@@ -20,8 +20,8 @@
"logging": {
"type": "boolean",
"default": false,
"x-packaged-default": true,
"description": "Enables logging to SmokeAPI.log.log file.",
"x-packaged-default": true,
"x-valid-values": "`true` or `false`."
},
"log_steam_http": {

View File

@@ -59,23 +59,27 @@ namespace {
bool is_hook_mode;
void check_for_updates() {
const auto latest_release_url = std::format(
"https://api.github.com/repos/acidicoala/{}/releases/latest",
PROJECT_NAME
);
const auto res = kb::http_client::get_json(latest_release_url);
const auto latest_tag = res["tag_name"].get<std::string>();
const auto current_tag = std::format("v{}", PROJECT_VERSION);
if(current_tag == latest_tag) {
LOG_DEBUG("Running the latest version");
} else {
const auto release_page = std::format(
"https://github.com/acidicoala/{}/releases/{}",
PROJECT_NAME, latest_tag
try {
const auto latest_release_url = std::format(
"https://api.github.com/repos/acidicoala/{}/releases/latest",
PROJECT_NAME
);
const auto res = kb::http_client::get_json(latest_release_url);
const auto latest_tag = res["tag_name"].get<std::string>();
const auto current_tag = std::format("v{}", PROJECT_VERSION);
LOG_WARN("New version {} available: {}", latest_tag, release_page);
if(current_tag == latest_tag) {
LOG_DEBUG("Running the latest version");
} else {
const auto release_page = std::format(
"https://github.com/acidicoala/{}/releases/{}",
PROJECT_NAME, latest_tag
);
LOG_WARN("New version {} available: {}", latest_tag, release_page);
}
} catch(const std::exception& e) {
LOG_ERROR("{} -> Unexpected error: {}", __func__, e.what());
}
}
@@ -133,10 +137,19 @@ namespace {
static const auto CreateInterface$ = KB_LIB_GET_FUNC(steamclient_handle, CreateInterface);
if(original_steamapi_handle) {
if(auto* steamapi_handle = kb::lib::get_lib_handle(STEAM_API_MODULE)) {
if(original_steamapi_handle == nullptr) { // hook mode on Windows
original_steamapi_handle = steamapi_handle;
} else if(steamapi_handle != original_steamapi_handle) {
LOG_WARN(
"{} -> steamapi_handle ({}) != original_steamapi_handle ({})",
__func__, steamapi_handle, original_steamapi_handle
);
}
// SteamAPI might have been initialized.
// Hence, we need to query SteamClient interfaces and hook them if needed.
const auto steamclient_versions = find_steamclient_versions(original_steamapi_handle);
const auto steamclient_versions = find_steamclient_versions(steamapi_handle);
for(const auto& steamclient_version : steamclient_versions) {
if(CreateInterface$(steamclient_version.c_str(), nullptr)) {
#ifdef KB_WIN
@@ -149,7 +162,7 @@ namespace {
}
}
} else {
LOG_ERROR("{} -> original_steamapi_handle is null", __func__);
LOG_ERROR("{} -> steamapi_handle is null", __func__);
}
return true;
@@ -217,7 +230,10 @@ namespace {
if(const auto lib_bitness = kb::lib::get_bitness(lib_path)) {
if(static_cast<uint8_t>(*lib_bitness) == kb::platform::bitness) {
if(const auto lib_handle = kb::lib::load(lib_path)) {
LOG_INFO("Found original library: {}", kb::path::to_str(lib_path));
LOG_INFO(
"Found & loaded original library '{}' @ {}",
kb::path::to_str(lib_path), *lib_handle
);
original_steamapi_handle = *lib_handle;
proxy_exports::init(self_module_handle, original_steamapi_handle);
@@ -277,12 +293,6 @@ namespace smoke_api {
kb::win::check_self_duplicates();
#endif
#ifdef KB_DEBUG
// TODO: Add config option to toggle this and show native OS notification
// The real reason behind this is for automatic testing of HTTPs dependencies
std::thread(check_for_updates).detach();
#endif
// We need to hook functions in either mode
kb::hook::init(true);
@@ -303,6 +313,14 @@ namespace smoke_api {
}
}
void post_init() {
#ifdef KB_DEBUG
// TODO: Add config option to toggle this and show native OS notification
// The real reason behind this is for automatic testing of HTTPs dependencies
std::thread(check_for_updates).detach();
#endif
}
void shutdown() {
try {
static bool shutdown_complete = false;

View File

@@ -4,6 +4,14 @@
namespace smoke_api {
void init(void* self_module_handle);
/**
* Post-initialization procedures that must be done after the module is finished loading.
* Reason being that on Windows we should not start new threads while being in DllMain callback,
* otherwise we would run into deadlocks/race-conditions/undefined behavior.
*/
void post_init();
void shutdown();
AppId_t get_app_id();

View File

@@ -15,7 +15,9 @@ namespace steam_client {
if(interface_version) {
LOG_DEBUG("{} -> '{}' @ {}", function_name, interface_version, interface);
steam_interfaces::hook_virtuals(interface, interface_version);
if(interface) {
steam_interfaces::hook_virtuals(interface, interface_version);
}
}
return interface;

View File

@@ -237,13 +237,10 @@ namespace steam_interfaces {
continue;
}
const auto* const interface_ptr = ISteamClient_GetISteamGenericInterface(
ISteamClient_GetISteamGenericInterface(
ARGS(steam_user, steam_pipe, interface_version.c_str())
);
if(not interface_ptr) {
LOG_ERROR("Failed to get generic interface: '{}'", interface_version)
}
}
} catch(const std::exception& e) {
LOG_ERROR("{} -> Unhandled exception: {}", __func__, e.what());

View File

@@ -4,6 +4,7 @@
#include <koalabox/logger.hpp>
#include "smoke_api/steamclient/steamclient.hpp"
#include "smoke_api/smoke_api.hpp"
#include "smoke_api/types.hpp"
#include "steam_api/steam_client.hpp"
@@ -16,6 +17,9 @@ C_DECL(void*) CreateInterface(const char* interface_version, create_interface_re
static std::mutex section;
const std::lock_guard lock(section);
static std::once_flag once_flag;
std::call_once(once_flag, smoke_api::post_init);
return steam_client::GetGenericInterface(
__func__,
interface_version,