From f2615b10de59ad1ca0e79c3d393908464700ea58 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 22 Jun 2023 00:33:00 +0200 Subject: [PATCH] Improve CClient class structure * Added structure for send/recv datablocks vtable. * Mapped out CClient structure more. * Fixed incorrect tick member offsets for CClient. --- r5dev/common/global.cpp | 3 + r5dev/common/global.h | 2 + r5dev/core/init.cpp | 4 + r5dev/engine/CMakeLists.txt | 6 +- r5dev/engine/client/client.h | 82 +++++++++++--------- r5dev/engine/client/clientstate.h | 5 +- r5dev/engine/client/datablock_receiver.cpp | 24 ++++++ r5dev/engine/client/datablock_receiver.h | 61 +++++++++++++++ r5dev/engine/datablock.h | 23 ------ r5dev/engine/net_chan.cpp | 17 +++++ r5dev/engine/net_chan.h | 2 + r5dev/engine/server/datablock_sender.cpp | 60 +++++++++++++++ r5dev/engine/server/datablock_sender.h | 88 ++++++++++++++++++++++ r5dev/public/idatablock.h | 24 ++++++ 14 files changed, 340 insertions(+), 61 deletions(-) create mode 100644 r5dev/engine/client/datablock_receiver.cpp create mode 100644 r5dev/engine/client/datablock_receiver.h delete mode 100644 r5dev/engine/datablock.h create mode 100644 r5dev/engine/server/datablock_sender.cpp create mode 100644 r5dev/engine/server/datablock_sender.h create mode 100644 r5dev/public/idatablock.h diff --git a/r5dev/common/global.cpp b/r5dev/common/global.cpp index 2ebd4658..61deb117 100644 --- a/r5dev/common/global.cpp +++ b/r5dev/common/global.cpp @@ -227,6 +227,8 @@ ConVar* net_useRandomKey = nullptr; ConVar* net_usesocketsforloopback = nullptr; ConVar* net_processTimeBudget = nullptr; +ConVar* net_datablock_networkLossForSlowSpeed = nullptr; + ConVar* pylon_matchmaking_hostname = nullptr; ConVar* pylon_host_update_interval = nullptr; ConVar* pylon_showdebuginfo = nullptr; @@ -482,6 +484,7 @@ void ConVar_InitShipped(void) hostport = g_pCVar->FindVar("hostport"); host_hasIrreversibleShutdown = g_pCVar->FindVar("host_hasIrreversibleShutdown"); host_timescale = g_pCVar->FindVar("host_timescale"); + net_datablock_networkLossForSlowSpeed = g_pCVar->FindVar("net_datablock_networkLossForSlowSpeed"); net_usesocketsforloopback = g_pCVar->FindVar("net_usesocketsforloopback"); #ifndef CLIENT_DLL sv_stats = g_pCVar->FindVar("sv_stats"); diff --git a/r5dev/common/global.h b/r5dev/common/global.h index 7c614d58..c754736e 100644 --- a/r5dev/common/global.h +++ b/r5dev/common/global.h @@ -213,6 +213,8 @@ extern ConVar* net_useRandomKey; extern ConVar* net_usesocketsforloopback; extern ConVar* net_processTimeBudget; +extern ConVar* net_datablock_networkLossForSlowSpeed; + extern ConVar* pylon_matchmaking_hostname; extern ConVar* pylon_host_update_interval; extern ConVar* pylon_showdebuginfo; diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index f18e4471..1850a8b4 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -49,11 +49,13 @@ #include "vguimatsurface/MatSystemSurface.h" #include "engine/client/vengineclient_impl.h" #include "engine/client/cdll_engine_int.h" +#include "engine/client/datablock_receiver.h" #endif // !DEDICATED #ifndef CLIENT_DLL #include "engine/server/server.h" #include "engine/server/persistence.h" #include "engine/server/vengineserver_impl.h" +#include "engine/server/datablock_sender.h" #endif // !CLIENT_DLL #include "studiorender/studiorendercontext.h" #include "rtech/rtech_game.h" @@ -457,6 +459,7 @@ void DetourRegister() // Register detour classes to be searched and hooked. // Client REGISTER(HVEngineClient); REGISTER(VDll_Engine_Int); + REGISTER(VClientDataBlockReceiver); #endif // !DEDICATED #ifndef CLIENT_DLL @@ -465,6 +468,7 @@ void DetourRegister() // Register detour classes to be searched and hooked. REGISTER(VServer); // REGISTER SERVER ONLY! REGISTER(VPersistence); // REGISTER SERVER ONLY! REGISTER(HVEngineServer); // REGISTER SERVER ONLY! + REGISTER(VServerDataBlockSender); // REGISTER SERVER ONLY! #endif // !CLIENT_DLL diff --git a/r5dev/engine/CMakeLists.txt b/r5dev/engine/CMakeLists.txt index 79499725..920ab696 100644 --- a/r5dev/engine/CMakeLists.txt +++ b/r5dev/engine/CMakeLists.txt @@ -45,7 +45,6 @@ endif() add_sources( SOURCE_GROUP "Network" "dt_recv.cpp" "datamap.cpp" - "datablock.h" "framesnapshot.h" "net.cpp" "net.h" @@ -110,6 +109,8 @@ add_sources( SOURCE_GROUP "Server" "server/sv_rcon.h" "server/vengineserver_impl.cpp" "server/vengineserver_impl.h" + "server/datablock_sender.cpp" + "server/datablock_sender.h" ) add_sources( SOURCE_GROUP "Client" @@ -119,6 +120,8 @@ add_sources( SOURCE_GROUP "Client" "client/cl_ents_parse.h" "client/client.cpp" "client/client.h" + "client/datablock_receiver.cpp" + "client/datablock_receiver.h" ) add_sources( SOURCE_GROUP "Shared" @@ -196,6 +199,7 @@ add_sources( SOURCE_GROUP "Public" "${ENGINE_SOURCE_DIR}/public/dt_send.h" "${ENGINE_SOURCE_DIR}/public/dt_recv.h" "${ENGINE_SOURCE_DIR}/public/datamap.h" + "${ENGINE_SOURCE_DIR}/public/idatablock.h" "${ENGINE_SOURCE_DIR}/public/idebugoverlay.h" "${ENGINE_SOURCE_DIR}/public/iengine.h" "${ENGINE_SOURCE_DIR}/public/igame.h" diff --git a/r5dev/engine/client/client.h b/r5dev/engine/client/client.h index b0f09884..1ef98852 100644 --- a/r5dev/engine/client/client.h +++ b/r5dev/engine/client/client.h @@ -3,6 +3,7 @@ #include "common/protocol.h" #include "engine/net_chan.h" #include "public/edict.h" +#include "engine/server/datablock_sender.h" //----------------------------------------------------------------------------- // Enumerations @@ -60,6 +61,7 @@ extern CClient* g_pClient; class CClient : IClientMessageHandler, INetChannelHandler { + friend class ServerDataBlockSender; public: CClient* GetClient(int nIndex) const; int64_t GetTeamNum() const; @@ -101,44 +103,55 @@ public: // Hook statics: static bool VSendNetMsgEx(CClient* pClient, CNetMessage* pMsg, char bLocal, bool bForceReliable, bool bVoice); private: - int m_nUserID; //0x0010 - edict_t m_nHandle; //0x0014 - char m_szServerName[256]; //0x0160 - char m_szClientName[256]; //0x0116 - char pad_0015[258]; //0x0216 - int m_nCommandTick; //0x0318 - char pad_031C[60]; //0x031C - int64_t m_iTeamNum; //0x0258 - KeyValues* m_ConVars; //0x0360 - char pad_0368[8]; //0x0368 - CServer* m_pServer; //0x0370 - char pad_0378[40]; //0x0378 - CNetChan* m_NetChannel; //0x03A0 - char pad_03A8[8]; //0x03A8 - SIGNONSTATE m_nSignonState; //0x03B0 - int32_t m_nDeltaTick; //0x03B4 - uint64_t m_nNucleusID; //0x03B8 - int32_t m_nStringTableAckTick; //0x03BC - int32_t m_nSignonTick; //0x03C0 - char pad_03C0[464]; //0x03C4 + uint32_t m_nUserID; + edict_t m_nHandle; + char m_szServerName[256]; + char m_szClientName[256]; + char m_szMachineName[256]; + int m_nCommandTick; + char m_bUsePersistence_MAYBE; + char pad_0016[59]; + int64_t m_iTeamNum; + KeyValues* m_ConVars; + char m_bInitialConVarsSet; + char m_bSendServerInfo; + char m_bSendSignonData; + char m_bFullStateAchieved; + char pad_0368[4]; + CServer* m_pServer; + char pad_0378[24]; + bool m_bKickedByFairFight_MAYBE; + char pad_0398[14]; + CNetChan* m_NetChannel; + char pad_03A8[8]; + SIGNONSTATE m_nSignonState; + int unk0; + uint64_t m_nNucleusID; + int unk1; + int unk2; + int m_nDeltaTick; + int m_nStringTableAckTick; + int m_nSignonTick; + int m_nBaselineUpdateTick_MAYBE; + char pad_03C0[448]; #if defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - char pad_0598[8]; //0x0598 + int unk3; + int m_nForceWaitForTick; #endif - bool m_bFakePlayer; //0x05A0 - bool m_bReceivedPacket; //0x05A1 - bool m_bLowViolence; //0x05A2 - bool m_bFullyAuthenticated; //0x05A3 - char pad_05A4[24]; //0x05A4 - PERSISTENCE m_nPersistenceState; //0x05BC - char pad_05C0[295312]; //0x05C0 - int m_iTracing; //0x48750 - CNetworkStatTrace m_Trace; //0x48754 - char pad_4878C[7304]; //0x4878C - int32_t m_LastMovementTick; //0x4A414 + bool m_bFakePlayer; + bool m_bReceivedPacket; + bool m_bLowViolence; + bool m_bFullyAuthenticated; + char pad_05A4[24]; + PERSISTENCE m_nPersistenceState; + char pad_05C0[48]; + ServerDataBlock m_DataBlock; + char pad_4A3D8[16]; + int m_LastMovementTick; #if defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - char pad_4A418[120]; //0x4A418 + char pad_4A418[130]; #endif - char pad_4A440[48]; //0x4A440 + char pad_4A49A[80]; }; #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) static_assert(sizeof(CClient) == 0x4A440); @@ -146,7 +159,6 @@ static_assert(sizeof(CClient) == 0x4A440); static_assert(sizeof(CClient) == 0x4A4C0); #endif - /* ==== CBASECLIENT ===================================================================================================================================================== */ inline CMemory p_CClient_Connect; inline auto v_CClient_Connect = p_CClient_Connect.RCast(); diff --git a/r5dev/engine/client/clientstate.h b/r5dev/engine/client/clientstate.h index fb9aa296..4e38f844 100644 --- a/r5dev/engine/client/clientstate.h +++ b/r5dev/engine/client/clientstate.h @@ -4,12 +4,12 @@ #include "common/protocol.h" #include "public/inetmsghandler.h" #include "public/isnapshotmgr.h" -#include "engine/datablock.h" #include "engine/net_chan.h" #include "engine/debugoverlay.h" #include "engine/clockdriftmgr.h" #include "engine/framesnapshot.h" #include "engine/packed_entity.h" +#include "datablock_receiver.h" class CClientSnapshotManager : public IClientSnapshotManager { @@ -23,6 +23,7 @@ public: /////////////////////////////////////////////////////////////////////////////// class CClientState : CS_INetChannelHandler, IConnectionlessPacketHandler, IServerMessageHandler, CClientSnapshotManager { + friend class ClientDataBlockReceiver; public: // Hook statics. static void VConnectionClosing(CClientState* thisptr, const char* szReason); static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg); @@ -111,7 +112,7 @@ public: bool m_bRestrictServerCommands; bool m_bRestrictClientCommands; char buffer_0x400[1024]; - NetDataBlockReceiver blockReceiver; + ClientDataBlockReceiver blockReceiver; char client_requested_disconnect; char error_message[512]; _BYTE gap18CA1[3]; diff --git a/r5dev/engine/client/datablock_receiver.cpp b/r5dev/engine/client/datablock_receiver.cpp new file mode 100644 index 00000000..c3917ee7 --- /dev/null +++ b/r5dev/engine/client/datablock_receiver.cpp @@ -0,0 +1,24 @@ +//===========================================================================// +// +// Purpose: client side datablock receiver +// +//===========================================================================// +#include "engine/client/clientstate.h" +#include "datablock_receiver.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ClientDataBlockReceiver::~ClientDataBlockReceiver() +{ + v_ClientDataBlockReceiver__Destructor(this); +} + +//----------------------------------------------------------------------------- +// Purpose: send an ack back to the server to let them know +// we received the datablock +//----------------------------------------------------------------------------- +void ClientDataBlockReceiver::AcknowledgeTransmission() +{ + v_ClientDataBlockReceiver__AcknowledgeTransmission(this); +} diff --git a/r5dev/engine/client/datablock_receiver.h b/r5dev/engine/client/datablock_receiver.h new file mode 100644 index 00000000..134d5484 --- /dev/null +++ b/r5dev/engine/client/datablock_receiver.h @@ -0,0 +1,61 @@ +#ifndef DATABLOCK_RECEIVER_H +#define DATABLOCK_RECEIVER_H +#include "idatablock.h" + +class CClientState; + +class ClientDataBlockReceiver : public NetDataBlockReceiver +{ + friend class CClientState; +public: + virtual ~ClientDataBlockReceiver(); + virtual void AcknowledgeTransmission() override; + +protected: + CClientState* m_pClientState; + bool m_bStartedRecv; + bool m_bCompletedRecv; + bool byte12; + short m_TransferId; + short m_Counter; + bool m_bInitialized; + int m_nTransferSize; + int m_nTotalBlocks; + int m_nBlockAckTick; + double m_flStartTime; + bool m_BlockStatus[DATABLOCK_STATUS_SIZE]; + void* m_pBigBuffer; +}; + +inline CMemory p_ClientDataBlockReceiver__Destructor; +inline auto v_ClientDataBlockReceiver__Destructor = p_ClientDataBlockReceiver__Destructor.RCast(); + +inline CMemory p_ClientDataBlockReceiver__AcknowledgeTransmission; +inline auto v_ClientDataBlockReceiver__AcknowledgeTransmission = p_ClientDataBlockReceiver__AcknowledgeTransmission.RCast(); + +/////////////////////////////////////////////////////////////////////////////// +class VClientDataBlockReceiver : public IDetour +{ + virtual void GetAdr(void) const + { + LogFunAdr("ClientDataBlockReceiver::~ClientDataBlockReceiver", p_ClientDataBlockReceiver__Destructor.GetPtr()); + LogFunAdr("ClientDataBlockReceiver::AcknowledgeTransmission", p_ClientDataBlockReceiver__AcknowledgeTransmission.GetPtr()); + } + virtual void GetFun(void) const + { + p_ClientDataBlockReceiver__Destructor = 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 48 8D 05 ?? ?? ?? ?? C6 41 12 00"); + v_ClientDataBlockReceiver__Destructor = p_ClientDataBlockReceiver__Destructor.RCast(); + + p_ClientDataBlockReceiver__AcknowledgeTransmission = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 4C 8B 51 08"); + v_ClientDataBlockReceiver__AcknowledgeTransmission = p_ClientDataBlockReceiver__AcknowledgeTransmission.RCast(); + } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Attach(void) const { } + virtual void Detach(void) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + +#endif // DATABLOCK_RECEIVER_H diff --git a/r5dev/engine/datablock.h b/r5dev/engine/datablock.h deleted file mode 100644 index 7a34d2fb..00000000 --- a/r5dev/engine/datablock.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef DATABLOCK_H -#define DATABLOCK_H - -struct __declspec(align(8)) NetDataBlockReceiver -{ - void* __vftable /*VFT*/; - void* client; /*CClientState*/ - char m_bStartedRecv; - char m_bCompletedRecv; - _BYTE byte12; - __int16 transfer_id; - __int16 counter; - _BYTE m_bInitialized; - int transfer_size; - int total_blocks; - _DWORD blocks_ackd; - double start_time; - bool block_status[768]; - char* m_pBigBuffer; -}; - - -#endif // DATABLOCK_H \ No newline at end of file diff --git a/r5dev/engine/net_chan.cpp b/r5dev/engine/net_chan.cpp index e20e90e9..15966ed9 100644 --- a/r5dev/engine/net_chan.cpp +++ b/r5dev/engine/net_chan.cpp @@ -63,6 +63,23 @@ int CNetChan::GetBufferSize(void) const return NET_FRAMES_BACKUP; } +//----------------------------------------------------------------------------- +// Purpose: gets the netchannel network loss +// Output : float +//----------------------------------------------------------------------------- +float CNetChan::GetNetworkLoss() const +{ + float v1 = *&m_DataFlow[1].frames[0].one; + if (!v1 && !m_nSequencesSkipped_MAYBE) + return 0.0f; + + float v4 = (v1 + m_nSequencesSkipped_MAYBE); + if (v1 + m_nSequencesSkipped_MAYBE < 0) + v4 = v4 + float(2 ^ 64); + + return m_nSequencesSkipped_MAYBE / v4; +} + //----------------------------------------------------------------------------- // Purpose: gets the netchannel latency // Input : flow - diff --git a/r5dev/engine/net_chan.h b/r5dev/engine/net_chan.h index 5f331423..1ba94178 100644 --- a/r5dev/engine/net_chan.h +++ b/r5dev/engine/net_chan.h @@ -103,6 +103,8 @@ public: int GetDataRate(void) const; int GetBufferSize(void) const; + float GetNetworkLoss() const; + float GetLatency(int flow) const; float GetAvgChoke(int flow) const; float GetAvgLatency(int flow) const; diff --git a/r5dev/engine/server/datablock_sender.cpp b/r5dev/engine/server/datablock_sender.cpp new file mode 100644 index 00000000..bc81d981 --- /dev/null +++ b/r5dev/engine/server/datablock_sender.cpp @@ -0,0 +1,60 @@ +//===========================================================================// +// +// Purpose: server side datablock sender +// +//===========================================================================// +#include "engine/client/client.h" +#include "datablock_sender.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ServerDataBlockSender::~ServerDataBlockSender() +{ + v_ServerDataBlockSender__Destructor(this); +} + +//----------------------------------------------------------------------------- +// Purpose: sends the datablock +//----------------------------------------------------------------------------- +void ServerDataBlockSender::SendDataBlock(short unk0, int unk1, + short unk2, short unk3, const void* buffer, int length) +{ + v_ServerDataBlockSender__SendDataBlock(this, unk0, unk1, + unk2, unk3, buffer, length); +} + +//----------------------------------------------------------------------------- +// Purpose: gets the resend rate +//----------------------------------------------------------------------------- +float ServerDataBlockSender::GetResendRate() const +{ + float flRet = 0.0f; + + if (!m_pClient) + return flRet; + + CNetChan* pChan = m_pClient->GetNetChan(); + if (!pChan) + return flRet; + + if (!m_bStartedTransfer) + { + flRet = pChan->GetNetworkLoss(); + + if (flRet < net_datablock_networkLossForSlowSpeed->GetFloat()) + { + return m_flResendRate; + } + } + + return flRet; +} + +//----------------------------------------------------------------------------- +// Purpose: gets the receiver name (client name as registered on the server) +//----------------------------------------------------------------------------- +const char* ServerDataBlockSender::GetReceiverName() const +{ + return m_pClient->m_szServerName; +} diff --git a/r5dev/engine/server/datablock_sender.h b/r5dev/engine/server/datablock_sender.h new file mode 100644 index 00000000..bcc49ff1 --- /dev/null +++ b/r5dev/engine/server/datablock_sender.h @@ -0,0 +1,88 @@ +#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(short unk0, int unk1, + short unk2, short unk3, const void* buffer, int length) override; + + virtual float GetResendRate() const override; + virtual const char* GetReceiverName() const override; + +protected: + char pad_0008[56]; + RTL_SRWLOCK LOCK; + char pad_0048[56]; + CClient* m_pClient; + char m_bInitialized; + char m_bStartedTransfer; + char m_bMultiplayer; + char field_8B; + short m_nTransferId; + short m_nCounter; + int m_nTransferSize; + int m_nTotalBlocks; + int m_nBlockAckTick; + int m_nCurrentBlock; + int m_nUnkA0; + int m_nBlockSendsAttempted; + float m_flResendRate; + char pad_00AC[4]; + double m_TimeCurrentSend; + double m_TimeFirstSend; + double m_TimeLastSend; + double m_flBlockTimesArray[DATABLOCK_STATUS_SIZE]; + char m_szDebugName[64]; + bool m_bBlockStatusArray[DATABLOCK_STATUS_SIZE]; + void* m_pData; + bool m_bAbnormalSending_Maybe; +}; + +struct ServerDataBlock +{ + char SnapshotBuffer[295312]; // this might be wrong !!! + void* pUnkBlockStruct; + char gapC0008[56]; + ServerDataBlockSender sender; +}; + +inline CMemory p_ServerDataBlockSender__Destructor; +inline auto v_ServerDataBlockSender__Destructor = p_ServerDataBlockSender__Destructor.RCast(); + +inline CMemory p_ServerDataBlockSender__SendDataBlock; +inline auto v_ServerDataBlockSender__SendDataBlock = p_ServerDataBlockSender__SendDataBlock.RCast(); + +/////////////////////////////////////////////////////////////////////////////// +class VServerDataBlockSender : public IDetour +{ + virtual void GetAdr(void) const + { + LogFunAdr("ServerDataBlockSender::~ServerDataBlockSender", p_ServerDataBlockSender__Destructor.GetPtr()); + LogFunAdr("ServerDataBlockSender::SendDataBlock", p_ServerDataBlockSender__SendDataBlock.GetPtr()); + } + virtual void GetFun(void) const + { + p_ServerDataBlockSender__Destructor = 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 ?? ?? ?? ?? ?? ??"); + v_ServerDataBlockSender__Destructor = p_ServerDataBlockSender__Destructor.RCast(); + + p_ServerDataBlockSender__SendDataBlock = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 99 ?? ?? ?? ??"); + v_ServerDataBlockSender__SendDataBlock = p_ServerDataBlockSender__SendDataBlock.RCast(); + } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Attach(void) const { } + virtual void Detach(void) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + +#endif // DATABLOCK_SENDER_H diff --git a/r5dev/public/idatablock.h b/r5dev/public/idatablock.h new file mode 100644 index 00000000..3d47395f --- /dev/null +++ b/r5dev/public/idatablock.h @@ -0,0 +1,24 @@ +#ifndef IDATABLOCK_H +#define IDATABLOCK_H + +#define DATABLOCK_STATUS_SIZE 0x300 + +abstract_class NetDataBlockSender +{ +public: + virtual ~NetDataBlockSender() {}; + virtual void SendDataBlock(short unk0, int unk1, + short unk2, short unk3, const void* buffer, int length) = 0; + virtual float GetResendRate() const = 0; + virtual const char* GetReceiverName() const = 0; +}; + +abstract_class NetDataBlockReceiver +{ +public: + virtual ~NetDataBlockReceiver() {}; + virtual void NotImplemented() {}// = 0; + virtual void AcknowledgeTransmission() {}// = 0; +}; + +#endif // IDATABLOCK_H