From 8931f32527aedec81fbeb5500015ce9bc30f87c8 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Thu, 6 Jun 2024 19:46:06 +0200 Subject: [PATCH] work on realtime --- DOMAINS.md => DOMAINS-FIREWALL.md | 4 +- notes.txt | 64 +++++++++++++++++++ .../realweather/time/AsyncPlayerTimeTask.java | 8 +-- .../realweather/time/SyncTimeUpdateTask.java | 6 +- .../eu/m724/realweather/time/TimeConfig.java | 4 +- .../eu/m724/realweather/time/TimeMaster.java | 14 ++-- 6 files changed, 87 insertions(+), 13 deletions(-) rename DOMAINS.md => DOMAINS-FIREWALL.md (53%) create mode 100644 notes.txt diff --git a/DOMAINS.md b/DOMAINS-FIREWALL.md similarity index 53% rename from DOMAINS.md rename to DOMAINS-FIREWALL.md index 3924204..17d3a92 100644 --- a/DOMAINS.md +++ b/DOMAINS-FIREWALL.md @@ -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: diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..477da42 --- /dev/null +++ b/notes.txt @@ -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 + diff --git a/src/main/java/eu/m724/realweather/time/AsyncPlayerTimeTask.java b/src/main/java/eu/m724/realweather/time/AsyncPlayerTimeTask.java index d0d2a8b..5cc5666 100644 --- a/src/main/java/eu/m724/realweather/time/AsyncPlayerTimeTask.java +++ b/src/main/java/eu/m724/realweather/time/AsyncPlayerTimeTask.java @@ -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 } diff --git a/src/main/java/eu/m724/realweather/time/SyncTimeUpdateTask.java b/src/main/java/eu/m724/realweather/time/SyncTimeUpdateTask.java index 22e1463..d23be32 100644 --- a/src/main/java/eu/m724/realweather/time/SyncTimeUpdateTask.java +++ b/src/main/java/eu/m724/realweather/time/SyncTimeUpdateTask.java @@ -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 } } diff --git a/src/main/java/eu/m724/realweather/time/TimeConfig.java b/src/main/java/eu/m724/realweather/time/TimeConfig.java index a1ec56b..c4f2168 100644 --- a/src/main/java/eu/m724/realweather/time/TimeConfig.java +++ b/src/main/java/eu/m724/realweather/time/TimeConfig.java @@ -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; } diff --git a/src/main/java/eu/m724/realweather/time/TimeMaster.java b/src/main/java/eu/m724/realweather/time/TimeMaster.java index 5922dc4..110f1ce 100644 --- a/src/main/java/eu/m724/realweather/time/TimeMaster.java +++ b/src/main/java/eu/m724/realweather/time/TimeMaster.java @@ -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); } }