From c965bb77bd3fa16e3f4bcd947bbb347dcf192733 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 15 Oct 2025 00:21:07 +0200 Subject: [PATCH] Fix possible `sendPlayerPos` desync situation (#16498) --- src/client/client.cpp | 22 ++++++++++++++++------ src/client/client.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 2e585ea2f..78509baee 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -566,9 +566,8 @@ void Client::step(float dtime) { float &counter = m_playerpos_send_timer; counter += dtime; - if((m_state == LC_Ready) && (counter >= m_recommended_send_interval)) - { - counter = 0.0; + if (m_state == LC_Ready && counter >= m_recommended_send_interval) { + counter = 0; sendPlayerPos(); } } @@ -1403,7 +1402,7 @@ void Client::sendPlayerPos() f32 movement_speed = player->control.movement_speed; f32 movement_dir = player->control.movement_direction; - if ( + bool identical = ( player->last_position == player->getPosition() && player->last_speed == player->getSpeed() && player->last_pitch == player->getPitch() && @@ -1413,8 +1412,19 @@ void Client::sendPlayerPos() player->last_camera_inverted == camera_inverted && player->last_wanted_range == wanted_range && player->last_movement_speed == movement_speed && - player->last_movement_dir == movement_dir) - return; + player->last_movement_dir == movement_dir); + + if (identical) { + // Since the movement info is sent non-reliable an unfortunate desync might + // occur if we stop sending and the last packet gets lost or re-ordered. + // To make this situation less likely we stop sending duplicate packets + // only after a delay. + m_playerpos_repeat_count++; + if (m_playerpos_repeat_count >= 5) + return; + } else { + m_playerpos_repeat_count = 0; + } player->last_position = player->getPosition(); player->last_speed = player->getSpeed(); diff --git a/src/client/client.h b/src/client/client.h index 4b36472f9..d21618e7a 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -478,6 +478,7 @@ private: float m_connection_reinit_timer = 0.1f; float m_avg_rtt_timer = 0.0f; float m_playerpos_send_timer = 0.0f; + int m_playerpos_repeat_count = 0; IntervalLimiter m_map_timer_and_unload_interval; IWritableTextureSource *m_tsrc;