diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersConfig.java new file mode 100644 index 0000000000..4f47e41ba7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersConfig.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019, RuneLitePlus + * Copyright (c) 2019, kyle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.plugins.reminders; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("Reminders") +public interface RemindersConfig extends Config +{ + @ConfigItem( + keyName = "breakReminder", + name = "Break Reminder", + description = "Reminds you to take a 5-10 minute break every hour.", + position = 0 + ) + default boolean breakReminder() + { + return false; + } + + @ConfigItem( + keyName = "hydrationReminder", + name = "Hydration Reminder", + description = "Reminds you to drink 4oz/120ml of water every hour", + position = 1 + ) + default boolean hydrationReminder() + { + return false; + } + + @ConfigItem( + keyName = "personalReminders", + name = "Personal Reminders", + description = "Set your own personal reminders", + position = 2 + ) + default boolean personalReminders() + { + return false; + } + + @ConfigItem( + keyName = "personalReminder1", + name = "Personal Reminder #1", + description = "Set your first personal reminder", + position = 3, + hidden = true, + unhide = "personalReminders" + ) + default boolean personalReminder1() + { + return false; + } + + @ConfigItem( + keyName = "personalReminderText1", + name = "Personal Reminder Text #1", + description = "Set the text to your first personal reminder", + position = 4, + hidden = true, + unhide = "personalReminder1" + ) + default String personalReminderText1() + { + return ""; + } + + @ConfigItem( + keyName = "personalreminderTime1", + name = "Personal Reminder Time #1", + description = "Time in minutes for your first personal reminder", + position = 5, + hidden = true, + unhide = "personalReminder1" + ) + default int personalReminderTime1() + { + return 0; + } + + @ConfigItem( + keyName = "personalReminder2", + name = "Personal Reminder #2", + description = "Set your second personal reminder", + position = 6, + hidden = true, + unhide = "personalReminders" + ) + default boolean personalReminder2() + { + return false; + } + + @ConfigItem( + keyName = "personalReminderText2", + name = "Personal Reminder Text #2", + description = "Set the text to your second personal reminder", + position = 7, + hidden = true, + unhide = "personalReminder2" + ) + default String personalReminderText2() + { + return ""; + } + + @ConfigItem( + keyName = "personalreminderTime2", + name = "Personal Reminder Time #2", + description = "Time in minutes for your second personal reminder", + position = 8, + hidden = true, + unhide = "personalReminder2" + ) + default int personalReminderTime2() + { + return 0; + } + + @ConfigItem( + keyName = "personalReminder3", + name = "Personal Reminder #3", + description = "Set your third personal reminder", + position = 9, + hidden = true, + unhide = "personalReminders" + ) + default boolean personalReminder3() + { + return false; + } + + @ConfigItem( + keyName = "personalReminderText3", + name = "Personal Reminder Text #3", + description = "Set the text to your third personal reminder", + position = 10, + hidden = true, + unhide = "personalReminder3" + ) + default String personalReminderText3() + { + return ""; + } + + @ConfigItem( + keyName = "personalreminderTime3", + name = "Personal Reminder Time #3", + description = "Time in minutes for your third personal reminder", + position = 11, + hidden = true, + unhide = "personalReminder3" + ) + default int personalReminderTime3() + { + return 0; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersPlugin.java new file mode 100644 index 0000000000..740a901e51 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reminders/RemindersPlugin.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2019, jkybtw + * Copyright (c) 2019, RuneLitePlus + * Copyright (c) 2019, kyle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.reminders; + +import com.google.inject.Provides; +import static java.lang.Math.floor; +import static java.time.Duration.between; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.task.Schedule; +import javax.inject.Inject; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +@PluginDescriptor( + name = "Reminders", + description = "various reminders", + tags = {"session", "reminder", "hydrate", "hydration"}, + enabledByDefault = false, + type = PluginType.UTILITY +) + +@Slf4j +public class RemindersPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private EventBus eventBus; + + @Inject + private RemindersConfig config; + + @Inject + private ChatMessageManager chatMessageManager; + + private Instant loginTime; + private boolean ready; + private int seconds; + private int minutes; + private int hours; + private int ounces; + private int millilitres; + private boolean hydrationReminder; + private boolean breakReminder; + private boolean personalReminders; + private boolean personalReminder1; + private String personalReminderText1; + private int personalReminderTime1; + private boolean personalReminder2; + private String personalReminderText2; + private int personalReminderTime2; + private boolean personalReminder3; + private String personalReminderText3; + private int personalReminderTime3; + + + + @Provides + RemindersConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(RemindersConfig.class); + } + + @Override + public void startUp() + { + addSubscriptions(); + updateConfig(); + } + + @Override + public void shutDown() + { + eventBus.unregister(this); + loginTime = null; + } + + private void addSubscriptions() + { + eventBus.subscribe(GameStateChanged.class, this, this::onGameStateChanged); + eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged); + } + + public void onGameStateChanged(GameStateChanged event) + { + final GameState state = event.getGameState(); + + switch (state) + { + case LOGIN_SCREEN: + case LOGIN_SCREEN_AUTHENTICATOR: + case LOGGING_IN: + ready = true; + loginTime = null; + break; + case LOGGED_IN: + if (ready) + { + loginTime = Instant.now(); + ready = false; + } + break; + } + } + + private void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("Reminders")) + { + updateConfig(); + } + } + + private void timers() + { + if (loginTime == null) + { + return; + } + seconds = 60; + minutes = (int) floor(between(loginTime, Instant.now()).getSeconds() / seconds); + hours = minutes / seconds; + ounces = 4 * hours; + millilitres = 120 * hours; + } + + private String pluralizeTime(String time, int count) + { + final StringBuilder sb = new StringBuilder(); + sb + .append(count) + .append(" ") + .append(time); + if (count != 1) + { + sb.append("s"); + } + return sb.toString(); + } + + private void breakReminders() + { + timers(); + if (!this.breakReminder) + { + log.error("breakReminder - Unexpected value: " + hours); + } + + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage( + new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("You have been logged in for ") + .append(pluralizeTime("hour", hours)) + .append(". You should take a 5-10 minute break.") + .build()) + .build()); + } + + private void hydrationReminders() + { + timers(); + if (!this.hydrationReminder) + { + log.error("hydrationReminder - Unexpected value: " + hours); + } + + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage( + new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("You have been logged in for ") + .append(pluralizeTime("hour", hours)) + .append(". By this point, you should have consumed at least " + ounces + "oz (" + millilitres + "ml) of Water to maintain optimum hydration.") + .build()) + .build()); + } + + private void personalReminder1() + { + if (!this.personalReminders && !this.personalReminder1) + { + log.error("personalReminder1 - Unexpected value: " + this.personalReminderText1 + hours); + } + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage( + new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(this.personalReminderText1) + .build()) + .build()); + } + + private void personalReminder2() + { + if (!this.personalReminders && !this.personalReminder2) + { + log.error("personalReminder2 - Unexpected value: " + this.personalReminderText2 + hours); + } + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage( + new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(this.personalReminderText2) + .build()) + .build()); + } + + private void personalReminder3() + { + if (!this.personalReminders && !this.personalReminder3) + { + log.error("personalReminder3 - Unexpected value: " + this.personalReminderText3 + hours); + } + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.CONSOLE).runeLiteFormattedMessage( + new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append(this.personalReminderText3) + .build()) + .build()); + } + + + @Schedule( + period = 1, + unit = ChronoUnit.MINUTES + ) + public void reminders() + { + + timers(); + if (minutes % seconds == 0 && minutes > 0) + { + if (this.breakReminder) + { + breakReminders(); + } + if (this.hydrationReminder) + { + hydrationReminders(); + } + } + if (minutes % this.personalReminderTime1 == 0 && minutes > 0 && !this.personalReminderText1.isEmpty()) + { + personalReminder1(); + } + if (minutes % this.personalReminderTime2 == 0 && minutes > 0 && !this.personalReminderText2.isEmpty()) + { + personalReminder2(); + } + if (minutes % this.personalReminderTime3 == 0 && minutes > 0 && !this.personalReminderText3.isEmpty()) + { + personalReminder3(); + } + } + + private void updateConfig() + { + this.hydrationReminder = config.hydrationReminder(); + this.breakReminder = config.breakReminder(); + this.personalReminders = config.personalReminders(); + this.personalReminder1 = config.personalReminder1(); + this.personalReminder2 = config.personalReminder2(); + this.personalReminder3 = config.personalReminder3(); + this.personalReminderText1 = config.personalReminderText1(); + this.personalReminderText2 = config.personalReminderText2(); + this.personalReminderText3 = config.personalReminderText3(); + this.personalReminderTime1 = config.personalReminderTime1(); + this.personalReminderTime2 = config.personalReminderTime2(); + this.personalReminderTime3 = config.personalReminderTime3(); + } +}