Merge pull request #86 from diamante0018/master
Add features from IW4x, fix buffer overflow.
This commit is contained in:
commit
cf281ed7e5
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -34,3 +34,6 @@
|
||||
path = deps/zstd
|
||||
url = https://github.com/facebook/zstd.git
|
||||
branch = dev
|
||||
[submodule "deps/minhook"]
|
||||
path = deps/minhook
|
||||
url = https://github.com/TsudaKageyu/minhook.git
|
||||
|
1
deps/minhook
vendored
Submodule
1
deps/minhook
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 4a455528f61b5a375b1f9d44e7d296d47f18bb18
|
31
deps/premake/minhook.lua
vendored
Normal file
31
deps/premake/minhook.lua
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
minhook = {
|
||||
source = path.join(dependencies.basePath, "minhook"),
|
||||
}
|
||||
|
||||
function minhook.import()
|
||||
links { "minhook" }
|
||||
minhook.includes()
|
||||
end
|
||||
|
||||
function minhook.includes()
|
||||
includedirs {
|
||||
path.join(minhook.source, "include")
|
||||
}
|
||||
end
|
||||
|
||||
function minhook.project()
|
||||
project "minhook"
|
||||
language "C"
|
||||
|
||||
minhook.includes()
|
||||
|
||||
files {
|
||||
path.join(minhook.source, "src/**.h"),
|
||||
path.join(minhook.source, "src/**.c"),
|
||||
}
|
||||
|
||||
warnings "Off"
|
||||
kind "StaticLib"
|
||||
end
|
||||
|
||||
table.insert(dependencies, minhook)
|
@ -17,8 +17,6 @@ namespace game
|
||||
|
||||
Dvar_RegisterInt_t Dvar_RegisterInt;
|
||||
|
||||
Dvar_RegisterFloat_t Dvar_RegisterFloat;
|
||||
|
||||
Dvar_SetIntByName_t Dvar_SetIntByName;
|
||||
|
||||
Dvar_SetFromStringByName_t Dvar_SetFromStringByName;
|
||||
@ -59,6 +57,8 @@ namespace game
|
||||
|
||||
SV_SendServerCommand_t SV_SendServerCommand;
|
||||
|
||||
Sys_IsServerThread_t Sys_IsServerThread;
|
||||
|
||||
XUIDToString_t XUIDToString;
|
||||
|
||||
SEH_LocalizeTextMessage_t SEH_LocalizeTextMessage;
|
||||
@ -81,6 +81,8 @@ namespace game
|
||||
|
||||
Com_Quit_f_t Com_Quit_f;
|
||||
|
||||
player_die_t player_die;
|
||||
|
||||
decltype(longjmp)* _longjmp;
|
||||
|
||||
CmdArgs* sv_cmd_args;
|
||||
@ -106,6 +108,8 @@ namespace game
|
||||
|
||||
gentity_s* g_entities;
|
||||
|
||||
DeferredQueue* deferredQueue;
|
||||
|
||||
namespace mp
|
||||
{
|
||||
client_t* svs_clients;
|
||||
@ -118,6 +122,8 @@ namespace game
|
||||
|
||||
namespace sp
|
||||
{
|
||||
sp::IsServerRunning_t IsServerRunning;
|
||||
|
||||
sp::gentity_s* g_entities;
|
||||
}
|
||||
|
||||
@ -244,13 +250,67 @@ namespace game
|
||||
{
|
||||
return dvar_find_malleable_var(dvarName);
|
||||
}
|
||||
else
|
||||
|
||||
return reinterpret_cast<dvar_t*(*)(const char*)>
|
||||
(SELECT_VALUE(0x539550, 0x5BDCC0, 0x0))(dvarName);
|
||||
}
|
||||
|
||||
__declspec(naked) const dvar_t* Dvar_RegisterVariant(const char* dvarName, unsigned char type,
|
||||
unsigned __int16 flags, DvarValue value, DvarLimits domain, const char* description)
|
||||
{
|
||||
static DWORD func = 0x531F70;
|
||||
|
||||
__asm
|
||||
{
|
||||
return reinterpret_cast<dvar_t*(*)(const char*)>
|
||||
(SELECT_VALUE(0x539550, 0x5BDCC0, 0x0))(dvarName);
|
||||
push eax
|
||||
pushad
|
||||
|
||||
mov edi, [esp + 0x24 + 0x28] // description
|
||||
mov eax, [esp + 0x24 + 0x4] // dvarName
|
||||
|
||||
push [esp + 0x24 + 0x24] // domain
|
||||
push [esp + 0x24 + 0x24] // domain
|
||||
|
||||
push [esp + 0x24 + 0x24] // value
|
||||
push [esp + 0x24 + 0x24] // value
|
||||
push [esp + 0x24 + 0x24] // value
|
||||
push [esp + 0x24 + 0x24] // value
|
||||
|
||||
push [esp + 0x24 + 0x24] // flags
|
||||
push [esp + 0x24 + 0x24] // type
|
||||
|
||||
call func
|
||||
add esp, 0x20
|
||||
|
||||
mov [esp + 0x20], eax // result
|
||||
popad
|
||||
pop eax
|
||||
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
const dvar_t* Dvar_RegisterFloat(const char* dvarName, float value,
|
||||
float min, float max, unsigned __int16 flags, const char* description)
|
||||
{
|
||||
if (!is_dedi())
|
||||
{
|
||||
return reinterpret_cast<const dvar_t*(*)(const char*, float, float, float, unsigned __int16, const char*)>
|
||||
(SELECT_VALUE(0x4F9CC0, 0x5BEA80, 0x0))(dvarName, value, min, max, flags, description);
|
||||
}
|
||||
|
||||
DvarLimits domain;
|
||||
DvarValue dvar_value;
|
||||
|
||||
domain.value.min = min;
|
||||
domain.value.max = max;
|
||||
|
||||
dvar_value.value = value;
|
||||
|
||||
return Dvar_RegisterVariant(dvarName, dvar_type::DVAR_TYPE_FLOAT,
|
||||
flags, dvar_value, domain, description);
|
||||
}
|
||||
|
||||
const float* Scr_AllocVector(const float* v)
|
||||
{
|
||||
const auto mem = static_cast<DWORD*>(MT_Alloc(16, 2));
|
||||
@ -630,8 +690,6 @@ namespace game
|
||||
|
||||
native::Dvar_RegisterInt = native::Dvar_RegisterInt_t(SELECT_VALUE(0x48CD40, 0x5BEA40, 0x0));
|
||||
|
||||
native::Dvar_RegisterFloat = native::Dvar_RegisterFloat_t(SELECT_VALUE(0x4F9CC0, 0x5BEA80, 0x0));
|
||||
|
||||
native::Dvar_SetIntByName = native::Dvar_SetIntByName_t(SELECT_VALUE(0x5396B0, 0x5BF560, 0x0));
|
||||
|
||||
native::Dvar_SetFromStringByName = native::Dvar_SetFromStringByName_t(
|
||||
@ -675,6 +733,10 @@ namespace game
|
||||
|
||||
native::SV_SendServerCommand = native::SV_SendServerCommand_t(SELECT_VALUE(0x4F6990, 0x575DE0, 0x4FD5A0));
|
||||
|
||||
native::Sys_IsServerThread = native::Sys_IsServerThread_t(SELECT_VALUE(0x4CC5A0, 0x55F9A0, 0x0));
|
||||
|
||||
native::sp::IsServerRunning = native::sp::IsServerRunning_t(0x45D310);
|
||||
|
||||
native::XUIDToString = native::XUIDToString_t(SELECT_VALUE(0x4FAA30, 0x55CC20, 0x0));
|
||||
|
||||
native::SEH_LocalizeTextMessage = native::SEH_LocalizeTextMessage_t(
|
||||
@ -701,6 +763,8 @@ namespace game
|
||||
|
||||
native::Com_Quit_f = native::Com_Quit_f_t(SELECT_VALUE(0x4F48B0, 0x5556B0, 0x4D95B0));
|
||||
|
||||
native::player_die = native::player_die_t(SELECT_VALUE(0x0, 0x503460, 0x47F4D0));
|
||||
|
||||
native::_longjmp = reinterpret_cast<decltype(longjmp)*>(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558));
|
||||
|
||||
native::sv_cmd_args = reinterpret_cast<native::CmdArgs*>(SELECT_VALUE(0x1757218, 0x1CAA998, 0x1B5E7D8));
|
||||
@ -732,5 +796,7 @@ namespace game
|
||||
|
||||
native::g_entities = reinterpret_cast<native::gentity_s*>(SELECT_VALUE(0, 0x1A66E28, 0x191B900));
|
||||
native::sp::g_entities = reinterpret_cast<native::sp::gentity_s*>(0x1197AD8);
|
||||
|
||||
native::deferredQueue = reinterpret_cast<native::DeferredQueue*>(SELECT_VALUE(0x0, 0x1D55438, 0x0));
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,6 @@ namespace game
|
||||
int min, int max, unsigned __int16 flags, const char* description);
|
||||
extern Dvar_RegisterInt_t Dvar_RegisterInt;
|
||||
|
||||
typedef const dvar_t* (*Dvar_RegisterFloat_t)(const char* dvarName, float value,
|
||||
float min, float max, unsigned __int16 flags, const char* description);
|
||||
extern Dvar_RegisterFloat_t Dvar_RegisterFloat;
|
||||
|
||||
typedef void (*Dvar_SetIntByName_t)(const char* dvarName, int value);
|
||||
extern Dvar_SetIntByName_t Dvar_SetIntByName;
|
||||
|
||||
@ -95,6 +91,9 @@ namespace game
|
||||
typedef void (*SV_SendServerCommand_t)(dedi::client_t* cl, svscmd_type type, const char* fmt, ...);
|
||||
extern SV_SendServerCommand_t SV_SendServerCommand;
|
||||
|
||||
typedef bool (*Sys_IsServerThread_t)();
|
||||
extern Sys_IsServerThread_t Sys_IsServerThread;
|
||||
|
||||
typedef void (*XUIDToString_t)(const unsigned __int64* xuid, char* str);
|
||||
extern XUIDToString_t XUIDToString;
|
||||
|
||||
@ -104,8 +103,8 @@ namespace game
|
||||
typedef void (*PM_WeaponUseAmmo_t)(playerState_s* ps, const Weapon weapon, bool isAlternate, int amount, PlayerHandIndex hand);
|
||||
extern PM_WeaponUseAmmo_t PM_WeaponUseAmmo;
|
||||
|
||||
typedef void (*CM_TransformedCapsuleTrace_t)(game::native::trace_t* results, const float* start, const float* end,
|
||||
const game::native::Bounds* bounds, const game::native::Bounds* capsule, int contents,
|
||||
typedef void (*CM_TransformedCapsuleTrace_t)(trace_t* results, const float* start, const float* end,
|
||||
const Bounds* bounds, const Bounds* capsule, int contents,
|
||||
const float* origin, const float* angles);
|
||||
extern CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace;
|
||||
|
||||
@ -133,6 +132,9 @@ namespace game
|
||||
typedef void (*Com_Quit_f_t)();
|
||||
extern Com_Quit_f_t Com_Quit_f;
|
||||
|
||||
typedef void (*player_die_t)(gentity_s* self, const gentity_s* inflictor, gentity_s* attacker, int damage, int meansOfDeath, const Weapon* iWeapon, bool isAlternate, const float* vDir, const hitLocation_t hitLoc, int psTimeOffset);
|
||||
extern player_die_t player_die;
|
||||
|
||||
extern decltype(longjmp)* _longjmp;
|
||||
|
||||
constexpr auto CMD_MAX_NESTING = 8;
|
||||
@ -161,6 +163,8 @@ namespace game
|
||||
constexpr auto ENTITYNUM_NONE = MAX_GENTITIES - 1u;
|
||||
extern gentity_s* g_entities;
|
||||
|
||||
extern DeferredQueue* deferredQueue;
|
||||
|
||||
// PM Global Definitions & Functions
|
||||
constexpr auto JUMP_LAND_SLOWDOWN_TIME = 1800;
|
||||
|
||||
@ -180,6 +184,9 @@ namespace game
|
||||
|
||||
namespace sp
|
||||
{
|
||||
typedef bool (*IsServerRunning_t)();
|
||||
extern IsServerRunning_t IsServerRunning;
|
||||
|
||||
extern sp::gentity_s* g_entities;
|
||||
}
|
||||
|
||||
@ -194,6 +201,8 @@ namespace game
|
||||
void* MT_Alloc(int numBytes, int type);
|
||||
|
||||
dvar_t* Dvar_FindVar(const char* dvarName);
|
||||
const dvar_t* Dvar_RegisterVariant(const char* dvarName, unsigned char type, unsigned __int16 flags, DvarValue value, DvarLimits domain, const char* description);
|
||||
const dvar_t* Dvar_RegisterFloat(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description);
|
||||
|
||||
const float* Scr_AllocVector(const float* v);
|
||||
void Scr_ClearOutParams();
|
||||
|
@ -547,13 +547,15 @@ namespace game
|
||||
|
||||
enum dvar_flags : std::uint16_t
|
||||
{
|
||||
DVAR_ARCHIVE = 0x1,
|
||||
DVAR_CHEAT = 0x4,
|
||||
DVAR_CODINFO = 0x8,
|
||||
DVAR_SCRIPTINFO = 0x10,
|
||||
DVAR_SERVERINFO = 0x400,
|
||||
DVAR_WRITEPROTECTED = 0x800,
|
||||
DVAR_READONLY = 0x2000,
|
||||
DVAR_ARCHIVE = 1 << 0,
|
||||
DVAR_LATCH = 1 << 1,
|
||||
DVAR_CHEAT = 1 << 2,
|
||||
DVAR_CODINFO = 1 << 3,
|
||||
DVAR_SCRIPTINFO = 1 << 4,
|
||||
DVAR_SERVERINFO = 1 << 10,
|
||||
DVAR_WRITEPROTECTED = 1 << 11,
|
||||
DVAR_READONLY = 1 << 13,
|
||||
DVAR_AUTOEXEC = 1 << 15,
|
||||
}; // Incomplete
|
||||
|
||||
enum dvar_type : std::int8_t
|
||||
@ -581,6 +583,8 @@ namespace game
|
||||
char color[4];
|
||||
};
|
||||
|
||||
static_assert(sizeof(DvarValue) == 0x10);
|
||||
|
||||
struct enum_limit
|
||||
{
|
||||
int stringCount;
|
||||
@ -736,6 +740,32 @@ namespace game
|
||||
|
||||
static_assert(sizeof(weaponParms) == 0x4C);
|
||||
|
||||
enum hitLocation_t
|
||||
{
|
||||
HITLOC_NONE = 0x0,
|
||||
HITLOC_HELMET = 0x1,
|
||||
HITLOC_HEAD = 0x2,
|
||||
HITLOC_NECK = 0x3,
|
||||
HITLOC_TORSO_UPR = 0x4,
|
||||
HITLOC_TORSO_LWR = 0x5,
|
||||
HITLOC_R_ARM_UPR = 0x6,
|
||||
HITLOC_L_ARM_UPR = 0x7,
|
||||
HITLOC_R_ARM_LWR = 0x8,
|
||||
HITLOC_L_ARM_LWR = 0x9,
|
||||
HITLOC_R_HAND = 0xA,
|
||||
HITLOC_L_HAND = 0xB,
|
||||
HITLOC_R_LEG_UPR = 0xC,
|
||||
HITLOC_L_LEG_UPR = 0xD,
|
||||
HITLOC_R_LEG_LWR = 0xE,
|
||||
HITLOC_L_LEG_LWR = 0xF,
|
||||
HITLOC_R_FOOT = 0x10,
|
||||
HITLOC_L_FOOT = 0x11,
|
||||
HITLOC_GUN = 0x12,
|
||||
HITLOC_SHIELD = 0x13,
|
||||
|
||||
HITLOC_NUM = 0x14,
|
||||
};
|
||||
|
||||
enum ViewLockTypes
|
||||
{
|
||||
PLAYERVIEWLOCK_NONE = 0x0,
|
||||
@ -800,10 +830,10 @@ namespace game
|
||||
unsigned char __pad0[0x470];
|
||||
unsigned int perks[0x2];
|
||||
unsigned int perkSlots[0x9];
|
||||
unsigned char __pad1[0x2DE8];
|
||||
unsigned char __pad1[0x2DF4];
|
||||
};
|
||||
|
||||
static_assert(sizeof(playerState_s) == 0x3300);
|
||||
static_assert(sizeof(playerState_s) == 0x330C);
|
||||
|
||||
struct pmove_t
|
||||
{
|
||||
@ -831,12 +861,46 @@ namespace game
|
||||
|
||||
static_assert(sizeof(pmove_t) == 0x138);
|
||||
|
||||
enum sessionState_t
|
||||
{
|
||||
SESS_STATE_PLAYING = 0x0,
|
||||
SESS_STATE_DEAD = 0x1,
|
||||
SESS_STATE_SPECTATOR = 0x2,
|
||||
SESS_STATE_INTERMISSION = 0x3,
|
||||
};
|
||||
|
||||
enum clientConnected_t
|
||||
{
|
||||
CON_DISCONNECTED = 0x0,
|
||||
CON_CONNECTING = 0x1,
|
||||
CON_CONNECTED = 0x2,
|
||||
};
|
||||
|
||||
struct clientSession_t
|
||||
{
|
||||
sessionState_t sessionState;
|
||||
int forceSpectatorClient;
|
||||
int killCamEntity;
|
||||
int killCamLookAtEntity;
|
||||
int status_icon;
|
||||
int archiveTime;
|
||||
int score;
|
||||
int deaths;
|
||||
int kills;
|
||||
int assists;
|
||||
unsigned __int16 scriptPersId;
|
||||
clientConnected_t connected;
|
||||
unsigned char __pad0[0x290];
|
||||
};
|
||||
|
||||
static_assert(sizeof(clientSession_t) == 0x2C0);
|
||||
|
||||
struct gclient_s
|
||||
{
|
||||
playerState_s ps;
|
||||
unsigned char __pad0[0x2CC];
|
||||
clientSession_t sess;
|
||||
int flags;
|
||||
unsigned char __pad1[0x3B0];
|
||||
unsigned char __pad0[0x3B0];
|
||||
};
|
||||
|
||||
static_assert(sizeof(gclient_s) == 0x3980);
|
||||
@ -968,6 +1032,24 @@ namespace game
|
||||
|
||||
static_assert(sizeof(netadr_s) == 24);
|
||||
|
||||
struct DeferredMsg
|
||||
{
|
||||
netadr_s addr;
|
||||
unsigned char data[1262];
|
||||
int datalen;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DeferredMsg) == 0x50C);
|
||||
|
||||
struct DeferredQueue
|
||||
{
|
||||
DeferredMsg msgs[16];
|
||||
volatile long get;
|
||||
volatile long send;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DeferredQueue) == 0x50C8);
|
||||
|
||||
struct netProfileInfo_t // Unused
|
||||
{
|
||||
unsigned char __pad0[0x5E0];
|
||||
|
56
src/module/bullet.cpp
Normal file
56
src/module/bullet.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <std_include.hpp>
|
||||
#include <loader/module_loader.hpp>
|
||||
#include "game/game.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#include "bullet.hpp"
|
||||
|
||||
const game::native::dvar_t* bullet::bg_bulletRange;
|
||||
const game::native::dvar_t* bullet::bg_surfacePenetration;
|
||||
|
||||
DWORD bullet::bullet_fire_addr;
|
||||
|
||||
utils::hook::detour bullet::bg_get_surface_penetration_depth_hook;
|
||||
|
||||
__declspec(naked) void bullet::bullet_fire_stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, bg_bulletRange
|
||||
fld dword ptr [eax + 0xC] //dvar_t.current
|
||||
pop eax
|
||||
|
||||
jmp bullet_fire_addr
|
||||
}
|
||||
}
|
||||
|
||||
float bullet::bg_get_surface_penetration_depth_stub(const game::native::Weapon weapon, bool is_alternate, int surface_type)
|
||||
{
|
||||
const auto value = bg_surfacePenetration->current.value;
|
||||
if (value > 0.0f)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return bg_get_surface_penetration_depth_hook.invoke<float>(weapon, is_alternate, surface_type);
|
||||
}
|
||||
|
||||
void bullet::post_load()
|
||||
{
|
||||
bg_bulletRange = game::native::Dvar_RegisterFloat("bg_bulletRange", 8192.0f, 0.0f,
|
||||
std::numeric_limits<float>::max(), game::native::DVAR_CODINFO,
|
||||
"Max range used when calculating the bullet end position");
|
||||
|
||||
bg_surfacePenetration = game::native::Dvar_RegisterFloat("bg_surfacePenetration", 0.0f,
|
||||
0.0f, std::numeric_limits<float>::max(), game::native::DVAR_CODINFO,
|
||||
"Set to a value greater than 0 to override the surface penetration depth");
|
||||
|
||||
bullet_fire_addr = SELECT_VALUE(0x5B6442, 0x4F6C5C, 0x46CFFA);
|
||||
utils::hook(SELECT_VALUE(0x5B643C, 0x4F6C56, 0x46CFF4), &bullet_fire_stub, HOOK_JUMP).install()->quick();
|
||||
|
||||
bg_get_surface_penetration_depth_hook.create(SELECT_VALUE(0x43BDE0, 0x42F4D0, 0x421610), &bg_get_surface_penetration_depth_stub);
|
||||
}
|
||||
|
||||
REGISTER_MODULE(bullet)
|
17
src/module/bullet.hpp
Normal file
17
src/module/bullet.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
class bullet final : public module
|
||||
{
|
||||
public:
|
||||
void post_load() override;
|
||||
|
||||
private:
|
||||
static const game::native::dvar_t* bg_bulletRange;
|
||||
static const game::native::dvar_t* bg_surfacePenetration;
|
||||
|
||||
static DWORD bullet_fire_addr;
|
||||
static void bullet_fire_stub();
|
||||
|
||||
static utils::hook::detour bg_get_surface_penetration_depth_hook;
|
||||
static float bg_get_surface_penetration_depth_stub(const game::native::Weapon weapon, bool isAlternate, int surfaceType);
|
||||
};
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "command.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
class client_command final : public module
|
||||
{
|
||||
@ -127,13 +128,28 @@ private:
|
||||
angles[1] = std::strtof(params.get(4), nullptr); // Yaw
|
||||
}
|
||||
|
||||
if (params.size() == 6u)
|
||||
if (params.size() == 6)
|
||||
{
|
||||
angles[0] = std::strtof(params.get(5), nullptr); // Pitch
|
||||
}
|
||||
|
||||
game::native::TeleportPlayer(ent, origin, angles);
|
||||
});
|
||||
|
||||
command::add_sv("kill", [](game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params)
|
||||
{
|
||||
assert(ent->client->sess.connected != game::native::CON_DISCONNECTED);
|
||||
|
||||
if (ent->client->sess.sessionState != game::native::SESS_STATE_PLAYING || !cheats_ok(ent))
|
||||
return;
|
||||
|
||||
scheduler::once([ent]
|
||||
{
|
||||
ent->flags &= ~(game::native::entityFlag::FL_GODMODE | game::native::entityFlag::FL_DEMI_GODMODE);
|
||||
ent->health = 0;
|
||||
game::native::player_die(ent, ent, ent, 100000, 12, nullptr, false, nullptr, game::native::hitLocation_t::HITLOC_NONE, 0);
|
||||
}, scheduler::pipeline::server);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -235,7 +235,7 @@ void command::add_sp_commands()
|
||||
{
|
||||
add("noclip", []()
|
||||
{
|
||||
if (!game::native::Dvar_FindVar("sv_running")->current.enabled)
|
||||
if (!game::native::sp::IsServerRunning())
|
||||
return;
|
||||
|
||||
const auto* ent = &game::native::sp::g_entities[0];
|
||||
@ -253,7 +253,7 @@ void command::add_sp_commands()
|
||||
|
||||
add("ufo", []()
|
||||
{
|
||||
if (!game::native::Dvar_FindVar("sv_running")->current.enabled)
|
||||
if (!game::native::sp::IsServerRunning())
|
||||
return;
|
||||
|
||||
const auto* ent = &game::native::sp::g_entities[0];
|
||||
@ -271,7 +271,7 @@ void command::add_sp_commands()
|
||||
|
||||
add("god", []()
|
||||
{
|
||||
if (!game::native::Dvar_FindVar("sv_running")->current.enabled)
|
||||
if (!game::native::sp::IsServerRunning())
|
||||
return;
|
||||
|
||||
auto* ent = &game::native::sp::g_entities[0];
|
||||
@ -289,7 +289,7 @@ void command::add_sp_commands()
|
||||
|
||||
add("demigod", []()
|
||||
{
|
||||
if (!game::native::Dvar_FindVar("sv_running")->current.enabled)
|
||||
if (!game::native::sp::IsServerRunning())
|
||||
return;
|
||||
|
||||
auto* ent = &game::native::sp::g_entities[0];
|
||||
@ -307,7 +307,7 @@ void command::add_sp_commands()
|
||||
|
||||
add("notarget", []()
|
||||
{
|
||||
if (!game::native::Dvar_FindVar("sv_running")->current.enabled)
|
||||
if (!game::native::sp::IsServerRunning())
|
||||
return;
|
||||
|
||||
auto* ent = &game::native::sp::g_entities[0];
|
||||
|
@ -417,7 +417,7 @@ namespace demonware
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
|
||||
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap);
|
||||
_vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||
printf("%s: %s\n", function, buffer);
|
||||
|
||||
va_end(ap);
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include "player_movement.hpp"
|
||||
|
||||
const game::native::dvar_t* player_movement::player_sustainAmmo;
|
||||
const game::native::dvar_t* player_movement::player_lastStandCrawlSpeedScale;
|
||||
const game::native::dvar_t* player_movement::player_duckedSpeedScale;
|
||||
const game::native::dvar_t* player_movement::player_proneSpeedScale;
|
||||
const game::native::dvar_t* player_movement::jump_slowdownEnable;
|
||||
const game::native::dvar_t* player_movement::jump_ladderPushVel;
|
||||
const game::native::dvar_t* player_movement::jump_enableFallDamage;
|
||||
@ -30,7 +33,7 @@ DWORD player_movement::jump_get_step_height_addr;
|
||||
void player_movement::pm_weapon_use_ammo(game::native::playerState_s* ps, const game::native::Weapon weapon,
|
||||
bool is_alternate, int amount, game::native::PlayerHandIndex hand)
|
||||
{
|
||||
if (!player_movement::player_sustainAmmo->current.enabled)
|
||||
if (!player_sustainAmmo->current.enabled)
|
||||
{
|
||||
game::native::PM_WeaponUseAmmo(ps, weapon, is_alternate, amount, hand);
|
||||
}
|
||||
@ -41,7 +44,7 @@ __declspec(naked) void player_movement::pm_step_slide_move_stub()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::pm_bounces
|
||||
mov eax, pm_bounces
|
||||
cmp byte ptr [eax + 0xC], 1
|
||||
pop eax
|
||||
|
||||
@ -62,7 +65,7 @@ __declspec(naked) void player_movement::pm_step_slide_move_stub()
|
||||
|
||||
int player_movement::stuck_in_client_stub(game::native::gentity_s* self)
|
||||
{
|
||||
if (player_movement::pm_playerEjection->current.enabled)
|
||||
if (pm_playerEjection->current.enabled)
|
||||
{
|
||||
return reinterpret_cast<int(*)(game::native::gentity_s*)>(0x4F8930)(self);
|
||||
}
|
||||
@ -74,7 +77,7 @@ void player_movement::cm_transformed_capsule_trace_stub(game::native::trace_t* r
|
||||
const float* end, const game::native::Bounds* bounds, const game::native::Bounds* capsule, int contents,
|
||||
const float* origin, const float* angles)
|
||||
{
|
||||
if (player_movement::pm_playerCollision->current.enabled)
|
||||
if (pm_playerCollision->current.enabled)
|
||||
{
|
||||
game::native::CM_TransformedCapsuleTrace(results, start, end,
|
||||
bounds, capsule, contents, origin, angles);
|
||||
@ -88,7 +91,7 @@ game::native::gentity_s* player_movement::weapon_rocket_launcher_fire_stub(game:
|
||||
auto* result = game::native::Weapon_RocketLauncher_Fire(ent, weapon, spread, wp,
|
||||
gun_vel, fire_parms, magic_bullet);
|
||||
|
||||
if (ent->client != nullptr && player_movement::pm_rocketJump->current.enabled)
|
||||
if (ent->client != nullptr && pm_rocketJump->current.enabled)
|
||||
{
|
||||
ent->client->ps.velocity[0] += (0 - wp->forward[0]) * 64.0f;
|
||||
ent->client->ps.velocity[1] += (0 - wp->forward[1]) * 64.0f;
|
||||
@ -103,7 +106,7 @@ void player_movement::pm_player_trace_stub(game::native::pmove_t* pm, game::nati
|
||||
{
|
||||
game::native::PM_playerTrace(pm, results, start, end, bounds, pass_entity_num, content_mask);
|
||||
|
||||
if (player_movement::pm_elevators->current.enabled)
|
||||
if (pm_elevators->current.enabled)
|
||||
{
|
||||
results->startsolid = false;
|
||||
}
|
||||
@ -114,7 +117,7 @@ void player_movement::pm_trace_stub(const game::native::pmove_t* pm, game::nativ
|
||||
{
|
||||
game::native::PM_trace(pm, results, start, end, bounds, pass_entity_num, content_mask);
|
||||
|
||||
if (player_movement::pm_elevators->current.enabled)
|
||||
if (pm_elevators->current.enabled)
|
||||
{
|
||||
results->allsolid = false;
|
||||
}
|
||||
@ -125,7 +128,7 @@ __declspec(naked) void player_movement::jump_push_off_ladder_stub()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_ladderPushVel
|
||||
mov eax, jump_ladderPushVel
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
@ -138,7 +141,7 @@ __declspec(naked) void player_movement::jump_check_stub()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_height
|
||||
mov eax, jump_height
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
@ -178,7 +181,7 @@ void player_movement::jump_apply_slowdown_stub(game::native::playerState_s* ps)
|
||||
}
|
||||
|
||||
if ((ps->pm_flags & game::native::PMF_DIVING) == 0
|
||||
&& player_movement::jump_slowdownEnable->current.enabled)
|
||||
&& jump_slowdownEnable->current.enabled)
|
||||
{
|
||||
game::native::VectorScale(ps->velocity, scale, ps->velocity);
|
||||
}
|
||||
@ -189,7 +192,7 @@ float player_movement::jump_get_land_factor(game::native::playerState_s* ps)
|
||||
assert(ps->pm_flags & game::native::PMF_JUMPING);
|
||||
assert(ps->pm_time <= game::native::JUMP_LAND_SLOWDOWN_TIME);
|
||||
|
||||
if (!player_movement::jump_slowdownEnable->current.enabled
|
||||
if (!jump_slowdownEnable->current.enabled
|
||||
|| (ps->pm_flags & game::native::PMF_DIVING) != 0)
|
||||
{
|
||||
return 1.0f;
|
||||
@ -197,7 +200,7 @@ float player_movement::jump_get_land_factor(game::native::playerState_s* ps)
|
||||
|
||||
if (ps->pm_time < 1700)
|
||||
{
|
||||
return (ps->pm_time * 1.5f * 0.000588f) + 1.0f;
|
||||
return (static_cast<float>(ps->pm_time) * 1.5f * 0.000588f) + 1.0f;
|
||||
}
|
||||
|
||||
return 2.5f;
|
||||
@ -210,7 +213,7 @@ __declspec(naked) void player_movement::jump_get_land_factor_stub()
|
||||
pushad
|
||||
|
||||
push eax // ps
|
||||
call player_movement::jump_get_land_factor
|
||||
call jump_get_land_factor
|
||||
add esp, 4
|
||||
|
||||
popad
|
||||
@ -225,7 +228,7 @@ __declspec(naked) void player_movement::pm_crash_land_stub_mp()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_enableFallDamage
|
||||
mov eax, jump_enableFallDamage
|
||||
cmp byte ptr [eax + 0xC], 0
|
||||
pop eax
|
||||
|
||||
@ -247,7 +250,7 @@ __declspec(naked) void player_movement::pm_crash_land_stub_sp()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_enableFallDamage
|
||||
mov eax, jump_enableFallDamage
|
||||
cmp byte ptr [eax + 0xC], 0
|
||||
pop eax
|
||||
|
||||
@ -269,7 +272,7 @@ __declspec(naked) void player_movement::jump_get_step_height_stub()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_stepSize
|
||||
mov eax, jump_stepSize
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
@ -282,11 +285,11 @@ __declspec(naked) void player_movement::jump_start_stub()
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_movement::jump_spreadAdd
|
||||
mov eax, jump_spreadAdd
|
||||
fadd dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
jmp player_movement::jump_start_addr
|
||||
jmp jump_start_addr
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +311,7 @@ void player_movement::pm_project_velocity_stub(const float* vel_in, const float*
|
||||
const auto length_scale = std::sqrtf((vel_in[2] * vel_in[2] + length_squared_2d) /
|
||||
(new_z * new_z + length_squared_2d));
|
||||
|
||||
if (player_movement::pm_bouncesAllAngles->current.enabled == true
|
||||
if (pm_bouncesAllAngles->current.enabled == true
|
||||
|| (length_scale < 1.f || new_z < 0.f || vel_in[2] > 0.f))
|
||||
{
|
||||
vel_out[0] = vel_in[0] * length_scale;
|
||||
@ -323,7 +326,7 @@ __declspec(naked) void player_movement::bg_gravity_stub()
|
||||
{
|
||||
push eax
|
||||
|
||||
mov eax, player_movement::bg_gravity
|
||||
mov eax, bg_gravity
|
||||
// Quick and widely available extension since 1999
|
||||
cvttss2si eax, dword ptr [eax + 0xC]
|
||||
mov dword ptr [ebp + 0x58], eax // ps.gravity
|
||||
@ -341,7 +344,7 @@ __declspec(naked) void player_movement::g_speed_stub()
|
||||
{
|
||||
push eax
|
||||
|
||||
mov eax, player_movement::g_speed
|
||||
mov eax, g_speed
|
||||
mov eax, dword ptr [eax + 0xC]
|
||||
mov dword ptr [ebp + 0x5C], eax // ps.speed
|
||||
|
||||
@ -352,167 +355,245 @@ __declspec(naked) void player_movement::g_speed_stub()
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void player_movement::pm_cmd_scale_crawl_speed_stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_lastStandCrawlSpeedScale
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
// Game's code
|
||||
pop ecx
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void player_movement::pm_cmd_scale_ducked_speed_stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_duckedSpeedScale
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
// Game's code
|
||||
pop ecx
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void player_movement::pm_cmd_scale_prone_speed_stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, player_proneSpeedScale
|
||||
fld dword ptr [eax + 0xC]
|
||||
pop eax
|
||||
|
||||
// Game's code
|
||||
pop ecx
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_player_sustain_ammo(const char* dvar_name,
|
||||
bool value, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::player_sustainAmmo = game::native::Dvar_RegisterBool(dvar_name,
|
||||
player_sustainAmmo = game::native::Dvar_RegisterBool(dvar_name,
|
||||
value, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::player_sustainAmmo;
|
||||
return player_sustainAmmo;
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_jump_ladder_push_vel(const char* dvar_name,
|
||||
float value, float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::jump_ladderPushVel = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
jump_ladderPushVel = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
value, min, max, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::jump_ladderPushVel;
|
||||
return jump_ladderPushVel;
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_jump_step_size(const char* dvar_name,
|
||||
float value, float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::jump_stepSize = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
jump_stepSize = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
value, min, max, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::jump_stepSize;
|
||||
return jump_stepSize;
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_jump_spread_add(const char* dvar_name,
|
||||
float value, float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::jump_spreadAdd = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
jump_spreadAdd = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
value, min, max, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::jump_spreadAdd;
|
||||
return jump_spreadAdd;
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_jump_slowdown_enable(const char* dvar_name,
|
||||
bool value, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::jump_slowdownEnable = game::native::Dvar_RegisterBool(dvar_name,
|
||||
jump_slowdownEnable = game::native::Dvar_RegisterBool(dvar_name,
|
||||
value, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::jump_slowdownEnable;
|
||||
return jump_slowdownEnable;
|
||||
}
|
||||
|
||||
const game::native::dvar_t* player_movement::dvar_register_jump_height(const char* dvar_name,
|
||||
float value, float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||
{
|
||||
player_movement::jump_height = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
jump_height = game::native::Dvar_RegisterFloat(dvar_name,
|
||||
value, min, max, game::native::DVAR_CODINFO, description);
|
||||
|
||||
return player_movement::jump_height;
|
||||
return jump_height;
|
||||
}
|
||||
|
||||
void player_movement::patch_mp()
|
||||
{
|
||||
player_movement::pm_playerEjection = game::native::Dvar_RegisterBool("pm_playerEjection",
|
||||
pm_playerEjection = game::native::Dvar_RegisterBool("pm_playerEjection",
|
||||
true, game::native::DVAR_CODINFO, "Push intersecting players away from each other");
|
||||
player_movement::pm_rocketJump = game::native::Dvar_RegisterBool("pm_rocketJump",
|
||||
pm_rocketJump = game::native::Dvar_RegisterBool("pm_rocketJump",
|
||||
false, game::native::DVAR_CODINFO, "CoD4 rocket jumps");
|
||||
// Name is correct, SP registers this dvar in BG_RegisterDvars but still names it just "g_gravity"
|
||||
player_movement::bg_gravity = game::native::Dvar_RegisterFloat("g_gravity", 800.0f,
|
||||
bg_gravity = game::native::Dvar_RegisterFloat("g_gravity", 800.0f,
|
||||
1.0f, std::numeric_limits<float>::max(), game::native::DVAR_CODINFO, "Gravity in inches per second per second");
|
||||
player_movement::g_speed = game::native::Dvar_RegisterInt("g_speed", 190,
|
||||
g_speed = game::native::Dvar_RegisterInt("g_speed", 190,
|
||||
std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), game::native::DVAR_CODINFO, "Player speed");
|
||||
|
||||
// Un-Cheat the dvars
|
||||
utils::hook(0x418D9C, &player_movement::dvar_register_player_sustain_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x4160A7, &player_movement::dvar_register_jump_ladder_push_vel, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x41602B, &player_movement::dvar_register_jump_height, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x416074, &player_movement::dvar_register_jump_slowdown_enable, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x41605E, &player_movement::dvar_register_jump_step_size, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x4160DA, &player_movement::dvar_register_jump_spread_add, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x418D9C, dvar_register_player_sustain_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x4160A7, dvar_register_jump_ladder_push_vel, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x41602B, dvar_register_jump_height, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x416074, dvar_register_jump_slowdown_enable, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x41605E, dvar_register_jump_step_size, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x4160DA, dvar_register_jump_spread_add, HOOK_CALL).install()->quick();
|
||||
|
||||
utils::hook(0x42B5DA, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x42B2BD, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x42AE95, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x42B5DA, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x42B2BD, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x42AE95, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
|
||||
utils::hook(0x424D51, &player_movement::pm_step_slide_move_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook(0x424D51, pm_step_slide_move_stub, HOOK_JUMP).install()->quick();
|
||||
|
||||
utils::hook(0x4F9EFB, &player_movement::stuck_in_client_stub, HOOK_CALL).install()->quick(); // ClientEndFrame
|
||||
utils::hook(0x57CF45, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||
utils::hook(0x482C1B, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||
utils::hook(0x4F9EFB, stuck_in_client_stub, HOOK_CALL).install()->quick(); // ClientEndFrame
|
||||
utils::hook(0x57CF45, cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||
utils::hook(0x482C1B, cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||
|
||||
utils::hook(0x530CCB, &player_movement::weapon_rocket_launcher_fire_stub, HOOK_CALL).install()->quick(); // FireWeapon
|
||||
utils::hook(0x530CCB, weapon_rocket_launcher_fire_stub, HOOK_CALL).install()->quick(); // FireWeapon
|
||||
|
||||
utils::hook(0x422861, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x4228B5, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x422861, pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x4228B5, pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
|
||||
utils::hook(0x41F995, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x41F8D8, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x41F941, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x41F995, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x41F8D8, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x41F941, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
|
||||
utils::hook(0x416866, &player_movement::jump_push_off_ladder_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook(0x416866, jump_push_off_ladder_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook::nop(0x41686B, 1); // Nop skipped opcode
|
||||
|
||||
// Modify third argument of Jump_Start with the value of jump_height dvar
|
||||
utils::hook(0x416969, &player_movement::jump_check_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook(0x416969, jump_check_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook::nop(0x41696E, 1); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x4225CA, &player_movement::jump_apply_slowdown_stub, HOOK_CALL).install()->quick(); // PM_WalkMove
|
||||
utils::hook(0x41669B, &player_movement::jump_get_land_factor_stub, HOOK_CALL).install()->quick(); // Jump_Start
|
||||
utils::hook(0x4225CA, jump_apply_slowdown_stub, HOOK_CALL).install()->quick(); // PM_WalkMove
|
||||
utils::hook(0x41669B, jump_get_land_factor_stub, HOOK_CALL).install()->quick(); // Jump_Start
|
||||
|
||||
utils::hook(0x422BE0, &player_movement::pm_crash_land_stub_mp, HOOK_CALL).install()->quick(); // PM_GroundTrace
|
||||
utils::hook(0x422BE0, pm_crash_land_stub_mp, HOOK_CALL).install()->quick(); // PM_GroundTrace
|
||||
|
||||
utils::hook(0x41613F, &player_movement::jump_get_step_height_stub, HOOK_JUMP).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook(0x41613F, jump_get_step_height_stub, HOOK_JUMP).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook::nop(0x416144, 1); // Nop skipped opcode
|
||||
|
||||
// Modify the hardcoded value of the spread with the value of jump_spreadAdd
|
||||
utils::hook(0x4166F0, &player_movement::jump_start_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook(0x4166F0, jump_start_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook::nop(0x4166F5, 1); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x424E0A, &player_movement::pm_project_velocity_stub, HOOK_CALL).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook(0x424E0A, pm_project_velocity_stub, HOOK_CALL).install()->quick(); // PM_StepSlideMove
|
||||
|
||||
utils::hook(0x4F9BB3, &player_movement::bg_gravity_stub, HOOK_JUMP).install()->quick(); // ClientEndFrame
|
||||
utils::hook(0x4F9BB3, bg_gravity_stub, HOOK_JUMP).install()->quick(); // ClientEndFrame
|
||||
utils::hook::nop(0x4F9BB8, 2); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x4F93D7, &player_movement::g_speed_stub, HOOK_JUMP).install()->quick(); // ClientThink_real
|
||||
utils::hook(0x4F93D7, g_speed_stub, HOOK_JUMP).install()->quick(); // ClientThink_real
|
||||
utils::hook::nop(0x4F93DC, 2); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x4220E5, pm_cmd_scale_crawl_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
utils::hook(0x422104, pm_cmd_scale_ducked_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
utils::hook(0x42210E, pm_cmd_scale_prone_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
}
|
||||
|
||||
void player_movement::patch_sp()
|
||||
{
|
||||
player_movement::player_sustainAmmo = game::native::Dvar_RegisterBool("player_sustainAmmo",
|
||||
player_sustainAmmo = game::native::Dvar_RegisterBool("player_sustainAmmo",
|
||||
false, game::native::DVAR_CODINFO, "Firing weapon will not decrease clip ammo");
|
||||
player_movement::jump_ladderPushVel = game::native::Dvar_RegisterFloat("jump_ladderPushVel",
|
||||
jump_ladderPushVel = game::native::Dvar_RegisterFloat("jump_ladderPushVel",
|
||||
128.0f, 0.0f, 1024.0f, game::native::DVAR_CODINFO, "The velocity of a jump off of a ladder");
|
||||
player_movement::jump_stepSize = game::native::Dvar_RegisterFloat("jump_stepSize",
|
||||
jump_stepSize = game::native::Dvar_RegisterFloat("jump_stepSize",
|
||||
18.0f, 0.0f, 64.0f, game::native::DVAR_CODINFO, "The maximum step up to the top of a jump arc");
|
||||
player_movement::jump_spreadAdd = game::native::Dvar_RegisterFloat("jump_spreadAdd",
|
||||
jump_spreadAdd = game::native::Dvar_RegisterFloat("jump_spreadAdd",
|
||||
64.0f, 0.0f, 512.0f, game::native::DVAR_CODINFO, "The amount of spread scale to add as a side effect of jumping");
|
||||
|
||||
utils::hook(0x648C3A, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x64891D, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x6484E2, &player_movement::pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x648C3A, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x64891D, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
utils::hook(0x6484E2, pm_weapon_use_ammo, HOOK_CALL).install()->quick();
|
||||
|
||||
utils::hook(0x43D918, &player_movement::pm_step_slide_move_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook(0x43D918, pm_step_slide_move_stub, HOOK_JUMP).install()->quick();
|
||||
|
||||
utils::hook(0x41F9A6, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||
utils::hook(0x57B14F, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||
utils::hook(0x41F9A6, cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||
utils::hook(0x57B14F, cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||
|
||||
utils::hook(0x643F84, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x643FDB, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x643F84, pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
utils::hook(0x643FDB, pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint
|
||||
|
||||
utils::hook(0x64181A, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x641701, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x6417A9, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x64181A, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x641701, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
utils::hook(0x6417A9, pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck
|
||||
|
||||
utils::hook(0x63EA46, player_movement::jump_push_off_ladder_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook(0x63EA46, jump_push_off_ladder_stub, HOOK_JUMP).install()->quick(); // Jump_Check
|
||||
utils::hook::nop(0x63EA4B, 1); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x6442DF, &player_movement::pm_crash_land_stub_sp, HOOK_CALL).install()->quick(); // PM_GroundTrace
|
||||
utils::hook(0x6442DF, pm_crash_land_stub_sp, HOOK_CALL).install()->quick(); // PM_GroundTrace
|
||||
|
||||
utils::hook(0x48C1DC, &player_movement::jump_get_step_height_stub, HOOK_JUMP).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook(0x48C1DC, jump_get_step_height_stub, HOOK_JUMP).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook::nop(0x48C1E1, 1); // Nop skipped opcode
|
||||
|
||||
// Modify the hardcoded value of the spread with the value of jump_spreadAdd
|
||||
utils::hook(0x63E90A, &player_movement::jump_start_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook(0x63E90A, jump_start_stub, HOOK_JUMP).install()->quick();
|
||||
utils::hook::nop(0x63E90F, 1); // Nop skipped opcode
|
||||
|
||||
utils::hook(0x43D9D1, &player_movement::pm_project_velocity_stub, HOOK_CALL).install()->quick(); // PM_StepSlideMove
|
||||
utils::hook(0x43D9D1, pm_project_velocity_stub, HOOK_CALL).install()->quick(); // PM_StepSlideMove
|
||||
|
||||
utils::hook(0x64384F, pm_cmd_scale_crawl_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
utils::hook(0x643859, pm_cmd_scale_ducked_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
utils::hook(0x643863, pm_cmd_scale_prone_speed_stub, HOOK_JUMP).install()->quick(); // PM_CmdScaleForStance
|
||||
}
|
||||
|
||||
void player_movement::register_common_dvars()
|
||||
{
|
||||
// Pm dvars
|
||||
pm_bounces = game::native::Dvar_RegisterBool("pm_bounces", false,
|
||||
game::native::DVAR_CODINFO, "CoD4 Bounces");
|
||||
pm_bouncesAllAngles = game::native::Dvar_RegisterBool("pm_bouncesAllAngles", false,
|
||||
game::native::DVAR_CODINFO, "Force bounces from all angles");
|
||||
pm_playerCollision = game::native::Dvar_RegisterBool("pm_playerCollision",
|
||||
true, game::native::DVAR_CODINFO, "Push intersecting players away from each other");
|
||||
pm_elevators = game::native::Dvar_RegisterBool("pm_elevators",
|
||||
false, game::native::DVAR_CODINFO, "CoD4 Elevators");
|
||||
|
||||
// Jump dvars
|
||||
jump_enableFallDamage = game::native::Dvar_RegisterBool("jump_enableFallDamage",
|
||||
true, game::native::DVAR_CODINFO, "Enable fall damage");
|
||||
|
||||
// Player dvars
|
||||
player_lastStandCrawlSpeedScale = game::native::Dvar_RegisterFloat("player_lastStandCrawlSpeedScale", 0.2f,
|
||||
0.0f, 5.0f, game::native::DVAR_CODINFO, "The scale applied to the player speed when crawling in last stand");
|
||||
player_duckedSpeedScale = game::native::Dvar_RegisterFloat("player_duckedSpeedScale", 0.65f,
|
||||
0.0f, 5.0f, game::native::DVAR_CODINFO, "The scale applied to the player speed when ducking");
|
||||
player_proneSpeedScale = game::native::Dvar_RegisterFloat("player_proneSpeedScale", 0.15f,
|
||||
0.0f, 5.0f, game::native::DVAR_CODINFO, "The scale applied to the player speed when ducking");
|
||||
}
|
||||
|
||||
void player_movement::post_load()
|
||||
@ -525,22 +606,13 @@ void player_movement::post_load()
|
||||
return;
|
||||
}
|
||||
|
||||
player_movement::bounce_addr = SELECT_VALUE(0x43D91F, 0x424D58, 0x0);
|
||||
player_movement::dont_bounce_addr = SELECT_VALUE(0x43D933, 0x424D6C, 0x0);
|
||||
player_movement::push_off_ladder_addr = SELECT_VALUE(0x63EA4C, 0x41686C, 0x0);
|
||||
player_movement::jump_start_addr = SELECT_VALUE(0x63E910, 0x4166F6, 0x0);
|
||||
player_movement::jump_get_step_height_addr = SELECT_VALUE(0x48C1E2, 0x416145, 0x0);
|
||||
bounce_addr = SELECT_VALUE(0x43D91F, 0x424D58, 0x0);
|
||||
dont_bounce_addr = SELECT_VALUE(0x43D933, 0x424D6C, 0x0);
|
||||
push_off_ladder_addr = SELECT_VALUE(0x63EA4C, 0x41686C, 0x0);
|
||||
jump_start_addr = SELECT_VALUE(0x63E910, 0x4166F6, 0x0);
|
||||
jump_get_step_height_addr = SELECT_VALUE(0x48C1E2, 0x416145, 0x0);
|
||||
|
||||
player_movement::pm_bounces = game::native::Dvar_RegisterBool("pm_bounces", false,
|
||||
game::native::dvar_flags::DVAR_CODINFO, "CoD4 Bounces");
|
||||
player_movement::pm_bouncesAllAngles = game::native::Dvar_RegisterBool("pm_bouncesAllAngles", false,
|
||||
game::native::dvar_flags::DVAR_CODINFO, "Force bounces from all angles");
|
||||
player_movement::pm_playerCollision = game::native::Dvar_RegisterBool("pm_playerCollision",
|
||||
true, game::native::DVAR_CODINFO, "Push intersecting players away from each other");
|
||||
player_movement::pm_elevators = game::native::Dvar_RegisterBool("pm_elevators",
|
||||
false, game::native::DVAR_CODINFO, "CoD4 Elevators");
|
||||
player_movement::jump_enableFallDamage = game::native::Dvar_RegisterBool("jump_enableFallDamage",
|
||||
true, game::native::dvar_flags::DVAR_CODINFO, "Enable fall damage");
|
||||
this->register_common_dvars();
|
||||
|
||||
if (game::is_mp()) this->patch_mp();
|
||||
else if (game::is_sp()) this->patch_sp();
|
||||
|
@ -6,19 +6,26 @@ public:
|
||||
void post_load() override;
|
||||
|
||||
private:
|
||||
// Player dvars
|
||||
static const game::native::dvar_t* player_sustainAmmo;
|
||||
static const game::native::dvar_t* player_lastStandCrawlSpeedScale;
|
||||
static const game::native::dvar_t* player_duckedSpeedScale;
|
||||
static const game::native::dvar_t* player_proneSpeedScale;
|
||||
// Jump dvars
|
||||
static const game::native::dvar_t* jump_slowdownEnable;
|
||||
static const game::native::dvar_t* jump_ladderPushVel;
|
||||
static const game::native::dvar_t* jump_enableFallDamage;
|
||||
static const game::native::dvar_t* jump_height;
|
||||
static const game::native::dvar_t* jump_stepSize;
|
||||
static const game::native::dvar_t* jump_spreadAdd;
|
||||
// Pm dvars
|
||||
static const game::native::dvar_t* pm_bounces;
|
||||
static const game::native::dvar_t* pm_bouncesAllAngles;
|
||||
static const game::native::dvar_t* pm_playerEjection;
|
||||
static const game::native::dvar_t* pm_playerCollision;
|
||||
static const game::native::dvar_t* pm_rocketJump;
|
||||
static const game::native::dvar_t* pm_elevators;
|
||||
// Misc dvars
|
||||
static const game::native::dvar_t* bg_gravity;
|
||||
static const game::native::dvar_t* g_speed;
|
||||
|
||||
@ -83,6 +90,11 @@ private:
|
||||
static void bg_gravity_stub();
|
||||
static void g_speed_stub();
|
||||
|
||||
static void pm_cmd_scale_crawl_speed_stub();
|
||||
static void pm_cmd_scale_ducked_speed_stub();
|
||||
static void pm_cmd_scale_prone_speed_stub();
|
||||
|
||||
static void register_common_dvars();
|
||||
static void patch_mp();
|
||||
static void patch_sp();
|
||||
};
|
||||
|
@ -12,6 +12,8 @@ public:
|
||||
if (game::is_mp())
|
||||
{
|
||||
utils::hook(0x4AECD4, read_p2p_auth_ticket_stub, HOOK_JUMP).install()->quick();
|
||||
|
||||
utils::hook(0x57680C, net_defer_packet_to_client, HOOK_CALL).install()->quick(); // SV_ConnectionlessPacket
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +23,25 @@ private:
|
||||
if (len < 0) return;
|
||||
return game::native::MSG_ReadData(msg, data, std::min(len, 200));
|
||||
}
|
||||
|
||||
static void net_defer_packet_to_client(game::native::netadr_s* net_from, game::native::msg_t* net_message)
|
||||
{
|
||||
assert(game::native::Sys_IsServerThread());
|
||||
|
||||
if (static_cast<std::size_t>(net_message->cursize) >= sizeof(game::native::DeferredMsg::data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto* msg = &game::native::deferredQueue->msgs[game::native::deferredQueue->send
|
||||
% std::extent_v<decltype(game::native::DeferredQueue::msgs)>];
|
||||
std::memcpy(msg->data, net_message->data, net_message->cursize);
|
||||
|
||||
msg->datalen = net_message->cursize;
|
||||
msg->addr = *net_from;
|
||||
|
||||
InterlockedIncrement(&game::native::deferredQueue->send);
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_MODULE(security)
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <mshtml.h>
|
||||
#include <mshtmhst.h>
|
||||
#include <Windows.h>
|
||||
#include <MsHTML.h>
|
||||
#include <MsHtmHst.h>
|
||||
#include <ExDisp.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <corecrt_io.h>
|
||||
#include <fcntl.h>
|
||||
#include <shellapi.h>
|
||||
@ -74,4 +74,4 @@
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
extern __declspec(thread) char tls_data[TLS_PAYLOAD_SIZE];
|
||||
extern __declspec(thread) char tls_data[TLS_PAYLOAD_SIZE];
|
||||
|
@ -1,8 +1,30 @@
|
||||
#include <std_include.hpp>
|
||||
#include "hook.hpp"
|
||||
|
||||
#include <MinHook.h>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace
|
||||
{
|
||||
[[maybe_unused]] class _
|
||||
{
|
||||
public:
|
||||
_()
|
||||
{
|
||||
if (MH_Initialize() != MH_OK)
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize MinHook");
|
||||
}
|
||||
}
|
||||
|
||||
~_()
|
||||
{
|
||||
MH_Uninitialize();
|
||||
}
|
||||
} __;
|
||||
}
|
||||
|
||||
void hook::signature::process()
|
||||
{
|
||||
if (this->signatures_.empty()) return;
|
||||
@ -42,6 +64,64 @@ namespace utils
|
||||
signatures_.push_back(container);
|
||||
}
|
||||
|
||||
hook::detour::detour(const size_t place, void* target) : detour(reinterpret_cast<void*>(place), target)
|
||||
{
|
||||
}
|
||||
|
||||
hook::detour::detour(void* place, void* target)
|
||||
{
|
||||
this->create(place, target);
|
||||
}
|
||||
|
||||
hook::detour::~detour()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void hook::detour::enable() const
|
||||
{
|
||||
MH_EnableHook(this->place_);
|
||||
}
|
||||
|
||||
void hook::detour::disable() const
|
||||
{
|
||||
MH_DisableHook(this->place_);
|
||||
}
|
||||
|
||||
void hook::detour::create(void* place, void* target)
|
||||
{
|
||||
this->clear();
|
||||
this->place_ = place;
|
||||
|
||||
if (MH_CreateHook(this->place_, target, &this->original_) != MH_OK)
|
||||
{
|
||||
throw std::runtime_error("Unable to create hook");
|
||||
}
|
||||
|
||||
this->enable();
|
||||
}
|
||||
|
||||
void hook::detour::create(const size_t place, void* target)
|
||||
{
|
||||
this->create(reinterpret_cast<void*>(place), target);
|
||||
}
|
||||
|
||||
void hook::detour::clear()
|
||||
{
|
||||
if (this->place_)
|
||||
{
|
||||
MH_RemoveHook(this->place_);
|
||||
}
|
||||
|
||||
this->place_ = nullptr;
|
||||
this->original_ = nullptr;
|
||||
}
|
||||
|
||||
void* hook::detour::get_original() const
|
||||
{
|
||||
return this->original_;
|
||||
}
|
||||
|
||||
hook::~hook()
|
||||
{
|
||||
if (this->initialized_)
|
||||
|
@ -40,6 +40,64 @@ namespace utils
|
||||
std::vector<container> signatures_;
|
||||
};
|
||||
|
||||
class detour
|
||||
{
|
||||
public:
|
||||
detour() = default;
|
||||
detour(void* place, void* target);
|
||||
detour(size_t place, void* target);
|
||||
~detour();
|
||||
|
||||
detour(detour&& other) noexcept
|
||||
{
|
||||
this->operator=(std::move(other));
|
||||
}
|
||||
|
||||
detour& operator=(detour&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->~detour();
|
||||
|
||||
this->place_ = other.place_;
|
||||
this->original_ = other.original_;
|
||||
|
||||
other.place_ = nullptr;
|
||||
other.original_ = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
detour(const detour&) = delete;
|
||||
detour& operator=(const detour&) = delete;
|
||||
|
||||
void enable() const;
|
||||
void disable() const;
|
||||
|
||||
void create(void* place, void* target);
|
||||
void create(size_t place, void* target);
|
||||
void clear();
|
||||
|
||||
template <typename T>
|
||||
T* get() const
|
||||
{
|
||||
return static_cast<T*>(this->get_original());
|
||||
}
|
||||
|
||||
template <typename T = void, typename... Args>
|
||||
T invoke(Args ... args)
|
||||
{
|
||||
return static_cast<T(*)(Args ...)>(this->get_original())(args...);
|
||||
}
|
||||
|
||||
[[nodiscard]] void* get_original() const;
|
||||
|
||||
private:
|
||||
void* place_{};
|
||||
void* original_{};
|
||||
};
|
||||
|
||||
hook() : initialized_(false), installed_(false), place_(nullptr), stub_(nullptr), original_(nullptr),
|
||||
use_jump_(false), protection_(0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user