From 16b66528f25b69cb42c40c903fb53939270a1be8 Mon Sep 17 00:00:00 2001 From: bencat07 Date: Sat, 4 May 2019 22:50:40 +0200 Subject: [PATCH] Add Auto equip Base ( Needs to be used with more stuff ) and add proof of conncept commands for it (cat_achievement_cathats, cat_equip_debug) --- include/hacks/Misc.hpp | 3 +- include/reclasses/CTFInventoryManager.hpp | 29 +++++--- src/hacks/Achievement.cpp | 85 +++++++++++++++++++++++ src/hacks/Misc.cpp | 17 +++-- src/reclasses/CTFInventoryManager.cpp | 50 ++++++++----- 5 files changed, 150 insertions(+), 34 deletions(-) diff --git a/include/hacks/Misc.hpp b/include/hacks/Misc.hpp index b48c31fe..63e9ae3f 100644 --- a/include/hacks/Misc.hpp +++ b/include/hacks/Misc.hpp @@ -12,7 +12,8 @@ namespace hacks::shared::misc { - +void generate_schema(); +void Schema_Reload(); void CreateMove(); #if ENABLE_VISUALS void DrawText(); diff --git a/include/reclasses/CTFInventoryManager.hpp b/include/reclasses/CTFInventoryManager.hpp index 8cb94513..e60be73a 100644 --- a/include/reclasses/CTFInventoryManager.hpp +++ b/include/reclasses/CTFInventoryManager.hpp @@ -9,27 +9,36 @@ #include "common.hpp" namespace re { -class CTFInventoryManager -{ -public: - CTFInventoryManager() = delete; - static CTFInventoryManager *GTFInventoryManager(); -public: - bool EquipItemInLoadout(int, int, unsigned long long); -}; class CEconItem { public: unsigned long long uniqueid(); }; + +class CEconItemView +{ +public: + unsigned long long UUID(); +}; + class CTFPlayerInventory { public: CTFPlayerInventory() = delete; - static CTFPlayerInventory *GTFPlayerInventory(); public: - CEconItem *GetFirstItemOfItemDef(int id); + CEconItemView *GetFirstItemOfItemDef(int id); +}; + +class CTFInventoryManager +{ +public: + CTFInventoryManager() = delete; + static CTFInventoryManager *GTFInventoryManager(); + CTFPlayerInventory *GTFPlayerInventory(); + +public: + bool EquipItemInLoadout(int, int, unsigned long long); }; } // namespace re diff --git a/src/hacks/Achievement.cpp b/src/hacks/Achievement.cpp index a99b7320..8f238451 100644 --- a/src/hacks/Achievement.cpp +++ b/src/hacks/Achievement.cpp @@ -6,6 +6,7 @@ */ #include +#include "Misc.hpp" #include "common.hpp" static settings::Bool safety{ "achievement.safety", "true" }; @@ -112,4 +113,88 @@ CatCommand lock_single("achievement_lock_single", "Locks single achievement by I }); CatCommand lock("achievement_lock", "Lock all achievements", Lock); CatCommand unlock("achievement_unlock", "Unlock all achievements", Unlock); + +static bool accept_notifs; +static bool equip; + +void unlock_achievements_and_accept(std::vector items) +{ + for (auto id : items) + { + IAchievement *ach = reinterpret_cast(g_IAchievementMgr->GetAchievementByID(id)); + if (ach) + { + g_IAchievementMgr->AwardAchievement(id); + } + } + accept_notifs = true; +} +static CatCommand get_sniper_items("achievement_sniper", "Get all sniper achievement items", []() { + static std::vector sniper_items = { 1136, 1137, 1138 }; + unlock_achievements_and_accept(sniper_items); +}); +static Timer accept_time{}; +static Timer cooldowm{}; +static CatCommand get_best_hats("achievement_cathats", "Get and equip the bencat hats", []() { + static std::vector bencat_hats = { 1902, 1912, 2006 }; + unlock_achievements_and_accept(bencat_hats); + hacks::shared::misc::Schema_Reload(); + equip = true; +}); +bool equip_on_all(int hat1, int hat2, int hat3) +{ + auto invmng = re::CTFInventoryManager::GTFInventoryManager(); + auto inv = invmng->GTFPlayerInventory(); + auto item_view1 = inv->GetFirstItemOfItemDef(hat1); + auto item_view2 = inv->GetFirstItemOfItemDef(hat2); + auto item_view3 = inv->GetFirstItemOfItemDef(hat3); + for (int i = tf_scout; i < tf_engineer; i++) + { + bool success1 = invmng->EquipItemInLoadout(i, 7, item_view1->UUID()); + bool success2 = invmng->EquipItemInLoadout(i, 8, item_view2->UUID()); + bool success3 = invmng->EquipItemInLoadout(i, 10, item_view3->UUID()); + if (!(success1 && success2 && success3)) + return false; + } + return true; +} +static InitRoutine init([]() { + EC::Register( + EC::Paint, + []() { + if (accept_notifs) + { + accept_time.update(); + accept_notifs = false; + } + if (!accept_time.check(5000) && cooldowm.test_and_set(500)) + g_IEngine->ClientCmd_Unrestricted("cl_trigger_first_notification"); + if (equip) + { + if (accept_time.check(5000) && !accept_time.check(10000) && cooldowm.test_and_set(500)) + { + auto invmng = re::CTFInventoryManager::GTFInventoryManager(); + auto inv = invmng->GTFPlayerInventory(); + // Frontline field recorder + auto item_view1 = inv->GetFirstItemOfItemDef(302); + // Gibus + auto item_view2 = inv->GetFirstItemOfItemDef(940); + // Skull Island Tropper + auto item_view3 = inv->GetFirstItemOfItemDef(941); + if (item_view1 && item_view2 && item_view3) + { + bool success = equip_on_all(302, 940, 941); + if (success) + { + logging::Info("Equipped hats"); + equip = false; + } + } + } + else if (accept_time.check(20000)) + equip = false; + } + }, + "achievement_autounlock"); +}); } // namespace hacks::tf2::achievement diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index 57637b57..28e9a446 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -84,14 +84,14 @@ static void updateAntiAfk() if (!afk_timer) afk_timer = g_ICvar->FindVar("mp_idlemaxtime"); // Trigger 10 seconds before kick - else if (afk_timer->m_nValue != 0 && anti_afk_timer.check(afk_timer->m_nValue*60*1000-10000)) + else if (afk_timer->m_nValue != 0 && anti_afk_timer.check(afk_timer->m_nValue * 60 * 1000 - 10000)) { // Just duck tf if (current_user_cmd->buttons & IN_DUCK) current_user_cmd->buttons &= ~IN_DUCK; else - current_user_cmd->buttons = IN_DUCK; - if (anti_afk_timer.check(afk_timer->m_nValue*60*1000+1000)) + current_user_cmd->buttons = IN_DUCK; + if (anti_afk_timer.check(afk_timer->m_nValue * 60 * 1000 + 1000)) { anti_afk_timer.update(); } @@ -412,7 +412,8 @@ void DrawText() #endif -static CatCommand generateschema("schema_generate", "Generate custom schema", []() { +void generate_schema() +{ std::ifstream in("tf/scripts/items/items_game.txt"); std::string outS((std::istreambuf_iterator(in)), std::istreambuf_iterator()); std::ofstream out("/opt/cathook/data/items_game.txt"); @@ -421,7 +422,8 @@ static CatCommand generateschema("schema_generate", "Generate custom schema", [] outS = std::regex_replace(outS, a, ""); out << std::regex_replace(outS, b, ""); out.close(); -}); +} +static CatCommand generateschema("schema_generate", "Generate custom schema", generate_schema); void Schema_Reload() { @@ -431,10 +433,11 @@ void Schema_Reload() void *schema = GetItemSchema() + 0x4; FILE *file = fopen("/opt/cathook/data/items_game.txt", "r"); - if (ferror(file) != 0) + if (!file || ferror(file) != 0) { logging::Info("Error loading file"); - fclose(file); + if (file) + fclose(file); return; } diff --git a/src/reclasses/CTFInventoryManager.cpp b/src/reclasses/CTFInventoryManager.cpp index bc9c629f..10b5a0ba 100644 --- a/src/reclasses/CTFInventoryManager.cpp +++ b/src/reclasses/CTFInventoryManager.cpp @@ -5,37 +5,55 @@ * Author: bencat07 */ #include "common.hpp" +#include "e8call.hpp" using namespace re; CTFInventoryManager *CTFInventoryManager::GTFInventoryManager() { typedef CTFInventoryManager *(*GTFInventoryManager_t)(); - uintptr_t address = gSignatures.GetClientSignature("55 A1 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 89 E5 56 53 83 EC ? 8B " - "5D ? C7 44 24"); - GTFInventoryManager_t GTFInventoryManager_fn = GTFInventoryManager_t(address); + static uintptr_t address = (unsigned) e8call((void *) (gSignatures.GetClientSignature("E8 ? ? ? ? 0F B6 55 0C") + 1)); + static GTFInventoryManager_t GTFInventoryManager_fn = GTFInventoryManager_t(address); return GTFInventoryManager_fn(); } -bool CTFInventoryManager::EquipItemInLoadout(int slot, int classid, unsigned long long uniqueid) +bool CTFInventoryManager::EquipItemInLoadout(int classid, int slot, unsigned long long uniqueid) { typedef bool (*fn_t)(void *, int, int, unsigned long long); - return vfunc(this, offsets::PlatformOffset(19, offsets::undefined, 19), 0)(this, slot, classid, uniqueid); + return vfunc(this, offsets::PlatformOffset(20, offsets::undefined, 20), 0)(this, classid, slot, uniqueid); } unsigned long long int CEconItem::uniqueid() { return *((unsigned long long int *) this + 36); } -CTFPlayerInventory *CTFPlayerInventory::GTFPlayerInventory() +CTFPlayerInventory *CTFInventoryManager::GTFPlayerInventory() { - typedef CTFPlayerInventory *(*GTFPlayerInventory_t)(); - uintptr_t address = gSignatures.GetClientSignature("55 B8 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 B8 ? ? ? ? 89 E5 5D C3 " - "8D B6 00 00 00 00 55 89 E5 57 56 53 83 EC ? 8B 45 ? 8B 5D"); - GTFPlayerInventory_t GTFPlayerInventory_fn = GTFPlayerInventory_t(address); - return GTFPlayerInventory_fn(); + return (CTFPlayerInventory *) (this + 268); + /*typedef CTFPlayerInventory *(*fn_t)(void *); + return vfunc(this, offsets::PlatformOffset(21, offsets::undefined, 22), 0)(this);*/ } -CEconItem *CTFPlayerInventory::GetFirstItemOfItemDef(int id) + +CEconItemView *CTFPlayerInventory::GetFirstItemOfItemDef(int id) { - typedef CEconItem *(*GetFirstItemOfItemDef_t)(CTFPlayerInventory *, int); - uintptr_t address = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC ? 8B 4D ? 0F B7 45"); - GetFirstItemOfItemDef_t GetFirstItemOfItemDef_fn = GetFirstItemOfItemDef_t(address); - return GetFirstItemOfItemDef_fn(this, id); + typedef CEconItemView *(*GetFirstItemOfItemDef_t)(int16_t, void *); + static uintptr_t address = (unsigned) e8call((void *) (gSignatures.GetClientSignature("E8 ? ? ? ? 85 C0 74 35 8B 55 C0") + 1)); + static GetFirstItemOfItemDef_t GetFirstItemOfItemDef_fn = GetFirstItemOfItemDef_t(address); + return GetFirstItemOfItemDef_fn(id, this); } + +unsigned long long CEconItemView::UUID() +{ + unsigned long long value = *(unsigned long long *) ((char *) this + 56); + auto a = value >> 32; + auto b = value << 32; + return b | a; +} + +static CatCommand equip_debug("equip_debug", "Debug auto equip stuff", []() { + auto invmng = CTFInventoryManager::GTFInventoryManager(); + auto inv = invmng->GTFPlayerInventory(); + auto item_view = inv->GetFirstItemOfItemDef(56); + if (item_view) + { + logging::Info("%llu %llu", item_view->UUID()); + logging::Info("Equip item: %d", invmng->EquipItemInLoadout(tf_sniper, 0, item_view->UUID())); + } +});