mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2026-01-25 14:02:55 -05:00
Compare commits
9 Commits
907e939b67
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bd112c8f4 | ||
|
|
7b54b4bc7b | ||
|
|
077096b7ed | ||
|
|
bc8ee85e19 | ||
|
|
5aaa9ed151 | ||
|
|
e2b126c8b6 | ||
|
|
2f6d6cc9aa | ||
|
|
8784df5f45 | ||
|
|
dc12301090 |
2
.idea/SmokeAPI.iml
generated
Normal file
2
.idea/SmokeAPI.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CIDR" type="CPP_MODULE" version="4" />
|
||||
@@ -1,5 +1,5 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="linux_exports_generator [32]" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="--input_libs_glob $ProjectFileDir$/res/steamworks/*/binaries/linux32/libsteam_api.so --output_path $ProjectFileDir$/src/generated/32/proxy_exports" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="linux_exports_generator" CONFIG_NAME="Debug [32]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="linux_exports_generator">
|
||||
<configuration default="false" name="linux_exports_generator [32]" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="--input_libs_glob $ProjectFileDir$/res/steamworks/*/binaries/linux32/libsteam_api.so --output_path $ProjectFileDir$/src/generated/32/proxy_exports" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="linux_exports_generator" CONFIG_NAME="Debug [64]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="linux_exports_generator">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="steamworks_downloader [prompt]" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="$Prompt$" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$/res" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="steamworks_downloader" CONFIG_NAME="Debug [32]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="steamworks_downloader">
|
||||
<configuration default="false" name="steamworks_downloader [prompt]" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="$Prompt$" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$/res" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="steamworks_downloader" CONFIG_NAME="Debug [64]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="steamworks_downloader">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
|
||||
2
.idea/runConfigurations/sync.xml
generated
2
.idea/runConfigurations/sync.xml
generated
@@ -1,5 +1,5 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="sync" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="sync" CONFIG_NAME="Debug [32]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="sync">
|
||||
<configuration default="false" name="sync" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$" PASS_PARENT_ENVS_2="true" PROJECT_NAME="SmokeAPI" TARGET_NAME="sync" CONFIG_NAME="Debug [64]" RUN_TARGET_PROJECT_NAME="SmokeAPI" RUN_TARGET_NAME="sync">
|
||||
<method v="2">
|
||||
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
project(SmokeAPI VERSION 4.1.0)
|
||||
project(SmokeAPI VERSION 4.1.3)
|
||||
|
||||
include(KoalaBox/cmake/KoalaBox.cmake)
|
||||
add_subdirectory(KoalaBox)
|
||||
|
||||
2
KoalaBox
2
KoalaBox
Submodule KoalaBox updated: 8e083b99fd...997b5db2ee
11
README.md
11
README.md
@@ -145,7 +145,11 @@ In such cases, it might be worth trying [Special K], which can inject SmokeAPI a
|
||||
|
||||
### ✔️ Requirements
|
||||
|
||||
Linux builds of SmokeAPI depend on several libraries. Make sure they are installed on your system.
|
||||
Linux builds of SmokeAPI depend on several libraries. These libraries are usually included in the
|
||||
[Steam Linux Runtime 3.0 (sniper)](https://github.com/ValveSoftware/steam-runtime#readme),
|
||||
so nothing is required to be installed on the system. But when launching a game directly via its executable
|
||||
(such as in case of hook mode) your system needs to have the following required libraries installed.
|
||||
|
||||
The following list features links in Arch Linux repositories, but if you are using a different distribution,
|
||||
you should use the equivalent package for your distro.
|
||||
|
||||
@@ -214,7 +218,7 @@ Where `<GameExe32>` and `<GameExe64>` correspond to the actual filename of the g
|
||||
- `TheEscapists2.x86_64` (64-bit)
|
||||
- `_linux/darkest.bin.x86` (32-bit)
|
||||
- `_linux/darkest.bin.x86_64` (64-bit)
|
||||
- `bin/linux_x64/eurotrucks2` (64-bit)
|
||||
- `eurotrucks2` (64-bit)
|
||||
- `binaries/victoria3` (64-bit)
|
||||
|
||||
And so on. Notice that Linux executables do not have `.exe` extension like on Windows, so make sure to copy the entire
|
||||
@@ -431,7 +435,8 @@ This project makes use of the following open source projects:
|
||||
- [p-ranav/glob](https://github.com/p-ranav/glob)
|
||||
- [pantor/inja](https://github.com/pantor/inja)
|
||||
- [jarro2783/cxxopts](https://github.com/jarro2783/cxxopts)
|
||||
- [serge1/ELFIO](https://github.com/serge1/ELFIO)
|
||||
- [serge1/ELFIO](https://github.com/serge1/ELFIO)
|
||||
- [Mbed-TLS/mbedtls](https://github.com/Mbed-TLS/mbedtls)
|
||||
- [bshoshany/thread-pool](https://github.com/bshoshany/thread-pool)
|
||||
- [batterycenter/embed](https://github.com/batterycenter/embed)
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
||||
#include <koalabox/config.hpp>
|
||||
#include <koalabox/globals.hpp>
|
||||
#include <koalabox/hook.hpp>
|
||||
#include <koalabox/http_client.hpp>
|
||||
#include <koalabox/lib.hpp>
|
||||
#include <koalabox/lib_monitor.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
@@ -57,6 +58,31 @@ namespace {
|
||||
void* original_steamapi_handle = nullptr;
|
||||
bool is_hook_mode;
|
||||
|
||||
void check_for_updates() {
|
||||
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);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> find_steamclient_versions(void* steamapi_handle) {
|
||||
if(!steamapi_handle) {
|
||||
kb::util::panic("Invalid state. steamapi_handle is null.");
|
||||
@@ -111,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
|
||||
@@ -127,7 +162,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("{} -> original_steamapi_handle is null", __func__);
|
||||
LOG_ERROR("{} -> steamapi_handle is null", __func__);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -195,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);
|
||||
@@ -212,7 +250,7 @@ namespace {
|
||||
}
|
||||
|
||||
void init_proxy_mode([[maybe_unused]] void* self_module_handle) {
|
||||
is_hook_mode = true;
|
||||
is_hook_mode = false;
|
||||
|
||||
original_steamapi_handle = kb::lib::load_original_library(kb::paths::get_self_dir(), STEAM_API_MODULE);
|
||||
#ifdef KB_LINUX
|
||||
@@ -275,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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user