From 95eb893b87beffdacfbad2d084befd6b627c44c6 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sun, 15 Feb 2026 12:48:21 +0100 Subject: [PATCH] World time widget (#7) --- .../widgets/client/WidgetsModClient.java | 1 + .../widgets/widgets/BandwidthWidget.java | 2 +- .../widgets/widgets/BasicTextWidget.java | 4 + .../shiewk/widgets/widgets/BiomeWidget.java | 5 +- .../shiewk/widgets/widgets/ClockWidget.java | 10 ++- .../shiewk/widgets/widgets/ComboWidget.java | 6 +- .../de/shiewk/widgets/widgets/FPSWidget.java | 5 +- .../widgets/widgets/MemoryUsageWidget.java | 5 +- .../de/shiewk/widgets/widgets/PingWidget.java | 6 +- .../widgets/widgets/PlainTextWidget.java | 4 +- .../widgets/widgets/ServerIPWidget.java | 3 +- .../shiewk/widgets/widgets/SpeedWidget.java | 4 +- .../de/shiewk/widgets/widgets/TPSWidget.java | 9 +- .../widgets/widgets/WorldTimeWidget.java | 88 +++++++++++++++++++ .../resources/assets/widgets/lang/de_de.json | 8 +- .../resources/assets/widgets/lang/en_us.json | 8 +- 16 files changed, 132 insertions(+), 36 deletions(-) create mode 100644 src/main/java/de/shiewk/widgets/widgets/WorldTimeWidget.java diff --git a/src/main/java/de/shiewk/widgets/client/WidgetsModClient.java b/src/main/java/de/shiewk/widgets/client/WidgetsModClient.java index 4bda071..5a8dcfc 100644 --- a/src/main/java/de/shiewk/widgets/client/WidgetsModClient.java +++ b/src/main/java/de/shiewk/widgets/client/WidgetsModClient.java @@ -69,6 +69,7 @@ public class WidgetsModClient implements ClientModInitializer { WidgetManager.register(new SpeedWidget(Identifier.of(WidgetsMod.MOD_ID, "speed"))); WidgetManager.register(new ArmorHudWidget(Identifier.of(WidgetsMod.MOD_ID, "armor"))); WidgetManager.register(new InventoryWidget(Identifier.of(WidgetsMod.MOD_ID, "inventory"))); + WidgetManager.register(new WorldTimeWidget(Identifier.of(WidgetsMod.MOD_ID, "worldtime"))); WidgetManager.register(TPSWidget.INSTANCE); ComboWidget comboWidget = new ComboWidget(Identifier.of(WidgetsMod.MOD_ID, "combo")); diff --git a/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java b/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java index 50f712e..1d7e38e 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java @@ -71,7 +71,7 @@ public class BandwidthWidget extends BasicTextWidget { if (t >= tickRate || fastUpdate){ t = 0; long avgBytesPerSecond = getAvgBytesPerSecond(MinecraftClient.getInstance(), tickRate); - formatAndSetRenderText(literal(unit.sizeFormatter.apply(avgBytesPerSecond))); + formatAndSetRenderText(unit.sizeFormatter.apply(avgBytesPerSecond)); if (this.dynamicColor){ if (avgBytesPerSecond < 100000){ this.textColor = GradientOptions.solidColor(0xff00ff00); diff --git a/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java b/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java index 778c708..2b5afa0 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java @@ -146,6 +146,10 @@ public abstract class BasicTextWidget extends ResizableWidget { } } + protected void formatAndSetRenderText(String renderText) { + formatAndSetRenderText(literal(renderText)); + } + public abstract void tickWidget(); @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java b/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java index 70d0f2c..9c0de7b 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java @@ -12,7 +12,6 @@ import net.minecraft.world.biome.Biome; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class BiomeWidget extends BasicTextWidget { @@ -44,12 +43,12 @@ public class BiomeWidget extends BasicTextWidget { }, (b) -> "[unregistered " + b + "]" ); - formatAndSetRenderText(literal(text)); + formatAndSetRenderText(text); } else { if (showLabel){ formatAndSetRenderText(translatable("widgets.widgets.biome.label", "?")); } else { - formatAndSetRenderText(literal("?")); + formatAndSetRenderText("?"); } } } diff --git a/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java b/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java index 11c3595..61dc39a 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java @@ -12,8 +12,6 @@ import java.time.Instant; import java.util.Date; import java.util.List; -import static net.minecraft.text.Text.literal; - public class ClockWidget extends BasicTextWidget { public enum TimeOption { @@ -26,6 +24,10 @@ public class ClockWidget extends BasicTextWidget { TimeOption(String key) { this.key = key; } + + public Text getName() { + return Text.translatable("widgets.widgets.clock.hourFormat."+key); + } } public enum DateOption { @@ -75,7 +77,7 @@ public class ClockWidget extends BasicTextWidget { Text.translatable("widgets.widgets.clock.hourFormat"), TimeOption.class, TimeOption.HOUR_24, - timeOption -> Text.translatable("widgets.widgets.clock.hourFormat."+timeOption.key)), + TimeOption::getName), new ToggleWidgetSetting("show_seconds", Text.translatable("widgets.widgets.clock.showSeconds"), true), @@ -97,7 +99,7 @@ public class ClockWidget extends BasicTextWidget { @Override public void tickWidget() { - formatAndSetRenderText(literal(dateFormat.format(Date.from(Instant.now())))); + formatAndSetRenderText(dateFormat.format(Date.from(Instant.now()))); } @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java b/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java index 3eea3a8..a0c03da 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java @@ -13,10 +13,10 @@ import net.minecraft.util.Identifier; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NonNull; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class ComboWidget extends BasicTextWidget implements AttackEntityCallback { @@ -40,7 +40,7 @@ public class ComboWidget extends BasicTextWidget implements AttackEntityCallback private int displayThreshold = 0; @Override - public ActionResult interact(PlayerEntity playerEntity, World world, Hand hand, Entity entity, @Nullable EntityHitResult entityHitResult) { + public @NonNull ActionResult interact(@NonNull PlayerEntity playerEntity, @NonNull World world, @NonNull Hand hand, Entity entity, @Nullable EntityHitResult entityHitResult) { clientHitEntity(entity.getId()); return ActionResult.PASS; } @@ -89,7 +89,7 @@ public class ComboWidget extends BasicTextWidget implements AttackEntityCallback if (showLabel){ formatAndSetRenderText(translatable("widgets.widgets.combo.combo", combo)); } else { - formatAndSetRenderText(literal(""+combo)); + formatAndSetRenderText(""+combo); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java b/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java index c0af842..55708c4 100644 --- a/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java @@ -11,7 +11,6 @@ import net.minecraft.util.Identifier; import java.util.LinkedList; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class FPSWidget extends BasicTextWidget { @@ -32,7 +31,7 @@ public class FPSWidget extends BasicTextWidget { while (timedFrames.getFirst() < n - 500_000_100L){ timedFrames.removeFirst(); } - formatAndSetRenderText(literal(timedFrames.size() * 2 + " FPS")); + formatAndSetRenderText(timedFrames.size() * 2 + " FPS"); } super.renderScaled(context, n, textRenderer, posX, posY); } @@ -40,7 +39,7 @@ public class FPSWidget extends BasicTextWidget { @Override public void tickWidget() { if (!realtime){ - formatAndSetRenderText(literal(MinecraftClient.getInstance().getCurrentFps() + " FPS")); + formatAndSetRenderText(MinecraftClient.getInstance().getCurrentFps() + " FPS"); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java b/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java index f055176..9dc8ed4 100644 --- a/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java @@ -9,7 +9,6 @@ import net.minecraft.util.Identifier; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class MemoryUsageWidget extends BasicTextWidget { @@ -48,9 +47,9 @@ public class MemoryUsageWidget extends BasicTextWidget { mib(memUsed) + "MiB / " + mib(memTotal) + "MiB (" + memUsagePercent + "%)" : mib(memUsed) + "MiB / " + mib(memTotal) + "MiB"; if (showLabel){ - formatAndSetRenderText(literal(translatable("widgets.widgets.memory.withLabel", memUsageString).getString())); + formatAndSetRenderText(translatable("widgets.widgets.memory.withLabel", memUsageString).getString()); } else { - formatAndSetRenderText(literal(memUsageString)); + formatAndSetRenderText(memUsageString); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/PingWidget.java b/src/main/java/de/shiewk/widgets/widgets/PingWidget.java index da2a76f..2745353 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PingWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PingWidget.java @@ -13,8 +13,6 @@ import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl; import java.util.List; -import static net.minecraft.text.Text.literal; - public class PingWidget extends BasicTextWidget { public PingWidget(Identifier id) { @@ -51,12 +49,12 @@ public class PingWidget extends BasicTextWidget { valuesRead++; } if (valuesRead == 0){ - formatAndSetRenderText(literal("??? ms")); + formatAndSetRenderText("??? ms"); if (this.dynamicColor) this.textColor = GradientOptions.solidColor(0xff00ff00); return; } long avgPing = ping / valuesRead; - formatAndSetRenderText(literal(avgPing + " ms")); + formatAndSetRenderText(avgPing + " ms"); if (this.dynamicColor){ if (avgPing < 50){ this.textColor = GradientOptions.solidColor(0xff00ff00); diff --git a/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java b/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java index 9a47984..ae34e36 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java @@ -7,8 +7,6 @@ import net.minecraft.util.Identifier; import java.util.List; -import static net.minecraft.text.Text.literal; - public class PlainTextWidget extends BasicTextWidget { public PlainTextWidget(Identifier id) { super(id, List.of( @@ -32,6 +30,6 @@ public class PlainTextWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - formatAndSetRenderText(literal((String) settings.optionById("text").getValue())); + formatAndSetRenderText((String) settings.optionById("text").getValue()); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java b/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java index 1369400..83a94c3 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java @@ -10,7 +10,6 @@ import net.minecraft.util.Identifier; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class ServerIPWidget extends BasicTextWidget { @@ -34,7 +33,7 @@ public class ServerIPWidget extends BasicTextWidget { if (!shouldRender) return; final ServerInfo serverEntry = MinecraftClient.getInstance().getCurrentServerEntry(); if (serverEntry != null){ - formatAndSetRenderText(literal(serverEntry.address)); + formatAndSetRenderText(serverEntry.address); } else { formatAndSetRenderText(translatable("menu.singleplayer")); } diff --git a/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java b/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java index 96f126a..8dcd6a3 100644 --- a/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java @@ -13,8 +13,6 @@ import net.minecraft.util.math.Vec3d; import java.util.List; -import static net.minecraft.text.Text.literal; - public class SpeedWidget extends BasicTextWidget { public enum Unit { @@ -82,7 +80,7 @@ public class SpeedWidget extends BasicTextWidget { avg += v; } avg /= averagingWindow.length; - formatAndSetRenderText(literal(reduceDigits(avg) + unit.displayName)); + formatAndSetRenderText(reduceDigits(avg) + unit.displayName); } private String reduceDigits(double v) { diff --git a/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java b/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java index 039310e..21e911e 100644 --- a/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java @@ -13,7 +13,6 @@ import net.minecraft.util.Identifier; import java.util.List; -import static net.minecraft.text.Text.literal; import static net.minecraft.text.Text.translatable; public class TPSWidget extends BasicTextWidget { @@ -82,17 +81,17 @@ public class TPSWidget extends BasicTextWidget { private void updateTPS(float tps, float targetTickRate, boolean loadingFinished) { if (!loadingFinished){ if (showLabel){ - formatAndSetRenderText(literal(translatable("widgets.widgets.tps.tps", "???").getString())); + formatAndSetRenderText(translatable("widgets.widgets.tps.tps", "???").getString()); } else { - formatAndSetRenderText(literal("???")); + formatAndSetRenderText("???"); } if (dynamicColor) this.textColor = GradientOptions.solidColor(0xff00ff00); } else { tps = Math.round(tps * 10f) / 10f; if (showLabel){ - formatAndSetRenderText(literal(translatable("widgets.widgets.tps.tps", tps).getString())); + formatAndSetRenderText(translatable("widgets.widgets.tps.tps", tps).getString()); } else { - formatAndSetRenderText(literal(String.valueOf(tps))); + formatAndSetRenderText(String.valueOf(tps)); } if (dynamicColor){ if (tps >= targetTickRate * 0.990){ diff --git a/src/main/java/de/shiewk/widgets/widgets/WorldTimeWidget.java b/src/main/java/de/shiewk/widgets/widgets/WorldTimeWidget.java new file mode 100644 index 0000000..3ea499a --- /dev/null +++ b/src/main/java/de/shiewk/widgets/widgets/WorldTimeWidget.java @@ -0,0 +1,88 @@ +package de.shiewk.widgets.widgets; + +import de.shiewk.widgets.WidgetSettings; +import de.shiewk.widgets.widgets.settings.EnumWidgetSetting; +import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; +import net.minecraft.client.MinecraftClient; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.world.World; + +import java.util.List; + +import static net.minecraft.text.Text.*; + +public class WorldTimeWidget extends BasicTextWidget { + + public WorldTimeWidget(Identifier id) { + super(id, List.of( + new ToggleWidgetSetting("show_day", translatable("widgets.widgets.worldtime.showDay"), true), + new EnumWidgetSetting<>( + "time_format", + translatable("widgets.widgets.worldtime.timeFormat"), + ClockWidget.TimeOption.class, + ClockWidget.TimeOption.HOUR_24, + ClockWidget.TimeOption::getName + ) + )); + } + + protected boolean showDay; + protected ClockWidget.TimeOption timeFormat; + + public Text getDayLabel(long day) { + return translatable("widgets.widgets.worldtime.day", day); + } + + public Text getTimeLabel(long hour, long minute) { + return switch (timeFormat) { + case NO_TIME -> empty(); + case HOUR_24 -> literal(hour + ":" + (minute < 10 ? "0" + minute : minute)); + case AM_PM -> { + long displayHour = (hour % 12 == 0) ? 12 : hour % 12; + String suffix = (hour < 12) ? " AM" : " PM"; + yield literal(displayHour + ":" + (minute < 10 ? "0" + minute : minute) + suffix); + } + }; + } + + @Override + public void tickWidget() { + final World world = MinecraftClient.getInstance().world; + if (world == null) { + formatAndSetRenderText("?"); + } else { + long time = world.getTimeOfDay() + 6000; + long day = time / 24000; + long hour = time / 1000 % 24; + long minute = (long) ((time % 1000) / 16.6666); + if (showDay && timeFormat != ClockWidget.TimeOption.NO_TIME) { + formatAndSetRenderText(translatable("widgets.widgets.worldtime.dayAndTime", getDayLabel(day), getTimeLabel(hour, minute)).getString()); + } else if (showDay) { + formatAndSetRenderText(getDayLabel(day).getString()); + } else if (timeFormat != ClockWidget.TimeOption.NO_TIME) { + formatAndSetRenderText(getTimeLabel(hour, minute).getString()); + } else { + formatAndSetRenderText(getName()); + } + } + } + + @Override + public void onSettingsChanged(WidgetSettings settings) { + super.onSettingsChanged(settings); + this.showDay = (boolean) settings.optionById("show_day").getValue(); + this.timeFormat = (ClockWidget.TimeOption) settings.optionById("time_format").getValue(); + } + + @Override + public Text getName() { + return translatable("widgets.widgets.worldtime"); + } + + @Override + public Text getDescription() { + return translatable("widgets.widgets.worldtime.description"); + } + +} diff --git a/src/main/resources/assets/widgets/lang/de_de.json b/src/main/resources/assets/widgets/lang/de_de.json index f029dec..af5807b 100644 --- a/src/main/resources/assets/widgets/lang/de_de.json +++ b/src/main/resources/assets/widgets/lang/de_de.json @@ -165,5 +165,11 @@ "widgets.widgets.tps.description": "Zeigt die TPS im Einzelspielermodus an oder schätzt die TPS im Mehrspielermodus", "widgets.widgets.tps.dynamicColor": "Farbe dynamisch anzeigen", "widgets.widgets.tps.tps": "%s TPS", - "widgets.widgets.tps.windowSize": "Durchschnittsfenstergröße (Sekunden)" + "widgets.widgets.tps.windowSize": "Durchschnittsfenstergröße (Sekunden)", + "widgets.widgets.worldtime": "Weltzeit", + "widgets.widgets.worldtime.day": "Tag %s", + "widgets.widgets.worldtime.dayAndTime": "%1$s, %2$s", + "widgets.widgets.worldtime.description": "Zeigt die Uhrzeit und Tageszahl der Welt, in der du bist, an", + "widgets.widgets.worldtime.showDay": "Tag anzeigen", + "widgets.widgets.worldtime.timeFormat": "Zeitformat" } \ No newline at end of file diff --git a/src/main/resources/assets/widgets/lang/en_us.json b/src/main/resources/assets/widgets/lang/en_us.json index 47d6577..e18dc16 100644 --- a/src/main/resources/assets/widgets/lang/en_us.json +++ b/src/main/resources/assets/widgets/lang/en_us.json @@ -165,5 +165,11 @@ "widgets.widgets.tps.description": "Shows the current TPS when in singleplayer and estimates server TPS when in multiplayer.", "widgets.widgets.tps.dynamicColor": "Dynamic Color", "widgets.widgets.tps.tps": "%s TPS", - "widgets.widgets.tps.windowSize": "Averaging window size (seconds)" + "widgets.widgets.tps.windowSize": "Averaging window size (seconds)", + "widgets.widgets.worldtime": "World time", + "widgets.widgets.worldtime.day": "Day %s", + "widgets.widgets.worldtime.dayAndTime": "%1$s, %2$s", + "widgets.widgets.worldtime.description": "Shows the in-game time and day of the world you're in", + "widgets.widgets.worldtime.showDay": "Show day", + "widgets.widgets.worldtime.timeFormat": "Time format" } \ No newline at end of file