MoeMod / smcppsdk

Code csgo sourcepawn with Modern C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

m_szArmsModel crashes

laper32 opened this issue · comments

Here is the summary about why m_szArmsModel crashes.

First of all, the GetEntProp, with Prop_Send, the function is:

template<class T = cell_t>
T &EntProp(AutoEntity<CBaseEntity*> pEntity, decltype(Prop_Send), const char *prop, int size = sizeof(T), int element=0) {
	assert(pEntity != nullptr);
	sm_sendprop_info_t info = {};
	IServerNetworkable* pNet = ((IServerUnknown*)pEntity)->GetNetworkable();
	if (!pNet) throw std::runtime_error("Edict is not networkable");
	if (!gamehelpers->FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, &info)) throw std::runtime_error(std::string() + "Prop not found: " + prop);
	SendProp* pProp = info.prop;
	ptrdiff_t offset = info.actual_offset;
	T* data = (T*)(reinterpret_cast<intptr_t>(static_cast<CBaseEntity*>(pEntity)) + offset);
	return *data;
}

template<class T = cell_t>
const T &GetEntProp(AutoEntity<CBaseEntity*> pEntity, decltype(Prop_Send), const char *prop, int size=sizeof(T), int element=0) {
	return EntProp<T>(pEntity, Prop_Send, prop, size, element);
}

Now we want to retrieve m_szArmsModel, that we will write it as:

static cell_t GetArm(IPluginContext* pContext, const cell_t* params) {
	CBasePlayer* player = sm::ent_cast<CBasePlayer*>(params[1]);
	if (!player)
	{
		pContext->ReportError("Player is nullptr. Index: %d", params[1]);
		return 0;
	}
	const char* name = sm::GetEntProp<const char*>(player, sm::Prop_Send, "m_szArmsModel");
	return pContext->StringToLocalUTF8(params[2], params[3], name, nullptr);
}

But this will crash.
Be comparing with smn_entities.cpp, we can find that it has several extra steps to retrieve the true result.

if (info.prop->GetProxyFn())
{
	DVariant var;
	info.prop->GetProxyFn()(info.prop, pEntity, (const void *) ((intptr_t) pEntity + offset), &var, element, params[1]);
	src = var.m_pString;
}
else
{
	src = *(char **) ((uint8_t *) pEntity + offset);
}

Now we add up these steps, it works correctly. 79

But the strange thing is that: Get crashes, but set works.
Further investigation is required.