build: add back clang

This commit is contained in:
6arelyFuture 2025-04-01 19:03:59 +02:00
parent 0541f9d095
commit 572b71da00
Signed by: Future
GPG Key ID: F2000F181A4F7C85
11 changed files with 45 additions and 250 deletions

View File

@ -27,6 +27,7 @@ jobs:
- release
compiler:
- msvc
- clang
steps:
- name: Check out files
uses: actions/checkout@main

View File

@ -2,7 +2,6 @@
#include "loader/component_loader.hpp"
#include <utils/hook.hpp>
#include <utils/thread.hpp>
#include <utils/flags.hpp>
#include <utils/concurrency.hpp>
@ -37,8 +36,7 @@ public:
void post_start() override {
this->terminate_runner_ = false;
this->console_runner_ = utils::thread::create_named_thread(
"Console IO", [this] { this->runner(); });
this->console_runner_ = std::thread([this] { this->runner(); });
}
void post_unpack() override {
@ -77,8 +75,7 @@ private:
int handles_[2]{};
void initialize() {
this->console_thread_ =
utils::thread::create_named_thread("Console", [this] {
this->console_thread_ = std::thread([this] {
if (!utils::flags::has_flag("noconsole")) {
game::Sys_ShowConsole();
}

View File

@ -3,7 +3,6 @@
#include <utils/concurrency.hpp>
#include <utils/hook.hpp>
#include <utils/thread.hpp>
#include "scheduler.hpp"
@ -135,7 +134,7 @@ unsigned int thread_id;
class component final : public component_interface {
public:
void post_unpack() override {
thread = utils::thread::create_named_thread("Async Scheduler", [] {
thread = std::thread([] {
while (!kill) {
execute(pipeline::async);
std::this_thread::sleep_for(10ms);

View File

@ -2,6 +2,19 @@
#include "loader/component_loader.hpp"
namespace {
std::string get_current_date() {
auto now = std::chrono::system_clock::now();
auto current_time = std::chrono::system_clock::to_time_t(now);
std::tm local_time{};
(void)localtime_s(&local_time, &current_time);
std::stringstream ss;
ss << std::put_time(&local_time, "%Y%m%d_%H%M%S");
return ss.str();
}
LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info) {
if (exception_info->ExceptionRecord->ExceptionCode == 0x406D1388) {
return EXCEPTION_CONTINUE_EXECUTION;
@ -21,8 +34,8 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info) {
| MiniDumpWithFullMemoryInfo //
| MiniDumpWithThreadInfo;
const auto file_name = std::format("minidumps\\mw3-server-freezer_{}.dmp",
game::Sys_Milliseconds());
const auto file_name =
std::format("minidumps\\mw3-server-freezer_{}.dmp", get_current_date());
const auto file_handle = CreateFileA(
file_name.data(), GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS,

View File

@ -10,13 +10,16 @@
#include <DbgHelp.h>
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <format>
#include <functional>
#include <iostream>
#include <mutex>
#include <queue>
#include <source_location>

View File

@ -103,24 +103,6 @@ void hook::quick() {
}
}
bool hook::iat(const nt::library module, const std::string& target_module,
const std::string& process, void* stub) {
if (!module.is_valid())
return false;
auto ptr = module.get_iat_entry(target_module, process);
if (!ptr)
return false;
DWORD protect;
VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect);
*ptr = stub;
VirtualProtect(ptr, sizeof(*ptr), protect, &protect);
return true;
}
hook* hook::uninstall(const bool unprotect) {
std::lock_guard _(this->state_mutex_);

View File

@ -75,9 +75,6 @@ public:
void* get_original() const;
void quick();
static bool iat(nt::library module, const std::string& target_module,
const std::string& process, void* stub);
static void nop(void* place, size_t length);
static void nop(DWORD place, size_t length);

View File

@ -135,62 +135,6 @@ void library::free() {
HMODULE library::get_handle() const { return this->module_; }
void** library::get_iat_entry(const std::string& module_name,
const std::string& proc_name) const {
if (!this->is_valid())
return nullptr;
const library other_module(module_name);
if (!other_module.is_valid())
return nullptr;
auto* const target_function = other_module.get_proc<void*>(proc_name);
if (!target_function)
return nullptr;
auto* header = this->get_optional_header();
if (!header)
return nullptr;
auto* import_descriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
this->get_ptr() +
header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (import_descriptor->Name) {
if (!_stricmp(
reinterpret_cast<char*>(this->get_ptr() + import_descriptor->Name),
module_name.data())) {
auto* original_thunk_data = reinterpret_cast<PIMAGE_THUNK_DATA>(
import_descriptor->OriginalFirstThunk + this->get_ptr());
auto* thunk_data = reinterpret_cast<PIMAGE_THUNK_DATA>(
import_descriptor->FirstThunk + this->get_ptr());
while (original_thunk_data->u1.AddressOfData) {
const size_t ordinal_number =
original_thunk_data->u1.AddressOfData & 0xFFFFFFF;
if (ordinal_number > 0xFFFF)
continue;
if (GetProcAddress(other_module.module_,
reinterpret_cast<char*>(ordinal_number)) ==
target_function) {
return reinterpret_cast<void**>(&thunk_data->u1.Function);
}
++original_thunk_data;
++thunk_data;
}
// break;
}
++import_descriptor;
}
return nullptr;
}
std::string load_resource(const int id) {
auto* const res = FindResource(library(), MAKEINTRESOURCE(id), RT_RCDATA);
if (!res)

View File

@ -48,27 +48,12 @@ public:
HMODULE get_handle() const;
template <typename T> T get_proc(const std::string& process) const {
if (!this->is_valid())
return T{};
return reinterpret_cast<T>(GetProcAddress(this->module_, process.data()));
}
template <typename T> std::function<T> get(const std::string& process) const {
if (!this->is_valid())
return std::function<T>();
return reinterpret_cast<T*>(this->get_proc<void*>(process));
}
std::vector<PIMAGE_SECTION_HEADER> get_section_headers() const;
PIMAGE_NT_HEADERS get_nt_headers() const;
PIMAGE_DOS_HEADER get_dos_header() const;
PIMAGE_OPTIONAL_HEADER get_optional_header() const;
void** get_iat_entry(const std::string& module_name,
const std::string& proc_name) const;
private:
HMODULE module_;
};

View File

@ -1,105 +0,0 @@
#include <thread>
#include "nt.hpp"
#include "string.hpp"
#include "thread.hpp"
#include <TlHelp32.h>
#include <gsl/gsl>
namespace utils::thread {
bool set_name(const HANDLE t, const std::string& name) {
const nt::library kernel32("kernel32.dll");
if (!kernel32) {
return false;
}
const auto set_description =
kernel32.get_proc<HRESULT(WINAPI*)(HANDLE, PCWSTR)>(
"SetThreadDescription");
if (!set_description) {
return false;
}
return SUCCEEDED(set_description(t, string::convert(name).data()));
}
bool set_name(const DWORD id, const std::string& name) {
auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id);
if (!t)
return false;
const auto _ = gsl::finally([t]() { CloseHandle(t); });
return set_name(t, name);
}
bool set_name(std::thread& t, const std::string& name) {
return set_name(t.native_handle(), name);
}
bool set_name(const std::string& name) {
return set_name(GetCurrentThread(), name);
}
std::vector<DWORD> get_thread_ids() {
auto* const h =
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
if (h == INVALID_HANDLE_VALUE) {
return {};
}
const auto _ = gsl::finally([h]() { CloseHandle(h); });
THREADENTRY32 entry{};
entry.dwSize = sizeof(entry);
if (!Thread32First(h, &entry)) {
return {};
}
std::vector<DWORD> ids;
do {
const auto check_size =
entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
sizeof(entry.th32OwnerProcessID);
entry.dwSize = sizeof(entry);
if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId()) {
ids.emplace_back(entry.th32ThreadID);
}
} while (Thread32Next(h, &entry));
return ids;
}
void for_each_thread(const std::function<void(HANDLE)>& callback) {
const auto ids = get_thread_ids();
for (const auto& id : ids) {
auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id);
if (thread != nullptr) {
const auto _ = gsl::finally([thread]() { CloseHandle(thread); });
callback(thread);
}
}
}
void suspend_other_threads() {
for_each_thread([](const HANDLE thread) {
if (GetThreadId(thread) != GetCurrentThreadId()) {
SuspendThread(thread);
}
});
}
void resume_other_threads() {
for_each_thread([](const HANDLE thread) {
if (GetThreadId(thread) != GetCurrentThreadId()) {
ResumeThread(thread);
}
});
}
} // namespace utils::thread

View File

@ -1,21 +0,0 @@
#pragma once
namespace utils::thread {
bool set_name(HANDLE t, const std::string& name);
bool set_name(DWORD id, const std::string& name);
bool set_name(std::thread& t, const std::string& name);
bool set_name(const std::string& name);
template <typename... Args>
std::thread create_named_thread(const std::string& name, Args&&... args) {
auto t = std::thread(std::forward<Args>(args)...);
set_name(t, name);
return t;
}
std::vector<DWORD> get_thread_ids();
void for_each_thread(const std::function<void(HANDLE)>& callback);
void suspend_other_threads();
void resume_other_threads();
} // namespace utils::thread