From 296deb95e69367aa615d4296766294703a2f740f Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Sun, 1 Aug 2021 19:44:18 +0100 Subject: [PATCH] Return array type info with FindSendPropInfo (#1548) --- core/HalfLife2.cpp | 17 ++++++++----- core/smn_entities.cpp | 52 ++++++++++++++++++++++++++++++++++---- plugins/include/entity.inc | 6 +++-- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index 6036fcb8..1932dbd8 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -320,15 +320,20 @@ bool UTIL_FindInSendTable(SendTable *pTable, sm_sendprop_info_t *info, unsigned int offset) { - const char *pname; int props = pTable->GetNumProps(); - SendProp *prop; - - for (int i=0; iGetProp(i); - pname = prop->GetName(); + SendProp *prop = pTable->GetProp(i); + + // Skip InsideArray props (SendPropArray / SendPropArray2), + // we'll find them later by their containing array. + if (prop->IsInsideArray()) { + continue; + } + + const char *pname = prop->GetName(); SendTable *pInnerTable = prop->GetDataTable(); + if (pname && strcmp(name, pname) == 0) { // get true offset of CUtlVector diff --git a/core/smn_entities.cpp b/core/smn_entities.cpp index 13f04453..836ed757 100644 --- a/core/smn_entities.cpp +++ b/core/smn_entities.cpp @@ -825,7 +825,7 @@ static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params) { char *cls, *prop; sm_sendprop_info_t info; - cell_t *pType, *pBits, *pLocal; + cell_t *pType, *pBits, *pLocal, *pArraySize; pContext->LocalToString(params[1], &cls); pContext->LocalToString(params[2], &prop); @@ -839,7 +839,45 @@ static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params) pContext->LocalToPhysAddr(params[4], &pBits); pContext->LocalToPhysAddr(params[5], &pLocal); - switch (info.prop->GetType()) + if (params[0] >= 6) { + pContext->LocalToPhysAddr(params[6], &pArraySize); + *pArraySize = 0; + } + + SendProp *pProp = info.prop; + unsigned int actual_offset = info.actual_offset; + + // SendPropArray / SendPropArray2 + if (pProp->GetType() == DPT_Array && pProp->GetArrayProp()) + { + if (pArraySize) { + // This'll only work for SendPropArray + *pArraySize = pProp->GetNumElements(); + } + + // Use the type / bits / local offset of the real data prop + pProp = pProp->GetArrayProp(); + + // This is sane as the DPT_Array prop's local offset is always 0 + actual_offset += pProp->GetOffset(); + } + + // Get the local offset now before we might dive into another table + *pLocal = pProp->GetOffset(); + + // SendPropArray3 + SendTable *pTable = pProp->GetDataTable(); + if (pProp->GetType() == DPT_DataTable && pTable && pTable->GetNumProps() > 0) + { + if (pArraySize) { + *pArraySize = pTable->GetNumProps(); + } + + // Use the type / bits of the first data prop + pProp = pTable->GetProp(0); + } + + switch (pProp->GetType()) { case DPT_Int: { @@ -868,10 +906,9 @@ static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params) } } - *pBits = info.prop->m_nBits; - *pLocal = info.prop->GetOffset(); + *pBits = pProp->m_nBits; - return info.actual_offset; + return actual_offset; } static void GuessDataPropTypes(typedescription_t *td, cell_t * pSize, cell_t * pType) @@ -1297,6 +1334,11 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params ((class_name) ? class_name : "")); } + if (info.prop->GetType() == DPT_Array) + { + return info.prop->GetNumElements(); + } + if (info.prop->GetType() != DPT_DataTable) { return 0; diff --git a/plugins/include/entity.inc b/plugins/include/entity.inc index b6d82d3d..ba13c6e2 100644 --- a/plugins/include/entity.inc +++ b/plugins/include/entity.inc @@ -428,6 +428,7 @@ native int FindSendPropOffs(const char[] cls, const char[] prop); * for strings. * @param local_offset Optional parameter to store the local offset, as * FindSendPropOffs() would return. + * @param array_size Optional parameter to store array size, 0 if not an array. * @return On success, returns an absolutely computed offset. * If no offset is available, 0 is returned. * If the property is not found, -1 is returned. @@ -436,7 +437,8 @@ native int FindSendPropInfo(const char[] cls, const char[] prop, PropFieldType &type=view_as(0), int &num_bits=0, - int &local_offset=0); + int &local_offset=0, + int &array_size=0); /** * Given an entity, finds a datamap property offset. @@ -700,7 +702,7 @@ native int SetEntPropString(int entity, PropType type, const char[] prop, const * @param entity Entity/edict index. * @param type Property type. * @param prop Property name. - * @return Size of array (in elements) or 1 if property is not an array. + * @return Size of array (in elements) or 0 if property is not an array. * @error Invalid entity or property not found. */ native int GetEntPropArraySize(int entity, PropType type, const char[] prop);