mirror of
https://github.com/arthurdead/proxysend.git
synced 2025-12-06 18:08:22 +00:00
fix crash on unload and fix some props getting the wrong type
This commit is contained in:
parent
e6667807e1
commit
673c8b7774
201
extension.cpp
201
extension.cpp
@ -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();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user