diff --git a/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp b/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp index 79679cc..79d0964 100644 --- a/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp +++ b/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp @@ -46,7 +46,9 @@ static SConfigurationValueEntry sConfigurationValueEntryList[] = { k_ESteamNetworkingConfigurationValue_FakePacketReorder_Send, "FakePacketReorder_Send", &steamdatagram_fakepacketreorder_send }, { k_ESteamNetworkingConfigurationValue_FakePacketReorder_Recv, "FakePacketReorder_Recv", &steamdatagram_fakepacketreorder_recv }, { k_ESteamNetworkingConfigurationValue_FakePacketReorder_Time, "FakePacketReorder_Time", &steamdatagram_fakepacketreorder_time }, - + { k_ESteamNetworkingConfigurationValue_FakePacketDup_Send, "FakePacketDup_Send", &steamdatagram_fakepacketdup_send }, + { k_ESteamNetworkingConfigurationValue_FakePacketDup_Recv, "FakePacketDup_Recv", &steamdatagram_fakepacketdup_recv }, + { k_ESteamNetworkingConfigurationValue_FakePacketDup_TimeMax, "FakePacketDup_Time", &steamdatagram_fakepacketdup_timemax }, { k_ESteamNetworkingConfigurationValue_SendBufferSize, "SendBufferSize", &steamdatagram_snp_send_buffer_size }, { k_ESteamNetworkingConfigurationValue_MaxRate, "MaxRate", &steamdatagram_snp_max_rate }, { k_ESteamNetworkingConfigurationValue_MinRate, "MinRate", &steamdatagram_snp_min_rate }, diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingconfig.h b/src/steamnetworkingsockets/clientlib/steamnetworkingconfig.h index 68f8b02..4e62854 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingconfig.h +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingconfig.h @@ -62,6 +62,10 @@ SDT_EXTERNAL int32 steamdatagram_fakepacketreorder_send SDT_DEFAULT( 0 ); // 0-1 SDT_EXTERNAL int32 steamdatagram_fakepacketreorder_recv SDT_DEFAULT( 0 ); // 0-100 Randomly redorder N pct of packets received SDT_EXTERNAL int32 steamdatagram_fakepacketreorder_time SDT_DEFAULT( 15 ); // How many ms to delay reordered packets. +SDT_EXTERNAL int32 steamdatagram_fakepacketdup_send SDT_DEFAULT( 0 ); // 0-100 Randomly duplicate N pct of packets sent +SDT_EXTERNAL int32 steamdatagram_fakepacketdup_recv SDT_DEFAULT( 0 ); // 0-100 Randomly duplicate N pct of packets received +SDT_EXTERNAL int32 steamdatagram_fakepacketdup_timemax SDT_DEFAULT( 5 ); // Max delay of duplicated packets. + SDT_EXTERNAL int32 steamdatagram_snp_send_buffer_size SDT_DEFAULT( 524288 ); // Upper limit of buffered pending bytes to be sent SDT_EXTERNAL int32 steamdatagram_snp_max_rate SDT_DEFAULT( 1000000 ); // Maximum send rate clamp, 0 is no limit SDT_EXTERNAL int32 steamdatagram_snp_min_rate SDT_DEFAULT( 128000 ); // Mininum send rate clamp, 0 is no limit diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp index e269879..7bdc143 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp @@ -418,12 +418,21 @@ bool IRawUDPSocket::BSendRawPacketGather( int nChunks, const iovec *pChunks, con // Fake lag? int32 nPacketFakeLagTotal = steamdatagram_fakepacketlag_send; - // Check for simulation random packet reordering - if ( ( steamdatagram_fakepacketreorder_send ) > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketreorder_send ) + // Check for simulating random packet reordering + if ( steamdatagram_fakepacketreorder_send > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketreorder_send ) { nPacketFakeLagTotal += steamdatagram_fakepacketreorder_time; } + // Check for simulating random packet duplication + if ( steamdatagram_fakepacketdup_send > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketdup_send ) + { + int32 nDupLag = nPacketFakeLagTotal + WeakRandomInt( 0, steamdatagram_fakepacketdup_timemax ); + nDupLag = std::max( 1, nDupLag ); + s_packetLagQueue.LagPacket( true, self, adrTo, nDupLag, nChunks, pChunks ); + } + + // Lag the original packet? if ( nPacketFakeLagTotal > 0 ) { s_packetLagQueue.LagPacket( true, self, adrTo, nPacketFakeLagTotal, nChunks, pChunks ); @@ -909,12 +918,23 @@ static bool PollRawUDPSockets( int nMaxTimeoutMS ) int32 nPacketFakeLagTotal = steamdatagram_fakepacketlag_recv; - // Check for simulation random packet reordering - if ( ( steamdatagram_fakepacketreorder_recv ) > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketreorder_recv ) + // Check for simulating random packet reordering + if ( steamdatagram_fakepacketreorder_recv > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketreorder_recv ) { nPacketFakeLagTotal += steamdatagram_fakepacketreorder_time; } + // Check for simulating random packet duplication + if ( steamdatagram_fakepacketdup_recv > 0 && WeakRandomFloat( 0, 100.0 ) < steamdatagram_fakepacketdup_recv ) + { + int32 nDupLag = nPacketFakeLagTotal + WeakRandomInt( 0, steamdatagram_fakepacketdup_timemax ); + nDupLag = std::max( 1, nDupLag ); + iovec temp; + temp.iov_len = ret; + temp.iov_base = buf; + s_packetLagQueue.LagPacket( false, pSock, adr, nDupLag, 1, &temp ); + } + // Check for simulating lag if ( nPacketFakeLagTotal > 0 ) { diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h index fa584dc..439e282 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h @@ -58,11 +58,12 @@ class IRawUDPSocket public: /// A thin wrapper around ::sendto /// - /// Packets sent through this method are subject to fake loss (steamdatagram_fakepacketloss_send) - /// and fake lag (steamdatagram_fakepacketlag_send) + /// Packets sent through this method are subject to fake loss (steamdatagram_fakepacketloss_send), + /// lag (steamdatagram_fakepacketlag_send and steamdatagram_fakepacketreorder_send), and + /// duplication (steamdatagram_fakepacketdup_send) bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const; - /// Gather-based send + /// Gather-based send. Simulated lag, loss, etc are applied bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const; /// Logically close the socket. This might not actually close the socket IMMEDIATELY, @@ -78,7 +79,7 @@ protected: ~IRawUDPSocket(); }; -const int k_nAddressFamily_Auto = -1; // Wil try to use IPv6 dual stack if possible. Falls back to IPv4 if necessary (and possible for your requested bind address) +const int k_nAddressFamily_Auto = -1; // Will try to use IPv6 dual stack if possible. Falls back to IPv4 if necessary (and possible for your requested bind address) const int k_nAddressFamily_IPv4 = 1; const int k_nAddressFamily_IPv6 = 2; const int k_nAddressFamily_DualStack = k_nAddressFamily_IPv4|k_nAddressFamily_IPv6;