Added a few more calls (+macros)

Added support for game dll func hooking
Fixed table pointer...
This commit is contained in:
Steve Dudenhoeffer 2004-08-06 00:56:48 +00:00
parent 7f41ac3410
commit 2cd6ea9de3
6 changed files with 229 additions and 43 deletions

View File

@ -7,6 +7,7 @@ void OnAmxxAttach()
MF_AddNatives(engfunc_natives);
MF_AddNatives(dllfunc_natives);
MF_AddNatives(pev_natives);
MF_AddNatives(forward_natives);
}
// sawce: Do not null out the forward for ServerActivate. It's required for the INDEXENT() fix. (I don't think ServerActivate is planned on being forwarded anyway)

View File

@ -23,9 +23,18 @@ inline edict_t* INDEXENT2( int iEdictNum )
extern AMX_NATIVE_INFO engfunc_natives[];
extern AMX_NATIVE_INFO dllfunc_natives[];
extern AMX_NATIVE_INFO pev_natives[];
extern AMX_NATIVE_INFO forward_natives[];
extern TraceResult g_tr;
/* Wouldnt modifying the table AFTER it's memcpy'd be ... pointless?
extern enginefuncs_t g_EngineFuncs_Table;
extern enginefuncs_t g_EngineFuncs_Post_Table;
*/
// mark down pointers when the calls are made instead (this means amxxmodule.cpp needs to be changed slightly for this module)
extern DLL_FUNCTIONS *g_pFunctionTable;
extern DLL_FUNCTIONS *g_pFunctionTable_Post;
extern enginefuncs_t *g_pengfuncsTable;
extern enginefuncs_t *g_pengfuncsTable_Post;
#endif //_FAKEMETA_INCLUDE_H

View File

@ -12,12 +12,72 @@ const char *mlStringResult;
int retType = 0;
int lastFmRes = FMRES_IGNORED;
#define SIMPLE_INT_HOOK_STRING(call) \
int call (char *s) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), s)); \
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult); \
}
#define SIMPLE_INT_HOOK_CONSTSTRING(call) \
int call (const char *s) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), s)); \
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult); \
}
#define SIMPLE_VOID_HOOK_EDICT(call) \
void call (edict_t *ent) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), ENTINDEX(ent))); \
RETURN_META(mswi(lastFmRes)); \
}
#define SIMPLE_VOID_HOOK_EDICT_EDICT(call) \
void call (edict_t *ent,edict_t *entb) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), ENTINDEX(ent), ENTINDEX(entb))); \
RETURN_META(mswi(lastFmRes)); \
}
#define SIMPLE_VOID_HOOK_VOID(call) \
void call () \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i))); \
RETURN_META(mswi(lastFmRes)); \
}
#define SIMPLE_INT_HOOK_EDICT(call) \
int call (edict_t *pent) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), ENTINDEX(pent))); \
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult); \
}
#define SIMPLE_INT_HOOK_INT(call) \
int call (int v) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), v)); \
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult); \
}
#define SIMPLE_INT_HOOK_VOID(call) \
int call () \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i))); \
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult); \
}
#define ENGHOOK(pfnCall) \
if (engtable->pfn##pfnCall == NULL) \
engtable->pfn##pfnCall = pfnCall
#define DLLHOOK(pfnCall) \
if (dlltable->pfn##pfnCall == NULL) \
dlltable->pfn##pfnCall = pfnCall
#define FM_ENG_HANDLE(pfnCall, pfnArgs) \
register unsigned int i = 0; \
clfm(); \
@ -93,18 +153,11 @@ static cell AMX_NATIVE_CALL fm_return(AMX *amx, cell *params)
}
// pfnPrecacheModel
SIMPLE_INT_HOOK_STRING(PrecacheModel);
int PrecacheModel(char *s)
{
FM_ENG_HANDLE(FM_PrecacheModel, (Engine[FM_PrecacheModel].at(i), s));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
int PrecacheSound(char *s)
{
FM_ENG_HANDLE(FM_PrecacheSound, (Engine[FM_PrecacheSound].at(i), s));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
// pfnPrecacheSound
SIMPLE_INT_HOOK_STRING(PrecacheSound);
void SetModel(edict_t *e, const char *m)
{
@ -112,17 +165,11 @@ void SetModel(edict_t *e, const char *m)
RETURN_META(mswi(lastFmRes));
}
int ModelIndex(const char *m)
{
FM_ENG_HANDLE(FM_ModelIndex, (Engine[FM_ModelIndex].at(i), m));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
// pfnModelIndex
SIMPLE_INT_HOOK_CONSTSTRING(ModelIndex);
int ModelFrames(int modelIndex)
{
FM_ENG_HANDLE(FM_ModelIndex, (Engine[FM_ModelIndex].at(i), modelIndex));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
// pfnModelFrames
SIMPLE_INT_HOOK_INT(ModelFrames);
void SetSize(edict_t *e, const float *rgflMin, const float *rgflMax)
{
@ -166,34 +213,103 @@ void MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType)
RETURN_META(mswi(lastFmRes));
}
void ChangeYaw(edict_t *ent)
{
FM_ENG_HANDLE(FM_ChangeYaw, (Engine[FM_ChangeYaw].at(i), ENTINDEX(ent)));
RETURN_META(mswi(lastFmRes));
}
void ChangePitch(edict_t *ent)
{
FM_ENG_HANDLE(FM_ChangePitch, (Engine[FM_ChangePitch].at(i), ENTINDEX(ent)));
RETURN_META(mswi(lastFmRes));
}
edict_t *FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue)
{
FM_ENG_HANDLE(FM_FindEntityByString, (Engine[FM_FindEntityByString].at(i), ENTINDEX(pEdictStartSearchAfter), pszField, pszValue));
RETURN_META_VALUE(mswi(lastFmRes), INDEXENT2((int)mlCellResult));
}
// pfnGetEntityIllum
SIMPLE_INT_HOOK_EDICT(GetEntityIllum);
int GetEntityIllum(edict_t *pent)
{
FM_ENG_HANDLE(FM_ChangePitch, (Engine[FM_ChangePitch].at(i), ENTINDEX(pent)));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
// pfnChangeYaw
SIMPLE_VOID_HOOK_EDICT(ChangeYaw);
// pfnChangePitch
SIMPLE_VOID_HOOK_EDICT(ChangePitch);
// pfnRemoveEntity
SIMPLE_VOID_HOOK_EDICT(RemoveEntity);
// pfnMakeStatic
SIMPLE_VOID_HOOK_EDICT(MakeStatic);
// pfnEntIsOnFloor
SIMPLE_INT_HOOK_EDICT(EntIsOnFloor);
// pfnDropToFloor
SIMPLE_INT_HOOK_EDICT(DropToFloor);
// pfnNumberOfEntities
SIMPLE_INT_HOOK_VOID(NumberOfEntities);
/*
* Beginning of Game DLL hooks
*/
// pfnSpawn
SIMPLE_INT_HOOK_EDICT(Spawn);
// pfnThink
SIMPLE_VOID_HOOK_EDICT(Think);
// pfnUse
SIMPLE_VOID_HOOK_EDICT_EDICT(Use);
// pfnTouch
SIMPLE_VOID_HOOK_EDICT_EDICT(Touch);
// pfnBlocked
SIMPLE_VOID_HOOK_EDICT_EDICT(Blocked);
// pfnSetAbsBox
SIMPLE_VOID_HOOK_EDICT(SetAbsBox);
// pfnClientDisconnect
SIMPLE_VOID_HOOK_EDICT(ClientDisconnect);
// pfnClientPutInServer
SIMPLE_VOID_HOOK_EDICT(ClientPutInServer);
// pfnClientKill
SIMPLE_VOID_HOOK_EDICT(ClientKill);
// pfnClientCommand
SIMPLE_VOID_HOOK_EDICT(ClientCommand);
// pfnServerDeactivate
SIMPLE_VOID_HOOK_VOID(ServerDeactivate);
// pfnPlayerPreThink
SIMPLE_VOID_HOOK_EDICT(PlayerPreThink);
// pfnPlayerPostThink
SIMPLE_VOID_HOOK_EDICT(PlayerPostThink);
// pfnStartFrame
SIMPLE_VOID_HOOK_VOID(StartFrame);
// pfnParmsNewLevel
SIMPLE_VOID_HOOK_VOID(ParmsNewLevel);
// pfnParmsChangeLevel
SIMPLE_VOID_HOOK_VOID(ParmsChangeLevel);
// pfnSpectatorConnect
SIMPLE_VOID_HOOK_EDICT(SpectatorConnect);
// pfnSpectatorDisconnect
SIMPLE_VOID_HOOK_EDICT(SpectatorDisconnect);
// pfnSpectatorThink
SIMPLE_VOID_HOOK_EDICT(SpectatorThink);
static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
{
int func = params[1];
int post = params[2];
// You originally had both post coming from params[2] AND the function name. I've moved post to 3.
int post = params[3];
if (func > ENGFUNC_NUM || func < 1)
{
MF_RaiseAmxError(amx, AMX_ERR_NATIVE);
@ -205,10 +321,18 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
enginefuncs_t *engtable;
DLL_FUNCTIONS *dlltable;
if (post)
engtable = &g_EngineFuncs_Table;
{
engtable = g_pengfuncsTable_Post;
dlltable = g_pFunctionTable_Post;
}
else
engtable = &g_EngineFuncs_Post_Table;
{
engtable = g_pengfuncsTable;
dlltable = g_pFunctionTable;
}
switch (func)
{
@ -288,18 +412,22 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
break;
case FM_RemoveEntity:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
ENGHOOK(RemoveEntity);
break;
case FM_CreateNamedEntity:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_STRING, FP_DONE);
break;
case FM_MakeStatic:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
ENGHOOK(MakeStatic);
break;
case FM_EntIsOnFloor:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
ENGHOOK(EntIsOnFloor);
break;
case FM_DropToFloor:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
ENGHOOK(DropToFloor);
break;
case FM_WalkMove:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_FLOAT, FP_FLOAT, FP_CELL, FP_DONE);
@ -393,6 +521,7 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
break;
case FM_NumberOfEntities:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
ENGHOOK(NumberOfEntities);
break;
case FM_StaticDecal:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_ARRAY, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
@ -466,6 +595,11 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
case FM_SetClientKeyValue:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_STRING, FP_STRING, FP_STRING, FP_DONE);
break;
/*
* Begin of DLLFuncs
*/
//DLLFunc_GameInit, // void) ( void );
case FM_GameInit:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
@ -473,22 +607,27 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
//DLLFunc_Spawn, // int ) ( edict_t *pent );
case FM_Spawn:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(Spawn);
break;
//DLLFunc_Think, // void ) ( edict_t *pent );
case FM_Think:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(Think);
break;
//DLLFunc_Use, // void ) ( edict_t *pentUsed, edict_t *pentOther );
case FM_Use:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(Use);
break;
//DLLFunc_Touch, // void ) ( edict_t *pentTouched, edict_t *pentOther );
case FM_Touch:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(Touch);
break;
//DLLFunc_Blocked, // void ) ( edict_t *pentBlocked, edict_t *pentOther );
case FM_Blocked:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(Blocked);
break;
//DLLFunc_KeyValue, // void ) ( edict_t *pentKeyvalue, KeyValueData *pkvd );
/*
@ -499,6 +638,7 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
//DLLFunc_SetAbsBox, // void ) ( edict_t *pent );
case FM_SetAbsBox:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(SetAbsBox);
break;
//DLLFunc_ClientConnect, // bool) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] );
@ -508,45 +648,55 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
//DLLFunc_ClientDisconnect, // void ) ( edict_t *pEntity );
case FM_ClientDisconnect:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(ClientDisconnect);
break;
//DLLFunc_ClientKill, // void ) ( edict_t *pEntity );
case FM_ClientKill:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(ClientKill);
break;
//DLLFunc_ClientPutInServer, // void ) ( edict_t *pEntity );
case FM_ClientPutInServer:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(ClientPutInServer);
break;
//DLLFunc_ClientCommand, // void ) ( edict_t *pEntity );
case FM_ClientCommand:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(ClientCommand);
break;
//DLLFunc_ServerDeactivate, // void) ( void );
case FM_ServerDeactivate:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
DLLHOOK(ServerDeactivate);
break;
//DLLFunc_PlayerPreThink, // void ) ( edict_t *pEntity );
case FM_PlayerPreThink:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(PlayerPreThink);
break;
//DLLFunc_PlayerPostThink, // void ) ( edict_t *pEntity );
case FM_PlayerPostThink:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(PlayerPostThink);
break;
//DLLFunc_StartFrame, // void ) ( void );
case FM_StartFrame:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
DLLHOOK(StartFrame);
break;
//DLLFunc_ParmsNewLevel, // void ) ( void );
case FM_ParmsNewLevel:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
DLLHOOK(ParmsNewLevel);
break;
//DLLFunc_ParmsChangeLevel, // void ) ( void );
case FM_ParmsChangeLevel:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_DONE);
DLLHOOK(ParmsChangeLevel);
break;
// Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life
@ -559,14 +709,17 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
//DLLFunc_SpectatorConnect, // void) ( edict_t *pEntity );
case FM_SpectatorConnect:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(SpectatorConnect);
break;
//DLLFunc_SpectatorDisconnect, // void ) ( edict_t *pEntity );
case FM_SpectatorDisconnect:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(SpectatorDisconnect);
break;
//DLLFunc_SpectatorThink, // void ) ( edict_t *pEntity );
case FM_SpectatorThink:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(SpectatorThink);
break;
// Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint.
@ -622,3 +775,8 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
return 1;
}
AMX_NATIVE_INFO forward_natives[] = {
{ "register_forward", register_forward },
{ NULL, NULL }
};

View File

@ -89,6 +89,9 @@ enum {
FM_InfoKeyValue, // char* ) (char *infobuffer, char *key);
FM_SetKeyValue, // void ) (char *infobuffer, char *key, char *value);
FM_SetClientKeyValue, // void ) (int clientIndex, char *infobuffer, char *key, char *value);
FM_GameInit, // void) ( void );
FM_Spawn, // int ) ( edict_t *pent );
FM_Think, // void ) ( edict_t *pent );

View File

@ -39,10 +39,18 @@
#include <stdio.h>
#include "amxxmodule.h"
DLL_FUNCTIONS *g_pFunctionTable;
DLL_FUNCTIONS *g_pFunctionTable_Post;
enginefuncs_t *g_pengfuncsTable;
enginefuncs_t *g_pengfuncsTable_Post;
/************* METAMOD SUPPORT *************/
#ifdef USE_METAMOD
enginefuncs_t g_engfuncs;
DLL_FUNCTIONS *gameDLLFunc;
globalvars_t *gpGlobals;
// GetEntityAPI2 functions
@ -2114,6 +2122,8 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
return(FALSE);
}
memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof(DLL_FUNCTIONS));
// Mark down the pointer to this mod's function tables...
g_pFunctionTable=pFunctionTable;
return(TRUE);
}
@ -2131,7 +2141,8 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
return(FALSE);
}
memcpy( pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) );
// Mark down the pointer to this mod's function tables...
g_pFunctionTable_Post=pFunctionTable;
return(TRUE);
}
@ -2154,6 +2165,8 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
return(FALSE);
}
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Table, sizeof(enginefuncs_t));
// Mark down the pointer to this mod's function tables...
g_pengfuncsTable=pengfuncsFromEngine;
return TRUE;
}
@ -2171,6 +2184,8 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
return(FALSE);
}
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t));
// Mark down the pointer to this mod's function tables...
g_pengfuncsTable_Post=pengfuncsFromEngine;
return TRUE;
}

View File

@ -74,7 +74,7 @@
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
// #define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
#define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
// #define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */