Alot of warp related stuff (see description)
- Add a speed meter - Smoothen Warp Drastically - GIve full control while in warp (Especially useful for bots) - Rewrite the peek mode - Add 22 tick fakelag (as a sideeffect)
This commit is contained in:
parent
ef59d93734
commit
d259fbacd0
@ -5,7 +5,7 @@
|
||||
<AutoVariable width="fill" target="antiaim.draw-fakes" label="Draw Fakes"/>
|
||||
<AutoVariable width="fill" target="antiaim.crouch" label="Fake Crouch"/>
|
||||
<AutoVariable width="fill" target="antiaim.no-clamp" label="No Clamping"/>
|
||||
<AutoVariable width="fill" target="misc.fakelag" label="Fakelag" min="0" max="15"/>
|
||||
<AutoVariable width="fill" target="misc.fakelag" label="Fakelag" min="0" max="22"/>
|
||||
<AutoVariable width="fill" target="antiaim.spin-speed" label="Spin speed" min="-45" max="45" step="0.1"/>
|
||||
<AutoVariable width="fill" target="antiaim.roll" label="Roll"/>
|
||||
<AutoVariable width="fill" target="antiaim.pitch.static" label="Custom Pitch"/>
|
||||
|
@ -59,6 +59,7 @@
|
||||
<Box padding="12 6 6 6" width="content" height="content" name="Warp" x="370" y="65">
|
||||
<List width="180">
|
||||
<AutoVariable width="fill" target="warp.enabled" label="Enable Warp" tooltip="Allows you to charge a burst of speed"/>
|
||||
<AutoVariable width="fill" target="warp.speed" label="Warp speed" tooltip="The Discharge speed (0.5 = +50%, 2 = +200%, +1000% is the maximum possible)"/>
|
||||
<AutoVariable width="fill" target="warp.key" label="Warp Key" tooltip="Pressing this key will use all stored ticks to accelerate you"/>
|
||||
<AutoVariable width="fill" target="warp.draw" label="Draw Warp" tooltip="Draws a bar indicating your warp readyness"/>
|
||||
<AutoVariable width="fill" target="warp.bar-size" label="Bar Size"/>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <inetmsghandler.h>
|
||||
#include <KeyValues.h>
|
||||
#include "bitvec.h"
|
||||
#include "CSignature.h"
|
||||
|
||||
#define DECLARE_BASE_MESSAGE(msgtype) \
|
||||
public: \
|
||||
@ -98,6 +99,26 @@ public:
|
||||
return false;
|
||||
}; // no handler set
|
||||
|
||||
public:
|
||||
// I don't get what it does but we need it
|
||||
virtual bool BIncomingMessageForProcessing(double param_1, int param_2)
|
||||
{
|
||||
// Call original to be sure nothing breaks
|
||||
typedef bool (*BIncomingMessageForProcessing_t)(CNetMessage *, double, int);
|
||||
static auto addr = gSignatures.GetEngineSignature("55 89 E5 56 53 83 EC 10 8B 5D ? F2 0F 10 45");
|
||||
BIncomingMessageForProcessing_t BIncomingMessageForProcessing_fn = (BIncomingMessageForProcessing_t)addr;
|
||||
return BIncomingMessageForProcessing_fn(this, param_1, param_2);
|
||||
};
|
||||
// I don't get what it does but we need it
|
||||
virtual void SetRatePolicy()
|
||||
{
|
||||
// Call original to be sure nothing breaks
|
||||
typedef bool (*SetRatePolicy_t)(CNetMessage *);
|
||||
static auto addr = gSignatures.GetEngineSignature("55 89 E5 83 EC 18 C7 04 24 2C 00 00 00");
|
||||
SetRatePolicy_t SetRatePolicy_fn = (SetRatePolicy_t)addr;
|
||||
SetRatePolicy_fn(this);
|
||||
};
|
||||
|
||||
protected:
|
||||
bool m_bReliable; // true if message should be send reliable
|
||||
INetChannel *m_NetChannel; // netchannel this message is from/for
|
||||
@ -177,7 +198,7 @@ protected:
|
||||
|
||||
#define MAX_OSPATH 260
|
||||
|
||||
#define NETMSG_TYPE_BITS 5
|
||||
#define NETMSG_TYPE_BITS 6
|
||||
typedef int QueryCvarCookie_t;
|
||||
typedef enum
|
||||
{
|
||||
|
@ -11,10 +11,12 @@
|
||||
#endif
|
||||
#include "MiscAimbot.hpp"
|
||||
#include "PlayerTools.hpp"
|
||||
#include "DetourHook.hpp"
|
||||
|
||||
namespace hacks::tf2::warp
|
||||
{
|
||||
static settings::Boolean enabled{ "warp.enabled", "false" };
|
||||
static settings::Float speed{ "warp.speed", "10" };
|
||||
static settings::Boolean draw{ "warp.draw", "false" };
|
||||
static settings::Button warp_key{ "warp.key", "<null>" };
|
||||
static settings::Boolean charge_passively{ "warp.charge-passively", "true" };
|
||||
@ -34,63 +36,73 @@ static settings::Int size{ "warp.bar-size", "100" };
|
||||
static settings::Int bar_x{ "warp.bar-x", "50" };
|
||||
static settings::Int bar_y{ "warp.bar-y", "200" };
|
||||
|
||||
static bool should_charge = false;
|
||||
static int warp_amount = 0;
|
||||
static int warp_amount_override = 0;
|
||||
static int warp_override_one_tick = 0;
|
||||
static bool charged = false;
|
||||
|
||||
// Taken from MrSteyk
|
||||
class clc_move_proto
|
||||
{
|
||||
public:
|
||||
int VTable;
|
||||
char reliable;
|
||||
int netchan;
|
||||
int field_C;
|
||||
int field_10;
|
||||
int m_nBackupCommands;
|
||||
int m_nNewCommands;
|
||||
int m_nLength;
|
||||
bf_write m_DataIn;
|
||||
bf_write m_DataOut;
|
||||
};
|
||||
static bool should_charge = false;
|
||||
static int warp_amount = 0;
|
||||
static int warp_amount_override = 0;
|
||||
static bool charged = false;
|
||||
|
||||
// How many ticks of excess we have (for decimal speeds)
|
||||
float excess_ticks = 0.0f;
|
||||
int GetWarpAmount()
|
||||
{
|
||||
static auto sv_max_dropped_packets_to_process = g_ICvar->FindVar("sv_max_dropped_packets_to_process");
|
||||
return warp_override_one_tick ? warp_override_one_tick : sv_max_dropped_packets_to_process->GetInt();
|
||||
float warp_amount_preprocessed = *speed;
|
||||
// Store excess
|
||||
excess_ticks += warp_amount_preprocessed - std::floor(warp_amount_preprocessed);
|
||||
|
||||
// How many ticks to warp, add excess too
|
||||
int warp_amount_processed = std::floor(warp_amount_preprocessed) + std::floor(excess_ticks);
|
||||
|
||||
// Remove the used amount from excess
|
||||
excess_ticks -= std::floor(excess_ticks);
|
||||
|
||||
// Return smallest of the two
|
||||
return std::min(warp_amount_processed, sv_max_dropped_packets_to_process->GetInt());
|
||||
}
|
||||
|
||||
static bool should_warp = true;
|
||||
static bool was_hurt = false;
|
||||
|
||||
// Warping part
|
||||
void Warp()
|
||||
DetourHook cl_move_detour;
|
||||
typedef void (*CL_Move_t)(float accumulated_extra_samples, bool bFinalTick);
|
||||
|
||||
// Warping part, uses CL_Move
|
||||
void Warp(float accumulated_extra_samples, bool finalTick)
|
||||
{
|
||||
auto ch = g_IEngine->GetNetChannelInfo();
|
||||
if (!ch)
|
||||
return;
|
||||
if (!should_warp)
|
||||
{
|
||||
should_warp = true;
|
||||
if (finalTick)
|
||||
should_warp = true;
|
||||
return;
|
||||
}
|
||||
int &m_nOutSequenceNr = *(int *) ((uintptr_t) ch + offsets::m_nOutSequenceNr());
|
||||
|
||||
int warp_ticks = warp_amount;
|
||||
if (warp_amount_override)
|
||||
warp_ticks = warp_amount_override;
|
||||
|
||||
// Don' add more than the warp_ticks
|
||||
m_nOutSequenceNr += std::min(warp_ticks, GetWarpAmount());
|
||||
warp_amount -= std::min(warp_ticks, GetWarpAmount());
|
||||
warp_ticks -= std::min(warp_ticks, GetWarpAmount());
|
||||
CL_Move_t original = (CL_Move_t) cl_move_detour.GetOriginalFunc();
|
||||
|
||||
// Call CL_Move once for every warp tick
|
||||
int warp_amnt = GetWarpAmount();
|
||||
for (int i = 0; i <= std::min(warp_ticks, warp_amnt); i++)
|
||||
{
|
||||
original(accumulated_extra_samples, finalTick);
|
||||
// Only decrease ticks for the final CL_Move tick
|
||||
if (finalTick)
|
||||
{
|
||||
warp_amount--;
|
||||
warp_ticks--;
|
||||
}
|
||||
}
|
||||
|
||||
cl_move_detour.RestorePatch();
|
||||
|
||||
if (warp_amount_override)
|
||||
warp_amount_override = warp_ticks;
|
||||
|
||||
// Don't attack while warping
|
||||
current_user_cmd->buttons &= ~IN_ATTACK;
|
||||
if (warp_ticks <= 0)
|
||||
{
|
||||
was_hurt = false;
|
||||
@ -122,7 +134,7 @@ void SendNetMessage(INetMessage &msg)
|
||||
if (should_charge && !charged)
|
||||
{
|
||||
int ticks = GetMaxWarpTicks();
|
||||
auto movemsg = (clc_move_proto *) &msg;
|
||||
auto movemsg = (CLC_Move *) &msg;
|
||||
// Just null it :shrug:
|
||||
movemsg->m_nBackupCommands = 0;
|
||||
movemsg->m_nNewCommands = 0;
|
||||
@ -138,13 +150,6 @@ void SendNetMessage(INetMessage &msg)
|
||||
charged = true;
|
||||
}
|
||||
}
|
||||
// Warp
|
||||
if ((warp_key.isKeyDown() || was_hurt) && warp_amount)
|
||||
{
|
||||
Warp();
|
||||
if (warp_amount < GetMaxWarpTicks())
|
||||
charged = false;
|
||||
}
|
||||
}
|
||||
should_charge = false;
|
||||
}
|
||||
@ -165,7 +170,19 @@ enum charge_state
|
||||
DONE
|
||||
};
|
||||
|
||||
charge_state current_state = ATTACK;
|
||||
enum peek_state
|
||||
{
|
||||
IDLE = 0,
|
||||
MOVE_TOWARDS,
|
||||
MOVE_BACK,
|
||||
STOP
|
||||
};
|
||||
|
||||
charge_state current_state = ATTACK;
|
||||
peek_state current_peek_state = IDLE;
|
||||
|
||||
// Used to determine when we should start moving back with peek
|
||||
static int charge_at_start = 0;
|
||||
|
||||
// Used to determine when demoknight warp should be over
|
||||
static bool was_overridden = false;
|
||||
@ -175,11 +192,11 @@ void CreateMove()
|
||||
return;
|
||||
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer())
|
||||
return;
|
||||
warp_override_one_tick = 0;
|
||||
if (!warp_key.isKeyDown() && !was_hurt)
|
||||
{
|
||||
warp_last_tick = false;
|
||||
current_state = ATTACK;
|
||||
warp_last_tick = false;
|
||||
current_state = ATTACK;
|
||||
current_peek_state = IDLE;
|
||||
|
||||
Vector velocity{};
|
||||
velocity::EstimateAbsVelocity(RAW_ENT(LOCAL_E), velocity);
|
||||
@ -329,34 +346,59 @@ void CreateMove()
|
||||
// Warp peaking
|
||||
else if (warp_peek)
|
||||
{
|
||||
// We have Warp
|
||||
if (warp_amount)
|
||||
switch (current_peek_state)
|
||||
{
|
||||
// Warped last tick, time to reverse
|
||||
if (warp_last_tick)
|
||||
{
|
||||
// Wait 1 tick before warping back
|
||||
if (should_warp && !should_warp_last_tick)
|
||||
{
|
||||
should_warp_last_tick = true;
|
||||
should_warp = false;
|
||||
}
|
||||
else
|
||||
should_warp_last_tick = false;
|
||||
case IDLE:
|
||||
{
|
||||
// Not doing anything, update warp amount
|
||||
charge_at_start = warp_amount;
|
||||
|
||||
// Inverse direction
|
||||
current_user_cmd->forwardmove = -current_user_cmd->forwardmove;
|
||||
current_user_cmd->sidemove = -current_user_cmd->sidemove;
|
||||
}
|
||||
Vector vel;
|
||||
velocity::EstimateAbsVelocity(RAW_ENT(LOCAL_E), vel);
|
||||
|
||||
// if we move more than 1.0 HU/s , go to move towards statement...
|
||||
if (!vel.IsZero(1.0f))
|
||||
current_peek_state = MOVE_TOWARDS;
|
||||
// ...else don't warp
|
||||
else
|
||||
warp_override_one_tick = warp_amount / 2;
|
||||
warp_last_tick = true;
|
||||
{
|
||||
should_warp = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// No "break;" here is intentional :)
|
||||
}
|
||||
// Prevent movement so you don't overshoot when you don't want to
|
||||
else
|
||||
case MOVE_TOWARDS:
|
||||
{
|
||||
// Just wait until we used about half of our warp, then we can start going back
|
||||
if (warp_amount <= charge_at_start / 2.0f)
|
||||
current_peek_state = MOVE_BACK;
|
||||
break;
|
||||
}
|
||||
case MOVE_BACK:
|
||||
{
|
||||
// Inverse direction if we still have warp left
|
||||
if (warp_amount)
|
||||
{
|
||||
current_user_cmd->forwardmove *= -1.0f;
|
||||
current_user_cmd->sidemove *= -1.0f;
|
||||
break;
|
||||
}
|
||||
// ... Else we stop in our tracks
|
||||
else
|
||||
current_peek_state = STOP;
|
||||
|
||||
// Once again, intentionally missing "break;"
|
||||
}
|
||||
case STOP:
|
||||
{
|
||||
// Stop dead in our tracks while key is still held
|
||||
current_user_cmd->forwardmove = 0.0f;
|
||||
current_user_cmd->sidemove = 0.0f;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
was_hurt_last_tick = was_hurt;
|
||||
@ -438,12 +480,93 @@ void rvarCallback(settings::VariableBase<bool> &, bool)
|
||||
yaw_selections.push_back(90.0f);
|
||||
}
|
||||
|
||||
DetourHook cl_sendmove_detour;
|
||||
typedef void (*CL_SendMove_t)();
|
||||
void CL_SendMove_hook()
|
||||
{
|
||||
byte data[4000];
|
||||
|
||||
// the +4 one is choked commands
|
||||
int nextcommandnr = NET_INT(g_IBaseClientState, offsets::lastoutgoingcommand()) + NET_INT(g_IBaseClientState, offsets::lastoutgoingcommand() + 4) + 1;
|
||||
|
||||
// send the client update packet
|
||||
|
||||
CLC_Move moveMsg;
|
||||
|
||||
moveMsg.m_DataOut.StartWriting(data, sizeof(data));
|
||||
|
||||
// Determine number of backup commands to send along
|
||||
int cl_cmdbackup = 2;
|
||||
|
||||
// How many real new commands have queued up
|
||||
moveMsg.m_nNewCommands = 1 + NET_INT(g_IBaseClientState, offsets::lastoutgoingcommand() + 4);
|
||||
moveMsg.m_nNewCommands = std::clamp(moveMsg.m_nNewCommands, 0, 15);
|
||||
|
||||
// Excessive commands (Used for longer fakelag, credits to https://www.unknowncheats.me/forum/source-engine/370916-23-tick-guwop-fakelag-break-lag-compensation-running.html)
|
||||
int extra_commands = NET_INT(g_IBaseClientState, offsets::lastoutgoingcommand() + 4) + 1 - moveMsg.m_nNewCommands;
|
||||
cl_cmdbackup = std::max(2, extra_commands);
|
||||
moveMsg.m_nBackupCommands = std::clamp(cl_cmdbackup, 0, 7);
|
||||
|
||||
int numcmds = moveMsg.m_nNewCommands + moveMsg.m_nBackupCommands;
|
||||
|
||||
int from = -1; // first command is deltaed against zeros
|
||||
|
||||
bool bOK = true;
|
||||
|
||||
for (int to = nextcommandnr - numcmds + 1; to <= nextcommandnr; to++)
|
||||
{
|
||||
bool isnewcmd = to >= (nextcommandnr - moveMsg.m_nNewCommands + 1);
|
||||
|
||||
// Call the write to buffer
|
||||
typedef bool (*WriteUsercmdDeltaToBuffer_t)(IBaseClientDLL *, bf_write *, int, int, bool);
|
||||
|
||||
// first valid command number is 1
|
||||
bOK = bOK && vfunc<WriteUsercmdDeltaToBuffer_t>(g_IBaseClient, offsets::PlatformOffset(23, offsets::undefined, offsets::undefined), 0)(g_IBaseClient, &moveMsg.m_DataOut, from, to, isnewcmd);
|
||||
from = to;
|
||||
}
|
||||
|
||||
if (bOK)
|
||||
{
|
||||
// Make fakelag work as we want it to
|
||||
if (extra_commands > 0)
|
||||
((INetChannel *) g_IEngine->GetNetChannelInfo())->m_nChokedPackets -= extra_commands;
|
||||
|
||||
// only write message if all usercmds were written correctly, otherwise parsing would fail
|
||||
((INetChannel *) g_IEngine->GetNetChannelInfo())->SendNetMsg(moveMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void CL_Move_hook(float accumulated_extra_samples, bool bFinalTick)
|
||||
{
|
||||
CL_Move_t original = (CL_Move_t) cl_move_detour.GetOriginalFunc();
|
||||
original(accumulated_extra_samples, bFinalTick);
|
||||
cl_move_detour.RestorePatch();
|
||||
|
||||
// Should we warp?
|
||||
if ((warp_key.isKeyDown() || was_hurt) && warp_amount)
|
||||
{
|
||||
Warp(accumulated_extra_samples, bFinalTick);
|
||||
if (warp_amount < GetMaxWarpTicks())
|
||||
charged = false;
|
||||
}
|
||||
}
|
||||
|
||||
static InitRoutine init([]() {
|
||||
static auto cl_sendmove_addr = gSignatures.GetEngineSignature("55 89 E5 57 56 53 81 EC 2C 10 00 00 C6 85 ? ? ? ? 01");
|
||||
cl_sendmove_detour.Init(cl_sendmove_addr, (void *) CL_SendMove_hook);
|
||||
static auto cl_move_addr = gSignatures.GetEngineSignature("55 89 E5 57 56 53 81 EC 9C 00 00 00 83 3D ? ? ? ? 01");
|
||||
cl_move_detour.Init(cl_move_addr, (void *) CL_Move_hook);
|
||||
|
||||
EC::Register(EC::LevelShutdown, LevelShutdown, "warp_levelshutdown");
|
||||
EC::Register(EC::CreateMove, CreateMove, "warp_createmove", EC::very_late);
|
||||
g_IEventManager2->AddListener(&listener, "player_hurt", false);
|
||||
EC::Register(
|
||||
EC::Shutdown, []() { g_IEventManager2->RemoveListener(&listener); }, "warp_shutdown");
|
||||
EC::Shutdown,
|
||||
[]() {
|
||||
g_IEventManager2->RemoveListener(&listener);
|
||||
cl_sendmove_detour.Shutdown();
|
||||
},
|
||||
"warp_shutdown");
|
||||
warp_forward.installChangeCallback(rvarCallback);
|
||||
warp_backwards.installChangeCallback(rvarCallback);
|
||||
warp_left.installChangeCallback(rvarCallback);
|
||||
|
@ -20,6 +20,8 @@ bf_write::bf_write()
|
||||
m_pDebugName = NULL;
|
||||
}
|
||||
|
||||
static char s_text[1024];
|
||||
|
||||
unsigned long g_LittleBits[32];
|
||||
|
||||
// Precalculated bit masks for WriteUBitLong. Using these tables instead of
|
||||
@ -498,7 +500,8 @@ const char *CLC_ListenEvents::ToString(void) const
|
||||
|
||||
const char *CLC_Move::ToString(void) const
|
||||
{
|
||||
return strfmt("%s: backup %i, new %i, bytes %i", GetName(), m_nNewCommands, m_nBackupCommands, Bits2Bytes(m_nLength)).release();
|
||||
Q_snprintf(s_text, sizeof(s_text), "%s: backup %i, new %i, bytes %i", GetName(), m_nNewCommands, m_nBackupCommands, Bits2Bytes(m_nLength));
|
||||
return s_text;
|
||||
}
|
||||
|
||||
bool CLC_Move::WriteToBuffer(bf_write &buffer)
|
||||
|
Reference in New Issue
Block a user