Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <extdll.h>
- #include <meta_api.h>
- #include <stdarg.h>
- #include <cbase.h>
- #ifdef __linux__
- #include <sys/mman.h>
- #include <malloc.h>
- #endif
- #if _MSC_VER
- #if _MSC_VER >= 1400
- #define stricmp _stricmp
- #endif
- #endif
- #ifdef __linux__
- #define stricmp strcasecmp
- #endif
- #ifdef _WIN32
- #define VirtFuncSpawn 0
- #define VirtFuncTakeDamage 12
- #elif __linux__
- #define VirtFuncSpawn 2
- #define VirtFuncTakeDamage 14
- #endif
- #ifdef _WIN32
- #define PrivateToEdict(pPrivate) (*(entvars_t **)((char*)pPrivate + 4))->pContainingEntity
- #elif __linux__
- #define PrivateToEdict(pPrivate) (*(entvars_t **)pPrivate)->pContainingEntity
- #endif
- plugin_info_t Plugin_info =
- {
- META_INTERFACE_VERSION, // ifvers
- "WPMG", // name
- "Alpha", // version
- "2011/11/7", // date
- "WPMG Team", // author
- "http://www.wpmg.ru", // url
- "WPMG", // logtag, all caps please
- PT_ANYTIME, // (when) loadable
- PT_ANYPAUSE // (when) unloadable
- };
- meta_globals_t *gpMetaGlobals;
- mutil_funcs_t *gpMetaUtilFuncs;
- enginefuncs_t g_engfuncs;
- globalvars_t *gpGlobals;
- bool g_bActivated = false;
- bool g_bInitialized = false;
- void *pOrigFuncSpawn = NULL;
- void *pOrigFuncTakeDamage = NULL;
- void print_srvconsole(char *fmt, ...)
- {
- va_list argptr;
- static char string[384];
- va_start(argptr, fmt);
- vsnprintf(string, sizeof(string) - 1, fmt, argptr);
- string[sizeof(string) - 1] = '\0';
- va_end(argptr);
- SERVER_PRINT(string);
- }
- #ifdef _WIN32
- void __fastcall HookSpawn(void *pthis)
- #elif __linux__
- void HookSpawn(void *pthis)
- #endif
- {
- print_srvconsole("::Spawn(void) %d prehook!\n", ENTINDEX(PrivateToEdict(pthis)));
- #ifdef _WIN32
- reinterpret_cast<int (__fastcall *)(void *, int)>(pOrigFuncSpawn)(pthis, 0);
- #elif __linux__
- reinterpret_cast<int (*)(void *)>(pOrigFuncSpawn)(pthis);
- #endif
- SERVER_PRINT("::Spawn(void) posthook!\n");
- }
- #ifdef _WIN32
- int __fastcall HookTakeDamage(void *pthis, int i, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamage)
- #elif __linux__
- int HookTakeDamage(void *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamage)
- #endif
- {
- SERVER_PRINT("::TakeDamage(int) prehook!\n");
- #ifdef _WIN32
- int iOrigRet = reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *, entvars_t *, float, int)>(pOrigFuncTakeDamage)(pthis, 0, pevInflictor, pevAttacker, flDamage, bitsDamage);
- #elif __linux__
- int iOrigRet = reinterpret_cast<int (*)(void *, entvars_t *, entvars_t *, float, int)>(pOrigFuncTakeDamage)(pthis, pevInflictor, pevAttacker, flDamage, bitsDamage);
- #endif
- SERVER_PRINT("::TakeDamage(int) posthook!\n");
- return iOrigRet;
- }
- void MakeHookSpawn()
- {
- edict_t *pEdict = CREATE_ENTITY();
- CALL_GAME_ENTITY(PLID, "player", &pEdict->v);
- if (pEdict->pvPrivateData == NULL)
- {
- REMOVE_ENTITY(pEdict);
- return;
- }
- #ifdef _WIN32
- void **vtable = *((void***)((char*)pEdict->pvPrivateData));
- #elif __linux__
- void **vtable = *((void***)(((char*)pEdict->pvPrivateData) + 0x94));
- #endif
- REMOVE_ENTITY(pEdict);
- if(vtable == NULL)
- return;
- int **ivtable = (int **)vtable;
- pOrigFuncSpawn = (void *)ivtable[VirtFuncSpawn];
- #ifdef _WIN32
- DWORD OldFlags;
- VirtualProtect(&ivtable[VirtFuncSpawn], sizeof(int *), PAGE_READWRITE, &OldFlags);
- #elif __linux__
- mprotect(&ivtable[VirtFuncSpawn], sizeof(int*), PROT_READ | PROT_WRITE);
- #endif
- ivtable[VirtFuncSpawn] = (int *)HookSpawn;
- }
- void MakeHookTakeDamage()
- {
- edict_t *pEdict = CREATE_ENTITY();
- CALL_GAME_ENTITY(PLID, "player", &pEdict->v);
- if (pEdict->pvPrivateData == NULL)
- {
- REMOVE_ENTITY(pEdict);
- return;
- }
- #ifdef _WIN32
- void **vtable = *((void***)((char*)pEdict->pvPrivateData));
- #elif __linux__
- void **vtable = *((void***)(((char*)pEdict->pvPrivateData) + 0x94));
- #endif
- REMOVE_ENTITY(pEdict);
- if(vtable == NULL)
- return;
- int **ivtable = (int **)vtable;
- pOrigFuncTakeDamage = (void *)ivtable[VirtFuncTakeDamage];
- #ifdef _WIN32
- DWORD OldFlags;
- VirtualProtect(&ivtable[VirtFuncTakeDamage], sizeof(int *), PAGE_READWRITE, &OldFlags);
- #elif __linux__
- mprotect(&ivtable[VirtFuncTakeDamage], sizeof(int*), PROT_READ | PROT_WRITE);
- #endif
- ivtable[VirtFuncTakeDamage] = (int *)HookTakeDamage;
- }
- void ServerActivatePost(edict_t *pEdictList, int edictCount, int clientMax)
- {
- if (g_bActivated)
- RETURN_META(MRES_IGNORED);
- MakeHookSpawn();
- MakeHookTakeDamage();
- g_bActivated = true;
- RETURN_META(MRES_IGNORED);
- }
- void ServerDeactivatePost()
- {
- if (!g_bInitialized)
- RETURN_META(MRES_IGNORED);
- g_bInitialized = false;
- RETURN_META(MRES_IGNORED);
- }
- void ClientCommandPost(edict_t *pEntity)
- {
- const char *szArg;
- szArg = CMD_ARGV(0);
- if (stricmp(szArg, "say"))
- RETURN_META(MRES_IGNORED);
- szArg = CMD_ARGV(1);
- if (stricmp(szArg, "/damage"))
- RETURN_META(MRES_IGNORED);
- #ifdef _WIN32
- reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *, entvars_t *, float, int)>((*((void***)((char*)pEntity->pvPrivateData)))[VirtFuncTakeDamage])(pEntity->pvPrivateData, 0, &(pEntity->v), &(pEntity->v), 50.0, DMG_SLASH);
- #elif defined __linux__
- reinterpret_cast<int (*)(void *, entvars_t *, entvars_t *, float, int)>((*((void***)(((char*)pEntity->pvPrivateData) + 0x94)))[VirtFuncTakeDamage])(pEntity->pvPrivateData, &(pEntity->v), &(pEntity->v), 50.0, DMG_SLASH);
- #endif
- RETURN_META(MRES_IGNORED);
- }
- int SpawnPre(edict_t *pEnt)
- {
- if (g_bInitialized)
- RETURN_META_VALUE(MRES_IGNORED, 0);
- g_bActivated = false;
- g_bInitialized = true;
- RETURN_META_VALUE(MRES_IGNORED, 0);
- }
- C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
- {
- gpMetaUtilFuncs = pMetaUtilFuncs;
- *pPlugInfo = &Plugin_info;
- return(TRUE);
- }
- static META_FUNCTIONS gMetaFunctionTable;
- C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs)
- {
- gpMetaGlobals = pMGlobals;
- gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
- gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
- memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
- return(TRUE);
- }
- #ifdef __linux__
- // linux prototype
- C_DLLEXPORT void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
- {
- #else
- #ifdef _MSC_VER
- // MSVC: Simulate __stdcall calling convention
- C_DLLEXPORT __declspec(naked) void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
- {
- __asm // Prolog
- {
- // Save ebp
- push ebp
- // Set stack frame pointer
- mov ebp, esp
- // Allocate space for local variables
- // The MSVC compiler gives us the needed size in __LOCAL_SIZE.
- sub esp, __LOCAL_SIZE
- // Push registers
- push ebx
- push esi
- push edi
- }
- #else // _MSC_VER
- #ifdef __GNUC__
- // GCC can also work with this
- C_DLLEXPORT void __stdcall GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
- {
- #else // __GNUC__
- // compiler not known
- #error There is no support (yet) for your compiler. Please use MSVC or GCC compilers or contact the AMX Mod X dev team.
- #endif // __GNUC__
- #endif // _MSC_VER
- #endif // __linux__
- // ** Function core <--
- memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
- gpGlobals = pGlobals;
- // --> ** Function core
- #ifdef _MSC_VER
- // Epilog
- if (sizeof(int*) == 8)
- { // 64 bit
- __asm
- {
- // Pop registers
- pop edi
- pop esi
- pop ebx
- // Restore stack frame pointer
- mov esp, ebp
- // Restore ebp
- pop ebp
- // 2 * sizeof(int*) = 16 on 64 bit
- ret 16
- }
- }
- else
- { // 32 bit
- __asm
- {
- // Pop registers
- pop edi
- pop esi
- pop ebx
- // Restore stack frame pointer
- mov esp, ebp
- // Restore ebp
- pop ebp
- // 2 * sizeof(int*) = 8 on 32 bit
- ret 8
- }
- }
- #endif // #ifdef _MSC_VER
- }
- DLL_FUNCTIONS gFunctionTable;
- C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
- {
- memset(&gFunctionTable, 0, sizeof(DLL_FUNCTIONS));
- gFunctionTable.pfnSpawn = SpawnPre;
- memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
- return 1;
- }
- DLL_FUNCTIONS gFunctionTable_Post;
- C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
- {
- memset(&gFunctionTable_Post, 0, sizeof(DLL_FUNCTIONS));
- gFunctionTable_Post.pfnServerActivate = ServerActivatePost;
- gFunctionTable_Post.pfnServerDeactivate = ServerDeactivatePost;
- gFunctionTable_Post.pfnClientCommand = ClientCommandPost;
- memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement