diff --git a/css_zstd_training_set.dictionary b/css_zstd_training_set.dictionary new file mode 100644 index 0000000000..bd91aaefc4 Binary files /dev/null and b/css_zstd_training_set.dictionary differ diff --git a/css_zstd_training_set.tar.gz b/css_zstd_training_set.tar.gz new file mode 100644 index 0000000000..cb0178906b Binary files /dev/null and b/css_zstd_training_set.tar.gz differ diff --git a/engine/common.cpp b/engine/common.cpp index 74c90b6b03..74597905c3 100644 --- a/engine/common.cpp +++ b/engine/common.cpp @@ -9,12 +9,16 @@ #include "host.h" #include #include "draw.h" +#include "strtools.h" +#include "sysexternal.h" +#include "utlbuffer.h" #include "zone.h" #include "sys.h" #include #include #include #include +#include #include "common.h" #ifdef OSX #include @@ -44,6 +48,8 @@ #include #include "tier1/lzss.h" #include "tier1/snappy.h" +#include "zstd.h" +#include // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1292,6 +1298,160 @@ bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const return true; } +unsigned int COM_GetIdealDestinationCompressionBufferSize_ZSTD( + unsigned int uncompressedSize) +{ + return 4 + ZSTD_compressBound(uncompressedSize); +} + +static constexpr int ZSTD_COMPRESSION_LEVEL = 999; +static auto g_pZSTDCCtx = ZSTD_createCCtx(); + +template +static T* GetZSTD_CDictionary() +{ + static T* dict = nullptr; + static constexpr auto dictionaryFilePath = "bin/zstd.dictionary"; + + static std::once_flag flag; + std::call_once(flag, + [&] + { + CUtlBuffer buffer; + if (!g_pFileSystem->ReadFile(dictionaryFilePath, + "DEFAULT_WRITE_PATH", + buffer)) + { + Sys_Error("g_pZSTDInfo: could not find " + "dictionary at %s!\n", + dictionaryFilePath); + } + + if constexpr (std::is_same::value) + { + dict = ZSTD_createCDict(buffer.Base(), + buffer.Size(), + ZSTD_COMPRESSION_LEVEL); + } + else if constexpr (std::is_same::value) + { + dict = ZSTD_createDDict(buffer.Base(), + buffer.Size()); + } + + ErrorIfNot(dict != NULL, ("GetZSTD_Dictionary() failed!\n")); + }); + + return dict; +}; + +void* COM_CompressBuffer_ZSTD(const void* source, + unsigned int sourceLen, + unsigned int* compressedLen, + unsigned int maxCompressedLen) +{ + Assert( source ); + Assert( compressedLen ); + + // Allocate a buffer big enough to hold the worst case. + unsigned nMaxCompressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( sourceLen ); + char *pCompressed = (char*)malloc( nMaxCompressedSize ); + if ( pCompressed == NULL ) + return NULL; + + // Do the compression + *(uint32 *)pCompressed = ZSTD_ID; + size_t compressed_length = ZSTD_compress_usingCDict( + g_pZSTDCCtx, + pCompressed + sizeof(uint32), + nMaxCompressedSize, + (const char*)source, + sourceLen, + GetZSTD_CDictionary()); + compressed_length += 4; + Assert( compressed_length <= nMaxCompressedSize ); + + // Check if this result is OK + if ( (maxCompressedLen != 0 && compressed_length > maxCompressedLen) || ZSTD_isError(compressed_length) ) + { + free( pCompressed ); + return NULL; + } + + *compressedLen = compressed_length; + return pCompressed; +} + +bool COM_BufferToBufferCompress_ZSTD(void* dest, + unsigned int* destLen, + const void* source, + unsigned int sourceLen) +{ + Assert( dest ); + Assert( destLen ); + Assert( source ); + +//#define ZSTD_GENERATE_TRAINING_SET + +#ifdef ZSTD_GENERATE_TRAINING_SET +static int zstdTrainingSetCount = 0; +#endif + +#ifdef ZSTD_GENERATE_TRAINING_SET + char fileName[64]; +#ifdef SWDS + const auto strContext = "dedicated"; +#else + const auto strContext = "client"; +#endif + + V_sprintf_safe(fileName, "css_zstd_training_set/%s_%i.bin", strContext, zstdTrainingSetCount++); + CUtlBuffer buffer; + buffer.CopyBuffer(source, sourceLen); + static std::once_flag flag; + std::call_once(flag, [&]{g_pFileSystem->CreateDirHierarchy("css_zstd_training_set", "DEFAULT_WRITE_PATH");}); + g_pFileSystem->WriteFile(fileName, NULL, buffer); +#endif + + // Check if we need to use a temporary buffer + unsigned nMaxCompressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( sourceLen ); + unsigned compressedLen = *destLen; + if ( compressedLen < nMaxCompressedSize ) + { + + // Yep. Use the other function to allocate the buffer of the right size and comrpess into it + void *temp = COM_CompressBuffer_ZSTD( source, sourceLen, &compressedLen, compressedLen ); + if ( temp == NULL ) + return false; + + // Copy over the data + V_memcpy( dest, temp, compressedLen ); + *destLen = compressedLen; + free( temp ); + return true; + } + + // We have room and should be able to compress directly + *(uint32 *)dest = ZSTD_ID; + size_t compressed_length = ZSTD_compress_usingCDict( + g_pZSTDCCtx, + (char*)dest + sizeof(uint32), + nMaxCompressedSize, + (const char*)source, + sourceLen, + GetZSTD_CDictionary()); + if (ZSTD_isError(compressed_length)) + { + return false; + } + + compressed_length += 4; + Assert( compressed_length <= nMaxCompressedSize ); + *destLen = compressed_length; + return true; +} + + //----------------------------------------------------------------------------- unsigned COM_GetIdealDestinationCompressionBufferSize_LZSS( unsigned int uncompressedSize ) { @@ -1354,6 +1514,19 @@ int COM_GetUncompressedSize( const void *compressed, unsigned int compressedLen size_t snappySize; if ( snappy::GetUncompressedLength( (const char *)compressed + sizeof(pHeader->id), compressedLen-sizeof(pHeader->id), &snappySize ) ) return (int)snappySize; + } + + if (pHeader->id == ZSTD_ID) + { + auto srcSize = ZSTD_getFrameContentSize((const char*)compressed + sizeof(pHeader->id), + compressedLen); + if (srcSize > std::numeric_limits::max() || ZSTD_isError(srcSize)) + { + Warning("COM_GetUncompressedSize: ZSTD Failed on getting uncompressed size\n"); + return -1; + } + + return static_cast(srcSize); } return -1; @@ -1400,6 +1573,25 @@ bool COM_BufferToBufferDecompress( void *dest, unsigned int *destLen, const void return true; } + if ( pHeader->id == ZSTD_ID ) + { + static auto g_pZSTDDCtx = ZSTD_createDCtx(); + + if (ZSTD_isError(ZSTD_decompress_usingDDict( + g_pZSTDDCtx, + (char*)dest, + *destLen, + (const char*)source + 4, + sourceLen - 4, + GetZSTD_CDictionary()))) + { + Warning( "NET_BufferToBufferDecompress: ZSTD decompression failed\n" ); + return false; + } + *destLen = nDecompressedSize; + return true; + } + // Mismatch between this routine and COM_GetUncompressedSize AssertMsg( false, "Unknown compression type?" ); return false; diff --git a/engine/common.h b/engine/common.h index bbb07a9859..3e7410eaf9 100644 --- a/engine/common.h +++ b/engine/common.h @@ -114,6 +114,10 @@ void *COM_CompressBuffer_Snappy( const void *source, unsigned int sourceLen, uns bool COM_BufferToBufferCompress_Snappy( void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen ); unsigned int COM_GetIdealDestinationCompressionBufferSize_Snappy( unsigned int uncompressedSize ); +void *COM_CompressBuffer_ZSTD( const void *source, unsigned int sourceLen, unsigned int *compressedLen, unsigned int maxCompressedLen = 0 ); +bool COM_BufferToBufferCompress_ZSTD( void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen ); +unsigned int COM_GetIdealDestinationCompressionBufferSize_ZSTD( unsigned int uncompressedSize ); + /// Fetch ideal working buffer size. You should allocate the buffer you wish to compress into /// at least this big, in order to get the best performance when using COM_BufferToBufferCompress inline unsigned int COM_GetIdealDestinationCompressionBufferSize( unsigned int uncompressedSize ) diff --git a/engine/net_chan.cpp b/engine/net_chan.cpp index 080c727ceb..dcd52929e3 100644 --- a/engine/net_chan.cpp +++ b/engine/net_chan.cpp @@ -6,6 +6,7 @@ #include "../utils/bzip2/bzlib.h" #include "net_chan.h" +#include "common.h" #include "tier1/strtools.h" #include "filesystem_engine.h" #include "demo.h" @@ -167,10 +168,10 @@ void CNetChan::CompressFragments() compressTimer.Start(); // fragments data is in memory - unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_Snappy( data->bytes ); + unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( data->bytes ); char * compressedData = new char[ compressedSize ]; - if ( COM_BufferToBufferCompress_Snappy( compressedData, &compressedSize, data->buffer, data->bytes ) && + if ( COM_BufferToBufferCompress_ZSTD( compressedData, &compressedSize, data->buffer, data->bytes ) && ( compressedSize < data->bytes ) ) { compressTimer.End(); @@ -218,7 +219,7 @@ void CNetChan::CompressFragments() { // create compressed version of source file unsigned int uncompressedSize = data->bytes; - unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_Snappy( uncompressedSize ); + unsigned int compressedSize = COM_GetIdealDestinationCompressionBufferSize_ZSTD( uncompressedSize ); char *uncompressed = new char[uncompressedSize]; char *compressed = new char[compressedSize]; @@ -226,7 +227,7 @@ void CNetChan::CompressFragments() g_pFileSystem->Read( uncompressed, data->bytes, data->file ); // compress into buffer - if ( COM_BufferToBufferCompress_Snappy( compressed, &compressedSize, uncompressed, uncompressedSize ) ) + if ( COM_BufferToBufferCompress_ZSTD( compressed, &compressedSize, uncompressed, uncompressedSize ) ) { // write out to disk compressed version hZipFile = g_pFileSystem->Open( compressedfilename, "wb", NULL ); diff --git a/engine/net_ws.cpp b/engine/net_ws.cpp index 6f3c656b2c..8ef01b3e2c 100644 --- a/engine/net_ws.cpp +++ b/engine/net_ws.cpp @@ -2346,6 +2346,8 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns struct sockaddr addr; int net_socket; + bUseCompression = true; + if ( net_showudp.GetInt() && (*(unsigned int*)data == CONNECTIONLESS_HEADER) ) { Assert( !bUseCompression ); @@ -2405,7 +2407,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns if ( pVoicePayload ) { VPROF_BUDGET( "NET_SendPacket_CompressVoice", VPROF_BUDGETGROUP_OTHER_NETWORKING ); - unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_Snappy( pVoicePayload->GetNumBytesWritten() ); + unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_ZSTD( pVoicePayload->GetNumBytesWritten() ); memCompressedVoice.EnsureCapacity( nCompressedLength + sizeof( unsigned short ) ); byte *pVoice = (byte *)memCompressedVoice.Base(); @@ -2417,7 +2419,7 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns byte *pOutput = NULL; if ( net_compressvoice.GetBool() ) { - if ( COM_BufferToBufferCompress_Snappy( pVoice, &nCompressedLength, pVoicePayload->GetData(), pVoicePayload->GetNumBytesWritten() + if ( COM_BufferToBufferCompress_ZSTD( pVoice, &nCompressedLength, pVoicePayload->GetData(), pVoicePayload->GetNumBytesWritten() && ( (int)nCompressedLength < pVoicePayload->GetNumBytesWritten() ) ) ) { pOutput = pVoice; @@ -2432,17 +2434,17 @@ int NET_SendPacket ( INetChannel *chan, int sock, const netadr_t &to, const uns } if ( bUseCompression ) - { + { VPROF_BUDGET( "NET_SendPacket_Compress", VPROF_BUDGETGROUP_OTHER_NETWORKING ); - unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_Snappy( length ); + unsigned int nCompressedLength = COM_GetIdealDestinationCompressionBufferSize_ZSTD( length ); memCompressed.EnsureCapacity( nCompressedLength + nVoiceBytes + sizeof( unsigned int ) ); *(int *)memCompressed.Base() = LittleLong( NET_HEADER_FLAG_COMPRESSEDPACKET ); - if ( COM_BufferToBufferCompress_Snappy( memCompressed.Base() + sizeof( unsigned int ), &nCompressedLength, data, length ) + if ( COM_BufferToBufferCompress_ZSTD( memCompressed.Base() + sizeof( unsigned int ), &nCompressedLength, data, length ) && (int)nCompressedLength < length ) - { + { data = memCompressed.Base(); length = nCompressedLength + sizeof( unsigned int ); diff --git a/engine/networkstringtable.cpp b/engine/networkstringtable.cpp index 6d537a5c60..ba4ac29286 100644 --- a/engine/networkstringtable.cpp +++ b/engine/networkstringtable.cpp @@ -1433,7 +1433,7 @@ void CNetworkStringTableContainer::WriteBaselines( bf_write &buf ) unsigned int compressedSize = (unsigned int)numBytes; char *compressedData = new char[numBytes]; - if ( COM_BufferToBufferCompress_Snappy( compressedData, &compressedSize, (char *)msg.m_DataOut.GetData(), numBytes ) ) + if ( COM_BufferToBufferCompress_ZSTD( compressedData, &compressedSize, (char *)msg.m_DataOut.GetData(), numBytes ) ) { msg.m_bDataCompressed = true; msg.m_DataOut.Reset(); diff --git a/engine/wscript b/engine/wscript index 2cb5d9fba5..0563ddf836 100755 --- a/engine/wscript +++ b/engine/wscript @@ -357,7 +357,7 @@ def build(bld): defines = [] - libs = ['tier0','vgui_controls','dmxloader','tier1','tier2','tier3','bitmap','vstdlib','appframework','datamodel','vtf','mathlib','steam_api','matsys_controls','BZ2','SDL2','JPEG','ZLIB','OPENAL','CURL' ] + libs = ['ZSTD','tier0','vgui_controls','dmxloader','tier1','tier2','tier3','bitmap','vstdlib','appframework','datamodel','vtf','mathlib','steam_api','matsys_controls','BZ2','SDL2','JPEG','ZLIB','OPENAL','CURL' ] if bld.env.DEST_OS == 'android': libs += ['SSL', 'CRYPTO'] # android curl was built with openssl diff --git a/game/client/cstrike/c_cs_player.h b/game/client/cstrike/c_cs_player.h index 37851061ad..a966e672d5 100644 --- a/game/client/cstrike/c_cs_player.h +++ b/game/client/cstrike/c_cs_player.h @@ -176,7 +176,8 @@ public: float &flPenetrationDistance, float &flBulletDiameter ); - void FireBullet( + void FireBullet( + int iBullet, Vector vecSrc, const QAngle &shootAngles, float flDistance, diff --git a/game/server/cstrike/cs_player.cpp b/game/server/cstrike/cs_player.cpp index ad8e9df2f8..e78d3c2ba4 100644 --- a/game/server/cstrike/cs_player.cpp +++ b/game/server/cstrike/cs_player.cpp @@ -304,7 +304,7 @@ LINK_ENTITY_TO_CLASS( player, CCSPlayer ); PRECACHE_REGISTER(player); BEGIN_SEND_TABLE_NOBASE( CCSPlayer, DT_CSLocalPlayerExclusive ) - SendPropFloat( SENDINFO( m_flStamina ), 14, 0, 0, 1400 ), + SendPropFloat( SENDINFO( m_flStamina ) ), SendPropInt( SENDINFO( m_iDirection ), 1, SPROP_UNSIGNED ), SendPropInt( SENDINFO( m_iShotsFired ), 8, SPROP_UNSIGNED ), SendPropFloat( SENDINFO( m_flVelocityModifier ), 8, 0, 0, 1 ), diff --git a/game/server/cstrike/cs_player.h b/game/server/cstrike/cs_player.h index 50840370c9..0d77106142 100644 --- a/game/server/cstrike/cs_player.h +++ b/game/server/cstrike/cs_player.h @@ -296,7 +296,8 @@ public: virtual float GetPlayerMaxSpeed(); - void FireBullet( + void FireBullet( + int iBullet, Vector vecSrc, const QAngle &shootAngles, float flDistance, diff --git a/game/server/playerlocaldata.cpp b/game/server/playerlocaldata.cpp index 76787278a4..c2a43b00ff 100644 --- a/game/server/playerlocaldata.cpp +++ b/game/server/playerlocaldata.cpp @@ -45,9 +45,9 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local ) SendPropFloat ( SENDINFO_VECTORELEM(m_vecPunchAngleVel, 2), 32, SPROP_NOSCALE|SPROP_CHANGES_OFTEN ), #else - SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_COORD|SPROP_CHANGES_OFTEN ), - SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_COORD|SPROP_CHANGES_OFTEN), - SendPropVector (SENDINFO(m_vecPunchAngleVel), -1, SPROP_COORD), + SendPropFloat (SENDINFO(m_flFallVelocity), -1, SPROP_CHANGES_OFTEN ), + SendPropVector (SENDINFO(m_vecPunchAngle), -1, SPROP_CHANGES_OFTEN), + SendPropVector (SENDINFO(m_vecPunchAngleVel)), #endif SendPropInt (SENDINFO(m_bDrawViewmodel), 1, SPROP_UNSIGNED ), SendPropInt (SENDINFO(m_bWearingSuit), 1, SPROP_UNSIGNED ), diff --git a/game/shared/cstrike/cs_player_shared.cpp b/game/shared/cstrike/cs_player_shared.cpp index 7f5ea8df5d..7c27217fee 100644 --- a/game/shared/cstrike/cs_player_shared.cpp +++ b/game/shared/cstrike/cs_player_shared.cpp @@ -185,19 +185,14 @@ float CCSPlayer::GetPlayerMaxSpeed() return speed; } -void UTIL_ClipTraceToPlayersHull( float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr ) +void UTIL_ClipTraceToPlayersHull(const Vector& vecAbsStart, const Vector& vecAbsEnd, const Vector& mins, const Vector& maxs, unsigned int mask, ITraceFilter *filter, trace_t *tr ) { trace_t playerTrace; Ray_t ray; float smallestFraction = tr->fraction; const float maxRange = 60.0f; - Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); - vecBulletDiameterMaxs /= 2.0f; - Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); - vecBulletDiameterMins /= 2.0f; - - ray.Init( vecAbsStart, vecAbsEnd , vecBulletDiameterMins, vecBulletDiameterMaxs ); + ray.Init( vecAbsStart, vecAbsEnd , mins, maxs ); for ( int k = 1; k <= gpGlobals->maxClients; ++k ) { @@ -411,25 +406,21 @@ static bool TraceToExit(Vector &start, Vector &dir, Vector &end, float flStepSiz return false; } -inline void UTIL_TraceLineIgnoreTwoEntities(float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, +inline void UTIL_TraceLineIgnoreTwoEntities(const Vector& vecAbsStart, const Vector& vecAbsEnd, const Vector& mins, const Vector& maxs, unsigned int mask, const IHandleEntity *ignore, const IHandleEntity *ignore2, int collisionGroup, trace_t *ptr ) { - Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); - vecBulletDiameterMaxs /= 2.0f; - Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); - vecBulletDiameterMins /= 2.0f; - Ray_t ray; - ray.Init( vecAbsStart, vecAbsEnd, vecBulletDiameterMins, vecBulletDiameterMaxs ); + ray.Init( vecAbsStart, vecAbsEnd, mins, maxs ); CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup ); enginetrace->TraceRay( ray, mask, &traceFilter, ptr ); if( r_visualizetraces.GetBool() ) { - NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, QAngle(), 255, 0, 0, true, 100.0f ); + NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, mins, maxs, QAngle(), 255, 0, 0, true, 100.0f ); } } void CCSPlayer::FireBullet( + int iBullet, // bullet number Vector vecSrc, // shooting postion const QAngle &shootAngles, //shooting angle float flDistance, // max distance @@ -457,10 +448,10 @@ void CCSPlayer::FireBullet( GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter ); - Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); - vecBulletDiameterMaxs /= 2.0f; - Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); - vecBulletDiameterMins /= 2.0f; + float flBulletRadius = flBulletDiameter / 2.0f; + + Vector vecBulletRadiusMaxs(flBulletRadius, flBulletRadius, flBulletRadius); + Vector vecBulletRadiusMins(-flBulletRadius, -flBulletRadius, -flBulletRadius); if ( !pevAttacker ) pevAttacker = this; // the default attacker is ourselves @@ -534,13 +525,13 @@ void CCSPlayer::FireBullet( trace_t tr; // main enter bullet trace - UTIL_TraceLineIgnoreTwoEntities(flBulletDiameter, vecSrc, vecEnd, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLineIgnoreTwoEntities(vecSrc, vecEnd, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr ); { CTraceFilterSkipTwoEntities filter( this, lastPlayerHit, COLLISION_GROUP_NONE ); // Check for player hitboxes extending outside their collision bounds const float rayExtension = 40.0f; - UTIL_ClipTraceToPlayersHull(flBulletDiameter, vecSrc, vecEnd + vecDir * rayExtension, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr ); + UTIL_ClipTraceToPlayersHull(vecSrc, vecEnd + vecDir * rayExtension, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr ); } lastPlayerHit = ToBasePlayer(tr.m_pEnt); @@ -583,8 +574,8 @@ void CCSPlayer::FireBullet( { NDebugOverlay::SweptBox(vecSrc, tr.endpos, - vecBulletDiameterMins, - vecBulletDiameterMaxs, + vecBulletRadiusMins, + vecBulletRadiusMaxs, QAngle(0, 0, 0), 255, 0, @@ -609,23 +600,17 @@ void CCSPlayer::FireBullet( #else if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_HIT || m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ALWAYS_ON ) { - if (m_iBulletServerPositionCount.Get() - < MAX_PLAYER_BULLET_SERVER_POSITIONS) + if (iBullet < MAX_PLAYER_BULLET_SERVER_POSITIONS) { - m_vecBulletServerPositions.Set( - m_iBulletServerPositionCount.Get(), - tr.endpos); - m_vecServerShootPosition.Set( - m_iBulletServerPositionCount.Get(), - vecSrc); - m_iBulletServerPositionCount.Set( - m_iBulletServerPositionCount.Get() + 1); + m_vecBulletServerPositions.Set(m_iBulletServerPositionCount.Get(), tr.endpos); + m_vecServerShootPosition.Set(m_iBulletServerPositionCount.Get(), vecSrc); + m_iBulletServerPositionCount.Set(m_iBulletServerPositionCount.Get() + 1); } - if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) - { - CBasePlayer *player = ToBasePlayer( tr.m_pEnt ); - player->RecordServerHitboxes( this ); + if (tr.m_pEnt && tr.m_pEnt->IsPlayer()) + { + CBasePlayer* player = ToBasePlayer(tr.m_pEnt); + player->RecordServerHitboxes(this); } } #endif @@ -651,7 +636,7 @@ void CCSPlayer::FireBullet( if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) ) { trace_t waterTrace; - UTIL_TraceHull( vecSrc, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace ); + UTIL_TraceHull( vecSrc, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace ); if( waterTrace.allsolid != 1 ) { @@ -734,12 +719,12 @@ void CCSPlayer::FireBullet( // find exact penetration exit trace_t exitTr; - UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr ); + UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr ); if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL ) { // something was blocking, trace again - UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr ); + UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr ); } // get material at exit point diff --git a/game/shared/cstrike/fx_cs_shared.cpp b/game/shared/cstrike/fx_cs_shared.cpp index 1faa4293d4..38fb60c830 100644 --- a/game/shared/cstrike/fx_cs_shared.cpp +++ b/game/shared/cstrike/fx_cs_shared.cpp @@ -301,7 +301,8 @@ void FX_FireBullets( if (debug_screenshot_bullet_position.GetBool()) gpGlobals->client_taking_screenshot = true; #endif - pPlayer->FireBullet( + pPlayer->FireBullet( + iBullet, vOrigin, vAngles, flRange, diff --git a/public/dt_send.cpp b/public/dt_send.cpp index a49f36af70..d586678b86 100644 --- a/public/dt_send.cpp +++ b/public/dt_send.cpp @@ -381,13 +381,17 @@ SendProp SendPropFloat( Assert( sizeofVar == 0 || sizeofVar == 4 ); } + // TODO_ENHANCED: These variables will get compressed with zstd + flags = SPROP_NOSCALE; + nBits = 0; + if ( nBits <= 0 || nBits == 32 ) { flags |= SPROP_NOSCALE; fLowValue = 0.f; fHighValue = 0.f; } - else + else { if (fHighValue == HIGH_DEFAULT) { @@ -428,13 +432,17 @@ SendProp SendPropVector( Assert(sizeofVar == sizeof(Vector)); } + // TODO_ENHANCED: These variables will get compressed with zstd + flags = SPROP_NOSCALE; + nBits = 0; + if ( nBits <= 0 || nBits == 32 ) { flags |= SPROP_NOSCALE; fLowValue = 0.f; fHighValue = 0.f; } - else + else { if (fHighValue == HIGH_DEFAULT) { @@ -475,13 +483,17 @@ SendProp SendPropVectorXY( Assert(sizeofVar == sizeof(Vector)); } + // TODO_ENHANCED: These variables will get compressed with zstd + flags = SPROP_NOSCALE; + nBits = 0; + if ( nBits <= 0 || nBits == 32 ) { flags |= SPROP_NOSCALE; fLowValue = 0.f; fHighValue = 0.f; } - else + else { if (fHighValue == HIGH_DEFAULT) { @@ -504,7 +516,8 @@ SendProp SendPropVectorXY( return ret; } -#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + #if 0 // We can't ship this since it changes the size of DTVariant to + // be 20 bytes instead of 16 and that breaks MODs!!! SendProp SendPropQuaternion( const char *pVarName, int offset, @@ -523,13 +536,17 @@ SendProp SendPropQuaternion( Assert(sizeofVar == sizeof(Quaternion)); } + // TODO_ENHANCED: These variables will get compressed with zstd + flags = SPROP_NOSCALE; + nBits = 0; + if ( nBits <= 0 || nBits == 32 ) { flags |= SPROP_NOSCALE; fLowValue = 0.f; fHighValue = 0.f; } - else + else { if (fHighValue == HIGH_DEFAULT) { diff --git a/public/tier1/lzss.h b/public/tier1/lzss.h index 0a1f3002f2..a508102115 100644 --- a/public/tier1/lzss.h +++ b/public/tier1/lzss.h @@ -11,6 +11,7 @@ #define LZSS_ID uint32( BigLong( ('L'<<24)|('Z'<<16)|('S'<<8)|('S') ) ) #define SNAPPY_ID uint32( BigLong( ('S'<<24)|('N'<<16)|('A'<<8)|('P') ) ) +#define ZSTD_ID uint32( BigLong( ('Z'<<24)|('S'<<16)|('T'<<8)|('D') ) ) // bind the buffer for correct identification struct lzss_header_t diff --git a/wscript b/wscript index 7db37e55e2..bf9d5e5455 100644 --- a/wscript +++ b/wscript @@ -327,6 +327,7 @@ def options(opt): opt.load('reconfigure') def check_deps(conf): + conf.check_cc(lib='zstd', mandatory=False) if conf.env.DEST_OS != 'win32': conf.check_cc(lib='dl', mandatory=False) conf.check_cc(lib='bz2', mandatory=True)