diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 5f3b3e36..0a24919e 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -2806,6 +2806,14 @@ static cell AMX_NATIVE_CALL precache_generic(AMX *amx, cell *params) return PRECACHE_GENERIC((char*)STRING(ALLOC_STRING(sptemp))); } +static cell AMX_NATIVE_CALL precache_event(AMX *amx, cell *params) +{ + int len; + char *sptemp = format_amxstring(amx, params, 2, len); + + return PRECACHE_EVENT(params[1], (char*)STRING(ALLOC_STRING(sptemp))); +} + static cell AMX_NATIVE_CALL random_float(AMX *amx, cell *params) /* 2 param */ { float one = amx_ctof(params[1]); diff --git a/modules/engine/AMBuilder b/modules/engine/AMBuilder index e94a3797..12715fb0 100644 --- a/modules/engine/AMBuilder +++ b/modules/engine/AMBuilder @@ -14,6 +14,9 @@ binary.sources = [ 'entity.cpp', 'globals.cpp', 'forwards.cpp', + '../../public/memtools/MemoryUtils.cpp', + '../../public/memtools/CDetour/detours.cpp', + '../../public/memtools/CDetour/asm/asm.c', ] if builder.target_platform == 'windows': diff --git a/modules/engine/Makefile b/modules/engine/Makefile index c7044492..1797f04b 100644 --- a/modules/engine/Makefile +++ b/modules/engine/Makefile @@ -30,7 +30,7 @@ CPP_OSX = clang LINK = -INCLUDE = -I. -I$(PUBLIC_ROOT) -I$(PUBLIC_ROOT)/sdk -I$(PUBLIC_ROOT)/amtl \ +INCLUDE = -I. -I$(PUBLIC_ROOT) -I$(PUBLIC_ROOT)/sdk -I$(PUBLIC_ROOT)/memtools -I$(PUBLIC_ROOT)/memtools/CDetour -I$(PUBLIC_ROOT)/memtools/CDetour/asm -I$(PUBLIC_ROOT)/amtl \ -I$(HLSDK) -I$(HLSDK)/public -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/pm_shared\ -I$(MM_ROOT) @@ -108,6 +108,9 @@ $(BIN_DIR)/%.o: %.cpp all: mkdir -p $(BIN_DIR) ln -sf $(PUBLIC_ROOT)/sdk/amxxmodule.cpp + ln -sf $(PUBLIC_ROOT)/memtools/MemoryUtils.cpp + ln -sf $(PUBLIC_ROOT)/memtools/CDetour/detours.cpp + ln -sf $(PUBLIC_ROOT)/memtools/CDetour/asm/asm.c $(MAKE) -f $(MAKEFILE_NAME) $(PROJECT) $(PROJECT): $(OBJ_BIN) diff --git a/modules/engine/amxxapi.cpp b/modules/engine/amxxapi.cpp index b21ab8cf..3be75992 100644 --- a/modules/engine/amxxapi.cpp +++ b/modules/engine/amxxapi.cpp @@ -14,6 +14,10 @@ #include "engine.h" BOOL CheckForPublic(const char *publicname); +void CreateDetours(); +void DestroyDetours(); + +CDetour *LightStyleDetour = NULL; edict_t *g_player_edicts[33]; @@ -57,8 +61,14 @@ void OnAmxxAttach() MF_AddNatives(global_Natives); memset(glinfo.szLastLights, 0x0, 128); memset(glinfo.szRealLights, 0x0, 128); - glinfo.fNextLights = 0; glinfo.bCheckLights = false; + + CreateDetours(); +} + +void OnAmxxDetach() +{ + DestroyDetours(); } void OnPluginsLoaded() @@ -197,7 +207,6 @@ void ServerDeactivate() memset(glinfo.szLastLights, 0x0, 128); memset(glinfo.szRealLights, 0x0, 128); glinfo.bCheckLights = false; - glinfo.fNextLights = 0; // Reset all forwarding function tables (so that forwards won't be called before plugins are initialized) g_pFunctionTable->pfnAddToFullPack=NULL; @@ -211,7 +220,6 @@ void ServerDeactivate() g_pFunctionTable->pfnThink=NULL; // "pfn_think", "register_think" g_pFunctionTable->pfnStartFrame=NULL; // "server_frame","ServerFrame" g_pFunctionTable->pfnTouch=NULL; // "pfn_touch","vexd_pfntouch" - g_pFunctionTable_Post->pfnStartFrame = NULL; // "set_lights" ClearHooks(); @@ -226,12 +234,27 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) RETURN_META(MRES_IGNORED); } -void LightStyle(int style, const char *val) { - if (!style) { +DETOUR_DECL_STATIC2(LightStyle, void, int, style, const char *, val) // void (*pfnLightStyle) (int style, const char* val); +{ + DETOUR_STATIC_CALL(LightStyle)(style, val); + + if (!style && strcmp(val, glinfo.szRealLights)) { memset(glinfo.szRealLights, 0x0, 128); - memcpy(glinfo.szRealLights, val, strlen(val)); + memcpy(glinfo.szRealLights, val, ke::Min(strlen(val), (size_t)127)); } + if (glinfo.bCheckLights && strcmp(val, glinfo.szLastLights)) + g_pFunctionTable_Post->pfnStartFrame = StartFrame_Post; +} + +void StartFrame_Post() +{ + g_pFunctionTable_Post->pfnStartFrame = NULL; + + LightStyleDetour->DisableDetour(); + LIGHT_STYLE(0, glinfo.szLastLights); + LightStyleDetour->EnableDetour(); + RETURN_META(MRES_IGNORED); } @@ -255,3 +278,13 @@ BOOL CheckForPublic(const char *publicname) return FALSE; // no public found in any loaded script } + +void CreateDetours() +{ + LightStyleDetour = DETOUR_CREATE_STATIC_FIXED(LightStyle, (void*)(g_engfuncs.pfnLightStyle)); +} + +void DestroyDetours() +{ + LightStyleDetour->Destroy(); +} \ No newline at end of file diff --git a/modules/engine/engine.cpp b/modules/engine/engine.cpp index 042dfa8e..666d1f9a 100644 --- a/modules/engine/engine.cpp +++ b/modules/engine/engine.cpp @@ -55,6 +55,27 @@ static cell AMX_NATIVE_CALL register_think(AMX *amx, cell *params) return p->Forward; } +static cell AMX_NATIVE_CALL unregister_think(AMX *amx, cell *params) +{ + int fwd = params[1]; + for (size_t i = 0; i < Thinks.length(); ++i) + { + EntClass *p = Thinks.at(i); + if (p->Forward == fwd) + { + Thinks.remove(i); + delete p; + + if (!Thinks.length()) + g_pFunctionTable->pfnThink = NULL; + + return 1; + } + } + + return 0; +} + static cell AMX_NATIVE_CALL register_impulse(AMX *amx, cell *params) { int len; @@ -72,6 +93,27 @@ static cell AMX_NATIVE_CALL register_impulse(AMX *amx, cell *params) return p->Forward; } +static cell AMX_NATIVE_CALL unregister_impulse(AMX *amx, cell *params) +{ + int fwd = params[1]; + for (size_t i = 0; i < Impulses.length(); ++i) + { + Impulse *p = Impulses.at(i); + if (p->Forward == fwd) + { + Impulses.remove(i); + delete p; + + if (!Impulses.length()) + g_pFunctionTable->pfnCmdStart = NULL; + + return 1; + } + } + + return 0; +} + static cell AMX_NATIVE_CALL register_touch(AMX *amx, cell *params) { int len; @@ -102,6 +144,27 @@ static cell AMX_NATIVE_CALL register_touch(AMX *amx, cell *params) return p->Forward; } +static cell AMX_NATIVE_CALL unregister_touch(AMX *amx, cell *params) +{ + int fwd = params[1]; + for (size_t i = 0; i < Touches.length(); ++i) + { + Touch *p = Touches.at(i); + if (p->Forward == fwd) + { + Touches.remove(i); + delete p; + + if (!Touches.length()) + g_pFunctionTable->pfnTouch = NULL; + + return 1; + } + } + + return 0; +} + static cell AMX_NATIVE_CALL halflife_time(AMX *amx, cell *params) { REAL fVal = gpGlobals->time; @@ -206,6 +269,7 @@ static cell AMX_NATIVE_CALL PointContents(AMX *amx, cell *params) static cell AMX_NATIVE_CALL trace_normal(AMX *amx, cell *params) { int iEnt = params[1]; + CHECK_ENTITY(iEnt); cell *cStart = MF_GetAmxAddr(amx, params[2]); cell *cEnd = MF_GetAmxAddr(amx, params[3]); @@ -221,14 +285,13 @@ static cell AMX_NATIVE_CALL trace_normal(AMX *amx, cell *params) Vector vStart = Vector(fStartX, fStartY, fStartZ); Vector vEnd = Vector(fEndX, fEndY, fEndZ); - TraceResult tr; - TRACE_LINE(vStart, vEnd, dont_ignore_monsters, INDEXENT2(iEnt), &tr); + TRACE_LINE(vStart, vEnd, dont_ignore_monsters, INDEXENT2(iEnt), &g_tr); - vRet[0] = amx_ftoc(tr.vecPlaneNormal.x); - vRet[1] = amx_ftoc(tr.vecPlaneNormal.y); - vRet[2] = amx_ftoc(tr.vecPlaneNormal.z); + vRet[0] = amx_ftoc(g_tr.vecPlaneNormal.x); + vRet[1] = amx_ftoc(g_tr.vecPlaneNormal.y); + vRet[2] = amx_ftoc(g_tr.vecPlaneNormal.z); - if (tr.flFraction >= 1.0) + if (g_tr.flFraction >= 1.0) return 0; return 1; @@ -237,6 +300,9 @@ static cell AMX_NATIVE_CALL trace_normal(AMX *amx, cell *params) static cell AMX_NATIVE_CALL trace_line(AMX *amx, cell *params) { int iEnt = params[1]; + if (iEnt != -1) { + CHECK_ENTITY(iEnt); + } cell *cStart = MF_GetAmxAddr(amx, params[2]); cell *cEnd = MF_GetAmxAddr(amx, params[3]); @@ -251,19 +317,17 @@ static cell AMX_NATIVE_CALL trace_line(AMX *amx, cell *params) Vector vStart = Vector(fStartX, fStartY, fStartZ); Vector vEnd = Vector(fEndX, fEndY, fEndZ); - - TraceResult tr; - + if (iEnt == -1) - TRACE_LINE(vStart, vEnd, ignore_monsters, NULL, &tr); + TRACE_LINE(vStart, vEnd, ignore_monsters, NULL, &g_tr); else - TRACE_LINE(vStart, vEnd, dont_ignore_monsters, INDEXENT2(iEnt), &tr); + TRACE_LINE(vStart, vEnd, dont_ignore_monsters, INDEXENT2(iEnt), &g_tr); - edict_t *pHit = tr.pHit; + edict_t *pHit = g_tr.pHit; - vRet[0] = amx_ftoc(tr.vecEndPos.x); - vRet[1] = amx_ftoc(tr.vecEndPos.y); - vRet[2] = amx_ftoc(tr.vecEndPos.z); + vRet[0] = amx_ftoc(g_tr.vecEndPos.x); + vRet[1] = amx_ftoc(g_tr.vecEndPos.y); + vRet[2] = amx_ftoc(g_tr.vecEndPos.z); if (FNullEnt(pHit)) return 0; @@ -303,25 +367,17 @@ static cell AMX_NATIVE_CALL get_decal_index(AMX *amx, cell *params) return DECAL_INDEX(szDecal); } -static cell AMX_NATIVE_CALL precache_event(AMX *amx, cell *params) -{ - int len; - char *szEvent = MF_FormatAmxString(amx, params, 2, &len); - return PRECACHE_EVENT(params[1], (char *)STRING(ALLOC_STRING(szEvent))); - -} - static cell AMX_NATIVE_CALL get_info_keybuffer(AMX *amx, cell *params) { int iEnt = params[1]; - CHECK_ENTITY(iEnt); + if (iEnt != -1) { + CHECK_ENTITY(iEnt); + } - edict_t *e = INDEXENT2(iEnt); - - char *info = GETINFOKEYBUFFER(e); + char *info = GETINFOKEYBUFFER((iEnt == -1) ? NULL : INDEXENT2(iEnt)); - return MF_SetAmxString(amx, params[2], info, params[3]); + return MF_SetAmxStringUTF8Char(amx, params[2], info, strlen(info), params[3]); } //from jghg, who says it doesn't work @@ -346,6 +402,7 @@ static cell AMX_NATIVE_CALL attach_view(AMX *amx, cell *params) int iTargetIndex = params[2]; CHECK_ENTITY(iIndex); + CHECK_ENTITY(iTargetIndex); SET_VIEW(INDEXENT2(iIndex), INDEXENT2(iTargetIndex)); @@ -491,21 +548,20 @@ static cell AMX_NATIVE_CALL set_lights(AMX *amx, cell *params) { if (FStrEq(szLights, "#OFF")) { glinfo.bCheckLights = false; - g_pFunctionTable_Post->pfnStartFrame = NULL; memset(glinfo.szLastLights, 0x0, 128); - (g_engfuncs.pfnLightStyle)(0, glinfo.szRealLights); + LIGHT_STYLE(0, glinfo.szRealLights); return 1; } - g_pFunctionTable_Post->pfnStartFrame = StartFrame_Post; glinfo.bCheckLights = true; - //Reset LastLights + //Reset LastLights and store custom lighting memset(glinfo.szLastLights, 0x0, 128); - //Store the previous lighting. - memcpy(glinfo.szLastLights, szLights, strlen(szLights)); + memcpy(glinfo.szLastLights, szLights, ke::Min(iLength, 127)); - (g_engfuncs.pfnLightStyle)(0, szLights); + LightStyleDetour->DisableDetour(); + LIGHT_STYLE(0, szLights); + LightStyleDetour->EnableDetour(); // These make it so that players/weaponmodels look like whatever the lighting is // at. otherwise it would color players under the skybox to these values. @@ -519,26 +575,42 @@ static cell AMX_NATIVE_CALL set_lights(AMX *amx, cell *params) { //(mahnsawce) static cell AMX_NATIVE_CALL trace_hull(AMX *amx,cell *params) { + int iEnt = params[3]; + if (iEnt > 0) { + CHECK_ENTITY(iEnt); + } + int iResult=0; - TraceResult tr; - Vector vPos; + Vector vStart; + Vector vEnd; cell *vCell; vCell = MF_GetAmxAddr(amx, params[1]); - vPos.x = amx_ctof(vCell[0]); - vPos.y = amx_ctof(vCell[1]); - vPos.z = amx_ctof(vCell[2]); + vStart.x = amx_ctof(vCell[0]); + vStart.y = amx_ctof(vCell[1]); + vStart.z = amx_ctof(vCell[2]); - TRACE_HULL(vPos,vPos, params[4], params[2], params[3] > 0 ? INDEXENT2(params[3]) : 0 , &tr); + if (params[0] / sizeof(cell) >= 5 && (vCell = MF_GetAmxVectorNull(amx, params[5]))) + { - if (tr.fStartSolid) { + vEnd.x = amx_ctof(vCell[0]); + vEnd.y = amx_ctof(vCell[1]); + vEnd.z = amx_ctof(vCell[2]); + } + else + vEnd = vStart; + + + TRACE_HULL(vStart, vEnd, params[4], params[2], iEnt > 0 ? INDEXENT2(iEnt) : NULL, &g_tr); + + if (g_tr.fStartSolid) { iResult += 1; } - if (tr.fAllSolid) { + if (g_tr.fAllSolid) { iResult += 2; } - if (!tr.fInOpen) { + if (!g_tr.fInOpen) { iResult += 4; } return iResult; @@ -564,6 +636,7 @@ static cell AMX_NATIVE_CALL playback_event(AMX *amx, cell *params) int bparam1; int bparam2; flags = params[1]; + CHECK_ENTITY(params[2]); pInvoker=INDEXENT2(params[2]); eventindex=params[3]; delay=amx_ctof(params[4]); @@ -881,6 +954,10 @@ static cell AMX_NATIVE_CALL trace_forward(AMX *amx, cell *params) cell *cAngles = MF_GetAmxAddr(amx, params[2]); REAL fGive = amx_ctof(params[3]); int iIgnoreEnt = params[4]; + if (iIgnoreEnt != -1) { + CHECK_ENTITY(iIgnoreEnt); + } + cell *hitX = MF_GetAmxAddr(amx, params[5]); cell *hitY = MF_GetAmxAddr(amx, params[6]); cell *shortestDistance = MF_GetAmxAddr(amx, params[7]); @@ -971,7 +1048,6 @@ AMX_NATIVE_INFO engine_Natives[] = { {"set_speak", set_speak}, {"get_speak", get_speak}, - {"precache_event", precache_event}, {"playback_event", playback_event}, {"set_view", set_view}, @@ -985,10 +1061,12 @@ AMX_NATIVE_INFO engine_Natives[] = { {"get_usercmd", get_usercmd}, {"set_usercmd", set_usercmd}, - {"register_impulse", register_impulse}, {"register_think", register_think}, {"register_touch", register_touch}, + {"unregister_impulse", unregister_impulse}, + {"unregister_think", unregister_think}, + {"unregister_touch", unregister_touch}, {"eng_get_string", get_string}, {"is_in_viewcone", in_view_cone}, diff --git a/modules/engine/engine.h b/modules/engine/engine.h index d0415445..1b5337d5 100644 --- a/modules/engine/engine.h +++ b/modules/engine/engine.h @@ -25,6 +25,7 @@ #include "entity_state.h" #include #include +#include "CDetour/detours.h" extern DLL_FUNCTIONS *g_pFunctionTable; extern DLL_FUNCTIONS *g_pFunctionTable_Post; @@ -47,6 +48,8 @@ extern int DispatchUseForward; extern int VexdTouchForward; extern int VexdServerForward; +extern CDetour *LightStyleDetour; + #define AMS_OFFSET 0.01 #define GETINFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) @@ -118,7 +121,6 @@ struct PlayerInfo { }; struct GlobalInfo { - float fNextLights; char szLastLights[128]; char szRealLights[128]; bool bCheckLights; @@ -205,7 +207,7 @@ void StartFrame_Post(); MF_LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", x); \ return 0; \ } else { \ - if (x <= gpGlobals->maxClients) { \ + if (x > 0 && x <= gpGlobals->maxClients) { \ if (!MF_IsPlayerIngame(x)) { \ MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not in-game)", x); \ return 0; \ diff --git a/modules/engine/entity.cpp b/modules/engine/entity.cpp index c1f76491..4449c145 100644 --- a/modules/engine/entity.cpp +++ b/modules/engine/entity.cpp @@ -120,11 +120,17 @@ static cell AMX_NATIVE_CALL create_entity(AMX *amx, cell *params) static cell AMX_NATIVE_CALL remove_entity(AMX *amx, cell *params) { int id = params[1]; + if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d can not be removed", id); + return 0; + } + edict_t *pEnt = INDEXENT2(id); if (FNullEnt(pEnt)) return 0; - + REMOVE_ENTITY(pEnt); return 1; @@ -150,11 +156,7 @@ static cell AMX_NATIVE_CALL DispatchKeyValue(AMX *amx, cell *params) cell *cVal = MF_GetAmxAddr(amx, params[1]); int iValue = *cVal; - if (iValue != 0 && (FNullEnt(INDEXENT2(iValue)) || iValue < 0 || iValue > gpGlobals->maxEntities)) - { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", iValue); - return 0; - } + CHECK_ENTITY_SIMPLE(iValue); edict_t *pEntity = INDEXENT2(iValue); KeyValueData kvd; @@ -168,7 +170,13 @@ static cell AMX_NATIVE_CALL DispatchKeyValue(AMX *amx, cell *params) kvd.fHandled = 0; MDLL_KeyValue(pEntity, &kvd); - } else { + } else if (count == 2) { + if (!g_inKeyValue) + { + MF_LogError(amx, AMX_ERR_NATIVE, "DispatchKeyValue() with two arguments can only be used inside of pfn_keyvalue()"); + return 0; + } + int iLength; char *char1 = MF_GetAmxString(amx, params[1], 0, &iLength); char *char2 = MF_GetAmxString(amx, params[2], 1, &iLength); @@ -188,20 +196,21 @@ static cell AMX_NATIVE_CALL get_keyvalue(AMX *amx, cell *params) edict_t *pEntity = INDEXENT2(idx); int iLength=0; char *char1 = MF_GetAmxString(amx, params[2], 1, &iLength); - return MF_SetAmxString(amx, params[3], INFO_KEY_VALUE(INFO_KEY_BUFFER(pEntity),char1), params[4]); + char *val = INFO_KEY_VALUE(INFO_KEY_BUFFER(pEntity), char1); + return MF_SetAmxStringUTF8Char(amx, params[3], val, strlen(val), params[4]); } static cell AMX_NATIVE_CALL copy_keyvalue(AMX *amx, cell *params) { if (!g_inKeyValue) return 0; - + if (g_pkvd->szClassName) - MF_SetAmxString(amx, params[1], g_pkvd->szClassName, params[2]); + MF_SetAmxStringUTF8Char(amx, params[1], g_pkvd->szClassName, strlen(g_pkvd->szClassName), params[2]); if (g_pkvd->szKeyName) - MF_SetAmxString(amx, params[3], g_pkvd->szKeyName, params[4]); + MF_SetAmxStringUTF8Char(amx, params[3], g_pkvd->szKeyName, strlen(g_pkvd->szKeyName), params[4]); if (g_pkvd->szValue) - MF_SetAmxString(amx, params[5], g_pkvd->szValue, params[6]); + MF_SetAmxStringUTF8Char(amx, params[5], g_pkvd->szValue, strlen(g_pkvd->szValue), params[6]); return 1; } @@ -609,7 +618,6 @@ static cell AMX_NATIVE_CALL entity_get_int(AMX *amx, cell *params) iRetValue = pEnt->v.deadflag; break; default: - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid property %d", idx); return 0; break; } @@ -1057,7 +1065,7 @@ static cell AMX_NATIVE_CALL entity_set_string(AMX *amx, cell *params) return 1; } -static cell AMX_NATIVE_CALL entity_get_edict(AMX *amx, cell *params) +static cell AMX_NATIVE_CALL entity_get_edict2(AMX *amx, cell *params) { int iEnt = params[1]; int idx = params[2]; @@ -1103,16 +1111,26 @@ static cell AMX_NATIVE_CALL entity_get_edict(AMX *amx, cell *params) pRet = pEnt->v.euser4; break; default: - return 0; + return -1; break; } if (FNullEnt(pRet)) - return 0; + return -1; return ENTINDEX(pRet); } +static cell AMX_NATIVE_CALL entity_get_edict(AMX *amx, cell *params) +{ + cell res = entity_get_edict2(amx, params); + + if (res == -1) + res = 0; + + return res; +} + static cell AMX_NATIVE_CALL entity_set_edict(AMX *amx, cell *params) { int iEnt = params[1]; @@ -1320,6 +1338,7 @@ static cell AMX_NATIVE_CALL get_entity_pointer(AMX *amx, cell *params) // get_en static cell AMX_NATIVE_CALL find_ent_in_sphere(AMX *amx, cell *params) { int idx = params[1]; + CHECK_ENTITY_SIMPLE(idx); edict_t *pEnt = INDEXENT2(idx); cell *cAddr = MF_GetAmxAddr(amx, params[2]); @@ -1340,7 +1359,10 @@ static cell AMX_NATIVE_CALL find_ent_in_sphere(AMX *amx, cell *params) static cell AMX_NATIVE_CALL find_ent_by_class(AMX *amx, cell *params) /* 3 param */ { - edict_t *pEnt = INDEXENT2(params[1]); + int idx = params[1]; + CHECK_ENTITY_SIMPLE(idx); + + edict_t *pEnt = INDEXENT2(idx); int len; char* sValue = MF_GetAmxString(amx, params[2], 0, &len); @@ -1476,7 +1498,7 @@ static cell AMX_NATIVE_CALL find_ent_by_owner(AMX *amx, cell *params) // native { int iEnt = params[1]; int oEnt = params[3]; - // Check index to start searching at, 0 must be possible for iEnt. + CHECK_ENTITY_SIMPLE(iEnt); CHECK_ENTITY_SIMPLE(oEnt); edict_t *pEnt = INDEXENT2(iEnt); @@ -1512,6 +1534,7 @@ static cell AMX_NATIVE_CALL get_grenade_id(AMX *amx, cell *params) /* 4 param * int index = params[1]; const char *szModel; + CHECK_ENTITY_SIMPLE(params[4]); CHECK_ENTITY(index); edict_t* pentFind = INDEXENT2(params[4]); @@ -1602,6 +1625,7 @@ AMX_NATIVE_INFO ent_Natives[] = { {"entity_get_string", entity_get_string}, {"entity_set_string", entity_set_string}, {"entity_get_edict", entity_get_edict}, + {"entity_get_edict2", entity_get_edict2}, {"entity_set_edict", entity_set_edict}, {"entity_get_byte", entity_get_byte}, {"entity_set_byte", entity_set_byte}, diff --git a/modules/engine/forwards.cpp b/modules/engine/forwards.cpp index a5b6c22c..5c1f3c64 100644 --- a/modules/engine/forwards.cpp +++ b/modules/engine/forwards.cpp @@ -118,20 +118,6 @@ void StartFrame() RETURN_META(MRES_IGNORED); } -void StartFrame_Post() -{ - if (glinfo.bCheckLights) - { - if (glinfo.fNextLights < gpGlobals->time) - { - (g_engfuncs.pfnLightStyle)(0, glinfo.szLastLights); - glinfo.fNextLights = gpGlobals->time + 1; - } - } - - RETURN_META(MRES_IGNORED); -} - void CmdStart(const edict_t *player, const struct usercmd_s *_cmd, unsigned int random_seed) { unsigned int i = 0; diff --git a/modules/engine/globals.cpp b/modules/engine/globals.cpp index 3b8a281d..4b859c12 100644 --- a/modules/engine/globals.cpp +++ b/modules/engine/globals.cpp @@ -157,7 +157,7 @@ static cell AMX_NATIVE_CALL get_global_vector(AMX *amx, cell *params) // globals return 1; } -static cell AMX_NATIVE_CALL get_global_edict(AMX *amx, cell *params) // globals_get_edict(variable); = 1 param +static cell AMX_NATIVE_CALL get_global_edict2(AMX *amx, cell *params) { edict_t* pReturnEntity; @@ -167,14 +167,24 @@ static cell AMX_NATIVE_CALL get_global_edict(AMX *amx, cell *params) // globals_ break; default: MF_LogError(amx, AMX_ERR_NATIVE, "Undefined global_edict index %d", params[1]); - return 0; + return -1; } // Will crash if ENTINDEX() is called on bad pointer? if(!FNullEnt(pReturnEntity)) return ENTINDEX(pReturnEntity); - return 0; + return -1; +} + +static cell AMX_NATIVE_CALL get_global_edict(AMX *amx, cell *params) // globals_get_edict(variable); = 1 param +{ + cell res = get_global_edict2(amx, params); + + if (res == -1) + res = 0; + + return res; } AMX_NATIVE_INFO global_Natives[] = { @@ -182,6 +192,7 @@ AMX_NATIVE_INFO global_Natives[] = { {"get_global_int", get_global_int}, {"get_global_string", get_global_string}, {"get_global_edict", get_global_edict}, + {"get_global_edict2", get_global_edict2}, {"get_global_vector", get_global_vector}, {NULL, NULL}, /////////////////// diff --git a/modules/engine/moduleconfig.h b/modules/engine/moduleconfig.h index 827f3234..170e03e5 100644 --- a/modules/engine/moduleconfig.h +++ b/modules/engine/moduleconfig.h @@ -243,7 +243,7 @@ // #define FN_ServerExecute ServerExecute // #define FN_engClientCommand engClientCommand // #define FN_ParticleEffect ParticleEffect -#define FN_LightStyle LightStyle +// #define FN_LightStyle LightStyle // #define FN_DecalIndex DecalIndex // #define FN_PointContents PointContents // #define FN_MessageBegin MessageBegin diff --git a/modules/engine/msvc12/engine.vcxproj b/modules/engine/msvc12/engine.vcxproj index 88b4f687..84e647d0 100644 --- a/modules/engine/msvc12/engine.vcxproj +++ b/modules/engine/msvc12/engine.vcxproj @@ -54,7 +54,7 @@ Disabled - ..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) + ..\;..\..\..\public;..\..\..\public\memtools;..\..\..\public\sdk;..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;ENGINE_EXPORTS;HAVE_STDINT_H;%(PreprocessorDefinitions) true EnableFastChecks @@ -98,6 +98,9 @@ + + + @@ -106,6 +109,10 @@ + + + + diff --git a/modules/engine/msvc12/engine.vcxproj.filters b/modules/engine/msvc12/engine.vcxproj.filters index b062f64c..5e439186 100644 --- a/modules/engine/msvc12/engine.vcxproj.filters +++ b/modules/engine/msvc12/engine.vcxproj.filters @@ -18,6 +18,15 @@ {e7f2c5c2-cba9-4712-a576-ceb676c94b36} + + {ca6abf66-eee2-4d06-813e-792d82d6e846} + + + {59354b8c-0925-4d8b-bb2b-684f6638de6b} + + + {6c2c3c74-4dc3-45bf-b3a5-6224971eee69} + @@ -38,6 +47,15 @@ Module SDK\SDK Base + + Memtools + + + Memtools\CDetour + + + Memtools\CDetour\asm + @@ -55,6 +73,18 @@ Module SDK\SDK Base + + Memtools + + + Memtools\CDetour + + + Memtools\CDetour + + + Memtools\CDetour\asm + diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index b58239de..46ae4431 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -248,6 +248,25 @@ native precache_sound(const name[]); */ native precache_generic(const szFile[]); +/** + * Precaches an event file. + * + * @note The event type should always be 1. + * @note Contrary to the other precache_* natives, this can be used outside of + * the plugin_precache() forward, e.g. in plugin_init() or plugin_cfg(). + * A bug in some clients makes this necessary, as plugin_precache() is + * called before the mod has precached its own, default event files. This + * can cause the event table to be misaligned on the client, leading to + * visual and audio bugs that are hard to diagnose. + * + * @param type Event type + * @param Name Formatting rules, path to the event file + * @param ... Variable number of formatting parameters + * + * @return Unique cache id of the event + */ +native precache_event(type, const Name[], any:...); + /** * Changes the map. * diff --git a/plugins/include/engine.inc b/plugins/include/engine.inc index cd0b5e5f..09e2f427 100755 --- a/plugins/include/engine.inc +++ b/plugins/include/engine.inc @@ -25,7 +25,7 @@ #endif /** - * Retrieves a result from the global trace handle. + * Retrieves a result from the global engine module trace handle. * * @note For a list of trace results available see the TR_* constants in * engine_const.inc. @@ -70,7 +70,7 @@ native traceresult(type, any:...); * @param impulse Impulse to hook * @param function Name of callback function * - * @noreturn + * @return Impulse forward id */ native register_impulse(impulse, const function[]); @@ -96,7 +96,7 @@ native register_impulse(impulse, const function[]); * @param Toucher Entity classname touching, "*" or "" for any class * @param function Name of callback function * - * @noreturn + * @return Touch forward id */ native register_touch(const Touched[], const Toucher[], const function[]); @@ -120,28 +120,36 @@ native register_touch(const Touched[], const Toucher[], const function[]); * @param Touched Entity classname to hook * @param function Name of callback function * - * @noreturn + * @return Think forward id */ native register_think(const Classname[], const function[]); /** - * Precaches an event file. + * Removes a previously registered impulse hook. * - * @note The event type should always be 1. - * @note Contrary to the other precache_* natives, this can be used outside of - * the plugin_precache() forward, e.g. in plugin_init() or plugin_cfg(). - * A bug in some clients makes this necessary, as plugin_precache() is - * called before the mod has precached its own, default event files. This - * can cause the event table to be misaligned on the client, leading to - * visual and audio bugs that are hard to diagnose. + * @param registerid Impulse forward id * - * @param type Event type - * @param Name Formatting rules, path to the event file - * @param ... Variable number of formatting parameters - * - * @return Unique cache id of the event + * @return 1 on success, 0 if nothing was removed */ -native precache_event(type, const Name[], any:...); +native unregister_impulse(registerid); + +/** + * Removes a previously registered touch hook. + * + * @param registerid Touch forward id + * + * @return 1 on success, 0 if nothing was removed + */ +native unregister_touch(registerid); + +/** + * Removes a previously registered think hook. + * + * @param registerid Think forward id + * + * @return 1 on success, 0 if nothing was removed + */ +native unregister_think(registerid); /** * Sets the engine module speak flags on a client. @@ -298,6 +306,21 @@ native get_global_vector(variable, Float:vector[3]); */ native get_global_edict(variable); +/** + * Returns a edict type value from the server globals. + * + * @note For a list of valid edict type entries, see the GL_* constants in + * engine_const.inc under the "Edict" section. + * @note This native returns -1 as a safe error value if the edict retrieved is + * an invalid entity. Otherwise it is identical to get_global_edict(). + * + * @param variable Entry to retrieve from + * + * @return Value of specified entry + * @error If an invalid entry is provided, an error will be thrown. + */ +native get_global_edict2(variable); + /** * Sets the size of the entity bounding box, as described by the minimum and * maximum vectors relative to the origin. @@ -357,8 +380,8 @@ native bool:entity_intersects(entity, other); * @param iKey Entry to retrieve from * * @return Value of specified entry - * @error If an invalid entity index or entry is provided, an error - * will be thrown. + * @error If an invalid entity index is provided, an error will be + * thrown. */ native entity_get_int(iIndex, iKey); @@ -468,6 +491,26 @@ native entity_set_vector(iIndex, iKey, const Float:vNewVector[3]); */ native entity_get_edict(iIndex, iKey); +/** + * Returns an edict type value from an entities entvar struct. + * + * @note For a list of valid edict type entries, see the EV_ENT_* constants in + * engine_const.inc + * @note This native returns -1 as a safe error value if the edict retrieved + * from the entvar is an invalid entity. Otherwise it is identical to + * entity_get_edict(). + * + * @param iIndex Entity index + * @param iKey Entry to retrieve from + * + * @return Entity index in specified entry, -1 if the edict in the + * entvar is not a valid entity or an invalid entry was + * specified + * @error If an invalid entity index is provided, an error will be + * thrown. + */ +native entity_get_edict2(iIndex, iKey); + /** * Sets an edict type value in an entities entvar struct. * @@ -578,6 +621,8 @@ native create_entity(const szClassname[]); * * @return 1 if entity was sucessfully removed, 0 if an invalid entity * was provided + * @error If an entity index in the range of 0 to MaxClients is + * provided, an error will be thrown. */ native remove_entity(iIndex); @@ -921,8 +966,8 @@ native is_visible(entity, target); * Fires a trace line between two origins, retrieving the end point and entity * hit. * - * @note This native writes to the global trace handle. Additional trace results - * can be retrieved using traceresult(). + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). * @note This native returns 0 if the trace did not hit anything. As 0 is an * entity index that is considered to be a valid value for a trace hit * ("worldspawn"), this native can potentially return a misleading value. @@ -941,8 +986,8 @@ native trace_line(iIgnoreEnt, const Float:fStart[3], const Float:fEnd[3], Float: /** * Fires a trace line between two origins, retrieving the trace normal. * - * @note This native writes to the global trace handle. Additional trace results - * can be retrieved using traceresult(). + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). * * @param iIgnoreEnt Entity index that trace will ignore, -1 if trace should * not ignore any entities @@ -956,31 +1001,33 @@ native trace_line(iIgnoreEnt, const Float:fStart[3], const Float:fEnd[3], Float: native trace_normal(iIgnoreEnt, const Float:fStart[3], const Float:fEnd[3], Float:vReturn[3]); /** - * Fires a trace hull on a specified origin. + * Fires a trace hull on a specified origin or between two origins. * - * @note This native writes to the global trace handle. Additional trace results - * can be retrieved using traceresult(). + * @note This native writes to the global engine module trace handle. Additional + * trace results can be retrieved using traceresult(). * @note For a list of valid hull types see the HULL_* constants in * hlsdk_const.inc * @note For a list of valid ignore types see the *IGNORE_* constants in * hlsdk_const.inc * - * @param origin Trace startin and end point + * @param origin Trace start point (and end point if not specified) * @param hull Hull type * @param ignoredent Entity index that trace will ignore * @param ignoremonsters Entity ignore type + * @param end Trace end point, pass NULL_VECTOR to use start point * * @return Custom bitflag sum of relevant trace results * StartSolid (1), AllSolid (2) and InOpen (4) */ -native trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0); +native trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0, const Float:end[3] = NULL_VECTOR); /** * Attempts to describe an obstacle by firing trace lines in a specified * direction, offset on the z-axis around an origin. * * @note The functionality of this native can mostly be replaced by a single - * hull trace. This native does not write to the global trace handle. + * hull trace. This native does not write to the global engine module + * trace handle. * @note This native is intended to examine an obstacle in front of a standing * player. Start should usually be the origin of a client while angle * should be its forward angle vector. 73 traces are fired, each offset by diff --git a/public/amtl b/public/amtl index 9b1cb728..1bb5196c 160000 --- a/public/amtl +++ b/public/amtl @@ -1 +1 @@ -Subproject commit 9b1cb728c931c0b42a23b96a3c0909470769a72f +Subproject commit 1bb5196ce39ff3ed59445e51f9223734d4bcf886