From 073cd6805eb1dfb4ea0f9c92b761d2f287047c3d Mon Sep 17 00:00:00 2001 From: BenCat07 Date: Thu, 16 Apr 2020 23:03:32 +0200 Subject: [PATCH] Add a Warp hack Seems i also accidentally formatted stuff but i'm leaving it in here --- data/menu/nullifiedcat/movement.xml | 12 + include/hacks/Warp.hpp | 6 + include/hooks/HookedMethods.hpp | 5 +- src/hacks/CMakeLists.txt | 3 +- src/hacks/KillfeedColor.cpp | 2 +- src/hacks/Radar.cpp | 64 ++--- src/hacks/Warp.cpp | 245 ++++++++++++++++++ src/hooks/SendNetMsg.cpp | 4 + src/visual/menu/menu/wm/WindowCloseButton.cpp | 2 +- 9 files changed, 305 insertions(+), 38 deletions(-) create mode 100644 include/hacks/Warp.hpp create mode 100644 src/hacks/Warp.cpp diff --git a/data/menu/nullifiedcat/movement.xml b/data/menu/nullifiedcat/movement.xml index 1652dc4a..66924d8d 100755 --- a/data/menu/nullifiedcat/movement.xml +++ b/data/menu/nullifiedcat/movement.xml @@ -56,4 +56,16 @@ + + + + + + + + + + + + diff --git a/include/hacks/Warp.hpp b/include/hacks/Warp.hpp new file mode 100644 index 00000000..69ec257c --- /dev/null +++ b/include/hacks/Warp.hpp @@ -0,0 +1,6 @@ +#pragma once +class INetMessage; +namespace hacks::tf2::warp +{ +void SendNetMessage(INetMessage &msg); +} diff --git a/include/hooks/HookedMethods.hpp b/include/hooks/HookedMethods.hpp index 274e8f3d..28a970d8 100644 --- a/include/hooks/HookedMethods.hpp +++ b/include/hooks/HookedMethods.hpp @@ -10,7 +10,7 @@ #include "SeedPrediction.hpp" #if ENABLE_VISUALS union SDL_Event; -struct SDL_Window; +class SDL_Window; #endif #define DECLARE_HOOKED_METHOD(name, rtype, ...) \ @@ -43,6 +43,7 @@ DECLARE_HOOKED_METHOD(FireGameEvent, void, void *, IGameEvent *); // IBaseClient DECLARE_HOOKED_METHOD(DispatchUserMessage, bool, void *, int, bf_read &); DECLARE_HOOKED_METHOD(IN_KeyEvent, int, void *, int, ButtonCode_t, const char *); +DECLARE_HOOKED_METHOD(FrameStageNotify, void, void *, ClientFrameStage_t); // IInput DECLARE_HOOKED_METHOD(GetUserCmd, CUserCmd *, IInput *, int); // INetChannel @@ -73,8 +74,6 @@ DECLARE_HOOKED_METHOD(ChatPrintf, void, CHudBaseChat *, int, int, const char *, DECLARE_HOOKED_METHOD(OverrideView, void, void *, CViewSetup *); // IStudioRender DECLARE_HOOKED_METHOD(BeginFrame, void, IStudioRender *); -// IBaseClient -DECLARE_HOOKED_METHOD(FrameStageNotify, void, void *, ClientFrameStage_t); // SDL DECLARE_HOOKED_METHOD(SDL_GL_SwapWindow, void, SDL_Window *); DECLARE_HOOKED_METHOD(SDL_PollEvent, int, SDL_Event *); diff --git a/src/hacks/CMakeLists.txt b/src/hacks/CMakeLists.txt index de3d3922..4d243982 100755 --- a/src/hacks/CMakeLists.txt +++ b/src/hacks/CMakeLists.txt @@ -36,7 +36,8 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp" "${CMAKE_CURRENT_LIST_DIR}/PureBypass.cpp" "${CMAKE_CURRENT_LIST_DIR}/Trigger.cpp" "${CMAKE_CURRENT_LIST_DIR}/UberSpam.cpp" - "${CMAKE_CURRENT_LIST_DIR}/Walkbot.cpp") + "${CMAKE_CURRENT_LIST_DIR}/Walkbot.cpp" + "${CMAKE_CURRENT_LIST_DIR}/Warp.cpp") target_sources(cathook PRIVATE ${files}) list(REMOVE_ITEM ignore_files ${files}) set(ignore_files ${ignore_files} CACHE INTERNAL "") diff --git a/src/hacks/KillfeedColor.cpp b/src/hacks/KillfeedColor.cpp index 464255c8..f6061725 100644 --- a/src/hacks/KillfeedColor.cpp +++ b/src/hacks/KillfeedColor.cpp @@ -172,5 +172,5 @@ mov [esp], ecx } }); }); -} +} // namespace hacks::tf2::killfeed #endif diff --git a/src/hacks/Radar.cpp b/src/hacks/Radar.cpp index faf69de4..949b7dd1 100644 --- a/src/hacks/Radar.cpp +++ b/src/hacks/Radar.cpp @@ -56,34 +56,34 @@ std::pair WorldToRadar(int x, int y) if (*shape == 0) { - if (nx < -halfsize) - nx = -halfsize; - if (nx > halfsize) - nx = halfsize; - if (ny < -halfsize) - ny = -halfsize; - if (ny > halfsize) - ny = halfsize; + if (nx < -halfsize) + nx = -halfsize; + if (nx > halfsize) + nx = halfsize; + if (ny < -halfsize) + ny = -halfsize; + if (ny > halfsize) + ny = halfsize; - return { nx + halfsize - (int) icon_size / 2, ny + halfsize - (int) icon_size / 2 }; + return { nx + halfsize - (int) icon_size / 2, ny + halfsize - (int) icon_size / 2 }; } else if (*shape == 1) { - float PI = 3.14159265; + float PI = 3.14159265; - float theta = atan2(ny,nx); + float theta = atan2(ny, nx); - if (nx > halfsize * std::cos(theta) && nx > 0) - nx = halfsize * std::cos(theta); - if (nx < halfsize * std::cos(theta) && nx < 0) - nx = halfsize * std::cos(theta); - if (ny > halfsize * std::sin(theta) && ny > 0) - ny = halfsize * std::sin(theta); - if (ny < halfsize * std::sin(theta) && ny < 0) - ny = halfsize * std::sin(theta); - - return { nx + halfsize - (int) icon_size / 2, ny + halfsize - (int) icon_size / 2 }; + if (nx > halfsize * std::cos(theta) && nx > 0) + nx = halfsize * std::cos(theta); + if (nx < halfsize * std::cos(theta) && nx < 0) + nx = halfsize * std::cos(theta); + if (ny > halfsize * std::sin(theta) && ny > 0) + ny = halfsize * std::sin(theta); + if (ny < halfsize * std::sin(theta) && ny < 0) + ny = halfsize * std::sin(theta); + + return { nx + halfsize - (int) icon_size / 2, ny + halfsize - (int) icon_size / 2 }; } } bool loaded = false; @@ -214,24 +214,24 @@ void Draw() std::vector enemies{}; CachedEntity *ent; - x = (int) radar_x; - y = (int) radar_y; + x = (int) radar_x; + y = (int) radar_y; int radar_size = *size; - int half_size = radar_size / 2; + int half_size = radar_size / 2; outlineclr = GUIColor(); if (*shape == 0) { - draw::Rectangle(x, y, radar_size, radar_size, colors::Transparent(colors::black, *opacity)); - draw::RectangleOutlined(x, y, radar_size, radar_size, outlineclr, 0.5f); + draw::Rectangle(x, y, radar_size, radar_size, colors::Transparent(colors::black, *opacity)); + draw::RectangleOutlined(x, y, radar_size, radar_size, outlineclr, 0.5f); } else if (*shape == 1) { - int center_x = x + half_size; - int center_y = y + half_size; - draw::Circle(center_x, center_y, half_size, outlineclr, 1, 100); - draw::Circle(center_x, center_y, half_size / 2, colors::Transparent(colors::black, *opacity), half_size, 100); + int center_x = x + half_size; + int center_y = y + half_size; + draw::Circle(center_x, center_y, half_size, outlineclr, 1, 100); + draw::Circle(center_x, center_y, half_size / 2, colors::Transparent(colors::black, *opacity), half_size, 100); } if (enemies_over_teammates) @@ -272,8 +272,8 @@ void Draw() if (show_cross) { - draw::Line(x + half_size, y + half_size / 2, 0, half_size, colors::Transparent(GUIColor(), 0.4f), 0.5f); - draw::Line(x + half_size / 2, y + half_size, half_size, 0, colors::Transparent(GUIColor(), 0.4f), 0.5f); + draw::Line(x + half_size, y + half_size / 2, 0, half_size, colors::Transparent(GUIColor(), 0.4f), 0.5f); + draw::Line(x + half_size / 2, y + half_size, half_size, 0, colors::Transparent(GUIColor(), 0.4f), 0.5f); } } diff --git a/src/hacks/Warp.cpp b/src/hacks/Warp.cpp new file mode 100644 index 00000000..bce430d3 --- /dev/null +++ b/src/hacks/Warp.cpp @@ -0,0 +1,245 @@ +/* + * Created on 16.4.2020 + * Author: BenCat07 + * + * Copyright Nullworks 2020 + */ + +#include "init.hpp" +#include "sdk.hpp" +#include "interfaces.hpp" +#include "settings/Bool.hpp" +#include "offsets.hpp" +#include "globals.h" +#include "Warp.hpp" +#include "HookTools.hpp" +#include "usercmd.hpp" +#include "localplayer.hpp" +#include "netvars.hpp" +#include "entitycache.hpp" +#include "conditions.hpp" +#include "velocity.hpp" +#if ENABLE_VISUALS +#include "drawing.hpp" +#endif + +namespace hacks::tf2::warp +{ +static settings::Boolean enabled{ "warp.enabled", "false" }; +static settings::Boolean draw{ "warp.draw", "false" }; +static settings::Button warp_key{ "warp.key", "" }; +static settings::Int warp_movement_ratio{ "warp.movement-ratio", "6" }; +static settings::Boolean warp_peek{ "warp.peek", "false" }; + +// Draw control +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_override = 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; +}; + +int GetWarpAmount() +{ + static auto sv_max_dropped_packets_to_process = g_ICvar->FindVar("sv_max_dropped_packets_to_process"); + if (!warp_override) + return sv_max_dropped_packets_to_process->GetInt(); + else + return warp_override; +} +bool should_warp = true; + +// Warping part +void Warp() +{ + auto ch = g_IEngine->GetNetChannelInfo(); + if (!ch) + return; + if (!should_warp) + { + should_warp = true; + return; + } + int &m_nOutSequenceNr = *(int *) ((uintptr_t) ch + offsets::m_nOutSequenceNr()); + + // Has to be from the cvar + m_nOutSequenceNr += GetWarpAmount(); + warp_amount -= GetWarpAmount(); + if (warp_amount < 0) + warp_amount = 0; +} + +int GetMaxWarpTicks() +{ + static auto usercmd_cvar = g_ICvar->FindVar("sv_maxusrcmdprocessticks"); + int ticks = usercmd_cvar->GetInt(); + // No limit set + if (!ticks) + ticks = INT_MAX; + return ticks; +} + +void SendNetMessage(INetMessage &msg) +{ + if (!enabled) + return; + + // Credits to MrSteyk for this btw + if (msg.GetGroup() == 0xA) + { + // Charge + if (should_charge && !charged) + { + int ticks = GetMaxWarpTicks(); + auto movemsg = (clc_move_proto *) &msg; + // Just null it :shrug: + movemsg->m_nBackupCommands = 0; + movemsg->m_nNewCommands = 0; + movemsg->m_DataOut.Reset(); + movemsg->m_DataOut.m_nDataBits = 0; + movemsg->m_DataOut.m_nDataBytes = 0; + movemsg->m_DataOut.m_iCurBit = 0; + + warp_amount++; + if (warp_amount >= ticks) + { + warp_amount = ticks; + charged = true; + } + } + // Warp + if (warp_key.isKeyDown() && warp_amount) + { + Warp(); + if (warp_amount < GetWarpAmount()) + charged = false; + } + } + should_charge = false; +} + +static bool move_last_tick = true; +static bool warp_last_tick = false; +static bool should_warp_last_tick = false; +void CreateMove() +{ + if (!enabled) + return; + warp_override = 0; + if (!warp_key.isKeyDown()) + { + warp_last_tick = false; + // Bunch of checks, if they all pass we are standing still + if (!HasCondition(LOCAL_E) && !current_user_cmd->forwardmove && !current_user_cmd->sidemove && !current_user_cmd->upmove && (CE_INT(LOCAL_E, netvar.iFlags) & FL_ONGROUND) && !(current_user_cmd->buttons & (IN_ATTACK | IN_ATTACK2))) + { + Vector velocity{}; + velocity::EstimateAbsVelocity(RAW_ENT(LOCAL_E), velocity); + if (velocity.IsZero()) + { + if (!move_last_tick) + should_charge = true; + move_last_tick = false; + } + return; + } + else + { + should_charge = false; + // Use everxy xth tick for charging + if (!(tickcount % *warp_movement_ratio)) + should_charge = true; + move_last_tick = true; + } + } + // Warp peaking + else if (warp_peek) + { + // We Have warp + if (warp_amount) + { + // Warped last tick, time to reverse + if (warp_last_tick) + { + // Wait 1 tick before tping back + if (should_warp && !should_warp_last_tick) + { + should_warp_last_tick = true; + should_warp = false; + } + else + should_warp_last_tick = false; + + // Inverse direction + current_user_cmd->forwardmove = -current_user_cmd->forwardmove; + current_user_cmd->sidemove = -current_user_cmd->sidemove; + } + else + warp_override = warp_amount / 2; + warp_last_tick = true; + } + // Prevent movement so you don't overshoot when you don't want to + else + { + current_user_cmd->forwardmove = 0.0f; + current_user_cmd->sidemove = 0.0f; + } + } +} + +#if ENABLE_VISUALS +void Draw() +{ + if (!enabled || !draw) + return; + if (!g_IEngine->IsInGame()) + return; + if (CE_BAD(LOCAL_E)) + return; + + float charge_percent = (float) warp_amount / (float) GetMaxWarpTicks(); + // Draw background + static rgba_t background_color = colors::FromRGBA8(96, 96, 96, 150); + float bar_bg_x_size = *size * 2.0f; + float bar_bg_y_size = *size / 5.0f; + draw::Rectangle(*bar_x - 5.0f, *bar_y - 5.0f, bar_bg_x_size + 10.0f, bar_bg_y_size + 10.0f, background_color); + // Draw bar + rgba_t color_bar = colors::orange; + if (GetMaxWarpTicks() == warp_amount) + color_bar = colors::green; + color_bar.a = 100 / 255.0f; + draw::Rectangle(*bar_x, *bar_y, *size * 2.0f * charge_percent, *size / 5.0f, color_bar); +} +#endif + +void LevelShutdown() +{ + charged = false; + warp_amount = 0; +} + +static InitRoutine init([]() { + EC::Register(EC::LevelShutdown, LevelShutdown, "warp_levelshutdown"); + EC::Register(EC::CreateMove, CreateMove, "warp_createmove", EC::late); +#if ENABLE_VISUALS + EC::Register(EC::Draw, Draw, "warp_draw"); +#endif +}); +} // namespace hacks::tf2::warp diff --git a/src/hooks/SendNetMsg.cpp b/src/hooks/SendNetMsg.cpp index afb40634..5a17fbcf 100644 --- a/src/hooks/SendNetMsg.cpp +++ b/src/hooks/SendNetMsg.cpp @@ -9,6 +9,7 @@ #include #include "nullnexus.hpp" #include "e8call.hpp" +#include "Warp.hpp" static settings::Int newlines_msg{ "chat.prefix-newlines", "0" }; static settings::Boolean log_sent{ "debug.log-sent-chat", "false" }; @@ -195,6 +196,9 @@ DEFINE_HOOKED_METHOD(SendNetMsg, bool, INetChannel *this_, INetMessage &msg, boo int offset; std::string newlines{}; NET_StringCmd stringcmd; + + hacks::tf2::warp::SendNetMessage(msg); + // net_StringCmd if (msg.GetType() == 4 && (newlines_msg || crypt_chat)) { diff --git a/src/visual/menu/menu/wm/WindowCloseButton.cpp b/src/visual/menu/menu/wm/WindowCloseButton.cpp index 0a875896..41f977ab 100644 --- a/src/visual/menu/menu/wm/WindowCloseButton.cpp +++ b/src/visual/menu/menu/wm/WindowCloseButton.cpp @@ -11,7 +11,7 @@ namespace zerokernel_windowclosebutton { -static draw::Texture cross{ paths::getDataPath( "/menu/cross.png") }; +static draw::Texture cross{ paths::getDataPath("/menu/cross.png") }; static settings::RVariable background_hover{ "zk.style.window-close-button.color.background-hover", "ff0000" }; static settings::RVariable color_border{ "zk.style.window-close-button.color.border", "446498ff" }; } // namespace zerokernel_windowclosebutton