Merge remote-tracking branch 'upstream/main' into dvar_sessionmode
This commit is contained in:
commit
b8a8125750
2
deps/curl
vendored
2
deps/curl
vendored
@ -1 +1 @@
|
||||
Subproject commit c3f3c2557c64d4947f8c6337a0590cd28304d8fd
|
||||
Subproject commit b16d1fa8ee567b52c09a0f89940b07d8491b881d
|
@ -4,14 +4,16 @@
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "steam/steam.hpp"
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/thread.hpp>
|
||||
|
||||
#include "integrity.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
||||
#define ProcessDebugPort 7
|
||||
#define ProcessDebugObjectHandle 30
|
||||
#define ProcessDebugFlags 31
|
||||
@ -19,8 +21,84 @@
|
||||
|
||||
namespace arxan
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
void* callstack_proxy_addr{nullptr};
|
||||
static thread_local const void* address_to_call{};
|
||||
|
||||
void set_address_to_call(const void* address)
|
||||
{
|
||||
address_to_call = address;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
thread_local std::stack<uint64_t> address_stack{};
|
||||
|
||||
const void* get_address_to_call()
|
||||
{
|
||||
return detail::address_to_call;
|
||||
}
|
||||
|
||||
void store_address(const uint64_t address)
|
||||
{
|
||||
address_stack.push(address);
|
||||
}
|
||||
|
||||
uint64_t get_stored_address()
|
||||
{
|
||||
const auto res = address_stack.top();
|
||||
address_stack.pop();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void callstack_return_stub(utils::hook::assembler& a)
|
||||
{
|
||||
a.push(rax);
|
||||
a.pushad64();
|
||||
|
||||
a.call_aligned(get_stored_address);
|
||||
a.mov(qword_ptr(rsp, 0x80), rax);
|
||||
|
||||
a.popad64();
|
||||
|
||||
a.add(rsp, 8);
|
||||
|
||||
a.jmp(qword_ptr(rsp, -8));
|
||||
}
|
||||
|
||||
uint64_t get_callstack_return_stub()
|
||||
{
|
||||
const auto placeholder = game::select(0x140001056, 0x140101167);
|
||||
utils::hook::nop(placeholder, 1);
|
||||
utils::hook::jump(placeholder + 1, utils::hook::assemble(callstack_return_stub));
|
||||
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
void callstack_stub(utils::hook::assembler& a)
|
||||
{
|
||||
a.push(rax);
|
||||
|
||||
a.pushad64();
|
||||
a.call_aligned(get_address_to_call);
|
||||
a.mov(qword_ptr(rsp, 0x80), rax);
|
||||
|
||||
a.mov(rcx, qword_ptr(rsp, 0x88));
|
||||
a.call_aligned(store_address);
|
||||
|
||||
a.mov(rax, get_callstack_return_stub());
|
||||
a.mov(qword_ptr(rsp, 0x88), rax);
|
||||
|
||||
a.popad64();
|
||||
|
||||
a.add(rsp, 8);
|
||||
|
||||
a.jmp(qword_ptr(rsp, -8));
|
||||
}
|
||||
|
||||
constexpr auto pseudo_steam_id = 0x1337;
|
||||
const auto pseudo_steam_handle = reinterpret_cast<HANDLE>(reinterpret_cast<uint64_t>(INVALID_HANDLE_VALUE) -
|
||||
pseudo_steam_id);
|
||||
@ -788,6 +866,8 @@ namespace arxan
|
||||
{
|
||||
search_and_patch_integrity_checks();
|
||||
//restore_debug_functions();
|
||||
|
||||
detail::callstack_proxy_addr = utils::hook::assemble(callstack_stub);
|
||||
}
|
||||
|
||||
component_priority priority() const override
|
||||
|
@ -14,9 +14,10 @@ namespace client_patches
|
||||
{
|
||||
utils::hook::detour preload_map_hook;
|
||||
|
||||
void stop_zombies_intro_if_needed()
|
||||
void stop_intro_if_needed()
|
||||
{
|
||||
if (game::Com_SessionMode_GetMode() != game::MODE_ZOMBIES)
|
||||
if (game::Com_SessionMode_GetMode() != game::MODE_ZOMBIES &&
|
||||
game::Com_SessionMode_GetMode() != game::MODE_CAMPAIGN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -39,7 +40,7 @@ namespace client_patches
|
||||
void preload_map_stub(int localClientNum, const char* mapname, const char* gametype)
|
||||
{
|
||||
game::Com_GametypeSettings_SetGametype(gametype, false, false);
|
||||
stop_zombies_intro_if_needed();
|
||||
stop_intro_if_needed();
|
||||
preload_map_hook.invoke(localClientNum, mapname, gametype);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "game/demonware/servers/umbrella_server.hpp"
|
||||
#include "game/demonware/server_registry.hpp"
|
||||
|
||||
#include "localized_strings.hpp"
|
||||
|
||||
#define TCP_BLOCKING true
|
||||
#define UDP_BLOCKING false
|
||||
|
||||
@ -497,6 +499,8 @@ namespace demonware
|
||||
utils::hook::set<uint64_t>(0x141F03130_g, 0xC300000001B8); // Kill LPC_DeleteStale
|
||||
|
||||
utils::hook::set<uint8_t>(0x141E0AA1B_g, 0xEB); // Release un-handled reportReward spamming loop
|
||||
|
||||
localized_strings::override("MENU_CONNECTING_DW", "Emulating Online Service");
|
||||
}
|
||||
|
||||
void pre_destroy() override
|
||||
|
52
src/client/component/localized_strings.cpp
Normal file
52
src/client/component/localized_strings.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "localized_strings.hpp"
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
#include "game/game.hpp"
|
||||
|
||||
namespace localized_strings
|
||||
{
|
||||
namespace
|
||||
{
|
||||
utils::hook::detour seh_string_ed_get_string_hook;
|
||||
|
||||
using localized_map = std::unordered_map<std::string, std::string>;
|
||||
utils::concurrency::container<localized_map> localized_overrides;
|
||||
|
||||
const char* seh_string_ed_get_string(const char* reference)
|
||||
{
|
||||
return localized_overrides.access<const char*>([&](const localized_map& map)
|
||||
{
|
||||
const auto entry = map.find(reference);
|
||||
if (entry != map.end())
|
||||
{
|
||||
return utils::string::va("%s", entry->second.data());
|
||||
}
|
||||
|
||||
return seh_string_ed_get_string_hook.invoke<const char*>(reference);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void override(const std::string& key, const std::string& value)
|
||||
{
|
||||
localized_overrides.access([&](localized_map& map)
|
||||
{
|
||||
map[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
class component final : public client_component
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
// Change some localized strings
|
||||
seh_string_ed_get_string_hook.create(0x1422796E0_g, &seh_string_ed_get_string);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(localized_strings::component)
|
6
src/client/component/localized_strings.hpp
Normal file
6
src/client/component/localized_strings.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace localized_strings
|
||||
{
|
||||
void override(const std::string& key, const std::string& value);
|
||||
}
|
@ -29,6 +29,9 @@ namespace patches
|
||||
{
|
||||
// don't make script errors fatal error
|
||||
utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub);
|
||||
|
||||
// Change 4 character name limit to 3 characters
|
||||
utils::hook::set<uint8_t>(game::select(0x14224DBB4, 0x1405312A8), 3);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include "structs.hpp"
|
||||
#include <utils/nt.hpp>
|
||||
|
||||
namespace arxan::detail
|
||||
{
|
||||
void set_address_to_call(const void* address);
|
||||
extern void* callstack_proxy_addr;
|
||||
}
|
||||
|
||||
namespace game
|
||||
{
|
||||
size_t get_base();
|
||||
@ -42,15 +48,15 @@ namespace game
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class symbol
|
||||
class base_symbol
|
||||
{
|
||||
public:
|
||||
symbol(const size_t address)
|
||||
base_symbol(const size_t address)
|
||||
: address_(address)
|
||||
{
|
||||
}
|
||||
|
||||
symbol(const size_t address, const size_t server_address)
|
||||
base_symbol(const size_t address, const size_t server_address)
|
||||
: address_(address)
|
||||
, server_address_(server_address)
|
||||
{
|
||||
@ -76,6 +82,26 @@ namespace game
|
||||
size_t server_address_{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct symbol : base_symbol<T>
|
||||
{
|
||||
using base_symbol<T>::base_symbol;
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
struct symbol<T(Args...)> : base_symbol<T(Args...)>
|
||||
{
|
||||
using func_type = T(Args...);
|
||||
|
||||
using base_symbol<func_type>::base_symbol;
|
||||
|
||||
T call_safe(Args... args)
|
||||
{
|
||||
arxan::detail::set_address_to_call(this->get());
|
||||
return static_cast<func_type*>(arxan::detail::callstack_proxy_addr)(args...);
|
||||
}
|
||||
};
|
||||
|
||||
std::filesystem::path get_appdata_path();
|
||||
}
|
||||
|
||||
|
@ -190,12 +190,26 @@ namespace utils::hook
|
||||
this->push(rsi);
|
||||
this->push(rdi);
|
||||
|
||||
this->sub(rsp, 0x40);
|
||||
this->push(r8);
|
||||
this->push(r9);
|
||||
this->push(r10);
|
||||
this->push(r11);
|
||||
this->push(r12);
|
||||
this->push(r13);
|
||||
this->push(r14);
|
||||
this->push(r15);
|
||||
}
|
||||
|
||||
void assembler::popad64()
|
||||
{
|
||||
this->add(rsp, 0x40);
|
||||
this->pop(r15);
|
||||
this->pop(r14);
|
||||
this->pop(r13);
|
||||
this->pop(r12);
|
||||
this->pop(r11);
|
||||
this->pop(r10);
|
||||
this->pop(r9);
|
||||
this->pop(r8);
|
||||
|
||||
this->pop(rdi);
|
||||
this->pop(rsi);
|
||||
|
Loading…
Reference in New Issue
Block a user