Add support for setting string_t values with SetEntPropString.
Adds new AllowPooledString func to CHalfLife2 to allocate a string in the game's string pool. Also fixes SetEntPropString using incorrect offset for nested sendprops.
This commit is contained in:
+61
-11
@@ -2020,6 +2020,13 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
int offset;
|
||||
int maxlen;
|
||||
edict_t *pEdict;
|
||||
bool bIsStringIndex;
|
||||
|
||||
int element = 0;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
element = params[5];
|
||||
}
|
||||
|
||||
if (!IndexToAThings(params[1], &pEntity, &pEdict))
|
||||
{
|
||||
@@ -2043,17 +2050,31 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
|
||||
typedescription_t *td = info.prop;
|
||||
if (td->fieldType != FIELD_CHARACTER)
|
||||
if (td->fieldType != FIELD_CHARACTER
|
||||
&& td->fieldType != FIELD_STRING
|
||||
&& td->fieldType != FIELD_MODELNAME
|
||||
&& td->fieldType != FIELD_SOUNDNAME)
|
||||
{
|
||||
return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
|
||||
}
|
||||
|
||||
offset = info.actual_offset;
|
||||
maxlen = td->fieldSize;
|
||||
|
||||
bIsStringIndex = (td->fieldType != FIELD_CHARACTER);
|
||||
if (bIsStringIndex)
|
||||
{
|
||||
offset += (element * (td->fieldSizeInBytes / td->fieldSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
maxlen = td->fieldSize;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Prop_Send:
|
||||
{
|
||||
char *prop;
|
||||
sm_sendprop_info_t info;
|
||||
IServerUnknown *pUnk = (IServerUnknown *)pEntity;
|
||||
IServerNetworkable *pNet = pUnk->GetNetworkable();
|
||||
if (!pNet)
|
||||
@@ -2061,17 +2082,37 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("The edict is not networkable");
|
||||
}
|
||||
pContext->LocalToString(params[3], &prop);
|
||||
SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
|
||||
if (!pSend)
|
||||
if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info))
|
||||
{
|
||||
return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
|
||||
}
|
||||
if (pSend->GetType() != DPT_String)
|
||||
|
||||
offset = info.prop->GetOffset();
|
||||
|
||||
if (info.prop->GetType() != DPT_String)
|
||||
{
|
||||
return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
|
||||
}
|
||||
offset = pSend->GetOffset();
|
||||
maxlen = DT_MAX_STRING_BUFFERSIZE;
|
||||
else if (element != 0)
|
||||
{
|
||||
return pContext->ThrowNativeError("SendProp %s is not an array. Element %d is invalid.",
|
||||
prop,
|
||||
element);
|
||||
}
|
||||
|
||||
if (info.prop->GetProxyFn())
|
||||
{
|
||||
DVariant var;
|
||||
info.prop->GetProxyFn()(info.prop, pEntity, (const void *) ((intptr_t) pEntity + offset), &var, element, params[1]);
|
||||
if (var.m_pString == ((string_t *) ((intptr_t) pEntity + offset))->ToCStr())
|
||||
{
|
||||
bIsStringIndex = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maxlen = DT_MAX_STRING_BUFFERSIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2081,10 +2122,19 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
|
||||
char *src;
|
||||
char *dest = (char *)((uint8_t *)pEntity + offset);
|
||||
|
||||
size_t len;
|
||||
pContext->LocalToString(params[4], &src);
|
||||
size_t len = strncopy(dest, src, maxlen);
|
||||
|
||||
if (bIsStringIndex)
|
||||
{
|
||||
*(string_t *) ((intptr_t) pEntity + offset) = g_HL2.AllocPooledString(src);
|
||||
len = strlen(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *dest = (char *) ((uint8_t *) pEntity + offset);
|
||||
len = strncopy(dest, src, maxlen);
|
||||
}
|
||||
|
||||
if (params[2] == Prop_Send && (pEdict != NULL))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user