diff --git a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp index bb82c465..d187454a 100644 --- a/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp +++ b/Amalgam/src/Features/Aimbot/AimbotMelee/AimbotMelee.cpp @@ -119,9 +119,10 @@ int CAimbotMelee::GetSwingTime(CTFWeaponBase* pWeapon, bool bVar) { if (pWeapon->GetWeaponID() == TF_WEAPON_KNIFE) return 0; + int iSmackTicks = ceilf(pWeapon->GetSmackDelay() / TICK_INTERVAL); if (bVar) - return Vars::Aimbot::Melee::SwingTicks.Value; - return 14; + iSmackTicks = std::max(iSmackTicks + Vars::Aimbot::Melee::SwingOffset.Value, 0); + return iSmackTicks; } void CAimbotMelee::UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd, std::vector vTargets) diff --git a/Amalgam/src/Features/Binds/Binds.cpp b/Amalgam/src/Features/Binds/Binds.cpp index 1d737237..6475de53 100644 --- a/Amalgam/src/Features/Binds/Binds.cpp +++ b/Amalgam/src/Features/Binds/Binds.cpp @@ -4,34 +4,38 @@ #include "../Configs/Configs.h" #include -#define IsType(type) pVar->m_iType == typeid(type).hash_code() -#define SetType(type, cond)\ -{\ - if (pVar->As()->Map.contains(cond))\ - pVar->As()->Value = pVar->As()->Map[cond];\ +#define IsType(t) pBase->m_iType == typeid(t).hash_code() + +template +static inline void SetMain(BaseVar*& pBase, int iBind) +{ + auto pVar = pBase->As(); + + if (pVar->Map.contains(iBind)) + pVar->Value = pVar->Map[iBind]; } -#define SetT(type, cond) if (IsType(type)) SetType(type, cond) +#define Set(t, b) if (IsType(t)) SetMain(pBase, b); static inline void LoopVars(int iBind, std::vector& vVars = G::Vars) { const bool bDefault = iBind == DEFAULT_BIND; - for (auto pVar : vVars) + for (auto pBase : vVars) { - if (pVar->m_iFlags & (NOSAVE | NOBIND) && !bDefault) + if (pBase->m_iFlags & (NOSAVE | NOBIND) && !bDefault) continue; - SetT(bool, iBind) - else SetT(int, iBind) - else SetT(float, iBind) - else SetT(IntRange_t, iBind) - else SetT(FloatRange_t, iBind) - else SetT(std::string, iBind) - else SetT(VA_LIST(std::vector>), iBind) - else SetT(Color_t, iBind) - else SetT(Gradient_t, iBind) - else SetT(Vec3, iBind) - else SetT(DragBox_t, iBind) - else SetT(WindowBox_t, iBind) + Set(bool, iBind) + else Set(int, iBind) + else Set(float, iBind) + else Set(IntRange_t, iBind) + else Set(FloatRange_t, iBind) + else Set(std::string, iBind) + else Set(VA_LIST(std::vector>), iBind) + else Set(Color_t, iBind) + else Set(Gradient_t, iBind) + else Set(Vec3, iBind) + else Set(DragBox_t, iBind) + else Set(WindowBox_t, iBind) } } @@ -191,30 +195,33 @@ void CBinds::AddBind(int iBind, Bind_t& tBind) m_vBinds[iBind] = tBind; } -#define HasType(type, bind) IsType(type) && pVar->As()->contains(bind) +#define HasType(t, b) IsType(t) && pBase->As()->contains(b) -#define RemoveType(type, bind)\ -{\ - std::unordered_map mMap = {};\ - for (auto it = pVar->As()->Map.begin(); it != pVar->As()->Map.end(); it++)\ - {\ - int iKey = it->first;\ - auto tVal = it->second;\ - if (bind == iKey)\ - continue;\ - else if (bind < iKey)\ - iKey--;\ - mMap[iKey] = tVal;\ - }\ - pVar->As()->Map = mMap;\ +template +static inline void RemoveMain(BaseVar*& pBase, int iBind) +{ + auto pVar = pBase->As(); + + std::unordered_map mMap = {}; + for (auto it = pVar->Map.begin(); it != pVar->Map.end(); it++) + { + int iKey = it->first; + auto tVal = it->second; + if (iBind == iKey) + continue; + else if (iBind < iKey) + iKey--; + mMap[iKey] = tVal; + } + pVar->Map = mMap; } -#define RemoveT(type, bind) if (IsType(type)) RemoveType(type, bind) +#define Remove(t, b) if (IsType(t)) RemoveMain(pBase, b); void CBinds::RemoveBind(int iBind, bool bForce) { if (!bForce) { - for (auto pVar : G::Vars) + for (auto& pBase : G::Vars) { if (HasType(bool, iBind) || HasType(int, iBind) @@ -258,20 +265,20 @@ void CBinds::RemoveBind(int iBind, bool bForce) tBind.m_iParent--; } - for (auto pVar : G::Vars) + for (auto& pBase : G::Vars) { - RemoveT(bool, iIndex) - else RemoveT(int, iIndex) - else RemoveT(float, iIndex) - else RemoveT(IntRange_t, iIndex) - else RemoveT(FloatRange_t, iIndex) - else RemoveT(std::string, iIndex) - else RemoveT(VA_LIST(std::vector>), iIndex) - else RemoveT(Color_t, iIndex) - else RemoveT(Gradient_t, iIndex) - else RemoveT(Vec3, iIndex) - else RemoveT(DragBox_t, iIndex) - else RemoveT(WindowBox_t, iIndex) + Remove(bool, iIndex) + else Remove(int, iIndex) + else Remove(float, iIndex) + else Remove(IntRange_t, iIndex) + else Remove(FloatRange_t, iIndex) + else Remove(std::string, iIndex) + else Remove(VA_LIST(std::vector>), iIndex) + else Remove(Color_t, iIndex) + else Remove(Gradient_t, iIndex) + else Remove(Vec3, iIndex) + else Remove(DragBox_t, iIndex) + else Remove(WindowBox_t, iIndex) } }; searchBinds(iBind); @@ -306,4 +313,67 @@ bool CBinds::WillBeEnabled(int iBind) iBind = tBind.m_iParent; } return true; +} + +template +static inline void SwapMain(BaseVar*& pBase, int iBind1, int iBind2) +{ + auto pVar = pBase->As(); + + bool bHas1 = pVar->contains(iBind1), bHas2 = pVar->contains(iBind2); + if (bHas1 && bHas2) + { + auto& tVal1 = pVar->Map[iBind1]; + auto& tVal2 = pVar->Map[iBind2]; + auto tTemp = tVal1; + tVal1 = tVal2; + tVal2 = tTemp; + } + else if (bHas1) + { + pVar->Map[iBind2] = pVar->Map[iBind1]; + pVar->Map.erase(iBind1); + } + else if (bHas2) + { + pVar->Map[iBind1] = pVar->Map[iBind2]; + pVar->Map.erase(iBind2); + } +} +#define Swap(t, i1, i2) if (IsType(t)) SwapMain(pBase, i1, i2); + +void CBinds::Move(int i1, int i2) +{ + auto& tBind1 = m_vBinds[i1]; + auto& tBind2 = m_vBinds[i2]; + auto tTemp = tBind1; + tBind1 = tBind2; + tBind2 = tTemp; + + std::vector vBinds1, vBinds2; + for (auto& tBind : m_vBinds) + { + if (tBind.m_iParent == i1) + vBinds1.push_back(&tBind); + else if (tBind.m_iParent == i2) + vBinds2.push_back(&tBind); + } + std::for_each(vBinds1.begin(), vBinds1.end(), [&](auto pBind) { pBind->m_iParent = i2; }); + std::for_each(vBinds2.begin(), vBinds2.end(), [&](auto pBind) { pBind->m_iParent = i1; }); + + for (auto& pBase : G::Vars) + { + Swap(bool, i1, i2) + else Swap(int, i1, i2) + else Swap(float, i1, i2) + else Swap(IntRange_t, i1, i2) + else Swap(FloatRange_t, i1, i2) + else Swap(std::string, i1, i2) + else Swap(VA_LIST(std::vector>), i1, i2) + else Swap(Color_t, i1, i2) + else Swap(Gradient_t, i1, i2) + else Swap(Vec3, i1, i2) + else Swap(DragBox_t, i1, i2) + else Swap(WindowBox_t, i1, i2) + } } \ No newline at end of file diff --git a/Amalgam/src/Features/Binds/Binds.h b/Amalgam/src/Features/Binds/Binds.h index 0aa14ace..01a230e1 100644 --- a/Amalgam/src/Features/Binds/Binds.h +++ b/Amalgam/src/Features/Binds/Binds.h @@ -43,6 +43,8 @@ public: bool HasChildren(int iBind); bool WillBeEnabled(int iBind); + void Move(int i1, int i2); + std::vector m_vBinds = {}; }; diff --git a/Amalgam/src/Features/Configs/Configs.cpp b/Amalgam/src/Features/Configs/Configs.cpp index 6bb2ac1a..b3d54864 100644 --- a/Amalgam/src/Features/Configs/Configs.cpp +++ b/Amalgam/src/Features/Configs/Configs.cpp @@ -289,36 +289,43 @@ CConfigs::CConfigs() std::filesystem::create_directory(m_sMaterialsPath); } -#define IsType(t) pVar->m_iType == typeid(t).hash_code() +#define IsType(t) pBase->m_iType == typeid(t).hash_code() -#define SaveCond(t, j) \ -{ \ - boost::property_tree::ptree tMap; \ - for (auto& [iBind, tValue] : pVar->As()->Map) \ - SaveJson(tMap, std::to_string(iBind), tValue); \ - j.put_child(pVar->m_sName, tMap);\ +template +static inline void SaveMain(BaseVar*& pBase, boost::property_tree::ptree& tTree) +{ + auto pVar = pBase->As(); + + boost::property_tree::ptree tMap; + for (auto& [iBind, tValue] : pVar->Map) + F::Configs.SaveJson(tMap, std::to_string(iBind), tValue); + tTree.put_child(pVar->m_sName, tMap); } -#define SaveMain(t, j) if (IsType(t)) SaveCond(t, j) -#define LoadCond(t, j) \ -{ \ - pVar->As()->Map = { { DEFAULT_BIND, pVar->As()->Default } }; \ - if (auto tMap = (j).get_child_optional(pVar->m_sName)) \ - { \ - for (auto& [sKey, _] : *tMap) \ - { \ - int iBind = std::stoi(sKey); \ - if (iBind == DEFAULT_BIND || F::Binds.m_vBinds.size() > iBind && !(pVar->As()->m_iFlags & NOBIND)) \ - { \ - LoadJson(*tMap, sKey, pVar->As()->Map[iBind]); \ - if (iBind != DEFAULT_BIND) \ - std::next(F::Binds.m_vBinds.begin(), iBind)->m_vVars.push_back(pVar); \ - } \ - } \ - } \ - else if (!(pVar->m_iFlags & NOSAVE)) \ - SDK::Output("Amalgam", std::format("{} not found", pVar->m_sName).c_str(), { 175, 150, 255, 127 }, OUTPUT_CONSOLE | OUTPUT_DEBUG); \ +#define Save(t, j) if (IsType(t)) SaveMain(pBase, j); + +template +static inline void LoadMain(BaseVar*& pBase, boost::property_tree::ptree& tTree) +{ + auto pVar = pBase->As(); + + pVar->Map = { { DEFAULT_BIND, pVar->Default } }; + if (auto tMap = tTree.get_child_optional(pVar->m_sName)) + { + for (auto& [sKey, _] : *tMap) + { + int iBind = std::stoi(sKey); + if (iBind == DEFAULT_BIND || F::Binds.m_vBinds.size() > iBind && !(pVar->m_iFlags & NOBIND)) + { + F::Configs.LoadJson(*tMap, sKey, pVar->Map[iBind]); + if (iBind != DEFAULT_BIND) + std::next(F::Binds.m_vBinds.begin(), iBind)->m_vVars.push_back(pVar); + } + } + } + else if (!(pVar->m_iFlags & NOSAVE)) + SDK::Output("Amalgam", std::format("{} not found", pVar->m_sName).c_str(), { 175, 150, 255, 127 }, OUTPUT_CONSOLE | OUTPUT_DEBUG); } -#define LoadMain(t, j) if (IsType(t)) LoadCond(t, j) +#define Load(t, j) if (IsType(t)) LoadMain(pBase, j); bool CConfigs::SaveConfig(const std::string& sConfigName, bool bNotify) { @@ -352,22 +359,22 @@ bool CConfigs::SaveConfig(const std::string& sConfigName, bool bNotify) { boost::property_tree::ptree tSub; const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!bNosave && pVar->m_iFlags & NOSAVE) + if (!bNosave && pBase->m_iFlags & NOSAVE) continue; - SaveMain(bool, tSub) - else SaveMain(int, tSub) - else SaveMain(float, tSub) - else SaveMain(IntRange_t, tSub) - else SaveMain(FloatRange_t, tSub) - else SaveMain(std::string, tSub) - else SaveMain(VA_LIST(std::vector>), tSub) - else SaveMain(Color_t, tSub) - else SaveMain(Gradient_t, tSub) - else SaveMain(DragBox_t, tSub) - else SaveMain(WindowBox_t, tSub) + Save(bool, tSub) + else Save(int, tSub) + else Save(float, tSub) + else Save(IntRange_t, tSub) + else Save(FloatRange_t, tSub) + else Save(std::string, tSub) + else Save(VA_LIST(std::vector>), tSub) + else Save(Color_t, tSub) + else Save(Gradient_t, tSub) + else Save(DragBox_t, tSub) + else Save(WindowBox_t, tSub) } tWrite.put_child("Vars", tSub); } @@ -466,22 +473,22 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify) tSub || (tSub = tRead.get_child_optional("ConVars"))) { const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!bNosave && pVar->m_iFlags & NOSAVE) + if (!bNosave && pBase->m_iFlags & NOSAVE) continue; - LoadMain(bool, *tSub) - else LoadMain(int, *tSub) - else LoadMain(float, *tSub) - else LoadMain(IntRange_t, *tSub) - else LoadMain(FloatRange_t, *tSub) - else LoadMain(std::string, *tSub) - else LoadMain(VA_LIST(std::vector>), *tSub) - else LoadMain(Color_t, *tSub) - else LoadMain(Gradient_t, *tSub) - else LoadMain(DragBox_t, *tSub) - else LoadMain(WindowBox_t, *tSub) + Load(bool, *tSub) + else Load(int, *tSub) + else Load(float, *tSub) + else Load(IntRange_t, *tSub) + else Load(FloatRange_t, *tSub) + else Load(std::string, *tSub) + else Load(VA_LIST(std::vector>), *tSub) + else Load(Color_t, *tSub) + else Load(Gradient_t, *tSub) + else Load(DragBox_t, *tSub) + else Load(WindowBox_t, *tSub) } } @@ -532,10 +539,19 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify) return true; } -#define SaveRegular(t, j) SaveJson(j, pVar->m_sName, pVar->As()->Map[DEFAULT_BIND]) -#define SaveMisc(t, j) if (IsType(t)) SaveRegular(t, j); -#define LoadRegular(t, j) LoadJson(j, pVar->m_sName, pVar->As()->Map[DEFAULT_BIND]) -#define LoadMisc(t, j) if (IsType(t)) LoadRegular(t, j); +template +static inline void SaveMiscMain(BaseVar*& pBase, boost::property_tree::ptree& tTree) +{ + F::Configs.SaveJson(tTree, pBase->m_sName, pBase->As()->Map[DEFAULT_BIND]); +} +#define SaveMisc(t, j) if (IsType(t)) SaveMiscMain(pBase, j); + +template +static inline void LoadMiscMain(BaseVar*& pBase, boost::property_tree::ptree& tTree) +{ + F::Configs.LoadJson(tTree, pBase->m_sName, pBase->As()->Map[DEFAULT_BIND]); +} +#define LoadMisc(t, j) if (IsType(t)) LoadMiscMain(pBase, j); bool CConfigs::SaveVisual(const std::string& sConfigName, bool bNotify) { @@ -546,9 +562,9 @@ bool CConfigs::SaveVisual(const std::string& sConfigName, bool bNotify) { boost::property_tree::ptree tSub; const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!(pVar->m_iFlags & VISUAL) || !bNosave && pVar->m_iFlags & NOSAVE) + if (!(pBase->m_iFlags & VISUAL) || !bNosave && pBase->m_iFlags & NOSAVE) continue; SaveMisc(bool, tSub) @@ -632,9 +648,9 @@ bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify) tSub || (tSub = tRead)) { const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!(pVar->m_iFlags & VISUAL) || !bNosave && pVar->m_iFlags & NOSAVE) + if (!(pBase->m_iFlags & VISUAL) || !bNosave && pBase->m_iFlags & NOSAVE) continue; LoadMisc(bool, *tSub) @@ -696,8 +712,14 @@ bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify) return true; } -#define ResetType(type) pVar->As()->Map = { { DEFAULT_BIND, pVar->As()->Default } }; -#define ResetT(type) if (IsType(type)) ResetType(type) +template +static inline void ResetMain(BaseVar*& pBase) +{ + auto pVar = pBase->As(); + + pVar->Map = { { DEFAULT_BIND, pVar->Default } }; +} +#define Reset(t) if (IsType(t)) ResetMain(pBase); void CConfigs::DeleteConfig(const std::string& sConfigName, bool bNotify) { @@ -730,22 +752,22 @@ void CConfigs::ResetConfig(const std::string& sConfigName, bool bNotify) F::Groups.m_vGroups.clear(); const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!bNosave && pVar->m_iFlags & NOSAVE) + if (!bNosave && pBase->m_iFlags & NOSAVE) continue; - ResetT(bool) - else ResetT(int) - else ResetT(float) - else ResetT(IntRange_t) - else ResetT(FloatRange_t) - else ResetT(std::string) - else ResetT(std::vector) - else ResetT(Color_t) - else ResetT(Gradient_t) - else ResetT(DragBox_t) - else ResetT(WindowBox_t) + Reset(bool) + else Reset(int) + else Reset(float) + else Reset(IntRange_t) + else Reset(FloatRange_t) + else Reset(std::string) + else Reset(std::vector) + else Reset(Color_t) + else Reset(Gradient_t) + else Reset(DragBox_t) + else Reset(WindowBox_t) } SaveConfig(sConfigName, false); @@ -783,22 +805,22 @@ void CConfigs::ResetVisual(const std::string& sConfigName, bool bNotify) F::Groups.m_vGroups.clear(); const bool bNosave = GetAsyncKeyState(VK_SHIFT) & 0x8000; - for (auto& pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!(pVar->m_iFlags & VISUAL) || !bNosave && pVar->m_iFlags & NOSAVE) + if (!(pBase->m_iFlags & VISUAL) || !bNosave && pBase->m_iFlags & NOSAVE) continue; - ResetT(bool) - else ResetT(int) - else ResetT(float) - else ResetT(IntRange_t) - else ResetT(FloatRange_t) - else ResetT(std::string) - else ResetT(std::vector) - else ResetT(Color_t) - else ResetT(Gradient_t) - else ResetT(DragBox_t) - else ResetT(WindowBox_t) + Reset(bool) + else Reset(int) + else Reset(float) + else Reset(IntRange_t) + else Reset(FloatRange_t) + else Reset(std::string) + else Reset(std::vector) + else Reset(Color_t) + else Reset(Gradient_t) + else Reset(DragBox_t) + else Reset(WindowBox_t) } SaveVisual(sConfigName, false); diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index 3dcbebb5..fbc258c8 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -324,7 +324,7 @@ void CMenu::MenuAimbot(int iTab) { if (Section("##Debug Melee")) { - FSlider(Vars::Aimbot::Melee::SwingTicks, FSliderEnum::Left); + FSlider(Vars::Aimbot::Melee::SwingOffset, FSliderEnum::Left); FToggle(Vars::Aimbot::Melee::SwingPredictLag, FToggleEnum::Right); FToggle(Vars::Aimbot::Melee::BackstabAccountPing, FToggleEnum::Left); FToggle(Vars::Aimbot::Melee::BackstabDoubleTest, FToggleEnum::Right); @@ -484,6 +484,28 @@ void CMenu::MenuVisuals(int iTab) SetCursorPosY(GetCursorPosY() - H::Draw.Scale(5)); PopStyleColor(); + auto positionToIndex = [](ImVec2 vPos) + { + int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)) * 2 + + (vPos.x > GetWindowWidth() / 2 ? 1 : 0); + iIndex = std::clamp(iIndex, 0, int(F::Groups.m_vGroups.size() - 1)); + return iIndex; + }; + + static int iDragging = -1; + if (!IsMouseDown(ImGuiMouseButton_Left)) + iDragging = -1; + else if (iDragging != -1) + { + int iTo = positionToIndex(GetMousePos() - GetDrawPos()); + if (iDragging != iTo) + { + SDK::Output("Dragged", std::format("{} -> {}", iDragging, iTo).c_str(), { 0, 255, 255 }, OUTPUT_CONSOLE | OUTPUT_DEBUG); + F::Groups.Move(iDragging, iTo); + iDragging = iTo; + } + } + for (auto it = F::Groups.m_vGroups.begin(); it < F::Groups.m_vGroups.end();) { int iGroup = std::distance(F::Groups.m_vGroups.begin(), it); @@ -523,8 +545,33 @@ void CMenu::MenuVisuals(int iTab) bool bDelete = IconButton(ICON_MD_DELETE); SetCursorPos(vOriginalPos); - if (Button(std::format("##{}", iGroup).c_str(), { flWidth, flHeight })) + bool bClicked = Button(std::format("##{}", iGroup).c_str(), { flWidth, flHeight }); + bool bPopup = IsItemClicked(ImGuiMouseButton_Right); + + if (bClicked) iCurrentGroup = iGroup; + else if (bPopup) + OpenPopup(std::format("RightClicked{}", iGroup).c_str()); + else if (iDragging == -1 && IsItemHovered() && IsMouseDown(ImGuiMouseButton_Left)) + iDragging = iGroup; + + if (FBeginPopup(std::format("RightClicked{}", iGroup).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); + + { + static std::string sInput = ""; + + bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = tGroup.m_sName; + if (bEnter) + tGroup.m_sName = sInput; + } + + PopStyleVar(); + EndPopup(); + } if (!bDelete) ++it; @@ -986,7 +1033,8 @@ void CMenu::MenuMisc(int iTab) FToggle(Vars::Misc::Exploits::CheatsBypass, FToggleEnum::Right); FToggle(Vars::Misc::Exploits::EquipRegionUnlock, FToggleEnum::Left); FToggle(Vars::Misc::Exploits::BackpackExpander, FToggleEnum::Right); - FToggle(Vars::Misc::Exploits::PingReducer); + FToggle(Vars::Misc::Exploits::PingReducer, FToggleEnum::Left); + FToggle(Vars::Misc::Exploits::NoisemakerSpam, FToggleEnum::Right); PushTransparent(!Vars::Misc::Exploits::PingReducer.Value); { FSlider(Vars::Misc::Exploits::PingTarget); @@ -1364,14 +1412,9 @@ void CMenu::MenuLogs(int iTab) bool bHasAlias = F::PlayerUtils.m_mPlayerAliases.contains(tPlayer.m_uAccountID); static std::string sInput = ""; - PushStyleVar(ImGuiStyleVar_FramePadding, { H::Draw.Scale(8), H::Draw.Scale(8) }); - PushItemWidth(H::Draw.Scale(150)); bool bEnter = FInputText("Alias...", sInput, H::Draw.Scale(150), ImGuiInputTextFlags_EnterReturnsTrue); if (!IsItemFocused()) sInput = bHasAlias ? F::PlayerUtils.m_mPlayerAliases[tPlayer.m_uAccountID] : ""; - PopItemWidth(); - PopStyleVar(); - if (bEnter) { if (sInput.empty() && bHasAlias) @@ -2468,6 +2511,55 @@ void CMenu::MenuSettings(int iTab) SetCursorPosY(GetCursorPosY() - H::Draw.Scale(5)); PopStyleColor(); + auto numberToIndex = [](int iNumber, int iLayer) + { + int iIndex = -1, i = -1; + + std::unordered_map mBinds = {}; + std::function getBinds = [&](int iParent) + { + for (auto it = F::Binds.m_vBinds.begin(); it < F::Binds.m_vBinds.end(); it++) + { + int _iBind = std::distance(F::Binds.m_vBinds.begin(), it); + auto& _tBind = *it; + if (iParent != _tBind.m_iParent || mBinds.contains(_iBind)) + continue; + + mBinds[_iBind] = true; + + i++; + //if (iParent == iLayer && iNumber >= i) + if (iIndex == -1 && iParent == iLayer && iNumber <= i) + iIndex = _iBind; + getBinds(_iBind); + } + }; + getBinds(DEFAULT_BIND); + + return iIndex; + }; + auto positionToIndex = [&](ImVec2 vPos, int iLayer = DEFAULT_BIND) + { + int iIndex = floorf((vPos.y - GetCursorPosY() - H::Draw.Scale(4)) / H::Draw.Scale(36)); + iIndex = std::clamp(iIndex, 0, int(F::Binds.m_vBinds.size() - 1)); + iIndex = numberToIndex(iIndex, iLayer); + return iIndex; + }; + + static int iDragging = -1, iLayer = DEFAULT_BIND; + if (!IsMouseDown(ImGuiMouseButton_Left)) + iDragging = -1; + else if (iDragging != -1) + { + int iTo = positionToIndex(GetMousePos() - GetDrawPos(), iLayer); + if (iTo != -1 && iDragging != iTo) + { + SDK::Output("Dragged", std::format("{} -> {}", iDragging, iTo).c_str(), { 255, 0, 255 }, OUTPUT_CONSOLE | OUTPUT_DEBUG); + F::Binds.Move(iDragging, iTo); + iDragging = iTo; + } + } + std::unordered_map mBinds = {}; std::function getBinds = [&](int iParent, int x) { @@ -2589,12 +2681,18 @@ void CMenu::MenuSettings(int iTab) SetCursorPos(vOriginalPos); bool bClicked = Button(std::format("##{}", _iBind).c_str(), { flWidth, flHeight }); + bool bPopup = IsItemClicked(ImGuiMouseButton_Right); PopTransparent(1, 1); if (bClicked) { - if (bParent) + if (!bParent) + { + iBind = _iBind; + tBind = _tBind; + } + else { bParent = false; tBind.m_iParent = _iBind; @@ -2609,12 +2707,11 @@ void CMenu::MenuSettings(int iTab) _iBind2 = _tBind2.m_iParent; } } - else - { - iBind = _iBind; - tBind = _tBind; - } } + else if (bPopup) + OpenPopup(std::format("RightClicked{}", _iBind).c_str()); + else if (iDragging == -1 && IsItemHovered() && IsMouseDown(ImGuiMouseButton_Left)) + iDragging = _iBind, iLayer = iParent; if (bDelete) { if (U::KeyHandler.Down(VK_SHIFT)) // allow user to quickly remove binds @@ -2639,6 +2736,34 @@ void CMenu::MenuSettings(int iTab) EndPopup(); } + if (FBeginPopup(std::format("RightClicked{}", _iBind).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { H::Draw.Scale(8), 0 }); + + { + static std::string sInput = ""; + + bool bEnter = FInputText("Name...", sInput, H::Draw.Scale(284), ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = _tBind.m_sName; + if (bEnter) + _tBind.m_sName = sInput; + } + + FDropdown("Type", &_tBind.m_iType, { "Key", "Class", "Weapon type", "Item slot" }, {}, FDropdownEnum::Left); + switch (_tBind.m_iType) + { + case BindEnum::Key: _tBind.m_iInfo = std::clamp(_tBind.m_iInfo, 0, 2); FDropdown("Behavior", &_tBind.m_iInfo, { "Hold", "Toggle", "Double click" }, {}, FDropdownEnum::Right); break; + case BindEnum::Class: _tBind.m_iInfo = std::clamp(_tBind.m_iInfo, 0, 8); FDropdown("Class", &_tBind.m_iInfo, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy" }, {}, FDropdownEnum::Right); break; + case BindEnum::WeaponType: _tBind.m_iInfo = std::clamp(_tBind.m_iInfo, 0, 3); FDropdown("Weapon type", &_tBind.m_iInfo, { "Hitscan", "Projectile", "Melee", "Throwable" }, {}, FDropdownEnum::Right); break; + case BindEnum::ItemSlot: _tBind.m_iInfo = std::max(_tBind.m_iInfo, 0); FDropdown("Item slot", &_tBind.m_iInfo, { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, {}, FDropdownEnum::Right); break; + } + if (_tBind.m_iType == BindEnum::Key) + FKeybind("Key", _tBind.m_iKey); + + PopStyleVar(); + EndPopup(); + } if (iParent != DEFAULT_BIND - 1) getBinds(_iBind, x + 1); @@ -2949,12 +3074,12 @@ void CMenu::MenuSettings(int iTab) #ifdef DEBUG_HOOKS if (Section("Hooks", 8)) { - int i = 0; for (auto& pVar : G::Vars) + int i = 0; for (auto& pBase : G::Vars) { - if (pVar->m_sName.find("Vars::Hooks::") == std::string::npos) + if (pBase->m_sName.find("Vars::Hooks::") == std::string::npos) continue; - FToggle(*pVar->As(), !(i % 2) ? FToggleEnum::Left : FToggleEnum::Right); + FToggle(*pBase->As(), !(i % 2) ? FToggleEnum::Left : FToggleEnum::Right); i++; } } EndSection(); @@ -2981,14 +3106,14 @@ void CMenu::MenuSearch(std::string sSearch) std::transform(sSearch2.begin(), sSearch2.end(), sSearch2.begin(), ::tolower); vVars.clear(); - for (auto pVar : G::Vars) + for (auto& pBase : G::Vars) { - if (!Vars::Debug::Options[DEFAULT_BIND] && pVar->m_iFlags & DEBUGVAR) + if (!Vars::Debug::Options[DEFAULT_BIND] && pBase->m_iFlags & DEBUGVAR) continue; - std::vector vSearch = { pVar->m_sName.c_str(), pVar->m_sSection }; - vSearch.insert(vSearch.end(), pVar->m_vTitle.begin(), pVar->m_vTitle.end()); - vSearch.insert(vSearch.end(), pVar->m_vValues.begin(), pVar->m_vValues.end()); + std::vector vSearch = { pBase->m_sName.c_str(), pBase->m_sSection }; + vSearch.insert(vSearch.end(), pBase->m_vTitle.begin(), pBase->m_vTitle.end()); + vSearch.insert(vSearch.end(), pBase->m_vValues.begin(), pBase->m_vValues.end()); for (auto pSearch : vSearch) { std::string sSearch3 = pSearch; @@ -2999,7 +3124,7 @@ void CMenu::MenuSearch(std::string sSearch) std::transform(sSearch3.begin(), sSearch3.end(), sSearch3.begin(), ::tolower); if (sSearch3.find(sSearch2) != std::string::npos) { - vVars.push_back(pVar); + vVars.push_back(pBase); break; } } diff --git a/Amalgam/src/Features/Misc/Misc.cpp b/Amalgam/src/Features/Misc/Misc.cpp index 4ff4f0a4..c5ef2fa4 100644 --- a/Amalgam/src/Features/Misc/Misc.cpp +++ b/Amalgam/src/Features/Misc/Misc.cpp @@ -11,8 +11,10 @@ void CMisc::RunPre(CTFPlayer* pLocal, CUserCmd* pCmd) WeaponSway(); AntiAFK(pLocal, pCmd); InstantRespawnMVM(pLocal); + NoisemakerSpam(pLocal); - if (!pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->m_MoveType() != MOVETYPE_WALK || pLocal->IsSwimming() || pLocal->InCond(TF_COND_SHIELD_CHARGE) || pLocal->InCond(TF_COND_HALLOWEEN_KART)) + if (!pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->m_MoveType() != MOVETYPE_WALK || pLocal->IsSwimming() + || pLocal->IsTaunting() || pLocal->InCond(TF_COND_HALLOWEEN_KART) || pLocal->InCond(TF_COND_SHIELD_CHARGE)) return; AutoJump(pLocal, pCmd); @@ -26,13 +28,18 @@ void CMisc::RunPre(CTFPlayer* pLocal, CUserCmd* pCmd) void CMisc::RunPost(CTFPlayer* pLocal, CUserCmd* pCmd, bool pSendPacket) { - if (!pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->m_MoveType() != MOVETYPE_WALK || pLocal->IsSwimming() || pLocal->InCond(TF_COND_SHIELD_CHARGE)) + if (!pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->m_MoveType() != MOVETYPE_WALK || pLocal->IsSwimming() + || pLocal->InCond(TF_COND_SHIELD_CHARGE)) return; - EdgeJump(pLocal, pCmd, true); - TauntKartControl(pLocal, pCmd); - AutoPeek(pLocal, pCmd, true); - FastMovement(pLocal, pCmd); + if (pLocal->IsTaunting() || pLocal->InCond(TF_COND_HALLOWEEN_KART)) + TauntKartControl(pLocal, pCmd); + else + { + EdgeJump(pLocal, pCmd, true); + AutoPeek(pLocal, pCmd, true); + FastMovement(pLocal, pCmd); + } } @@ -204,12 +211,22 @@ void CMisc::AntiAFK(CTFPlayer* pLocal, CUserCmd* pCmd) void CMisc::InstantRespawnMVM(CTFPlayer* pLocal) { - if (Vars::Misc::MannVsMachine::InstantRespawn.Value && I::EngineClient->IsInGame() && !pLocal->IsAlive()) - { - KeyValues* kv = new KeyValues("MVM_Revive_Response"); - kv->SetInt("accepted", 1); - I::EngineClient->ServerCmdKeyValues(kv); - } + if (!Vars::Misc::MannVsMachine::InstantRespawn.Value || !pLocal->IsAlive()) + return; + + KeyValues* kv = new KeyValues("MVM_Revive_Response"); + kv->SetInt("accepted", 1); + I::EngineClient->ServerCmdKeyValues(kv); +} + +void CMisc::NoisemakerSpam(CTFPlayer* pLocal) +{ + if (!Vars::Misc::Exploits::NoisemakerSpam.Value || !pLocal->IsAlive() || pLocal->IsAGhost() + || pLocal->m_bUsingActionSlot() || pLocal->m_flNextNoiseMakerTime() > I::GlobalVars->curtime) + return; + + KeyValues* kv = new KeyValues("use_action_slot_item_server"); + I::EngineClient->ServerCmdKeyValues(kv); } void CMisc::CheatsBypass() diff --git a/Amalgam/src/Features/Misc/Misc.h b/Amalgam/src/Features/Misc/Misc.h index a7ad5602..a10f87d3 100644 --- a/Amalgam/src/Features/Misc/Misc.h +++ b/Amalgam/src/Features/Misc/Misc.h @@ -11,6 +11,7 @@ private: void BreakJump(CTFPlayer* pLocal, CUserCmd* pCmd); void AntiAFK(CTFPlayer* pLocal, CUserCmd* pCmd); void InstantRespawnMVM(CTFPlayer* pLocal); + void NoisemakerSpam(CTFPlayer* pLocal); void CheatsBypass(); void WeaponSway(); diff --git a/Amalgam/src/Features/Visuals/Groups/Groups.cpp b/Amalgam/src/Features/Visuals/Groups/Groups.cpp index 9de0707a..bea164a4 100644 --- a/Amalgam/src/Features/Visuals/Groups/Groups.cpp +++ b/Amalgam/src/Features/Visuals/Groups/Groups.cpp @@ -430,4 +430,10 @@ Color_t CGroups::GetColor(CBaseEntity* pEntity, Group_t* pGroup) bool CGroups::GroupsActive() { return Vars::ESP::ActiveGroups.Value && !m_vGroups.empty(); +} + +void CGroups::Move(int i1, int i2) +{ + m_vGroups.insert(std::next(m_vGroups.begin(), i2 + (i1 < i2 ? 1 : 0)), m_vGroups[i1]); + m_vGroups.erase(std::next(m_vGroups.begin(), i1 + (i1 > i2 ? 1 : 0))); } \ No newline at end of file diff --git a/Amalgam/src/Features/Visuals/Groups/Groups.h b/Amalgam/src/Features/Visuals/Groups/Groups.h index b819e33e..8984a901 100644 --- a/Amalgam/src/Features/Visuals/Groups/Groups.h +++ b/Amalgam/src/Features/Visuals/Groups/Groups.h @@ -62,6 +62,8 @@ public: Color_t GetColor(CBaseEntity* pEntity, Group_t* pGroup); bool GroupsActive(); + void Move(int i1, int i2); + std::vector m_vGroups = {}; // loop through this in reverse so back groups have higher priority }; diff --git a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp index b1f6544b..24d0ddeb 100644 --- a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp +++ b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.cpp @@ -67,8 +67,8 @@ float CTFWeaponBase::GetDamage(bool bAttribHookValue) if (auto pWeaponInfo = GetWeaponInfo()) { if (!bAttribHookValue) - return pWeaponInfo->GetWeaponData(0).m_nDamage; - return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(0).m_nDamage, "mult_dmg", this); + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_nDamage; + return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_nDamage, "mult_dmg", this); } return 0.f; } @@ -78,8 +78,8 @@ float CTFWeaponBase::GetFireRate(bool bAttribHookValue) if (auto pWeaponInfo = GetWeaponInfo()) { if (!bAttribHookValue) - return pWeaponInfo->GetWeaponData(0).m_flTimeFireDelay; - return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(0).m_flTimeFireDelay, "mult_postfiredelay", this); + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_flTimeFireDelay; + return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_flTimeFireDelay, "mult_postfiredelay", this); } return 0.315f; } @@ -89,8 +89,8 @@ int CTFWeaponBase::GetBulletsPerShot(bool bAttribHookValue) if (auto pWeaponInfo = GetWeaponInfo()) { if (!bAttribHookValue) - return pWeaponInfo->GetWeaponData(0).m_nBulletsPerShot; - return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(0).m_nBulletsPerShot, "mult_bullets_per_shot", this); + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_nBulletsPerShot; + return SDK::AttribHookValue(pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_nBulletsPerShot, "mult_bullets_per_shot", this); } return 1; } @@ -100,9 +100,9 @@ int CTFWeaponBase::GetAmmoPerShot(bool bAttribHookValue) if (auto pWeaponInfo = GetWeaponInfo()) { if (!bAttribHookValue) - return pWeaponInfo->GetWeaponData(0).m_iAmmoPerShot; + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_iAmmoPerShot; int iAmmoPerShot = SDK::AttribHookValue(0, "mod_ammo_per_shot", this); - return iAmmoPerShot > 0 ? iAmmoPerShot : pWeaponInfo->GetWeaponData(0).m_iAmmoPerShot; + return iAmmoPerShot > 0 ? iAmmoPerShot : pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_iAmmoPerShot; } return 1; } @@ -110,10 +110,17 @@ int CTFWeaponBase::GetAmmoPerShot(bool bAttribHookValue) bool CTFWeaponBase::IsRapidFire() { if (auto pWeaponInfo = GetWeaponInfo()) - return pWeaponInfo->GetWeaponData(0).m_bUseRapidFireCrits; + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_bUseRapidFireCrits; return false; } +float CTFWeaponBase::GetSmackDelay() +{ + if (auto pWeaponInfo = GetWeaponInfo()) + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_flSmackDelay; + return 0.2f; +} + float CTFWeaponBase::GetRange() { switch (GetWeaponID()) @@ -123,7 +130,7 @@ float CTFWeaponBase::GetRange() } if (auto pWeaponInfo = GetWeaponInfo()) - return pWeaponInfo->GetWeaponData(0).m_flRange; + return pWeaponInfo->GetWeaponData(m_iWeaponMode()).m_flRange; return 8192.f; } diff --git a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.h b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.h index 9c6e2b2b..5934ab85 100644 --- a/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.h +++ b/Amalgam/src/SDK/Definitions/Main/CTFWeaponBase.h @@ -239,6 +239,7 @@ public: int GetBulletsPerShot(bool bAttribHookValue = true); int GetAmmoPerShot(bool bAttribHookValue = true); bool IsRapidFire(); + float GetSmackDelay(); float GetRange(); CHudTexture* GetWeaponIcon(); }; diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h index 2781744f..fdfa1b23 100644 --- a/Amalgam/src/SDK/Vars.h +++ b/Amalgam/src/SDK/Vars.h @@ -384,7 +384,7 @@ namespace Vars CVar(SwingPrediction, "Swing prediction", false); CVar(WhipTeam, "Whip team", false); - CVar(SwingTicks, "Swing ticks", 13, NOSAVE | DEBUGVAR, 10, 14); + CVar(SwingOffset, "Swing offset", -1, NOSAVE | DEBUGVAR, -1, 1); CVar(SwingPredictLag, "Swing predict lag", true, NOSAVE | DEBUGVAR); CVar(BackstabAccountPing, "Backstab account ping", true, NOSAVE | DEBUGVAR); CVar(BackstabDoubleTest, "Backstab double test", true, NOSAVE | DEBUGVAR); @@ -727,6 +727,7 @@ namespace Vars CVar(CheatsBypass, "Cheats bypass", false); CVar(EquipRegionUnlock, "Equip region unlock", false); CVar(BackpackExpander, "Backpack expander", false); + CVar(NoisemakerSpam, "Noisemaker spam", false); CVar(PingReducer, "Ping reducer", false); CVar(PingTarget, "cl_cmdrate", 1, SLIDER_CLAMP, 1, 66); SUBNAMESPACE_END(Exploits); diff --git a/Amalgam/src/Utils/CrashLog/CrashLog.cpp b/Amalgam/src/Utils/CrashLog/CrashLog.cpp index 90bfdf21..0bd52e7e 100644 --- a/Amalgam/src/Utils/CrashLog/CrashLog.cpp +++ b/Amalgam/src/Utils/CrashLog/CrashLog.cpp @@ -128,9 +128,8 @@ static LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) case STATUS_ACCESS_VIOLATION: //case STATUS_STACK_OVERFLOW: //case STATUS_HEAP_CORRUPTION: - { - auto vTrace = StackTrace(ExceptionInfo->ContextRecord); - if (!vTrace.empty()) + if (auto vTrace = StackTrace(ExceptionInfo->ContextRecord); + !vTrace.empty()) { for (auto& tFrame : vTrace) { @@ -146,7 +145,10 @@ static LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) } ssErrorStream << "\n"; } - } + break; + default: + ssErrorStream << U::Memory.GetModuleOffset(ExceptionInfo->ExceptionRecord->ExceptionAddress); + ssErrorStream << "\n\n"; } ssErrorStream << "Built @ " __DATE__ ", " __TIME__ ", " __CONFIGURATION__ "\n"; diff --git a/Amalgam/src/Utils/Memory/Memory.h b/Amalgam/src/Utils/Memory/Memory.h index 6de3d0d7..39a47de3 100644 --- a/Amalgam/src/Utils/Memory/Memory.h +++ b/Amalgam/src/Utils/Memory/Memory.h @@ -12,6 +12,7 @@ public: std::vector PatternToInt(const char* szPattern); uintptr_t FindSignature(const char* szModule, const char* szPattern); PVOID FindInterface(const char* szModule, const char* szObject); + std::string GetModuleOffset(void* pAddress) { return GetModuleOffset(uintptr_t(pAddress)); }; std::string GetModuleOffset(uintptr_t uAddress); inline void* GetVirtual(void* p, size_t i)