work on realtime
This commit is contained in:
		
					parent
					
						
							
								b2a474b011
							
						
					
				
			
			
				commit
				
					
						8931f32527
					
				
			
		
					 6 changed files with 87 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
If you're using a firewall, you must whitelist the following domains:
 | 
			
		||||
If you're using a firewall, you must allow the following hosts:
 | 
			
		||||
- core functionality:
 | 
			
		||||
  * rw-api.m724.eu
 | 
			
		||||
- weather:
 | 
			
		||||
  * api.openweathermap.org
 | 
			
		||||
- thunder:
 | 
			
		||||
							
								
								
									
										64
									
								
								notes.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								notes.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
goal: realtime to in game time conversion
 | 
			
		||||
There is no need to keep days
 | 
			
		||||
 | 
			
		||||
minecraft day is 0 - 24000 ticks
 | 
			
		||||
where 6000 ticks is noon (peak sun) and 18000 is midnight (peak moon)
 | 
			
		||||
 | 
			
		||||
irl day is 0 - 86400 seconds
 | 
			
		||||
 | 
			
		||||
0. s = epoch % 86400 to get seconds since midnight
 | 
			
		||||
            ^
 | 
			
		||||
       (* scale) here
 | 
			
		||||
1. t = s / 72.0 to fit into minecraft day
 | 
			
		||||
2. t = t * 20 to convert that to ticks
 | 
			
		||||
3. t = t - 6000 to align noon and midnight
 | 
			
		||||
   this leaves us with negative time, so
 | 
			
		||||
4. t = floorMod(t, 24000) to wrap if negative
 | 
			
		||||
 | 
			
		||||
example:
 | 
			
		||||
epoch = 1713593340
 | 
			
		||||
 | 
			
		||||
0. getting seconds since midnight
 | 
			
		||||
   s = epoch % 86400
 | 
			
		||||
   s = 1713593340 % 86400
 | 
			
		||||
   s = 22140
 | 
			
		||||
 | 
			
		||||
1. conversion to minecraft day length
 | 
			
		||||
   gs = s / 72.0
 | 
			
		||||
   gs = 22140 / 72.0
 | 
			
		||||
   gs = 307.5
 | 
			
		||||
   
 | 
			
		||||
2. to ticks
 | 
			
		||||
   t = gs * 20
 | 
			
		||||
   t = 307.5 * 20
 | 
			
		||||
   t = 6150
 | 
			
		||||
   
 | 
			
		||||
3. step 3
 | 
			
		||||
   t = t - 6000
 | 
			
		||||
   t = 6150 - 6000
 | 
			
		||||
   t = 150
 | 
			
		||||
 
 | 
			
		||||
4. wrapping
 | 
			
		||||
   t = floorMod(150, 24000)
 | 
			
		||||
   t = 150
 | 
			
		||||
   
 | 
			
		||||
 
 | 
			
		||||
goal: frequency of time update
 | 
			
		||||
 | 
			
		||||
t = 72 / scale
 | 
			
		||||
t is the period, in ticks of course
 | 
			
		||||
 | 
			
		||||
to see how many irl seconds a tick represents:
 | 
			
		||||
s = 3.6 * scale
 | 
			
		||||
(from 1 / (1/72 * 20 * scale))
 | 
			
		||||
 | 
			
		||||
however, some scales result in fractions
 | 
			
		||||
here's how many in game aligned seconds have passed at the end of a real day:
 | 
			
		||||
  84000 / 72 * scale * floor(72/scale)
 | 
			
		||||
for scale 0.99: 83160
 | 
			
		||||
so we'll be 14 minutes behind
 | 
			
		||||
 | 
			
		||||
solution? for now let's warn and update time every tick
 | 
			
		||||
to check:
 | 
			
		||||
scale * floor(72/scale) == 72
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,10 +22,11 @@ public class AsyncPlayerTimeTask extends BukkitRunnable {
 | 
			
		|||
		this.timeConfig = timeConfig;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override // TODO TODO TODO
 | 
			
		||||
	@Override
 | 
			
		||||
	public void run() {
 | 
			
		||||
		for (Player player : server.getOnlinePlayers()) {
 | 
			
		||||
			if (!player.hasPermission("realweather.dynamic")) continue;
 | 
			
		||||
			
 | 
			
		||||
			Weather weather = playerWeatherDirectory.getWeather(player);
 | 
			
		||||
			
 | 
			
		||||
			if (weather != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,9 +34,8 @@ public class AsyncPlayerTimeTask extends BukkitRunnable {
 | 
			
		|||
			}
 | 
			
		||||
			
 | 
			
		||||
			Coordinates coordinates = mapper.locationToCoordinates(player.getLocation());
 | 
			
		||||
			long offsetTicks = (long) (coordinates.longitude / (360 / 1728000));
 | 
			
		||||
			player.setPlayerTime(offsetTicks, true);
 | 
			
		||||
			long offsetTicks = (long) ((coordinates.longitude / 15) * 1000 * timeConfig.scale);
 | 
			
		||||
			player.setPlayerTime(offsetTicks, true); // TODO can this be negative?
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	 // TODO make this also a listener for player joins
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,10 +15,12 @@ public class SyncTimeUpdateTask extends BukkitRunnable {
 | 
			
		|||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void run() {
 | 
			
		||||
		long now = System.currentTimeMillis() / 1000;
 | 
			
		||||
		long time = (long) (((now / 3600 * 1000) - 6000) * timeConfig.modifier % 24000); // TODO test this
 | 
			
		||||
		// TODO double?
 | 
			
		||||
		long now = (long) (System.currentTimeMillis() * timeConfig.scale / 1000);
 | 
			
		||||
		long time = Math.floorMod(now % 86400 / 72 * 20 - 6000, 24000);
 | 
			
		||||
		
 | 
			
		||||
		mapper.getWorlds().forEach(world -> world.setFullTime(time));
 | 
			
		||||
		 // TODO add world handlers to mapper and don't calculate time each run
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ public class TimeConfig {
 | 
			
		|||
	// state is per player
 | 
			
		||||
	public boolean dynamic;
 | 
			
		||||
	// x day cycles in 1 irl day
 | 
			
		||||
	public double modifier;
 | 
			
		||||
	public double scale;
 | 
			
		||||
	
 | 
			
		||||
	public static TimeConfig fromConfiguration(ConfigurationSection configuration) {
 | 
			
		||||
		TimeConfig timeConfig = new TimeConfig();
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ public class TimeConfig {
 | 
			
		|||
		timeConfig.enabled = configuration.getBoolean("enabled");
 | 
			
		||||
		
 | 
			
		||||
		timeConfig.dynamic = configuration.getBoolean("dynamic");
 | 
			
		||||
		timeConfig.modifier = configuration.getDouble("modifier");
 | 
			
		||||
		timeConfig.scale = configuration.getDouble("scale");
 | 
			
		||||
		
 | 
			
		||||
		return timeConfig;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,11 +25,17 @@ public class TimeMaster {
 | 
			
		|||
			return;
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		long period = 1; // TODO calculate update period
 | 
			
		||||
		new SyncTimeUpdateTask(config).runTaskTimer(plugin, 0, period);
 | 
			
		||||
		new AsyncPlayerTimeTask(config).runTaskTimerAsynchronously(plugin, 0, period);
 | 
			
		||||
		long period = (long) (72 / config.scale);
 | 
			
		||||
		
 | 
			
		||||
		if (config.scale * Math.floor(period) == 72) {
 | 
			
		||||
			// TODO log this properly
 | 
			
		||||
			DebugLogger.info("Warning: RealTime scale is not optimal. Time will be out of sync.", 0);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		new SyncTimeUpdateTask(config).runTaskTimer(plugin, 0, period);
 | 
			
		||||
		new AsyncPlayerTimeTask(config).runTaskTimerAsynchronously(plugin, 0, period); // TODO maybe use a different period?
 | 
			
		||||
		// TODO also make it on player join
 | 
			
		||||
		
 | 
			
		||||
		// TODO start task, actually create that task, account for data from weather like sunrise sunset timezone
 | 
			
		||||
		DebugLogger.info("time loaded", 1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue