diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MiscCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MiscCategory.java index 06ab5f9fbbb..c4f446e6fea 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/MiscCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/MiscCategory.java @@ -36,6 +36,14 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .controller(ConfigUtils.createBooleanController()) .build() ) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.misc.disableBreakReminders")) + .description(Text.translatable("skyblocker.config.misc.disableBreakReminders.@Tooltip")) + .binding(defaults.misc.disableBreakReminders, + () -> config.misc.disableBreakReminders, + newValue -> config.misc.disableBreakReminders = newValue) + .controller(ConfigUtils.createBooleanController()) + .build()) //Discord RPC .group(OptionGroup.createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/config/configs/MiscConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/MiscConfig.java index 194725965e7..ea5f201206d 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/MiscConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/MiscConfig.java @@ -11,6 +11,8 @@ public class MiscConfig { public boolean cat = true; + public boolean disableBreakReminders = false; + public static class RichPresence { public boolean enableRichPresence = false; diff --git a/src/main/java/de/hysky/skyblocker/mixins/accessors/InactivityFpsLimiterAccessor.java b/src/main/java/de/hysky/skyblocker/mixins/accessors/InactivityFpsLimiterAccessor.java new file mode 100644 index 00000000000..b3bf1c5c6c6 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixins/accessors/InactivityFpsLimiterAccessor.java @@ -0,0 +1,12 @@ +package de.hysky.skyblocker.mixins.accessors; + +import net.minecraft.client.option.InactivityFpsLimiter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(InactivityFpsLimiter.class) +public interface InactivityFpsLimiterAccessor { + + @Accessor("lastInputTime") + long getLastInputTime(); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/BreakReminder.java b/src/main/java/de/hysky/skyblocker/skyblock/BreakReminder.java new file mode 100644 index 00000000000..75d1384b354 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/BreakReminder.java @@ -0,0 +1,58 @@ +package de.hysky.skyblocker.skyblock; + +import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.events.SkyblockEvents; +import de.hysky.skyblocker.mixins.accessors.InactivityFpsLimiterAccessor; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.toast.SystemToast; +import net.minecraft.text.Text; +import net.minecraft.util.Util; + +import java.util.Random; + +public class BreakReminder { + private static final long WARNING_INTERVAL = 60 * 60 * 1000; + private static final long AFK_REQUIRED_FOR_BREAK = 90 * 1000; + private static final int DESCRIPTION_COUNT = 6; + + private static long startedPlayingMillis; + private static long lastWarningMillis; + + @Init + public static void init() { + SkyblockEvents.JOIN.register(() -> { + long l = Util.getMeasuringTimeMs(); + startedPlayingMillis = l; + lastWarningMillis = l; + }); + Scheduler.INSTANCE.scheduleCyclic(BreakReminder::tick, 20 * 30, true); + } + + private static void tick() { + if (!Utils.isOnSkyblock() || SkyblockerConfigManager.get().misc.disableBreakReminders) return; + long time = Util.getMeasuringTimeMs(); + MinecraftClient client = MinecraftClient.getInstance(); + if (time - ((InactivityFpsLimiterAccessor) client.getInactivityFpsLimiter()).getLastInputTime() > AFK_REQUIRED_FOR_BREAK) { + lastWarningMillis = time; + } + if (time - lastWarningMillis > WARNING_INTERVAL) { + lastWarningMillis = time; + client.execute(BreakReminder::warnCouchPotato); + } + } + + private static void warnCouchPotato() { + MinecraftClient client = MinecraftClient.getInstance(); + long playingFor = lastWarningMillis - startedPlayingMillis; + int playingForHours = (int) (playingFor / 3600_000); + client.getToastManager().add(SystemToast.create( + client, + SystemToast.Type.PERIODIC_NOTIFICATION, + Text.translatable("skyblocker.potato.title", playingForHours), + Text.translatable("skyblocker.potato.description" + new Random().nextInt(DESCRIPTION_COUNT)) + )); + } +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 22139e5d726..01d2ec5addb 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -875,6 +875,9 @@ "skyblocker.config.misc.configBackend": "Config Backend", "skyblocker.config.misc.configBackend.@Tooltip": "You can choose between having YetAnotherConfigLib (YACL) or MoulConfig as the Config Backend.", + "skyblocker.config.misc.disableBreakReminders": "Disable break reminders", + "skyblocker.config.misc.disableBreakReminders.@Tooltip": "This is meant for content creators. If you disable this, please remember to take breaks.", + "skyblocker.config.misc.richPresence": "Discord RPC", "skyblocker.config.misc.richPresence.customMessage": "Custom Message", "skyblocker.config.misc.richPresence.cycleMode": "Cycle Skyblock Info", @@ -1580,6 +1583,14 @@ "skyblocker.partyFinder.tabs.searchSettings": "Search Filters", "skyblocker.partyFinder.yourParty": "Your party", + "skyblocker.potato.description0": "Get up and go get a glass of water.", + "skyblocker.potato.description1": "You are reaching critical levels of potato.", + "skyblocker.potato.description2": "Remember to take breaks!", + "skyblocker.potato.description3": "Don't forget to hydrate!", + "skyblocker.potato.description4": "Might be time for a break don't ya think?", + "skyblocker.potato.description5": "Are you using a macro?", + "skyblocker.potato.title": "You have been playing for %s hours.", + "skyblocker.powderTracker": "Powder Mining Tracker", "skyblocker.powderTracker.emptyHistory": "Your powder mining rewards list is empty :(", "skyblocker.powderTracker.historyReset": "Powder mining tracker has been reset for the current profile.", diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 8416809b02a..61f897ba01f 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -69,6 +69,7 @@ "accessors.EntityRenderManagerAccessor", "accessors.FrustumInvoker", "accessors.HandledScreenAccessor", + "accessors.InactivityFpsLimiterAccessor", "accessors.InGameHudInvoker", "accessors.MapStateAccessor", "accessors.MessageHandlerAccessor",