9 Commits

Author SHA1 Message Date
acidicoala
bc8ee85e19 Fixed proxy mode detection 2026-01-08 23:16:10 +05:00
acidicoala
5aaa9ed151 Added trace logs to proxy exports 2026-01-04 21:41:26 +05:00
acidicoala
e2b126c8b6 Regenerated README [skip ci] 2026-01-04 07:22:14 +05:00
acidicoala
2f6d6cc9aa Regenerated linux proxy exports 2026-01-04 07:12:44 +05:00
acidicoala
8784df5f45 Fix mbedtls include attempt 3 2026-01-04 06:54:06 +05:00
acidicoala
dc12301090 Fix mbedtls include attempt 2 2026-01-04 06:13:58 +05:00
acidicoala
907e939b67 Fixed string section name 2026-01-04 04:49:35 +05:00
acidicoala
7b82994b17 Regenerate linux proxy exports 2026-01-04 04:49:28 +05:00
acidicoala
11bd820921 Sync KoalaBox (brotli, openssl) 2026-01-04 04:49:19 +05:00
9 changed files with 5056 additions and 29 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

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

View File

@@ -145,14 +145,15 @@ 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.
Required libraries:
- [brotli](https://archlinux.org/packages/core/x86_64/brotli/)
[[32-bit](https://archlinux.org/packages/multilib/x86_64/lib32-brotli/)]
- [gcc-libs](https://archlinux.org/packages/core/x86_64/gcc-libs/)
[[32-bit](https://archlinux.org/packages/core/x86_64/lib32-gcc-libs/)]
@@ -165,12 +166,6 @@ Required libraries:
- [libnghttp2](https://archlinux.org/packages/core/x86_64/libnghttp2/)
[[32-bit](https://archlinux.org/packages/multilib/x86_64/lib32-libnghttp2/)]
- [libssh2](https://archlinux.org/packages/core/x86_64/libssh2/)
[[32-bit](https://archlinux.org/packages/multilib/x86_64/lib32-libssh2/)]
- [openssl](https://archlinux.org/packages/core/x86_64/openssl/)
[[32-bit](https://archlinux.org/packages/multilib/x86_64/lib32-openssl/)]
- [zlib](https://archlinux.org/packages/core/x86_64/zlib/)
[[32-bit](https://archlinux.org/packages/multilib/x86_64/lib32-zlib/)]
@@ -194,7 +189,6 @@ wrappers might cause issues in theory. However, in practice real tests show that
chance of success compared to proxy mode. So, at the end of the day, try both modes to see which one works
best for you.
### 🔀 Proxy mode (🐧 Linux)
Same as on Windows:
@@ -214,17 +208,17 @@ For example:
1. Extract and paste the `libsmoke_api32.so` or `libsmoke_api64.so` in the root of game's installation directory.
2. In Steam _Library_ open game's _Properties_, switch to the _General_ tab, and set the following _LAUNCH OPTIONS_:
| Bitness | Launch Options |
|---------|------------------------------------------------------------------------------------------------------------------------|
| 32-bit | `LD_PRELOAD="./libsmoke_api32.so $HOME/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so" ./<GameExe32> %command%` |
| 64-bit | `LD_PRELOAD="./libsmoke_api64.so $HOME/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so" ./<GameExe64> %command%` |
| Bitness | Launch Options |
|---------|---------------------------------------------------------------------------------------------------------------------------------|
| 32-bit | `LD_PRELOAD="./libsmoke_api32.so $HOME/.local/share/Steam/ubuntu12_32/gameoverlayrenderer.so" ./<GameExe32> ; exit ; %command%` |
| 64-bit | `LD_PRELOAD="./libsmoke_api64.so $HOME/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so" ./<GameExe64> ; exit ; %command%` |
Where `<GameExe32>` and `<GameExe64>` correspond to the actual filename of the game executable. For example:
- `TheEscapists2.x86` (32-bit)
- `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
@@ -234,6 +228,9 @@ If you have other environment variables, and you don't know how to correctly com
then please make extensive use of search engines and LLMs for guidance and examples
before seeking help the official forum topic.
> [!NOTE]
> The `; exit ; %command%` at the end of launch options
> is a trick used to force Steam to directly run the game executable.
## ⚙ Configuration
@@ -438,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)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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,27 @@ namespace {
void* original_steamapi_handle = nullptr;
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
);
LOG_WARN("New version {} available: {}", latest_tag, release_page);
}
}
std::set<std::string> find_steamclient_versions(void* steamapi_handle) {
if(!steamapi_handle) {
kb::util::panic("Invalid state. steamapi_handle is null.");
@@ -65,12 +87,13 @@ namespace {
std::set<std::string> versions;
// On Linux the section name depends on individual lib file, so we can't use generic constants
const std::string str_section_name = kb::platform::is_windows ? ".text" : ".rodata.str";
const auto rdata_section = kb::lib::get_section_or_throw(steamapi_handle, str_section_name);
const auto rdata = rdata_section.to_string();
// ReSharper disable once CppDFAUnreachableCode
const std::string str_section_name = kb::platform::is_windows ? ".rdata" : ".rodata";
const auto str_section = kb::lib::get_section_or_throw(steamapi_handle, str_section_name);
const auto str_section_str = str_section.to_string();
const std::regex pattern(R"(SteamClient\d{3})");
const auto matches_begin = std::sregex_iterator(rdata.begin(), rdata.end(), pattern);
const auto matches_begin = std::sregex_iterator(str_section_str.begin(), str_section_str.end(), pattern);
const auto matches_end = std::sregex_iterator();
for(std::sregex_iterator i = matches_begin; i != matches_end; ++i) {
@@ -110,10 +133,10 @@ namespace {
static const auto CreateInterface$ = KB_LIB_GET_FUNC(steamclient_handle, CreateInterface);
if(auto* steamapi_handle = kb::lib::get_lib_handle(STEAM_API_MODULE)) {
if(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(steamapi_handle);
const auto steamclient_versions = find_steamclient_versions(original_steamapi_handle);
for(const auto& steamclient_version : steamclient_versions) {
if(CreateInterface$(steamclient_version.c_str(), nullptr)) {
#ifdef KB_WIN
@@ -125,6 +148,8 @@ namespace {
LOG_INFO("'{}' has not been initialized. Waiting for initialization.", steamclient_version);
}
}
} else {
LOG_ERROR("{} -> original_steamapi_handle is null", __func__);
}
return true;
@@ -209,7 +234,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
@@ -252,6 +277,12 @@ 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);