diff --git a/Sources/Plasma/Apps/plClient/win32/winmain.cpp b/Sources/Plasma/Apps/plClient/win32/winmain.cpp index 12079ece04..e9c8df245c 100644 --- a/Sources/Plasma/Apps/plClient/win32/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/win32/winmain.cpp @@ -207,14 +207,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Handle messages switch (message) { - case WM_TIMECHANGE: - // To prevent cheating and keep things better synchronized, - // we will completely re-eval the offsets on the next NetMsg we - // get from the server - if (plNetClientMgr* nc = plNetClientMgr::GetInstance()) - nc->ResetServerTimeOffset(true); - break; - case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONDBLCLK: diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp index e5791f7ace..24434103c0 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetCliAgeJoiner.cpp @@ -212,7 +212,7 @@ void plNCAgeJoiner::Start () { plNetClientMgr * nc = plNetClientMgr::GetInstance(); nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false); - nc->fServerTimeOffset = 0; // reset since we're connecting to a new server + nc->ResetServerTimeOffset(); nc->fRequiredNumInitialSDLStates = 0; nc->fNumInitialSDLStates = 0; nc->SetFlagsBit(plNetClientApp::kNeedInitialAgeStateCount); diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp index 3c416dc305..04ee04361c 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp @@ -102,10 +102,10 @@ plNetClientMgr::PendingLoad::~PendingLoad() // plNetClientMgr::plNetClientMgr() : fLocalPlayerKey(), fMsgHandler(this), fJoinOrder(), fTaskProgBar(), - fMsgRecorder(), fServerTimeOffset(), fTimeSamples(), fLastTimeUpdate(), - fListenListMode(kListenList_Distance), fAgeSDLObjectKey(), fExperimentalLevel(), - fOverrideAgeTimeOfDayPercent(-1.f), fNumInitialSDLStates(), fRequiredNumInitialSDLStates(), - fDisableMsg(), fIsOwner(true), fIniPlayerID(), fPingServerType() + fMsgRecorder(), fLastLocalTime(), fListenListMode(kListenList_Distance), + fAgeSDLObjectKey(), fExperimentalLevel(), fOverrideAgeTimeOfDayPercent(-1.f), + fNumInitialSDLStates(), fRequiredNumInitialSDLStates(), fDisableMsg(), fIsOwner(true), + fIniPlayerID(), fPingServerType() { #ifndef HS_DEBUGGING // release code will timeout inactive players on servers by default @@ -403,50 +403,36 @@ void plNetClientMgr::IUnloadNPCs() // void plNetClientMgr::UpdateServerTimeOffset(plNetMessage* msg) { - if ((hsTimer::GetSysSeconds() - fLastTimeUpdate) > 5) - { - fLastTimeUpdate = hsTimer::GetSysSeconds(); - - const plUnifiedTime& msgSentUT = msg->GetTimeSent(); - if (!msgSentUT.AtEpoch()) - { - double diff = plUnifiedTime::GetTimeDifference(msgSentUT, plUnifiedTime::GetCurrent()); + if (!msg->GetHasTimeSent()) + return; + if (msg->GetTimeSent().AtEpoch()) + return; - if (fServerTimeOffset == 0) - { - fServerTimeOffset = diff; - } - else - { - fServerTimeOffset = fServerTimeOffset + ((diff - fServerTimeOffset) / ++fTimeSamples); - } + double localTime = hsTimer::GetSeconds(); + if (localTime - fLastLocalTime < 1.0) + return; - DebugMsg("Setting server time offset to {f}", fServerTimeOffset); - } - } + fLastServerTime = msg->GetTimeSent(); + fLastLocalTime = localTime; } -void plNetClientMgr::ResetServerTimeOffset(bool delayed) +void plNetClientMgr::ResetServerTimeOffset() { - if (!delayed) - fServerTimeOffset = 0; - fTimeSamples = 0; - fLastTimeUpdate = 0; + fLastServerTime.ToEpoch(); + fLastLocalTime = 0.0; } // // return the gameservers time // plUnifiedTime plNetClientMgr::GetServerTime() const -{ - if ( fServerTimeOffset==0 ) // offline mode or before connecting/calibrating to a server +{ + if (fLastServerTime.AtEpoch()) { + WarningMsg("WARNING: Someone asked for the server time, but we don't know it yet!"); return plUnifiedTime::GetCurrent(); - - plUnifiedTime serverUT; - if (fServerTimeOffset<0) - return plUnifiedTime::GetCurrent() - plUnifiedTime(fabs(fServerTimeOffset)); - else - return plUnifiedTime::GetCurrent() + plUnifiedTime(fServerTimeOffset); + } + + return fLastServerTime + plUnifiedTime(hsTimer::GetSeconds() - fLastLocalTime); } // diff --git a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h index 63ec58f560..66e1a193a4 100644 --- a/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h +++ b/Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h @@ -161,9 +161,8 @@ class plNetClientMgr : public plNetClientApp std::string fSPDesiredPlayerName; // SP: the player we want to load from vault. // server info - double fServerTimeOffset; // diff between our unified time and server's unified time - uint32_t fTimeSamples; - double fLastTimeUpdate; + plUnifiedTime fLastServerTime; // Last received time update from the server + double fLastLocalTime; // Last monotonic time (in seconds) when the above update was received uint8_t fJoinOrder; // returned by the server @@ -379,7 +378,7 @@ class plNetClientMgr : public plNetClientApp void StoreSDLState(const plStateDataRecord* sdRec, const plUoid& uoid, uint32_t sendFlags, uint32_t writeOptions); void UpdateServerTimeOffset(plNetMessage* msg); - void ResetServerTimeOffset(bool delayed=false); + void ResetServerTimeOffset(); private: plNetClientComm fNetClientComm;