mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
This patch partially rebuilds the data block sender/receiver. The receiver leaks memory if the sender sends a bogus LZ4 packet, it would allocate memory to copy the encoded data into, from which it would decode it to the scratch buffer, but it would never deallocate this temporary buffer is the LZ4 decoder failed. This has been fixed. The second reason to rebuild these was to look into potential compression optimization. The data block rebuild now also features the latest LZ4 codec.
124 lines
4.2 KiB
C++
124 lines
4.2 KiB
C++
#ifndef DATABLOCK_SENDER_H
|
|
#define DATABLOCK_SENDER_H
|
|
#include "idatablock.h"
|
|
|
|
class CClient;
|
|
|
|
class ServerDataBlockSender : public NetDataBlockSender
|
|
{
|
|
friend class CClient;
|
|
public:
|
|
virtual ~ServerDataBlockSender() override;
|
|
virtual void SendDataBlock(const short transferId, const int transferSize, const short transferNr,
|
|
const short blockNr, const uint8_t* const blockData, const int blockSize) override;
|
|
|
|
virtual float GetResendRate() const override;
|
|
virtual const char* GetReceiverName() const override;
|
|
|
|
void StartBlockSender(const int transferSize, const bool isMultiplayer, const char* const debugName);
|
|
void ResetBlockSender();
|
|
|
|
void WriteDataBlock(const uint8_t* const sourceData, const int dataSize, const bool isMultiplayer, const char* const debugName);
|
|
|
|
protected:
|
|
char pad_0008[56];
|
|
RTL_SRWLOCK m_Lock;
|
|
char pad_0048[56];
|
|
|
|
// the server side client handle that is our 'receiving' end
|
|
CClient* m_pClient;
|
|
|
|
char m_bInitialized;
|
|
char m_bStartedTransfer;
|
|
|
|
char m_bMultiplayer;
|
|
char field_8B;
|
|
|
|
// the current transfer id, and the global transfer count for this
|
|
// particular client. the transfer nr keeps getting incremented on
|
|
// each new context setup
|
|
short m_nTransferId;
|
|
short m_nTransferNr;
|
|
|
|
// the total transfer size for the data, and the number of blocks this data
|
|
// has been carved up to
|
|
int m_nTransferSize;
|
|
int m_nTotalBlocks;
|
|
|
|
// last block that has been ack'd, and the current block that is pending to
|
|
// be sent to the receiver
|
|
int m_nBlockAckTick;
|
|
int m_nCurrentBlock;
|
|
|
|
// the total number of bytes remaining to be sent, and the number of times
|
|
// we attempted to send data blocks
|
|
int m_nTotalSizeRemaining;
|
|
int m_nBlockSendsAttempted;
|
|
|
|
// the resend rate for this connection, which depends of the stability/loss
|
|
// and other factors computed from the netchan
|
|
float m_flResendRate;
|
|
char pad_00AC[4]; // padding, in case we want to stuff our own vars in here
|
|
|
|
// times used to determine when a data block has been sent, and how long it
|
|
// took to get this out and acknowledged
|
|
double m_TimeCurrentSend;
|
|
double m_TimeFirstSend;
|
|
double m_TimeLastSend;
|
|
|
|
// the last time we attempted to send this block, this gets updated when
|
|
// a data block hasn't been acknowledged in time and is being resent
|
|
double m_flBlockSendTimes[MAX_DATABLOCK_FRAGMENTS];
|
|
|
|
// the debug name used when details get dumped to the console
|
|
char m_szDebugName[MAX_DATABLOCK_DEBUG_NAME];
|
|
|
|
// if a data block has been acknowledged by the receiver, we mark that
|
|
// particular block as acknowledged
|
|
bool m_bBlockAckStatus[MAX_DATABLOCK_FRAGMENTS];
|
|
uint8_t* m_pScratchBuffer;
|
|
bool m_bDumbDataBlockInfo;
|
|
};
|
|
|
|
struct ServerDataBlock
|
|
{
|
|
char blockBuffer[295312]; // this might be wrong !!!
|
|
void* userData;
|
|
char gapC0008[56];
|
|
ServerDataBlockSender sender;
|
|
};
|
|
|
|
struct ServerDataBlockHeader_s
|
|
{
|
|
bool isCompressed;
|
|
};
|
|
|
|
inline void*(*ServerDataBlockSender__Destructor)(ServerDataBlockSender* thisptr);
|
|
inline void* (*ServerDataBlockSender__SendDataBlock)(ServerDataBlockSender* thisptr,
|
|
const short transferId, const int transferSize, const short transferNr,
|
|
const short blockNr, const uint8_t* const blockData, const int blockSize);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class VServerDataBlockSender : public IDetour
|
|
{
|
|
virtual void GetAdr(void) const
|
|
{
|
|
LogFunAdr("ServerDataBlockSender::~ServerDataBlockSender", ServerDataBlockSender__Destructor);
|
|
LogFunAdr("ServerDataBlockSender::SendDataBlock", ServerDataBlockSender__SendDataBlock);
|
|
}
|
|
virtual void GetFun(void) const
|
|
{
|
|
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 8B DA 48 8B F9 E8 ?? ?? ?? ?? F6 C3 01 74"
|
|
" 0D BA ?? ?? ?? ?? 48 8B CF E8 ?? ?? ?? ?? 48 8B C7 48 8B 5C 24 ?? 48 83 C4 20 5F C3 CC CC CC CC CC CC CC CC CC CC CC CC 48 89 5C 24"
|
|
" ?? 48 89 74 24 ?? 57 48 83 EC 20 33 F6 66 C7 81 ?? ?? ?? ?? ?? ??").GetPtr(ServerDataBlockSender__Destructor);
|
|
|
|
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 99 ?? ?? ?? ??").GetPtr(ServerDataBlockSender__SendDataBlock);
|
|
}
|
|
virtual void GetVar(void) const { }
|
|
virtual void GetCon(void) const { }
|
|
virtual void Detour(const bool bAttach) const { }
|
|
};
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#endif // DATABLOCK_SENDER_H
|