mirror of
https://github.com/arthurdead/proxysend.git
synced 2025-12-06 18:08:22 +00:00
remove std::unique_ptr from packed_entity_data_t, ignore connecting players, fix crash SendTable_CalcDelta when the entity_data vector was empty
This commit is contained in:
parent
2ec732b0b2
commit
c92fb41e2b
@ -586,19 +586,43 @@ private:
|
|||||||
|
|
||||||
struct packed_entity_data_t final
|
struct packed_entity_data_t final
|
||||||
{
|
{
|
||||||
packed_entity_data_t(packed_entity_data_t &&) noexcept = default;
|
packed_entity_data_t(packed_entity_data_t &&other) noexcept
|
||||||
packed_entity_data_t &operator=(packed_entity_data_t &&) noexcept = default;
|
{ operator=(std::move(other)); }
|
||||||
|
packed_entity_data_t &operator=(packed_entity_data_t &&other) noexcept {
|
||||||
|
packedData = other.packedData;
|
||||||
|
other.packedData = nullptr;
|
||||||
|
writeBuf = other.writeBuf;
|
||||||
|
other.writeBuf = nullptr;
|
||||||
|
objectID = other.objectID;
|
||||||
|
other.objectID = -1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<char[]> packedData{};
|
char *packedData{nullptr};
|
||||||
std::unique_ptr<bf_write> writeBuf{};
|
bf_write *writeBuf{nullptr};
|
||||||
int objectID{-1};
|
int objectID{-1};
|
||||||
|
|
||||||
packed_entity_data_t() noexcept = default;
|
packed_entity_data_t() noexcept = default;
|
||||||
~packed_entity_data_t() noexcept = default;
|
~packed_entity_data_t() noexcept {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() noexcept {
|
||||||
|
if(packedData) {
|
||||||
|
free(packedData);
|
||||||
|
packedData = nullptr;
|
||||||
|
}
|
||||||
|
if(writeBuf) {
|
||||||
|
delete writeBuf;
|
||||||
|
writeBuf = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void allocate() noexcept {
|
void allocate() noexcept {
|
||||||
packedData.reset(static_cast<char *>(aligned_alloc(4, MAX_PACKEDENTITY_DATA)));
|
reset();
|
||||||
writeBuf.reset(new bf_write{"SV_PackEntity->writeBuf", packedData.get(), MAX_PACKEDENTITY_DATA});
|
|
||||||
|
packedData = static_cast<char *>(aligned_alloc(4, MAX_PACKEDENTITY_DATA));
|
||||||
|
writeBuf = new bf_write{"SV_PackEntity->writeBuf", packedData, MAX_PACKEDENTITY_DATA};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1221,7 +1245,7 @@ DETOUR_DECL_STATIC6(SendTable_Encode, bool, const SendTable *, pTable, const voi
|
|||||||
packedData.allocate();
|
packedData.allocate();
|
||||||
|
|
||||||
sendproxy_client_slot = packentity_params->slots[i];
|
sendproxy_client_slot = packentity_params->slots[i];
|
||||||
const bool encoded{DETOUR_STATIC_CALL(SendTable_Encode)(pTable, pStruct, packedData.writeBuf.get(), objectID, pRecipients, bNonZeroOnly)};
|
const bool encoded{DETOUR_STATIC_CALL(SendTable_Encode)(pTable, pStruct, packedData.writeBuf, objectID, pRecipients, bNonZeroOnly)};
|
||||||
sendproxy_client_slot = nullptr;
|
sendproxy_client_slot = nullptr;
|
||||||
if(!encoded) {
|
if(!encoded) {
|
||||||
Host_Error( "SV_PackEntity: SendTable_Encode returned false (ent %d).\n", objectID );
|
Host_Error( "SV_PackEntity: SendTable_Encode returned false (ent %d).\n", objectID );
|
||||||
@ -1248,9 +1272,14 @@ DETOUR_DECL_STATIC8(SendTable_CalcDelta, int, const SendTable *, pTable, const v
|
|||||||
int *client_deltaProps{new int[nMaxDeltaProps]{static_cast<unsigned int>(-1)}};
|
int *client_deltaProps{new int[nMaxDeltaProps]{static_cast<unsigned int>(-1)}};
|
||||||
|
|
||||||
for(int i{0}; i < packentity_params->slots.size(); ++i) {
|
for(int i{0}; i < packentity_params->slots.size(); ++i) {
|
||||||
packed_entity_data_t &packedData{packentity_params->entity_data[i].back()};
|
std::vector<packed_entity_data_t> &entity_data{packentity_params->entity_data[i]};
|
||||||
|
if(entity_data.size() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const int client_nChanges{DETOUR_STATIC_CALL(SendTable_CalcDelta)(pTable, pFromState, nFromBits, packedData.packedData.get(), packedData.writeBuf->GetNumBitsWritten(), client_deltaProps, nMaxDeltaProps, objectID)};
|
packed_entity_data_t &packedData{entity_data.back()};
|
||||||
|
|
||||||
|
const int client_nChanges{DETOUR_STATIC_CALL(SendTable_CalcDelta)(pTable, pFromState, nFromBits, packedData.packedData, packedData.writeBuf->GetNumBitsWritten(), client_deltaProps, nMaxDeltaProps, objectID)};
|
||||||
|
|
||||||
bool done{false};
|
bool done{false};
|
||||||
|
|
||||||
@ -1349,7 +1378,8 @@ DETOUR_DECL_MEMBER2(CFrameSnapshotManager_GetPackedEntity, PackedEntity *, CFram
|
|||||||
const packed_entity_data_t *packedData{nullptr};
|
const packed_entity_data_t *packedData{nullptr};
|
||||||
for(int i{0}; i < packentity_params->slots.size(); ++i) {
|
for(int i{0}; i < packentity_params->slots.size(); ++i) {
|
||||||
if(packentity_params->slots[i] == slot) {
|
if(packentity_params->slots[i] == slot) {
|
||||||
for(const packed_entity_data_t &it : packentity_params->entity_data[i]) {
|
const std::vector<packed_entity_data_t> &entity_data{packentity_params->entity_data[i]};
|
||||||
|
for(const packed_entity_data_t &it : entity_data) {
|
||||||
if(it.objectID == entity) {
|
if(it.objectID == entity) {
|
||||||
packedData = ⁢
|
packedData = ⁢
|
||||||
break;
|
break;
|
||||||
@ -1364,7 +1394,7 @@ DETOUR_DECL_MEMBER2(CFrameSnapshotManager_GetPackedEntity, PackedEntity *, CFram
|
|||||||
packed->FreeData();
|
packed->FreeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
packed->AllocAndCopyPadded(packedData->packedData.get(), packedData->writeBuf->GetNumBytesWritten());
|
packed->AllocAndCopyPadded(packedData->packedData, packedData->writeBuf->GetNumBytesWritten());
|
||||||
}
|
}
|
||||||
|
|
||||||
return packed;
|
return packed;
|
||||||
@ -1372,12 +1402,28 @@ DETOUR_DECL_MEMBER2(CFrameSnapshotManager_GetPackedEntity, PackedEntity *, CFram
|
|||||||
|
|
||||||
static ConVar *sv_stressbots{nullptr};
|
static ConVar *sv_stressbots{nullptr};
|
||||||
|
|
||||||
|
static bool is_client_valid(CBaseClient *client) noexcept
|
||||||
|
{
|
||||||
|
if(!sv_stressbots->GetBool()) {
|
||||||
|
if(client->IsFakeClient() ||
|
||||||
|
client->IsHLTV() ||
|
||||||
|
client->IsReplay()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!client->IsConnected() ||
|
||||||
|
!client->IsSpawned() ||
|
||||||
|
!client->IsActive()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DETOUR_DECL_MEMBER4(CBaseServer_WriteDeltaEntities, void, CBaseClient *, client, CClientFrame *, to, CClientFrame *, from, bf_write &, pBuf)
|
DETOUR_DECL_MEMBER4(CBaseServer_WriteDeltaEntities, void, CBaseClient *, client, CClientFrame *, to, CClientFrame *, from, bf_write &, pBuf)
|
||||||
{
|
{
|
||||||
if(!sv_stressbots->GetBool() &&
|
if(!is_client_valid(client)) {
|
||||||
(client->IsFakeClient() ||
|
|
||||||
client->IsHLTV() ||
|
|
||||||
client->IsReplay())) {
|
|
||||||
writedeltaentities_client = nullptr;
|
writedeltaentities_client = nullptr;
|
||||||
} else {
|
} else {
|
||||||
writedeltaentities_client = client->GetPlayerSlot();
|
writedeltaentities_client = client->GetPlayerSlot();
|
||||||
@ -1422,10 +1468,7 @@ DETOUR_DECL_STATIC3(SV_ComputeClientPacks, void, int, clientCount, CGameClient *
|
|||||||
slots.reserve(clientCount);
|
slots.reserve(clientCount);
|
||||||
for(int i{0}; i < clientCount; ++i) {
|
for(int i{0}; i < clientCount; ++i) {
|
||||||
CGameClient *client{clients[i]};
|
CGameClient *client{clients[i]};
|
||||||
if(!sv_stressbots->GetBool() &&
|
if(!is_client_valid(client)) {
|
||||||
(client->IsFakeClient() ||
|
|
||||||
client->IsHLTV() ||
|
|
||||||
client->IsReplay())) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
slots.emplace_back(client->GetPlayerSlot());
|
slots.emplace_back(client->GetPlayerSlot());
|
||||||
@ -1469,6 +1512,11 @@ DETOUR_DECL_STATIC3(SV_ComputeClientPacks, void, int, clientCount, CGameClient *
|
|||||||
|
|
||||||
const bool any_per_client_hook{slots.size() > 0 && entities.size() > 0};
|
const bool any_per_client_hook{slots.size() > 0 && entities.size() > 0};
|
||||||
|
|
||||||
|
#if defined _DEBUG && 1
|
||||||
|
printf("slots = %i, entities = %i\n", slots.size(), entities.size());
|
||||||
|
printf("any_hook = %i, any_per_client_hook = %i, is_parallel_pack_allowed = %i\n", any_hook, any_per_client_hook, g_Sample.is_parallel_pack_allowed());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(any_per_client_hook) {
|
if(any_per_client_hook) {
|
||||||
packentity_params.reset(new pack_entity_params_t{std::move(slots), std::move(entities), snapshot->m_ListIndex});
|
packentity_params.reset(new pack_entity_params_t{std::move(slots), std::move(entities), snapshot->m_ListIndex});
|
||||||
SendTable_Encode_detour->EnableDetour();
|
SendTable_Encode_detour->EnableDetour();
|
||||||
@ -1487,11 +1535,6 @@ DETOUR_DECL_STATIC3(SV_ComputeClientPacks, void, int, clientCount, CGameClient *
|
|||||||
g_Sample.is_parallel_pack_allowed()
|
g_Sample.is_parallel_pack_allowed()
|
||||||
);
|
);
|
||||||
|
|
||||||
#if defined _DEBUG && 0
|
|
||||||
printf("slots = %i, entities = %i\n", slots.size(), entities.size());
|
|
||||||
printf("any_hook = %i, any_per_client_hook = %i, is_parallel_pack_allowed = %i\n", any_hook, any_per_client_hook, g_Sample.is_parallel_pack_allowed());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
in_compute_packs = true;
|
in_compute_packs = true;
|
||||||
DETOUR_STATIC_CALL(SV_ComputeClientPacks)(clientCount, clients, snapshot);
|
DETOUR_STATIC_CALL(SV_ComputeClientPacks)(clientCount, clients, snapshot);
|
||||||
in_compute_packs = false;
|
in_compute_packs = false;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user