fix crash on unload and fix some props getting the wrong type

This commit is contained in:
arthurdead 2022-05-21 16:17:40 -03:00
parent e6667807e1
commit 673c8b7774

View File

@ -150,48 +150,6 @@ static void global_send_proxy(const SendProp *pProp, const void *pStructBase, co
using tables_t = std::unordered_map<const SendTable *, std::unique_ptr<std::size_t>>; using tables_t = std::unordered_map<const SendTable *, std::unique_ptr<std::size_t>>;
static tables_t tables; static tables_t tables;
struct proxyrestore_t final
{
inline proxyrestore_t(proxyrestore_t &&other) noexcept
{ operator=(std::move(other)); }
proxyrestore_t(SendProp *pProp_) noexcept
: pProp{pProp_}, pRealProxy{pProp->GetProxyFn()}
{
#ifdef _DEBUG
printf("set %s proxy func\n", pProp->GetName());
#endif
pProp->SetProxyFn(global_send_proxy);
}
~proxyrestore_t() noexcept {
if(pProp && pRealProxy) {
#ifdef _DEBUG
printf("reset %s proxy func\n", pProp->GetName());
#endif
pProp->SetProxyFn(pRealProxy);
}
}
proxyrestore_t &operator=(proxyrestore_t &&other) noexcept
{
pProp = other.pProp;
other.pProp = nullptr;
pRealProxy = other.pRealProxy;
other.pRealProxy = nullptr;
return *this;
}
SendProp *pProp{nullptr};
SendVarProxyFn pRealProxy{nullptr};
std::size_t ref{0};
private:
proxyrestore_t(const proxyrestore_t &) = delete;
proxyrestore_t &operator=(const proxyrestore_t &) = delete;
proxyrestore_t() = delete;
};
static const CStandardSendProxies *std_proxies; static const CStandardSendProxies *std_proxies;
static const SendProp *m_nPlayerCond{nullptr}; static const SendProp *m_nPlayerCond{nullptr};
@ -222,6 +180,12 @@ static prop_types guess_prop_type(const SendProp *pProp, const SendTable *pTable
switch(pProp->GetType()) { switch(pProp->GetType()) {
case DPT_Int: { case DPT_Int: {
SendVarProxyFn pRealProxy{pProp->GetProxyFn()}; SendVarProxyFn pRealProxy{pProp->GetProxyFn()};
if(pRealProxy == global_send_proxy) {
#if defined _DEBUG
printf("invalid (global send proxy)\n");
#endif
return prop_types::unknown;
}
if(pProp->GetFlags() & SPROP_UNSIGNED) { if(pProp->GetFlags() & SPROP_UNSIGNED) {
if(pRealProxy == std_proxies->m_UInt8ToInt32) { if(pRealProxy == std_proxies->m_UInt8ToInt32) {
if(pProp->m_nBits == 1) { if(pProp->m_nBits == 1) {
@ -332,7 +296,7 @@ static prop_types guess_prop_type(const SendProp *pProp, const SendTable *pTable
} }
} }
case DPT_Float: case DPT_Float:
{ return prop_types::float_; } return prop_types::float_;
case DPT_Vector: { case DPT_Vector: {
if(pProp->m_fLowValue == 0.0f && pProp->m_fHighValue == 360.0f) { if(pProp->m_fLowValue == 0.0f && pProp->m_fHighValue == 360.0f) {
return prop_types::qangle; return prop_types::qangle;
@ -341,18 +305,62 @@ static prop_types guess_prop_type(const SendProp *pProp, const SendTable *pTable
} }
} }
case DPT_VectorXY: case DPT_VectorXY:
{ return prop_types::vector; } return prop_types::vector;
case DPT_String: case DPT_String:
{ return prop_types::cstring; } return prop_types::cstring;
case DPT_Array: case DPT_Array:
{ return prop_types::unknown; } return prop_types::unknown;
case DPT_DataTable: case DPT_DataTable:
{ return prop_types::unknown; } return prop_types::unknown;
} }
return prop_types::unknown; return prop_types::unknown;
} }
struct proxyrestore_t final
{
inline proxyrestore_t(proxyrestore_t &&other) noexcept
{ operator=(std::move(other)); }
proxyrestore_t(SendProp *pProp_, prop_types type_) noexcept
: pProp{pProp_}, pRealProxy{pProp->GetProxyFn()}, type{type_}
{
#ifdef _DEBUG
printf("set %s proxy func\n", pProp->GetName());
#endif
pProp->SetProxyFn(global_send_proxy);
}
~proxyrestore_t() noexcept {
if(pProp && pRealProxy) {
#ifdef _DEBUG
printf("reset %s proxy func\n", pProp->GetName());
#endif
pProp->SetProxyFn(pRealProxy);
}
}
proxyrestore_t &operator=(proxyrestore_t &&other) noexcept
{
pProp = other.pProp;
other.pProp = nullptr;
pRealProxy = other.pRealProxy;
other.pRealProxy = nullptr;
type = other.type;
return *this;
}
SendProp *pProp{nullptr};
SendVarProxyFn pRealProxy{nullptr};
std::size_t ref{0};
prop_types type{prop_types::unknown};
private:
proxyrestore_t(const proxyrestore_t &) = delete;
proxyrestore_t &operator=(const proxyrestore_t &) = delete;
proxyrestore_t() = delete;
};
template <typename T> template <typename T>
class thread_var_base class thread_var_base
{ {
@ -677,11 +685,11 @@ private:
struct prop_reference_t struct prop_reference_t
{ {
prop_reference_t(SendProp *pProp) noexcept prop_reference_t(SendProp *pProp, prop_types type) noexcept
{ {
restores_t::iterator it_restore{restores.find(pProp)}; restores_t::iterator it_restore{restores.find(pProp)};
if(it_restore == restores.end()) { if(it_restore == restores.end()) {
it_restore = restores.emplace(std::pair<SendProp *, std::unique_ptr<proxyrestore_t>>{pProp, new proxyrestore_t{pProp}}).first; it_restore = restores.emplace(std::pair<SendProp *, std::unique_ptr<proxyrestore_t>>{pProp, new proxyrestore_t{pProp, type}}).first;
} }
restore = it_restore->second.get(); restore = it_restore->second.get();
++restore->ref; ++restore->ref;
@ -797,7 +805,7 @@ private:
struct callback_t final : prop_reference_t struct callback_t final : prop_reference_t
{ {
callback_t(int index_, SendTable *pTable, SendProp *pProp, prop_types type_, std::size_t offset_) noexcept callback_t(int index_, SendTable *pTable, SendProp *pProp, prop_types type_, std::size_t offset_) noexcept
: prop_reference_t{pProp}, offset{offset_}, type{type_}, table{pTable}, prop{pProp}, index{index_} : prop_reference_t{pProp, type_}, offset{offset_}, type{type_}, table{pTable}, prop{pProp}, index{index_}
{ {
if(type == prop_types::cstring) { if(type == prop_types::cstring) {
fwd = forwards->CreateForwardEx(nullptr, ET_Hook, 6, nullptr, Param_Cell, Param_String, Param_String, Param_Cell, Param_Cell, Param_Cell); fwd = forwards->CreateForwardEx(nullptr, ET_Hook, 6, nullptr, Param_Cell, Param_String, Param_String, Param_Cell, Param_Cell, Param_Cell);
@ -909,8 +917,7 @@ struct callback_t final : prop_reference_t
static int get_current_client_slot() noexcept static int get_current_client_slot() noexcept
{ {
if(!sendproxy_client_slot || if(!sendproxy_client_slot) {
sendproxy_client_slot == -1) {
return -1; return -1;
} }
@ -1078,45 +1085,32 @@ struct callback_t final : prop_reference_t
bool fwd_call(int client, const SendProp *pProp, const void *old_pData, opaque_ptr &new_pData, int iElement, int objectID) const noexcept bool fwd_call(int client, const SendProp *pProp, const void *old_pData, opaque_ptr &new_pData, int iElement, int objectID) const noexcept
{ {
switch(type) { switch(type) {
case prop_types::int_: { case prop_types::int_:
return fwd_call_int<int>(client, pProp, old_pData, new_pData, iElement, objectID); return fwd_call_int<int>(client, pProp, old_pData, new_pData, iElement, objectID);
} break; case prop_types::bool_:
case prop_types::bool_: { return fwd_call_int<bool>(client, pProp, old_pData, new_pData, iElement, objectID);
return fwd_call_int<bool>(client, pProp, old_pData, new_pData, iElement, objectID); case prop_types::short_:
} break; return fwd_call_int<short>(client, pProp, old_pData, new_pData, iElement, objectID);
case prop_types::short_: { case prop_types::char_:
return fwd_call_int<short>(client, pProp, old_pData, new_pData, iElement, objectID); return fwd_call_int<char>(client, pProp, old_pData, new_pData, iElement, objectID);
} break; case prop_types::unsigned_int:
case prop_types::char_: { return fwd_call_int<unsigned int>(client, pProp, old_pData, new_pData, iElement, objectID);
return fwd_call_int<char>(client, pProp, old_pData, new_pData, iElement, objectID); case prop_types::unsigned_short:
} break; return fwd_call_int<unsigned short>(client, pProp, old_pData, new_pData, iElement, objectID);
case prop_types::unsigned_int: { case prop_types::unsigned_char:
return fwd_call_int<unsigned int>(client, pProp, old_pData, new_pData, iElement, objectID); return fwd_call_int<unsigned char>(client, pProp, old_pData, new_pData, iElement, objectID);
} break; case prop_types::float_:
case prop_types::unsigned_short: { return fwd_call_float(client, pProp, old_pData, new_pData, iElement, objectID);
return fwd_call_int<unsigned short>(client, pProp, old_pData, new_pData, iElement, objectID); case prop_types::vector:
} break; return fwd_call_vec<Vector>(client, pProp, old_pData, new_pData, iElement, objectID);
case prop_types::unsigned_char: { case prop_types::qangle:
return fwd_call_int<unsigned char>(client, pProp, old_pData, new_pData, iElement, objectID); return fwd_call_vec<QAngle>(client, pProp, old_pData, new_pData, iElement, objectID);
} break; case prop_types::color32_:
case prop_types::float_: { return fwd_call_color32(client, pProp, old_pData, new_pData, iElement, objectID);
return fwd_call_float(client, pProp, old_pData, new_pData, iElement, objectID); case prop_types::ehandle:
} break; return fwd_call_ehandle(client, pProp, old_pData, new_pData, iElement, objectID);
case prop_types::vector: { case prop_types::cstring:
return fwd_call_vec<Vector>(client, pProp, old_pData, new_pData, iElement, objectID); return fwd_call_str(client, pProp, old_pData, new_pData, iElement, objectID);
} break;
case prop_types::qangle: {
return fwd_call_vec<QAngle>(client, pProp, old_pData, new_pData, iElement, objectID);
} break;
case prop_types::color32_: {
return fwd_call_color32(client, pProp, old_pData, new_pData, iElement, objectID);
} break;
case prop_types::ehandle: {
return fwd_call_ehandle(client, pProp, old_pData, new_pData, iElement, objectID);
} break;
case prop_types::cstring: {
return fwd_call_str(client, pProp, old_pData, new_pData, iElement, objectID);
} break;
} }
return false; return false;
} }
@ -1210,17 +1204,8 @@ struct proxyhook_t final : table_reference_t
{ {
} }
~proxyhook_t() noexcept inline ~proxyhook_t() noexcept
{ {
if(index != -1) {
edict_t *edict{gamehelpers->EdictOfIndex(index)};
if(edict) {
for(callbacks_t::value_type &it : callbacks) {
gamehelpers->SetEdictStateChanged(edict, it.second.offset);
it.second.index = -1;
}
}
}
} }
void add_callback(SendTable *pTable, SendProp *pProp, prop_types type, int offset, IPluginFunction *func, bool per_client) noexcept void add_callback(SendTable *pTable, SendProp *pProp, prop_types type, int offset, IPluginFunction *func, bool per_client) noexcept
@ -1729,7 +1714,13 @@ static cell_t proxysend_hook(IPluginContext *pContext, const cell_t *params) noe
SendTable *pTable{info.table}; SendTable *pTable{info.table};
SendProp *pProp{info.prop}; SendProp *pProp{info.prop};
prop_types type{guess_prop_type(pProp, pTable)}; prop_types type{prop_types::unknown};
restores_t::const_iterator it_restore{restores.find(pProp)};
if(it_restore != restores.cend()) {
type = it_restore->second->type;
} else {
type = guess_prop_type(pProp, pTable);
}
if(type == prop_types::unknown) { if(type == prop_types::unknown) {
return pContext->ThrowNativeError("Unsupported prop"); return pContext->ThrowNativeError("Unsupported prop");
} }
@ -1904,9 +1895,9 @@ void Sample::SDK_OnUnload() noexcept
SendTable_CalcDelta_detour->Destroy(); SendTable_CalcDelta_detour->Destroy();
SendTable_Encode_detour->Destroy(); SendTable_Encode_detour->Destroy();
SV_ComputeClientPacks_detour->Destroy(); SV_ComputeClientPacks_detour->Destroy();
SV_PackEntity_detour->Destroy(); //SV_PackEntity_detour->Destroy();
PackWork_tProcess_detour->Destroy(); //PackWork_tProcess_detour->Destroy();
InvalidateSharedEdictChangeInfos_detour->Destroy(); //InvalidateSharedEdictChangeInfos_detour->Destroy();
CGameServer_SendClientMessages_detour->Destroy(); CGameServer_SendClientMessages_detour->Destroy();
CFrameSnapshotManager_GetPackedEntity_detour->Destroy(); CFrameSnapshotManager_GetPackedEntity_detour->Destroy();
CBaseServer_WriteDeltaEntities_detour->Destroy(); CBaseServer_WriteDeltaEntities_detour->Destroy();