From 7cfae98e81337a85939444437fa21a94e1f2b2b9 Mon Sep 17 00:00:00 2001 From: s1lent Date: Thu, 22 Feb 2018 17:31:28 +0700 Subject: [PATCH] Reworked NetChannel::ValidateFragments Added macros HLTV_FIXES Minor refactoring BitBuffer.cpp and cosmetic changes --- rehlds/HLTV/Console/msvc/Console.vcxproj | 4 +- rehlds/HLTV/Core/build.gradle | 2 +- rehlds/HLTV/Core/msvc/Core.vcxproj | 4 +- rehlds/HLTV/Core/src/NetSocket.cpp | 41 ++++++- rehlds/HLTV/Core/src/World.h | 8 +- rehlds/HLTV/DemoPlayer/build.gradle | 2 +- .../HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj | 4 +- rehlds/HLTV/Director/build.gradle | 2 +- rehlds/HLTV/Director/msvc/Director.vcxproj | 4 +- rehlds/HLTV/Proxy/build.gradle | 7 +- rehlds/HLTV/Proxy/msvc/Proxy.vcxproj | 4 +- rehlds/HLTV/common/BitBuffer.cpp | 114 +++++++++--------- rehlds/HLTV/common/BitBuffer.h | 3 +- rehlds/HLTV/common/NetChannel.cpp | 48 ++++++-- rehlds/HLTV/common/NetChannel.h | 84 +++++++------ 15 files changed, 196 insertions(+), 135 deletions(-) diff --git a/rehlds/HLTV/Console/msvc/Console.vcxproj b/rehlds/HLTV/Console/msvc/Console.vcxproj index 8661108..bb8326e 100644 --- a/rehlds/HLTV/Console/msvc/Console.vcxproj +++ b/rehlds/HLTV/Console/msvc/Console.vcxproj @@ -159,7 +159,7 @@ Use Level3 Disabled - HLTV;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;%(AdditionalIncludeDirectories) precompiled.h MultiThreadedDebug @@ -190,7 +190,7 @@ Disabled true true - HLTV;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;%(AdditionalIncludeDirectories) precompiled.h MultiThreaded diff --git a/rehlds/HLTV/Core/build.gradle b/rehlds/HLTV/Core/build.gradle index c89287d..0f3c129 100644 --- a/rehlds/HLTV/Core/build.gradle +++ b/rehlds/HLTV/Core/build.gradle @@ -20,7 +20,7 @@ void setupToolchain(NativeBinarySpec b) { cfg.projectInclude(project, '/..', '/../..', '/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared'); cfg.projectInclude(dep_bzip2, '/include') - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'CORE_MODULE' + cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'HLTV_FIXES', 'CORE_MODULE' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( diff --git a/rehlds/HLTV/Core/msvc/Core.vcxproj b/rehlds/HLTV/Core/msvc/Core.vcxproj index aca1150..d9f36a3 100644 --- a/rehlds/HLTV/Core/msvc/Core.vcxproj +++ b/rehlds/HLTV/Core/msvc/Core.vcxproj @@ -77,7 +77,7 @@ Use Level3 Disabled - HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;_DEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories) @@ -112,7 +112,7 @@ MaxSpeed true true - HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;NDEBUG;_WINDOWS;_USRDLL;CORE_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories) diff --git a/rehlds/HLTV/Core/src/NetSocket.cpp b/rehlds/HLTV/Core/src/NetSocket.cpp index 263dc73..748d928 100644 --- a/rehlds/HLTV/Core/src/NetSocket.cpp +++ b/rehlds/HLTV/Core/src/NetSocket.cpp @@ -297,6 +297,14 @@ int NetSocket::GetLong(unsigned char *pData, int size) { m_NetSplitPacket.currentSequence = sequenceNumber; m_NetSplitPacket.splitCount = packetCount; + +#ifdef HLTV_FIXES + m_NetSplitPacket.totalSize = 0; + + // clear part's sequence + for (int i = 0; i < MAX_SPLIT_FRAGMENTS; i++) + netSplitFlags[i] = -1; +#endif } unsigned int packetPayloadSize = size - sizeof(SPLITPACKET); @@ -310,16 +318,47 @@ int NetSocket::GetLong(unsigned char *pData, int size) m_NetSplitPacket.totalSize = packetPayloadSize + SPLIT_SIZE * (packetCount - 1); } - --m_NetSplitPacket.splitCount; + m_NetSplitPacket.splitCount--; netSplitFlags[packetNumber] = sequenceNumber; + +#ifdef HLTV_FIXES + if (SPLIT_SIZE * packetNumber + packetPayloadSize > MAX_UDP_PACKET) + { + m_System->DPrintf("WARNING! NetSocket::GetLong: Malformed packet size (%i, %i)\n", SPLIT_SIZE * packetNumber, packetPayloadSize); + m_NetSplitPacket.currentSequence = -1; + return -1; + } + + Q_memcpy(&m_NetSplitPacket.buffer[SPLIT_SIZE * packetNumber], pHeader + 1, packetPayloadSize); +#endif + } +#ifndef HLTV_FIXES Q_memcpy(&m_NetSplitPacket.buffer[SPLIT_SIZE * packetNumber], pHeader + 1, packetPayloadSize); +#endif if (m_NetSplitPacket.splitCount > 0) { return 0; } +#ifdef HLTV_FIXES + for (unsigned int i = 0; i < packetCount; i++) + { + if (netSplitFlags[i] != m_NetSplitPacket.currentSequence) + { + m_System->DPrintf("WARNING! NetSocket::GetLong: Split packet without all %i parts, part %i had wrong sequence %i/%i\n", + packetCount, + i + 1, + netSplitFlags[i], + m_NetSplitPacket.currentSequence); + + m_NetSplitPacket.currentSequence = -1; + return -1; + } + } +#endif + m_NetSplitPacket.currentSequence = -1; if (m_NetSplitPacket.totalSize > MAX_UDP_PACKET) { diff --git a/rehlds/HLTV/Core/src/World.h b/rehlds/HLTV/Core/src/World.h index 565d23e..09e98dd 100644 --- a/rehlds/HLTV/Core/src/World.h +++ b/rehlds/HLTV/Core/src/World.h @@ -252,11 +252,11 @@ protected: int m_MaxInstanced_BaseLine; -#ifdef HOOK_HLTV - char m_Lightstyles[MAX_LIGHTSTYLES][65]; -#else +#if defined(HLTV_FIXES) && !defined(HOOK_HLTV) char m_Lightstyles[MAX_LIGHTSTYLES][64]; -#endif // HOOK_HLTV +#else + char m_Lightstyles[MAX_LIGHTSTYLES][65]; +#endif movevars_t m_MoveVars; BSPModel m_WorldModel; diff --git a/rehlds/HLTV/DemoPlayer/build.gradle b/rehlds/HLTV/DemoPlayer/build.gradle index 6c78149..65629d2 100644 --- a/rehlds/HLTV/DemoPlayer/build.gradle +++ b/rehlds/HLTV/DemoPlayer/build.gradle @@ -16,7 +16,7 @@ void setupToolchain(NativeBinarySpec b) { boolean useGcc = project.hasProperty("useGcc") def cfg = rootProject.createToolchainConfig(b); cfg.projectInclude(project, '/..', '/../..', '/src', '/../common', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared'); - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'DEMOPLAYER_MODULE' + cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'HLTV_FIXES', 'DEMOPLAYER_MODULE' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( diff --git a/rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj b/rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj index 8a6bd55..b01b6d0 100644 --- a/rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj +++ b/rehlds/HLTV/DemoPlayer/msvc/DemoPlayer.vcxproj @@ -125,7 +125,7 @@ Use Level3 Disabled - HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;_DEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) precompiled.h $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\game_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories) MultiThreadedDebug @@ -155,7 +155,7 @@ MaxSpeed true true - HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitiHOOons) + HLTV;HLTV_FIXES;WIN32;NDEBUG;_WINDOWS;_USRDLL;DEMOPLAYER_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitiHOOons) precompiled.h $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories) MultiThreaded diff --git a/rehlds/HLTV/Director/build.gradle b/rehlds/HLTV/Director/build.gradle index bbe6564..213fbbd 100644 --- a/rehlds/HLTV/Director/build.gradle +++ b/rehlds/HLTV/Director/build.gradle @@ -16,7 +16,7 @@ void setupToolchain(NativeBinarySpec b) { boolean useGcc = project.hasProperty("useGcc") def cfg = rootProject.createToolchainConfig(b); cfg.projectInclude(project, '/..', '/../..', '/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared'); - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'DIRECTOR_MODULE' + cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'HLTV_FIXES', 'DIRECTOR_MODULE' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( diff --git a/rehlds/HLTV/Director/msvc/Director.vcxproj b/rehlds/HLTV/Director/msvc/Director.vcxproj index efb8178..34689cc 100644 --- a/rehlds/HLTV/Director/msvc/Director.vcxproj +++ b/rehlds/HLTV/Director/msvc/Director.vcxproj @@ -76,7 +76,7 @@ Use Level3 Disabled - HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;_DEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories) precompiled.h MultiThreadedDebug @@ -107,7 +107,7 @@ MaxSpeed true true - HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;NDEBUG;_WINDOWS;_USRDLL;DIRECTOR_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;%(AdditionalIncludeDirectories) precompiled.h MultiThreaded diff --git a/rehlds/HLTV/Proxy/build.gradle b/rehlds/HLTV/Proxy/build.gradle index dc191a0..92e2deb 100644 --- a/rehlds/HLTV/Proxy/build.gradle +++ b/rehlds/HLTV/Proxy/build.gradle @@ -16,13 +16,12 @@ project.ext.dep_bzip2 = project(':dep/bzip2') void setupToolchain(NativeBinarySpec b) { boolean useGcc = project.hasProperty("useGcc") - boolean rehltvFixes = b.flavor.name.contains('rehltvFixes') def cfg = rootProject.createToolchainConfig(b); cfg.projectInclude(project, '/..', '/../..', '/src', '/../Director/src', '/../../common', '/../../engine', '/../../public', '/../../public/rehlds', '/../../pm_shared'); cfg.projectInclude(dep_bzip2, '/include') - cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'CORE_MODULE' + cfg.singleDefines 'USE_BREAKPAD_HANDLER', 'HLTV', 'HLTV_FIXES', 'PROXY_MODULE' if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( @@ -66,10 +65,6 @@ void setupToolchain(NativeBinarySpec b) { cfg.extraLibs "steam_api" } - if (rehltvFixes) { - cfg.singleDefines 'REHLTV_FIXES', 'REHLTV_CHECKS' - } - ToolchainConfigUtils.apply(project, cfg, b); } diff --git a/rehlds/HLTV/Proxy/msvc/Proxy.vcxproj b/rehlds/HLTV/Proxy/msvc/Proxy.vcxproj index 822b067..bff3c46 100644 --- a/rehlds/HLTV/Proxy/msvc/Proxy.vcxproj +++ b/rehlds/HLTV/Proxy/msvc/Proxy.vcxproj @@ -384,7 +384,7 @@ Use Level3 Disabled - HLTV;WIN32;_DEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;_DEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\Director\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories) precompiled.h MultiThreadedDebug @@ -418,7 +418,7 @@ MaxSpeed true true - HLTV;WIN32;NDEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + HLTV;HLTV_FIXES;WIN32;NDEBUG;_WINDOWS;_USRDLL;PROXY_MODULE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\..\;$(ProjectDir)\..\..\..\;$(ProjectDir)\..\..\Director\src;$(ProjectDir)\..\..\..\common;$(ProjectDir)\..\..\..\engine;$(ProjectDir)\..\..\..\public;$(ProjectDir)\..\..\..\public\rehlds;$(ProjectDir)\..\..\..\pm_shared;$(ProjectDir)\..\..\..\..\dep\bzip2\include;%(AdditionalIncludeDirectories) precompiled.h MultiThreaded diff --git a/rehlds/HLTV/common/BitBuffer.cpp b/rehlds/HLTV/common/BitBuffer.cpp index d309a4b..f730896 100644 --- a/rehlds/HLTV/common/BitBuffer.cpp +++ b/rehlds/HLTV/common/BitBuffer.cpp @@ -69,7 +69,7 @@ const uint32 INVBITTABLE[] = BitBuffer::BitBuffer() : m_Data(nullptr), m_CurByte(nullptr), - m_CurSize(0), + m_CurBit(0), m_MaxSize(0), m_Overflowed(false), m_LittleEndian(false), @@ -83,7 +83,7 @@ BitBuffer::BitBuffer(void *newData, unsigned int size) m_Data = (unsigned char *)newData; m_CurByte = m_Data; - m_CurSize = 0; + m_CurBit = 0; m_MaxSize = size; m_Overflowed = false; m_LittleEndian = true; @@ -100,7 +100,7 @@ BitBuffer::BitBuffer(unsigned int size) m_Data = nullptr; m_CurByte = nullptr; - m_CurSize = 0; + m_CurBit = 0; m_MaxSize = size; m_Overflowed = false; m_LittleEndian = false; @@ -114,7 +114,7 @@ bool BitBuffer::Resize(unsigned int size) Free(); m_Data = (unsigned char *)Mem_ZeroMalloc(size + 4); - m_CurSize = 0; + m_CurBit = 0; m_Overflowed = false; if (m_Data) @@ -139,7 +139,7 @@ void BitBuffer::Clear() Q_memset(m_Data, 0, m_MaxSize); m_CurByte = m_Data; - m_CurSize = 0; + m_CurBit = 0; m_Overflowed = false; m_LittleEndian = true; @@ -147,13 +147,13 @@ void BitBuffer::Clear() int BitBuffer::CurrentBit() { - return m_CurSize + 8 * (m_CurByte - m_Data); + return m_CurBit + 8 * (m_CurByte - m_Data); } void BitBuffer::Reset() { m_CurByte = m_Data; - m_CurSize = 0; + m_CurBit = 0; m_Overflowed = false; m_LittleEndian = true; @@ -168,7 +168,7 @@ void BitBuffer::Free() m_Data = nullptr; m_CurByte = nullptr; - m_CurSize = 0; + m_CurBit = 0; m_MaxSize = 0; m_OwnData = false; @@ -187,26 +187,26 @@ unsigned int BitBuffer::ReadBits(int numbits) return -1; } - int bits = m_CurSize + numbits; + int bits = m_CurBit + numbits; if (bits <= 32) { - result = (*(unsigned int *)m_CurByte >> m_CurSize) & ROWBITTABLE[numbits]; + result = (*(unsigned int *)m_CurByte >> m_CurBit) & ROWBITTABLE[numbits]; m_CurByte += numbits >> 3; - m_CurSize += numbits & 7; + m_CurBit += numbits & 7; - if (m_CurSize > 7) + if (m_CurBit > 7) { - m_CurSize &= 7; + m_CurBit &= 7; m_CurByte++; } } else { - unsigned int data = *(unsigned int *)m_CurByte >> m_CurSize; + unsigned int data = *(unsigned int *)m_CurByte >> m_CurBit; m_CurByte += 4; - result = ((ROWBITTABLE[bits & 7] & *(unsigned int *)m_CurByte) << (32 - m_CurSize)) | data; - m_CurSize = bits & 7; + result = ((ROWBITTABLE[bits & 7] & *(unsigned int *)m_CurByte) << (32 - m_CurBit)) | data; + m_CurBit = bits & 7; } } else @@ -235,26 +235,26 @@ int BitBuffer::ReadBit() { if (m_LittleEndian) { - if (m_CurSize == 7) + if (m_CurBit == 7) { - m_CurSize = 0; + m_CurBit = 0; result = (*m_CurByte++ >> 7) & 1; } else { - result = ((unsigned int)*m_CurByte >> m_CurSize++) & 1; + result = ((unsigned int)*m_CurByte >> m_CurBit++) & 1; } } else { - if (m_CurSize == 7) + if (m_CurBit == 7) { - m_CurSize = 0; + m_CurBit = 0; result = *m_CurByte++ & 1; } else { - result = ((unsigned int)*m_CurByte >> (7 - m_CurSize++)) & 1; + result = ((unsigned int)*m_CurByte >> (7 - m_CurBit++)) & 1; } } } @@ -264,11 +264,11 @@ int BitBuffer::ReadBit() unsigned int BitBuffer::PeekBits(int numbits) { - int oldcurrentBit = m_CurSize; + int oldcurrentBit = m_CurBit; unsigned char *oldcurrentByte = m_CurByte; unsigned int data = ReadBits(numbits); - m_CurSize = oldcurrentBit; + m_CurBit = oldcurrentBit; m_CurByte = oldcurrentByte; return data; } @@ -316,7 +316,7 @@ bool BitBuffer::ReadBuf(int iSize, void *pbuf) return false; } - if (m_CurSize) + if (m_CurBit) { int i, j; unsigned int *p = (unsigned int *)pbuf; @@ -402,7 +402,7 @@ void BitBuffer::WriteBit(int c) if (m_LittleEndian) { - if (m_CurSize == 7) + if (m_CurBit == 7) { if (c) { @@ -414,20 +414,20 @@ void BitBuffer::WriteBit(int c) } m_CurByte++; - m_CurSize = 0; + m_CurBit = 0; } else { if (c) { - m_CurByte[0] |= BITTABLE[ m_CurSize ]; + m_CurByte[0] |= BITTABLE[ m_CurBit ]; } else { - m_CurByte[0] &= INVBITTABLE[ m_CurSize ]; + m_CurByte[0] &= INVBITTABLE[ m_CurBit ]; } - m_CurSize++; + m_CurBit++; } } else @@ -436,13 +436,13 @@ void BitBuffer::WriteBit(int c) static unsigned char inv_masks[] = { 0x7Fu, 0xBFu, 0xDFu, 0xEFu, 0xF7u, 0xFBu, 0xFDu, 0xFEu }; if (c) - m_CurByte[0] |= masks[ m_CurSize ]; + m_CurByte[0] |= masks[ m_CurBit ]; else - m_CurByte[0] &= inv_masks[ m_CurSize ]; + m_CurByte[0] &= inv_masks[ m_CurBit ]; - if (++m_CurSize == 8) + if (++m_CurBit == 8) { - m_CurSize = 0; + m_CurBit = 0; m_CurByte++; } } @@ -461,26 +461,26 @@ void BitBuffer::WriteBits(unsigned int data, int numbits) return; } - int bits = numbits + m_CurSize; + int bits = numbits + m_CurBit; if (bits <= 32) { - *(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurSize; + *(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurBit; m_CurByte = &m_CurByte[numbits >> 3]; - m_CurSize = m_CurSize + (numbits & 7); + m_CurBit = m_CurBit + (numbits & 7); - if (m_CurSize > 7) + if (m_CurBit > 7) { - m_CurSize = m_CurSize & 7; + m_CurBit = m_CurBit & 7; m_CurByte = m_CurByte + 1; } } else { - *(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurSize; + *(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) << m_CurBit; - int leftBits = (32 - m_CurSize); - m_CurSize = (m_CurSize + numbits) & 7; + int leftBits = (32 - m_CurBit); + m_CurBit = (m_CurBit + numbits) & 7; m_CurByte += 4; *(uint32 *)m_CurByte |= (ROWBITTABLE[numbits] & data) >> leftBits; @@ -581,7 +581,7 @@ void BitBuffer::WriteBuf(const void *buf, int iSize) return; } - if (m_CurSize) + if (m_CurBit) { int i, j; unsigned int *p = (unsigned int *)buf; @@ -623,7 +623,7 @@ void BitBuffer::WriteHiresAngle(float f) int BitBuffer::CurrentSize() { - return (m_CurSize != 0) + m_CurByte - m_Data; + return (m_CurBit != 0) + m_CurByte - m_Data; } unsigned char *BitBuffer::CurrentByte() @@ -638,10 +638,10 @@ int BitBuffer::SpaceLeft() void BitBuffer::AlignByte() { - if (m_CurSize) + if (m_CurBit) { m_CurByte++; - m_CurSize = 0; + m_CurBit = 0; } } @@ -712,7 +712,7 @@ void BitBuffer::WriteBitString(const char *p) void BitBuffer::StartBitMode() { - if (m_CurSize) { + if (m_CurBit) { m_Overflowed = true; } } @@ -739,7 +739,7 @@ void BitBuffer::SetBuffer(void *buffer, int size) m_Data = (unsigned char *)buffer; m_CurByte = (unsigned char *)buffer; m_MaxSize = size; - m_CurSize = 0; + m_CurBit = 0; m_OwnData = false; m_Overflowed = false; @@ -811,22 +811,22 @@ void BitBuffer::SkipBits(int numbits) return; } - int bits = m_CurSize + numbits; + int bits = m_CurBit + numbits; if (bits <= 32) { m_CurByte += numbits >> 3; - m_CurSize += numbits & 7; + m_CurBit += numbits & 7; - if (m_CurSize > 7) + if (m_CurBit > 7) { - m_CurSize &= 7; + m_CurBit &= 7; m_CurByte++; } } else { m_CurByte += 4; - m_CurSize = bits & 7; + m_CurBit = bits & 7; } } else @@ -835,14 +835,14 @@ void BitBuffer::SkipBits(int numbits) while (d > 0) { --d; - if (m_CurSize == 7) + if (m_CurBit == 7) { m_CurByte++; - m_CurSize = 0; + m_CurBit = 0; } else { - m_CurSize++; + m_CurBit++; } } } @@ -870,7 +870,7 @@ void BitBuffer::FastClear() Q_memset(m_Data, 0, iSize); m_CurByte = m_Data; - m_CurSize = 0; + m_CurBit = 0; m_Overflowed = false; m_LittleEndian = true; diff --git a/rehlds/HLTV/common/BitBuffer.h b/rehlds/HLTV/common/BitBuffer.h index 119e6b6..0e0b2b7 100644 --- a/rehlds/HLTV/common/BitBuffer.h +++ b/rehlds/HLTV/common/BitBuffer.h @@ -41,7 +41,6 @@ public: unsigned char *CurrentByte(); int GetMaxSize() const { return m_MaxSize; } - unsigned int GetCurSize() const { return m_CurSize; } unsigned char *GetData() const { return m_Data; } bool IsOverflowed() const { return m_Overflowed; } @@ -108,7 +107,7 @@ public: bool m_Overflowed; unsigned char *m_Data; unsigned char *m_CurByte; - int m_CurSize; + int m_CurBit; int m_MaxSize; protected: diff --git a/rehlds/HLTV/common/NetChannel.cpp b/rehlds/HLTV/common/NetChannel.cpp index 34cc85d..ce4c6e5 100644 --- a/rehlds/HLTV/common/NetChannel.cpp +++ b/rehlds/HLTV/common/NetChannel.cpp @@ -310,7 +310,12 @@ void NetChannel::UpdateFlow(int stream) void NetChannel::TransmitOutgoing() { +#ifdef HLTV_FIXES + byte send_buf[MAX_UDP_PACKET]; +#else byte send_buf[NET_MAX_MESSAGE]; +#endif + BitBuffer data(send_buf, sizeof(send_buf)); bool send_reliable; @@ -336,7 +341,7 @@ void NetChannel::TransmitOutgoing() // check for reliable message overflow if (m_reliableStream.IsOverflowed()) { - m_System->DPrintf("Transmit:Outgoing m_reliableStream overflow (%s)\n", m_remote_address.ToString()); + m_System->DPrintf("NetChannel::Transmit:Outgoing m_reliableStream overflow (%s)\n", m_remote_address.ToString()); m_reliableStream.Clear(); return; } @@ -344,7 +349,7 @@ void NetChannel::TransmitOutgoing() // check for unreliable message overflow if (m_unreliableStream.IsOverflowed()) { - m_System->DPrintf("Transmit:Outgoing m_unreliableStream overflow (%s)\n", m_remote_address.ToString()); + m_System->DPrintf("NetChannel::Transmit:Outgoing m_unreliableStream overflow (%s)\n", m_remote_address.ToString()); m_unreliableStream.Clear(); } @@ -653,8 +658,7 @@ bool NetChannel::CheckForCompletion(int stream, int intotalbuffers) return false; } -#ifdef REHLTV_FIXES -bool NetChannel::ValidateFragments(int pkt_size, qboolean *frag_message, unsigned int *fragid, int *frag_offset, int *frag_length) +bool NetChannel::ValidateFragments(BitBuffer &buf, bool *frag_message, unsigned int *fragid, int *frag_offset, int *frag_length) { for (int i = 0; i < MAX_STREAMS; i++) { @@ -664,32 +668,35 @@ bool NetChannel::ValidateFragments(int pkt_size, qboolean *frag_message, unsigne // total fragments should be <= MAX_FRAGMENTS and current fragment can't be > total fragments if (i == FRAG_NORMAL_STREAM && FRAG_GETCOUNT(fragid[i]) > MAX_NORMAL_FRAGMENTS) return false; + if (i == FRAG_FILE_STREAM && FRAG_GETCOUNT(fragid[i]) > MAX_FILE_FRAGMENTS) return false; + if (FRAG_GETID(fragid[i]) > FRAG_GETCOUNT(fragid[i])) return false; + if (!frag_length[i]) return false; + if ((size_t)frag_length[i] > FRAGMENT_MAX_SIZE || (size_t)frag_offset[i] > MAX_POSSIBLE_MSG - 1) return false; int frag_end = frag_offset[i] + frag_length[i]; // end of fragment is out of the packet - if (frag_end + msg_readcount > pkt_size) + if (frag_end + buf.CurrentSize() > buf.GetMaxSize()) return false; // fragment overlaps next stream's fragment or placed after it for (int j = i + 1; j < MAX_STREAMS; j++) { - if (frag_end > frag_offset[j] && frag_message[j]) // don't add msg_readcount for comparison + if (frag_end > frag_offset[j] && frag_message[j]) // don't add buf.CurrentSize() for comparison return false; } } return true; } -#endif // REHLTV_FIXES void NetChannel::ProcessIncoming(unsigned char *data, int size) { @@ -760,8 +767,8 @@ void NetChannel::ProcessIncoming(unsigned char *data, int size) } } -#ifdef REHLTV_FIXES - if (!ValidateFragments(size, frag_message, fragid, frag_offset, frag_length)) +#ifdef HLTV_FIXES + if (!ValidateFragments(message, frag_message, fragid, frag_offset, frag_length)) return; #endif } @@ -801,7 +808,12 @@ void NetChannel::ProcessIncoming(unsigned char *data, int size) // clear the buffer to make way for the next if (reliable_ack == (unsigned int)m_reliable_sequence) { + // Make sure we actually could have ack'd this message +#ifdef HLTV_FIXES + if (sequence_ack >= (unsigned)m_last_reliable_sequence) +#else if (m_incoming_acknowledged + 1 >= m_last_reliable_sequence) +#endif { // it has been received m_reliableOutSize = 0; @@ -1147,6 +1159,24 @@ void NetChannel::CopyNormalFragments() p = n; } +#ifdef HLTV_FIXES + if (packet->data.IsOverflowed()) + { + if (packet->address.IsValid()) + { + m_System->Printf("WARNING! NetChannel::CopyNormalFragments: Incoming overflowed from %s\n", packet->address.ToString()); + } + else + { + m_System->Printf("WARNING! NetChannel::CopyNormalFragments: Incoming overflowed\n"); + } + + packet->data.Clear(); + m_incomingbufs[FRAG_NORMAL_STREAM] = nullptr; + return; + } +#endif + if (*(uint32 *)packet->data.GetData() == MAKEID('B', 'Z', '2', '\0')) { char uncompressed[65536]; diff --git a/rehlds/HLTV/common/NetChannel.h b/rehlds/HLTV/common/NetChannel.h index 18b00f9..4a3b292 100644 --- a/rehlds/HLTV/common/NetChannel.h +++ b/rehlds/HLTV/common/NetChannel.h @@ -51,41 +51,41 @@ enum MAX_FLOWS }; -#define MAX_LATENT 32 -#define FRAGMENT_MAX_SIZE 1400 // Size of fragmentation buffer internal buffers -#define CLIENT_FRAGMENT_SIZE_ONCONNECT 128 -#define CUSTOMIZATION_MAX_SIZE 20480 +#define MAX_LATENT 32 +#define FRAGMENT_MAX_SIZE 1400 // Size of fragmentation buffer internal buffers +#define CLIENT_FRAGMENT_SIZE_ONCONNECT 128 +#define CUSTOMIZATION_MAX_SIZE 20480 // Client sends normal fragments only while connecting -#define MAX_NORMAL_FRAGMENTS (MAX_POSSIBLE_MSG / CLIENT_FRAGMENT_SIZE_ONCONNECT) +#define MAX_NORMAL_FRAGMENTS (MAX_POSSIBLE_MSG / CLIENT_FRAGMENT_SIZE_ONCONNECT) // While client is connecting it sending fragments with minimal size, also it transfers sprays with minimal fragments... // But with sv_delayed_spray_upload it sends with cl_dlmax fragment size -#define MAX_FILE_FRAGMENTS (CUSTOMIZATION_MAX_SIZE / FRAGMENT_C2S_MIN_SIZE) +#define MAX_FILE_FRAGMENTS (CUSTOMIZATION_MAX_SIZE / FRAGMENT_C2S_MIN_SIZE) -#define UDP_HEADER_SIZE 28 -#define MAX_RELIABLE_PAYLOAD 1200 +#define UDP_HEADER_SIZE 28 +#define MAX_RELIABLE_PAYLOAD 1200 -#define MAKE_FRAGID(id, count) (((id & 0xffff) << 16) | (count & 0xffff)) -#define FRAG_GETID(fragid) ((fragid >> 16) & 0xffff) -#define FRAG_GETCOUNT(fragid) (fragid & 0xffff) +#define MAKE_FRAGID(id, count) (((id & 0xffff) << 16) | (count & 0xffff)) +#define FRAG_GETID(fragid) ((fragid >> 16) & 0xffff) +#define FRAG_GETCOUNT(fragid) (fragid & 0xffff) // Max length of a reliable message -#define MAX_MSGLEN 3990 // 10 reserved for fragheader? -#define MAX_POSSIBLE_MSG 65536 +#define MAX_MSGLEN 3990 // 10 reserved for fragheader? +#define MAX_POSSIBLE_MSG 65536 -#define MAX_ROUTEABLE_PACKET 1400 -#define MIN_ROUTEABLE_PACKET 16 +#define MAX_ROUTEABLE_PACKET 1400 +#define MIN_ROUTEABLE_PACKET 16 -#define SPLIT_SIZE (MAX_ROUTEABLE_PACKET - sizeof(SPLITPACKET)) +#define SPLIT_SIZE (MAX_ROUTEABLE_PACKET - sizeof(SPLITPACKET)) // Pad this to next higher 16 byte boundary // This is the largest packet that can come in/out over the wire, before processing the header // bytes will be stripped by the networking channel layer // #define NET_MAX_MESSAGE PAD_NUMBER( ( MAX_MSGLEN + HEADER_BYTES ), 16 ) // This is currently used value in the engine. TODO: define above gives 4016, check it why. -#define NET_MAX_MESSAGE 4037 -#define NET_HEADER_FLAG_SPLITPACKET -2 +#define NET_MAX_MESSAGE 4037 +#define NET_HEADER_FLAG_SPLITPACKET -2 class IBaseSystem; @@ -125,7 +125,7 @@ public: typedef struct flowstats_s { int size; // Size of message sent/received - double time; // Time that message was sent/received + double time; // Time that message was sent/received } flowstats_t; typedef struct flow_s @@ -143,27 +143,25 @@ public: typedef struct fragbuf_s { struct fragbuf_s *next; // Next buffer in chain - int bufferId; // Id of this buffer - byte data[FRAGMENT_MAX_SIZE]; // The actual data sits here + int bufferId; // Id of this buffer + byte data[FRAGMENT_MAX_SIZE]; // The actual data sits here - int size; // Size of data to read at that offset - bool isfile; // Is this a file buffer? - bool isbuffer; // Is this file buffer from memory ( custom decal, etc. ). + int size; // Size of data to read at that offset + bool isfile; // Is this a file buffer? + bool isbuffer; // Is this file buffer from memory ( custom decal, etc. ). char fileName[MAX_PATH]; // Name of the file to save out on remote host - int fOffset; // Offset in file from which to read data + int fOffset; // Offset in file from which to read data } fragbuf_t; // Waiting list of fragbuf chains typedef struct fragbufwaiting_s { - struct fragbufwaiting_s *next; // Next chain in waiting list - int fragbufcount; // Number of buffers in this chain + struct fragbufwaiting_s *next; // Next chain in waiting list + int fragbufcount; // Number of buffers in this chain fragbuf_t *fragbufs; // The actual buffers } fragbufwaiting_t; -#ifdef REHLTV_FIXES - bool ValidateFragments(int pkt_size, qboolean *frag_message, unsigned int *fragid, int *frag_offset, int *frag_length); -#endif + bool ValidateFragments(BitBuffer &buf, bool *frag_message, unsigned int *fragid, int *frag_offset, int *frag_length); bool CreateFragmentsFromFile(char *fileName); bool CopyFileFragments(); void GetFlowStats(float *avgInKBSec, float *avgOutKBSec); @@ -191,25 +189,25 @@ public: NetAddress m_remote_address; // Address this channel is talking to. double m_last_received; double m_last_send; - double m_connect_time; // Time when channel was connected. + double m_connect_time; // Time when channel was connected. float m_timeout; int m_max_bandwidth_rate; double m_send_interval; - int m_updaterate; // Bandwidth choke, bytes per second - double m_cleartime; // If realtime > cleartime, free to send next packet + int m_updaterate; // Bandwidth choke, bytes per second + double m_cleartime; // If realtime > cleartime, free to send next packet bool m_keep_alive; bool m_crashed; bool m_connected; // Sequencing variables - int m_incoming_sequence; // Increasing count of sequence numbers - int m_incoming_acknowledged; // # of last outgoing message that has been ack'd. + int m_incoming_sequence; // Increasing count of sequence numbers + int m_incoming_acknowledged; // # of last outgoing message that has been ack'd. int m_incoming_reliable_acknowledged; // Toggles T/F as reliable messages are received. - int m_incoming_reliable_sequence; // single bit, maintained local - int m_outgoing_sequence; // Message we are sending to remote - int m_reliable_sequence; // Whether the message contains reliable payload, single bit - int m_last_reliable_sequence; // Outgoing sequence number of last send that had reliable data + int m_incoming_reliable_sequence; // single bit, maintained local + int m_outgoing_sequence; // Message we are sending to remote + int m_reliable_sequence; // Whether the message contains reliable payload, single bit + int m_last_reliable_sequence; // Outgoing sequence number of last send that had reliable data void *m_connection_status; @@ -228,11 +226,11 @@ public: int m_reliable_fragment[MAX_STREAMS]; // Is reliable waiting buf a fragment? size_t m_reliable_fragid[MAX_STREAMS]; // Buffer id for each waiting fragment - fragbuf_t *m_fragbufs[MAX_STREAMS]; // The current fragment being set - int m_fragbufcount[MAX_STREAMS]; // The total number of fragments in this stream + fragbuf_t *m_fragbufs[MAX_STREAMS]; // The current fragment being set + int m_fragbufcount[MAX_STREAMS]; // The total number of fragments in this stream - int16 m_frag_startpos[MAX_STREAMS]; // Position in outgoing buffer where frag data starts - int16 m_frag_length[MAX_STREAMS]; // Length of frag data in the buffer + int16 m_frag_startpos[MAX_STREAMS]; // Position in outgoing buffer where frag data starts + int16 m_frag_length[MAX_STREAMS]; // Length of frag data in the buffer fragbuf_t *m_incomingbufs[MAX_STREAMS]; // Incoming fragments are stored here