diff --git a/r5dev/engine/net_chan.cpp b/r5dev/engine/net_chan.cpp index b80919fc..13c34756 100644 --- a/r5dev/engine/net_chan.cpp +++ b/r5dev/engine/net_chan.cpp @@ -64,6 +64,237 @@ double CNetChan::GetTimeConnected(void) const return (t > 0.0) ? t : 0.0; } +//----------------------------------------------------------------------------- +// Purpose: flows a new packet +// Input : *pChan - +// outSeqNr - +// acknr - +// inSeqNr - +// nChoked - +// nDropped - +// nSize - +//----------------------------------------------------------------------------- +void CNetChan::_FlowNewPacket(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize) +{ + float v7; // xmm4_8 (was double) + int v8; // r13d + int v9; // r14d + int v12; // r12d + int currentindex; // eax + int v16; // r15d + int v17; // r8d + int v18; // ebp + unsigned int v19; // eax + int v20; // r9 (was char) + int v21; // r8d + __int64 v22; // r14 + float time; // xmm0_4 + __int64 v24; // rdx + __int64 v25; // rcx + __int64 v26; // rdx + __int64 v27; // rcx + __int64 v28; // rdx + __int64 v29; // rcx + int v30; // edx + int v31; // r8 (was char) + float v32; // xmm0_4 + __int64 v33; // r9 + __int64 v34; // rax + __int64 v35; // rdx + int v36; // r8d + float v37; // xmm3_4 + __int64 result; // rax + float v39; // xmm1_4 + float v40; // xmm0_4 + float v41; // xmm1_4 + netframe_header_t* v42; // rdx + float v43; // xmm0_4 + float v44; // xmm2_4 + float v45; // xmm0_4 + + v7 = (float)*g_pNetTime; + v8 = flow; + v9 = inSeqNr; + netflow_t* pFlow = &pChan->m_DataFlow[flow]; + v12 = outSeqNr; + + netframe_header_t* pFrameHeader = nullptr; + netframe_t* pFrame = nullptr; + + currentindex = pFlow->currentindex; + if (outSeqNr > currentindex) + { + v16 = currentindex + 1; + if (currentindex + 1 <= outSeqNr) + { + v17 = outSeqNr - v16; + if (v17 + 1 >= 4) + { + v18 = nChoked + nDropped; + v19 = ((unsigned int)(v12 - v16 - 3) >> 2) + 1; + v20 = v16 + 2; + v21 = v17 - 2; + v22 = v19; + time = (float)*g_pNetTime; + v16 += 4 * v19; + do + { + v24 = (v20 - 2) & NET_FRAMES_MASK; + v25 = v24; + pFlow->frame_headers[v25].time = time; + pFlow->frame_headers[v25].valid = 0; + pFlow->frame_headers[v25].size = 0; + pFlow->frame_headers[v25].latency = -1.0; + pFlow->frames[v24].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + pFlow->frame_headers[v25].choked = 0; + pFlow->frames[v24].dropped = 0; + if (v21 + 2 < v18) + { + if (v21 + 2 >= nChoked) + pFlow->frames[v24].dropped = 1; + else + pFlow->frame_headers[(v20 - 2) & NET_FRAMES_MASK].choked = 1; + } + v26 = (v20 - 1) & NET_FRAMES_MASK; + v27 = v26; + pFlow->frame_headers[v27].time = time; + pFlow->frame_headers[v27].valid = 0; + pFlow->frame_headers[v27].size = 0; + pFlow->frame_headers[v27].latency = -1.0; + pFlow->frames[v26].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + pFlow->frame_headers[v27].choked = 0; + pFlow->frames[v26].dropped = 0; + if (v21 + 1 < v18) + { + if (v21 + 1 >= nChoked) + pFlow->frames[v26].dropped = 1; + else + pFlow->frame_headers[(v20 - 1) & NET_FRAMES_MASK].choked = 1; + } + v28 = v20 & NET_FRAMES_MASK; + v29 = v28; + pFlow->frame_headers[v29].time = time; + pFlow->frame_headers[v29].valid = 0; + pFlow->frame_headers[v29].size = 0; + pFlow->frame_headers[v29].latency = -1.0; + pFlow->frames[v28].avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + pFlow->frame_headers[v29].choked = 0; + pFlow->frames[v28].dropped = 0; + if (v21 < v18) + { + if (v21 >= nChoked) + pFlow->frames[v28].dropped = 1; + else + pFlow->frame_headers[v20 & NET_FRAMES_MASK].choked = 1; + } + pFrame = &pFlow->frames[(v20 + 1) & NET_FRAMES_MASK]; + pFrameHeader = &pFlow->frame_headers[(v20 + 1) & NET_FRAMES_MASK]; + pFrameHeader->time = time; + pFrameHeader->valid = 0; + pFrameHeader->size = 0; + pFrameHeader->latency = -1.0; + pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + pFrameHeader->choked = 0; + pFrame->dropped = 0; + if (v21 - 1 < v18) + { + if (v21 - 1 >= nChoked) + pFrame->dropped = 1; + else + pFrameHeader->choked = 1; + } + v21 -= 4; + v20 += 4; + --v22; + } while (v22); + v12 = outSeqNr; + v8 = flow; + v9 = inSeqNr; + } + if (v16 <= v12) + { + v30 = v12 - v16; + v31 = v16; + v33 = v12 - v16 + 1; + do + { + pFrame = &pFlow->frames[v31 & NET_FRAMES_MASK]; + pFrameHeader = &pFlow->frame_headers[v31 & NET_FRAMES_MASK]; + v32 = v7; + pFrameHeader->time = v32; + pFrameHeader->valid = 0; + pFrameHeader->size = 0; + pFrameHeader->latency = -1.0; + pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + pFrameHeader->choked = 0; + pFrame->dropped = 0; + if (v30 < nChoked + nDropped) + { + if (v30 >= nChoked) + pFrame->dropped = 1; + else + pFrameHeader->choked = 1; + } + --v30; + ++v31; + --v33; + } while (v33); + v9 = inSeqNr; + } + } + pFrame->dropped = nDropped; + pFrameHeader->choked = (short)nChoked; + pFrameHeader->size = nSize; + pFrameHeader->valid = 1; + pFrame->avg_latency = pChan->m_DataFlow[FLOW_OUTGOING].avglatency; + } + ++pFlow->totalpackets; + pFlow->currentindex = v12; + v34 = 544i64; + + if (!v8) + v34 = 3688i64; + + pFlow->current_frame = pFrame; + v35 = 548i64; + v36 = *(_DWORD*)(&pChan->m_bProcessingMessages + v34); + if (v9 > v36 - NET_FRAMES_BACKUP) + { + if (!v8) + v35 = 3692i64; + result = (__int64)pChan + 16 * (v9 & NET_FRAMES_MASK); + v42 = (netframe_header_t*)(result + v35); + if (v42->valid && v42->latency == -1.0) + { + v43 = 0.0; + v44 = fmax(0.0f, v7 - v42->time); + v42->latency = v44; + if (v44 >= 0.0) + v43 = v44; + else + v42->latency = 0.0; + v45 = v43 + pFlow->latency; + ++pFlow->totalupdates; + pFlow->latency = v45; + pFlow->maxlatency = fmaxf(pFlow->maxlatency, v42->latency); + } + } + else + { + if (!v8) + v35 = 3692i64; + + v37 = *(float*)(&pChan->m_bProcessingMessages + 16 * (v36 & NET_FRAMES_MASK) + v35); + result = v35 + 16i64 * (((_BYTE)v36 + 1) & NET_FRAMES_MASK); + v39 = v37 - *(float*)(&pChan->m_bProcessingMessages + result); + ++pFlow->totalupdates; + v40 = (float)((float)(v39 / 127.0) * (float)(v36 - v9)) + v7 - v37; + v41 = fmaxf(pFlow->maxlatency, v40); + pFlow->latency = v40 + pFlow->latency; + pFlow->maxlatency = v41; + } +} + //----------------------------------------------------------------------------- // Purpose: shutdown netchannel // Input : *this - @@ -170,10 +401,12 @@ bool CNetChan::HasPendingReliableData(void) void VNetChan::Attach() const { DetourAttach((PVOID*)&v_NetChan_Shutdown, &CNetChan::_Shutdown); + DetourAttach((PVOID*)&v_NetChan_FlowNewPacket, &CNetChan::_FlowNewPacket); DetourAttach((PVOID*)&v_NetChan_ProcessMessages, &CNetChan::_ProcessMessages); } void VNetChan::Detach() const { DetourDetach((PVOID*)&v_NetChan_Shutdown, &CNetChan::_Shutdown); + DetourDetach((PVOID*)&v_NetChan_FlowNewPacket, &CNetChan::_FlowNewPacket); DetourDetach((PVOID*)&v_NetChan_ProcessMessages, &CNetChan::_ProcessMessages); } diff --git a/r5dev/engine/net_chan.h b/r5dev/engine/net_chan.h index 501cde4e..ad719610 100644 --- a/r5dev/engine/net_chan.h +++ b/r5dev/engine/net_chan.h @@ -96,6 +96,9 @@ inline void(*v_NetChan_Shutdown)(CNetChan* pChan, const char* szReason, uint8_t inline CMemory p_NetChan_CanPacket; inline bool(*v_NetChan_CanPacket)(const CNetChan* pChan); +inline CMemory p_NetChan_FlowNewPacket; +inline void(*v_NetChan_FlowNewPacket)(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize); + inline CMemory p_NetChan_SendDatagram; inline int(*v_NetChan_SendDatagram)(CNetChan* pChan, bf_write* pMsg); @@ -145,6 +148,8 @@ public: static void _Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow); static bool _ProcessMessages(CNetChan* pChan, bf_read* pMsg); + static void _FlowNewPacket(CNetChan* pChan, int flow, int outSeqNr, int inSeqNr, int nChoked, int nDropped, int nSize); + void SetChoked(); void SetRemoteFramerate(float flFrameTime, float flFrameTimeStdDeviation); inline void SetRemoteCPUStatistics(uint8_t nStats) { m_nServerCPU = nStats; } @@ -251,6 +256,7 @@ class VNetChan : public IDetour LogFunAdr("CNetChan::Clear", p_NetChan_Clear.GetPtr()); LogFunAdr("CNetChan::Shutdown", p_NetChan_Shutdown.GetPtr()); LogFunAdr("CNetChan::CanPacket", p_NetChan_CanPacket.GetPtr()); + LogFunAdr("CNetChan::FlowNewPacket", p_NetChan_FlowNewPacket.GetPtr()); LogFunAdr("CNetChan::SendDatagram", p_NetChan_SendDatagram.GetPtr()); LogFunAdr("CNetChan::ProcessMessages", p_NetChan_ProcessMessages.GetPtr()); } @@ -265,6 +271,9 @@ class VNetChan : public IDetour p_NetChan_CanPacket = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B D9 75 15 48 8B 05 ?? ?? ?? ??"); v_NetChan_CanPacket = p_NetChan_CanPacket.RCast<bool (*)(const CNetChan*)>(); + p_NetChan_FlowNewPacket = g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 89 44 24 ?? 89 54 24 10 56"); + v_NetChan_FlowNewPacket = p_NetChan_FlowNewPacket.RCast<void (*)(CNetChan*, int, int, int, int, int, int)>(); + p_NetChan_SendDatagram = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 56 41 57 48 83 EC 70"); v_NetChan_SendDatagram = p_NetChan_SendDatagram.RCast<int (*)(CNetChan*, bf_write*)>();