diff --git a/README.md b/README.md index 7f0c43c7..9634f3e3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ubuntu (and probably Debian) users can run this script: ``` -sudo apt update && sudo apt install build-essential software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-snapshot -y && sudo apt update && sudo apt install libc6-dev gcc-6 g++-6 g++-6-multilib gdb -y && git clone --recursive https://github.com/nullifiedcat/cathook && cd cathook && make -j4 +sudo apt update && sudo apt install build-essential software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-snapshot -y && sudo apt update && sudo apt install git libc6-dev gcc-6 g++-6 libc6-dev:i386 g++-6-multilib gdb -y && git clone --recursive https://github.com/nullifiedcat/cathook && cd cathook && make -j4 ``` **Errors while installing?** diff --git a/src/gui/ncc/Menu.cpp b/src/gui/ncc/Menu.cpp index 59a470c8..7e45c31d 100644 --- a/src/gui/ncc/Menu.cpp +++ b/src/gui/ncc/Menu.cpp @@ -531,6 +531,11 @@ static const std::string list_tf2 = R"( "killsay" "spam" "spam_random" + "uberspam" + "uberspam_build" + "uberspam_ready" + "uberspam_used" + "uberspam_ended" ] "Follow Bot" [ diff --git a/src/hack.cpp b/src/hack.cpp index 64336ae5..1432a221 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -67,17 +67,11 @@ void hack::ExecuteCommand(const std::string command) { ConCommand* hack::c_Cat = 0; void hack::CC_Cat(const CCommand& args) { - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::blu), "cathook"); - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::white), " by "); - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::blu), "d4rkc4t\n"); - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::white), "build: " CATHOOK_BUILD_NUMBER " \"" CATHOOK_BUILD_NAME "\"\n"); -#if _DEVELOPER - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::red), "[DEVELOPER BUILD]\n"); -#else - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::red), "Build for user " __DRM_NAME " (Early Access)\n"); -#endif -#ifdef __DRM_NOTES - g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::red), "Build notes: " __DRM_NOTES "\n"); + g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::white), "cathook"); + g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::blu), " by "); + g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::red), "nullifiedcat\n"); +#if defined(GIT_COMMIT_HASH) && defined(GIT_COMMIT_DATE) + g_ICvar->ConsoleColorPrintf(*reinterpret_cast(&colors::white), "commit: #" GIT_COMMIT_HASH " " GIT_COMMIT_DATE "\n"); #endif } @@ -167,10 +161,26 @@ void hack::Initialize() { hooks::hkInput->Init((void*)g_IInput, 0); hooks::hkInput->HookMethod((void*)GetUserCmd_hook, hooks::offGetUserCmd); hooks::hkInput->Apply(); + //logging::Info("Before hacking: %s", g_ISteamFriends->GetPersonaName()); hooks::hkIVModelRender = new hooks::VMTHook(); hooks::hkIVModelRender->Init(g_IVModelRender, 0); hooks::hkIVModelRender->HookMethod((void*)DrawModelExecute_hook, hooks::offDrawModelExecute); hooks::hkIVModelRender->Apply(); + hooks::hkSteamFriends = new hooks::VMTHook(); + hooks::hkSteamFriends->Init(g_ISteamFriends, 0); + hooks::hkSteamFriends->HookMethod((void*)GetFriendPersonaName_hook, hooks::offGetFriendPersonaName); + hooks::hkSteamFriends->Apply(); + //logging::Info("After hacking: %s", g_ISteamFriends->GetPersonaName()); + // Sadly, it doesn't work as expected :( + /*hooks::hkBaseClientState = new hooks::VMTHook(); + hooks::hkBaseClientState->Init((void*)g_IBaseClientState, 0); + hooks::hkBaseClientState->HookMethod((void*)GetClientName_hook, hooks::offGetClientName); + hooks::hkBaseClientState->Apply();*/ + //hooks::hkBaseClientState8 = new hooks::VMTHook(); + //hooks::hkBaseClientState8->Init((void*)g_IBaseClientState, 8); + //hooks::hkBaseClientState8->HookMethod((void*)ProcessSetConVar_hook, hooks::offProcessSetConVar); + //hooks::hkBaseClientState8->HookMethod((void*)ProcessGetCvarValue_hook, hooks::offProcessGetCvarValue); + //hooks::hkBaseClientState8->Apply(); if (TF2) g_GlowObjectManager = *reinterpret_cast(gSignatures.GetClientSignature("C1 E0 05 03 05") + 5); InitStrings(); hacks::shared::killsay::Init(); @@ -210,6 +220,8 @@ void hack::Shutdown() { if (hooks::hkStudioRender) hooks::hkStudioRender->Kill(); if (hooks::hkInput) hooks::hkInput->Kill(); if (hooks::hkIVModelRender) hooks::hkIVModelRender->Kill(); + if (hooks::hkBaseClientState) hooks::hkBaseClientState->Kill(); + if (hooks::hkBaseClientState8) hooks::hkBaseClientState8->Kill(); //if (hooks::hkCTFPlayer) hooks::hkCTFPlayer->Kill(); logging::Info("Unregistering convars.."); ConVar_Unregister(); diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 700a5f1b..aac0f9f0 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -496,7 +496,7 @@ bool ShouldAim(CUserCmd* cmd) { if (g_pLocalPlayer->weapon()->m_iClassID == g_pClassID->CTFSniperRifle || g_pLocalPlayer->weapon()->m_iClassID == g_pClassID->CTFSniperRifleDecap) { // confused_nigga.jpg - return g_pLocalPlayer->bZoomed; + if (!g_pLocalPlayer->bZoomed) return false; } } if (only_can_shoot) { diff --git a/src/hacks/Spam.cpp b/src/hacks/Spam.cpp index 8ec644e6..defc8fad 100644 --- a/src/hacks/Spam.cpp +++ b/src/hacks/Spam.cpp @@ -23,6 +23,18 @@ TextFile file {}; void CreateMove() { if (!spam_source) return; + static int safety_ticks = 0; + static int last_spam = 0; + if ((int)spam_source != last_spam) { + safety_ticks = 300; + last_spam = (int)spam_source; + } + if (safety_ticks > 0) { + safety_ticks--; + return; + } else { + safety_ticks = 0; + } if (last_spam > g_GlobalVars->curtime) last_spam = 0.0f; const std::vector* source = nullptr; switch ((int)spam_source) { @@ -68,7 +80,8 @@ const std::vector builtin_default = { "cathook - more fun than a ball of yarn!", "GNU/Linux is the best OS!", "get cathook: discord.gg/7bu3AFw", - "cathook - free tf2 cheat!" + "cathook - free tf2 cheat!", + "cathook - ca(n)t stop me meow!" }; const std::vector builtin_lennyfaces = { "( ͡° ͜ʖ ͡°)", "( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°)", "ʕ•ᴥ•ʔ", diff --git a/src/hacks/UberSpam.cpp b/src/hacks/UberSpam.cpp new file mode 100644 index 00000000..962c9bfe --- /dev/null +++ b/src/hacks/UberSpam.cpp @@ -0,0 +1,98 @@ +/* + * UberSpam.cpp + * + * Created on: May 3, 2017 + * Author: nullifiedcat + */ + +#include "UberSpam.hpp" + +namespace hacks { namespace tf { namespace uberspam { + +TextFile custom_lines; + +static CatEnum source_enum({"DISABLED", "CATHOOK", "NCC", "CUSTOM"}); +static CatVar source(source_enum, "uberspam", "0", "Ubercharge Spam", "Defines spam ubercharge source"); +static CatVar on_ready(CV_SWITCH, "uberspam_ready", "1", "Uber Ready"); +static CatVar on_used(CV_SWITCH, "uberspam_used", "1", "Uber Used"); +static CatVar on_ended(CV_SWITCH, "uberspam_ended", "1", "Uber Ended"); +static CatVar on_build(CV_INT, "uberspam_build", "25", "Uber Build", "Send a message every #% ubercharge. 0 = never send", 0, 100); +static CatVar custom_file(CV_STRING, "uberspam_file", "uberspam.txt", "Ubercharge Spam File", "Use cat_uberspam_file_reload! Same as spam/killsay files."); +static CatCommand custom_file_reload("uberspam_file_reload", "Reload Ubercharge Spam File", []() { + custom_lines.Load(std::string(custom_file.GetString())); +}); + +const std::vector* GetSource() { + switch ((int)source) { + case 1: + return &builtin_cathook; + case 2: + return &builtin_nonecore; + case 3: + return &custom_lines.lines; + } + return nullptr; +} + +int ChargePercentLineIndex(float chargef) { + if ((int)on_build <= 0) return 0; + int charge = chargef * 100.0f; + if (charge == 100) return 0; + auto src = GetSource(); + if (!src) return 0; + int lines = src->size() - 3; + if (lines <= 0) return 0; + int cpl = 100 / lines; + return 3 + (charge / cpl); +} + +void CreateMove() { + if (!GetSource()) return; + if (LOCAL_W->m_iClassID != g_pClassID->CWeaponMedigun) return; + if (GetSource()->size() < 4) return; + float charge = CE_FLOAT(LOCAL_W, netvar.m_flChargeLevel); + static bool release_last_frame = false; + static int last_charge = 0; + bool release = CE_BYTE(LOCAL_W, netvar.bChargeRelease); + if (release_last_frame != release) { + if (release) { + if (on_used) chat_stack::stack.push(GetSource()->at(1)); + } else { + if (on_ended) chat_stack::stack.push(GetSource()->at(2)); + } + } + if (!release && ((int)(100.0f * charge) != last_charge)) { + if (charge == 1.0f) { + if (on_ready) chat_stack::stack.push(GetSource()->at(0)); + } else { + if ((int)(charge * 100.0f) != 0 && on_build) { + if (((int)(charge * 100.0f) % (int)on_build) == 0) { + std::string res = GetSource()->at(ChargePercentLineIndex(charge)); + ReplaceString(res, "%i%", std::to_string((int)(charge * 100.0f))); + chat_stack::stack.push(res); + } + } + } + } + release_last_frame = release; + last_charge = (int)(100.0f * charge); +} + +// Ready, Used, Ended, %... + +const std::vector builtin_cathook = { + "-> I am charged!", + "-> Not a step back! UBERCHARGE USED!", + "-> My Ubercharge comes to an end!", + "-> I have a bit of ubercharge!", + "-> I have half of the ubercharge!", + "-> Ubercharge almost ready!" +}; +const std::vector builtin_nonecore = { + ">>> GET READY TO RUMBLE! <<<", + ">>> CHEATS ACTIVATED! <<<", + ">>> RUMBLE COMPLETE! <<<", + ">>> RUMBLE IS %i%% CHARGED! <<<" +}; + +}}} diff --git a/src/hacks/UberSpam.hpp b/src/hacks/UberSpam.hpp new file mode 100644 index 00000000..bb3a93e9 --- /dev/null +++ b/src/hacks/UberSpam.hpp @@ -0,0 +1,24 @@ +/* + * UberSpam.hpp + * + * Created on: May 3, 2017 + * Author: nullifiedcat + */ + +#ifndef HACKS_UBERSPAM_HPP_ +#define HACKS_UBERSPAM_HPP_ + +#include "../common.h" + +namespace hacks { namespace tf { namespace uberspam { + +void CreateMove(); + +// Ready, Used, Ended, %... + +extern const std::vector builtin_cathook; +extern const std::vector builtin_nonecore; + +}}} + +#endif /* HACKS_UBERSPAM_HPP_ */ diff --git a/src/hacks/hacklist.h b/src/hacks/hacklist.h index eac379f3..fe453563 100644 --- a/src/hacks/hacklist.h +++ b/src/hacks/hacklist.h @@ -23,6 +23,7 @@ #include "SpyAlert.h" #include "Trigger.h" #include "KillSay.h" +#include "UberSpam.hpp" #include "Achievement.h" #include "Spam.h" #include "Noisemaker.h" diff --git a/src/hooks.cpp b/src/hooks.cpp index 142cae49..1c3c0fce 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -74,6 +74,9 @@ void hooks::VMTHook::Apply() { //hooks::VMTHook* hooks::hkCTFPlayer = nullptr; hooks::VMTHook* hooks::hkInput = nullptr; +hooks::VMTHook* hooks::hkSteamFriends = nullptr; +hooks::VMTHook* hooks::hkBaseClientState = nullptr; +hooks::VMTHook* hooks::hkBaseClientState8 = nullptr; hooks::VMTHook* hooks::hkClientMode = 0; hooks::VMTHook* hooks::hkPanel = 0; hooks::VMTHook* hooks::hkClient = 0; diff --git a/src/hooks.h b/src/hooks.h index 3f4a8a89..1a75bfdb 100644 --- a/src/hooks.h +++ b/src/hooks.h @@ -41,10 +41,17 @@ extern VMTHook* hkMatSurface; extern VMTHook* hkStudioRender; extern VMTHook* hkInput; extern VMTHook* hkIVModelRender; +extern VMTHook* hkBaseClientState; +extern VMTHook* hkBaseClientState8; +extern VMTHook* hkSteamFriends; constexpr unsigned int offGetUserCmd = 8; constexpr unsigned int offShouldDraw = 136; constexpr unsigned int offDrawModelExecute = 19; +constexpr unsigned int offGetClientName = 44; +constexpr unsigned int offProcessSetConVar = 4; +constexpr unsigned int offProcessGetCvarValue = 29; +constexpr unsigned int offGetFriendPersonaName = 7; extern unsigned int offHandleInputEvent; extern unsigned int offPaintTraverse; extern unsigned int offCreateMove; diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 4cc74cc9..7295211d 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -178,6 +178,7 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) { //RunEnginePrediction(g_pLocalPlayer->entity, cmd); SAFE_CALL(hacks::shared::esp::CreateMove()); if (!g_pLocalPlayer->life_state && CE_GOOD(g_pLocalPlayer->weapon())) { + if (TF) SAFE_CALL(hacks::tf::uberspam::CreateMove()); if (TF2) SAFE_CALL(hacks::tf2::antibackstab::CreateMove()); if (TF2) SAFE_CALL(hacks::tf2::noisemaker::CreateMove()); SAFE_CALL(hacks::shared::bunnyhop::CreateMove()); diff --git a/src/hooks/hookedmethods.h b/src/hooks/hookedmethods.h index 9a43891a..c93787d4 100644 --- a/src/hooks/hookedmethods.h +++ b/src/hooks/hookedmethods.h @@ -25,10 +25,20 @@ typedef void(BeginFrame_t)(IStudioRender*); typedef bool(*CanInspect_t)(IClientEntity*); typedef void(*DrawModelExecute_t)(IVModelRender*, const DrawModelState_t&, const ModelRenderInfo_t&, matrix3x4_t*); typedef CUserCmd*(GetUserCmd_t)(IInput*, int); +typedef const char*(GetClientName_t)(CBaseClientState*); +typedef bool(ProcessSetConVar_t)(CBaseClientState*, NET_SetConVar*); +typedef bool(ProcessGetCvarValue_t)(CBaseClientState*, SVC_GetCvarValue*); +const char* GetClientName_hook(CBaseClientState* _this); +bool ProcessSetConVar_hook(CBaseClientState* _this, NET_SetConVar* msg); +bool ProcessGetCvarValue_hook(CBaseClientState* _this, SVC_GetCvarValue* msg); //typedef void(*CInput__CreateMove_t)(void*, int, float, bool); //void CInput__CreateMove_hook(void*, int sequence_number, float input_sample_frametime, bool active); bool CanInspect_hook(IClientEntity*); const unsigned int offCanInspect = 512; + +typedef const char*(GetFriendPersonaName_t)(ISteamFriends*, CSteamID); +const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID); + void BeginFrame_hook(IStudioRender*); CUserCmd* GetUserCmd_hook(IInput*, int); void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, const ModelRenderInfo_t& info, matrix3x4_t* matrix); diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index e15df73b..603d6a9a 100644 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -166,6 +166,13 @@ static CatVar glow_enabled(CV_SWITCH, "glow_old_enabled", "0", "Enable", "Make s static CatVar glow_alpha(CV_FLOAT, "glow_old_alpha", "1", "Alpha", "Glow Transparency", 0.0f, 1.0f); static CatVar resolver(CV_SWITCH, "resolver", "0", "Resolve angles"); +const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID) { + if ((force_name.convar->m_StringLength > 2) && steamID == g_ISteamUser->GetSteamID()) { + return force_name.GetString(); + } + return ((GetFriendPersonaName_t*)(hooks::hkSteamFriends->GetMethod(hooks::offGetFriendPersonaName)))(_this, steamID); +} + void FrameStageNotify_hook(void* thisptr, int stage) { SEGV_BEGIN; if (!g_IEngine->IsInGame()) g_Settings.bInvalid = true; @@ -183,76 +190,57 @@ void FrameStageNotify_hook(void* thisptr, int stage) { } } } - if (stage == FRAME_NET_UPDATE_START) { - static int next_name_change = 0; - if (next_name_change == 0) { - need_name_change = true; - } else next_name_change--; - if (force_name.convar->m_StringLength > 2 && need_name_change) { - INetChannel* ch = (INetChannel*)g_IEngine->GetNetChannelInfo(); - if (ch) { - logging::Info("Sending new name"); - NET_SetConVar setname("name", force_name.GetString()); - setname.SetNetChannel(ch); - setname.SetReliable(false); - ch->SendNetMsg(setname, false); - need_name_change = false; - } - next_name_change = 60 * 100; - } - static ConVar* name_cv = g_ICvar->FindVar("name"); - //name_cv->SetValue(force_name.GetString()); - name_cv->m_pszString = (char*)strfmt("%s", force_name.GetString()); - name_cv->m_StringLength = strlen(force_name.GetString()) + 1; - } + static ConVar* glow_outline_effect = g_ICvar->FindVar("glow_outline_effect_enable"); if (TF && cathook && !g_Settings.bInvalid && stage == FRAME_RENDER_START) { - if (glow_enabled) { - for (int i = 0; i < g_GlowObjectManager->m_GlowObjectDefinitions.m_Size; i++) { - GlowObjectDefinition_t& glowobject = g_GlowObjectManager->m_GlowObjectDefinitions[i]; - if (glowobject.m_nNextFreeSlot != ENTRY_IN_USE) - continue; - int color = GetEntityGlowColor(glowobject.m_hEntity.m_Index & 0xFFF); - if (color == 0) { - glowobject.m_flGlowAlpha = 0.0f; - } else { - glowobject.m_flGlowAlpha = (float)glow_alpha; - } - unsigned char _b = (color >> 16) & 0xFF; - unsigned char _g = (color >> 8) & 0xFF; - unsigned char _r = (color) & 0xFF; - glowobject.m_vGlowColor.x = (float)_r / 255.0f; - glowobject.m_vGlowColor.y = (float)_g / 255.0f; - glowobject.m_vGlowColor.z = (float)_b / 255.0f; - } - } - // Remove glow from dead entities - for (int i = 0; i < g_GlowObjectManager->m_GlowObjectDefinitions.Count(); i++) { - if (g_GlowObjectManager->m_GlowObjectDefinitions[i].m_nNextFreeSlot != ENTRY_IN_USE) continue; - IClientEntity* ent = (IClientEntity*)g_IEntityList->GetClientEntityFromHandle(g_GlowObjectManager->m_GlowObjectDefinitions[i].m_hEntity); - if (ent && ent->IsDormant()) { - g_GlowObjectManager->DisableGlow(i); - } else if (ent && ent->GetClientClass()->m_ClassID == g_pClassID->C_Player) { - if (NET_BYTE(ent, netvar.iLifeState) != LIFE_ALIVE) { - g_GlowObjectManager->DisableGlow(i); - } - } - } - if (glow_enabled) { - for (int i = 1; i < g_IEntityList->GetHighestEntityIndex(); i++) { - IClientEntity* entity = g_IEntityList->GetClientEntity(i); - if (!entity || i == g_IEngine->GetLocalPlayer() || entity->IsDormant()) - continue; - if (!CanEntityEvenGlow(i)) continue; - int clazz = entity->GetClientClass()->m_ClassID; - int current_handle = g_GlowObjectManager->GlowHandle(entity); - bool shouldglow = ShouldEntityGlow(i); - if (current_handle != -1) { - if (!shouldglow) { - g_GlowObjectManager->DisableGlow(current_handle); + if (glow_outline_effect->GetBool()) { + if (glow_enabled) { + for (int i = 0; i < g_GlowObjectManager->m_GlowObjectDefinitions.m_Size; i++) { + GlowObjectDefinition_t& glowobject = g_GlowObjectManager->m_GlowObjectDefinitions[i]; + if (glowobject.m_nNextFreeSlot != ENTRY_IN_USE) + continue; + int color = GetEntityGlowColor(glowobject.m_hEntity.m_Index & 0xFFF); + if (color == 0) { + glowobject.m_flGlowAlpha = 0.0f; + } else { + glowobject.m_flGlowAlpha = (float)glow_alpha; } - } else { - if (shouldglow) { - g_GlowObjectManager->EnableGlow(entity, colors::white); + unsigned char _b = (color >> 16) & 0xFF; + unsigned char _g = (color >> 8) & 0xFF; + unsigned char _r = (color) & 0xFF; + glowobject.m_vGlowColor.x = (float)_r / 255.0f; + glowobject.m_vGlowColor.y = (float)_g / 255.0f; + glowobject.m_vGlowColor.z = (float)_b / 255.0f; + } + } + // Remove glow from dead entities + for (int i = 0; i < g_GlowObjectManager->m_GlowObjectDefinitions.Count(); i++) { + if (g_GlowObjectManager->m_GlowObjectDefinitions[i].m_nNextFreeSlot != ENTRY_IN_USE) continue; + IClientEntity* ent = (IClientEntity*)g_IEntityList->GetClientEntityFromHandle(g_GlowObjectManager->m_GlowObjectDefinitions[i].m_hEntity); + if (ent && ent->IsDormant()) { + g_GlowObjectManager->DisableGlow(i); + } else if (ent && ent->GetClientClass()->m_ClassID == g_pClassID->C_Player) { + if (NET_BYTE(ent, netvar.iLifeState) != LIFE_ALIVE) { + g_GlowObjectManager->DisableGlow(i); + } + } + } + if (glow_enabled) { + for (int i = 1; i < g_IEntityList->GetHighestEntityIndex(); i++) { + IClientEntity* entity = g_IEntityList->GetClientEntity(i); + if (!entity || i == g_IEngine->GetLocalPlayer() || entity->IsDormant()) + continue; + if (!CanEntityEvenGlow(i)) continue; + int clazz = entity->GetClientClass()->m_ClassID; + int current_handle = g_GlowObjectManager->GlowHandle(entity); + bool shouldglow = ShouldEntityGlow(i); + if (current_handle != -1) { + if (!shouldglow) { + g_GlowObjectManager->DisableGlow(current_handle); + } + } else { + if (shouldglow) { + g_GlowObjectManager->EnableGlow(entity, colors::white); + } } } } @@ -303,7 +291,7 @@ bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) { int j = 0; for (int i = 0; i < 3; i++) { while (char c = data[j++]) { - if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '?'; + if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) data[j - 1] = '*'; } } buf = bf_read(data, s); @@ -327,22 +315,6 @@ void LevelInit_hook(void* thisptr, const char* newmap) { //if (TF) LEVEL_INIT(SpyAlert); chat_stack::Reset(); hacks::shared::spam::Reset(); - need_name_change = true; - if (force_name.convar->m_StringLength > 2) { - //static ConVar* name_cv = g_ICvar->FindVar("name"); - INetChannel* ch = (INetChannel*)g_IEngine->GetNetChannelInfo(); - if (ch) { - logging::Info("Sending new name"); - NET_SetConVar setname("name", force_name.GetString()); - setname.SetNetChannel(ch); - setname.SetReliable(false); - ch->SendNetMsg(setname, false); - //name_cv->m_pszString = strfmt("%s", force_name.GetString()); - } - static ConVar* name_cv = g_ICvar->FindVar("name"); - name_cv->m_pszString = (char*)strfmt("%s", force_name.GetString()); - name_cv->m_StringLength = strlen(force_name.GetString()) + 1; - } } bool CanInspect_hook(IClientEntity*) { return true; } @@ -355,20 +327,5 @@ void LevelShutdown_hook(void* thisptr) { hacks::shared::aimbot::Reset(); chat_stack::Reset(); hacks::shared::spam::Reset(); - if (force_name.convar->m_StringLength > 2) { - //static ConVar* name_cv = g_ICvar->FindVar("name"); - INetChannel* ch = (INetChannel*)g_IEngine->GetNetChannelInfo(); - if (ch) { - logging::Info("Sending new name"); - NET_SetConVar setname("name", force_name.GetString()); - setname.SetNetChannel(ch); - setname.SetReliable(false); - ch->SendNetMsg(setname, false); - //name_cv->m_pszString = strfmt("%s", force_name.GetString()); - } - static ConVar* name_cv = g_ICvar->FindVar("name"); - name_cv->m_pszString = (char*)strfmt("%s", force_name.GetString()); - name_cv->m_StringLength = strlen(force_name.GetString()) + 1; - } } diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 88133c18..c8b0dbe2 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -47,6 +47,7 @@ IMaterialSystemFixed* g_IMaterialSystem = nullptr; IVRenderView* g_IVRenderView = nullptr; IMaterialSystem* g_IMaterialSystemHL = nullptr; IMoveHelperServer* g_IMoveHelperServer = nullptr; +CBaseClientState* g_IBaseClientState = nullptr; template T* BruteforceInterface(std::string name, sharedobj::SharedObject* object, int start) { @@ -86,7 +87,10 @@ void CreateInterfaces() { HSteamPipe sp = g_ISteamClient->CreateSteamPipe(); HSteamUser su = g_ISteamClient->ConnectToGlobalUser(sp); g_IVModelRender = BruteforceInterface("VEngineModel", sharedobj::engine, 16); - g_ISteamFriends = g_ISteamClient->GetISteamFriends(su, sp, "SteamFriends002"); + uintptr_t sig_steamapi = gSignatures.GetEngineSignature("55 0F 57 C0 89 E5 83 EC 18 F3 0F 11 05 ? ? ? ? F3 0F 11 05 ? ? ? ? F3 0F 10 05 ? ? ? ? C7 04 24 ? ? ? ? F3 0F 11 05 ? ? ? ? F3 0F 11 05 ? ? ? ? E8 ? ? ? ? C7 44 24 08 ? ? ? ? C7 44 24 04 ? ? ? ? C7 04 24 ? ? ? ? E8 ? ? ? ? C9 C3"); + logging::Info("SteamAPI: 0x%08x", sig_steamapi); + void** SteamAPI_engine = *reinterpret_cast(sig_steamapi + 36); + g_ISteamFriends = (ISteamFriends*)(SteamAPI_engine[1]);//g_ISteamClient->GetISteamFriends(su, sp, "SteamFriends002"); g_GlobalVars = **(reinterpret_cast((uintptr_t)11 + gSignatures.GetClientSignature("55 89 E5 83 EC ? 8B 45 08 8B 15 ? ? ? ? F3 0F 10"))); g_IPrediction = BruteforceInterface("VClientPrediction", sharedobj::client); g_IGameMovement = BruteforceInterface("GameMovement", sharedobj::client); @@ -111,6 +115,7 @@ void CreateInterfaces() { else if (TF2C) g_IInput = **(reinterpret_cast((uintptr_t)1 + gSignatures.GetClientSignature("A1 ? ? ? ? C6 05 ? ? ? ? 01 8B 10 89 04 24 FF 92 A8 00 00 00 A1 ? ? ? ? 8B 10"))); else if (HL2DM) g_IInput = **(reinterpret_cast((uintptr_t)1 + gSignatures.GetClientSignature("A1 ? ? ? ? 8B 10 89 04 24 FF 52 78 A1 ? ? ? ? 8B 10"))); g_ISteamUser = g_ISteamClient->GetISteamUser(su, sp, "SteamUser018"); + g_IBaseClientState = *(reinterpret_cast(gSignatures.GetEngineSignature("55 89 E5 83 EC 18 C7 44 24 04 01 00 00 00 C7 04 24 ? ? ? ? E8 ? ? ? ? C7 04 24 ? ? ? ? 89 44 24 04 E8 ? ? ? ? A1 ? ? ? ? 85 C0 74 15 A1 ? ? ? ? 8B 10 89 04 24 FF 52 38 C9 C3") + 17)); g_IAchievementMgr = g_IEngine->GetAchievementMgr(); g_ISteamUserStats = g_ISteamClient->GetISteamUserStats(su, sp, "STEAMUSERSTATS_INTERFACE_VERSION011"); } diff --git a/src/interfaces.h b/src/interfaces.h index d47544c9..b32a082c 100644 --- a/src/interfaces.h +++ b/src/interfaces.h @@ -48,6 +48,7 @@ class IVRenderView; class IMaterialSystemFixed; class IMaterialSystem; class IMoveHelperServer; +class CBaseClientState; extern ISteamClient* g_ISteamClient; extern ISteamFriends* g_ISteamFriends; @@ -75,6 +76,7 @@ extern IMaterialSystem* g_IMaterialSystemHL; extern IVModelRender* g_IVModelRender; extern IVRenderView* g_IVRenderView; extern IMoveHelperServer* g_IMoveHelperServer; +extern CBaseClientState* g_IBaseClientState; template T* BruteforceInterface(std::string name, sharedobj::SharedObject* object, int start = 0); diff --git a/src/netmessage.cpp b/src/netmessage.cpp index 3f791fdf..f1517572 100644 --- a/src/netmessage.cpp +++ b/src/netmessage.cpp @@ -7,6 +7,7 @@ #include "netmessage.h" #include "logging.h" +#include "common.h" bf_write::bf_write() { @@ -336,6 +337,40 @@ void bf_write::WriteLong(long val) WriteSBitLong(val, sizeof(long) << 3); } +bool CLC_RespondCvarValue::WriteToBuffer( bf_write &buffer ) +{ + buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS ); + + buffer.WriteSBitLong( m_iCookie, 32 ); + buffer.WriteSBitLong( m_eStatusCode, 4 ); + + buffer.WriteString( m_szCvarName ); + buffer.WriteString( m_szCvarValue ); + + return !buffer.IsOverflowed(); +} + +bool CLC_RespondCvarValue::ReadFromBuffer( bf_read &buffer ) +{ + m_iCookie = buffer.ReadSBitLong( 32 ); + m_eStatusCode = (EQueryCvarValueStatus)buffer.ReadSBitLong( 4 ); + + // Read the name. + buffer.ReadString( m_szCvarNameBuffer, sizeof( m_szCvarNameBuffer ) ); + m_szCvarName = m_szCvarNameBuffer; + + // Read the value. + buffer.ReadString( m_szCvarValueBuffer, sizeof( m_szCvarValueBuffer ) ); + m_szCvarValue = m_szCvarValueBuffer; + + return !buffer.IsOverflowed(); +} + +const char *CLC_RespondCvarValue::ToString(void) const +{ + return strfmt("%s: status: %d, value: %s, cookie: %d", GetName(), m_eStatusCode, m_szCvarValue, m_iCookie ); +} + bool NET_NOP::WriteToBuffer( bf_write &buffer ) { buffer.WriteUBitLong( GetType(), 6 ); diff --git a/src/netmessage.h b/src/netmessage.h index 8cb1d597..5974e373 100644 --- a/src/netmessage.h +++ b/src/netmessage.h @@ -137,6 +137,33 @@ protected: #define MAX_OSPATH 260 +#define NETMSG_TYPE_BITS 5 +typedef int QueryCvarCookie_t; +typedef enum +{ + eQueryCvarValueStatus_ValueIntact=0, // It got the value fine. + eQueryCvarValueStatus_CvarNotFound=1, + eQueryCvarValueStatus_NotACvar=2, // There's a ConCommand, but it's not a ConVar. + eQueryCvarValueStatus_CvarProtected=3 // The cvar was marked with FCVAR_SERVER_CAN_NOT_QUERY, so the server is not allowed to have its value. +} EQueryCvarValueStatus; + +class CLC_RespondCvarValue : public CNetMessage +{ +public: + DECLARE_CLC_MESSAGE( RespondCvarValue ); + + QueryCvarCookie_t m_iCookie; + + const char *m_szCvarName; + const char *m_szCvarValue; // The sender sets this, and it automatically points it at m_szCvarNameBuffer when receiving. + + EQueryCvarValueStatus m_eStatusCode; + +private: + char m_szCvarNameBuffer[256]; + char m_szCvarValueBuffer[256]; +}; + class NET_NOP : public CNetMessage { DECLARE_NET_MESSAGE( NOP ); @@ -158,6 +185,17 @@ public: int m_nSpawnCount; // server spawn count (session number) }; +class SVC_GetCvarValue : public CNetMessage +{ +public: + DECLARE_SVC_MESSAGE( GetCvarValue ); + + QueryCvarCookie_t m_iCookie; + const char *m_szCvarName; // The sender sets this, and it automatically points it at m_szCvarNameBuffer when receiving. + +private: + char m_szCvarNameBuffer[256]; +}; class NET_SetConVar : public CNetMessage {