aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-04-16 16:16:49 +0200
committerShauren <shauren.trinity@gmail.com>2025-04-16 16:16:49 +0200
commit821ecf8fa3b6b922ba178cde7593ef5d84ef734b (patch)
treed603527d78911133528897928fba90689eb70945 /src/server/game/Handlers
parent4dd4cfef8fef1037d44a631f95c0fa6a29597c93 (diff)
Core/Players: Improve setting ActivePlayerData::TransportServerTime by including TIME_SYNC and CMSG_QUEUED_MESSAGES_END values in its calculation
* This removes delay on nearby object visibility after login and teleport
Diffstat (limited to 'src/server/game/Handlers')
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp10
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp44
2 files changed, 39 insertions, 15 deletions
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 9a5ba64b353..510eefbe5f3 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -63,6 +63,7 @@
#include "SystemPackets.h"
#include "Util.h"
#include "World.h"
+#include <boost/circular_buffer.hpp>
#include <sstream>
class LoginQueryHolder : public CharacterDatabaseQueryHolder
@@ -1112,6 +1113,9 @@ void WorldSession::HandleContinuePlayerLogin()
SendPacket(WorldPackets::Auth::ResumeComms(CONNECTION_TYPE_INSTANCE).Write());
+ // client will respond to SMSG_RESUME_COMMS with CMSG_QUEUED_MESSAGES_END
+ RegisterTimeSync(SPECIAL_RESUME_COMMS_TIME_SYNC_COUNTER);
+
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
{
HandlePlayerLogin(static_cast<LoginQueryHolder const&>(holder));
@@ -1153,6 +1157,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder)
return;
}
+ if (!_timeSyncClockDeltaQueue->empty())
+ {
+ pCurrChar->SetPlayerLocalFlag(PLAYER_LOCAL_FLAG_OVERRIDE_TRANSPORT_SERVER_TIME);
+ pCurrChar->SetTransportServerTime(_timeSyncClockDelta);
+ }
+
pCurrChar->SetVirtualPlayerRealm(GetVirtualRealmAddress());
SendAccountDataTimes(ObjectGuid::Empty, GLOBAL_CACHE_MASK);
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 8f0eac766a6..b150e7668d2 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -15,6 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "AuthenticationPackets.h"
#include "WorldSession.h"
#include "Battleground.h"
#include "Corpse.h"
@@ -798,20 +799,18 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeS
mover->SendMessageToSet(moveSkipTime.Write(), _player);
}
-void WorldSession::HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse& timeSyncResponse)
+void WorldSession::HandleTimeSync(uint32 counter, int64 clientTime, TimePoint responseReceiveTime)
{
- if (_pendingTimeSyncRequests.count(timeSyncResponse.SequenceIndex) == 0)
+ auto serverTimeAtSent = _pendingTimeSyncRequests.extract(counter);
+ if (!serverTimeAtSent)
return;
- uint32 serverTimeAtSent = _pendingTimeSyncRequests.at(timeSyncResponse.SequenceIndex);
- _pendingTimeSyncRequests.erase(timeSyncResponse.SequenceIndex);
-
// time it took for the request to travel to the client, for the client to process it and reply and for response to travel back to the server.
// we are going to make 2 assumptions:
// 1) we assume that the request processing time equals 0.
// 2) we assume that the packet took as much time to travel from server to client than it took to travel from client to server.
- uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent, timeSyncResponse.GetReceivedTime());
- uint32 lagDelay = roundTripDuration / 2;
+ uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent.mapped(), responseReceiveTime);
+ int64 lagDelay = roundTripDuration / 2;
/*
clockDelta = serverTime - clientTime
@@ -823,11 +822,28 @@ void WorldSession::HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse&
using the following relation:
serverTime = clockDelta + clientTime
*/
- int64 clockDelta = (int64)serverTimeAtSent + (int64)lagDelay - (int64)timeSyncResponse.ClientTime;
+ int64 clockDelta = serverTimeAtSent.mapped() + lagDelay - clientTime;
_timeSyncClockDeltaQueue->push_back(std::pair<int64, uint32>(clockDelta, roundTripDuration));
ComputeNewClockDelta();
}
+void WorldSession::HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse const& timeSyncResponse)
+{
+ HandleTimeSync(timeSyncResponse.SequenceIndex, timeSyncResponse.ClientTime, timeSyncResponse.GetReceivedTime());
+}
+
+void WorldSession::HandleQueuedMessagesEnd(WorldPackets::Auth::QueuedMessagesEnd const& queuedMessagesEnd)
+{
+ HandleTimeSync(SPECIAL_RESUME_COMMS_TIME_SYNC_COUNTER, queuedMessagesEnd.Timestamp, queuedMessagesEnd.GetRawPacket()->GetReceivedTime());
+}
+
+void WorldSession::HandleMoveInitActiveMoverComplete(WorldPackets::Movement::MoveInitActiveMoverComplete const& moveInitActiveMoverComplete)
+{
+ HandleTimeSync(SPECIAL_INIT_ACTIVE_MOVER_TIME_SYNC_COUNTER, moveInitActiveMoverComplete.Ticks, moveInitActiveMoverComplete.GetRawPacket()->GetReceivedTime());
+
+ _player->UpdateObjectVisibility(false);
+}
+
void WorldSession::ComputeNewClockDelta()
{
// implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
@@ -861,12 +877,10 @@ void WorldSession::ComputeNewClockDelta()
}
else if (_timeSyncClockDelta == 0)
_timeSyncClockDelta = _timeSyncClockDeltaQueue->back().first;
-}
-void WorldSession::HandleMoveInitActiveMoverComplete(WorldPackets::Movement::MoveInitActiveMoverComplete& moveInitActiveMoverComplete)
-{
- _player->SetPlayerLocalFlag(PLAYER_LOCAL_FLAG_OVERRIDE_TRANSPORT_SERVER_TIME);
- _player->SetTransportServerTime(GameTime::GetGameTimeMS() - moveInitActiveMoverComplete.Ticks);
-
- _player->UpdateObjectVisibility(false);
+ if (_player)
+ {
+ _player->SetPlayerLocalFlag(PLAYER_LOCAL_FLAG_OVERRIDE_TRANSPORT_SERVER_TIME);
+ _player->SetTransportServerTime(int32(_timeSyncClockDelta));
+ }
}