diff --git a/core/smn_entities.cpp b/core/smn_entities.cpp index 11e374bd..3c58a47c 100644 --- a/core/smn_entities.cpp +++ b/core/smn_entities.cpp @@ -14,6 +14,8 @@ #include "sm_globals.h" #include "sourcemod.h" #include "sourcemm_api.h" +#include "server_class.h" +#include "CPlayerManager.h" inline edict_t *GetEdict(cell_t num) { @@ -22,6 +24,14 @@ inline edict_t *GetEdict(cell_t num) { return NULL; } + if (num > 0 && num < g_Players.GetMaxClients()) + { + CPlayer *pPlayer = g_Players.GetPlayerByIndex(num); + if (!pPlayer || !pPlayer->IsConnected()) + { + return NULL; + } + } return pEdict; } @@ -58,7 +68,7 @@ static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params) static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params) { - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); + edict_t *pEdict = GetEdict(params[1]); if (!pEdict) { @@ -71,9 +81,9 @@ static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params) static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params) { - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); + edict_t *pEdict = GetEdict(params[1]); - if (!pEdict || pEdict->IsFree()) + if (!pEdict) { return 0; } @@ -90,9 +100,9 @@ static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params) static cell_t IsEntNetworkable(IPluginContext *pContext, const cell_t *params) { - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]); + edict_t *pEdict = GetEdict(params[1]); - if (!pEdict || pEdict->IsFree()) + if (!pEdict) { return 0; } @@ -131,11 +141,55 @@ static cell_t SetEdictFlags(IPluginContext *pContext, const cell_t *params) return 1; } +static cell_t GetEdictClassname(IPluginContext *pContext, const cell_t *params) +{ + edict_t *pEdict = GetEdict(params[1]); + + if (!pEdict) + { + return pContext->ThrowNativeError("Invalid edict (%d)", params[1]); + } + + const char *cls = pEdict->GetClassName(); + + if (!cls || cls[0] == '\0') + { + return 0; + } + + pContext->StringToLocal(params[2], params[3], cls); + + return 1; +} + +static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params) +{ + edict_t *pEdict = GetEdict(params[1]); + + if (!pEdict) + { + return pContext->ThrowNativeError("Invalid edict (%d)", params[1]); + } + + IServerNetworkable *pNet = pEdict->GetNetworkable(); + if (!pNet) + { + return 0; + } + + ServerClass *pClass = pNet->GetServerClass(); + + pContext->StringToLocal(params[2], params[3], pClass->GetName()); + + return 1; +} + REGISTER_NATIVES(entityNatives) { {"CreateEdict", CreateEdict}, + {"GetEdictClassname", GetEdictClassname}, {"GetEdictFlags", GetEdictFlags}, - {"GetEntityCount", GetEntityCount}, + {"GetEntityNetClass", GetEntityNetClass}, {"GetMaxEntities", GetMaxEntities}, {"IsEntNetworkable", IsEntNetworkable}, {"IsValidEdict", IsValidEdict}, diff --git a/plugins/include/entity.inc b/plugins/include/entity.inc index 4d6709bd..6870d62d 100644 --- a/plugins/include/entity.inc +++ b/plugins/include/entity.inc @@ -106,4 +106,26 @@ native GetEdictFlags(edict); * @noreturn * @error Invalid edict index. */ -native SetEdictFlags(edict, flags); \ No newline at end of file +native SetEdictFlags(edict, flags); + +/** + * Retrieves an edict classname. + * + * @param edict Index of the entity. + * @param clsname Buffer to store the classname. + * @param maxlength Maximum length of the buffer. + * @return True on success, false if there is no classname set. + */ +native bool:GetEdictClassname(edict, String:clsname[], maxlength); + +/** + * Retrieves an entity's networkable serverclass name. + * This is not the same as the classname and is used for networkable state changes. + * + * @param edict Index of the entity. + * @param clsname Buffer to store the serverclass name. + * @param maxlength Maximum lnegth of the buffer. + * @return True on success, false if the edict is not networkable. + * @error Invalid edict index. + */ +native bool:GetEntityNetClass(edict, String:clsname[], maxlength);