Skip to content

Commit

Permalink
Update VtableHook to snake_case
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Aug 19, 2022
1 parent 5166f8a commit f9e3ea4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 158 deletions.
64 changes: 32 additions & 32 deletions shared/utility/VtableHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
using namespace std;

VtableHook::VtableHook()
: m_rawData{},
m_vtablePtr(),
m_newVtable(nullptr),
m_oldVtable(),
m_vtableSize(0)
: m_raw_data{},
m_vtable_ptr(),
m_new_vtable(nullptr),
m_old_vtable(),
m_vtable_size(0)
{}

VtableHook::VtableHook(Address target)
Expand All @@ -17,48 +17,48 @@ VtableHook::VtableHook(Address target)
}

VtableHook::VtableHook(VtableHook&& other)
: m_rawData(move(other.m_rawData)),
m_vtablePtr(other.m_vtablePtr),
m_newVtable(other.m_newVtable),
m_oldVtable(other.m_oldVtable),
m_vtableSize(other.m_vtableSize)
: m_raw_data(move(other.m_raw_data)),
m_vtable_ptr(other.m_vtable_ptr),
m_new_vtable(other.m_new_vtable),
m_old_vtable(other.m_old_vtable),
m_vtable_size(other.m_vtable_size)
{
other.m_vtablePtr = nullptr;
other.m_newVtable = nullptr;
other.m_oldVtable = nullptr;
other.m_vtableSize = 0;
other.m_vtable_ptr = nullptr;
other.m_new_vtable = nullptr;
other.m_old_vtable = nullptr;
other.m_vtable_size = 0;
}

VtableHook::~VtableHook() {
remove();
}

bool VtableHook::create(Address target) {
if (!m_rawData.empty()) {
if (!m_raw_data.empty()) {
remove();
m_rawData.clear();
m_raw_data.clear();
}

m_vtablePtr = target;
m_oldVtable = m_vtablePtr.to<Address>();
m_vtableSize = getVtableSize(m_oldVtable);
m_vtable_ptr = target;
m_old_vtable = m_vtable_ptr.to<Address>();
m_vtable_size = get_vtable_size(m_old_vtable);
// RTTI.
m_rawData.resize(m_vtableSize + 1);
m_newVtable = m_rawData.data() + 1;
m_raw_data.resize(m_vtable_size + 1);
m_new_vtable = m_raw_data.data() + 1;

memcpy(m_rawData.data(), m_oldVtable.as<Address*>() - 1, sizeof(Address) * (m_vtableSize + 1));
memcpy(m_raw_data.data(), m_old_vtable.as<Address*>() - 1, sizeof(Address) * (m_vtable_size + 1));

// At this point we have the address of the old vtable, and a copy of it
// stored in m_newVtable. Set the target objects vtable
// stored in m_new_vtable. Set the target objects vtable
// pointer to our copy of the original.
*m_vtablePtr.as<Address*>() = m_newVtable;
*m_vtable_ptr.as<Address*>() = m_new_vtable;

return true;
}

bool VtableHook::recreate() {
if (m_vtablePtr != nullptr) {
*m_vtablePtr.as<Address*>() = m_newVtable;
if (m_vtable_ptr != nullptr) {
*m_vtable_ptr.as<Address*>() = m_new_vtable;
return true;
}

Expand All @@ -67,24 +67,24 @@ bool VtableHook::recreate() {

bool VtableHook::remove() {
// Can cause issues where we set the vtable/random memory of some other pointer.
if (m_vtablePtr != nullptr && IsBadReadPtr(m_vtablePtr.ptr(), sizeof(void*)) == FALSE && m_vtablePtr.to<void*>() == m_newVtable) {
*m_vtablePtr.as<Address*>() = m_oldVtable;
if (m_vtable_ptr != nullptr && IsBadReadPtr(m_vtable_ptr.ptr(), sizeof(void*)) == FALSE && m_vtable_ptr.to<void*>() == m_new_vtable) {
*m_vtable_ptr.as<Address*>() = m_old_vtable;
return true;
}

return false;
}

bool VtableHook::hookMethod(uint32_t index, Address newMethod) {
if (m_oldVtable != nullptr && m_newVtable != nullptr && index < m_vtableSize) {
m_newVtable[index] = newMethod;
bool VtableHook::hook_method(uint32_t index, Address newMethod) {
if (m_old_vtable != nullptr && m_new_vtable != nullptr && index < m_vtable_size) {
m_new_vtable[index] = newMethod;
return true;
}

return false;
}

size_t VtableHook::getVtableSize(Address vtable) {
size_t VtableHook::get_vtable_size(Address vtable) {
size_t i = 0;

for (; vtable.as<Address*>()[i] != nullptr; ++i) {
Expand Down
28 changes: 14 additions & 14 deletions shared/utility/VtableHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,33 @@ class VtableHook {
bool recreate();
bool remove();

bool hookMethod(uint32_t index, Address newMethod);
bool hook_method(uint32_t index, Address newMethod);

auto getInstance() {
return m_vtablePtr;
auto get_instance() {
return m_vtable_ptr;
}

// Access to original methods.
Address getMethod(uint32_t index) {
if (index < m_vtableSize && m_oldVtable && m_newVtable) {
return m_oldVtable.as<Address*>()[index];
Address get_method(uint32_t index) {
if (index < m_vtable_size && m_old_vtable && m_new_vtable) {
return m_old_vtable.as<Address*>()[index];
}
else {
return nullptr;
}
}

template <typename T>
T getMethod(uint32_t index) {
return (T)getMethod(index).ptr();
T get_method(uint32_t index) {
return (T)get_method(index).ptr();
}

private:
std::vector<Address> m_rawData;
Address m_vtablePtr;
Address* m_newVtable;
Address m_oldVtable;
size_t m_vtableSize;
std::vector<Address> m_raw_data;
Address m_vtable_ptr;
Address* m_new_vtable;
Address m_old_vtable;
size_t m_vtable_size;

size_t getVtableSize(Address vtable);
size_t get_vtable_size(Address vtable);
};
107 changes: 0 additions & 107 deletions src/mods/AutomataMPMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,81 +233,6 @@ void AutomataMPMod::on_think() {
}
}
}
else {
/*spdlog::info("Spawning partner");
auto ent = entityList->spawnEntity("partner", EModel::MODEL_2B, *player->entity->getPosition());
if (ent) {
ent->entity->setBuddyHandle(player->handle);
player->entity->setBuddyHandle(ent->handle);
ent->entity->setSuspend(false);
ent->assignAIRoutine("PLAYER");
ent->assignAIRoutine("player");
// alternate way of assigning AI/control to the entity easily.
player->entity->changePlayer();
player->entity->changePlayer();
const auto old_flags = ent->entity->getBuddyFlags();
ent->entity->setBuddyFlags(8);
ent->entity->setBuddyFromNpc();
ent->entity->setBuddyFlags(old_flags);
m_players[1].setStartTick(*ent->entity->getTickCount());
}*/
}

//spdlog::info("Player: 0x%p, handle: 0x%X", player, player->handle);
//spdlog::info("Partner: 0x%p, handle: 0x%X", partner, partner->handle);
//spdlog::info(" partner real ent: 0x%p", partner->entity);

//static uint32_t(*possessEntity)(Entity* player, uint32_t* handle, bool a3) = (decltype(possessEntity))0x1402118D0;
//static uint32_t(*unpossessEntity)(Entity* player, bool a2) = (decltype(unpossessEntity))0x140211AE0;

/*if (utility::was_key_down(VK_F5)) {
auto curHandle = Address(0x1416053E0).as<uint32_t*>();
auto curEnt = entityList->getByHandle(*curHandle);
if (!curEnt)
return;
auto pl = entityList->getAllByName("Player");
auto players = entityList->getAllByName("partner");
players.insert(players.end(), pl.begin(), pl.end());
auto curPlayer = players.begin();
for (auto& i : *entityList) {
if (!i.ent || !i.handle || i.handle == player->handle || i.handle == *curHandle || std::find(players.begin(), players.end(), i.ent) != players.end())
continue;
if (!i.ent->entity || i.ent->handle == *curHandle)
continue;
if (i.ent->entity->getHealth() == 0)
continue;
if ((*curPlayer)->entity->getBuddyThing() == 0x10200) {
if ((*curPlayer)->entity->getPossessedHandle() != 0) {
unpossessEntity((*curPlayer)->entity, true);
}
possessEntity((*curPlayer)->entity, &i.handle, true);
if ((*curPlayer)->entity->getPossessedHandle() != 0) {
curPlayer++;
}
}
else
curPlayer++;
if (curPlayer == players.end())
break;
}
}*/

if (utility::was_key_down(VK_F6)) {
player->behavior->as<sdk::Pl0000>()->changePlayer();
Expand Down Expand Up @@ -337,41 +262,9 @@ void AutomataMPMod::on_think() {
}
}

/*auto prevPlayer = player;
// generates a linked list of players pretty much
// so we can swap between all of them instead of just two.
for (uint32_t index = 0; index < entityList->size(); ++index) {
auto ent = entityList->get(index);
if (!ent || !ent->behavior) {
continue;
}
if (ent->name != string("Player") && ent->name != string("partner"))
continue;
if (prevPlayer == ent)
continue;
prevPlayer->behavior->as<sdk::Pl0000>()->setBuddyHandle(ent->handle);
prevPlayer = ent;
}
if (prevPlayer != player) {
prevPlayer->behavior->as<sdk::Pl0000>()->setBuddyHandle(player->handle);
}*/

//static uint32_t(*spawnBuddy)(Entity* player) = (decltype(spawnBuddy))0x140245C30;

shared_think();

if (utility::was_key_down(VK_F9)) {
/*auto old = player->entity->getBuddyHandle();
player->entity->setBuddyHandle(0);
spawnBuddy(player->entity);
player->entity->setBuddyHandle(old);*/

auto ent = entity_list->spawn_entity("partner", sdk::EModel::MODEL_2B, player->behavior->position());

if (ent) {
Expand Down
4 changes: 2 additions & 2 deletions src/mods/multiplayer/EntitySync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ NetworkEntity::NetworkEntity(sdk::Entity* entity, uint32_t guid)
m_hook = std::make_unique<VtableHook>();

if (m_hook->create(entity->behavior)) {
m_hook->hookMethod(sdk::Behavior::s_start_animation_index, &start_animation_hook);
m_hook->hook_method(sdk::Behavior::s_start_animation_index, &start_animation_hook);
spdlog::info("Hooked entity {}", guid);
}
}
Expand All @@ -37,7 +37,7 @@ void NetworkEntity::start_animation_hook(sdk::Behavior* behavior, uint32_t anim,
client->send_entity_animation_start(network_entity->get_guid(), anim, variant, a3, a4);
}

auto original = network_entity->m_hook->getMethod<decltype(start_animation_hook)*>(sdk::Behavior::s_start_animation_index);
auto original = network_entity->m_hook->get_method<decltype(start_animation_hook)*>(sdk::Behavior::s_start_animation_index);
original(behavior, anim, variant, a3, a4);
}

Expand Down
6 changes: 3 additions & 3 deletions src/mods/multiplayer/PlayerHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ PlayerHook::PlayerHook() {
}

void PlayerHook::re_hook(sdk::Pl0000* player) {
if (m_hook.getInstance().as<sdk::Pl0000*>() == player) {
if (m_hook.get_instance().as<sdk::Pl0000*>() == player) {
return;
}

if (m_hook.create(player)) {
m_hook.hookMethod(sdk::Behavior::s_start_animation_index, &start_animation_hook);
m_hook.hook_method(sdk::Behavior::s_start_animation_index, &start_animation_hook);
}
}

Expand All @@ -39,6 +39,6 @@ void __thiscall PlayerHook::start_animation_hook(sdk::Pl0000* ent, uint32_t anim

spdlog::info("anim: {}, variant: {}, a3: {}, return: {:x}", anim, variant, a3, (uintptr_t)_ReturnAddress());

auto original = g_player_hook->get_hook().getMethod<decltype(start_animation_hook)*>(sdk::Behavior::s_start_animation_index);
auto original = g_player_hook->get_hook().get_method<decltype(start_animation_hook)*>(sdk::Behavior::s_start_animation_index);
original(ent, anim, variant, a3, a4);
}

0 comments on commit f9e3ea4

Please sign in to comment.