From 6618d86fd94c19d973a86bfcecec86b81afaf1ea Mon Sep 17 00:00:00 2001 From: BenCat07 Date: Tue, 12 Jun 2018 16:54:31 +0200 Subject: [PATCH] Updates. --- CMakeLists.txt | 2 +- attach-libnamed.sh | 4 +- include/core/offsets.hpp | 5 --- include/hacks/Aimbot.hpp | 1 + include/hacks/Backtrack.hpp | 2 +- src/MiscTemporary.cpp | 2 +- src/hacks/Aimbot.cpp | 62 ++++++++++++++++++++++--- src/hacks/AntiAim.cpp | 40 ----------------- src/hacks/AutoDeadringer.cpp | 10 ++--- src/hacks/AutoJoin.cpp | 27 +++++------ src/hacks/FollowBot.cpp | 8 ++-- src/hacks/Walkbot.cpp | 70 +++++++++++++++++++++++++++-- src/helpers.cpp | 9 ++++ src/hooks/CreateMove.cpp | 8 ++-- src/hooks/SendDatagram.cpp | 18 +++----- src/hooks/SendNetMsg.cpp | 4 +- src/prediction.cpp | 4 +- src/reclasses/CTFGCClientSystem.cpp | 7 ++- src/visual/EffectChams.cpp | 62 +++++++++++++++++++++++++ 19 files changed, 244 insertions(+), 101 deletions(-) mode change 100644 => 100755 attach-libnamed.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index ea03b02b..c2b49df3 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ endif() configure_file(include/config.h.in ${CMAKE_SOURCE_DIR}/include/config.h @ONLY) configure_file(include/version.h.in ${CMAKE_SOURCE_DIR}/include/version.h @ONLY) -set_target_properties(cathook PROPERTIES COMPILE_FLAGS "-m32 -msse -msse2 -msse3 -fexceptions" LINK_FLAGS "-m32 -fno-gnu-unique -fexceptions") +set_target_properties(cathook PROPERTIES COMPILE_FLAGS "-m32 -msse -msse2 -msse3 -fexceptions" LINK_FLAGS "-m32 -fno-gnu-unique -fexceptions -DNDEBUG") target_compile_definitions(cathook PRIVATE _GLIBCXX_USE_CXX11_ABI=0 diff --git a/attach-libnamed.sh b/attach-libnamed.sh old mode 100644 new mode 100755 index 369b7b2a..41c7f53a --- a/attach-libnamed.sh +++ b/attach-libnamed.sh @@ -46,14 +46,14 @@ done # echo $FILENAME > build_id # For detaching -cp "bin/libcathook.so" "/usr/lib64/${FILENAME}" +sudo cp "bin/libcathook.so" "/usr/lib64/${FILENAME}" echo loading "$FILENAME" to "$proc" sudo killall -19 steam sudo killall -19 steamwebhelper -gdb -n -q -batch \ +sudo gdb -n -q -batch \ -ex "attach $proc" \ -ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \ -ex "call \$dlopen(\"/usr/lib64/$FILENAME\", 1)" \ diff --git a/include/core/offsets.hpp b/include/core/offsets.hpp index 3d65831f..c6d2a1c3 100644 --- a/include/core/offsets.hpp +++ b/include/core/offsets.hpp @@ -146,7 +146,6 @@ struct offsets { return PlatformOffset(466, 0, 466); } - static constexpr uint32_t lastoutgoingcommand() { return PlatformOffset(19228, undefined, undefined); @@ -155,10 +154,6 @@ struct offsets { return PlatformOffset(8, undefined, undefined); } - static constexpr uint32_t ProcessMovement() - { - return PlatformOffset(1, undefined, 1); - } static constexpr uint32_t m_NetChannel() { return PlatformOffset(196, undefined, undefined); diff --git a/include/hacks/Aimbot.hpp b/include/hacks/Aimbot.hpp index 5e9e903b..75e7d571 100755 --- a/include/hacks/Aimbot.hpp +++ b/include/hacks/Aimbot.hpp @@ -30,6 +30,7 @@ struct AimbotCalculatedData_s // Functions used to calculate aimbot data, and if already calculated use it const Vector &PredictEntity(CachedEntity *entity); bool VischeckPredictedEntity(CachedEntity *entity); +bool BacktrackVisCheck(CachedEntity *entity); // Variable used to tell when the aimbot has found a target extern bool foundTarget; diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp index b54af1c3..f1c77c10 100644 --- a/include/hacks/Backtrack.hpp +++ b/include/hacks/Backtrack.hpp @@ -53,7 +53,7 @@ struct CIncomingSequence int sequencenr; float curtime; }; -typedef boost::circular_buffer circular_buf; +typedef boost::circular_buffer_space_optimized circular_buf; extern circular_buf sequences; extern CatVar latency; extern CatVar enable; diff --git a/src/MiscTemporary.cpp b/src/MiscTemporary.cpp index b1e3fbd0..e2d73757 100644 --- a/src/MiscTemporary.cpp +++ b/src/MiscTemporary.cpp @@ -12,7 +12,7 @@ CatVar jointeam(CV_SWITCH, "fb_autoteam", "1", CatVar joinclass(CV_STRING, "fb_autoclass", "spy", "Class that will be picked after joining a team (NYI)"); -CatVar nolerp(CV_SWITCH, "nolerp", "1", "NoLerp mode (experimental)"); +CatVar nolerp(CV_SWITCH, "nolerp", "0", "NoLerp mode (experimental)"); CatVar engine_pred(CV_SWITCH, "engine_prediction", "0", "Engine Prediction"); CatVar debug_projectiles(CV_SWITCH, "debug_projectiles", "0", diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 6e50b8ad..3bf769a3 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -137,6 +137,13 @@ static CatVar "Set it to 0.01 if you want to shoot as soon as you " "start pulling the arrow", 0.01f, 1.0f); +static CatVar + sticky_autoshoot(CV_FLOAT, "aimbot_sticky_charge", "0.5", + "Sticky autoshoot", + "Minimum charge for autoshooting with Pipebomb Launcher.\n" + "Set it to 0.01 if you want to shoot as soon as you " + "start Charging", + 0.01f, 4.0f); static CatVar miss_chance(CV_FLOAT, "aimbot_miss_chance", "0", "Miss chance", "From 0 to 1. Aimbot will NOT aim in these % cases", 0.0f, 1.0f); @@ -268,6 +275,30 @@ void CreateMove() // Not release type weapon } + else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) + { + float chargebegin = + *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); + float chargetime = g_GlobalVars->curtime - chargebegin; + + DoAutoshoot(); + static bool currently_charging_pipe = false; + + // Grenade started charging + if (chargetime < 6.0f && chargetime) + currently_charging_pipe = true; + + // Grenade was released + if (!(g_pUserCmd->buttons & IN_ATTACK) && currently_charging_pipe) + { + currently_charging_pipe = false; + Aim(target_entity); + } + else + return; + + // Not release type weapon + } else if (GetWeaponMode() == weapon_melee) { DoAutoshoot(); @@ -321,10 +352,6 @@ bool ShouldAim() // Is cloaked if (IsPlayerInvisible(g_pLocalPlayer->entity)) return false; - // Disable aimbot with stickbomb launcher - if (g_pLocalPlayer->weapon()->m_iClassID() == - CL_CLASS(CTFPipebombLauncher)) - return false; } IF_GAME(IsTF2()) @@ -740,6 +767,7 @@ void Aim(CachedEntity *entity) miny += (maxy - miny) / 6; maxz -= (maxz - minz) / 6; minz += (maxz - minz) / 6; + // Create Vectors positions.push_back({ minx, centery, minz }); positions.push_back({ maxx, centery, minz }); @@ -782,6 +810,7 @@ void Aim(CachedEntity *entity) // A function to check whether player can autoshoot bool begancharge = false; +int begansticky = 0; void DoAutoshoot() { // Enable check @@ -816,6 +845,28 @@ void DoAutoshoot() } else begancharge = false; + if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) + { + float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); + float chargetime = g_GlobalVars->curtime - chargebegin; + + // Release Sticky if > chargetime + if ((chargetime >= (float) sticky_autoshoot) && begansticky > 3) + { + g_pUserCmd->buttons &= ~IN_ATTACK; + hacks::shared::antiaim::SetSafeSpace(3); + begansticky = 0; + } + // Else just keep charging + else + { + g_pUserCmd->buttons |= IN_ATTACK; + begansticky++; + } + return; + } + else + begansticky = 0; bool attack = true; // Rifle check @@ -957,7 +1008,8 @@ int BestHitbox(CachedEntity *target) else if (ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_DirectHit) || - ci == CL_CLASS(CTFRocketLauncher_Mortar)) + ci == CL_CLASS(CTFRocketLauncher_Mortar) || + ci == CL_CLASS(CTFPipebombLauncher)) { preferred = hitbox_t::hip_L; } diff --git a/src/hacks/AntiAim.cpp b/src/hacks/AntiAim.cpp index c007599d..8e26e9ab 100644 --- a/src/hacks/AntiAim.cpp +++ b/src/hacks/AntiAim.cpp @@ -420,46 +420,6 @@ int val = 0; int value[32] = { 0 }; void ProcessUserCmd(CUserCmd *cmd) { - if (communicate && CE_GOOD(LOCAL_E)) - { - for (int i = 0; i < g_IEngine->GetMaxClients(); i++) - { - CachedEntity *ent = ENTITY(i); - if (CE_GOOD(ent)) - { - if ((int) (CE_FLOAT(ent, netvar.angEyeAngles)) == 33 && - (int) (CE_FLOAT(ent, netvar.angEyeAngles + 4)) == 33) - { - player_info_s info; - if (g_IEngine->GetPlayerInfo(ent->m_IDX, &info) && - playerlist::AccessData(info.friendsID).state != - playerlist::k_EState::CAT) - { - value[ent->m_IDX]++; - if (value[ent->m_IDX] > 5) - { - playerlist::AccessData(info.friendsID).state = - playerlist::k_EState::CAT; - cmd->viewangles.y = 53; - cmd->viewangles.x = 33; - g_pLocalPlayer->bUseSilentAngles = true; - return; - } - } - } - } - } - if (delay.test_and_set(180000) || val) - { - cmd->viewangles.y = 33; - cmd->viewangles.x = 33; - g_pLocalPlayer->bUseSilentAngles = true; - val++; - if (val == 3) - val = 0; - return; - } - } if (!ShouldAA(cmd)) return; static bool angstate = true; diff --git a/src/hacks/AutoDeadringer.cpp b/src/hacks/AutoDeadringer.cpp index 18ff9f60..2e8dcbd3 100644 --- a/src/hacks/AutoDeadringer.cpp +++ b/src/hacks/AutoDeadringer.cpp @@ -52,20 +52,18 @@ void CreateMove() return; if (CE_BAD(LOCAL_E)) return; - if (!HasWeapon(LOCAL_E, 59)) - return; - if (CE_INT(LOCAL_E, netvar.iHealth) < 30 && NearbyEntities() > 2) + if (CE_INT(LOCAL_E, netvar.iHealth) < 30 && NearbyEntities() > 1) g_pUserCmd->buttons |= IN_ATTACK2; for (int i = 0; i < HIGHEST_ENTITY; i++) { CachedEntity *ent = ENTITY(i); if (CE_BAD(ent)) continue; - if (!IsProjectile(ent)) + if (!IsProjectile(ent) && !ent->m_bGrenadeProjectile()) continue; - if (ent->m_bCritProjectile()) + if (ent->m_bCritProjectile() && ent->m_flDistance() <= 1000.0f) g_pUserCmd->buttons |= IN_ATTACK2; - if (ent->m_flDistance() < 100.0f) + if (ent->m_flDistance() < 300.0f) g_pUserCmd->buttons |= IN_ATTACK2; } } diff --git a/src/hacks/AutoJoin.cpp b/src/hacks/AutoJoin.cpp index ba6a4316..7150c1f9 100644 --- a/src/hacks/AutoJoin.cpp +++ b/src/hacks/AutoJoin.cpp @@ -95,24 +95,25 @@ void UpdateSearch() return; re::CTFGCClientSystem *gc = re::CTFGCClientSystem::GTFGCClientSystem(); - if (g_pUserCmd && gc && gc->BConnectedToMatchServer(false)) + if (g_pUserCmd && gc && gc->BConnectedToMatchServer(false) && + gc->BHaveLiveMatch()) tfmm::queue_leave(); - if (autoqueue_timer.test_and_set(60000)) - { - if (!gc->BConnectedToMatchServer(false) && - queuetime.test_and_set(10 * 1000 * 60)) - tfmm::queue_leave(); - if (gc && !gc->BConnectedToMatchServer(false)) - { - logging::Info("Starting queue"); - tfmm::queue_start(); - } - } - if (req_timer.test_and_set(1800000)) + if (!gc->BConnectedToMatchServer(false) && + queuetime.test_and_set(10 * 1000 * 60) && !gc->BHaveLiveMatch()) + tfmm::queue_leave(); + if (gc && !gc->BConnectedToMatchServer(false) && !gc->BHaveLiveMatch()) { logging::Info("Starting queue"); tfmm::queue_start(); } +#if LAGBOT_MODE + if (req_timer.test_and_set(1800000)) + { + logging::Info("Stuck in queue, segfaulting"); + *(int *) nullptr; + exit(1); + } +#endif } Timer timer{}; diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index ea89db8c..c536bd0f 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -261,7 +261,7 @@ void WorldTick() } } } - WalkTo(breadcrumbs.at(0)); + WalkTo(breadcrumbs[0]); } else idle_time.update(); @@ -277,15 +277,15 @@ void DrawTick() for (size_t i = 0; i < breadcrumbs.size() - 1; i++) { Vector wts1, wts2; - if (draw::WorldToScreen(breadcrumbs.at(i), wts1) && - draw::WorldToScreen(breadcrumbs.at(i + 1), wts2)) + if (draw::WorldToScreen(breadcrumbs[i], wts1) && + draw::WorldToScreen(breadcrumbs[i + 1], wts2)) { draw_api::draw_line(wts1.x, wts1.y, wts2.x - wts1.x, wts2.y - wts1.y, colors::white, 0.1f); } } Vector wts; - if (!draw::WorldToScreen(breadcrumbs.at(0), wts)) + if (!draw::WorldToScreen(breadcrumbs[0], wts)) return; draw_api::draw_rect(wts.x - 4, wts.y - 4, 8, 8, colors::white); draw_api::draw_rect_outlined(wts.x - 4, wts.y - 4, 7, 7, colors::white, diff --git a/src/hacks/Walkbot.cpp b/src/hacks/Walkbot.cpp index 581105c6..1426b323 100644 --- a/src/hacks/Walkbot.cpp +++ b/src/hacks/Walkbot.cpp @@ -70,7 +70,9 @@ enum EConnectionFlags CF_CAPPED_2 = (1 << 6), CF_CAPPED_3 = (1 << 7), CF_CAPPED_4 = (1 << 8), - CF_CAPPED_5 = (1 << 9) + CF_CAPPED_5 = (1 << 9), + + CF_STICKYBOMB = (1 << 10) }; struct connection_s @@ -643,6 +645,10 @@ std::string DescribeConnection(index_t node, connection conn) { extra += "H"; } + if (c.flags & CF_STICKYBOMB) + { + extra += "S"; + } } std::string result = format(node, ' ', (broken ? "-x>" : (oneway ? "-->" : "<->")), ' ', @@ -691,6 +697,27 @@ CatCommand c_toggle_cf_health( c.flags |= CF_LOW_HEALTH; } }); +CatCommand c_toggle_cf_sticky( + "wb_conn_sticky", + "Toggle 'Sticky' flag on connection from ACTIVE to CLOSEST node", []() { + auto a = state::active(); + auto b = state::closest(); + if (not(a and b)) + return; + for (connection i = 0; i < MAX_CONNECTIONS; i++) + { + auto &c = a->connections[i]; + if (c.free()) + continue; + if (c.node != state::closest_node) + continue; + // Actually flip the flag + if (c.flags & CF_STICKYBOMB) + c.flags &= ~CF_STICKYBOMB; + else + c.flags |= CF_STICKYBOMB; + } + }); // Displays all info about closest node and its connections CatCommand c_info("wb_dump", "Show info", []() { index_t node = state::closest_node; @@ -809,7 +836,7 @@ index_t FindNearestNode(bool traceray) return r_node; } - +int begansticky = 0; index_t SelectNextNode() { if (not state::node_good(state::active_node)) @@ -833,8 +860,45 @@ index_t SelectNextNode() { return n.connections[i].node; } - if (not(n.connections[i].flags & (CF_LOW_AMMO | CF_LOW_HEALTH))) + if (not(n.connections[i].flags & (CF_LOW_AMMO | CF_LOW_HEALTH)) && not(n.connections[i].flags & CF_STICKYBOMB)) chance.push_back(n.connections[i].node); + if ((n.connections[i].flags & CF_STICKYBOMB) && g_pLocalPlayer->clazz == tf_demoman) + { + state::node_good(n.connections[i].node); + if (IsVectorVisible(state::nodes[n.connections[i].node].xyz(), g_pLocalPlayer->v_Eye) && g_pLocalPlayer->v_Eye.DistTo(state::nodes[n.connections[i].node].xyz()) < 400.0f) + { + if (re::C_BaseCombatWeapon::GetSlot(RAW_ENT(LOCAL_W)) != 1) + { + begansticky = 0; + hack::ExecuteCommand("slot1"); + } + else if (CanShoot()) + { + Vector tr = (state::nodes[n.connections[i].node].xyz() - g_pLocalPlayer->v_Eye); + Vector angles; + VectorAngles(tr, angles); + // Clamping is important + fClampAngle(angles); + g_pLocalPlayer->bUseSilentAngles = true; + float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); + float chargetime = g_GlobalVars->curtime - chargebegin; + + // Release Sticky if > chargetime + if ((chargetime >= 0.1f) && begansticky > 3) + { + g_pUserCmd->buttons &= ~IN_ATTACK; + hacks::shared::antiaim::SetSafeSpace(3); + begansticky = 0; + } + // Else just keep charging + else + { + g_pUserCmd->buttons |= IN_ATTACK; + begansticky++; + } + } + } + } } } if (not chance.empty()) diff --git a/src/helpers.cpp b/src/helpers.cpp index 841326b2..731a75ba 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -692,6 +692,15 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity) rgrav = 0.5f; } } + else if (classid == CL_CLASS(CTFPipebombLauncher)) + { + float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); + float chargetime = g_GlobalVars->curtime - chargebegin; + rspeed = + (fminf(fmaxf(chargetime / 4.0f, 0.0f), 1.0f) * 1500.0f) + 900.0f; + rgrav = + (fminf(fmaxf(chargetime / 4.0f, 0.0f), 1.0f) * -0.70000001f) + 0.5f; + } else if (classid == CL_CLASS(CTFCompoundBow)) { float chargetime = diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 592a477c..2cc82661 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -332,10 +332,6 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, if (engine_pred) engine_prediction::RunEnginePrediction(RAW_ENT(LOCAL_E), g_pUserCmd); - { - PROF_SECTION(CM_backtracc); - hacks::shared::backtrack::Run(); - } { PROF_SECTION(CM_lightesp); hacks::shared::lightesp::run(); @@ -344,6 +340,10 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, PROF_SECTION(CM_aimbot); hacks::shared::aimbot::CreateMove(); } + { + PROF_SECTION(CM_backtracc); + hacks::shared::backtrack::Run(); + } IF_GAME(IsTF2()) { PROF_SECTION(CM_antibackstab); diff --git a/src/hooks/SendDatagram.cpp b/src/hooks/SendDatagram.cpp index 1732175a..417c1bd3 100644 --- a/src/hooks/SendDatagram.cpp +++ b/src/hooks/SendDatagram.cpp @@ -8,24 +8,20 @@ #include "Backtrack.hpp" namespace hooked_methods { -float latency2 = 0.0f; DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf) { #if not LAGBOT_MODE - if ((float) hacks::shared::backtrack::latency > latency2) - latency2 += 1.0f; - else if ((float) hacks::shared::backtrack::latency < latency2) - latency2 -= 1.0f; - if (latency2 + 1.0f > (float) hacks::shared::backtrack::latency && - latency2 - 1.0f < (float) hacks::shared::backtrack::latency) - latency2 = (float) hacks::shared::backtrack::latency; - if (!hacks::shared::backtrack::enable || latency2 <= 0.001f) + if (!hacks::shared::backtrack::enable || + (float) hacks::shared::backtrack::latency <= 200.0f) return original::SendDatagram(ch, buf); int in = ch->m_nInSequenceNr; auto state = ch->m_nInReliableState; - float latencysend = round( - (round((latency2 - 0.5f) / 15.1515151515f) - 0.5f) * 15.1515151515f); + float latencysend = + round((round(((float) hacks::shared::backtrack::latency - 0.5f) / + 15.1515151515f) - + 0.5f) * + 15.1515151515f); hacks::shared::backtrack::AddLatencyToNetchan(ch, latencysend); #endif diff --git a/src/hooks/SendNetMsg.cpp b/src/hooks/SendNetMsg.cpp index 8b9da518..15730f6c 100644 --- a/src/hooks/SendNetMsg.cpp +++ b/src/hooks/SendNetMsg.cpp @@ -38,7 +38,9 @@ DEFINE_HOOKED_METHOD(SendNetMsg, bool, INetChannel *this_, INetMessage &msg, msg = msg.substr(0, msg.length() - 2); if (msg.find("!!") == 0) { - msg = ucccccp::encrypt(msg.substr(2)); + // Change this version if you want version A back, look at ucccccp docs for more info + char Version = 'B'; + msg = ucccccp::encrypt(msg.substr(2), Version); str = str.substr(0, offset) + msg + "\"\""; crpt = true; } diff --git a/src/prediction.cpp b/src/prediction.cpp index 0d86afe7..9e79a7c3 100644 --- a/src/prediction.cpp +++ b/src/prediction.cpp @@ -246,8 +246,8 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, bestpos.z += (400 * besttime * besttime * gravitymod); // S = at^2/2 ; t = sqrt(2S/a)*/ Vector result = bestpos + hitbox_offset; - logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, - result.y - origin.y, result.z - origin.z); + /*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, + result.y - origin.y, result.z - origin.z);*/ return result; } diff --git a/src/reclasses/CTFGCClientSystem.cpp b/src/reclasses/CTFGCClientSystem.cpp index 542dd3a6..188f4256 100644 --- a/src/reclasses/CTFGCClientSystem.cpp +++ b/src/reclasses/CTFGCClientSystem.cpp @@ -52,11 +52,14 @@ bool CTFGCClientSystem::BHaveLiveMatch() typedef int (*BHaveLiveMatch_t)(CTFGCClientSystem *); static uintptr_t addr = gSignatures.GetClientSignature("55 31 C0 89 E5 53 8B 4D ? 0F B6 91"); - static BHaveLiveMatch_t BHaveLiveMatch_fn = BHaveLiveMatch_t(addr); - if (BHaveLiveMatch_fn == nullptr) + if (!addr) { logging::Info("calling NULL!"); + addr = gSignatures.GetClientSignature("55 31 C0 89 E5 53 8B 4D ? 0F B6 91"); + return true; } + static BHaveLiveMatch_t BHaveLiveMatch_fn = + BHaveLiveMatch_t(addr); return BHaveLiveMatch_fn(this); } diff --git a/src/visual/EffectChams.cpp b/src/visual/EffectChams.cpp index ee303a32..2b2acacd 100644 --- a/src/visual/EffectChams.cpp +++ b/src/visual/EffectChams.cpp @@ -51,6 +51,9 @@ static CatVar chamsself(CV_SWITCH, "chams_self", "0", "Enable chams on self", static CatVar rainbow(CV_SWITCH, "chams_self_rainbow", "1", "Enable rainbow chams on self", "Only visible in thirdperson!"); +static CatVar + disco_chams(CV_SWITCH, "chams_disco", "0", "Disco chams", + "Constantly change color of the chams on all players"); static CatVar chamsteam(CV_SWITCH, "chams_self_team", "0", "Team chams color"); static CatVar chamsR(CV_INT, "chams_self_r", "0", "Self chams red", "", 0, 255); static CatVar chamsG(CV_INT, "chams_self_g", "0", "Self chams green", "", 0, @@ -108,9 +111,68 @@ void EffectChams::SetEntityColor(CachedEntity *ent, rgba_t color) { data[ent->m_IDX] = color; } +Timer t{}; +int prevcolor = -1; rgba_t EffectChams::ChamsColor(IClientEntity *entity) { CachedEntity *ent = ENTITY(entity->entindex()); + if (disco_chams) + { + static rgba_t disco = { 0, 0, 0, 0 }; + if (t.test_and_set(200)) + { + int color = rand() % 20; + while (color == prevcolor) + color = rand() % 20; + prevcolor = color; + switch (color) + { + case 2: + disco = colors::pink; + break; + case 3: + disco = colors::red; + break; + case 4: + disco = colors::blu; + break; + case 5: + disco = colors::red_b; + break; + case 6: + disco = colors::blu_b; + break; + case 7: + disco = colors::red_v; + break; + case 8: + disco = colors::blu_v; + break; + case 9: + disco = colors::red_u; + break; + case 10: + disco = colors::blu_u; + break; + case 0: + case 1: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + float color1 = rand() % 256; + float color2 = rand() % 256; + float color3 = rand() % 256; + disco = { color1, color2, color3, 255.0f }; + } + } + return disco; + } if (data[entity->entindex()]) { data[entity->entindex()] = false;