build: test format (#1)
All checks were successful
check-formatting / check-formatting (push) Successful in 3m26s

This commit is contained in:
6arelyFuture 2025-02-05 15:49:53 +00:00
parent 9c796cd38b
commit b8e12abf89
4 changed files with 128 additions and 31 deletions

View File

@ -0,0 +1,33 @@
name: check-formatting
on:
push:
branches:
- "*"
pull_request:
branches:
- "*"
types: [opened, synchronize, reopened]
jobs:
check-formatting:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install LLVM
uses: KyleMayes/install-llvm-action@v2.0.5
with:
version: "17.0"
- name: Install dependencies (x64)
run: |
apt-get update
apt-get install libtinfo5 -y
- name: Test formatting for all files
working-directory: ${{ github.workspace }}
run: |
export CLANG_FORMAT_BIN="${LLVM_PATH}/bin/clang-format"
./scripts/check-format.sh

8
scripts/check-format.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
# Go to repository root
cd "$(dirname "$0")/.." || exit 2
CLANG_FORMAT_BIN="${CLANG_FORMAT_BIN:-clang-format}"
find ./src -iname '*.hpp' -o -iname '*.cpp' | xargs $CLANG_FORMAT_BIN -Werror -ferror-limit=1 --dry-run

View File

@ -12,8 +12,19 @@
#include "scheduler.hpp"
#include <xorstr.hpp>
namespace {
utils::binary_resource runner_file(RUNNER, "iw4sp-runner.exe");
enum class ownership_state {
success,
unowned,
nosteam,
error,
};
ownership_state state_;
utils::binary_resource runner_file(RUNNER, xorstr_("iw4sp-runner.exe"));
} // namespace
class steam_proxy final : public component_interface {
@ -23,22 +34,35 @@ public:
this->clean_up_on_error();
try {
this->start_mod("iw4x-sp singleplayer", 10180);
state_ = this->start_mod(xorstr_("iw4x-sp singleplayer"), 10180);
} catch (const std::exception& ex) {
printf("Steam: %s\n", ex.what());
state_ = ownership_state::error;
printf(xorstr_("Steam: %s\n"), ex.what());
}
#ifdef STEAM_OWNERSHIP_CHECK
if (utils::nt::is_wine()) {
state_ = ownership_state::success;
return;
}
#endif
#ifdef STEAM_OWNERSHIP_CHECK
evaluate_ownership_state(state_);
#endif
}
void pre_destroy() override {
if (this->steam_client_module_) {
if (this->steam_pipe_) {
if (this->global_user_) {
this->steam_client_module_.invoke<void>(
"Steam_ReleaseUser", this->steam_pipe_, this->global_user_);
this->steam_client_module_.invoke<void>(xorstr_("Steam_ReleaseUser"),
this->steam_pipe_,
this->global_user_);
}
this->steam_client_module_.invoke<bool>("Steam_BReleaseSteamPipe",
this->steam_pipe_);
this->steam_client_module_.invoke<bool>(
xorstr_("Steam_BReleaseSteamPipe"), this->steam_pipe_);
}
}
}
@ -59,10 +83,10 @@ private:
for (auto i = 1; i < 1000; ++i) {
const auto* name =
utils::string::va("CLIENTENGINE_INTERFACE_VERSION{0:03}", i);
utils::string::va(xorstr_("CLIENTENGINE_INTERFACE_VERSION{0:03}"), i);
auto* const client_engine = this->steam_client_module_.invoke<void*>(
"CreateInterface", name, nullptr);
xorstr_("CreateInterface"), name, nullptr);
if (client_engine)
return client_engine;
}
@ -75,10 +99,10 @@ private:
if (steam_path.empty())
return;
utils::nt::library::load(steam_path / "tier0_s.dll");
utils::nt::library::load(steam_path / "vstdlib_s.dll");
utils::nt::library::load(steam_path / xorstr_("tier0_s.dll"));
utils::nt::library::load(steam_path / xorstr_("vstdlib_s.dll"));
this->steam_client_module_ =
utils::nt::library::load(steam_path / "steamclient.dll");
utils::nt::library::load(steam_path / xorstr_("steamclient.dll"));
if (!this->steam_client_module_)
return;
@ -86,52 +110,62 @@ private:
if (!this->client_engine_)
return;
this->steam_pipe_ =
this->steam_client_module_.invoke<void*>("Steam_CreateSteamPipe");
this->steam_pipe_ = this->steam_client_module_.invoke<void*>(
xorstr_("Steam_CreateSteamPipe"));
this->global_user_ = this->steam_client_module_.invoke<void*>(
"Steam_ConnectToGlobalUser", this->steam_pipe_);
xorstr_("Steam_ConnectToGlobalUser"), this->steam_pipe_);
this->client_user_ = this->client_engine_.invoke<void*>(
8, this->steam_pipe_, this->global_user_); // GetIClientUser
this->client_utils_ = this->client_engine_.invoke<void*>(
14, this->steam_pipe_); // GetIClientUtils
}
void start_mod(const std::string& title, const std::size_t app_id) {
ownership_state start_mod(const std::string& title,
const std::size_t app_id) {
__try {
this->start_mod_unsafe(title, app_id);
return this->start_mod_unsafe(title, app_id);
} __except (EXCEPTION_EXECUTE_HANDLER) {
this->do_cleanup();
return ownership_state::error;
}
}
void start_mod_unsafe(const std::string& title, std::size_t app_id) {
ownership_state start_mod_unsafe(const std::string& title,
std::size_t app_id) {
if (!this->client_utils_ || !this->client_user_)
return;
return ownership_state::nosteam;
if (!this->client_user_.invoke<bool>("BIsSubscribedApp", app_id)) {
if (!this->client_user_.invoke<bool>(xorstr_("BIsSubscribedApp"), app_id)) {
#ifdef _DEBUG
app_id = 480; // Spacewar
#else
return ownership_state::unowned;
#endif
}
this->client_utils_.invoke<void>("SetAppIDForCurrentPipe", app_id, false);
this->client_utils_.invoke<void>(xorstr_("SetAppIDForCurrentPipe"), app_id,
false);
char our_directory[MAX_PATH]{};
GetCurrentDirectoryA(sizeof(our_directory), our_directory);
const auto path = runner_file.get_extracted_file();
const auto* cmd_line =
utils::string::va("\"{0}\" -proc {1}", path, GetCurrentProcessId());
const auto* cmd_line = utils::string::va(xorstr_("\"{0}\" -proc {1}"), path,
GetCurrentProcessId());
game_id game_id;
game_id.raw.type = 1; // k_EGameIDTypeGameMod
game_id.raw.app_id = app_id & 0xFFFFFF;
const auto* mod_id = "IW4";
const auto* mod_id = "IW4x-SP";
game_id.raw.mod_id =
*reinterpret_cast<const unsigned int*>(mod_id) | 0x80000000;
this->client_user_.invoke<bool>("SpawnProcess", path.data(), cmd_line,
our_directory, game_id.bits, title.data(),
app_id, 0, 0, 0);
this->client_user_.invoke<bool>(xorstr_("SpawnProcess"), path.c_str(),
cmd_line, our_directory, game_id.bits,
title.c_str(), app_id, 0, 0, 0);
return ownership_state::success;
}
void do_cleanup() {
@ -151,9 +185,11 @@ private:
if (this->steam_client_module_ && this->steam_pipe_ &&
this->global_user_ &&
this->steam_client_module_.invoke<bool>(
"Steam_BConnected", this->global_user_, this->steam_pipe_) &&
xorstr_("Steam_BConnected"), this->global_user_,
this->steam_pipe_) &&
this->steam_client_module_.invoke<bool>(
"Steam_BLoggedOn", this->global_user_, this->steam_pipe_)) {
xorstr_("Steam_BLoggedOn"), this->global_user_,
this->steam_pipe_)) {
return scheduler::cond_continue;
}
@ -162,6 +198,24 @@ private:
},
scheduler::pipeline::async);
}
#ifdef STEAM_OWNERSHIP_CHECK
void evaluate_ownership_state(const ownership_state state) {
switch (state) {
case ownership_state::nosteam:
throw std::runtime_error(
xorstr_("Steam must be running to play this game!"));
case ownership_state::unowned:
throw std::runtime_error(
xorstr_("You must own the game on Steam to play this mod!"));
case ownership_state::error:
throw std::runtime_error(
xorstr_("Failed to verify ownership of the game!"));
case ownership_state::success:
break;
}
}
#endif
};
REGISTER_COMPONENT(steam_proxy)

View File

@ -1,5 +1,7 @@
#include "nt.hpp"
#include <xorstr.hpp>
namespace utils::nt {
library library::load(const std::string& name) {
return library(LoadLibraryA(name.c_str()));
@ -206,8 +208,8 @@ std::string library::get_dll_directory() {
bool is_wine() {
static const auto has_wine_export = []() -> bool {
const library ntdll("ntdll.dll");
return ntdll.get_proc<void*>("wine_get_version");
const library ntdll(xorstr_("ntdll.dll"));
return ntdll.get_proc<void*>(xorstr_("wine_get_version"));
}();
return has_wine_export;