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)
This commit is contained in:
parent
0b9893a5cb
commit
16b66528f2
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
namespace hacks::shared::misc
|
namespace hacks::shared::misc
|
||||||
{
|
{
|
||||||
|
void generate_schema();
|
||||||
|
void Schema_Reload();
|
||||||
void CreateMove();
|
void CreateMove();
|
||||||
#if ENABLE_VISUALS
|
#if ENABLE_VISUALS
|
||||||
void DrawText();
|
void DrawText();
|
||||||
|
@ -9,27 +9,36 @@
|
|||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
namespace re
|
namespace re
|
||||||
{
|
{
|
||||||
class CTFInventoryManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CTFInventoryManager() = delete;
|
|
||||||
static CTFInventoryManager *GTFInventoryManager();
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool EquipItemInLoadout(int, int, unsigned long long);
|
|
||||||
};
|
|
||||||
class CEconItem
|
class CEconItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned long long uniqueid();
|
unsigned long long uniqueid();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CEconItemView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned long long UUID();
|
||||||
|
};
|
||||||
|
|
||||||
class CTFPlayerInventory
|
class CTFPlayerInventory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CTFPlayerInventory() = delete;
|
CTFPlayerInventory() = delete;
|
||||||
static CTFPlayerInventory *GTFPlayerInventory();
|
|
||||||
|
|
||||||
public:
|
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
|
} // namespace re
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <settings/Bool.hpp>
|
#include <settings/Bool.hpp>
|
||||||
|
#include "Misc.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
static settings::Bool safety{ "achievement.safety", "true" };
|
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 lock("achievement_lock", "Lock all achievements", Lock);
|
||||||
CatCommand unlock("achievement_unlock", "Unlock all achievements", Unlock);
|
CatCommand unlock("achievement_unlock", "Unlock all achievements", Unlock);
|
||||||
|
|
||||||
|
static bool accept_notifs;
|
||||||
|
static bool equip;
|
||||||
|
|
||||||
|
void unlock_achievements_and_accept(std::vector<int> items)
|
||||||
|
{
|
||||||
|
for (auto id : items)
|
||||||
|
{
|
||||||
|
IAchievement *ach = reinterpret_cast<IAchievement *>(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<int> 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<int> 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
|
} // namespace hacks::tf2::achievement
|
||||||
|
@ -84,14 +84,14 @@ static void updateAntiAfk()
|
|||||||
if (!afk_timer)
|
if (!afk_timer)
|
||||||
afk_timer = g_ICvar->FindVar("mp_idlemaxtime");
|
afk_timer = g_ICvar->FindVar("mp_idlemaxtime");
|
||||||
// Trigger 10 seconds before kick
|
// 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
|
// Just duck tf
|
||||||
if (current_user_cmd->buttons & IN_DUCK)
|
if (current_user_cmd->buttons & IN_DUCK)
|
||||||
current_user_cmd->buttons &= ~IN_DUCK;
|
current_user_cmd->buttons &= ~IN_DUCK;
|
||||||
else
|
else
|
||||||
current_user_cmd->buttons = IN_DUCK;
|
current_user_cmd->buttons = IN_DUCK;
|
||||||
if (anti_afk_timer.check(afk_timer->m_nValue*60*1000+1000))
|
if (anti_afk_timer.check(afk_timer->m_nValue * 60 * 1000 + 1000))
|
||||||
{
|
{
|
||||||
anti_afk_timer.update();
|
anti_afk_timer.update();
|
||||||
}
|
}
|
||||||
@ -412,7 +412,8 @@ void DrawText()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CatCommand generateschema("schema_generate", "Generate custom schema", []() {
|
void generate_schema()
|
||||||
|
{
|
||||||
std::ifstream in("tf/scripts/items/items_game.txt");
|
std::ifstream in("tf/scripts/items/items_game.txt");
|
||||||
std::string outS((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
|
std::string outS((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
|
||||||
std::ofstream out("/opt/cathook/data/items_game.txt");
|
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, "");
|
outS = std::regex_replace(outS, a, "");
|
||||||
out << std::regex_replace(outS, b, "");
|
out << std::regex_replace(outS, b, "");
|
||||||
out.close();
|
out.close();
|
||||||
});
|
}
|
||||||
|
static CatCommand generateschema("schema_generate", "Generate custom schema", generate_schema);
|
||||||
|
|
||||||
void Schema_Reload()
|
void Schema_Reload()
|
||||||
{
|
{
|
||||||
@ -431,9 +433,10 @@ void Schema_Reload()
|
|||||||
void *schema = GetItemSchema() + 0x4;
|
void *schema = GetItemSchema() + 0x4;
|
||||||
|
|
||||||
FILE *file = fopen("/opt/cathook/data/items_game.txt", "r");
|
FILE *file = fopen("/opt/cathook/data/items_game.txt", "r");
|
||||||
if (ferror(file) != 0)
|
if (!file || ferror(file) != 0)
|
||||||
{
|
{
|
||||||
logging::Info("Error loading file");
|
logging::Info("Error loading file");
|
||||||
|
if (file)
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5,37 +5,55 @@
|
|||||||
* Author: bencat07
|
* Author: bencat07
|
||||||
*/
|
*/
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "e8call.hpp"
|
||||||
using namespace re;
|
using namespace re;
|
||||||
|
|
||||||
CTFInventoryManager *CTFInventoryManager::GTFInventoryManager()
|
CTFInventoryManager *CTFInventoryManager::GTFInventoryManager()
|
||||||
{
|
{
|
||||||
typedef CTFInventoryManager *(*GTFInventoryManager_t)();
|
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 "
|
static uintptr_t address = (unsigned) e8call((void *) (gSignatures.GetClientSignature("E8 ? ? ? ? 0F B6 55 0C") + 1));
|
||||||
"5D ? C7 44 24");
|
static GTFInventoryManager_t GTFInventoryManager_fn = GTFInventoryManager_t(address);
|
||||||
GTFInventoryManager_t GTFInventoryManager_fn = GTFInventoryManager_t(address);
|
|
||||||
return GTFInventoryManager_fn();
|
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);
|
typedef bool (*fn_t)(void *, int, int, unsigned long long);
|
||||||
return vfunc<fn_t>(this, offsets::PlatformOffset(19, offsets::undefined, 19), 0)(this, slot, classid, uniqueid);
|
return vfunc<fn_t>(this, offsets::PlatformOffset(20, offsets::undefined, 20), 0)(this, classid, slot, uniqueid);
|
||||||
}
|
}
|
||||||
unsigned long long int CEconItem::uniqueid()
|
unsigned long long int CEconItem::uniqueid()
|
||||||
{
|
{
|
||||||
return *((unsigned long long int *) this + 36);
|
return *((unsigned long long int *) this + 36);
|
||||||
}
|
}
|
||||||
CTFPlayerInventory *CTFPlayerInventory::GTFPlayerInventory()
|
CTFPlayerInventory *CTFInventoryManager::GTFPlayerInventory()
|
||||||
{
|
{
|
||||||
typedef CTFPlayerInventory *(*GTFPlayerInventory_t)();
|
return (CTFPlayerInventory *) (this + 268);
|
||||||
uintptr_t address = gSignatures.GetClientSignature("55 B8 ? ? ? ? 89 E5 5D C3 8D B6 00 00 00 00 55 B8 ? ? ? ? 89 E5 5D C3 "
|
/*typedef CTFPlayerInventory *(*fn_t)(void *);
|
||||||
"8D B6 00 00 00 00 55 89 E5 57 56 53 83 EC ? 8B 45 ? 8B 5D");
|
return vfunc<fn_t>(this, offsets::PlatformOffset(21, offsets::undefined, 22), 0)(this);*/
|
||||||
GTFPlayerInventory_t GTFPlayerInventory_fn = GTFPlayerInventory_t(address);
|
|
||||||
return GTFPlayerInventory_fn();
|
|
||||||
}
|
}
|
||||||
CEconItem *CTFPlayerInventory::GetFirstItemOfItemDef(int id)
|
|
||||||
|
CEconItemView *CTFPlayerInventory::GetFirstItemOfItemDef(int id)
|
||||||
{
|
{
|
||||||
typedef CEconItem *(*GetFirstItemOfItemDef_t)(CTFPlayerInventory *, int);
|
typedef CEconItemView *(*GetFirstItemOfItemDef_t)(int16_t, void *);
|
||||||
uintptr_t address = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC ? 8B 4D ? 0F B7 45");
|
static uintptr_t address = (unsigned) e8call((void *) (gSignatures.GetClientSignature("E8 ? ? ? ? 85 C0 74 35 8B 55 C0") + 1));
|
||||||
GetFirstItemOfItemDef_t GetFirstItemOfItemDef_fn = GetFirstItemOfItemDef_t(address);
|
static GetFirstItemOfItemDef_t GetFirstItemOfItemDef_fn = GetFirstItemOfItemDef_t(address);
|
||||||
return GetFirstItemOfItemDef_fn(this, id);
|
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()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user