i am working with Java and i am making a game. In this game the real time is very essensial part. For this reason i am trying to get the real time using Ntp.
What i found in the web 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 using this, the system is still getting the System.currentMillis(); because it actually prints you the time that your local machine got the time message. For this reason if the player changes his Desktop time to the future, the game time will also change.
If someone could help in order to have the real time i would be very thankful. P.S. i dont have a server, my game will be playing on Kongregate and the data will be on the players computer.
Thanks in advance.
Real-Time is perhaps the simpler concept, in that a game that runs in real time has events that update…in real time. If there is a clock in the game, it runs at 60 seconds per minute. Characters move, actions are taken, and choices are made with the clock running consistently and incessantly.
In a real-time match, the players are connected to each other simultaneously in a single game session where they exchange data messages. This form of match is suitable for implementing any type of game that requires live participation.
Welcome to Colyseus Arena It provides developers with enterprise grade hosting leaving server management, infrastructure, DevOps and scaling to us. With Arena, you can setup, manage and update your Colyseus servers with a few clicks from an intuitive administration dashboard.
Just get the time once via NTP at the start of your program and then use System.nanoTime() to get the relative time after that. It is completely monotomic and will not be changed via the setting of the system time.
As per the NTPUDPClient
javadoc:
To use the class, merely open a local datagram socket with open and call
getTime()
to retrieve the time. Then call close to close the connection properly. Successive calls to getTime are permitted without re-establishing a connection.
You are missing a call to open()
in your code (technically close()
as well, but that's not the reason for your issue).
Also, in your requirements, you state you needed the real time (and not whatever time the local client can set). This quantity should not be obtained directly but as an offset required to match local time to server (remote) time, obtained by the method getOffset()
.
If getting the real time is a common procedure, you may want to only use NTP once at the start and use the offset obtained to correct system time in the future, reducing the latency when retrieving real time.
Such a process can be described in a 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)
}
}
Try this:
String TIME_SERVER = "time-a.nist.gov";
TimeTCPClient client = new TimeTCPClient();
try {
client.connect(TIME_SERVER);
System.out.println(client.getDate());
} finally {
client.disconnect();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With