Waystones (Fabric Edition)

Waystones (Fabric Edition)

4M Downloads

Use ingame world time instead of Unix Time for cooldowns

ryanskeldon opened this issue ยท 7 comments

commented

I'm not entirely sure this is right line (I haven't gone through all of the source), but I've come across an issue where differences in server/client clocks cause the cooldown timer tooltip to be incorrect.

I noticed the issue when I moved my server to a dedicated host who had the wrong time set on the server. My cooldown for warp stones in the config is set to 60 seconds. Whenever I'd use a warp stone, the cooldown would show about 1,140 seconds left on the timer. I changed my cooldown to 0 seconds and the timer would say 1080ish seconds. That equates to 18 minutes. I check the current time on my dedicated host and the system time was 18 minutes ahead of my PC's clock. If I adjust my PC's clock to match the server's the warp stone works as expected.

I've contacted my dedicated host to resolve the clock issue, but that won't fix this bug. Is there a way to use a single clock source to calculate seconds remaining?

https://github.com/blay09/Waystones/blob/db6067009e3bf4e12dbd737649a666d97ae68094/src/main/java/net/blay09/mods/waystones/item/ItemWarpStone.java#L107

commented

It's not a bug, and it's already using a single clock source, which is the seconds since the unix epoch. You will get all kinds of issues in other networked applications as well if it's out of sync. It's quite questionable your host wasn't already keeping server time in sync via NTP.

In theory it could probably be bound to the ingame world age instead, and I may look into doing that, but not sure when yet.

commented

Forgive my ignorance, but does using @SideOnly set the reference of "System.currentTimeMillis()" to the client's system clock? If so, then that would explain the issue. The setting of the last warp time would be using the server's currentTimeMillis() and the calculation of time remaining would use the client's.

In my case, the server is 18 minutes ahead, so the cooldown would be that offset plus the 60 seconds from the config. If there was a way to use the server's currentTimeMillis() in both calls that would fix the issue, because regardless of the actual time, 60 seconds would still be 60 seconds.

I get that this can be avoided by just making sure the server and all clients are as close to UTC as possible, but that might not always be the case. Using the world age might be a better reference point if possible. I've never developed for MC so I don't know what is available.

commented

@SideOnly strips methods from the server (for example when referencing client-side only classes in it, to prevent the famous NoClassDefFound dedicated server crashes), it doesn't change what side the method actually runs on.

commented

OK, so in the line I linked in the OP, that function would only be called by the client and that means System.currentTimeMillis() would be using the client's clock, not the server's. If the last warp time was set using the server's clock, any difference from the client and server's clock would either add or subtract an offset to the cooldown relative to how far off the two clocks are.

If I wanted to, I could set my PC's clock ahead whatever a server's config is set at for the cooldown and get free warps.

commented

You could make it look like that, but the server has authority and will refuse the warp.

commented

Just tested my theory and it works!

commented

Huh, you're right, looks like I was being sloppy in my server-side checks.

Guess this just gained a little priority.