-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't trust the local machine's system time. #1453
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good solution to me.
This can never happen I think. When joining an age instance, the client always sends a
According to my notes, none of the fan servers support Perhaps |
Previously, when asking for the server's time, the calculation was done by basically offsetting the local system time by some previously calculated delta. This was basically useless because the user can easily change the system time out from under us and cause huge deltas. The attempt to fix things in H-uru#173 by using `WM_TIMECHANGE` was a good idea but ultimately incorrect because `hsTimer` is a monotonic timer. At this point, it uses `std::chrono::steady_clock` as its backend, so attempting to use `hsTimer` to recalculate the server/client time offset is useless. Therefore, this changes us to simply save the last time value that we received from the game server and the monotonic time that we received that update. This is definitely not perfect because we don't consider things like round trip time for the message and time spent in the update loop. However, it *is* a clear improvement in that now the KI will always display what the server thinks Mountain time is, and it should be impossible to perform system clock based exploits (such as instantly baking pellets)... without any platform specific code!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One really minor thing, otherwise LGTM.
Co-authored-by: dgelessus <[email protected]>
Previously, when asking for the server's time, the calculation was done by basically offsetting the local system time by some previously calculated delta. This was basically useless because the user can easily change the system time out from under us and cause huge deltas. The attempt to fix things in #173 by using
WM_TIMECHANGE
was a good idea but ultimately incorrect becausehsTimer
is a monotonic timer. At this point, it usesstd::chrono::steady_clock
as its backend, so attempting to usehsTimer
to recalculate the server/client time offset is useless.Therefore, this changes us to simply save the last time value that we received from the game server and the monotonic time that we received that update. This is definitely not perfect because we don't consider things like round trip time for the message and time spent in the update loop. However, it is a clear improvement in that now the KI will always display what the server thinks Mountain time is, and it should be impossible to perform system clock based exploits (such as instantly baking pellets)... without any platform specific code!
Future work: currently, we are implicitly depending on the server to send us periodic
plNetMessage
s with the time sent value to synchronize the time. If that's never done, then we simply return the client's time (yikes!). This is a decent assumption in all current content because we will receiveplNetMsgGameMessage
withplServerReply
for region enters on spawn andplNetSDLMsg
for the Age state (when an Age has any non-excluded SDL states), however, there is little guarantee that the server will continue to send us these messages if we are in an Age by ourselves doing nothing. One option would be to send an innocuous message such asplNetMsgGetSharedState
periodically. I have not implemented that here because it is not immediately apparent whether or not the various server types implement this message.