// vim: set ts=4 sw=4 tw=99 noet: // // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license // // Ham Sandwich Module // #include "hook_specialbot.h" #include "hooklist.h" #include "hook.h" extern ke::Vector hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL]; extern hook_t hooklist[]; CRegisterHamParams::CRegisterHamParams(AMX *arg_amx, int &arg_func, const char *arg_function, int &arg_post, Forward *arg_pfwd) { amx = arg_amx; func = arg_func; function = new char[strlen(arg_function)+1]; strcpy(function, arg_function); post = arg_post; pfwd = arg_pfwd; } CRegisterHamParams::~CRegisterHamParams() { delete[] function; } CHamSpecialBotHandler::CHamSpecialBotHandler() { m_specialbot_vtable = NULL; } void CHamSpecialBotHandler::CheckClientKeyValue(int &clientIndex, char *infobuffer, const char *key, const char *value) { if(m_specialbot_vtable != NULL) return; edict_t *pEdict = MF_GetPlayerEdict(clientIndex); if((pEdict->v.flags & FL_FAKECLIENT) != FL_FAKECLIENT) { const char *auth = GETPLAYERAUTHID(pEdict); if (auth && (strcmp(auth, "BOT") != 0)) return; } if(strcmp(key, "*bot") != 0 || strcmp(value, "1") != 0) return; m_specialbot_vtable = GetVTable(pEdict->pvPrivateData, Offsets.GetBase()); if(m_RHP_list.empty()) return; for (size_t i = 0; i < m_RHP_list.length(); ++i) { CRegisterHamParams *item = m_RHP_list.at(i); RegisterChecked(item->amx, item->func, item->function, item->post, item->pfwd); delete item; } m_RHP_list.clear(); } void CHamSpecialBotHandler::RegisterHamSpecialBot(AMX *amx, int &func, const char *function, int &post, Forward *pfwd) { if(m_specialbot_vtable == NULL) { m_RHP_list.append(new CRegisterHamParams(amx, func, function, post, pfwd)); return; } RegisterChecked(amx, func, function, post, pfwd); } void CHamSpecialBotHandler::RegisterChecked(AMX *amx, int &func, const char *function, int &post, Forward *pfwd) { pfwd->AddRef(); void **vtable = m_specialbot_vtable; int **ivtable=(int **)vtable; void *vfunction=(void *)ivtable[hooklist[func].vtid]; for (size_t i = 0; i < hooks[func].length(); ++i) { if (hooks[func].at(i)->tramp == vfunction) { // Yes, this function is hooked if (post) { hooks[func].at(i)->post.append(pfwd); } else { hooks[func].at(i)->pre.append(pfwd); } return; } } char classname[] = "player"; // If we got here, the function is not hooked Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname); hooks[func].append(hook); if (post) { hook->post.append(pfwd); } else { hook->pre.append(pfwd); } }