Skip to content

Commit

Permalink
Merge pull request #1453 from Hoikas/time_fix_fix
Browse files Browse the repository at this point in the history
Don't trust the local machine's system time.
  • Loading branch information
Hoikas authored Aug 17, 2023
2 parents d863078 + 2356db8 commit 3a27b23
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 49 deletions.
8 changes: 0 additions & 8 deletions Sources/Plasma/Apps/plClient/win32/winmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
58 changes: 22 additions & 36 deletions Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,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
Expand Down Expand Up @@ -370,50 +370,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("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);
}

//
Expand Down
7 changes: 3 additions & 4 deletions Sources/Plasma/PubUtilLib/plNetClient/plNetClientMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,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

Expand Down Expand Up @@ -362,7 +361,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;
Expand Down

0 comments on commit 3a27b23

Please sign in to comment.