Skip to content
This repository was archived by the owner on Sep 5, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 49 additions & 63 deletions src/main/java/xyz/verarr/synchrono/IRLTimeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class IRLTimeManager extends PersistentState {

public LocalDate firstStartDate;

public IRLTimeManager() { this.firstStartDate = LocalDate.now(SynchronoConfig.timezone()); }
public IRLTimeManager() { this.firstStartDate = LocalDate.now(ZoneId.of("UTC")); }

public IRLTimeManager(long firstStartDate) {
this.firstStartDate = LocalDate.ofEpochDay(firstStartDate);
Expand All @@ -45,44 +45,41 @@ public static IRLTimeManager getInstance(ServerWorld world) {

private SunriseSunsetData querySunriseSunsetAPI(LocalDate localDate) {
return SunriseSunsetAPI.query(localDate, SynchronoConfig.latitude,
SynchronoConfig.longitude, SynchronoConfig.timezone());
SynchronoConfig.longitude);
}

public long tickAt(LocalDateTime dateTime) {
public long tickAt(Instant instant) {
long ticks;

long days = ChronoUnit.DAYS.between(firstStartDate, dateTime.toLocalDate());
ticks = days * TICKS_PER_DAY;
long days =
ChronoUnit.DAYS.between(firstStartDate, instant.atZone(ZoneId.of("UTC")).toLocalDate());
ticks = days * TICKS_PER_DAY;
LocalDate yesterday, today, tomorrow;
yesterday = dateTime.minusDays(1).toLocalDate();
today = dateTime.toLocalDate();
tomorrow = dateTime.plusDays(1).toLocalDate();
yesterday = instant.minus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();
today = instant.atZone(ZoneId.of("UTC")).toLocalDate();
tomorrow = instant.plus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();

SunriseSunsetData yesterday_data, today_data, tomorrow_data;
yesterday_data = querySunriseSunsetAPI(yesterday);
today_data = querySunriseSunsetAPI(today);
tomorrow_data = querySunriseSunsetAPI(tomorrow);

if (dateTime.isBefore(dateTime.toLocalDate().atTime(today_data.sunrise))) {
if (instant.isBefore(today_data.sunrise)) {
// before sunrise - use yesterday_data (and today_data)
Duration night_length = Duration.between(yesterday.atTime(yesterday_data.sunset),
today.atTime(today_data.sunrise));
Duration since_sunset =
Duration.between(yesterday.atTime(yesterday_data.sunset), dateTime);
double tick_scalar = (double) since_sunset.toMillis() / night_length.toMillis();
ticks -= (TICKS_PER_HALF_DAY) - (long) (TICKS_PER_HALF_DAY * tick_scalar);
} else if (dateTime.isAfter(today.atTime(today_data.sunset))) {
Duration night_length = Duration.between(yesterday_data.sunset, today_data.sunrise);
Duration since_sunset = Duration.between(yesterday_data.sunset, instant);
double tick_scalar = (double) since_sunset.toMillis() / night_length.toMillis();
ticks -= (TICKS_PER_HALF_DAY) - (long) (TICKS_PER_HALF_DAY * tick_scalar);
} else if (instant.isAfter(today_data.sunset)) {
// after sunset - use tomorrow_data (and today_data)
Duration night_length = Duration.between(today.atTime(today_data.sunset),
tomorrow.atTime(tomorrow_data.sunrise));
Duration since_sunset = Duration.between(today.atTime(today_data.sunset), dateTime);
Duration night_length = Duration.between(today_data.sunset, tomorrow_data.sunrise);
Duration since_sunset = Duration.between(today_data.sunset, instant);
double tick_scalar = (double) since_sunset.toMillis() / night_length.toMillis();
ticks += TICKS_PER_HALF_DAY + (long) (TICKS_PER_HALF_DAY * tick_scalar);
} else {
// daytime - only use today_data
Duration day_length =
Duration.between(today.atTime(today_data.sunrise), today.atTime(today_data.sunset));
Duration since_sunrise = Duration.between(today.atTime(today_data.sunrise), dateTime);
Duration day_length = Duration.between(today_data.sunrise, today_data.sunset);
Duration since_sunrise = Duration.between(today_data.sunrise, instant);
double tick_scalar = (double) since_sunrise.toMillis() / day_length.toMillis();
ticks += (long) (TICKS_PER_HALF_DAY * tick_scalar);
}
Expand All @@ -96,88 +93,77 @@ public long tickAt(LocalDateTime dateTime) {
return ticks;
}

public int daytimeTicksAt(LocalDateTime dateTime) {
public int daytimeTicksAt(Instant instant) {
int daytimeTicks;

if (!SynchronoConfig.invert) daytimeTicks = hardDaytimeTicksAt(dateTime);
else daytimeTicks = hardNighttimeTicksAt(dateTime) + TICKS_PER_HALF_DAY;
if (!SynchronoConfig.invert) daytimeTicks = hardDaytimeTicksAt(instant);
else daytimeTicks = hardNighttimeTicksAt(instant) + TICKS_PER_HALF_DAY;

daytimeTicks = (int) Math.round(daytimeTicks / SynchronoConfig.scalar);

return daytimeTicks;
}

public int nighttimeTicksAt(LocalDateTime dateTime) {
public int nighttimeTicksAt(Instant instant) {
int nighttimeTicks;

if (!SynchronoConfig.invert) nighttimeTicks = hardNighttimeTicksAt(dateTime);
else nighttimeTicks = hardDaytimeTicksAt(dateTime) + TICKS_PER_HALF_DAY;
if (!SynchronoConfig.invert) nighttimeTicks = hardNighttimeTicksAt(instant);
else nighttimeTicks = hardDaytimeTicksAt(instant) + TICKS_PER_HALF_DAY;

nighttimeTicks = (int) Math.round(nighttimeTicks / SynchronoConfig.scalar);

return nighttimeTicks;
}

private int hardDaytimeTicksAt(LocalDateTime dateTime) {
private int hardDaytimeTicksAt(Instant instant) {
LocalDate yesterday, today, tomorrow;
yesterday = dateTime.minusDays(1).toLocalDate();
today = dateTime.toLocalDate();
tomorrow = dateTime.plusDays(1).toLocalDate();
yesterday = instant.minus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();
today = instant.atZone(ZoneId.of("UTC")).toLocalDate();
tomorrow = instant.plus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();

SunriseSunsetData yesterdayData, todayData, tomorrowData;
yesterdayData = querySunriseSunsetAPI(yesterday);
todayData = querySunriseSunsetAPI(today);
tomorrowData = querySunriseSunsetAPI(tomorrow);

if (dateTime.isBefore(today.atTime(todayData.sunrise))) {
if (instant.isBefore(todayData.sunrise)) {
// update next daytime aka today
return (int) Duration
.between(today.atTime(todayData.sunrise), today.atTime(todayData.sunset))
.toSeconds()
* SERVER_TICKS_PER_SECOND;
} else if (dateTime.isAfter(today.atTime(todayData.sunset))) {
return (int) (Duration.between(todayData.sunrise, todayData.sunset).toSeconds()
* SERVER_TICKS_PER_SECOND);
} else if (instant.isAfter(todayData.sunset)) {
// update next daytime aka tomorrow
return (int) Duration.between(tomorrowData.sunrise, tomorrowData.sunset).toSeconds()
* SERVER_TICKS_PER_SECOND;
return (int) (Duration.between(tomorrowData.sunrise, tomorrowData.sunset).toSeconds()
* SERVER_TICKS_PER_SECOND);
} else {
// update current daytime
return (int) Duration.between(todayData.sunrise, todayData.sunset).toSeconds()
* SERVER_TICKS_PER_SECOND;
return (int) (Duration.between(todayData.sunrise, todayData.sunset).toSeconds()
* SERVER_TICKS_PER_SECOND);
}
}

private int hardNighttimeTicksAt(LocalDateTime dateTime) {
private int hardNighttimeTicksAt(Instant instant) {
LocalDate yesterday, today, tomorrow;
yesterday = dateTime.minusDays(1).toLocalDate();
today = dateTime.toLocalDate();
tomorrow = dateTime.plusDays(1).toLocalDate();
yesterday = instant.minus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();
today = instant.atZone(ZoneId.of("UTC")).toLocalDate();
tomorrow = instant.plus(Duration.ofDays(1)).atZone(ZoneId.of("UTC")).toLocalDate();

SunriseSunsetData yesterdayData, todayData, tomorrowData;
yesterdayData = querySunriseSunsetAPI(yesterday);
todayData = querySunriseSunsetAPI(today);
tomorrowData = querySunriseSunsetAPI(tomorrow);

if (dateTime.isBefore(today.atTime(todayData.sunrise))) {
if (instant.isBefore(todayData.sunrise)) {
// update current nighttime aka yesterday and today
return (int) Duration
.between(yesterday.atTime(yesterdayData.sunset),
today.atTime(todayData.sunrise))
.toSeconds()
* SERVER_TICKS_PER_SECOND;
} else if (dateTime.isAfter(today.atTime(todayData.sunset))) {
return (int) (Duration.between(yesterdayData.sunset, todayData.sunrise).toSeconds()
* SERVER_TICKS_PER_SECOND);
} else if (instant.isAfter(todayData.sunset)) {
// update current nighttime aka today and tomorrow
return (int) Duration
.between(today.atTime(todayData.sunset),
tomorrow.atTime(tomorrowData.sunrise))
.toSeconds()
* SERVER_TICKS_PER_SECOND;
return (int) (Duration.between(todayData.sunset, tomorrowData.sunrise).toSeconds()
* SERVER_TICKS_PER_SECOND);
} else {
// update next nighttime aka today and tomorrow
return (int) Duration
.between(yesterday.atTime(todayData.sunset),
today.atTime(tomorrowData.sunrise))
.toSeconds()
* SERVER_TICKS_PER_SECOND;
return (int) (Duration.between(todayData.sunset, tomorrowData.sunrise).toSeconds()
* SERVER_TICKS_PER_SECOND);
}
}
}
41 changes: 0 additions & 41 deletions src/main/java/xyz/verarr/synchrono/config/SynchronoConfig.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
package xyz.verarr.synchrono.config;

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.GsonBuilder;

Expand All @@ -17,7 +11,6 @@
import dev.isxander.yacl3.config.v2.api.SerialEntry;
import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder;
import net.fabricmc.loader.api.FabricLoader;
import xyz.verarr.synchrono.external_apis.GeoNamesAPI;

public class SynchronoConfig {
public static ConfigClassHandler<SynchronoConfig> HANDLER =
Expand Down Expand Up @@ -72,38 +65,4 @@ public Text getDisplayName() {
@SerialEntry public static boolean setRate = true;
@SerialEntry public static boolean preventSleep = true;
@SerialEntry public static boolean removeCommands = true;

private static class Coordinates {
public double latitude;
public double longitude;

public Coordinates(double lat, double lng) {
this.latitude = lat;
this.longitude = lng;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinates that = (Coordinates) o;
return Double.compare(that.latitude, latitude) == 0
&& Double.compare(that.longitude, longitude) == 0;
}

@Override
public int hashCode() {
return Objects.hash(latitude, longitude);
}
}

private static final Map<Coordinates, ZoneOffset> zoneOffsetCache = new HashMap<>(1);

public static ZoneId timezone() {
return ZoneId.ofOffset(
"UTC",
zoneOffsetCache.computeIfAbsent(
new Coordinates(latitude, longitude),
coordinates -> GeoNamesAPI.query(coordinates.latitude, coordinates.longitude)));
}
}
40 changes: 0 additions & 40 deletions src/main/java/xyz/verarr/synchrono/external_apis/GeoNamesAPI.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import java.net.URI;
import java.net.URISyntaxException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
Expand All @@ -24,14 +24,10 @@ private static class SunriseSunsetAPIQuery {
double latitude, longitude;
ZoneId timezone;

public SunriseSunsetAPIQuery(LocalDate date,
double latitude,
double longitude,
ZoneId timezone) {
public SunriseSunsetAPIQuery(LocalDate date, double latitude, double longitude) {
this.date = date;
this.latitude = latitude;
this.longitude = longitude;
this.timezone = timezone;
}

@Override
Expand All @@ -40,7 +36,7 @@ public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
SunriseSunsetAPIQuery that = (SunriseSunsetAPIQuery) o;
return date.isEqual(that.date) && (Double.compare(that.latitude, latitude) == 0)
&& (Double.compare(that.longitude, longitude) == 0) && timezone.equals(that.timezone);
&& (Double.compare(that.longitude, longitude) == 0);
}

@Override
Expand All @@ -52,8 +48,8 @@ public int hashCode() {
private static Map<SunriseSunsetAPIQuery, SunriseSunsetData> cache = new HashMap<>();

public static @NotNull
SunriseSunsetData query(LocalDate date, double latitude, double longitude, ZoneId timezone) {
return cache.computeIfAbsent(new SunriseSunsetAPIQuery(date, latitude, longitude, timezone),
SunriseSunsetData query(LocalDate date, double latitude, double longitude) {
return cache.computeIfAbsent(new SunriseSunsetAPIQuery(date, latitude, longitude),
SunriseSunsetAPI::query);
}

Expand All @@ -63,11 +59,10 @@ SunriseSunsetData query(LocalDate date, double latitude, double longitude, ZoneI
URI uri;
try {
Formatter formatter = new Formatter(Locale.ROOT);
uri =
new URI(API_URL
+ formatter.format("?date=%s&lat=%f&lng=%f&timezone=%s&time_format=24",
details.date.format(DateTimeFormatter.ISO_LOCAL_DATE),
details.latitude, details.longitude, details.timezone));
uri = new URI(API_URL
+ formatter.format("?date=%s&lat=%f&lng=%f&timezone=UTC&time_format=unix",
details.date.format(DateTimeFormatter.ISO_LOCAL_DATE),
details.latitude, details.longitude));
} catch (URISyntaxException e) { throw new RuntimeException(e); }

String result = HTTPHelper.get(uri);
Expand All @@ -84,10 +79,12 @@ SunriseSunsetData query(LocalDate date, double latitude, double longitude, ZoneI
}

JsonObject results = jsonObject.get("results").getAsJsonObject();
LocalTime sunrise, sunset;
Instant sunrise, sunset;
try {
sunrise = LocalTime.parse(results.get(SynchronoConfig.sunriseProperty).getAsString());
sunset = LocalTime.parse(results.get(SynchronoConfig.sunsetProperty).getAsString());
sunrise = Instant.ofEpochSecond(
Long.parseLong(results.get(SynchronoConfig.sunriseProperty).getAsString()));
sunset = Instant.ofEpochSecond(
Long.parseLong(results.get(SynchronoConfig.sunsetProperty).getAsString()));
} catch (UnsupportedOperationException e) {
throw new RuntimeException(e + " JSON: " + result);
}
Expand All @@ -99,7 +96,7 @@ SunriseSunsetData query(LocalDate date, double latitude, double longitude, ZoneI
}

public static class SunriseSunsetData {
public LocalTime sunrise;
public LocalTime sunset;
public Instant sunrise;
public Instant sunset;
}
}
Loading