Christmas Update

This commit is contained in:
6arelyFuture 2024-12-23 12:14:50 +01:00
parent 89a735326d
commit e530495ecb
Signed by: Future
GPG Key ID: F2000F181A4F7C85
17 changed files with 190 additions and 29 deletions

2
deps/GSL vendored

@ -1 +1 @@
Subproject commit e64c97fc2cfc11992098bb38eda932de275e3f4d
Subproject commit b8ac820fe1efde9c63ca290f4ae8670f938a7dae

2
deps/libtomcrypt vendored

@ -1 +1 @@
Subproject commit f7e6519fae1e11ff5ff9d36c84101a673002133b
Subproject commit c900951dab1bb94bab803fc57688dac18e3b71f9

2
deps/minhook vendored

@ -1 +1 @@
Subproject commit 1cc46107ee522d7a5c73656c519ca16addf2c23a
Subproject commit c1a7c3843bd1a5fe3eb779b64c0d823bca3dc339

2
deps/rapidjson vendored

@ -1 +1 @@
Subproject commit ab1842a2dae061284c0a62dca1cc6d5e7e37e346
Subproject commit d621dc9e9c77f81e5c8a35b8dcc16dcd63351321

2
deps/zlib vendored

@ -1 +1 @@
Subproject commit 0f51fb4933fc9ce18199cb2554dacea8033e7fd3
Subproject commit ef24c4c7502169f016dcd2a26923dbaf3216748c

View File

@ -3,6 +3,7 @@
#include <utils/cryptography.hpp>
#include <utils/hook.hpp>
#include <utils/nt.hpp>
#include <utils/smbios.hpp>
#include <utils/string.hpp>
@ -68,9 +69,29 @@ utils::cryptography::ecc::key& get_key() {
return key;
}
bool is_second_instance() {
static const auto is_first = []() -> bool {
static utils::nt::handle mutex =
CreateMutexA(nullptr, FALSE, "iw4xsp_mutex");
return mutex && GetLastError() != ERROR_ALREADY_EXISTS;
}();
return !is_first;
}
} // namespace
std::uint64_t get_guid() { return get_key().get_hash(); }
std::uint64_t get_guid() {
static const auto guid = []() -> std::uint64_t {
if (is_second_instance()) {
return 0x110000100000000 |
(::utils::cryptography::random::get_integer() & ~0x80000000);
}
return get_key().get_hash();
}();
return guid;
}
class component final : public component_interface {
public:

View File

@ -77,6 +77,7 @@ void cg_draw_full_screen_debug_overlays_stub(int local_client_num) {
utils::hook::invoke<void>(0x44BD00, local_client_num);
}
volatile bool left_side = true;
game::Font_s** small_font;
void branding_loop() {
float color[4] = {1.0f, 1.0f, 1.0f, 0.25f};
@ -88,7 +89,10 @@ void branding_loop() {
auto* const scr_place =
game::ScrPlace_GetActivePlacement(game::LOCAL_CLIENT_0);
const auto x = scr_place->realViewportSize[0] -
const auto x =
left_side
? 10.0f
: scr_place->realViewportSize[0] -
static_cast<float>(game::R_TextWidth(text, 0, *small_font)) -
10.0f;
@ -122,6 +126,8 @@ public:
small_font = reinterpret_cast<game::Font_s**>(0x192A0DC);
scheduler::loop(branding_loop, scheduler::pipeline::renderer);
scheduler::loop([] { left_side = !left_side; },
scheduler::pipeline::renderer, 60s);
}
static void register_branding_dvars() {

View File

@ -14,14 +14,15 @@ namespace {
void com_assert_f() { assert("a" && false); }
void com_bug_f(const command::params& params) {
char new_file_name[0x105]{};
char new_file_name[MAX_PATH]{};
char to_ospath[MAX_PATH]{};
char from_ospath[MAX_PATH]{};
const char* bug;
const char* bug{};
if (!*game::logfile) {
game::Com_PrintError(game::CON_CHANNEL_ERROR,
"CopyFile failed: logfile wasn't opened\n");
return;
}
if (params.size() == 2) {
@ -31,9 +32,10 @@ void com_bug_f(const command::params& params) {
bug = dvars::bug_name->current.string;
}
sprintf_s(new_file_name, "%s_%s.log", bug, game::Live_GetLocalClientName(0));
sprintf_s(new_file_name, "%s_%s.log", bug,
game::Live_GetLocalClientName(game::LOCAL_CLIENT_0));
game::engine::scoped_critical_section _(game::CRITSECT_CONSOLE,
game::engine::scoped_critical_section lock(game::CRITSECT_CONSOLE,
game::SCOPED_CRITSECT_NORMAL);
if (*game::logfile) {
@ -48,6 +50,8 @@ void com_bug_f(const command::params& params) {
const auto result = CopyFileA(from_ospath, to_ospath, 0);
game::Com_OpenLogFile();
lock.leave_crit_sect();
if (!result) {
game::Com_PrintError(game::CON_CHANNEL_ERROR, "CopyFile failed(%d) %s %s\n",
GetLastError(), "console.log", new_file_name);
@ -55,7 +59,7 @@ void com_bug_f(const command::params& params) {
}
void com_bug_name_inc_f() {
char buf[260]{};
char buf[MAX_PATH]{};
if (std::strlen(dvars::bug_name->current.string) < 4) {
game::Dvar_SetString(dvars::bug_name, "bug0");

View File

@ -22,6 +22,8 @@ public:
dvar::override::register_bool("intro", false, game::DVAR_ARCHIVE);
dvar::override::register_float("cg_fov", 65.0f, 65.0f, 160.0f,
game::DVAR_ARCHIVE | game::DVAR_SAVED);
dvar::override::register_float("cg_fovScale", 1.0f, 0.2f, 2.0f,
game::DVAR_ARCHIVE | game::DVAR_SAVED);
dvar::override::register_string("fs_basegame", BASEGAME, game::DVAR_INIT);
#ifdef _DEBUG

View File

@ -0,0 +1,42 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/dvars.hpp"
#include <utils/hook.hpp>
#include <xorstr.hpp>
namespace fov {
namespace {
void dvar_set_from_string_by_name_from_source(const char* dvar_name,
const char* string,
game::DvarSetSource source) {
if ((!std::strcmp(dvar_name, "cg_fov")) ||
(!std::strcmp(dvar_name, "cg_fovScale"))) {
game::Com_Printf(game::CON_CHANNEL_DONT_FILTER,
xorstr_("Not allowing the client to override dvar '%s'\n"),
dvar_name);
return;
}
game::Dvar_SetFromStringByNameFromSource(dvar_name, string, source);
}
} // namespace
class component final : public component_interface {
public:
void post_load() override {
utils::hook(0x5D7818, dvar_set_from_string_by_name_from_source,
HOOK_CALL)
.install() // hook*
->quick(); // GScr_SetSavedDvar
utils::hook(0x5CC8D9, dvar_set_from_string_by_name_from_source,
HOOK_CALL)
.install() // hook*
->quick(); // GScr_SetDvar_Internal
}
};
} // namespace fov
REGISTER_COMPONENT(fov::component)

View File

@ -46,8 +46,8 @@ private:
// Disable MP packet handler
utils::hook::set<std::uint8_t>(0x65E717, 0xEB);
// Disable LSP packet handler
utils::hook::set<std::uint8_t>(0x65E3A4, 0xEB);
// Disable LSP packet handler (suppress print message)
utils::hook::nop(0x65E3C4, 5);
// Avoid spam
utils::hook(0x65E786, game::Com_DPrintf, HOOK_CALL).install()->quick();

View File

@ -31,6 +31,30 @@ const char* live_get_local_client_name_stub() {
}
bool g_exit_after_tool_complete_stub() { return false; }
void ui_replace_directive_stub(const int local_client_num,
const char* src_string, char* dst_string,
const int dst_buffer_size) {
if (!src_string) {
return;
}
if (!dst_string) {
return;
}
if (dst_buffer_size <= 0) {
return;
}
constexpr std::size_t MAX_HUDELEM_TEXT_LEN = 0x100;
if (std::strlen(src_string) > MAX_HUDELEM_TEXT_LEN) {
return;
}
game::UI_ReplaceDirective(local_client_num, src_string, dst_string,
dst_buffer_size);
}
} // namespace
class component final : public component_interface {
@ -58,6 +82,19 @@ public:
.install() // hook*
->quick();
utils::hook(0x563C0C, ui_replace_directive_stub, HOOK_CALL)
.install() // hook*
->quick();
utils::hook(0x56454F, ui_replace_directive_stub, HOOK_CALL)
.install() // hook*
->quick();
utils::hook(0x568A7E, ui_replace_directive_stub, HOOK_CALL)
.install() // hook*
->quick();
utils::hook(0x6283AE, ui_replace_directive_stub, HOOK_CALL)
.install() // hook*
->quick();
patch_sp();
}

View File

@ -11,7 +11,7 @@ namespace {
void __declspec(naked) pm_step_slide_move_stub() {
__asm {
push eax;
mov eax, dvars::pm_bounce;
mov eax, dvars::pm_bounces;
cmp byte ptr [eax + 0x10], 1;
pop eax;
@ -48,7 +48,7 @@ void pm_project_velocity_stub(const float* vel_in, const float* normal,
std::sqrtf((vel_in[2] * vel_in[2] + length_squared_2d) /
(new_z * new_z + length_squared_2d));
if (dvars::pm_bouncingAllAngles->current.enabled ||
if (dvars::pm_bouncesAllAngles->current.enabled ||
(length_scale < 1.f || new_z < 0.f || vel_in[2] > 0.f)) {
vel_out[0] = vel_in[0] * length_scale;
vel_out[1] = vel_in[1] * length_scale;
@ -222,10 +222,10 @@ public:
static void register_dvars() {
// clang-format off
dvars::pm_bounce = game::Dvar_RegisterBool(
"pm_bounce", false, game::DVAR_NONE, "CoD4 Bounces");
dvars::pm_bouncingAllAngles = game::Dvar_RegisterBool(
"pm_bouncingAllAngles", false, game::DVAR_NONE, "Enable bouncing from all angles");
dvars::pm_bounces = game::Dvar_RegisterBool(
"pm_bounces", false, game::DVAR_NONE, "CoD4 Bounces");
dvars::pm_bouncesAllAngles = game::Dvar_RegisterBool(
"pm_bouncesAllAngles", false, game::DVAR_NONE, "Enable bouncing from all angles");
dvars::pm_rocketJump = game::Dvar_RegisterBool(
"pm_rocketJump", true, game::DVAR_NONE, "CoD4 rocket jumps");
dvars::pm_rocketJumpScale = game::Dvar_RegisterFloat(

View File

@ -3,8 +3,8 @@
namespace dvars {
const game::dvar_t* r_noBorder = nullptr;
const game::dvar_t* pm_bounce = nullptr;
const game::dvar_t* pm_bouncingAllAngles = nullptr;
const game::dvar_t* pm_bounces = nullptr;
const game::dvar_t* pm_bouncesAllAngles = nullptr;
const game::dvar_t* pm_rocketJump = nullptr;
const game::dvar_t* pm_rocketJumpScale = nullptr;
const game::dvar_t* pm_playerCollision = nullptr;

View File

@ -3,8 +3,8 @@
namespace dvars {
extern const game::dvar_t* r_noBorder;
extern const game::dvar_t* pm_bounce;
extern const game::dvar_t* pm_bouncingAllAngles;
extern const game::dvar_t* pm_bounces;
extern const game::dvar_t* pm_bouncesAllAngles;
extern const game::dvar_t* pm_rocketJump;
extern const game::dvar_t* pm_rocketJumpScale;
extern const game::dvar_t* pm_playerCollision;

View File

@ -95,6 +95,9 @@ WEAK symbol<void(const char* dvarName, double value)> Dvar_SetFloatByName{
0x497250};
WEAK symbol<void(const char* dvarName, const char* value)> Dvar_SetStringByName{
0x440C60};
WEAK symbol<const dvar_t*(const char* dvarName, const char* string,
DvarSetSource source)>
Dvar_SetFromStringByNameFromSource{0x4774E0};
WEAK symbol<void(const dvar_t* dvar, int value)> Dvar_SetInt{0x4FA540};
WEAK symbol<void(const dvar_t* dvar, bool value)> Dvar_SetBool{0x4E57E0};
WEAK symbol<void(const dvar_t* dvar, const char* value)> Dvar_SetString{
@ -229,6 +232,9 @@ WEAK symbol<void(const ScreenPlacement* scrPlace, const char* text,
int maxChars, Font_s* font, float x, float y, int horzAlign,
int vertAlign, float scale, const float* color, int style)>
UI_DrawText{0x40FC70};
WEAK symbol<void(int localClientNum, const char* srcString, char* dstString,
int dstBufferSize)>
UI_ReplaceDirective{0x4BBD10};
// PC
WEAK symbol<int(source_s* source)> PC_Directive_define{0x4F8CF0};

View File

@ -91,7 +91,7 @@ public:
PIMAGE_DOS_HEADER get_dos_header() const;
PIMAGE_OPTIONAL_HEADER get_optional_header() const;
void** get_iat_entry(const std::string& module_name,
[[nodiscard]] void** get_iat_entry(const std::string& module_name,
const std::string& proc_name) const;
static void set_dll_directory(const std::string& directory);
@ -101,6 +101,49 @@ private:
HMODULE module_;
};
template <HANDLE InvalidHandle = nullptr> class handle {
public:
handle() = default;
handle(const HANDLE h) : handle_(h) {}
~handle() {
if (*this) {
CloseHandle(this->handle_);
this->handle_ = InvalidHandle;
}
}
handle(const handle&) = delete;
handle& operator=(const handle&) = delete;
handle(handle&& obj) noexcept : handle() { this->operator=(std::move(obj)); }
handle& operator=(handle&& obj) noexcept {
if (this != &obj) {
this->~handle();
this->handle_ = obj.handle_;
obj.handle_ = InvalidHandle;
}
return *this;
}
handle& operator=(HANDLE h) noexcept {
this->~handle();
this->handle_ = h;
return *this;
}
operator bool() const { return this->handle_ != InvalidHandle; }
operator HANDLE() const { return this->handle_; }
private:
HANDLE handle_{InvalidHandle};
};
bool is_wine();
__declspec(noreturn) void raise_hard_exception();