Core/Players: Improve setting ActivePlayerData::TransportServerTime by including TIME_SYNC and CMSG_QUEUED_MESSAGES_END values in its calculation
Port From (https://github.com/TrinityCore/TrinityCore/commit/821ecf8fa3b6b922ba178cde7593ef5d84ef734b)
This commit is contained in:
@@ -783,6 +783,9 @@ namespace Game
|
||||
|
||||
SendPacket(new ResumeComms(ConnectionType.Instance));
|
||||
|
||||
// client will respond to SMSG_RESUME_COMMS with CMSG_QUEUED_MESSAGES_END
|
||||
RegisterTimeSync(SPECIAL_RESUME_COMMS_TIME_SYNC_COUNTER);
|
||||
|
||||
AddQueryHolderCallback(DB.Characters.DelayQueryHolder(holder)).AfterComplete(holder => HandlePlayerLogin((LoginQueryHolder)holder));
|
||||
}
|
||||
|
||||
@@ -799,6 +802,12 @@ namespace Game
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_timeSyncClockDeltaQueue.IsEmpty)
|
||||
{
|
||||
pCurrChar.SetPlayerLocalFlag(PlayerLocalFlags.OverrideTransportServerTime);
|
||||
pCurrChar.SetTransportServerTime((int)_timeSyncClockDelta);
|
||||
}
|
||||
|
||||
pCurrChar.SetVirtualPlayerRealm(Global.WorldMgr.GetVirtualRealmAddress());
|
||||
|
||||
SendAccountDataTimes(ObjectGuid.Empty, AccountDataTypes.GlobalCacheMask);
|
||||
|
||||
@@ -624,7 +624,7 @@ namespace Game
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingBankingRateAck)]
|
||||
[WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingPitchingRateDownAck)]
|
||||
[WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingPitchingRateDownAck)]
|
||||
[WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingPitchingRateUpAck)]
|
||||
[WorldPacketHandler(ClientOpcodes.MoveSetAdvFlyingTurnVelocityThresholdAck)]
|
||||
void HandleSetAdvFlyingSpeedRangeAck(MovementSpeedRangeAck speedRangeAck)
|
||||
@@ -854,21 +854,20 @@ namespace Game
|
||||
GetPlayer().CastSpell(GetPlayer(), 2479, true);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.TimeSyncResponse, Processing = PacketProcessing.ThreadSafe)]
|
||||
void HandleTimeSyncResponse(TimeSyncResponse timeSyncResponse)
|
||||
void HandleTimeSync(uint counter, long clientTime, DateTime responseReceiveTime)
|
||||
{
|
||||
if (!_pendingTimeSyncRequests.ContainsKey(timeSyncResponse.SequenceIndex))
|
||||
var serverTimeAtSent = _pendingTimeSyncRequests.LookupByKey(counter);
|
||||
if (serverTimeAtSent == 0)
|
||||
return;
|
||||
|
||||
uint serverTimeAtSent = _pendingTimeSyncRequests.LookupByKey(timeSyncResponse.SequenceIndex);
|
||||
_pendingTimeSyncRequests.Remove(timeSyncResponse.SequenceIndex);
|
||||
_pendingTimeSyncRequests.Remove(counter);
|
||||
|
||||
// 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.
|
||||
uint roundTripDuration = Time.GetMSTimeDiff(serverTimeAtSent, timeSyncResponse.GetReceivedTime());
|
||||
uint lagDelay = roundTripDuration / 2;
|
||||
uint roundTripDuration = Time.GetMSTimeDiff((uint)serverTimeAtSent, responseReceiveTime);
|
||||
long lagDelay = roundTripDuration / 2;
|
||||
|
||||
/*
|
||||
clockDelta = serverTime - clientTime
|
||||
@@ -880,11 +879,31 @@ namespace Game
|
||||
using the following relation:
|
||||
serverTime = clockDelta + clientTime
|
||||
*/
|
||||
long clockDelta = (long)(serverTimeAtSent + lagDelay) - (long)timeSyncResponse.ClientTime;
|
||||
long clockDelta = serverTimeAtSent + lagDelay - clientTime;
|
||||
_timeSyncClockDeltaQueue.PushFront(Tuple.Create(clockDelta, roundTripDuration));
|
||||
ComputeNewClockDelta();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.TimeSyncResponse, Processing = PacketProcessing.ThreadSafe)]
|
||||
void HandleTimeSyncResponse(TimeSyncResponse timeSyncResponse)
|
||||
{
|
||||
HandleTimeSync(timeSyncResponse.SequenceIndex, timeSyncResponse.ClientTime, timeSyncResponse.GetReceivedTime());
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.QueuedMessagesEnd, Status = SessionStatus.Authed, Processing = PacketProcessing.Inplace)]
|
||||
void HandleQueuedMessagesEnd(QueuedMessagesEnd queuedMessagesEnd)
|
||||
{
|
||||
HandleTimeSync(SPECIAL_RESUME_COMMS_TIME_SYNC_COUNTER, queuedMessagesEnd.Timestamp, queuedMessagesEnd.GetWorldPacket().GetReceivedTime());
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.MoveInitActiveMoverComplete, Processing = PacketProcessing.ThreadSafe)]
|
||||
void HandleMoveInitActiveMoverComplete(MoveInitActiveMoverComplete moveInitActiveMoverComplete)
|
||||
{
|
||||
HandleTimeSync(SPECIAL_INIT_ACTIVE_MOVER_TIME_SYNC_COUNTER, moveInitActiveMoverComplete.Ticks, moveInitActiveMoverComplete.GetWorldPacket().GetReceivedTime());
|
||||
|
||||
_player.UpdateObjectVisibility(false);
|
||||
}
|
||||
|
||||
void ComputeNewClockDelta()
|
||||
{
|
||||
// implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
|
||||
@@ -921,15 +940,12 @@ namespace Game
|
||||
var back = _timeSyncClockDeltaQueue.Back();
|
||||
_timeSyncClockDelta = back.Item1;
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.MoveInitActiveMoverComplete, Processing = PacketProcessing.ThreadSafe)]
|
||||
void HandleMoveInitActiveMoverComplete(MoveInitActiveMoverComplete moveInitActiveMoverComplete)
|
||||
{
|
||||
_player.SetPlayerLocalFlag(PlayerLocalFlags.OverrideTransportServerTime);
|
||||
_player.SetTransportServerTime((int)(GameTime.GetGameTimeMS() - moveInitActiveMoverComplete.Ticks));
|
||||
|
||||
_player.UpdateObjectVisibility(false);
|
||||
if (_player != null)
|
||||
{
|
||||
_player.SetPlayerLocalFlag(PlayerLocalFlags.OverrideTransportServerTime);
|
||||
_player.SetTransportServerTime((int)_timeSyncClockDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user