How to get real time for the game

I am working with Java and I am making a game. In this game, real time is a very important part. For this reason, I am trying to get real time using Ntp.

What I found on the Internet is this code.

import java.net.InetAddress; import java.util.Date; import org.apache.commons.net.ntp.NTPUDPClient; import org.apache.commons.net.ntp.TimeInfo; public class test{ public static void main(String args[]) throws Exception{ String TIME_SERVER = "time-a.nist.gov"; NTPUDPClient timeClient = new NTPUDPClient(); InetAddress inetAddress = InetAddress.getByName(TIME_SERVER); TimeInfo timeInfo = timeClient.getTime(inetAddress); long returnTime = timeInfo.getReturnTime(); Date time = new Date(returnTime); System.out.println("Time from " + TIME_SERVER + ": " + time); } } 

My problem is that with this, the system still gets System.currentMillis (); because it actually prints you the time when your local computer received a time message. For this reason, if a player changes his working time for the future, the game time will also change.

If someone can help to have real time, I would be very grateful. PS I don’t have a server, my game will play on Kongregate, and the data will be on the players computer.

Thanks in advance.

+5
source share
3 answers

Try the following:

 String TIME_SERVER = "time-a.nist.gov"; TimeTCPClient client = new TimeTCPClient(); try { client.connect(TIME_SERVER); System.out.println(client.getDate()); } finally { client.disconnect(); } 
+2
source

Just run the time through NTP at the beginning of your program, and then use System.nanoTime () to get the relative time after that. It is completely monotomic and will not be changed through setting the system time.

+4
source

According to NTPUDPClient javadoc:

To use the class, just open the local dataset open and call getTime() to get the time. Then call close to close the connection correctly. Successive getTime calls are resolved without reconnecting.

You are missing the open() call in your code (technically close() , but that is not the cause of your problem).

In addition, in your requirements, you indicate what you need in real time (and not the time that the local client can set). This value should not be obtained directly, but as the offset necessary to match the local time to the server (remote) time obtained by the getOffset() method.

If real-time acquisition is a common procedure, you can only use NTP once at the beginning and use the resulting bias to correct the system time in the future, reducing the latency of receiving real-time.

Such a process can be described in the class as such:

 public class TimeKeeper{ // Constant: Time Server private final String TIME_SERVER = "time-a.nist.gov"; // Last time the time offset was retrieved via NTP private long last_offset_time = -1; // The real time, calculated from offsets, of when the last resync happened private long retrieve_time; private synchronized void resync(){ NTPUDPClient timeClient = new NTPUDPClient(); InetAddress inetAddress = InetAddress.getByName(TIME_SERVER); TimeInfo timeInfo = null; try{ timeClient.open(); timeInfo = timeClient.getTime(inetAddress); }catch(IOException ex){ return; }finally{ timeClient.close(); } // Real time calculated from the offset time and the current system time. retrieve_time = System.currentTimeMillis() + timeInfo.getOffset(); last_offset_time = System.nanoTime(); } public long getRealTimeInMillis(){ // Possible to set some resync criteria here if(last_offset_time == -1){ resync(); // Handle exception whilst retrieving time here } // Returns the system time, corrected with the offset return retrieve_time + Math.round((System.nanoTime() - last_offset_time) / 1000.0) } } 
+1
source

Source: https://habr.com/ru/post/1209706/


All Articles