Reconcile the concept of Edict & Networkable across the codebase (#1903)

* Reconcile the concept of Edict & Networkable across the codebase

* There's no need to check this, it's done elsewhere. Also could be null (segfault)

* This was never needed

* Pseudo review changes

Re-added removed null checks, and added new ones.

Changed the error messages in Get/SetProp natives to better reflect reality.

* Don't change the behaviour of GetEntityNetClass

* Overload IGameHelpers::FindServerClass

* Make error messages more accurate

* Fix a dev comment

* Rename FindServerClass

---------

Co-authored-by: Kenzzer <[email protected]>
This commit is contained in:
Benoist
2024-06-01 14:07:55 +00:00
committed by GitHub
co-authored by Kenzzer
parent 9f3584a056
commit 7df2f8e045
13 changed files with 152 additions and 118 deletions
+11
View File
@@ -413,6 +413,17 @@ ServerClass *CHalfLife2::FindServerClass(const char *classname)
return pInfo->sc;
}
ServerClass *CHalfLife2::FindEntityServerClass(CBaseEntity *pEntity)
{
IServerNetworkable* pNetwork = ((IServerUnknown *)pEntity)->GetNetworkable();
if (pNetwork == nullptr)
{
return nullptr;
}
return pNetwork->GetServerClass();
}
DataTableInfo *CHalfLife2::_FindServerClass(const char *classname)
{
DataTableInfo *pInfo = NULL;
+1
View File
@@ -221,6 +221,7 @@ public: //IGameHelpers
bool FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info);
datamap_t *GetDataMap(CBaseEntity *pEntity);
ServerClass *FindServerClass(const char *classname);
ServerClass *FindEntityServerClass(CBaseEntity *pEntity);
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset);
bool FindDataMapInfo(datamap_t *pMap, const char *offset, sm_datatable_info_t *pDataTable);
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
+24 -30
View File
@@ -134,12 +134,10 @@ inline edict_t *BaseEntityToEdict(CBaseEntity *pEntity)
{
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
IServerNetworkable *pNet = pUnk->GetNetworkable();
if (!pNet)
if (pNet == nullptr)
{
return NULL;
return nullptr;
}
return pNet->GetEdict();
}
@@ -363,14 +361,20 @@ static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params)
static cell_t IsEntNetworkable(IPluginContext *pContext, const cell_t *params)
{
edict_t *pEdict = GetEdict(params[1]);
if (!pEdict)
IServerUnknown *pUnknown = (IServerUnknown *)g_HL2.ReferenceToEntity(params[1]);
if (!pUnknown)
{
return 0;
}
return (pEdict->GetNetworkable() != NULL) ? 1 : 0;
IServerNetworkable *pNet = pUnknown->GetNetworkable();
if (!pNet)
{
return 0;
}
edict_t* edict = pNet->GetEdict();
return (edict && !edict->IsFree()) ? 1 : 0;
}
static cell_t GetEntityCount(IPluginContext *pContext, const cell_t *params)
@@ -436,14 +440,12 @@ static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid entity (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
}
IServerNetworkable *pNet = pUnk->GetNetworkable();
if (!pNet)
ServerClass *pClass = g_HL2.FindEntityServerClass(pEntity);
if (!pClass)
{
return 0;
}
ServerClass *pClass = pNet->GetServerClass();
pContext->StringToLocal(params[2], params[3], pClass->GetName());
return 1;
@@ -1270,13 +1272,11 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
#define FIND_PROP_SEND(type, type_name) \
sm_sendprop_info_t info;\
SendProp *pProp; \
IServerUnknown *pUnk = (IServerUnknown *)pEntity; \
IServerNetworkable *pNet = pUnk->GetNetworkable(); \
if (!pNet) \
{ \
return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]); \
ServerClass *pServerClass = g_HL2.FindEntityServerClass(pEntity); \
if (pServerClass == nullptr) { \
pContext->ThrowNativeError("Failed to retrieve entity %d (%d) server class!", g_HL2.ReferenceToIndex(params[1]), params[1]); \
} \
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) \
if (!g_HL2.FindSendPropInfo(pServerClass->GetName(), prop, &info)) \
{ \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
@@ -1434,13 +1434,13 @@ static cell_t GetEntPropArraySize(IPluginContext *pContext, const cell_t *params
{
sm_sendprop_info_t info;
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
IServerNetworkable *pNet = pUnk->GetNetworkable();
if (!pNet)
ServerClass *pServerClass = g_HL2.FindEntityServerClass(pEntity);
if (pServerClass == nullptr)
{
return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]);
return pContext->ThrowNativeError("Failed to retrieve entity %d (%d) server class!", g_HL2.ReferenceToIndex(params[1]), params[1]);
}
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
if (!g_HL2.FindSendPropInfo(pServerClass->GetName(), prop, &info))
{
const char *class_name = g_HL2.GetEntityClassname(pEntity);
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)",
@@ -2079,13 +2079,7 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
edict_t *pOtherEdict = NULL;
if (pOther)
{
IServerNetworkable *pNetworkable = ((IServerUnknown *) pOther)->GetNetworkable();
if (!pNetworkable)
{
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);
}
pOtherEdict = pNetworkable->GetEdict();
pOtherEdict = BaseEntityToEdict(pOther);
if (!pOtherEdict || pOtherEdict->IsFree())
{
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);