diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Tab.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/Tab.java similarity index 73% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Tab.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/Tab.java index 50f50b2ed8..5eafc8129f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Tab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/Tab.java @@ -22,7 +22,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -32,12 +32,17 @@ import net.runelite.api.ItemID; @Getter public enum Tab { - ALLOTMENT("Allotments", ItemID.CABBAGE), - HERB("Herbs", ItemID.GRIMY_RANARR_WEED), - TREE("Trees", ItemID.MAHOGANY_LOGS), - FRUIT_TREE("Fruit Trees", ItemID.PINEAPPLE), - BUSH("Bushes", ItemID.REDBERRIES), - SPECIAL("Special", ItemID.MUSHROOM); + ALLOTMENT("Allotment Patches", ItemID.CABBAGE), + FLOWER("Flower Patches", ItemID.RED_FLOWERS), + HERB("Herb Patches", ItemID.GRIMY_RANARR_WEED), + TREE("Tree Patches", ItemID.YEW_LOGS), + FRUIT_TREE("Fruit Tree Patches", ItemID.PINEAPPLE), + HOPS("Hops Patches", ItemID.BARLEY), + BUSH("Bush Patches", ItemID.POISON_IVY_BERRIES), + GRAPE("Grape Patches", ItemID.GRAPES), + SPECIAL("Special Patches", ItemID.MUSHROOM); + + public static final Tab[] FARMING_TABS = {ALLOTMENT, FLOWER, HERB, TREE, FRUIT_TREE, HOPS, BUSH, GRAPE, SPECIAL}; private final String name; private final int itemID; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TabContentPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TabContentPanel.java new file mode 100644 index 0000000000..199d6c920b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TabContentPanel.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, Daniel Teo + * 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.timetracking; + +import java.awt.Dimension; +import javax.swing.JPanel; +import net.runelite.client.ui.PluginPanel; + +public abstract class TabContentPanel extends JPanel +{ + public abstract void update(); + + @Override + public Dimension getPreferredSize() + { + return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java similarity index 80% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerConfig.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java index 30653b5aa9..9d013445f0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java @@ -22,22 +22,22 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup("farmingTracker") -public interface FarmingTrackerConfig extends Config +@ConfigGroup("timetracking") +public interface TimeTrackingConfig extends Config { - String KEY_NAME = "farmingTracker"; + String KEY_NAME = "timetracking"; String AUTOWEED = "autoweed"; @ConfigItem( keyName = "estimateRelative", name = "Show relative time", - description = "Show amount of time remaining for a patch, opposed to when the patch is finished" + description = "Show amount of time remaining instead of completion time" ) default boolean estimateRelative() { @@ -45,21 +45,21 @@ public interface FarmingTrackerConfig extends Config } @ConfigItem( - keyName = "patch", - name = "Default patch", - description = "Default patch on opening the panel", + keyName = "activeTab", + name = "Active Tab", + description = "The currently selected tab", hidden = true ) - default Tab patch() + default Tab activeTab() { return Tab.ALLOTMENT; } @ConfigItem( - keyName = "patch", + keyName = "activeTab", name = "", description = "", hidden = true ) - void setPatch(Tab t); -} \ No newline at end of file + void setActiveTab(Tab t); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPanel.java new file mode 100644 index 0000000000..72842e08a1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPanel.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018 Abex + * Copyright (c) 2018, Psikoi + * 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.timetracking; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.annotation.Nullable; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.border.EmptyBorder; +import lombok.extern.slf4j.Slf4j; +import net.runelite.client.game.AsyncBufferedImage; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.timetracking.farming.FarmingTracker; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.materialtabs.MaterialTab; +import net.runelite.client.ui.components.materialtabs.MaterialTabGroup; + +@Slf4j +class TimeTrackingPanel extends PluginPanel +{ + private final ItemManager itemManager; + private final TimeTrackingConfig config; + + /* This is the panel the tabs' respective panels will be displayed on. */ + private final JPanel display = new JPanel(); + private final MaterialTabGroup tabGroup = new MaterialTabGroup(display); + + private boolean active; + + @Nullable + private TabContentPanel activeTabPanel = null; + + TimeTrackingPanel(ItemManager itemManager, TimeTrackingConfig config, FarmingTracker farmingTracker) + { + super(false); + + this.itemManager = itemManager; + this.config = config; + + setLayout(new BorderLayout()); + setBackground(ColorScheme.DARK_GRAY_COLOR); + + display.setBorder(new EmptyBorder(10, 10, 8, 10)); + + tabGroup.setLayout(new GridLayout(0, 6, 7, 7)); + tabGroup.setBorder(new EmptyBorder(10, 10, 0, 10)); + + add(tabGroup, BorderLayout.NORTH); + add(display, BorderLayout.CENTER); + + for (Tab tab : Tab.FARMING_TABS) + { + addTab(tab, farmingTracker.createTabPanel(tab)); + } + } + + private void addTab(Tab tab, TabContentPanel tabContentPanel) + { + JPanel wrapped = new JPanel(new BorderLayout()); + wrapped.add(tabContentPanel, BorderLayout.NORTH); + wrapped.setBackground(ColorScheme.DARK_GRAY_COLOR); + + JScrollPane scroller = new JScrollPane(wrapped); + scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scroller.getVerticalScrollBar().setPreferredSize(new Dimension(16, 0)); + scroller.getVerticalScrollBar().setBorder(new EmptyBorder(0, 9, 0, 0)); + scroller.setBackground(ColorScheme.DARK_GRAY_COLOR); + + // Use a placeholder icon until the async image gets loaded + MaterialTab materialTab = new MaterialTab(new ImageIcon(), tabGroup, scroller); + materialTab.setPreferredSize(new Dimension(30, 27)); + materialTab.setName(tab.getName()); + materialTab.setToolTipText(tab.getName()); + + AsyncBufferedImage icon = itemManager.getImage(tab.getItemID()); + Runnable resize = () -> + { + BufferedImage subIcon = icon.getSubimage(0, 0, 32, 32); + materialTab.setIcon(new ImageIcon(subIcon.getScaledInstance(24, 24, Image.SCALE_SMOOTH))); + }; + icon.onChanged(resize); + resize.run(); + + materialTab.setOnSelectEvent(() -> + { + config.setActiveTab(tab); + activeTabPanel = tabContentPanel; + + tabContentPanel.update(); + return true; + }); + + tabGroup.addTab(materialTab); + if (config.activeTab() == tab) + { + tabGroup.select(materialTab); + } + } + + void update() + { + if (!active || activeTabPanel == null) + { + return; + } + + activeTabPanel.update(); + } + + @Override + public void onActivate() + { + active = true; + update(); + } + + @Override + public void onDeactivate() + { + active = false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java similarity index 54% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPlugin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index 81c4b9c495..200f133975 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Abex + * Copyright (c) 2018, Daniel Teo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,19 +23,17 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import java.awt.image.BufferedImage; -import java.time.Instant; import java.time.temporal.ChronoUnit; import javax.inject.Inject; import javax.swing.SwingUtilities; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.api.Varbits; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.GameTick; import net.runelite.api.events.UsernameChanged; @@ -42,58 +41,56 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.timetracking.farming.FarmingTracker; import net.runelite.client.task.Schedule; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.util.ImageUtil; @PluginDescriptor( - name = "Farming Tracker", - description = "Show when your farming plots would be fully grown", - tags = {"skilling", "panel", "timers"} + name = "Time Tracking", + description = "Enable the Time Tracking panel, which contains farming trackers", + tags = {"farming", "skilling", "panel"} ) @Slf4j -public class FarmingTrackerPlugin extends Plugin +public class TimeTrackingPlugin extends Plugin { @Inject private ClientToolbar clientToolbar; - @Inject - private ConfigManager configManager; - @Inject private Client client; @Inject - private FarmingWorld farmingWorld; + private FarmingTracker farmingTracker; @Inject private ItemManager itemManager; @Inject - private FarmingTrackerConfig config; + private TimeTrackingConfig config; - private FarmingTrackerPanel panel; + private TimeTrackingPanel panel; private NavigationButton navButton; - private WorldPoint lastTickLoc; + private WorldPoint lastTickLocation; @Provides - FarmingTrackerConfig provideConfig(ConfigManager configManager) + TimeTrackingConfig provideConfig(ConfigManager configManager) { - return configManager.getConfig(FarmingTrackerConfig.class); + return configManager.getConfig(TimeTrackingConfig.class); } @Override protected void startUp() throws Exception { - final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "farming.png"); + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "watch.png"); - panel = new FarmingTrackerPanel(client, itemManager, configManager, config, farmingWorld); + panel = new TimeTrackingPanel(itemManager, config, farmingTracker); navButton = NavigationButton.builder() - .tooltip("Farming Tracker") + .tooltip("Time Tracking") .icon(icon) .panel(panel) .priority(4) @@ -104,15 +101,10 @@ public class FarmingTrackerPlugin extends Plugin updatePanel(); } - @Subscribe - public void onUsernameChanged(UsernameChanged e) - { - updatePanel(); - } - @Override protected void shutDown() throws Exception { + lastTickLocation = null; clientToolbar.removeNavigation(navButton); } @@ -121,73 +113,33 @@ public class FarmingTrackerPlugin extends Plugin { if (client.getGameState() != GameState.LOGGED_IN) { - lastTickLoc = null; + lastTickLocation = null; return; } - WorldPoint loc = lastTickLoc; - lastTickLoc = client.getLocalPlayer().getWorldLocation(); - if (loc == null || loc.getRegionID() != lastTickLoc.getRegionID()) + WorldPoint loc = lastTickLocation; + lastTickLocation = client.getLocalPlayer().getWorldLocation(); + + if (loc == null || loc.getRegionID() != lastTickLocation.getRegionID()) { return; } - boolean changed = false; + boolean farmingDataChanged = farmingTracker.updateData(loc); - { - String group = FarmingTrackerConfig.KEY_NAME + "." + client.getUsername(); - String autoweed = Integer.toString(client.getVar(Varbits.AUTOWEED)); - if (!autoweed.equals(configManager.getConfiguration(group, FarmingTrackerConfig.AUTOWEED))) - { - configManager.setConfiguration(group, FarmingTrackerConfig.AUTOWEED, autoweed); - changed = true; - } - } - - FarmingRegion region = farmingWorld.getRegions().get(loc.getRegionID()); - if (region != null && region.isInBounds(loc)) - { - // Write config with new varbits - // farmingTracker...=: - String group = FarmingTrackerConfig.KEY_NAME + "." + client.getUsername() + "." + region.getRegionID(); - long unixNow = Instant.now().getEpochSecond(); - for (Varbits varbit : region.getVarbits()) - { - // Write the config value if it doesn't match what is current, or it is more than 5 minutes old - String key = Integer.toString(varbit.getId()); - String strVarbit = Integer.toString(client.getVar(varbit)); - String storedValue = configManager.getConfiguration(group, key); - if (storedValue != null) - { - String[] parts = storedValue.split(":"); - if (parts.length == 2 && parts[0].equals(strVarbit)) - { - long unixTime = 0; - try - { - unixTime = Long.parseLong(parts[1]); - } - catch (NumberFormatException e) - { - } - if (unixTime + (5 * 60) > unixNow && unixNow + 30 > unixTime) - { - continue; - } - } - } - String value = strVarbit + ":" + unixNow; - configManager.setConfiguration(group, key, value); - changed = true; - } - } - - if (changed) + if (farmingDataChanged) { updatePanel(); } } + @Subscribe + public void onUsernameChanged(UsernameChanged e) + { + farmingTracker.migrateConfiguration(); + updatePanel(); + } + @Schedule(period = 10, unit = ChronoUnit.SECONDS) public void updatePanel() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/CropState.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/CropState.java similarity index 96% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/CropState.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/CropState.java index 90bd66ff73..2d9ffced83 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/CropState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/CropState.java @@ -22,7 +22,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import java.awt.Color; import lombok.Getter; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatch.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatch.java similarity index 95% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatch.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatch.java index 7409687cd7..8c24588917 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatch.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatch.java @@ -22,7 +22,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import lombok.AccessLevel; import lombok.Getter; @@ -34,7 +34,7 @@ import net.runelite.api.Varbits; access = AccessLevel.PACKAGE ) @Getter -public class FarmingPatch +class FarmingPatch { @Setter(AccessLevel.PACKAGE) private FarmingRegion region; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatchPanel.java similarity index 98% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatchPanel.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatchPanel.java index aa3162b1ad..42bbcad621 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingPatchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingPatchPanel.java @@ -23,7 +23,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import com.google.common.base.Strings; import java.awt.BorderLayout; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingRegion.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingRegion.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingRegion.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingRegion.java index 305a10863a..c768d30c14 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingRegion.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingRegion.java @@ -22,7 +22,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import lombok.Getter; import net.runelite.api.Varbits; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java similarity index 58% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java index ab0f4b8d7b..986716ec5c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java @@ -23,15 +23,11 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import com.google.common.base.Strings; -import java.awt.BorderLayout; -import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; -import java.awt.Image; -import java.awt.image.BufferedImage; import java.time.Instant; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -39,180 +35,106 @@ import java.time.format.TextStyle; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import javax.swing.ImageIcon; +import java.util.Set; import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; import javax.swing.border.EmptyBorder; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.vars.Autoweed; import net.runelite.client.config.ConfigManager; -import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.timetracking.TabContentPanel; +import net.runelite.client.plugins.timetracking.TimeTrackingConfig; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; -import net.runelite.client.ui.PluginPanel; -import net.runelite.client.ui.components.materialtabs.MaterialTab; -import net.runelite.client.ui.components.materialtabs.MaterialTabGroup; @Slf4j -class FarmingTrackerPanel extends PluginPanel +public class FarmingTabPanel extends TabContentPanel { private final Client client; private final ItemManager itemManager; private final ConfigManager configManager; - private final FarmingTrackerConfig config; + private final TimeTrackingConfig config; + private final List patchPanels; - private boolean active; - - private List patchPanels = new ArrayList<>(); - - /* This is the panel the tabs' respective panels will be displayed on. */ - private final JPanel display = new JPanel(); - private final MaterialTabGroup tabGroup = new MaterialTabGroup(display); - - FarmingTrackerPanel( - Client client, - ItemManager itemManager, - ConfigManager configManager, - FarmingTrackerConfig config, - FarmingWorld farmingWorld - ) + FarmingTabPanel(Client client, ItemManager itemManager, ConfigManager configManager, + TimeTrackingConfig config, Set patches) { - super(false); - this.client = client; this.itemManager = itemManager; this.configManager = configManager; this.config = config; + this.patchPanels = new ArrayList<>(); - setLayout(new BorderLayout()); + setLayout(new GridBagLayout()); setBackground(ColorScheme.DARK_GRAY_COLOR); - display.setBorder(new EmptyBorder(10, 10, 8, 10)); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridx = 0; + c.gridy = 0; - tabGroup.setBorder(new EmptyBorder(10, 1, 0, 0)); + PatchImplementation lastImpl = null; - add(tabGroup, BorderLayout.NORTH); - add(display, BorderLayout.CENTER); - - farmingWorld.getTabs().forEach((tab, patches) -> + boolean first = true; + for (FarmingPatch patch : patches) { - JPanel container = new JPanel(new GridBagLayout()) + FarmingPatchPanel p = new FarmingPatchPanel(patch); + + /* Show labels to subdivide tabs into sections */ + if (patch.getImplementation() != lastImpl && !Strings.isNullOrEmpty(patch.getImplementation().getName())) { - @Override - public Dimension getPreferredSize() - { - return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height); - } - }; - container.setBackground(ColorScheme.DARK_GRAY_COLOR); + JLabel groupLabel = new JLabel(patch.getImplementation().getName()); - GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 0; - c.gridy = 0; - - PatchImplementation lastImpl = null; - - boolean first = true; - for (FarmingPatch patch : patches) - { - FarmingPatchPanel p = new FarmingPatchPanel(patch); - - /* Show labels to subdivide tabs into sections */ - if (patch.getImplementation() != lastImpl && !Strings.isNullOrEmpty(patch.getImplementation().getName())) - { - JLabel groupLabel = new JLabel(patch.getImplementation().getName()); - - if (first) - { - first = false; - groupLabel.setBorder(new EmptyBorder(4, 0, 0, 0)); - } - else - { - groupLabel.setBorder(new EmptyBorder(15, 0, 0, 0)); - } - - groupLabel.setFont(FontManager.getRunescapeSmallFont()); - - container.add(groupLabel, c); - c.gridy++; - lastImpl = patch.getImplementation(); - } - - patchPanels.add(p); - container.add(p, c); - c.gridy++; - - /* This is a weird hack to remove the top border on the first tracker of every tab */ if (first) { first = false; - p.setBorder(null); + groupLabel.setBorder(new EmptyBorder(4, 0, 0, 0)); } + else + { + groupLabel.setBorder(new EmptyBorder(15, 0, 0, 0)); + } + + groupLabel.setFont(FontManager.getRunescapeSmallFont()); + + add(groupLabel, c); + c.gridy++; + lastImpl = patch.getImplementation(); } - JPanel wrapped = new JPanel(new BorderLayout()); - wrapped.add(container, BorderLayout.NORTH); - wrapped.setBackground(ColorScheme.DARK_GRAY_COLOR); + patchPanels.add(p); + add(p, c); + c.gridy++; - JScrollPane scroller = new JScrollPane(wrapped); - scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - scroller.getVerticalScrollBar().setPreferredSize(new Dimension(16, 0)); - scroller.getVerticalScrollBar().setBorder(new EmptyBorder(0, 9, 0, 0)); - scroller.setBackground(ColorScheme.DARK_GRAY_COLOR); - - //Use a placeholder icon until the async image gets loaded - MaterialTab materialTab = new MaterialTab(new ImageIcon(), tabGroup, scroller); - materialTab.setPreferredSize(new Dimension(30, 27)); - materialTab.setName(tab.getName()); - - AsyncBufferedImage icon = itemManager.getImage(tab.getItemID()); - Runnable resize = () -> + /* This is a weird hack to remove the top border on the first tracker of every tab */ + if (first) { - BufferedImage subIcon = icon.getSubimage(0, 0, 32, 32); - materialTab.setIcon(new ImageIcon(subIcon.getScaledInstance(24, 24, Image.SCALE_SMOOTH))); - }; - icon.onChanged(resize); - resize.run(); - - materialTab.setOnSelectEvent(() -> - { - config.setPatch(tab); - return true; - }); - - tabGroup.addTab(materialTab); - if (config.patch() == tab) - { - tabGroup.select(materialTab); + first = false; + p.setBorder(null); } - }); + } + } - void update() + @Override + public void update() { - if (!active) - { - return; - } - long unixNow = Instant.now().getEpochSecond(); log.debug("Updating panel with username {}", client.getUsername()); - boolean autoweed = false; + + boolean autoweed; { - String group = FarmingTrackerConfig.KEY_NAME + "." + client.getUsername(); + String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername(); autoweed = Integer.toString(Autoweed.ON.ordinal()) - .equals(configManager.getConfiguration(group, FarmingTrackerConfig.AUTOWEED)); + .equals(configManager.getConfiguration(group, TimeTrackingConfig.AUTOWEED)); } + for (FarmingPatchPanel panel : patchPanels) { FarmingPatch patch = panel.getPatch(); - String group = FarmingTrackerConfig.KEY_NAME + "." + client.getUsername() + "." + patch.getRegion().getRegionID(); + String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername() + "." + patch.getRegion().getRegionID(); String key = Integer.toString(patch.getVarbit().getId()); String storedValue = configManager.getConfiguration(group, key); long unixTime = 0; @@ -258,19 +180,9 @@ class FarmingTrackerPanel extends PluginPanel } int stage = state.getStage(); - int stages = state.getCropState() == CropState.HARVESTABLE ? - state.getProduce().getHarvestStages() : - state.getProduce().getStages(); - int tickrate = 0; - switch (state.getCropState()) - { - case HARVESTABLE: - tickrate = state.getProduce().getRegrowTickrate() * 60; - break; - case GROWING: - tickrate = state.getProduce().getTickrate() * 60; - break; - } + int stages = state.getStages(); + int tickrate = state.getTickRate() * 60; + if (autoweed && state.getProduce() == Produce.WEEDS) { stage = 0; @@ -374,17 +286,4 @@ class FarmingTrackerPanel extends PluginPanel } } } - - @Override - public void onActivate() - { - active = true; - update(); - } - - @Override - public void onDeactivate() - { - active = false; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java new file mode 100644 index 0000000000..ba2ce8b0d3 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2018 Abex + * 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.timetracking.farming; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.time.Instant; +import net.runelite.api.Client; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.game.ItemManager; +import net.runelite.client.plugins.timetracking.Tab; +import net.runelite.client.plugins.timetracking.TimeTrackingConfig; + +@Singleton +public class FarmingTracker +{ + @Deprecated + private static final String OLD_KEY_NAME = "farmingTracker"; + + private final Client client; + private final ItemManager itemManager; + private final ConfigManager configManager; + private final TimeTrackingConfig config; + private final FarmingWorld farmingWorld; + + @Inject + private FarmingTracker(Client client, ItemManager itemManager, ConfigManager configManager, + TimeTrackingConfig config, FarmingWorld farmingWorld) + { + this.client = client; + this.itemManager = itemManager; + this.configManager = configManager; + this.config = config; + this.farmingWorld = farmingWorld; + } + + + public FarmingTabPanel createTabPanel(Tab tab) + { + return new FarmingTabPanel(client, itemManager, configManager, config, farmingWorld.getTabs().get(tab)); + } + + /** + * Updates tracker data for the current region. Returns true if any data was changed. + */ + public boolean updateData(WorldPoint location) + { + boolean changed = false; + + { + String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername(); + String autoweed = Integer.toString(client.getVar(Varbits.AUTOWEED)); + if (!autoweed.equals(configManager.getConfiguration(group, TimeTrackingConfig.AUTOWEED))) + { + configManager.setConfiguration(group, TimeTrackingConfig.AUTOWEED, autoweed); + changed = true; + } + } + + FarmingRegion region = farmingWorld.getRegions().get(location.getRegionID()); + if (region != null && region.isInBounds(location)) + { + // Write config with new varbits + // timetracking...=: + String group = TimeTrackingConfig.KEY_NAME + "." + client.getUsername() + "." + region.getRegionID(); + long unixNow = Instant.now().getEpochSecond(); + for (Varbits varbit : region.getVarbits()) + { + // Write the config value if it doesn't match what is current, or it is more than 5 minutes old + String key = Integer.toString(varbit.getId()); + String strVarbit = Integer.toString(client.getVar(varbit)); + String storedValue = configManager.getConfiguration(group, key); + + if (storedValue != null) + { + String[] parts = storedValue.split(":"); + if (parts.length == 2 && parts[0].equals(strVarbit)) + { + long unixTime = 0; + try + { + unixTime = Long.parseLong(parts[1]); + } + catch (NumberFormatException e) + { + // ignored + } + if (unixTime + (5 * 60) > unixNow && unixNow + 30 > unixTime) + { + continue; + } + } + } + + String value = strVarbit + ":" + unixNow; + configManager.setConfiguration(group, key, value); + changed = true; + } + } + + return changed; + } + + /** + * Migrates configuration data from {@code "farmingTracker"} key to {@code "timetracking"} key. + * This method should be removed after a reasonable amount of time. + */ + @Deprecated + public void migrateConfiguration() + { + String username = client.getUsername(); + + // migrate autoweed config + { + String oldGroup = OLD_KEY_NAME + "." + username; + String newGroup = TimeTrackingConfig.KEY_NAME + "." + username; + String storedValue = configManager.getConfiguration(oldGroup, TimeTrackingConfig.AUTOWEED); + + if (storedValue != null) + { + configManager.setConfiguration(newGroup, TimeTrackingConfig.AUTOWEED, storedValue); + configManager.unsetConfiguration(oldGroup, TimeTrackingConfig.AUTOWEED); + } + } + + // migrate all saved data in all regions + for (FarmingRegion region : farmingWorld.getRegions().values()) + { + String oldGroup = OLD_KEY_NAME + "." + username + "." + region.getRegionID(); + String newGroup = TimeTrackingConfig.KEY_NAME + "." + username + "." + region.getRegionID(); + + for (Varbits varbit : region.getVarbits()) + { + String key = Integer.toString(varbit.getId()); + String storedValue = configManager.getConfiguration(oldGroup, key); + + if (storedValue != null) + { + configManager.setConfiguration(newGroup, key, storedValue); + configManager.unsetConfiguration(oldGroup, key); + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingWorld.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingWorld.java similarity index 98% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingWorld.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingWorld.java index d5079c1696..7af327ec69 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingWorld.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingWorld.java @@ -23,7 +23,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import com.google.inject.Singleton; import java.util.Collections; @@ -36,9 +36,10 @@ import java.util.TreeSet; import lombok.Getter; import net.runelite.api.Varbits; import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.timetracking.Tab; @Singleton -public class FarmingWorld +class FarmingWorld { @Getter private Map regions = new HashMap<>(); @@ -51,7 +52,7 @@ public class FarmingWorld .thenComparing((FarmingPatch p) -> p.getRegion().getName()) .thenComparing(FarmingPatch::getName); - public FarmingWorld() + FarmingWorld() { // Some of these patches get updated in multiple regions. // It may be worth it to add a specialization for these patches diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchImplementation.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchImplementation.java similarity index 99% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchImplementation.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchImplementation.java index 89f4c40274..0a4000ac8e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchImplementation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchImplementation.java @@ -22,10 +22,11 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import lombok.Getter; import lombok.RequiredArgsConstructor; +import net.runelite.client.plugins.timetracking.Tab; @RequiredArgsConstructor @Getter @@ -733,7 +734,7 @@ public enum PatchImplementation return null; } }, - FLOWER(Tab.HERB, "Flowers") + FLOWER(Tab.FLOWER, "") { @Override PatchState forVarbitValue(int value) @@ -1205,7 +1206,7 @@ public enum PatchImplementation return null; } }, - FRUIT_TREE(Tab.FRUIT_TREE, "Fruit trees") + FRUIT_TREE(Tab.FRUIT_TREE, "") { @Override PatchState forVarbitValue(int value) @@ -1454,7 +1455,7 @@ public enum PatchImplementation return null; } }, - HOPS(Tab.SPECIAL, "Hops") + HOPS(Tab.HOPS, "") { @Override PatchState forVarbitValue(int value) @@ -2267,7 +2268,7 @@ public enum PatchImplementation return null; } }, - GRAPES(Tab.BUSH, "Grapes") + GRAPES(Tab.GRAPE, "") { @Override PatchState forVarbitValue(int value) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchState.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchState.java similarity index 79% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchState.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchState.java index c27e13d6c6..2857882b3f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/PatchState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/PatchState.java @@ -22,14 +22,32 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import lombok.Value; @Value -public class PatchState +class PatchState { private final Produce produce; private final CropState cropState; private final int stage; + + int getStages() + { + return cropState == CropState.HARVESTABLE ? produce.getHarvestStages() : produce.getStages(); + } + + int getTickRate() + { + switch (cropState) + { + case HARVESTABLE: + return produce.getRegrowTickrate(); + case GROWING: + return produce.getTickrate(); + default: + return 0; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Produce.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Produce.java rename to runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java index 867105fee7..96d4c6e189 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/Produce.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/Produce.java @@ -23,7 +23,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -127,7 +127,7 @@ public enum Produce */ private final int tickrate; /** - * How many states this crop has during groth. Typically tickcount+1 + * How many states this crop has during growth. Typically tickcount+1 */ private final int stages; /** diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/farmingtracker/farming.png b/runelite-client/src/main/resources/net/runelite/client/plugins/farmingtracker/farming.png deleted file mode 100644 index 5b1c5dff73..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/farmingtracker/farming.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/timetracking/watch.png b/runelite-client/src/main/resources/net/runelite/client/plugins/timetracking/watch.png new file mode 100644 index 0000000000..e418efc732 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/timetracking/watch.png differ diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/FarmingWorldTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/FarmingWorldTest.java similarity index 96% rename from runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/FarmingWorldTest.java rename to runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/FarmingWorldTest.java index 918a24a7f5..05a45ffe52 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/FarmingWorldTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/FarmingWorldTest.java @@ -21,7 +21,7 @@ * 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.farmingtracker; + */package net.runelite.client.plugins.timetracking.farming; import org.junit.Test; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/PatchImplementationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/PatchImplementationTest.java similarity index 98% rename from runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/PatchImplementationTest.java rename to runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/PatchImplementationTest.java index 8023958af8..ef6f73b94f 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/farmingtracker/PatchImplementationTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/timetracking/farming/PatchImplementationTest.java @@ -22,7 +22,7 @@ * (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.farmingtracker; +package net.runelite.client.plugins.timetracking.farming; import java.util.HashMap; import java.util.Map;