From df7cf901e655db26b31fc89689da974a8172065a Mon Sep 17 00:00:00 2001 From: l2- Date: Mon, 22 Oct 2018 17:20:51 +0200 Subject: [PATCH 01/63] correct font positioning to work with any font --- .../client/plugins/devtools/DevToolsOverlay.java | 4 ++-- .../plugins/grounditems/GroundItemsOverlay.java | 4 ++-- .../plugins/itemcharges/ItemChargeOverlay.java | 2 +- .../client/plugins/runecraft/BindNeckOverlay.java | 2 +- .../plugins/runepouch/RunepouchOverlay.java | 15 ++++++++++++--- .../ui/overlay/components/InfoBoxComponent.java | 4 ++-- .../ui/overlay/components/LineComponent.java | 8 +++++--- .../overlay/components/ProgressBarComponent.java | 2 +- .../ui/overlay/components/TitleComponent.java | 2 +- .../ui/overlay/components/TooltipComponent.java | 6 +++--- .../ui/overlay/worldmap/WorldMapOverlay.java | 2 +- 11 files changed, 31 insertions(+), 20 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index fd96de011c..977f3dfb59 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -373,7 +373,7 @@ class DevToolsOverlay extends Overlay Rectangle2D textBounds = fm.getStringBounds(idText, graphics); int textX = (int) (slotBounds.getX() + (slotBounds.getWidth() / 2) - (textBounds.getWidth() / 2)); - int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (textBounds.getHeight() / 2)); + int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (fm.getAscent() / 2)); graphics.setColor(new Color(255, 255, 255, 65)); graphics.fill(slotBounds); @@ -483,7 +483,7 @@ class DevToolsOverlay extends Overlay Rectangle2D textBounds = fm.getStringBounds(text, graphics); int textX = (int) (bounds.getX() + (bounds.getWidth() / 2) - (textBounds.getWidth() / 2)); - int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (textBounds.getHeight() / 2)); + int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (fm.getMaxAscent() / 2)); graphics.setColor(Color.BLACK); graphics.drawString(text, textX + 1, textY + 1); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 1406bb1747..34181cef31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -284,14 +284,14 @@ public class GroundItemsOverlay extends Overlay // Item bounds int x = textX - 2; - int y = textY - stringHeight - 2; + int y = textY - stringHeight - 2 + fm.getMaxDescent(); int width = stringWidth + 4; int height = stringHeight + 4; final Rectangle itemBounds = new Rectangle(x, y, width, height); // Hidden box x += width + 2; - y = textY - (RECTANGLE_SIZE + stringHeight) / 2; + y = textY - (fm.getMaxAscent() + RECTANGLE_SIZE) / 2; width = height = RECTANGLE_SIZE; final Rectangle itemHiddenBox = new Rectangle(x, y, width, height); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index 27bb35b21d..fe178bd3b9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -109,7 +109,7 @@ class ItemChargeOverlay extends Overlay final Rectangle bounds = item.getCanvasBounds(); final TextComponent textComponent = new TextComponent(); - textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); + textComponent.setPosition(new Point(bounds.x, bounds.y + 1 + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent())); textComponent.setText(charges < 0 ? "?" : String.valueOf(charges)); textComponent.setColor(itemChargePlugin.getColor(charges)); textComponent.render(graphics); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java index 6e8dbcd24f..e011e4e2eb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/BindNeckOverlay.java @@ -79,7 +79,7 @@ public class BindNeckOverlay extends Overlay final String text = bindingCharges <= 0 ? "?" : bindingCharges + ""; final TextComponent textComponent = new TextComponent(); - textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); + textComponent.setPosition(new Point(bounds.x, bounds.y + 1 + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent())); textComponent.setText(text); textComponent.setColor(color); textComponent.render(graphics); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java index 9eac070c94..0e2bfc1971 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/RunepouchOverlay.java @@ -104,6 +104,10 @@ public class RunepouchOverlay extends Overlay StringBuilder tooltipBuilder = new StringBuilder(); + // location.getY() + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent() + // this will draw the character exactly on the border + int yLocation = location.getY() + 1 + + graphics.getFontMetrics().getMaxAscent() - graphics.getFontMetrics().getMaxDescent(); for (int i = 0; i < AMOUNT_VARBITS.length; i++) { Varbits amountVarbit = AMOUNT_VARBITS[i]; @@ -133,13 +137,18 @@ public class RunepouchOverlay extends Overlay continue; } + // the reason this is not split up in maxascent and maxdescent to equal the height of the text like it should + // be is because numbers (afaik) dont use font descent so a 1 pixel seperator should be good and give + // consistent results across fonts + int yOffset = (1 + (graphics.getFontMetrics().getMaxAscent()) * i); + graphics.setColor(Color.black); graphics.drawString("" + formatNumber(amount), location.getX() + (config.showIcons() ? 13 : 6), - location.getY() + 14 + (graphics.getFontMetrics().getHeight() - 1) * i); + yLocation + yOffset); graphics.setColor(config.fontColor()); graphics.drawString("" + formatNumber(amount), location.getX() + (config.showIcons() ? 12 : 5), - location.getY() + 13 + (graphics.getFontMetrics().getHeight() - 1) * i); + yLocation + yOffset); if (!config.showIcons()) { @@ -150,7 +159,7 @@ public class RunepouchOverlay extends Overlay if (image != null) { OverlayUtil.renderImageLocation(graphics, - new Point(location.getX(), location.getY() + graphics.getFontMetrics().getHeight() * i), + new Point(location.getX(), location.getY() + (1 + graphics.getFontMetrics().getMaxAscent()) * i), image); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java index d8f7841099..8cd54cd926 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java @@ -39,7 +39,7 @@ import net.runelite.client.ui.FontManager; @Setter public class InfoBoxComponent implements LayoutableRenderableEntity { - private static final int SEPARATOR = 3; + private static final int SEPARATOR = 2; private static final int DEFAULT_SIZE = 32; @Getter @@ -92,7 +92,7 @@ public class InfoBoxComponent implements LayoutableRenderableEntity final TextComponent textComponent = new TextComponent(); textComponent.setColor(color); textComponent.setText(text); - textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - SEPARATOR)); + textComponent.setPosition(new Point(baseX + ((size - metrics.stringWidth(text)) / 2), baseY + size - metrics.getMaxDescent() - SEPARATOR)); textComponent.render(graphics); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java index f6c2f5e77c..03b8c0a71d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java @@ -68,7 +68,7 @@ public class LineComponent implements LayoutableRenderableEntity final FontMetrics metrics = graphics.getFontMetrics(); final int baseX = preferredLocation.x; - final int baseY = preferredLocation.y + metrics.getHeight(); + final int baseY = preferredLocation.y; int x = baseX; int y = baseY; final int leftFullWidth = getLineWidth(left, metrics); @@ -92,6 +92,7 @@ public class LineComponent implements LayoutableRenderableEntity for (int i = 0; i < lineCount; i++) { + y += metrics.getMaxAscent(); String leftText = ""; String rightText = ""; @@ -116,7 +117,7 @@ public class LineComponent implements LayoutableRenderableEntity rightLineComponent.setText(rightText); rightLineComponent.setColor(rightColor); rightLineComponent.render(graphics); - y += metrics.getHeight(); + y += metrics.getMaxDescent(); } final Dimension dimension = new Dimension(preferredSize.width, y - baseY); @@ -124,6 +125,7 @@ public class LineComponent implements LayoutableRenderableEntity bounds.setSize(dimension); return dimension; } + y += metrics.getMaxAscent(); final TextComponent leftLineComponent = new TextComponent(); leftLineComponent.setPosition(new Point(x, y)); @@ -136,7 +138,7 @@ public class LineComponent implements LayoutableRenderableEntity rightLineComponent.setText(right); rightLineComponent.setColor(rightColor); rightLineComponent.render(graphics); - y += metrics.getHeight(); + y += metrics.getMaxDescent(); final Dimension dimension = new Dimension(preferredSize.width, y - baseY); bounds.setLocation(preferredLocation); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java index ba4634deec..c81d59da2b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java @@ -84,7 +84,7 @@ public class ProgressBarComponent implements LayoutableRenderableEntity final int width = preferredSize.width; final int height = Math.max(preferredSize.height, 16); final int progressTextX = barX + (width - metrics.stringWidth(textToWrite)) / 2; - final int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getHeight(); + final int progressTextY = barY + ((height - metrics.getHeight()) / 2) + metrics.getMaxAscent(); final int progressFill = (int) (width * Math.min(1, pc)); // Draw bar diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java index fa4c9bc3bb..9c9793be66 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TitleComponent.java @@ -64,7 +64,7 @@ public class TitleComponent implements LayoutableRenderableEntity titleComponent.setColor(color); titleComponent.setPosition(new Point( baseX + ((preferredSize.width - metrics.stringWidth(text)) / 2), - baseY + metrics.getHeight())); + baseY + metrics.getMaxAscent())); final Dimension rendered = titleComponent.render(graphics); final Dimension dimension = new Dimension(preferredSize.width, rendered.height); bounds.setLocation(preferredLocation); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java index c7c5381b86..8743c31831 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TooltipComponent.java @@ -104,7 +104,7 @@ public class TooltipComponent implements RenderableEntity textComponent.setColor(nextColor); String text = line.substring(begin, j); textComponent.setText(text); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); textComponent.render(graphics); lineX += metrics.stringWidth(text); @@ -141,7 +141,7 @@ public class TooltipComponent implements RenderableEntity textComponent.setColor(nextColor); String text = line.substring(begin, j + 1); textComponent.setText(text); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); textComponent.render(graphics); lineX += metrics.stringWidth(text); @@ -155,7 +155,7 @@ public class TooltipComponent implements RenderableEntity final TextComponent textComponent = new TextComponent(); textComponent.setColor(nextColor); textComponent.setText(line.substring(begin, line.length())); - textComponent.setPosition(new Point(lineX, textY + (i + 1) * textHeight - textDescent)); + textComponent.setPosition(new Point(lineX, textY + (i + 1) * metrics.getMaxAscent() + i * metrics.getMaxDescent())); textComponent.render(graphics); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java index 6b5b7474a6..8d81efb61a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/worldmap/WorldMapOverlay.java @@ -277,7 +277,7 @@ public class WorldMapOverlay extends Overlay graphics.setColor(JagexColors.TOOLTIP_BORDER); graphics.drawRect((int) tooltipRect.getX(), (int) tooltipRect.getY(), (int) tooltipRect.getWidth(), (int) tooltipRect.getHeight()); graphics.setColor(JagexColors.TOOLTIP_TEXT); - graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + height); + graphics.drawString(tooltip, drawPoint.getX(), drawPoint.getY() + fm.getMaxAscent()); } private Point clipToRectangle(Point drawPoint, Rectangle mapDisplayRectangle) From e0c8c0ac792f879da92157a768675f3ae8e88831 Mon Sep 17 00:00:00 2001 From: l2- Date: Mon, 22 Oct 2018 17:48:08 +0200 Subject: [PATCH 02/63] adjust panels and components to work with any font --- .../plugins/timetracking/clocks/ClockTabPanel.java | 8 ++++++++ .../runelite/client/ui/components/ProgressBar.java | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java index 79578a3b79..fcc460fdf8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java @@ -40,6 +40,7 @@ import net.runelite.client.plugins.timetracking.TimeTrackingPlugin; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.IconButton; import net.runelite.client.ui.components.shadowlabel.JShadowedLabel; import net.runelite.client.util.ImageUtil; @@ -97,6 +98,13 @@ public class ClockTabPanel extends TabContentPanel rebuild(); } + // The max panel width is 225 but the + sign gets cut off at 225 so we set it at 223 + @Override + public Dimension getPreferredSize() + { + return new Dimension(PluginPanel.PANEL_WIDTH - 2, super.getPreferredSize().height); + } + /** * Clears and recreates the components of this panel. * This should be done whenever a clock is added or removed. diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java index a90d53eb87..bc15d21a71 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java @@ -66,18 +66,26 @@ public class ProgressBar extends DimmableJPanel setPreferredSize(new Dimension(100, 16)); + int topIndent = 0; + if (getFont().equals(FontManager.getRunescapeSmallFont()) + || getFont().equals(FontManager.getRunescapeFont()) + || getFont().equals(FontManager.getRunescapeBoldFont())) + { + topIndent = 2; + } + leftLabel.setFont(FontManager.getRunescapeSmallFont()); leftLabel.setForeground(Color.WHITE); - leftLabel.setBorder(new EmptyBorder(2, 5, 0, 0)); + leftLabel.setBorder(new EmptyBorder(topIndent, 5, 0, 0)); rightLabel.setFont(FontManager.getRunescapeSmallFont()); rightLabel.setForeground(Color.WHITE); - rightLabel.setBorder(new EmptyBorder(2, 0, 0, 5)); + rightLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 5)); centerLabel.setFont(FontManager.getRunescapeSmallFont()); centerLabel.setForeground(Color.WHITE); centerLabel.setHorizontalAlignment(SwingConstants.CENTER); - centerLabel.setBorder(new EmptyBorder(2, 0, 0, 0)); + centerLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 0)); // Adds components to be automatically redrawn when paintComponents is called add(leftLabel, BorderLayout.WEST); From 4b61804a4553ffa8d7ee9b984abb2e1be665b21c Mon Sep 17 00:00:00 2001 From: l2- Date: Mon, 22 Oct 2018 17:51:34 +0200 Subject: [PATCH 03/63] make sure rl uses OS font rendering hints --- .../components/shadowlabel/JShadowedLabel.java | 17 +++++++++++++++++ .../client/ui/overlay/OverlayRenderer.java | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/shadowlabel/JShadowedLabel.java b/runelite-client/src/main/java/net/runelite/client/ui/components/shadowlabel/JShadowedLabel.java index 35ccf12374..79b7200f7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/shadowlabel/JShadowedLabel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/shadowlabel/JShadowedLabel.java @@ -25,7 +25,11 @@ package net.runelite.client.ui.components.shadowlabel; import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Toolkit; +import java.util.Map; import javax.swing.JLabel; import lombok.Getter; @@ -61,4 +65,17 @@ public class JShadowedLabel extends JLabel revalidate(); repaint(); } + + @Override + public void paint(Graphics g) + { + // Set font rendering properties like the OS's font rendering + Toolkit tk = Toolkit.getDefaultToolkit(); + Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints")); + if (desktopHints != null) + { + ((Graphics2D)g).addRenderingHints(desktopHints); + } + super.paint(g); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index a9f2e9f017..eb817354b7 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -31,9 +31,11 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.List; +import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import javax.swing.SwingUtilities; @@ -165,6 +167,14 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener return; } + // Set font rendering properties like the OS's font rendering + Toolkit tk = Toolkit.getDefaultToolkit(); + Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints")); + if (desktopHints != null) + { + graphics.addRenderingHints(desktopHints); + } + if (shouldInvalidateBounds()) { snapCorners = buildSnapCorners(); From 15d513b3c690046f8de4908934ed2ec601c64275 Mon Sep 17 00:00:00 2001 From: l2- Date: Mon, 22 Oct 2018 21:09:29 +0200 Subject: [PATCH 04/63] add support to select and use any font installed on the user's system --- .../runelite/client/config/ConfigManager.java | 10 ++ .../net/runelite/client/config/FontType.java | 10 +- .../client/config/RuneLiteConfig.java | 13 ++ .../client/plugins/config/ConfigPanel.java | 33 +++++ .../java/net/runelite/client/ui/ClientUI.java | 2 +- .../net/runelite/client/ui/FontManager.java | 131 +++++++++++++++--- .../client/ui/overlay/OverlayRenderer.java | 7 +- 7 files changed, 175 insertions(+), 31 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 2cde4900ad..ba65241334 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -29,6 +29,7 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableMap; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.io.File; @@ -61,6 +62,7 @@ import net.runelite.client.RuneLite; import net.runelite.client.account.AccountSession; import net.runelite.client.eventbus.EventBus; import net.runelite.client.util.ColorUtil; +import net.runelite.client.ui.FontManager; import net.runelite.http.api.config.ConfigClient; import net.runelite.http.api.config.ConfigEntry; import net.runelite.http.api.config.Configuration; @@ -512,6 +514,10 @@ public class ConfigManager { return Enum.valueOf((Class) type, str); } + if (type == Font.class) + { + return FontManager.getFontOrDefault(FontManager.lookupFont(str)); + } if (type == Instant.class) { return Instant.parse(str); @@ -540,6 +546,10 @@ public class ConfigManager { return ((Enum) object).name(); } + if (object instanceof Font) + { + return FontManager.getFontName((Font)object); + } if (object instanceof Dimension) { Dimension d = (Dimension) object; diff --git a/runelite-client/src/main/java/net/runelite/client/config/FontType.java b/runelite-client/src/main/java/net/runelite/client/config/FontType.java index 8ed57bd302..31809d287c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/FontType.java +++ b/runelite-client/src/main/java/net/runelite/client/config/FontType.java @@ -26,20 +26,16 @@ package net.runelite.client.config; import lombok.RequiredArgsConstructor; import lombok.Getter; -import net.runelite.client.ui.FontManager; - -import java.awt.Font; @Getter @RequiredArgsConstructor public enum FontType { - REGULAR("Regular", FontManager.getRunescapeFont()), - BOLD("Bold", FontManager.getRunescapeBoldFont()), - SMALL("Small", FontManager.getRunescapeSmallFont()); + REGULAR("Regular"), + BOLD("Bold"), + SMALL("Small"); private final String name; - private final Font font; @Override public String toString() diff --git a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java index 546f7e77bc..5566974afb 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java @@ -25,7 +25,9 @@ package net.runelite.client.config; import java.awt.Dimension; +import java.awt.Font; import net.runelite.api.Constants; +import net.runelite.client.ui.FontManager; @ConfigGroup("runelite") public interface RuneLiteConfig extends Config @@ -196,6 +198,17 @@ public interface RuneLiteConfig extends Config return false; } + @ConfigItem( + keyName = "clientFont", + name = "Font", + description = "Configure what font is used for the client and runelite added overlays", + position = 29 + ) + default Font clientFont() + { + return FontManager.getRunescapeFont(); + } + @ConfigItem( keyName = "fontType", name = "Dynamic Overlay Font", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index b71d5e8b0e..9edbf71bf3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -30,6 +30,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.Font; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; @@ -84,6 +85,7 @@ import net.runelite.client.plugins.PluginInstantiationException; import net.runelite.client.plugins.PluginManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.DynamicGridLayout; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.ComboBoxListRenderer; import net.runelite.client.ui.components.IconButton; @@ -529,6 +531,37 @@ public class ConfigPanel extends PluginPanel item.add(button, BorderLayout.EAST); } + if (cid.getType() == Font.class) + { + JComboBox box = new JComboBox(FontManager.getAvailableFontNames()); + box.setPreferredSize(new Dimension(150, 25)); + box.setRenderer(new ComboBoxListRenderer()); + box.setForeground(Color.WHITE); + box.setFocusable(false); + String currentlyConfigured = configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()); + if (FontManager.lookupFont(currentlyConfigured) != null) + { + box.setSelectedItem(currentlyConfigured); + box.setToolTipText(currentlyConfigured); + } + else + { + log.debug("Selected font wasn't found on this system, resetting font back to runescape small"); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), FontManager.getRunescapeSmallFont()); + } + box.addItemListener(e -> + { + if (e.getStateChange() == ItemEvent.SELECTED && box.getSelectedItem() != null) + { + final Font selected = FontManager.lookupFont(box.getSelectedItem().toString()); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), selected); + box.setToolTipText(box.getSelectedItem().toString()); + } + }); + item.add(box, BorderLayout.EAST); + } + + mainPanel.add(item); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 59ce146601..ced93fa930 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -302,7 +302,7 @@ public class ClientUI SwingUtil.setTheme(new SubstanceRuneLiteLookAndFeel()); // Use custom UI font - SwingUtil.setFont(FontManager.getRunescapeFont()); + SwingUtil.setFont(FontManager.getFontOrDefault(config.clientFont())); // Create main window frame = new ContainableFrame(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java index b6fdac5172..3addfb26f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java @@ -24,11 +24,16 @@ */ package net.runelite.client.ui; -import javax.swing.text.StyleContext; +import com.google.common.collect.ImmutableBiMap; +import java.awt.Canvas; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedHashMap; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.IOException; +import net.runelite.client.config.FontType; public class FontManager { @@ -36,37 +41,45 @@ public class FontManager private static final Font runescapeSmallFont; private static final Font runescapeBoldFont; + private static final ImmutableBiMap fontMap; + static { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { - Font font = Font.createFont(Font.TRUETYPE_FONT, + runescapeFont = Font.createFont(Font.TRUETYPE_FONT, FontManager.class.getResourceAsStream("runescape.ttf")) .deriveFont(Font.PLAIN, 16); - ge.registerFont(font); - runescapeFont = StyleContext.getDefaultStyleContext() - .getFont(font.getName(), Font.PLAIN, 16); - ge.registerFont(runescapeFont); - - Font smallFont = Font.createFont(Font.TRUETYPE_FONT, + runescapeSmallFont = Font.createFont(Font.TRUETYPE_FONT, FontManager.class.getResourceAsStream("runescape_small.ttf")) .deriveFont(Font.PLAIN, 16); - ge.registerFont(smallFont); - runescapeSmallFont = StyleContext.getDefaultStyleContext() - .getFont(smallFont.getName(), Font.PLAIN, 16); + runescapeBoldFont = Font.createFont(Font.TRUETYPE_FONT, + FontManager.class.getResourceAsStream("runescape_bold.ttf")) + .deriveFont(Font.PLAIN, 16); + + final LinkedHashMap _fontMap = new LinkedHashMap<>(); + _fontMap.put("Runescape small", runescapeSmallFont); + _fontMap.put("Runescape default", runescapeFont); + _fontMap.put("Runescape bold", runescapeBoldFont); + + // Get all available fonts on the system + Font[] availableFonts = ge.getAllFonts(); + // build bidirectional map + Arrays.stream(availableFonts).sorted(Comparator.comparing(Font::getFontName)).forEach(f -> + { + if (!_fontMap.containsKey(f.getFontName())) + { + _fontMap.put(f.getFontName(), f); + } + }); + fontMap = ImmutableBiMap.copyOf(_fontMap); + + ge.registerFont(runescapeFont); ge.registerFont(runescapeSmallFont); - - Font boldFont = Font.createFont(Font.TRUETYPE_FONT, - FontManager.class.getResourceAsStream("runescape_bold.ttf")) - .deriveFont(Font.PLAIN, 16); - ge.registerFont(boldFont); - - runescapeBoldFont = StyleContext.getDefaultStyleContext() - .getFont(boldFont.getName(), Font.PLAIN, 16); ge.registerFont(runescapeBoldFont); } catch (FontFormatException ex) @@ -79,6 +92,25 @@ public class FontManager } } + public static Font getFontOffCorrectSize(Font f) + { + // Size of the font is already set + if (f.getSize2D() > 1) + { + return f; + } + + // Dummy canvas for font metrics + Canvas c = new Canvas(); + + f = f.deriveFont(12f); + if (c.getFontMetrics(f).getMaxAscent() > 11) + { + f = f.deriveFont(11f); + } + return f; + } + public static Font getRunescapeFont() { return runescapeFont; @@ -93,4 +125,63 @@ public class FontManager { return runescapeBoldFont; } -} + + private static boolean isRunescapeFont(Font f) + { + return f.equals(runescapeFont) || f.equals(runescapeSmallFont) || f.equals(runescapeBoldFont); + } + + public static Font getFontFromType(Font f, FontType type) + { + switch (type) + { + case SMALL: + if (isRunescapeFont(f)) + { + return runescapeSmallFont; + } + return getFontOrDefault(f); + case BOLD: + if (isRunescapeFont(f)) + { + return runescapeBoldFont; + } + return getFontOrDefault(f).deriveFont(Font.BOLD, 14.0f); + default: //in this case regular + if (isRunescapeFont(f)) + { + return runescapeFont; + } + return getFontOrDefault(f).deriveFont(14.0f); + } + } + + public static Font lookupFont(String fontName) + { + return fontMap.get(fontName); + } + + public static String getFontName(Font font) + { + return fontMap.inverse().get(font); + } + + public static String[] getAvailableFontNames() + { + return fontMap.keySet().toArray(new String[fontMap.keySet().size()]); + } + + public static boolean isAvailable(Font font) + { + return fontMap.containsKey(font.getFontName()); + } + + public static Font getFontOrDefault(Font font) + { + if (font == null || !fontMap.containsKey(font.getFontName())) + { + return getRunescapeFont(); + } + return getFontOffCorrectSize(font); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java index eb817354b7..06405dea83 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java @@ -56,6 +56,7 @@ import net.runelite.client.input.MouseAdapter; import net.runelite.client.input.MouseManager; import net.runelite.client.ui.JagexColors; import net.runelite.client.util.ColorUtil; +import net.runelite.client.ui.FontManager; @Singleton public class OverlayRenderer extends MouseAdapter implements KeyListener @@ -456,15 +457,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener // Set font based on configuration if (position == OverlayPosition.DYNAMIC || position == OverlayPosition.DETACHED) { - subGraphics.setFont(runeLiteConfig.fontType().getFont()); + subGraphics.setFont(FontManager.getFontFromType(runeLiteConfig.clientFont(), runeLiteConfig.fontType())); } else if (position == OverlayPosition.TOOLTIP) { - subGraphics.setFont(runeLiteConfig.tooltipFontType().getFont()); + subGraphics.setFont(FontManager.getFontFromType(runeLiteConfig.clientFont(), runeLiteConfig.tooltipFontType())); } else { - subGraphics.setFont(runeLiteConfig.interfaceFontType().getFont()); + subGraphics.setFont(FontManager.getFontFromType(runeLiteConfig.clientFont(), runeLiteConfig.interfaceFontType())); } subGraphics.translate(point.x, point.y); From 1f1478a9b22356c730770efec8fe877f47128eab Mon Sep 17 00:00:00 2001 From: l2- Date: Mon, 22 Oct 2018 21:49:22 +0200 Subject: [PATCH 05/63] convert items which would override to small font to override to small version of selected font --- .../client/plugins/devtools/DevToolsOverlay.java | 3 --- .../client/plugins/devtools/VarInspector.java | 2 +- .../runelite/client/plugins/feed/FeedPanel.java | 8 ++++---- .../grandexchange/GrandExchangeOfferSlot.java | 8 ++++---- .../client/plugins/hiscore/HiscorePanel.java | 2 +- .../runelite/client/plugins/info/InfoPanel.java | 8 ++++---- .../client/plugins/kourendlibrary/BookPanel.java | 2 +- .../plugins/loottracker/LootTrackerBox.java | 6 +++--- .../plugins/loottracker/LootTrackerPanel.java | 4 ++-- .../client/plugins/mta/MTAInventoryOverlay.java | 2 +- .../client/plugins/mta/MTASceneOverlay.java | 2 +- .../ui/ScreenMarkerCreationPanel.java | 2 +- .../screenmarkers/ui/ScreenMarkerPanel.java | 6 +++--- .../plugins/skillcalculator/SkillCalculator.java | 2 +- .../plugins/skillcalculator/UIActionSlot.java | 2 +- .../skillcalculator/UICalculatorInputArea.java | 2 +- .../skillcalculator/UICombinedActionSlot.java | 2 +- .../client/plugins/slayer/SlayerOverlay.java | 2 +- .../plugins/timetracking/OverviewItemPanel.java | 4 ++-- .../plugins/timetracking/TimeablePanel.java | 4 ++-- .../timetracking/clocks/ClockTabPanel.java | 4 ++-- .../timetracking/clocks/StopwatchPanel.java | 2 +- .../timetracking/farming/FarmingTabPanel.java | 2 +- .../plugins/worldhopper/WorldTableHeader.java | 2 +- .../client/plugins/worldhopper/WorldTableRow.java | 4 ++-- .../client/plugins/xptracker/XpInfoBox.java | 8 ++++---- .../client/plugins/xptracker/XpPanel.java | 4 ++-- .../java/net/runelite/client/ui/FontManager.java | 15 ++++++++++----- .../client/ui/components/PluginErrorPanel.java | 2 +- .../client/ui/components/ProgressBar.java | 6 +++--- .../ui/overlay/components/InfoBoxComponent.java | 9 ++++++++- 31 files changed, 70 insertions(+), 61 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index 977f3dfb59..b986112645 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.devtools; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Polygon; @@ -74,7 +73,6 @@ class DevToolsOverlay extends Overlay private static final int ITEM_EMPTY = 6512; private static final int ITEM_FILLED = 20594; - private static final Font FONT = FontManager.getRunescapeFont().deriveFont(Font.BOLD, 16); private static final Color RED = new Color(221, 44, 0); private static final Color GREEN = new Color(0, 200, 83); private static final Color ORANGE = new Color(255, 109, 0); @@ -111,7 +109,6 @@ class DevToolsOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - graphics.setFont(FONT); if (plugin.getPlayers().isActive()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java index dc6a6f6461..a6a6bcdeb7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/VarInspector.java @@ -192,7 +192,7 @@ class VarInspector extends JFrame { lastTick = tick; JLabel header = new JLabel("Tick " + tick); - header.setFont(FontManager.getRunescapeSmallFont()); + header.setFont(FontManager.getSmallFont(getFont())); header.setBorder(new CompoundBorder( BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.LIGHT_GRAY_COLOR), BorderFactory.createEmptyBorder(3, 6, 0, 0) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java index acace3fe33..b6eb858b72 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java @@ -221,14 +221,14 @@ class FeedPanel extends PluginPanel Color darkerForeground = UIManager.getColor("Label.foreground").darker(); JLabel titleLabel = new JLabel(item.getTitle()); - titleLabel.setFont(FontManager.getRunescapeSmallFont()); + titleLabel.setFont(FontManager.getSmallFont(getFont())); titleLabel.setBackground(null); titleLabel.setForeground(darkerForeground); titleLabel.setPreferredSize(new Dimension(CONTENT_WIDTH - TIME_WIDTH, 0)); Duration duration = Duration.between(Instant.ofEpochMilli(item.getTimestamp()), Instant.now()); JLabel timeLabel = new JLabel(durationToString(duration)); - timeLabel.setFont(FontManager.getRunescapeSmallFont()); + timeLabel.setFont(FontManager.getSmallFont(getFont())); timeLabel.setForeground(darkerForeground); titleAndTime.add(titleLabel, BorderLayout.WEST); @@ -237,9 +237,9 @@ class FeedPanel extends PluginPanel JPanel content = new JPanel(new BorderLayout()); content.setBackground(null); - JLabel contentLabel = new JLabel(lineBreakText(item.getContent(), FontManager.getRunescapeSmallFont())); + JLabel contentLabel = new JLabel(lineBreakText(item.getContent(), FontManager.getSmallFont(getFont()))); contentLabel.setBorder(new EmptyBorder(2, 0, 0, 0)); - contentLabel.setFont(FontManager.getRunescapeSmallFont()); + contentLabel.setFont(FontManager.getSmallFont(getFont())); contentLabel.setForeground(darkerForeground); content.add(contentLabel, BorderLayout.CENTER); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java index 14090170fe..93a6c586b4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java @@ -131,11 +131,11 @@ public class GrandExchangeOfferSlot extends JPanel itemName.setForeground(Color.WHITE); itemName.setVerticalAlignment(JLabel.BOTTOM); - itemName.setFont(FontManager.getRunescapeSmallFont()); + itemName.setFont(FontManager.getSmallFont(getFont())); offerInfo.setForeground(ColorScheme.LIGHT_GRAY_COLOR); offerInfo.setVerticalAlignment(JLabel.TOP); - offerInfo.setFont(FontManager.getRunescapeSmallFont()); + offerInfo.setFont(FontManager.getSmallFont(getFont())); JLabel switchFaceViewIcon = new JLabel(); switchFaceViewIcon.setIcon(RIGHT_ARROW_ICON); @@ -162,11 +162,11 @@ public class GrandExchangeOfferSlot extends JPanel itemPrice.setForeground(Color.WHITE); itemPrice.setVerticalAlignment(JLabel.BOTTOM); - itemPrice.setFont(FontManager.getRunescapeSmallFont()); + itemPrice.setFont(FontManager.getSmallFont(getFont())); offerSpent.setForeground(Color.WHITE); offerSpent.setVerticalAlignment(JLabel.TOP); - offerSpent.setFont(FontManager.getRunescapeSmallFont()); + offerSpent.setFont(FontManager.getSmallFont(getFont())); JLabel switchDetailsViewIcon = new JLabel(); switchDetailsViewIcon.setIcon(LEFT_ARROW_ICON); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 03419c7da9..1c78b36153 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -295,7 +295,7 @@ public class HiscorePanel extends PluginPanel private JPanel makeSkillPanel(HiscoreSkill skill) { JLabel label = new JLabel(); - label.setFont(FontManager.getRunescapeSmallFont()); + label.setFont(FontManager.getSmallFont(getFont())); label.setText("--"); String skillName = (skill == null ? "combat" : skill.getName().toLowerCase()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 2edb250135..3a04530212 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -106,7 +106,7 @@ public class InfoPanel extends PluginPanel versionPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); versionPanel.setLayout(new GridLayout(0, 1)); - final Font smallFont = FontManager.getRunescapeSmallFont(); + final Font smallFont = FontManager.getSmallFont(getFont()); JLabel version = new JLabel(htmlLabel("RuneLite version: ", runeLiteProperties.getVersion())); version.setFont(smallFont); @@ -170,7 +170,7 @@ public class InfoPanel extends PluginPanel /** * Builds a link panel with a given icon, text and url to redirect to. */ - private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url) + private JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url) { JPanel container = new JPanel(); container.setBackground(ColorScheme.DARKER_GRAY_COLOR); @@ -224,11 +224,11 @@ public class InfoPanel extends PluginPanel JLabel topLine = new JLabel(topText); topLine.setForeground(Color.WHITE); - topLine.setFont(FontManager.getRunescapeSmallFont()); + topLine.setFont(FontManager.getSmallFont(getFont())); JLabel bottomLine = new JLabel(bottomText); bottomLine.setForeground(Color.WHITE); - bottomLine.setFont(FontManager.getRunescapeSmallFont()); + bottomLine.setFont(FontManager.getSmallFont(getFont())); textContainer.add(topLine); textContainer.add(bottomLine); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java index a82cee5814..29976bc0bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/BookPanel.java @@ -47,7 +47,7 @@ class BookPanel extends JPanel JLabel image = new JLabel(); b.getIcon().addTo(image); JLabel name = new JLabel(b.getShortName()); - location.setFont(FontManager.getRunescapeSmallFont()); + location.setFont(FontManager.getSmallFont(getFont())); layout.setVerticalGroup(layout.createParallelGroup() .addComponent(image) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java index f37be3eb43..edd2700920 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java @@ -90,12 +90,12 @@ class LootTrackerBox extends JPanel logTitle.setBackground(ColorScheme.DARKER_GRAY_COLOR.darker()); final JLabel titleLabel = new JLabel(Text.removeTags(id)); - titleLabel.setFont(FontManager.getRunescapeSmallFont()); + titleLabel.setFont(FontManager.getSmallFont(getFont())); titleLabel.setForeground(Color.WHITE); logTitle.add(titleLabel, BorderLayout.WEST); - subTitleLabel.setFont(FontManager.getRunescapeSmallFont()); + subTitleLabel.setFont(FontManager.getSmallFont(getFont())); subTitleLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); logTitle.add(subTitleLabel, BorderLayout.CENTER); @@ -104,7 +104,7 @@ class LootTrackerBox extends JPanel subTitleLabel.setText(subtitle); } - priceLabel.setFont(FontManager.getRunescapeSmallFont()); + priceLabel.setFont(FontManager.getSmallFont(getFont())); priceLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); logTitle.add(priceLabel, BorderLayout.EAST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index 4aaa7e0c7a..7a3585b1a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -277,8 +277,8 @@ class LootTrackerPanel extends PluginPanel overallInfo.setBackground(ColorScheme.DARKER_GRAY_COLOR); overallInfo.setLayout(new GridLayout(2, 1)); overallInfo.setBorder(new EmptyBorder(2, 10, 2, 0)); - overallKillsLabel.setFont(FontManager.getRunescapeSmallFont()); - overallGpLabel.setFont(FontManager.getRunescapeSmallFont()); + overallKillsLabel.setFont(FontManager.getSmallFont(getFont())); + overallGpLabel.setFont(FontManager.getSmallFont(getFont())); overallInfo.add(overallKillsLabel); overallInfo.add(overallGpLabel); overallPanel.add(overallIcon, BorderLayout.WEST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java index 590b0ff65e..ea99cf7f00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTAInventoryOverlay.java @@ -51,7 +51,7 @@ public class MTAInventoryOverlay extends Overlay { if (room.inside()) { - graphics.setFont(FontManager.getRunescapeBoldFont()); + graphics.setFont(FontManager.getSmallFont(graphics.getFont())); room.over(graphics); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java index 717bd86060..5ed9a7e6b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mta/MTASceneOverlay.java @@ -51,7 +51,7 @@ public class MTASceneOverlay extends Overlay { if (room.inside()) { - graphics.setFont(FontManager.getRunescapeFont()); + graphics.setFont(FontManager.getSmallFont(graphics.getFont())); room.under(graphics); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java index 51567dd2dc..0ad6b73d4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java @@ -69,7 +69,7 @@ public class ScreenMarkerCreationPanel extends JPanel setBorder(new EmptyBorder(8, 8, 8, 8)); setLayout(new BorderLayout()); - instructionsLabel.setFont(FontManager.getRunescapeSmallFont()); + instructionsLabel.setFont(FontManager.getSmallFont(getFont())); instructionsLabel.setForeground(Color.WHITE); JPanel actionsContainer = new JPanel(new GridLayout(1, 2, 8, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index d225410209..e934bff8b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -162,7 +162,7 @@ class ScreenMarkerPanel extends JPanel nameActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); save.setVisible(false); - save.setFont(FontManager.getRunescapeSmallFont()); + save.setFont(FontManager.getSmallFont(getFont())); save.setForeground(ColorScheme.PROGRESS_COMPLETE_COLOR); save.addMouseListener(new MouseAdapter() { @@ -191,7 +191,7 @@ class ScreenMarkerPanel extends JPanel }); cancel.setVisible(false); - cancel.setFont(FontManager.getRunescapeSmallFont()); + cancel.setFont(FontManager.getSmallFont(getFont())); cancel.setForeground(ColorScheme.PROGRESS_ERROR_COLOR); cancel.addMouseListener(new MouseAdapter() { @@ -217,7 +217,7 @@ class ScreenMarkerPanel extends JPanel } }); - rename.setFont(FontManager.getRunescapeSmallFont()); + rename.setFont(FontManager.getSmallFont(getFont())); rename.setForeground(ColorScheme.LIGHT_GRAY_COLOR.darker()); rename.addMouseListener(new MouseAdapter() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java index e2114a6a95..92d17bd4ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java @@ -212,7 +212,7 @@ class SkillCalculator extends JPanel JCheckBox uiCheckbox = new JCheckBox(); uiLabel.setForeground(Color.WHITE); - uiLabel.setFont(FontManager.getRunescapeSmallFont()); + uiLabel.setFont(FontManager.getSmallFont(getFont())); uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0)); uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java index 2051a0ddcd..696fa2dfdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java @@ -125,7 +125,7 @@ class UIActionSlot extends JPanel uiLabelName.setForeground(Color.WHITE); uiLabelActions = new JShadowedLabel("Unknown"); - uiLabelActions.setFont(FontManager.getRunescapeSmallFont()); + uiLabelActions.setFont(FontManager.getSmallFont(getFont())); uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR); uiInfo.add(uiLabelName); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java index 3aa1bff236..b1d9af5665 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java @@ -123,7 +123,7 @@ class UICalculatorInputArea extends JPanel uiInput.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR); uiInput.setBorder(new EmptyBorder(5, 7, 5, 7)); - uiLabel.setFont(FontManager.getRunescapeSmallFont()); + uiLabel.setFont(FontManager.getSmallFont(getFont())); uiLabel.setBorder(new EmptyBorder(0, 0, 4, 0)); uiLabel.setForeground(Color.WHITE); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java index fa1614c91b..a6bc9c0d52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java @@ -68,7 +68,7 @@ class UICombinedActionSlot extends JPanel uiLabelTitle.setForeground(Color.WHITE); uiLabelActions = new JShadowedLabel("Shift-click to select multiple"); - uiLabelActions.setFont(FontManager.getRunescapeSmallFont()); + uiLabelActions.setFont(FontManager.getSmallFont(getFont())); uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR); uiInfo.add(uiLabelTitle); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java index 675381b1fb..b0d28cdd0b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerOverlay.java @@ -134,7 +134,7 @@ class SlayerOverlay extends Overlay int slaughterCount = plugin.getSlaughterChargeCount(); int expeditiousCount = plugin.getExpeditiousChargeCount(); - graphics.setFont(FontManager.getRunescapeSmallFont()); + graphics.setFont(FontManager.getSmallFont(graphics.getFont())); for (WidgetItem item : getSlayerItems()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java index 96cf62c6fc..9b0e40ee02 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/OverviewItemPanel.java @@ -105,11 +105,11 @@ class OverviewItemPanel extends JPanel JLabel titleLabel = new JLabel(title); titleLabel.setForeground(Color.WHITE); - titleLabel.setFont(FontManager.getRunescapeSmallFont()); + titleLabel.setFont(FontManager.getSmallFont(getFont())); statusLabel = new JLabel(); statusLabel.setForeground(Color.GRAY); - statusLabel.setFont(FontManager.getRunescapeSmallFont()); + statusLabel.setFont(FontManager.getSmallFont(getFont())); textContainer.add(titleLabel); textContainer.add(statusLabel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java index 8bbb5ae4ab..872eb43f5c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeablePanel.java @@ -66,10 +66,10 @@ public class TimeablePanel extends JPanel infoPanel.setBorder(new EmptyBorder(4, 4, 4, 0)); final JLabel location = new JShadowedLabel(title); - location.setFont(FontManager.getRunescapeSmallFont()); + location.setFont(FontManager.getSmallFont(getFont())); location.setForeground(Color.WHITE); - estimate.setFont(FontManager.getRunescapeSmallFont()); + estimate.setFont(FontManager.getSmallFont(getFont())); estimate.setForeground(Color.GRAY); infoPanel.add(location); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java index fcc460fdf8..14722f4b4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java @@ -155,7 +155,7 @@ public class ClockTabPanel extends TabContentPanel JLabel headerLabel = new JLabel(title); headerLabel.setForeground(Color.WHITE); - headerLabel.setFont(FontManager.getRunescapeSmallFont()); + headerLabel.setFont(FontManager.getSmallFont(getFont())); panel.add(headerLabel, BorderLayout.CENTER); IconButton addButton = new IconButton(ADD_ICON, ADD_ICON_HOVER); @@ -175,7 +175,7 @@ public class ClockTabPanel extends TabContentPanel JLabel infoLabel = new JShadowedLabel(text); infoLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR.darker()); - infoLabel.setFont(FontManager.getRunescapeSmallFont()); + infoLabel.setFont(FontManager.getSmallFont(getFont())); panel.add(infoLabel); return panel; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java index 99bb8def81..bf285be9e9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/StopwatchPanel.java @@ -129,7 +129,7 @@ class StopwatchPanel extends ClockPanel private JLabel createSmallLabel(String text) { JLabel label = new JLabel(text, SwingConstants.CENTER); - label.setFont(FontManager.getRunescapeSmallFont()); + label.setFont(FontManager.getSmallFont(getFont())); label.setForeground(LAP_DATA_COLOR); return label; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java index 2c262111e2..e4dcf97508 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTabPanel.java @@ -94,7 +94,7 @@ public class FarmingTabPanel extends TabContentPanel groupLabel.setBorder(new EmptyBorder(15, 0, 0, 0)); } - groupLabel.setFont(FontManager.getRunescapeSmallFont()); + groupLabel.setFont(FontManager.getSmallFont(getFont())); add(groupLabel, c); c.gridy++; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java index 2d7ef01406..89a2071124 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java @@ -102,7 +102,7 @@ class WorldTableHeader extends JPanel }); textLabel.setText(title); - textLabel.setFont(FontManager.getRunescapeSmallFont()); + textLabel.setFont(FontManager.getSmallFont(getFont())); final JMenuItem refresh = new JMenuItem("Refresh worlds"); refresh.addActionListener(e -> diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java index c23face9ba..faab767125 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java @@ -271,7 +271,7 @@ class WorldTableRow extends JPanel column.setBorder(new EmptyBorder(0, 5, 0, 5)); playerCountField = new JLabel(world.getPlayers() + ""); - playerCountField.setFont(FontManager.getRunescapeSmallFont()); + playerCountField.setFont(FontManager.getSmallFont(getFont())); column.add(playerCountField, BorderLayout.WEST); @@ -300,7 +300,7 @@ class WorldTableRow extends JPanel column.setBorder(new EmptyBorder(0, 5, 0, 5)); activityField = new JLabel(world.getActivity()); - activityField.setFont(FontManager.getRunescapeSmallFont()); + activityField.setFont(FontManager.getSmallFont(getFont())); column.add(activityField, BorderLayout.WEST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java index f5987290eb..62aef759b6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java @@ -142,10 +142,10 @@ class XpInfoBox extends JPanel statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); statsPanel.setBorder(new EmptyBorder(9, 2, 9, 2)); - expGained.setFont(FontManager.getRunescapeSmallFont()); - expHour.setFont(FontManager.getRunescapeSmallFont()); - expLeft.setFont(FontManager.getRunescapeSmallFont()); - actionsLeft.setFont(FontManager.getRunescapeSmallFont()); + expGained.setFont(FontManager.getSmallFont(getFont())); + expHour.setFont(FontManager.getSmallFont(getFont())); + expLeft.setFont(FontManager.getSmallFont(getFont())); + actionsLeft.setFont(FontManager.getSmallFont(getFont())); statsPanel.add(expGained); statsPanel.add(expLeft); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java index e98f4da4f7..03d0a4cbbe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpPanel.java @@ -114,8 +114,8 @@ class XpPanel extends PluginPanel overallInfo.setLayout(new GridLayout(2, 1)); overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0)); - overallExpGained.setFont(FontManager.getRunescapeSmallFont()); - overallExpHour.setFont(FontManager.getRunescapeSmallFont()); + overallExpGained.setFont(FontManager.getSmallFont(getFont())); + overallExpHour.setFont(FontManager.getSmallFont(getFont())); overallInfo.add(overallExpGained); overallInfo.add(overallExpHour); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java index 3addfb26f9..82d2ad2e1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java @@ -131,16 +131,21 @@ public class FontManager return f.equals(runescapeFont) || f.equals(runescapeSmallFont) || f.equals(runescapeBoldFont); } + public static Font getSmallFont(Font f) + { + if (isRunescapeFont(f)) + { + return runescapeSmallFont; + } + return getFontOrDefault(f); + } + public static Font getFontFromType(Font f, FontType type) { switch (type) { case SMALL: - if (isRunescapeFont(f)) - { - return runescapeSmallFont; - } - return getFontOrDefault(f); + return getSmallFont(f); case BOLD: if (isRunescapeFont(f)) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java b/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java index e7b2fad971..92f48a6993 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/PluginErrorPanel.java @@ -52,7 +52,7 @@ public class PluginErrorPanel extends JPanel noResultsTitle.setForeground(Color.WHITE); noResultsTitle.setHorizontalAlignment(SwingConstants.CENTER); - noResultsDescription.setFont(FontManager.getRunescapeSmallFont()); + noResultsDescription.setFont(FontManager.getSmallFont(getFont())); noResultsDescription.setForeground(Color.GRAY); noResultsDescription.setHorizontalAlignment(SwingConstants.CENTER); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java index bc15d21a71..8c3c7e6a54 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ProgressBar.java @@ -74,15 +74,15 @@ public class ProgressBar extends DimmableJPanel topIndent = 2; } - leftLabel.setFont(FontManager.getRunescapeSmallFont()); + leftLabel.setFont(FontManager.getSmallFont(getFont())); leftLabel.setForeground(Color.WHITE); leftLabel.setBorder(new EmptyBorder(topIndent, 5, 0, 0)); - rightLabel.setFont(FontManager.getRunescapeSmallFont()); + rightLabel.setFont(FontManager.getSmallFont(getFont())); rightLabel.setForeground(Color.WHITE); rightLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 5)); - centerLabel.setFont(FontManager.getRunescapeSmallFont()); + centerLabel.setFont(FontManager.getSmallFont(getFont())); centerLabel.setForeground(Color.WHITE); centerLabel.setHorizontalAlignment(SwingConstants.CENTER); centerLabel.setBorder(new EmptyBorder(topIndent, 0, 0, 0)); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java index 8cd54cd926..3a433ffb15 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/InfoBoxComponent.java @@ -63,7 +63,14 @@ public class InfoBoxComponent implements LayoutableRenderableEntity return new Dimension(); } - graphics.setFont(getSize() < DEFAULT_SIZE ? FontManager.getRunescapeSmallFont() : FontManager.getRunescapeFont()); + if (graphics.getFont().equals(FontManager.getRunescapeFont()) && getSize() > DEFAULT_SIZE) + { + graphics.setFont(FontManager.getRunescapeFont()); + } + else + { + graphics.setFont(FontManager.getSmallFont(graphics.getFont())); + } final int baseX = preferredLocation.x; final int baseY = preferredLocation.y; From 6dec9b5f626976430c15521c9361528edd224fb6 Mon Sep 17 00:00:00 2001 From: l2- Date: Tue, 23 Oct 2018 22:14:44 +0200 Subject: [PATCH 06/63] now caching the 3 differently sized font objects and setting fallback font as rs default --- .../client/plugins/config/ConfigPanel.java | 4 +- .../net/runelite/client/ui/FontManager.java | 53 ++++++++++++++++--- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 9edbf71bf3..a59769b48f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -546,8 +546,8 @@ public class ConfigPanel extends PluginPanel } else { - log.debug("Selected font wasn't found on this system, resetting font back to runescape small"); - configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), FontManager.getRunescapeSmallFont()); + log.debug("Selected font wasn't found on this system, resetting font back to runescape regular"); + configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), FontManager.getRunescapeFont()); } box.addItemListener(e -> { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java index 82d2ad2e1d..91a1a658ab 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java @@ -28,11 +28,13 @@ import com.google.common.collect.ImmutableBiMap; import java.awt.Canvas; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashMap; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.IOException; +import lombok.Getter; import net.runelite.client.config.FontType; public class FontManager @@ -41,7 +43,23 @@ public class FontManager private static final Font runescapeSmallFont; private static final Font runescapeBoldFont; + @Getter + private static class CachedFont + { + private final Font reg; + private final Font small; + private final Font bold; + + private CachedFont(Font f) + { + reg = f.deriveFont(14.0f); + small = getFontOffCorrectSize(f); + bold = f.deriveFont(Font.BOLD, 14.0f); + } + } + private static final ImmutableBiMap fontMap; + private static final HashMap derivedFontMap = new HashMap<>(); static { @@ -62,9 +80,7 @@ public class FontManager .deriveFont(Font.PLAIN, 16); final LinkedHashMap _fontMap = new LinkedHashMap<>(); - _fontMap.put("Runescape small", runescapeSmallFont); - _fontMap.put("Runescape default", runescapeFont); - _fontMap.put("Runescape bold", runescapeBoldFont); + _fontMap.put("Runescape", runescapeFont); // Get all available fonts on the system Font[] availableFonts = ge.getAllFonts(); @@ -137,7 +153,16 @@ public class FontManager { return runescapeSmallFont; } - return getFontOrDefault(f); + + if (derivedFontMap.containsKey(f)) + { + return derivedFontMap.get(f).getSmall(); + } + + // cache and return + CachedFont cachedFont = new CachedFont(f); + derivedFontMap.put(f, cachedFont); + return cachedFont.getSmall(); } public static Font getFontFromType(Font f, FontType type) @@ -151,13 +176,29 @@ public class FontManager { return runescapeBoldFont; } - return getFontOrDefault(f).deriveFont(Font.BOLD, 14.0f); + if (derivedFontMap.containsKey(f)) + { + return derivedFontMap.get(f).getBold(); + } + + // cache and return + CachedFont cachedBoldFont = new CachedFont(f); + derivedFontMap.put(f, cachedBoldFont); + return cachedBoldFont.getBold(); default: //in this case regular if (isRunescapeFont(f)) { return runescapeFont; } - return getFontOrDefault(f).deriveFont(14.0f); + if (derivedFontMap.containsKey(f)) + { + return derivedFontMap.get(f).getReg(); + } + + // cache and return + CachedFont cachedFont = new CachedFont(f); + derivedFontMap.put(f, cachedFont); + return cachedFont.getReg(); } } From dc6dc64dae107cfc9ed894426844816c3b746838 Mon Sep 17 00:00:00 2001 From: l2- Date: Wed, 24 Oct 2018 19:00:09 +0200 Subject: [PATCH 07/63] Change font metrics logic in xpglobes and dev plugin to center y text position for any font --- .../net/runelite/client/plugins/devtools/DevToolsOverlay.java | 4 ++-- .../net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index b986112645..907c2ce4e2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -370,7 +370,7 @@ class DevToolsOverlay extends Overlay Rectangle2D textBounds = fm.getStringBounds(idText, graphics); int textX = (int) (slotBounds.getX() + (slotBounds.getWidth() / 2) - (textBounds.getWidth() / 2)); - int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (fm.getAscent() / 2)); + int textY = (int) (slotBounds.getY() + (slotBounds.getHeight() / 2) + (fm.getHeight() / 2) - fm.getMaxDescent()); graphics.setColor(new Color(255, 255, 255, 65)); graphics.fill(slotBounds); @@ -480,7 +480,7 @@ class DevToolsOverlay extends Overlay Rectangle2D textBounds = fm.getStringBounds(text, graphics); int textX = (int) (bounds.getX() + (bounds.getWidth() / 2) - (textBounds.getWidth() / 2)); - int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (fm.getMaxAscent() / 2)); + int textY = (int) (bounds.getY() + (bounds.getHeight() / 2) + (fm.getHeight() / 2) - fm.getMaxDescent()); graphics.setColor(Color.BLACK); graphics.drawString(text, textX + 1, textY + 1); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java index 1b487ebe5c..232fb2588e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java @@ -185,7 +185,7 @@ public class XpGlobesOverlay extends Overlay final FontMetrics metrics = graphics.getFontMetrics(); int drawX = x + (config.xpOrbSize() / 2) - (metrics.stringWidth(progress) / 2); - int drawY = y + (config.xpOrbSize() / 2) + (metrics.getHeight() / 2); + int drawY = y + (config.xpOrbSize() / 2) + (metrics.getHeight() / 2) - metrics.getMaxDescent(); OverlayUtil.renderTextLocation(graphics, new Point(drawX, drawY), progress, Color.WHITE); } From 8747e40f6a3ff599f8ec09e7097805ea4a5bb0ce Mon Sep 17 00:00:00 2001 From: l2- Date: Sun, 20 Jan 2019 15:37:09 +0100 Subject: [PATCH 08/63] unused import --- .../net/runelite/client/plugins/devtools/DevToolsOverlay.java | 1 - 1 file changed, 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java index 907c2ce4e2..573cd70400 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevToolsOverlay.java @@ -59,7 +59,6 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; -import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; From 13e0baffe070d1598bbd4c96f7ac159c060d21f2 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Tue, 12 Mar 2019 11:47:11 +0000 Subject: [PATCH 09/63] Added support for transparent text and border color customization to TextComponent, added font and alpha customization to the ground items plugin --- .../grounditems/GroundItemsConfig.java | 30 +++++++++-- .../grounditems/GroundItemsOverlay.java | 12 ++++- .../ui/overlay/components/TextComponent.java | 50 +++++++++++++------ 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index da3db4a3f1..ce698609d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -26,9 +26,11 @@ package net.runelite.client.plugins.grounditems; import java.awt.Color; +import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.FontType; import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; @@ -115,16 +117,16 @@ public interface GroundItemsConfig extends Config { return false; } - + @ConfigItem( keyName = "highlightTiles", name = "Highlight Tiles", description = "Configures whether or not to highlight tiles containing ground items", position = 6 ) - default boolean highlightTiles() - { - return false; + default boolean highlightTiles() + { + return false; } @ConfigItem( @@ -199,6 +201,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for default, non-highlighted items", position = 13 ) + @Alpha default Color defaultColor() { return Color.WHITE; @@ -210,6 +213,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for highlighted items", position = 14 ) + @Alpha default Color highlightedColor() { return Color.decode("#AA00FF"); @@ -221,6 +225,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for hidden items in right-click menu and when holding ALT", position = 15 ) + @Alpha default Color hiddenColor() { return Color.GRAY; @@ -232,6 +237,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for low value items", position = 16 ) + @Alpha default Color lowValueColor() { return Color.decode("#66B2FF"); @@ -254,6 +260,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for medium value items", position = 18 ) + @Alpha default Color mediumValueColor() { return Color.decode("#99FF99"); @@ -276,6 +283,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for high value items", position = 20 ) + @Alpha default Color highValueColor() { return Color.decode("#FF9600"); @@ -298,6 +306,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for insane value items", position = 22 ) + @Alpha default Color insaneValueColor() { return Color.decode("#FF66B2"); @@ -346,4 +355,15 @@ public interface GroundItemsConfig extends Config { return false; } -} + + @ConfigItem( + keyName = "fontType", + name = "Font type", + description = "Configures the font type to use when drawing items", + position = 27 + ) + default FontType fontStyle() + { + return FontType.REGULAR; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 1406bb1747..ac1d0e2c1f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.grounditems; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Polygon; @@ -94,8 +95,6 @@ public class GroundItemsOverlay extends Overlay { return null; } - - final FontMetrics fm = graphics.getFontMetrics(); final Player player = client.getLocalPlayer(); if (player == null || client.getViewportWidget() == null) @@ -103,6 +102,13 @@ public class GroundItemsOverlay extends Overlay return null; } + final Font originalFont = graphics.getFont(); + final Font font = config.fontStyle().getFont(); + + graphics.setFont(font); + + final FontMetrics fm = graphics.getFontMetrics(); + offsetMap.clear(); final LocalPoint localLocation = player.getLocalLocation(); final Point mousePos = client.getMouseCanvasPosition(); @@ -339,6 +345,8 @@ public class GroundItemsOverlay extends Overlay textComponent.render(graphics); } + graphics.setFont(originalFont); + return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java index 98532a8d7c..fba19f5013 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java @@ -24,11 +24,15 @@ */ package net.runelite.client.ui.overlay.components; +import java.awt.AlphaComposite; import java.awt.Color; +import java.awt.Composite; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Shape; +import java.awt.font.GlyphVector; import java.util.regex.Pattern; import lombok.Setter; import net.runelite.client.ui.overlay.RenderableEntity; @@ -43,6 +47,7 @@ public class TextComponent implements RenderableEntity private String text; private Point position = new Point(); private Color color = Color.WHITE; + private Color borderColor = Color.BLACK; public static String textWithoutColTags(String text) { @@ -64,28 +69,43 @@ public class TextComponent implements RenderableEntity final String textWithoutCol = textWithoutColTags(textSplitOnCol); final String colColor = textSplitOnCol.substring(textSplitOnCol.indexOf("=") + 1, textSplitOnCol.indexOf(">")); - // shadow - graphics.setColor(Color.BLACK); - graphics.drawString(textWithoutCol, x + 1, position.y + 1); - - // actual text - graphics.setColor(Color.decode("#" + colColor)); - graphics.drawString(textWithoutCol, x, position.y); + renderText(graphics, x, position.y, textWithoutCol, Color.decode("#" + colColor), borderColor); x += fontMetrics.stringWidth(textWithoutCol); } } else { - // shadow - graphics.setColor(Color.BLACK); - graphics.drawString(text, position.x + 1, position.y + 1); - - // actual text - graphics.setColor(color); - graphics.drawString(text, position.x, position.y); + renderText(graphics, position.x, position.y, text, color, borderColor); } - return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight()); } + + private void renderText(Graphics2D graphics, int x, int y, String text, Color color, Color border) + { + // remember previous composite + Composite originalComposite = graphics.getComposite(); + + // create a vector of the text + GlyphVector vector = graphics.getFont().createGlyphVector(graphics.getFontRenderContext(), text); + + // compute the text shape + Shape stroke = vector.getOutline(x + 1, y + 1); + Shape shape = vector.getOutline(x, y); + + // draw text border + graphics.setColor(border); + graphics.fill(stroke); + + // replace the pixels instead of overlaying + graphics.setComposite(AlphaComposite.Src); + + // draw actual text + graphics.setColor(color); + graphics.fill(shape); + + // reset composite to original + graphics.setComposite(originalComposite); + } + } From ff8a85448077a258139e08efb654b5a7d335748f Mon Sep 17 00:00:00 2001 From: BuildTools Date: Tue, 12 Mar 2019 11:47:11 +0000 Subject: [PATCH 10/63] Added support for transparent text and border color customization to TextComponent, added font and alpha customization to the ground items plugin --- .../grounditems/GroundItemsConfig.java | 30 +++++++++-- .../grounditems/GroundItemsOverlay.java | 12 ++++- .../ui/overlay/components/TextComponent.java | 50 +++++++++++++------ 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index da3db4a3f1..ce698609d3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -26,9 +26,11 @@ package net.runelite.client.plugins.grounditems; import java.awt.Color; +import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.FontType; import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; @@ -115,16 +117,16 @@ public interface GroundItemsConfig extends Config { return false; } - + @ConfigItem( keyName = "highlightTiles", name = "Highlight Tiles", description = "Configures whether or not to highlight tiles containing ground items", position = 6 ) - default boolean highlightTiles() - { - return false; + default boolean highlightTiles() + { + return false; } @ConfigItem( @@ -199,6 +201,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for default, non-highlighted items", position = 13 ) + @Alpha default Color defaultColor() { return Color.WHITE; @@ -210,6 +213,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for highlighted items", position = 14 ) + @Alpha default Color highlightedColor() { return Color.decode("#AA00FF"); @@ -221,6 +225,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for hidden items in right-click menu and when holding ALT", position = 15 ) + @Alpha default Color hiddenColor() { return Color.GRAY; @@ -232,6 +237,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for low value items", position = 16 ) + @Alpha default Color lowValueColor() { return Color.decode("#66B2FF"); @@ -254,6 +260,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for medium value items", position = 18 ) + @Alpha default Color mediumValueColor() { return Color.decode("#99FF99"); @@ -276,6 +283,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for high value items", position = 20 ) + @Alpha default Color highValueColor() { return Color.decode("#FF9600"); @@ -298,6 +306,7 @@ public interface GroundItemsConfig extends Config description = "Configures the color for insane value items", position = 22 ) + @Alpha default Color insaneValueColor() { return Color.decode("#FF66B2"); @@ -346,4 +355,15 @@ public interface GroundItemsConfig extends Config { return false; } -} + + @ConfigItem( + keyName = "fontType", + name = "Font type", + description = "Configures the font type to use when drawing items", + position = 27 + ) + default FontType fontStyle() + { + return FontType.REGULAR; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index 1406bb1747..ac1d0e2c1f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.grounditems; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Polygon; @@ -94,8 +95,6 @@ public class GroundItemsOverlay extends Overlay { return null; } - - final FontMetrics fm = graphics.getFontMetrics(); final Player player = client.getLocalPlayer(); if (player == null || client.getViewportWidget() == null) @@ -103,6 +102,13 @@ public class GroundItemsOverlay extends Overlay return null; } + final Font originalFont = graphics.getFont(); + final Font font = config.fontStyle().getFont(); + + graphics.setFont(font); + + final FontMetrics fm = graphics.getFontMetrics(); + offsetMap.clear(); final LocalPoint localLocation = player.getLocalLocation(); final Point mousePos = client.getMouseCanvasPosition(); @@ -339,6 +345,8 @@ public class GroundItemsOverlay extends Overlay textComponent.render(graphics); } + graphics.setFont(originalFont); + return null; } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java index 98532a8d7c..fba19f5013 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java @@ -24,11 +24,15 @@ */ package net.runelite.client.ui.overlay.components; +import java.awt.AlphaComposite; import java.awt.Color; +import java.awt.Composite; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.Shape; +import java.awt.font.GlyphVector; import java.util.regex.Pattern; import lombok.Setter; import net.runelite.client.ui.overlay.RenderableEntity; @@ -43,6 +47,7 @@ public class TextComponent implements RenderableEntity private String text; private Point position = new Point(); private Color color = Color.WHITE; + private Color borderColor = Color.BLACK; public static String textWithoutColTags(String text) { @@ -64,28 +69,43 @@ public class TextComponent implements RenderableEntity final String textWithoutCol = textWithoutColTags(textSplitOnCol); final String colColor = textSplitOnCol.substring(textSplitOnCol.indexOf("=") + 1, textSplitOnCol.indexOf(">")); - // shadow - graphics.setColor(Color.BLACK); - graphics.drawString(textWithoutCol, x + 1, position.y + 1); - - // actual text - graphics.setColor(Color.decode("#" + colColor)); - graphics.drawString(textWithoutCol, x, position.y); + renderText(graphics, x, position.y, textWithoutCol, Color.decode("#" + colColor), borderColor); x += fontMetrics.stringWidth(textWithoutCol); } } else { - // shadow - graphics.setColor(Color.BLACK); - graphics.drawString(text, position.x + 1, position.y + 1); - - // actual text - graphics.setColor(color); - graphics.drawString(text, position.x, position.y); + renderText(graphics, position.x, position.y, text, color, borderColor); } - return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight()); } + + private void renderText(Graphics2D graphics, int x, int y, String text, Color color, Color border) + { + // remember previous composite + Composite originalComposite = graphics.getComposite(); + + // create a vector of the text + GlyphVector vector = graphics.getFont().createGlyphVector(graphics.getFontRenderContext(), text); + + // compute the text shape + Shape stroke = vector.getOutline(x + 1, y + 1); + Shape shape = vector.getOutline(x, y); + + // draw text border + graphics.setColor(border); + graphics.fill(stroke); + + // replace the pixels instead of overlaying + graphics.setComposite(AlphaComposite.Src); + + // draw actual text + graphics.setColor(color); + graphics.fill(shape); + + // reset composite to original + graphics.setComposite(originalComposite); + } + } From 1f45546dc9f1f4b5067c0720be132af313035045 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Tue, 12 Mar 2019 15:23:05 +0000 Subject: [PATCH 11/63] Replaced the TextComponentTest test --- .../overlay/components/TextComponentTest.java | 155 ++++++++---------- 1 file changed, 68 insertions(+), 87 deletions(-) diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java index 067205bd3b..ca36f014b5 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java @@ -1,87 +1,68 @@ -/* - * Copyright (c) 2018, Adam - * 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.ui.overlay.components; - -import java.awt.Color; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import org.mockito.runners.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class TextComponentTest -{ - @Mock - private Graphics2D graphics; - - @Before - public void before() - { - when(graphics.getFontMetrics()).thenReturn(mock(FontMetrics.class)); - } - - @Test - public void testRender() - { - TextComponent textComponent = new TextComponent(); - textComponent.setText("test"); - textComponent.setColor(Color.RED); - textComponent.render(graphics); - verify(graphics, times(2)).drawString(eq("test"), anyInt(), anyInt()); - verify(graphics, atLeastOnce()).setColor(Color.RED); - } - - @Test - public void testRender2() - { - TextComponent textComponent = new TextComponent(); - textComponent.setText("test"); - textComponent.render(graphics); - verify(graphics, times(2)).drawString(eq("test"), anyInt(), anyInt()); - verify(graphics, atLeastOnce()).setColor(Color.BLUE); - } - - @Test - public void testRender3() - { - TextComponent textComponent = new TextComponent(); - textComponent.setText("test test"); - textComponent.render(graphics); - verify(graphics, atLeastOnce()).drawString(eq("test"), anyInt(), anyInt()); - verify(graphics, atLeastOnce()).drawString(eq(" test"), anyInt(), anyInt()); - verify(graphics, atLeastOnce()).setColor(Color.BLUE); - verify(graphics, atLeastOnce()).setColor(Color.GREEN); - } -} +/* + * Copyright (c) 2018, Adam + * 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.ui.overlay.components; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import org.junit.Before; +import org.junit.Test; + +public class TextComponentTest +{ + private Graphics2D graphics; + + @Before + public void before() + { + BufferedImage dest = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + graphics = (Graphics2D) dest.getGraphics(); + } + + @Test + public void testRender() + { + TextComponent textComponent = new TextComponent(); + textComponent.setText("test"); + textComponent.setColor(Color.RED); + textComponent.render(graphics); + } + + @Test + public void testRender2() + { + TextComponent textComponent = new TextComponent(); + textComponent.setText("test"); + textComponent.render(graphics); + } + + @Test + public void testRender3() + { + TextComponent textComponent = new TextComponent(); + textComponent.setText("test test"); + textComponent.render(graphics); + } +} From dd2c351218ca8aff7f6b44c42f72fc5aeac8f3e3 Mon Sep 17 00:00:00 2001 From: CalebWhiting Date: Thu, 14 Mar 2019 13:13:30 +0000 Subject: [PATCH 12/63] Removed grounditems.fontStyle option --- .../client/plugins/grounditems/GroundItemsConfig.java | 11 ----------- .../plugins/grounditems/GroundItemsOverlay.java | 9 --------- .../ui/overlay/components/TextComponentTest.java | 11 ++++++++++- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java index ce698609d3..1e658f84cd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsConfig.java @@ -30,7 +30,6 @@ import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.FontType; import net.runelite.client.plugins.grounditems.config.ItemHighlightMode; import net.runelite.client.plugins.grounditems.config.MenuHighlightMode; import net.runelite.client.plugins.grounditems.config.PriceDisplayMode; @@ -356,14 +355,4 @@ public interface GroundItemsConfig extends Config return false; } - @ConfigItem( - keyName = "fontType", - name = "Font type", - description = "Configures the font type to use when drawing items", - position = 27 - ) - default FontType fontStyle() - { - return FontType.REGULAR; - } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java index ac1d0e2c1f..31a6077d1a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsOverlay.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.grounditems; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Polygon; @@ -102,11 +101,6 @@ public class GroundItemsOverlay extends Overlay return null; } - final Font originalFont = graphics.getFont(); - final Font font = config.fontStyle().getFont(); - - graphics.setFont(font); - final FontMetrics fm = graphics.getFontMetrics(); offsetMap.clear(); @@ -344,9 +338,6 @@ public class GroundItemsOverlay extends Overlay textComponent.setPosition(new java.awt.Point(textX, textY)); textComponent.render(graphics); } - - graphics.setFont(originalFont); - return null; } diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java index ca36f014b5..6bd5ebfaa4 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java @@ -27,17 +27,19 @@ package net.runelite.client.ui.overlay.components; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; +import org.junit.After; import org.junit.Before; import org.junit.Test; public class TextComponentTest { private Graphics2D graphics; + private BufferedImage dest; @Before public void before() { - BufferedImage dest = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + dest = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); graphics = (Graphics2D) dest.getGraphics(); } @@ -65,4 +67,11 @@ public class TextComponentTest textComponent.setText("test test"); textComponent.render(graphics); } + + @After + public void after() { + graphics.dispose(); + dest.flush(); + } + } From 51fb57e0b03b80802b078f683ef2e95cba379fb8 Mon Sep 17 00:00:00 2001 From: CalebWhiting Date: Thu, 14 Mar 2019 13:23:24 +0000 Subject: [PATCH 13/63] Formatting fix --- .../client/ui/overlay/components/TextComponentTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java index 6bd5ebfaa4..f1677daa4b 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/TextComponentTest.java @@ -69,7 +69,8 @@ public class TextComponentTest } @After - public void after() { + public void after() + { graphics.dispose(); dest.flush(); } From 67bfbf082b0898a9a7c084b7863aa0f90bd4778b Mon Sep 17 00:00:00 2001 From: Jeremy Plsek Date: Tue, 4 Jun 2019 13:49:28 +0200 Subject: [PATCH 14/63] inventory grid: add color config --- .../inventorygrid/InventoryGridConfig.java | 35 +++++++++++++++++-- .../inventorygrid/InventoryGridOverlay.java | 8 ++--- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java index eda6b7cbb8..80dcc007de 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridConfig.java @@ -24,6 +24,8 @@ */ package net.runelite.client.plugins.inventorygrid; +import java.awt.Color; +import net.runelite.client.config.Alpha; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -34,7 +36,8 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showItem", name = "Show item", - description = "Show a preview of the item in the new slot" + description = "Show a preview of the item in the new slot", + position = 1 ) default boolean showItem() { @@ -44,7 +47,8 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showGrid", name = "Show grid", - description = "Show a grid on the inventory while dragging" + description = "Show a grid on the inventory while dragging", + position = 2 ) default boolean showGrid() { @@ -54,10 +58,35 @@ public interface InventoryGridConfig extends Config @ConfigItem( keyName = "showHighlight", name = "Highlight background", - description = "Show a green background highlight on the new slot" + description = "Show a background highlight on the new slot", + position = 3 ) default boolean showHighlight() { return true; } + + @Alpha + @ConfigItem( + keyName = "gridColor", + name = "Grid color", + description = "The color of the grid", + position = 4 + ) + default Color gridColor() + { + return new Color(255, 255, 255, 45); + } + + @Alpha + @ConfigItem( + keyName = "highlightColor", + name = "Highlight color", + description = "The color of the new inventory slot highlight", + position = 5 + ) + default Color highlightColor() + { + return new Color(0, 255, 0, 45); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java index f628f007c6..2e845cd647 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorygrid/InventoryGridOverlay.java @@ -27,7 +27,6 @@ package net.runelite.client.plugins.inventorygrid; import com.google.inject.Inject; import java.awt.AlphaComposite; -import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -47,9 +46,6 @@ class InventoryGridOverlay extends Overlay private static final int INVENTORY_SIZE = 28; private static final int DRAG_DELAY = 5; - private static final Color HIGHLIGHT = new Color(0, 255, 0, 45); - private static final Color GRID = new Color(255, 255, 255, 45); - private final InventoryGridConfig config; private final Client client; private final ItemManager itemManager; @@ -101,12 +97,12 @@ class InventoryGridOverlay extends Overlay if (config.showHighlight() && inBounds) { - graphics.setColor(HIGHLIGHT); + graphics.setColor(config.highlightColor()); graphics.fill(bounds); } else if (config.showGrid()) { - graphics.setColor(GRID); + graphics.setColor(config.gridColor()); graphics.fill(bounds); } } From 658a2a7a00a772edd0f29c21ae2418c5130192fd Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Thu, 20 Jun 2019 14:23:22 +0100 Subject: [PATCH 15/63] prayer: add HD prayer bar --- .../plugins/prayer/PrayerBarOverlay.java | 42 +++++++++++++++++- .../runelite/client/plugins/prayer/back.png | Bin 0 -> 358 bytes .../runelite/client/plugins/prayer/front.png | Bin 0 -> 437 bytes 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/prayer/back.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/prayer/front.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java index 18d28da696..5798698621 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerBarOverlay.java @@ -28,6 +28,7 @@ package net.runelite.client.plugins.prayer; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; @@ -35,11 +36,13 @@ import net.runelite.api.Perspective; import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.api.Skill; +import net.runelite.api.SpriteID; import net.runelite.api.coords.LocalPoint; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.util.ImageUtil; @Singleton class PrayerBarOverlay extends Overlay @@ -48,6 +51,9 @@ class PrayerBarOverlay extends Overlay private static final Color BAR_BG_COLOR = Color.black; private static final Color FLICK_HELP_COLOR = Color.white; private static final Dimension PRAYER_BAR_SIZE = new Dimension(30, 5); + private static final int HD_PRAYER_BAR_PADDING = 1; + private static final BufferedImage HD_FRONT_BAR = ImageUtil.getResourceStreamFromClass(PrayerPlugin.class, "front.png"); + private static final BufferedImage HD_BACK_BAR = ImageUtil.getResourceStreamFromClass(PrayerPlugin.class, "back.png"); private final Client client; private final PrayerConfig config; @@ -79,12 +85,44 @@ class PrayerBarOverlay extends Overlay final LocalPoint localLocation = client.getLocalPlayer().getLocalLocation(); final Point canvasPoint = Perspective.localToCanvas(client, localLocation, client.getPlane(), height); + final float ratio = (float) client.getBoostedSkillLevel(Skill.PRAYER) / client.getRealSkillLevel(Skill.PRAYER); + + // Draw HD bar + if (client.getSpriteOverrides().containsKey(SpriteID.HEALTHBAR_DEFAULT_FRONT_30PX)) + { + final int barWidth = HD_FRONT_BAR.getWidth(); + final int barHeight = HD_FRONT_BAR.getHeight(); + final int barX = canvasPoint.getX() - barWidth / 2; + final int barY = canvasPoint.getY(); + + // Include padding so the bar doesn't show empty at very low prayer values + final int progressFill = (int) Math.ceil(Math.max(HD_PRAYER_BAR_PADDING * 2, Math.min((barWidth * ratio), barWidth))); + + graphics.drawImage(HD_BACK_BAR, barX, barY, barWidth, barHeight, null); + // Use a sub-image to create the same effect the HD Health Bar has + graphics.drawImage(HD_FRONT_BAR.getSubimage(0, 0, progressFill, barHeight), barX, barY, progressFill, barHeight, null); + + if ((plugin.isPrayersActive() || config.prayerFlickAlwaysOn()) + && (config.prayerFlickLocation().equals(PrayerFlickLocation.PRAYER_BAR) + || config.prayerFlickLocation().equals(PrayerFlickLocation.BOTH))) + { + final double t = plugin.getTickProgress(); + final int halfBarWidth = (barWidth / 2) - HD_PRAYER_BAR_PADDING; + + final int xOffset = (int) (-Math.cos(t) * halfBarWidth) + ((barWidth / 2) - halfBarWidth); + + graphics.setColor(FLICK_HELP_COLOR); + graphics.fillRect(barX + xOffset + HD_PRAYER_BAR_PADDING, barY + HD_PRAYER_BAR_PADDING, 1, barHeight - HD_PRAYER_BAR_PADDING * 2); + } + + return new Dimension(barWidth, barHeight); + } + // Draw bar final int barX = canvasPoint.getX() - 15; final int barY = canvasPoint.getY(); final int barWidth = PRAYER_BAR_SIZE.width; final int barHeight = PRAYER_BAR_SIZE.height; - final float ratio = (float) client.getBoostedSkillLevel(Skill.PRAYER) / client.getRealSkillLevel(Skill.PRAYER); // Restricted by the width to prevent the bar from being too long while you are boosted above your real prayer level. final int progressFill = (int) Math.ceil(Math.min((barWidth * ratio), barWidth)); @@ -100,7 +138,7 @@ class PrayerBarOverlay extends Overlay { double t = plugin.getTickProgress(); - int xOffset = (int) (-Math.cos(t) * barWidth / 2) + barWidth / 2; + final int xOffset = (int) (-Math.cos(t) * barWidth / 2) + barWidth / 2; graphics.setColor(FLICK_HELP_COLOR); graphics.fillRect(barX + xOffset, barY, 1, barHeight); diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/prayer/back.png b/runelite-client/src/main/resources/net/runelite/client/plugins/prayer/back.png new file mode 100644 index 0000000000000000000000000000000000000000..76773682c47c50546ed95e9dbf9b84f8694869e7 GIT binary patch literal 358 zcmeAS@N?(olHy`uVBq!ia0vp^7C_9-!3HE_SM{XanMprAyFYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zp`O`aKh76GHP<~|978Pp?_Rmj-fAGi{^76a&EQFfh8OvTC(0>Jlv_0Y-~a!~*DbGa zx|$Wcefgu{jhBAD%Mr9_QV7UTY3+V2VR%gB`JG8Bos$I)Y5QLGj+~bJ$;Mve^d)bv z%8Gn$PIV5}1uwSchF&(Q`0IMTblSf6R}FYFWR5pi&XeD$(;anP)c11B{nf9lxH}ma zYwWtJ8_(_#C?Yl^cI_%HeGR@BzyJP-y%3r1FugY5zK{*~n(3ECuN$X5{JqgQj9qi- zj{gc87k*!S!u3zT_|ZJEwuj~melD(*cH;QSP}Add!eos?4$zAXp00i_>zopr07m(Y AegFUf literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/prayer/front.png b/runelite-client/src/main/resources/net/runelite/client/plugins/prayer/front.png new file mode 100644 index 0000000000000000000000000000000000000000..d8df9d8bfef197e3894f126cba8b3270edba2229 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^7C_9-!3HE_SM{XanMprAyFYeY$Kep*R+Vo@qXL1JcJiC$i6iGqoq zp`O`aKh76GL)AQ8978PplNp%p&i+3vw74Sg=eqwq#eRR&XVeNbioa3gJAaeups|^A z!TG3=J3B;#uR9dpYx>XgvRJ^PL`&`4OdqSZY9SXHd+vkJ^)Im77*Fw;4av`v6Agr+sVcw333OXT9)uH zOb)V<*!|4D`TnZ^JZZv;67L-2N?V#8+QgVXEAu>O_<4iJ`MAPiM~j-H^=%tc9i%#H z(;pqrGZv7Tl7FY*iTMPJO;Hg-EtM=Sj)rW94bC^(a%g8b%xg(3u~VHfA=02yz&H2I cfdjx;sd_cP&GVcNFjN^lUHx3vIVCg!00;x3^Z)<= literal 0 HcmV?d00001 From 1228c132df2d26fae6a0cf1effe9351841960e63 Mon Sep 17 00:00:00 2001 From: gazivodag Date: Mon, 24 Jun 2019 08:43:53 -0400 Subject: [PATCH 16/63] Looting bag viewer update Ability to see GP overlayed on looting bag Config Draft PR --- .../LootingBagViewerConfig.java | 69 ++++++++++ .../LootingBagViewerPlugin.java | 120 ++++++++++++++++-- .../LootingBagViewerWidgetOverlay.java | 85 +++++++++++++ 3 files changed, 266 insertions(+), 8 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerWidgetOverlay.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerConfig.java new file mode 100644 index 0000000000..6f216c47df --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerConfig.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.lootingbagviewer; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Stub; + +@ConfigGroup("lootingbagviewer") +public interface LootingBagViewerConfig extends Config +{ + @ConfigItem( + keyName = "overlayStub", + name = "Overlays", + description = "", + position = 0 + ) + default Stub overlayStub() + { + return new Stub(); + } + + @ConfigItem( + keyName = "renderViewer", + name = "Render Viewer", + description = "Shows second inventory on screen with looting bag items.", + position = 1, + parent = "overlayStub" + ) + default boolean renderViewer() + { + return true; + } + + @ConfigItem( + keyName = "renderLootingBag", + name = "Render Looting Bag Worth", + description = "Shows current amount of GP over the looting bag.", + position = 2, + parent = "overlayStub" + ) + default boolean renderLootingBag() + { + return true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java index aea700c292..0a7ed4ba03 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 AWPH-I + * Copyright (c) 2019, gazivodag * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,37 +26,140 @@ package net.runelite.client.plugins.lootingbagviewer; +import com.google.common.base.Strings; +import com.google.inject.Provides; import javax.inject.Inject; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.WidgetHiddenChanged; +import net.runelite.api.widgets.Widget; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( - name = "PvP Looting Bag Viewer", - description = "Add an overlay showing the contents of your looting bag", - tags = {"alternate", "items", "overlay", "second"}, - type = PluginType.PVP, - enabledByDefault = false + name = "PvP Looting Bag Viewer", + description = "Add an overlay showing the contents of your looting bag", + tags = {"alternate", "items", "overlay", "second"}, + type = PluginType.PVP, + enabledByDefault = false ) - +/** + * TODO: Remember current looting bag value when client restarts + * TODO: Write an event for picking up an item (with opened looting bag) and add its price to the current looting bag value + * TODO: Write something to capture adding items to a looting bag and add its price to the current looting bag value + * TODO: Make if check for empty looting bag so it doesn't throw any errors + */ public class LootingBagViewerPlugin extends Plugin { @Inject - private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private LootingBagViewerOverlay overlay; + + @Inject + private LootingBagViewerWidgetOverlay widgetOverlay; @Inject private OverlayManager overlayManager; + @Inject + private LootingBagViewerConfig config; + + @Getter + @Setter + private int valueToShow = -1; + + @Provides + LootingBagViewerConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(LootingBagViewerConfig.class); + } + @Override public void startUp() { - overlayManager.add(overlay); + if (config.renderViewer()) + { + overlayManager.add(overlay); + } + + if (config.renderLootingBag()) + { + overlayManager.add(widgetOverlay); + } } @Override public void shutDown() { overlayManager.remove(overlay); + overlayManager.remove(widgetOverlay); } + + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) + { + if (configChanged.getKey().equals("renderViewer")) + { + if (Boolean.parseBoolean(configChanged.getNewValue()) == true) + { + overlayManager.add(overlay); + } + else + { + overlayManager.remove(overlay); + } + } + if (configChanged.getKey().equals("renderLootingBag")) + { + if (Boolean.parseBoolean(configChanged.getNewValue()) == true) + { + overlayManager.add(widgetOverlay); + } + else + { + overlayManager.remove(widgetOverlay); + } + } + } + + + /** + * @param widgetHiddenChanged + */ + @Subscribe + public void onWidgetHiddenChanged(WidgetHiddenChanged widgetHiddenChanged) + { + Widget widget = widgetHiddenChanged.getWidget(); + if (widget.getParentId() == 5308416 && !widget.isHidden()) + { + clientThread.invokeLater(() -> + { + Widget value = client.getWidget(81, 6); + if (!Strings.isNullOrEmpty(value.getText())) + { + String str = value.getText(); + str = str.replace("Bag value: ", "") + .replace("Value: ", "") + .replace(" coins", "") + .replace(",", ""); + + int val = Integer.parseInt(str); + setValueToShow(Math.round(val) / 1000); + } + }); + } + } + } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerWidgetOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerWidgetOverlay.java new file mode 100644 index 0000000000..00c716f2fb --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerWidgetOverlay.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019, gazivodag + * 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.lootingbagviewer; + +import java.awt.Color; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.ItemID; +import net.runelite.api.Point; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.ui.overlay.WidgetItemOverlay; + +public class LootingBagViewerWidgetOverlay extends WidgetItemOverlay +{ + private Client client; + private LootingBagViewerPlugin plugin; + + @Inject + LootingBagViewerWidgetOverlay(Client client, LootingBagViewerPlugin plugin) + { + this.client = client; + this.plugin = plugin; + showOnInventory(); + } + + @Override + public void renderItemOverlay(Graphics2D graphics, int itemId, WidgetItem itemWidget) + { + if (plugin.getValueToShow() != -1) + { + switch (itemId) + { + case ItemID.LOOTING_BAG: + case ItemID.LOOTING_BAG_22586: + Point point = new Point(itemWidget.getCanvasLocation().getX() + lineX(plugin.getValueToShow()), itemWidget.getCanvasLocation().getY() + 25); + OverlayUtil.renderTextLocation(graphics, point, (plugin.getValueToShow() + "K"), Color.WHITE); + break; + } + } + } + + /** + * To align 16k (gp) or 4213k (gp) correctly between the looting bag without looking off + * + * @return + */ + private static int lineX(int lootingBagValue) + { + switch ((int) (Math.log10(lootingBagValue) + 1)) + { + case 1: + case 2: + return 8; + case 3: + case 4: + return 6; + default: + return 8; + } + } +} From ffa85cbc791c13a979efa00c5c45f5b38eb71701 Mon Sep 17 00:00:00 2001 From: gazivodag Date: Mon, 24 Jun 2019 18:36:58 -0400 Subject: [PATCH 17/63] =?UTF-8?q?=E2=9C=94=E2=9C=94=E2=9C=94=20TODO:=20Mak?= =?UTF-8?q?e=20if=20check=20for=20empty=20looting=20bag=20so=20it=20doesn'?= =?UTF-8?q?t=20throw=20any=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LootingBagViewerPlugin.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java index 0a7ed4ba03..3124d0fe51 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -31,6 +31,7 @@ import com.google.inject.Provides; import javax.inject.Inject; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.WidgetHiddenChanged; @@ -54,8 +55,8 @@ import net.runelite.client.ui.overlay.OverlayManager; * TODO: Remember current looting bag value when client restarts * TODO: Write an event for picking up an item (with opened looting bag) and add its price to the current looting bag value * TODO: Write something to capture adding items to a looting bag and add its price to the current looting bag value - * TODO: Make if check for empty looting bag so it doesn't throw any errors */ +@Slf4j public class LootingBagViewerPlugin extends Plugin { @Inject @@ -112,7 +113,7 @@ public class LootingBagViewerPlugin extends Plugin { if (configChanged.getKey().equals("renderViewer")) { - if (Boolean.parseBoolean(configChanged.getNewValue()) == true) + if (Boolean.parseBoolean(configChanged.getNewValue())) { overlayManager.add(overlay); } @@ -123,7 +124,7 @@ public class LootingBagViewerPlugin extends Plugin } if (configChanged.getKey().equals("renderLootingBag")) { - if (Boolean.parseBoolean(configChanged.getNewValue()) == true) + if (Boolean.parseBoolean(configChanged.getNewValue())) { overlayManager.add(widgetOverlay); } @@ -147,16 +148,22 @@ public class LootingBagViewerPlugin extends Plugin clientThread.invokeLater(() -> { Widget value = client.getWidget(81, 6); + log.debug("val: {}", value.getText()); + if (!Strings.isNullOrEmpty(value.getText())) { - String str = value.getText(); - str = str.replace("Bag value: ", "") - .replace("Value: ", "") - .replace(" coins", "") - .replace(",", ""); + if (value.getText().equals("Value: -")) { + setValueToShow(-1); + } else { + String str = value.getText(); + str = str.replace("Bag value: ", "") + .replace("Value: ", "") + .replace(" coins", "") + .replace(",", ""); - int val = Integer.parseInt(str); - setValueToShow(Math.round(val) / 1000); + int val = Integer.parseInt(str); + setValueToShow(Math.round(val) / 1000); + } } }); } From 5860d29351322f6023aa538bf44516a942eab113 Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 24 Jun 2019 22:55:51 -0400 Subject: [PATCH 18/63] Update XteaClient.java --- .../runelite/http/api/xtea/XteaClient.java | 50 +------------------ 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java index ea859d8157..aa2b8382e4 100644 --- a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java +++ b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java @@ -49,55 +49,7 @@ public class XteaClient public void submit(XteaRequest xteaRequest) { - String json = RuneLiteAPI.GSON.toJson(xteaRequest); - - HttpUrl url = RuneLiteAPI.getPlusApiBase().newBuilder() - .addPathSegment("xtea") - .build(); - - logger.debug("Built URI: {}", url); - - Request request = new Request.Builder() - .post(RequestBody.create(JSON, json)) - .url(url) - .build(); - - try - { - try (Response response = RuneLiteAPI.RLP_CLIENT.newCall(request).execute()) - { - logger.debug("xtea response " + response.code()); - } - } - catch (IOException e) - { - e.printStackTrace(); - } - - RuneLiteAPI.RLP_CLIENT.newCall(request).enqueue(new Callback() - { - @Override - public void onFailure(Call call, IOException e) - { - logger.warn("unable to submit xtea keys", e); - } - - @Override - public void onResponse(Call call, Response response) - { - try - { - if (!response.isSuccessful()) - { - logger.debug("unsuccessful xtea response"); - } - } - finally - { - response.close(); - } - } - }); + // Don't submit xteas from private server } public List get() throws IOException From 135f536f9bb33b3c11c0f96fab44a338a1292943 Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 24 Jun 2019 23:05:17 -0400 Subject: [PATCH 19/63] Update README.md --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7ff563d196..92ba3ce985 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,25 @@ -# RuneLitePlus [![Build Status](https://travis-ci.org/runelite-extended/runelite.svg?branch=master)](https://travis-ci.org/runelite-extended/runelite) [![Discord](https://img.shields.io/discord/373382904769675265.svg)](https://discord.gg/HN5gf3m) +# RuneLitePlus-PS rev180 [![Build Status](https://travis-ci.org/zeruth/runeliteplus-ps.svg?branch=master)](https://travis-ci.org/zeruth/runeliteplus-ps) [![Discord](https://img.shields.io/discord/373382904769675265.svg)](https://discord.gg/HN5gf3m) -[RuneLitePlus](https://runelitepl.us) is a fork of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying open source. This is meant to directly compete with 3rd party RL clients that are trying to sell their code. +[RuneLitePlus-PS](https://runelitepl.us) is a fork of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying open source. This is a specific version meant for rs-mod which can be found here: +https://www.rune-server.ee/runescape-development/rs2-server/downloads/684206-180-rs-mod-release.html -## Project Layout +## Usage -- [cache](cache/src/main/java/net/runelite/cache) - Libraries used for reading/writing cache files, as well as the data in it -- [http-api](http-api/src/main/java/net/runelite/http/api) - API for api.runelite.net -- [http-service](http-service/src/main/java/net/runelite/http/service) - Service for api.runelite.net -- [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client -- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the injected client's classes -- [runescape-api](runescape-api/src/main/java/net/runelite) - Mappings correspond to these interfaces, runelite-api is a subset of this -- [runelite-client](runelite-client/src/main/java/net/runelite/client) - Game client with plugins +By default, this connects to our sandbox server, which is for client testing. + +To setup your rsa keys, navigate to runelite-mixins and go to RSBufferMixin and set modulus and exponent +To setup your codebase, navigate to runelite-client/rs and go to Launcher and set codebase = new URL("http://IP_OR_URL_HERE/"); + +After that it's ran much like RuneLite or RuneLitePlus, install then run RuneLite.main() + +To release the built jar publicly, you'd have to host your injected client remotely and make some small modifications to rs.ClientLoader ## License -RuneLitePlus is licensed under the BSD 2-clause license. See the license header in the respective file to be sure. +RuneLitePlus-PS is licensed under the BSD 2-clause license. See the license header in the respective file to be sure. ## Contribute and Develop From 572d5905866e2d54a9c847ed04d99f518a52ecda Mon Sep 17 00:00:00 2001 From: zeruth Date: Tue, 25 Jun 2019 00:32:15 -0400 Subject: [PATCH 20/63] fix rsps stuff --- params.txt | 24 +++ .../net/runelite/client/rs/ClientLoader.java | 2 +- .../net/runelite/client/rs/RSAppletStub.java | 147 +++++++++++++----- .../net/runelite/mixins/RSBufferMixin.java | 53 +++++++ .../net/runelite/mixins/RSGameShellMixin.java | 8 + 5 files changed, 191 insertions(+), 43 deletions(-) create mode 100644 params.txt create mode 100644 runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java diff --git a/params.txt b/params.txt new file mode 100644 index 0000000000..5de07bea64 --- /dev/null +++ b/params.txt @@ -0,0 +1,24 @@ +Created at Thu Jun 20 05:35:31 CDT 2019 + +codebase=http://oldschool6b.runescape.com/ +mainclass=client.class + +param=1=1 +param=2=https://payments.jagex.com/operator/v1/ +param=3=true +param=4=761 +param=5=1 +param=6=0 +param=7=0 +param=8=true +param=9=ElZAIrq5NpKN6D3mDdihco3oPeYN2KFy2DCquj7JMmECPmLrDP3Bnw +param=10=5 +param=11=https://auth.jagex.com/ +param=12=306 +param=13=.runescape.com +param=14=0 +param=15=0 +param=16=false +param=17=http://www.runescape.com/g=oldscape/slr.ws?order=LPWM +param=18= +param=19=196515767263-1oo20deqm6edn7ujlihl6rpadk9drhva.apps.googleusercontent.com diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 058336e738..175b5e9a5b 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -108,7 +108,7 @@ public class ClientLoader private static Applet loadFromClass(final RSConfig config, final Class clientClass) throws IllegalAccessException, InstantiationException { final Applet rs = (Applet) clientClass.newInstance(); - rs.setStub(new RSAppletStub(config)); + rs.setStub(new RSAppletStub()); return rs; } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java index a3a2a0f14a..df3fce8e0e 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java @@ -1,70 +1,133 @@ -/* - * Copyright (c) 2016-2017, Adam - * Copyright (c) 2018, Tomas Slusny - * 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.rs; import java.applet.AppletContext; import java.applet.AppletStub; -import java.net.MalformedURLException; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.net.URL; -import lombok.RequiredArgsConstructor; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; -@RequiredArgsConstructor -class RSAppletStub implements AppletStub +public class RSAppletStub implements AppletStub { - private final RSConfig config; + + public static final Logger logger = Logger.getLogger(RSAppletStub.class.getSimpleName()); + + private static final HashMap params = new HashMap(); + private static final HashMap cfg = new HashMap(); + private static URL codebase; + + static + { + cfg.put("privacyurl", "http://www.jagex.com/g=oldscape/privacy/privacy.ws"); + cfg.put("window_preferredheight", "600"); + cfg.put("msg", "new_version_link=http://oldschool.runescape.com/"); + cfg.put("applet_minwidth", "765"); + cfg.put("adverturl", "http://www.runescape.com/g=oldscape/bare_advert.ws"); + cfg.put("cachedir", "oldschool"); + cfg.put("window_preferredwidth", "800"); + cfg.put("applet_maxheight", "2160"); + cfg.put("win_sub_version", "1"); + cfg.put("browsercontrol_win_x86_jar", "browsercontrol_0_-1928975093.jar"); + cfg.put("other_sub_version", "2"); + cfg.put("initial_jar", "gamepack_4840368.jar"); + cfg.put("advert_height", "96"); + cfg.put("title", "Old School RuneScape"); + cfg.put("storebase", "0"); + cfg.put("initial_class", "client.class"); + cfg.put("applet_maxwidth", "5760"); + cfg.put("download", "1230228"); + cfg.put("termsurl", "http://www.jagex.com/g=oldscape/terms/terms.ws"); + cfg.put("codebase", "http://oldschool1.runescape.com/"); + cfg.put("mac_sub_version", "2"); + cfg.put("browsercontrol_win_amd64_jar", "browsercontrol_1_1674545273.jar"); + cfg.put("applet_minheight", "503"); + cfg.put("viewerversion", "124"); + } + + public RSAppletStub() + { + try + { + parseParams(new FileInputStream(new File("./params.txt"))); + String worldListKey = null; + for (Map.Entry paramEntry : params.entrySet()) + { + String key = paramEntry.getKey(); + String value = paramEntry.getValue(); + if (value.contains("slr.ws")) + { + worldListKey = key; + break; + } + } + codebase = new URL("http://runeliteplus-ps.ddns.net"); //host + params.put(worldListKey, "http://" + codebase.getHost()); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + private static void parseParams(InputStream stream) throws IOException + { + BufferedReader br = new BufferedReader(new InputStreamReader(stream)); + String line; + while ((line = br.readLine()) != null) + { + int idx = line.indexOf('='); + if (idx != -1) + { + String key = line.substring(0, idx); + String val = line.substring(idx + 1); + if (key.equals("param")) + { + idx = val.indexOf('='); + key = val.substring(0, idx); + val = val.substring(idx + 1); + params.put(key, val); + } + else + { + cfg.put(key, val); + } + } + } + } + + public static void log(String format, Object... params) + { + System.out.printf(format + "\n", params); + } @Override public boolean isActive() { - return true; + return false; } @Override public URL getDocumentBase() { - return getCodeBase(); + return codebase; } @Override public URL getCodeBase() { - try - { - return new URL(config.getCodeBase()); - } - catch (MalformedURLException ex) - { - return null; - } + return codebase; } @Override public String getParameter(String name) { - return config.getAppletProperties().get(name); + return params.get(name); } @Override @@ -77,4 +140,4 @@ class RSAppletStub implements AppletStub public void appletResize(int width, int height) { } -} \ No newline at end of file +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java new file mode 100644 index 0000000000..e37dadc241 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Null (zeruth) + * 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.mixins; + +import java.math.BigInteger; +import net.runelite.api.mixins.Copy; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; +import net.runelite.rs.api.RSBuffer; + +@Mixin(RSBuffer.class) +public abstract class RSBufferMixin implements RSBuffer +{ + @Inject + private static BigInteger modulus = new BigInteger("10001", 16); + + @Inject + private static BigInteger exponent = new BigInteger("bb5d826b249905895f4e463422dd339f8375ed5b212ac8890a97e4ab7dba0c5fe8188f44c00f8106e5721f615a8bcee2da7316ff1572cad5fbfd33f30985f0ae855cfd498483ecc0c3a01c8630f90cff1f54e75a44d58482c371e203e6eb7ba879fd65949aeef827a5e550429bd857d712f64351bc1162e1615ca6622a3bc9b8e31a96000fb0a01a12a51ca3e89918c06759d1db65c33dc6a074abec02f94466886d1a52e7d084aa88338aab1f25d58f9e03ed0a308c6c4eed139c1c1c818cd2370d8cd28ec34bce18360d1756e202eb733f998200242d71ce19548f23b03c1eac4d6e9892616ade1c66d2ce3ab69744e27d7099f3574bcd3d3e95e7a52180d9", 16); + + @Copy("encryptRsa") + public void rs$encryptRsa(BigInteger var1, BigInteger var2) + { + } + + @Replace("encryptRsa") + public void rl$encryptRsa(BigInteger var1, BigInteger var2) + { + rs$encryptRsa(modulus, exponent); + } +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java index e45d2612e7..93f389345a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java @@ -31,6 +31,7 @@ import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSGameShell; @@ -97,4 +98,11 @@ public abstract class RSGameShellMixin implements RSGameShell setResizeCanvasNextFrame(true); } } + + @Replace("checkHost") + protected final boolean checkHost() + { + //Always allow host. + return true; + } } From 901b224d0a2bcfdcbc011a7c2c7f76edc8ea2d0d Mon Sep 17 00:00:00 2001 From: zeruth Date: Tue, 25 Jun 2019 00:35:01 -0400 Subject: [PATCH 21/63] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92ba3ce985..cc2e8bd2b6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ https://www.rune-server.ee/runescape-development/rs2-server/downloads/684206-180 By default, this connects to our sandbox server, which is for client testing. To setup your rsa keys, navigate to runelite-mixins and go to RSBufferMixin and set modulus and exponent -To setup your codebase, navigate to runelite-client/rs and go to Launcher and set codebase = new URL("http://IP_OR_URL_HERE/"); +To setup your codebase, navigate to runelite-client/rs and go to RSAppletStub and set codebase = new URL("http://IP_OR_URL_HERE/"); After that it's ran much like RuneLite or RuneLitePlus, install then run RuneLite.main() From c1d0d69d8d8e03ea08a59832bd27a02133aab363 Mon Sep 17 00:00:00 2001 From: zeruth Date: Tue, 25 Jun 2019 00:43:17 -0400 Subject: [PATCH 22/63] Update ClientLoader.java no need for -rs=CUSTOM --- .../main/java/net/runelite/client/rs/ClientLoader.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 175b5e9a5b..a56a7b3a3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -60,14 +60,8 @@ public class ClientLoader switch (updateCheckMode) { - case AUTO: - case CUSTOM: - return loadRLPlus(config); default: - case VANILLA: - return loadVanilla(config); - case NONE: - return null; + return loadRLPlus(config); } } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) From ecdfb819c1ac89a0d6e2ad3c542d0bcd00a8e0a3 Mon Sep 17 00:00:00 2001 From: Twiglet1022 <29353990+Twiglet1022@users.noreply.github.com> Date: Sun, 16 Jun 2019 11:58:08 +0100 Subject: [PATCH 23/63] mining plugin: only show timers on same level in motherlode mine --- .../client/plugins/mining/MiningOverlay.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java index 62cc7c4d77..9442470c16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java @@ -48,6 +48,7 @@ class MiningOverlay extends Overlay private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90; private static final float ORE_VEIN_RANDOM_PERCENT_THRESHOLD = (float) ORE_VEIN_MIN_RESPAWN_TIME / ORE_VEIN_MAX_RESPAWN_TIME; private static final Color DARK_GREEN = new Color(0, 100, 0); + private static final int MOTHERLODE_UPPER_FLOOR_HEIGHT = -500; private final Client client; private final MiningPlugin plugin; @@ -92,8 +93,17 @@ class MiningOverlay extends Overlay continue; } + Rock rock = rockRespawn.getRock(); + + // Only draw timer for veins on the same level in motherlode mine + LocalPoint localLocation = client.getLocalPlayer().getLocalLocation(); + if (rock == Rock.ORE_VEIN && isUpstairsMotherlode(localLocation) != isUpstairsMotherlode(loc)) + { + continue; + } + // Recolour pie on motherlode veins during the portion of the timer where they may respawn - if (rockRespawn.getRock() == Rock.ORE_VEIN && percent > ORE_VEIN_RANDOM_PERCENT_THRESHOLD) + if (rock == Rock.ORE_VEIN && percent > ORE_VEIN_RANDOM_PERCENT_THRESHOLD) { pieFillColor = Color.GREEN; pieBorderColor = DARK_GREEN; @@ -108,4 +118,19 @@ class MiningOverlay extends Overlay } return null; } + + /** + * Checks if the given point is "upstairs" in the mlm. + * The upper floor is actually on z=0. + * + * This method assumes that the given point is already in the mlm + * and is not meaningful when outside the mlm. + * + * @param localPoint the LocalPoint to be tested + * @return true if localPoint is at same height as mlm upper floor + */ + private boolean isUpstairsMotherlode(LocalPoint localPoint) + { + return Perspective.getTileHeight(client, localPoint, 0) < MOTHERLODE_UPPER_FLOOR_HEIGHT; + } } From 5a96398b34d73ded195f4738a9a540845e5209af Mon Sep 17 00:00:00 2001 From: Rice Boxer Date: Thu, 27 Jun 2019 21:15:18 -0700 Subject: [PATCH 24/63] Fix Father Jean's coordinates in easy cryptic clue --- .../runelite/client/plugins/cluescrolls/clues/CrypticClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index ca75bf4ca8..125ed56687 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -80,7 +80,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Speak to the bartender of the Blue Moon Inn in Varrock.", "Bartender", new WorldPoint(3226, 3399, 0), "Talk to the bartender in Blue Moon Inn in Varrock."), new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2846, 1749, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), new CrypticClue("Search the crates in the shed just north of East Ardougne.", CRATE_355, new WorldPoint(2617, 3347, 0), "The crates in the shed north of the northern Ardougne bank."), - new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1697, 3574, 0), "Talk to father Jean in the Hosidius church"), + new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1734, 3576, 0), "Talk to father Jean in the Hosidius church"), new CrypticClue("Search the crate in the Toad and Chicken pub.", CRATE_354, new WorldPoint(2913, 3536, 0), "The Toad and Chicken pub is located in Burthorpe."), new CrypticClue("Search chests found in the upstairs of shops in Port Sarim.", CLOSED_CHEST_375, new WorldPoint(3016, 3205, 1), "Search the chest in the upstairs of Wydin's Food Store, on the east wall."), new CrypticClue("Right on the blessed border, cursed by the evil ones. On the spot inaccessible by both; I will be waiting. The bugs' imminent possession holds the answer.", new WorldPoint(3410, 3324, 0), "B I P. Dig right under the fairy ring."), From 1a7aa4666bdac7d9f35a9d4a090c313c35c3a1e0 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Thu, 27 Jun 2019 22:43:44 -0700 Subject: [PATCH 25/63] npc indicators: Fix long respawn timer bug By killing a monster which has a known respawn timer and leaving its respawn area (by walking away or teleporting) and returning to it some time after it has respawned, the plugin can erroneously overwrite its respawn time with a much longer one. This commit fixes that issue by assuming that the lower of the observed respawn time and the previously recorded respawn time is the correct one. --- .../plugins/npchighlight/NpcIndicatorsPlugin.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java index 183272586d..5bb9eb357d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java @@ -548,7 +548,16 @@ public class NpcIndicatorsPlugin extends Plugin if (mn.getDiedOnTick() != -1) { - mn.setRespawnTime(client.getTickCount() + 1 - mn.getDiedOnTick()); + final int respawnTime = client.getTickCount() + 1 - mn.getDiedOnTick(); + + // By killing a monster and leaving the area before seeing it again, an erroneously lengthy + // respawn time can be recorded. Thus, if the respawn time is already set and is greater than + // the observed time, assume that the lower observed respawn time is correct. + if (mn.getRespawnTime() == -1 || respawnTime < mn.getRespawnTime()) + { + mn.setRespawnTime(respawnTime); + } + mn.setDiedOnTick(-1); } From bb4da0b822ea82a04b428755af2072f80ab250fd Mon Sep 17 00:00:00 2001 From: psikoi Date: Sat, 29 Jun 2019 11:47:00 +0100 Subject: [PATCH 26/63] Add ENTER/ESC key events for screenmarker saving --- .../screenmarkers/ui/ScreenMarkerPanel.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index d225410209..b0270ba49d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -29,6 +29,8 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; @@ -169,12 +171,7 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - marker.getMarker().setName(nameInput.getText()); - plugin.updateConfig(); - - nameInput.setEditable(false); - updateNameActions(false); - requestFocusInWindow(); + save(); } @Override @@ -198,10 +195,7 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - nameInput.setEditable(false); - nameInput.setText(marker.getMarker().getName()); - updateNameActions(false); - requestFocusInWindow(); + cancel(); } @Override @@ -252,6 +246,21 @@ class ScreenMarkerPanel extends JPanel nameInput.setPreferredSize(new Dimension(0, 24)); nameInput.getTextField().setForeground(Color.WHITE); nameInput.getTextField().setBorder(new EmptyBorder(0, 8, 0, 0)); + nameInput.addKeyListener(new KeyAdapter() + { + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ENTER) + { + save(); + } + else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) + { + cancel(); + } + } + }); nameWrapper.add(nameInput, BorderLayout.CENTER); nameWrapper.add(nameActions, BorderLayout.EAST); @@ -424,6 +433,24 @@ class ScreenMarkerPanel extends JPanel } + private void save() + { + marker.getMarker().setName(nameInput.getText()); + plugin.updateConfig(); + + nameInput.setEditable(false); + updateNameActions(false); + requestFocusInWindow(); + } + + private void cancel() + { + nameInput.setEditable(false); + nameInput.setText(marker.getMarker().getName()); + updateNameActions(false); + requestFocusInWindow(); + } + private void updateNameActions(boolean saveAndCancel) { save.setVisible(saveAndCancel); From f6f66b6be32375d116888a32d4e7a4399ce04137 Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sat, 29 Jun 2019 18:06:14 -0400 Subject: [PATCH 27/63] rsclientmixin: make use of edited menuentryclicked event variables --- .../src/main/java/net/runelite/mixins/RSClientMixin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 069c9a99d4..a08bcaf36a 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1264,7 +1264,8 @@ public abstract class RSClientMixin implements RSClient return; } - rs$menuAction(actionParam, widgetId, menuAction, id, menuOption, menuTarget, var6, var7); + rs$menuAction(menuOptionClicked.getActionParam0(), menuOptionClicked.getActionParam1(), menuOptionClicked.getType(), + menuOptionClicked.getIdentifier(), menuOptionClicked.getOption(), menuOptionClicked.getTarget(), var6, var7); } @FieldHook("Login_username") From 32a95a679859bb6ee5d6224ecb2f681b29518cd0 Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sat, 29 Jun 2019 18:13:44 -0400 Subject: [PATCH 28/63] menumanager: fix priority entry and performance improvements --- .../runelite/client/menus/MenuManager.java | 242 ++++++++---------- 1 file changed, 106 insertions(+), 136 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 6c674c1d14..58200d407e 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -27,10 +27,12 @@ package net.runelite.client.menus; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -39,12 +41,10 @@ import java.util.Set; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MenuAction; -import static net.runelite.api.MenuAction.GAME_OBJECT_FIRST_OPTION; -import static net.runelite.api.MenuAction.WIDGET_DEFAULT; +import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; import net.runelite.api.events.ClientTick; @@ -97,7 +97,7 @@ public class MenuManager private final Set hiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); - private EntryTypeMapping originalType; + private MenuEntry leftClickEntry; @Inject private MenuManager(Client client, EventBus eventBus) @@ -170,109 +170,128 @@ public class MenuManager @Subscribe private void onClientTick(ClientTick event) { - originalType = null; + leftClickEntry = null; + + if (client.isMenuOpen()) + { + return; + } + currentPriorityEntries.clear(); client.sortMenuEntries(); MenuEntry[] oldEntries = client.getMenuEntries(); List newEntries = Lists.newArrayList(oldEntries); - for (MenuEntry entry : oldEntries) + boolean shouldDeprioritize = false; + boolean modified = false; + + + prioritizer: for (MenuEntry entry : oldEntries) { - for (ComparableEntry p : priorityEntries) - { - if (p.matches(entry)) - { - currentPriorityEntries.add(entry); - } - } - - // If there are entries we want to prioritize, we have to remove the rest - if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen()) - { - newEntries.retainAll(currentPriorityEntries); - - // This is because players existing changes walk-here target - // so without this we lose track of em - if (newEntries.size() != currentPriorityEntries.size()) - { - for (MenuEntry e : currentPriorityEntries) - { - if (newEntries.contains(e)) - { - continue; - } - - for (MenuEntry e2 : client.getMenuEntries()) - { - if (e.getType() == e2.getType()) - { - e.setTarget(e2.getTarget()); - newEntries.add(e); - } - } - } - } - } - - boolean isHidden = false; + // Remove hidden entries from menus for (ComparableEntry p : hiddenEntries) { if (p.matches(entry)) { - isHidden = true; - break; + newEntries.remove(entry); + continue prioritizer; } } - if (isHidden) + for (ComparableEntry p : priorityEntries) { - newEntries.remove(entry); - } - } - - if (!currentPriorityEntries.isEmpty() && !client.isMenuOpen()) - { - newEntries.add(0, CANCEL()); - } - - MenuEntry leftClickEntry = newEntries.get(newEntries.size() - 1); - - for (ComparableEntry src : swaps.keySet()) - { - if (!src.matches(leftClickEntry)) - { - continue; - } - - ComparableEntry tgt = swaps.get(src); - - for (int i = newEntries.size() - 2; i > 0; i--) - { - MenuEntry e = newEntries.get(i); - - if (tgt.matches(e)) + // Create list of priority entries, and remove from menus + if (p.matches(entry)) { - newEntries.set(newEntries.size() - 1, e); - newEntries.set(i, leftClickEntry); - - int type = e.getType(); - - if (type >= 1000) + // Other entries need to be deprioritized if their types are lower than 1000 + if (entry.getType() >= 1000 && !shouldDeprioritize) { - int newType = getLeftClickType(type); - if (newType != -1 && newType != type) - { - MenuEntry original = MenuEntry.copy(e); - e.setType(newType); - originalType = new EntryTypeMapping(new ComparableEntry(leftClickEntry), original); - } + shouldDeprioritize = true; + } + currentPriorityEntries.add(entry); + newEntries.remove(entry); + continue prioritizer; + } + } + } + + if (newEntries.size() > 0) + { + MenuEntry entry = Iterables.getLast(newEntries); + + // Swap first matching entry to top + for (ComparableEntry src : swaps.keySet()) + { + if (!src.matches(entry)) + { + continue; + } + + MenuEntry swapFrom = null; + + ComparableEntry from = swaps.get(src); + + for (MenuEntry e : newEntries) + { + if (from.matches(e)) + { + swapFrom = e; + break; + } + } + + // Do not need to swap with itself + if (swapFrom != null && swapFrom != entry) + { + // Deprioritize entries if the swaps are not in similar type groups + if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + { + shouldDeprioritize = true; } + int indexFrom = newEntries.indexOf(swapFrom); + int indexTo = newEntries.indexOf(entry); + + Collections.swap(newEntries, indexFrom, indexTo); + + // Set force left click if entry was moved to first entry + if (indexTo == newEntries.size() - 1) + { + swapFrom.setForceLeftClick(true); + entry.setForceLeftClick(false); + } + + modified = true; + + // If this loop is placed in the 'prioritizer' block and the following break is removed, + // all swaps will be applied instead of only swapping the first one found to the first entry break; } } } + + if (shouldDeprioritize) + { + for (MenuEntry entry : newEntries) + { + if (entry.getType() <= MENU_ACTION_DEPRIORITIZE_OFFSET) + { + entry.setType(entry.getType() + MENU_ACTION_DEPRIORITIZE_OFFSET); + } + } + } + + if (!priorityEntries.isEmpty()) + { + newEntries.addAll(currentPriorityEntries); + modified = true; + } + + if (modified) + { + leftClickEntry = newEntries.get(newEntries.size() - 1); + } client.setMenuEntries(newEntries.toArray(new MenuEntry[0])); } @@ -338,24 +357,6 @@ public class MenuManager } } - private int getLeftClickType(int oldType) - { - if (oldType > 2000) - { - oldType -= 2000; - } - - switch (MenuAction.of(oldType)) - { - case GAME_OBJECT_FIFTH_OPTION: - return GAME_OBJECT_FIRST_OPTION.getId(); - case EXAMINE_ITEM_BANK_EQ: - return WIDGET_DEFAULT.getId(); - default: - return oldType; - } - } - private void addNpcOption(NPCDefinition composition, String npcOption) { String[] actions = composition.getActions(); @@ -399,21 +400,10 @@ public class MenuManager @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - // Type is changed in check - if (originalType != null && originalType.check(event)) + if (leftClickEntry != null) { - event.consume(); - - client.invokeMenuAction( - event.getActionParam0(), - event.getActionParam1(), - event.getType(), - event.getIdentifier(), - "do not edit", - event.getTarget(), - client.getMouseCanvasPosition().getX(), - client.getMouseCanvasPosition().getY() - ); + event.setMenuEntry(leftClickEntry); + leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) @@ -739,24 +729,4 @@ public class MenuManager { hiddenEntries.remove(entry); } - - @AllArgsConstructor - private class EntryTypeMapping - { - private final ComparableEntry comparable; - private final MenuEntry target; - - private boolean check(MenuOptionClicked event) - { - MenuEntry entry = event.getMenuEntry(); - - if (event.getTarget().equals("do not edit") || !comparable.matches(entry)) - { - return false; - } - - event.setMenuEntry(target); - return true; - } - } } From 83d2a7e58b6db30879eafa9c2e3c57aca05abeaa Mon Sep 17 00:00:00 2001 From: William Collishaw Date: Sun, 30 Jun 2019 10:17:03 -0600 Subject: [PATCH 29/63] Clean up some instances of double white space --- .../java/net/runelite/cache/item/SpritePixels.java | 2 +- .../test/java/net/runelite/cache/AreaDumper.java | 2 +- .../net/runelite/client/game/AgilityShortcut.java | 4 ++-- .../plugins/cluescrolls/clues/CrypticClue.java | 10 +++++----- .../plugins/interfacestyles/WidgetOverride.java | 6 +++--- .../menuentryswapper/MenuEntrySwapperConfig.java | 2 +- .../menuentryswapper/MenuEntrySwapperPlugin.java | 2 +- .../plugins/nightmarezone/AbsorptionCounter.java | 2 +- .../net/runelite/client/plugins/poh/PohPlugin.java | 2 +- .../puzzlesolver/solver/pathfinding/IDAStarMM.java | 4 ++-- .../client/plugins/statusbars/Viewport.java | 4 ++-- .../plugins/worldhopper/WorldHopperPlugin.java | 2 +- .../plugins/worldmap/TeleportLocationData.java | 14 +++++++------- .../ui/overlay/components/PanelComponent.java | 2 +- .../net/runelite/mixins/WorldHoppingMixin.java | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/item/SpritePixels.java b/cache/src/main/java/net/runelite/cache/item/SpritePixels.java index 02079847f7..8bfada5bc2 100644 --- a/cache/src/main/java/net/runelite/cache/item/SpritePixels.java +++ b/cache/src/main/java/net/runelite/cache/item/SpritePixels.java @@ -108,7 +108,7 @@ class SpritePixels } - public void drawAtOn(Rasterizer2D graphics, int x, int y) + public void drawAtOn(Rasterizer2D graphics, int x, int y) { x += this.offsetX; y += this.offsetY; diff --git a/cache/src/test/java/net/runelite/cache/AreaDumper.java b/cache/src/test/java/net/runelite/cache/AreaDumper.java index 2aab1db48b..0b276fcce1 100644 --- a/cache/src/test/java/net/runelite/cache/AreaDumper.java +++ b/cache/src/test/java/net/runelite/cache/AreaDumper.java @@ -64,7 +64,7 @@ public class AreaDumper for (AreaDefinition area : areaManager.getAreas()) { - Files.asCharSink(new File(outDir, area.id + ".json"), Charset.defaultCharset()).write(gson.toJson(area)); + Files.asCharSink(new File(outDir, area.id + ".json"), Charset.defaultCharset()).write(gson.toJson(area)); ++count; } } diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index dcee1e6acd..8e10ac081c 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -84,7 +84,7 @@ public enum AgilityShortcut GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP), CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809), EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566), - TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 + TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL), YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056), COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274), @@ -128,7 +128,7 @@ public enum AgilityShortcut DEEP_WILDERNESS_DUNGEON_CREVICE_SOUTH(46, "Narrow Crevice", new WorldPoint(3045, 10327, 0), CREVICE_19043), TROLLHEIM_HARD_CLIFF_SCRAMBLE(47, "Rocks", new WorldPoint(2902, 3680, 0), ROCKS_16524), FREMENNIK_LOG_BALANCE(48, "Log Balance", new WorldPoint(2721, 3591, 0), LOG_BALANCE_16540, LOG_BALANCE_16541, LOG_BALANCE_16542), - YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140), + YANILLE_DUNGEON_PIPE_SQUEEZE(49, "Pipe Squeeze", null, OBSTACLE_PIPE_23140), ARCEUUS_ESSENCE_MINE_BOULDER(49, "Boulder", new WorldPoint(1774, 3888, 0), BOULDER_27990), MORYTANIA_STEPPING_STONE(50, "Stepping Stone", new WorldPoint(3418, 3326, 0), STEPPING_STONE_13504), VARROCK_SEWERS_PIPE_SQUEEZE(51, "Pipe Squeeze", new WorldPoint(3152, 9905, 0), OBSTACLE_PIPE_16511), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index ca75bf4ca8..403801b343 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -196,9 +196,9 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Search a bookcase in Lumbridge swamp.", BOOKCASE_9523, new WorldPoint(3146, 3177, 0), "Located in Father Urhney's house."), new CrypticClue("Surround my bones in fire, ontop the wooden pyre. Finally lay me to rest, before my one last test.", null, "Kill a confused/lost barbarian to receive mangled bones. Construct and burn a pyre ship. Kill the ferocious barbarian spirit that spawns to receive a clue casket."), new CrypticClue("Fiendish cooks probably won't dig the dirty dishes.", new WorldPoint(3043, 4974, 1), "Dig by the fire in the Rogues' Den."), - new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."), + new CrypticClue("My life was spared but these voices remain, now guarding these iron gates is my bane.", "Key Master", new WorldPoint(1310, 1251, 0), "Speak to the Key Master in Cerberus' Lair."), new CrypticClue("Search the boxes in one of the tents in Al Kharid.", BOXES_361, new WorldPoint(3308, 3206, 0), "Search the boxes in the tent east of the Silk trader."), - new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."), + new CrypticClue("One of several rhyming brothers, in business attire with an obsession for paper work.", "Piles", new WorldPoint(3186, 3936, 0), "Speak to Piles in the Wilderness Resource Area. An entry fee of 7,500 coins is required, or less if Wilderness Diaries have been completed."), new CrypticClue("Search the drawers on the first floor of a building overlooking Ardougne's Market.", DRAWERS_352, new WorldPoint(2657, 3322, 1), "Climb the ladder in the house north of the market."), new CrypticClue("'A bag belt only?', he asked his balding brothers.", "Abbot Langley", new WorldPoint(3058, 3487, 0), "Talk-to Abbot Langley in Monastery west of Edgeville"), new CrypticClue("Search the drawers upstairs in Falador's shield shop.", DRAWERS, new WorldPoint(2971, 3386, 1), "Cassie's Shield Shop at the northern Falador entrance."), @@ -276,7 +276,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Ghommal wishes to be impressed by how strong your equipment is.", "Ghommal", new WorldPoint(2878, 3546, 0), "Speak to Ghommal at the Warriors' Guild with a total Melee Strength bonus of over 100."), new CrypticClue("Shhhh!", "Logosia", new WorldPoint(1633, 3808, 0), "Speak to Logosia in the Arceuus Library's ground floor."), new CrypticClue("Salty peter.", "Konoo", new WorldPoint(1703, 3524, 0), "Talk to Konoo who is digging saltpetre in Hosidius, south of the bank."), - new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."), + new CrypticClue("Talk to Zeke in Al Kharid.", "Zeke", new WorldPoint(3287, 3190, 0), "Zeke is the owner of the scimitar shop in Al Kharid."), new CrypticClue("Guthix left his mark in a fiery lake, dig at the tip of it.", new WorldPoint(3069, 3935, 0), "Dig at the tip of the lava lake that is shaped like a Guthixian symbol, west of the Mage Arena."), new CrypticClue("Search the drawers in the upstairs of a house in Catherby.", DRAWERS_350, new WorldPoint(2809, 3451, 1), "Perdu's house in Catherby."), new CrypticClue("Search a crate in the Haymaker's arms.", CRATE_27532, new WorldPoint(1720, 3652, 1), "Search the crate in the north-east corner of The Haymaker's Arms tavern east of Kourend Castle."), @@ -294,9 +294,9 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Dig in the centre of a great kingdom of 5 cities.", new WorldPoint(1639, 3673, 0), "Dig in front of the large statue in the centre of Great Kourend."), new CrypticClue("Hopefully this set of armour will help you to keep surviving.", "Sir Vyvin", new WorldPoint(2982, 3336, 2), "Speak to Sir Vyvin while wearing a white platebody, and platelegs."), new CrypticClue("The beasts retreat, for their Queen is gone; the song of this town still plays on. Dig near the birthplace of a blade, be careful not to melt your spade.", new WorldPoint(2342, 3677, 0), "Dig in front of the small furnace in the Piscatoris Fishing Colony."), - new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."), + new CrypticClue("Darkness wanders around me, but fills my mind with knowledge.", "Biblia", new WorldPoint(1633, 3825, 2), "Speak to Biblia on the Arceuus Library's top floor."), new CrypticClue("I would make a chemistry joke, but I'm afraid I wouldn't get a reaction.", "Chemist", new WorldPoint(2932, 3212, 0), "Talk to the Chemist in Rimmington"), - new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."), + new CrypticClue("Show this to Hazelmere.", "Hazelmere", new WorldPoint(2677, 3088, 1), "Hazelmere is found upstairs on the island located just east of Yanille."), new CrypticClue("Does one really need a fire to stay warm here?", new WorldPoint(3816, 3810, 0), "Dig next to the fire near the Volcanic Mine entrance."), new CrypticClue("Search the open crate found in the Hosidius kitchens.", CRATE_27533, new WorldPoint(1683, 3616, 0), "The kitchens are north-west of the town in Hosidius."), new CrypticClue("Dig under Ithoi's cabin.", new WorldPoint(2529, 2838, 0), "Dig under Ithoi's cabin in the Corsair Cove."), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOverride.java b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOverride.java index 46997704a5..1998fb3808 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOverride.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/WidgetOverride.java @@ -35,12 +35,12 @@ enum WidgetOverride FIXED_CORNER_TOP_LEFT_2005(Skin.AROUND_2005, "1026", WidgetInfo.FIXED_VIEWPORT_COMBAT_TAB), FIXED_CORNER_TOP_RIGHT_2005(Skin.AROUND_2005, "1027", WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB), FIXED_CORNER_BOTTOM_LEFT_2005(Skin.AROUND_2005, "1028", WidgetInfo.FIXED_VIEWPORT_CLAN_CHAT_TAB), - FIXED_CORNER_BOTTOM_RIGHT_2005(Skin.AROUND_2005, "1029", WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB), + FIXED_CORNER_BOTTOM_RIGHT_2005(Skin.AROUND_2005, "1029", WidgetInfo.FIXED_VIEWPORT_MUSIC_TAB), FIXED_TOP_LEFT_2005(Skin.AROUND_2005, "1030_top_left", WidgetInfo.FIXED_VIEWPORT_STATS_TAB, WidgetInfo.FIXED_VIEWPORT_QUESTS_TAB), - FIXED_TOP_RIGHT_2005(Skin.AROUND_2005, "1030_top_right", WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_TAB, WidgetInfo.FIXED_VIEWPORT_PRAYER_TAB), + FIXED_TOP_RIGHT_2005(Skin.AROUND_2005, "1030_top_right", WidgetInfo.FIXED_VIEWPORT_EQUIPMENT_TAB, WidgetInfo.FIXED_VIEWPORT_PRAYER_TAB), FIXED_TOP_MIDDLE_2005(Skin.AROUND_2005, "1030_top_middle", WidgetInfo.FIXED_VIEWPORT_INVENTORY_TAB), FIXED_BOTTOM_LEFT_2005(Skin.AROUND_2005, "1030_bottom_left", WidgetInfo.FIXED_VIEWPORT_FRIENDS_TAB, WidgetInfo.FIXED_VIEWPORT_IGNORES_TAB), - FIXED_BOTTOM_RIGHT_2005(Skin.AROUND_2005, "1030_bottom_middle", WidgetInfo.FIXED_VIEWPORT_LOGOUT_TAB), + FIXED_BOTTOM_RIGHT_2005(Skin.AROUND_2005, "1030_bottom_middle", WidgetInfo.FIXED_VIEWPORT_LOGOUT_TAB), FIXED_BOTTOM_MIDDLE_2005(Skin.AROUND_2005, "1030_bottom_right", WidgetInfo.FIXED_VIEWPORT_OPTIONS_TAB, WidgetInfo.FIXED_VIEWPORT_EMOTES_TAB); private Skin skin; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 58fc922c7b..8d9ee74b8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -165,7 +165,7 @@ public interface MenuEntrySwapperConfig extends Config @ConfigItem( keyName = "swapHardWoodGrove", name = "Hardwood Grove", - description = "Swap Quick-Pay(100) and Send-Parcel at Hardwood Grove" + description = "Swap Quick-Pay(100) and Send-Parcel at Hardwood Grove" ) default boolean swapHardWoodGrove() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 5ab6cb6aca..a443fe0800 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -362,7 +362,7 @@ public class MenuEntrySwapperPlugin extends Plugin final int eventId = event.getIdentifier(); final String option = Text.removeTags(event.getOption()).toLowerCase(); final String target = Text.removeTags(event.getTarget()).toLowerCase(); - final NPC hintArrowNpc = client.getHintArrowNpc(); + final NPC hintArrowNpc = client.getHintArrowNpc(); if (hintArrowNpc != null && hintArrowNpc.getIndex() == eventId diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java index 4671edde12..fffd16fe4a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/AbsorptionCounter.java @@ -39,7 +39,7 @@ public class AbsorptionCounter extends Counter AbsorptionCounter(BufferedImage image, Plugin plugin, int absorption, int threshold) { - super(image, plugin, absorption); + super(image, plugin, absorption); this.threshold = threshold; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java index 04df91d05c..be70c9689d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java @@ -80,7 +80,7 @@ public class PohPlugin extends Plugin private final Map pohObjects = new HashMap<>(); @Getter(AccessLevel.PACKAGE) - private final Map incenseBurners = new HashMap<>(); + private final Map incenseBurners = new HashMap<>(); @Inject private OverlayManager overlayManager; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/pathfinding/IDAStarMM.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/pathfinding/IDAStarMM.java index f96b6971bd..a869ee13c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/pathfinding/IDAStarMM.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/pathfinding/IDAStarMM.java @@ -90,7 +90,7 @@ public class IDAStarMM extends IDAStar if (valCurrent != valTarget) { - moveTowardsVal(valTarget, i, row, true); + moveTowardsVal(valTarget, i, row, true); } } } @@ -107,7 +107,7 @@ public class IDAStarMM extends IDAStar if (valCurrent != valTarget) { - moveTowardsVal(valTarget, column, i, false); + moveTowardsVal(valTarget, column, i, false); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/Viewport.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/Viewport.java index 737cda9df0..6161192c1d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/Viewport.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/Viewport.java @@ -34,9 +34,9 @@ import net.runelite.api.widgets.WidgetInfo; enum Viewport { RESIZED_BOX(WidgetInfo.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX, WidgetInfo.RESIZABLE_VIEWPORT_INTERFACE_CONTAINER, - new Point(20, -4), new Point( 0, -4)), + new Point(20, -4), new Point(0, -4)), RESIZED_BOTTOM(WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_INTERFACE_CONTAINER, - new Point(61, 8), new Point(35, -12)), + new Point(61, 8), new Point(35, -12)), FIXED(WidgetInfo.FIXED_VIEWPORT, WidgetInfo.FIXED_VIEWPORT_INTERFACE_CONTAINER, new Point(20, -4), new Point(0, -4)); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 84abfcf9f5..0dce1c78b5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -97,7 +97,7 @@ public class WorldHopperPlugin extends Plugin { private static final int WORLD_FETCH_TIMER = 10; private static final int WORLD_PING_TIMER = 10; - private static final int REFRESH_THROTTLE = 60_000; // ms + private static final int REFRESH_THROTTLE = 60_000; // ms private static final int TICK_THROTTLE = (int) Duration.ofMinutes(10).toMillis(); private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TeleportLocationData.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TeleportLocationData.java index ab2035ae74..520f48ec3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TeleportLocationData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/TeleportLocationData.java @@ -127,7 +127,7 @@ enum TeleportLocationData RELLEKKKA_LYRE(TeleportType.OTHER, "Enchanted Lyre", "Rellekka", new WorldPoint(2664, 3643, 0), "enchanted_lyre_teleport_icon.png"), WATERBIRTH_ISLAND_LYRE(TeleportType.OTHER, "Enchanted Lyre", "Waterbirth Island", new WorldPoint(2550, 3756, 0), "enchanted_lyre_teleport_icon.png"), NEITIZNOT_LYRE(TeleportType.OTHER, "Enchanted Lyre", "Neitiznot", new WorldPoint(2336, 3801, 0), "enchanted_lyre_teleport_icon.png"), - JATIZSO_LYRE(TeleportType.OTHER, "Enchanted Lyre", "Jatizso", new WorldPoint(2409, 3809, 0), "enchanted_lyre_teleport_icon.png"), + JATIZSO_LYRE(TeleportType.OTHER, "Enchanted Lyre", "Jatizso", new WorldPoint(2409, 3809, 0), "enchanted_lyre_teleport_icon.png"), WEISS_ICY_BASALT(TeleportType.OTHER, "Icy Basalt", "Weiss", new WorldPoint(2846, 3940, 0), "icy_basalt_teleport_icon.png"), TROLL_STRONGHOLD_STONY_BASALT(TeleportType.OTHER, "Stony Basalt", "Troll Stronghold", new WorldPoint(2838, 3693, 0), "stony_basalt_teleport_icon.png"), KHAREDSTS_MEMOIRS_HOSIDIUS(TeleportType.OTHER, "Kharedst's Memoirs", "Lunch by the Lancalliums (Hosidius)", new WorldPoint(1713, 3612, 0), "kharedsts_memoirs_teleport_icon.png"), @@ -151,19 +151,19 @@ enum TeleportLocationData // Achievement Diary ARDOUGNE_CLOAK_MONASTERY(TeleportType.OTHER, "Ardougne Cloak", "Monastery", new WorldPoint(2606, 3222, 0), "ardougne_cloak_icon.png"), ARDOUGNE_CLOAK_FARM(TeleportType.OTHER, "Ardougne Cloak", "Farm", new WorldPoint(2673, 3375, 0), "ardougne_cloak_icon.png"), - EXPLORERS_RING(TeleportType.OTHER, "Explorer's Ring", new WorldPoint(3052, 3292, 0), "explorers_ring_icon.png"), + EXPLORERS_RING(TeleportType.OTHER, "Explorer's Ring", new WorldPoint(3052, 3292, 0), "explorers_ring_icon.png"), KARAMJA_GLOVES_GEM_MINE(TeleportType.OTHER, "Karamja Gloves", "Gem Mine (Underground)", new WorldPoint(2827, 2997, 0), "karamja_gloves_icon.png"), KARAMJA_GLOVES_DURADEL(TeleportType.OTHER, "Karamja Gloves", "Duradel", new WorldPoint(2870, 2981, 0), "karamja_gloves_icon.png"), DESERT_AMULET_NARDAH(TeleportType.OTHER, "Desert Amulet", "Nardah", new WorldPoint(3432, 2914, 0), "desert_amulet_icon.png"), DESERT_AMULKT_KALPHITE_CAVE(TeleportType.OTHER, "Desert Amulet", "Kalphite Cave", new WorldPoint(3322, 3122, 0), "desert_amulet_icon.png"), MORYTANIA_LEGS_SLIME_PIT(TeleportType.OTHER, "Morytania Legs", "Slime Pit (Underground)", new WorldPoint(3654, 3516, 0), "morytania_legs_icon.png"), MORYTANIA_LEGS_BURGH_DE_ROTT(TeleportType.OTHER, "Morytania Legs", "Burgh de Rott", new WorldPoint(3482, 3231, 0), "morytania_legs_icon.png"), - FREMENNIK_SEA_BOOTS(TeleportType.OTHER, "Fremennik Sea Boots", new WorldPoint(2640, 3675, 0), "fremennik_boots_icon.png"), - KANDARIN_HEADGEAR(TeleportType.OTHER, "Kandarin Headgear", new WorldPoint(2729, 3411, 0), "kandarin_headgear_icon.png"), + FREMENNIK_SEA_BOOTS(TeleportType.OTHER, "Fremennik Sea Boots", new WorldPoint(2640, 3675, 0), "fremennik_boots_icon.png"), + KANDARIN_HEADGEAR(TeleportType.OTHER, "Kandarin Headgear", new WorldPoint(2729, 3411, 0), "kandarin_headgear_icon.png"), WILDERNESS_SWORD(TeleportType.OTHER, "Wilderness Sword", new WorldPoint(3377, 3891, 0), "wilderness_sword_icon.png"), - WESTERN_BANNER(TeleportType.OTHER, "Western Banner", new WorldPoint(2329, 3685, 0), "western_banner_icon.png"), - RADAS_BLESSING_MOUNT_KARUULM(TeleportType.OTHER, "Rada's Blessing", new WorldPoint(1311, 3795, 0), "radas_blessing_icon.png"), - RADAS_BLESSING_WOODLANG(TeleportType.OTHER, "Rada's Blessing", new WorldPoint(1553, 3454, 0), "radas_blessing_icon.png"), + WESTERN_BANNER(TeleportType.OTHER, "Western Banner", new WorldPoint(2329, 3685, 0), "western_banner_icon.png"), + RADAS_BLESSING_MOUNT_KARUULM(TeleportType.OTHER, "Rada's Blessing", new WorldPoint(1311, 3795, 0), "radas_blessing_icon.png"), + RADAS_BLESSING_WOODLANG(TeleportType.OTHER, "Rada's Blessing", new WorldPoint(1553, 3454, 0), "radas_blessing_icon.png"), // Scrolls DIGSITE_SCROLL(TeleportType.SCROLL, "Digsite Teleport", new WorldPoint(3324, 3412, 0), "scroll_teleport_icon.png"), diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java index 6baf20985e..0d81a5bf18 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java @@ -136,7 +136,7 @@ public class PanelComponent implements LayoutableRenderableEntity totalWidth = Math.max(totalWidth, width); totalHeight = Math.max(totalHeight, height); - if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0) + if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0) { switch (orientation) { diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java index 2cbc773b23..78778e3993 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java @@ -47,6 +47,6 @@ public abstract class WorldHoppingMixin implements RSClient public void hopToWorld(World world) { final int worldId = world.getId(); - menuAction(worldId, WidgetInfo.WORLD_SWITCHER_LIST.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "Switch", "" + (worldId - 300) + "", 683, 244); + menuAction(worldId, WidgetInfo.WORLD_SWITCHER_LIST.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "Switch", "" + (worldId - 300) + "", 683, 244); } } From f1bb04455e8a0d79da5a78a1e90118cc5f476754 Mon Sep 17 00:00:00 2001 From: Zeruth Date: Sun, 30 Jun 2019 14:18:24 -0400 Subject: [PATCH 30/63] Removes DefaultWorld plugin. Fixes bad session id when using a valid key --- .../defaultworld/DefaultWorldConfig.java | 43 ----- .../defaultworld/DefaultWorldPlugin.java | 158 ------------------ 2 files changed, 201 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java deleted file mode 100644 index 480d4c891d..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Tomas Slusny - * 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.defaultworld; - -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; - -@ConfigGroup("defaultworld") -public interface DefaultWorldConfig extends Config -{ - @ConfigItem( - keyName = "defaultWorld", - name = "Default world", - description = "World to use as default one" - ) - default int getWorld() - { - return 0; - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java deleted file mode 100644 index 96d5dfa246..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2018, Tomas Slusny - * 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.defaultworld; - -import com.google.inject.Provides; -import java.io.IOException; -import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; -import net.runelite.api.Client; -import net.runelite.api.GameState; -import net.runelite.api.events.GameStateChanged; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.SessionOpen; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.util.WorldUtil; -import net.runelite.http.api.worlds.World; -import net.runelite.http.api.worlds.WorldClient; -import net.runelite.http.api.worlds.WorldResult; - -@PluginDescriptor( - name = "Default World", - description = "Enable a default world to be selected when launching the client", - tags = {"home"} -) -@Slf4j -public class DefaultWorldPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private DefaultWorldConfig config; - - private final WorldClient worldClient = new WorldClient(); - private int worldCache; - private boolean worldChangeRequired; - - @Override - protected void startUp() throws Exception - { - worldChangeRequired = true; - applyWorld(); - } - - @Override - protected void shutDown() throws Exception - { - worldChangeRequired = true; - changeWorld(worldCache); - } - - @Provides - DefaultWorldConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(DefaultWorldConfig.class); - } - - @Subscribe - public void onSessionOpen(SessionOpen event) - { - worldChangeRequired = true; - applyWorld(); - } - - @Subscribe - public void onGameStateChanged(GameStateChanged event) - { - applyWorld(); - } - - private void changeWorld(int newWorld) - { - if (!worldChangeRequired || client.getGameState() != GameState.LOGIN_SCREEN) - { - return; - } - - worldChangeRequired = false; - int correctedWorld = newWorld < 300 ? newWorld + 300 : newWorld; - - // Old School RuneScape worlds start on 301 so don't even bother trying to find lower id ones - // and also do not try to set world if we are already on it - if (correctedWorld <= 300 || client.getWorld() == correctedWorld) - { - return; - } - - try - { - final WorldResult worldResult = worldClient.lookupWorlds(); - - if (worldResult == null) - { - return; - } - - final World world = worldResult.findWorld(correctedWorld); - - if (world != null) - { - final net.runelite.api.World rsWorld = client.createWorld(); - rsWorld.setActivity(world.getActivity()); - rsWorld.setAddress(world.getAddress()); - rsWorld.setId(world.getId()); - rsWorld.setPlayerCount(world.getPlayers()); - rsWorld.setLocation(world.getLocation()); - rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); - - client.changeWorld(rsWorld); - log.debug("Applied new world {}", correctedWorld); - } - else - { - log.warn("World {} not found.", correctedWorld); - } - } - catch (IOException e) - { - log.warn("Error looking up world {}. Error: {}", correctedWorld, e); - } - } - - private void applyWorld() - { - if (worldCache == 0) - { - worldCache = client.getWorld(); - log.debug("Stored old world {}", worldCache); - } - - final int newWorld = config.getWorld(); - changeWorld(newWorld); - } -} From d2cd11a786d94b9de958167c386c3f78f6836ffb Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sun, 30 Jun 2019 16:06:20 -0400 Subject: [PATCH 31/63] rsclientmixin: make use of edited menuopened event variables --- .../src/main/java/net/runelite/mixins/RSClientMixin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index a08bcaf36a..ee569abca0 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -1304,6 +1304,7 @@ public abstract class RSClientMixin implements RSClient final MenuOpened event = new MenuOpened(); event.setMenuEntries(getMenuEntries()); callbacks.post(event); + client.setMenuEntries(event.getMenuEntries()); } @Inject From 16c45f1020f82c9e554d55cc57952b737591deef Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Sun, 30 Jun 2019 16:10:13 -0400 Subject: [PATCH 32/63] menumanager: moved back to menuentryadded, also using menuopened --- .../runelite/client/menus/MenuManager.java | 217 +++++++++++------- 1 file changed, 134 insertions(+), 83 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 58200d407e..ddc0a5fe5d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -30,6 +30,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; + +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -47,8 +49,8 @@ import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; -import net.runelite.api.events.ClientTick; import net.runelite.api.events.MenuEntryAdded; +import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcActionChanged; import net.runelite.api.events.PlayerMenuOptionClicked; @@ -58,6 +60,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.Text; +import org.apache.commons.lang3.ArrayUtils; @Singleton @Slf4j @@ -97,7 +100,8 @@ public class MenuManager private final Set hiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); - private MenuEntry leftClickEntry; + private MenuEntry leftClickEntry = null; + private ComparableEntry comparableEntry = null; @Inject private MenuManager(Client client, EventBus eventBus) @@ -144,48 +148,18 @@ public class MenuManager } @Subscribe - public void onMenuEntryAdded(MenuEntryAdded event) - { - int widgetId = event.getActionParam1(); - Collection options = managedMenuOptions.get(widgetId); - MenuEntry[] menuEntries = client.getMenuEntries(); - - for (WidgetMenuOption currentMenu : options) - { - if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget - { - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); - } - } - } - - @Subscribe - private void onClientTick(ClientTick event) + public void onMenuOpened(MenuOpened event) { leftClickEntry = null; - if (client.isMenuOpen()) - { - return; - } - currentPriorityEntries.clear(); - client.sortMenuEntries(); - MenuEntry[] oldEntries = client.getMenuEntries(); + MenuEntry[] entries = client.getMenuEntries(); + + ArrayList oldEntries = Lists.newArrayList(entries); List newEntries = Lists.newArrayList(oldEntries); boolean shouldDeprioritize = false; - boolean modified = false; - prioritizer: for (MenuEntry entry : oldEntries) { @@ -214,63 +188,50 @@ public class MenuManager continue prioritizer; } } - } - if (newEntries.size() > 0) - { - MenuEntry entry = Iterables.getLast(newEntries); - - // Swap first matching entry to top - for (ComparableEntry src : swaps.keySet()) + if (newEntries.size() > 0) { - if (!src.matches(entry)) + MenuEntry last = Iterables.getLast(newEntries); + + // Swap first matching entry to top + for (ComparableEntry src : swaps.keySet()) { - continue; - } - - MenuEntry swapFrom = null; - - ComparableEntry from = swaps.get(src); - - for (MenuEntry e : newEntries) - { - if (from.matches(e)) + if (!src.matches(last)) { - swapFrom = e; - break; - } - } - - // Do not need to swap with itself - if (swapFrom != null && swapFrom != entry) - { - // Deprioritize entries if the swaps are not in similar type groups - if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) - { - shouldDeprioritize = true; + continue; } - int indexFrom = newEntries.indexOf(swapFrom); - int indexTo = newEntries.indexOf(entry); + MenuEntry swapFrom = null; - Collections.swap(newEntries, indexFrom, indexTo); + ComparableEntry from = swaps.get(src); - // Set force left click if entry was moved to first entry - if (indexTo == newEntries.size() - 1) + for (MenuEntry e : newEntries) { - swapFrom.setForceLeftClick(true); - entry.setForceLeftClick(false); + if (from.matches(e)) + { + swapFrom = e; + break; + } } - modified = true; + // Do not need to swap with itself + if (swapFrom != null && swapFrom != last) + { + // Deprioritize entries if the swaps are not in similar type groups + if ((swapFrom.getType() >= 1000 && last.getType() < 1000) || (last.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + { + shouldDeprioritize = true; + } - // If this loop is placed in the 'prioritizer' block and the following break is removed, - // all swaps will be applied instead of only swapping the first one found to the first entry - break; + int indexFrom = newEntries.indexOf(swapFrom); + int indexTo = newEntries.indexOf(last); + + Collections.swap(newEntries, indexFrom, indexTo); + } } } } - + if (shouldDeprioritize) { for (MenuEntry entry : newEntries) @@ -285,15 +246,106 @@ public class MenuManager if (!priorityEntries.isEmpty()) { newEntries.addAll(currentPriorityEntries); - modified = true; } - if (modified) + event.setMenuEntries(newEntries.toArray(new MenuEntry[0])); + } + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) + { + int widgetId = event.getActionParam1(); + Collection options = managedMenuOptions.get(widgetId); + MenuEntry[] menuEntries = client.getMenuEntries(); + + for (WidgetMenuOption currentMenu : options) { - leftClickEntry = newEntries.get(newEntries.size() - 1); + if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget + { + menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); + + MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); + menuEntry.setOption(currentMenu.getMenuOption()); + menuEntry.setParam1(widgetId); + menuEntry.setTarget(currentMenu.getMenuTarget()); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + client.setMenuEntries(menuEntries); + } } - client.setMenuEntries(newEntries.toArray(new MenuEntry[0])); + final MenuEntry entry = menuEntries[menuEntries.length - 1]; + + // Reset tracked entries + if (entry.getOption().equals("Cancel")) + { + comparableEntry = null; + leftClickEntry = null; + } + + if (leftClickEntry == null) + { + for (ComparableEntry p : priorityEntries) + { + if (p.matches(entry)) + { + leftClickEntry = entry; + comparableEntry = new ComparableEntry(entry); + return; + } + } + + for (ComparableEntry p : swaps.values()) + { + if (p.matches(entry)) + { + leftClickEntry = entry; + comparableEntry = new ComparableEntry(entry); + return; + } + } + } + + if (leftClickEntry != null && menuEntries.length > 1) + { + // No need to move the entry if it is already the first option + if (comparableEntry.matches(menuEntries[menuEntries.length - 1])) + { + return; + } + + // If the entry is not the second to last, we can't do a normal swap + if (!comparableEntry.matches(menuEntries[menuEntries.length - 2])) + { + int position = 0; + MenuEntry foundEntry = null; + + for (MenuEntry e : menuEntries) + { + if (e.getOption().equals(leftClickEntry.getOption()) + && e.getTarget().equals(leftClickEntry.getTarget())) + { + foundEntry = menuEntries[position]; + break; + } + position++; + } + + if (foundEntry != null) + { + menuEntries = ArrayUtils.remove(menuEntries, position); + menuEntries = ArrayUtils.insert(menuEntries.length, menuEntries, foundEntry); + } + } + else + { + ArrayUtils.swap(menuEntries, menuEntries.length - 2, menuEntries.length - 1); + } + + menuEntries[menuEntries.length - 1].setType(MenuAction.WIDGET_DEFAULT.getId()); + + client.setMenuEntries(menuEntries); + } } public void addPlayerMenuItem(String menuText) @@ -403,7 +455,6 @@ public class MenuManager if (leftClickEntry != null) { event.setMenuEntry(leftClickEntry); - leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) From ba3edc1ecbf2a9dcbce5ea220a4f8d5211413518 Mon Sep 17 00:00:00 2001 From: psikoi Date: Sat, 29 Jun 2019 12:31:17 +0100 Subject: [PATCH 33/63] Add hover preview to screen markers --- .../screenmarkers/ui/ScreenMarkerPanel.java | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index b0270ba49d..23b6cad174 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -261,6 +261,20 @@ class ScreenMarkerPanel extends JPanel } } }); + nameInput.getTextField().addMouseListener(new MouseAdapter() + { + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + preview(true); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + preview(false); + } + }); nameWrapper.add(nameInput, BorderLayout.CENTER); nameWrapper.add(nameActions, BorderLayout.EAST); @@ -368,10 +382,7 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - visible = !visible; - marker.getMarker().setVisible(visible); - plugin.updateConfig(); - updateVisibility(); + toggle(!visible); } @Override @@ -433,6 +444,24 @@ class ScreenMarkerPanel extends JPanel } + private void preview(boolean on) + { + if (visible) + { + return; + } + + marker.getMarker().setVisible(on); + } + + private void toggle(boolean on) + { + visible = on; + marker.getMarker().setVisible(visible); + plugin.updateConfig(); + updateVisibility(); + } + private void save() { marker.getMarker().setName(nameInput.getText()); From 5a6b39036d6163333fd142fd3640a9d54be68445 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Wed, 12 Jun 2019 22:41:13 -0700 Subject: [PATCH 34/63] HotColdClue: Refactor to use enums for temperatures --- .../cluescrolls/clues/HotColdClue.java | 127 +++++------------- .../clues/hotcold/HotColdTemperature.java | 84 ++++++++++++ .../hotcold/HotColdTemperatureChange.java | 55 ++++++++ .../hotcold/HotColdTemperatureChangeTest.java | 68 ++++++++++ .../clues/hotcold/HotColdTemperatureTest.java | 75 +++++++++++ 5 files changed, 319 insertions(+), 90 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 826017744f..87f2b6c5e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Eadgars Ruse + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,8 +37,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import lombok.Getter; import net.runelite.api.NPC; import net.runelite.api.coords.LocalPoint; @@ -47,6 +48,8 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperature; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperatureChange; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -55,9 +58,6 @@ import net.runelite.client.ui.overlay.components.TitleComponent; @Getter public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll { - private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)"); - private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\."); - private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*"); private static final HotColdClue CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", "Jorral", @@ -231,52 +231,31 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public boolean update(final String message, final ClueScrollPlugin plugin) { - if (!message.startsWith("The device is")) + final HotColdTemperature temperature = HotColdTemperature.of(message); + + if (temperature == null) { return false; } - Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message); - Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message); - Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message); + final WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - // the order that these pattern matchers are checked is important - if (m1.find()) + if (localWorld == null) { - // final location for hot cold clue has been found - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - markFinalSpot(localWorld); - return true; - } - } - else if (m2.find()) - { - String temperature = m2.group(1); - String difference = m2.group(2); - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - updatePossibleArea(localWorld, temperature, difference); - return true; - } - } - else if (m3.find()) - { - String temperature = m3.group(1); - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - updatePossibleArea(localWorld, temperature, ""); - return true; - } + return false; } - return false; + if (temperature == HotColdTemperature.VISIBLY_SHAKING) + { + markFinalSpot(localWorld); + } + else + { + final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(message); + updatePossibleArea(localWorld, temperature, temperatureChange); + } + + return true; } @Override @@ -286,7 +265,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat digLocations.clear(); } - private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference) + private void updatePossibleArea(@Nonnull final WorldPoint worldPoint, @Nonnull final HotColdTemperature temperature, @Nullable final HotColdTemperatureChange temperatureChange) { this.location = null; @@ -295,73 +274,41 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat digLocations.addAll(Arrays.asList(HotColdLocation.values())); } - int maxSquaresAway = 5000; - int minSquaresAway = 0; - - switch (temperature) - { - // when the strange device reads a temperature, that means that the center of the final dig location - // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) - case "ice cold": - maxSquaresAway = 5000; - minSquaresAway = 500; - break; - case "very cold": - maxSquaresAway = 499; - minSquaresAway = 200; - break; - case "cold": - maxSquaresAway = 199; - minSquaresAway = 150; - break; - case "warm": - maxSquaresAway = 149; - minSquaresAway = 100; - break; - case "hot": - maxSquaresAway = 99; - minSquaresAway = 70; - break; - case "very hot": - maxSquaresAway = 69; - minSquaresAway = 30; - break; - case "incredibly hot": - maxSquaresAway = 29; - minSquaresAway = 5; - break; - } + // when the strange device reads a temperature, that means that the center of the final dig location + // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) + int maxSquaresAway = temperature.getMaxDistance(); + int minSquaresAway = temperature.getMinDistance(); // rectangle r1 encompasses all of the points that are within the max possible distance from the player - Point p1 = new Point(currentWp.getX() - maxSquaresAway, currentWp.getY() - maxSquaresAway); + Point p1 = new Point(worldPoint.getX() - maxSquaresAway, worldPoint.getY() - maxSquaresAway); Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1); // rectangle r2 encompasses all of the points that are within the min possible distance from the player - Point p2 = new Point(currentWp.getX() - minSquaresAway, currentWp.getY() - minSquaresAway); + Point p2 = new Point(worldPoint.getX() - minSquaresAway, worldPoint.getY() - minSquaresAway); Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1); // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect())); // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device - if (lastWorldPoint != null) + if (lastWorldPoint != null && temperatureChange != null) { - switch (difference) + switch (temperatureChange) { - case "but colder than": + case COLDER: // eliminate spots that are absolutely warmer - digLocations.removeIf(entry -> isFirstPointCloserRect(currentWp, lastWorldPoint, entry.getRect())); + digLocations.removeIf(entry -> isFirstPointCloserRect(worldPoint, lastWorldPoint, entry.getRect())); break; - case "and warmer than": + case WARMER: // eliminate spots that are absolutely colder - digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, currentWp, entry.getRect())); + digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, worldPoint, entry.getRect())); break; - case "and the same temperature as": + case SAME: // I couldn't figure out a clean implementation for this case // not necessary for quickly determining final location } } - lastWorldPoint = currentWp; + lastWorldPoint = worldPoint; } private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java new file mode 100644 index 0000000000..850d33aec1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum HotColdTemperature +{ + ICE_COLD("ice cold", 500, 5000), + VERY_COLD("very cold", 200, 499), + COLD("cold", 150, 199), + WARM("warm", 100, 149), + HOT("hot", 70, 99), + VERY_HOT("very hot", 30, 69), + INCREDIBLY_HOT("incredibly hot", 5, 29), + VISIBLY_SHAKING("visibly shaking", 0, 4); + + private final String text; + private final int minDistance; + private final int maxDistance; + + private static final String DEVICE_USED_START_TEXT = "The device is "; + + /** + * Gets the temperature corresponding to the passed string. + * + * @param message A string containing a temperature value + * @return The corresponding enum for the passed string. + *

+ * Note that in cases where two temperature enums are equally likely to be the given temperature (say, two + * temperatures with identical text values), the behavior is undefined. + */ + public static HotColdTemperature of(final String message) + { + if (!message.startsWith(DEVICE_USED_START_TEXT)) + { + return null; + } + + final List possibleTemperatures = new ArrayList<>(); + + for (final HotColdTemperature temperature : values()) + { + if (message.contains(temperature.getText())) + { + possibleTemperatures.add(temperature); + } + } + + return possibleTemperatures.stream() + // For messages such as "The device is very cold", this will choose the Enum with text of greatest length so + // that VERY_COLD would be selected over COLD, though both Enums have matching text for this message. + .max(Comparator.comparingInt(x -> (x.getText()).length())) + .orElse(null); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java new file mode 100644 index 0000000000..e9077bc9e1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum HotColdTemperatureChange +{ + WARMER("and warmer than"), + SAME("and the same temperature as"), + COLDER("but colder than"); + + private final String text; + + public static HotColdTemperatureChange of(final String message) + { + if (!message.endsWith(" last time.")) + { + return null; + } + + for (final HotColdTemperatureChange change : values()) + { + if (message.contains(change.text)) + { + return change; + } + } + + return null; + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java new file mode 100644 index 0000000000..9b7cdcaf3c --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import org.junit.Test; + +public class HotColdTemperatureChangeTest +{ + private static final String[] VALID_MESSAGES = { + "The device is warm, and warmer than last time.", + "The device is cold, but colder than last time.", + "The device is very hot, and the same temperature as last time.", + }; + private static final String[] INVALID_MESSAGES = { + "The device is cold.", + "The device is ice cold.", + "The device is very cold.", + "The device is hot.", + "The device is incredibly hot.", + "The device is an octopus, and is wetter than last time", + "foobar", + "a q p w", + "My feet are cold, I should put them in some lukewarm water, or run hot water over them.", + "and warmer than and colder than and the same temperature", + }; + + @Test + public void testValidTemperatureChangeMessages() + { + for (final String message : VALID_MESSAGES) + { + assertNotNull(message, HotColdTemperatureChange.of(message)); + } + } + + @Test + public void testInvalidTemperatureChangeMessages() + { + for (final String message : INVALID_MESSAGES) + { + assertNull(message, HotColdTemperatureChange.of(message)); + } + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java new file mode 100644 index 0000000000..505df56346 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import org.junit.Test; + +public class HotColdTemperatureTest +{ + private static final String[] VALID_MESSAGES = { + "The device is warm, and warmer than last time.", + "The device is visibly shaking and burns to the touch. This must be the spot.", + "The device is cold.", + "The device is ice cold.", + "The device is very cold.", + "The device is hot.", + "The device is incredibly hot.", + }; + private static final String[] INVALID_MESSAGES = { + "The device is an octopus, and is wetter than last time.", + "foobar", + "a q p w", + "My feet are cold, I should put them in some lukewarm water, or run hot water over them.", + }; + + @Test + public void testValidTemperatureMessages() + { + for (final String message : VALID_MESSAGES) + { + assertNotNull(message, HotColdTemperature.of(message)); + } + } + + @Test + public void testInvalidTemperatureMessages() + { + for (final String message : INVALID_MESSAGES) + { + assertNull(message, HotColdTemperature.of(message)); + } + } + + @Test + public void testAmbiguousTemperatureMessages() + { + assertEquals(HotColdTemperature.ICE_COLD, HotColdTemperature.of("The device is ice cold.")); + assertEquals(HotColdTemperature.VERY_COLD, HotColdTemperature.of("The device is very cold.")); + assertEquals(HotColdTemperature.VERY_HOT, HotColdTemperature.of("The device is very hot.")); + } +} From e5d4e7a8976505a9e2e0f23a1d66c76807bf33ca Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Wed, 12 Jun 2019 23:02:25 -0700 Subject: [PATCH 35/63] HotColdClue: Add hot-cold solver class This adds a general hot-cold puzzle solver class and implements it in HotColdClue. --- .../cluescrolls/clues/HotColdClue.java | 140 +++------- .../clues/hotcold/HotColdLocation.java | 3 +- .../clues/hotcold/HotColdSolver.java | 167 ++++++++++++ .../clues/hotcold/HotColdSolverTest.java | 258 ++++++++++++++++++ 4 files changed, 457 insertions(+), 111 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 87f2b6c5e1..1c970c33c8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -25,20 +25,15 @@ */ package net.runelite.client.plugins.cluescrolls.clues; -import com.google.common.collect.Lists; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.Collection; +import java.util.EnumMap; import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import java.util.Set; +import java.util.stream.Collectors; import lombok.Getter; import net.runelite.api.NPC; import net.runelite.api.coords.LocalPoint; @@ -48,6 +43,7 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperature; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperatureChange; import net.runelite.client.ui.overlay.OverlayUtil; @@ -58,18 +54,17 @@ import net.runelite.client.ui.overlay.components.TitleComponent; @Getter public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll { + private static final int HOT_COLD_PANEL_WIDTH = 200; private static final HotColdClue CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", "Jorral", "Speak to Jorral to receive a strange device."); - // list of potential places to dig - private List digLocations = new ArrayList<>(); private final String text; private final String npc; private final String solution; + private HotColdSolver hotColdSolver; private WorldPoint location; - private WorldPoint lastWorldPoint; public static HotColdClue forText(String text) { @@ -87,12 +82,13 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat this.npc = npc; this.solution = solution; setRequiresSpade(true); + initializeSolver(); } @Override public WorldPoint[] getLocations() { - return Lists.transform(digLocations, HotColdLocation::getWorldPoint).toArray(new WorldPoint[0]); + return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); } @Override @@ -101,10 +97,10 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat panelComponent.getChildren().add(TitleComponent.builder() .text("Hot/Cold Clue") .build()); - panelComponent.setPreferredSize(new Dimension(200, 0)); + panelComponent.setPreferredSize(new Dimension(HOT_COLD_PANEL_WIDTH, 0)); // strange device has not been tested yet, show how to get it - if (lastWorldPoint == null && location == null) + if (hotColdSolver.getLastWorldPoint() == null && location == null) { if (getNpc() != null) { @@ -131,7 +127,9 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat panelComponent.getChildren().add(LineComponent.builder() .left("Possible areas:") .build()); - Map locationCounts = new HashMap<>(); + + final Map locationCounts = new EnumMap<>(HotColdArea.class); + final Collection digLocations = hotColdSolver.getPossibleLocations(); for (HotColdLocation hotColdLocation : digLocations) { @@ -159,17 +157,16 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat } else { - for (HotColdArea s : locationCounts.keySet()) + for (HotColdArea area : locationCounts.keySet()) { panelComponent.getChildren().add(LineComponent.builder() - .left(s.getName() + ":") + .left(area.getName() + ':') .build()); for (HotColdLocation hotColdLocation : digLocations) { - if (hotColdLocation.getHotColdArea() == s) + if (hotColdLocation.getHotColdArea() == area) { - Rectangle2D r = hotColdLocation.getRect(); panelComponent.getChildren().add(LineComponent.builder() .left("- " + hotColdLocation.getArea()) .leftColor(Color.LIGHT_GRAY) @@ -185,7 +182,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) { // when final location has been found - if (this.location != null) + if (location != null) { LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); @@ -198,19 +195,16 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat } // when strange device hasn't been activated yet, show Jorral - if (lastWorldPoint == null) + if (hotColdSolver.getLastWorldPoint() == null && plugin.getNpcsToMark() != null) { - // Mark NPC - if (plugin.getNpcsToMark() != null) + for (NPC npcToMark : plugin.getNpcsToMark()) { - for (NPC npc : plugin.getNpcsToMark()) - { - OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); - } + OverlayUtil.renderActorOverlayImage(graphics, npcToMark, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); } } // once the number of possible dig locations is below 10, show the dig spots + final Collection digLocations = hotColdSolver.getPossibleLocations(); if (digLocations.size() < 10) { // Mark potential dig locations @@ -251,8 +245,10 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat } else { + location = null; + final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(message); - updatePossibleArea(localWorld, temperature, temperatureChange); + hotColdSolver.signal(localWorld, temperature, temperatureChange); } return true; @@ -261,88 +257,14 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat @Override public void reset() { - this.lastWorldPoint = null; - digLocations.clear(); + initializeSolver(); } - private void updatePossibleArea(@Nonnull final WorldPoint worldPoint, @Nonnull final HotColdTemperature temperature, @Nullable final HotColdTemperatureChange temperatureChange) + private void initializeSolver() { - this.location = null; - - if (digLocations.isEmpty()) - { - digLocations.addAll(Arrays.asList(HotColdLocation.values())); - } - - // when the strange device reads a temperature, that means that the center of the final dig location - // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) - int maxSquaresAway = temperature.getMaxDistance(); - int minSquaresAway = temperature.getMinDistance(); - - // rectangle r1 encompasses all of the points that are within the max possible distance from the player - Point p1 = new Point(worldPoint.getX() - maxSquaresAway, worldPoint.getY() - maxSquaresAway); - Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1); - // rectangle r2 encompasses all of the points that are within the min possible distance from the player - Point p2 = new Point(worldPoint.getX() - minSquaresAway, worldPoint.getY() - minSquaresAway); - Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1); - - // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range - digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect())); - - // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device - if (lastWorldPoint != null && temperatureChange != null) - { - switch (temperatureChange) - { - case COLDER: - // eliminate spots that are absolutely warmer - digLocations.removeIf(entry -> isFirstPointCloserRect(worldPoint, lastWorldPoint, entry.getRect())); - break; - case WARMER: - // eliminate spots that are absolutely colder - digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, worldPoint, entry.getRect())); - break; - case SAME: - // I couldn't figure out a clean implementation for this case - // not necessary for quickly determining final location - } - } - - lastWorldPoint = worldPoint; - } - - private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r) - { - WorldPoint p1 = new WorldPoint((int) r.getMaxX(), (int) r.getMaxY(), 0); - - if (!isFirstPointCloser(firstWp, secondWp, p1)) - { - return false; - } - - WorldPoint p2 = new WorldPoint((int) r.getMaxX(), (int) r.getMinY(), 0); - - if (!isFirstPointCloser(firstWp, secondWp, p2)) - { - return false; - } - - WorldPoint p3 = new WorldPoint((int) r.getMinX(), (int)r.getMaxY(), 0); - - if (!isFirstPointCloser(firstWp, secondWp, p3)) - { - return false; - } - - WorldPoint p4 = new WorldPoint((int) r.getMinX(), (int) r.getMinY(), 0); - return (isFirstPointCloser(firstWp, secondWp, p4)); - } - - private boolean isFirstPointCloser(WorldPoint firstWp, WorldPoint secondWp, WorldPoint wp) - { - int firstDistance = firstWp.distanceTo2D(wp); - int secondDistance = secondWp.distanceTo2D(wp); - return (firstDistance < secondDistance); + final Set locations = Arrays.stream(HotColdLocation.values()) + .collect(Collectors.toSet()); + hotColdSolver = new HotColdSolver(locations); } private void markFinalSpot(WorldPoint wp) @@ -355,4 +277,4 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat { return new String[] {npc}; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index e41fd5357e..4259d3d29d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -26,7 +26,6 @@ package net.runelite.client.plugins.cluescrolls.clues.hotcold; import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.coords.WorldPoint; @@ -180,7 +179,7 @@ public enum HotColdLocation private final HotColdArea hotColdArea; private final String area; - public Rectangle2D getRect() + public Rectangle getRect() { return new Rectangle(worldPoint.getX() - 4, worldPoint.getY() - 4, 9, 9); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java new file mode 100644 index 0000000000..87414f0387 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2018, Eadgars Ruse + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import com.google.common.annotations.VisibleForTesting; +import java.awt.Rectangle; +import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import lombok.Getter; +import net.runelite.api.coords.WorldPoint; + +/** + * Solution finder for hot-cold style puzzles. + *

+ * These puzzles are established by having some way to test the distance from the solution via "warmth", where being + * colder means one is farther away from the target, and being warmer means one is closer to it, with the goal being to + * reach the most warm value to discover the solution point. Hot-cold puzzles in Old School Runescape are implemented + * with specific set of solution points, so this solver will filter from a provided set of possible solutions as new + * signals of temperatures and temperature changes are provided. + */ +@Getter +public class HotColdSolver +{ + private final Set possibleLocations; + @Nullable + private WorldPoint lastWorldPoint; + + public HotColdSolver(Set possibleLocations) + { + this.possibleLocations = possibleLocations; + } + + /** + * Process a hot-cold update given a {@link WorldPoint} where a check occurred and the resulting temperature and + * temperature change discovered at that point. This will filter the set of possible locations which can be the + * solution. + * + * @param worldPoint The point where a hot-cold check occurred + * @param temperature The temperature of the checked point + * @param temperatureChange The change of temperature of the checked point compared to the previously-checked point + * @return A set of {@link HotColdLocation}s which are still possible after the filtering occurs. This return value + * is the same as would be returned by {@code getPossibleLocations()}. + */ + public Set signal(@Nonnull final WorldPoint worldPoint, @Nonnull final HotColdTemperature temperature, @Nullable final HotColdTemperatureChange temperatureChange) + { + // when the strange device reads a temperature, that means that the center of the final dig location + // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) + int maxSquaresAway = temperature.getMaxDistance(); + int minSquaresAway = temperature.getMinDistance(); + + // maxDistanceArea encompasses all of the points that are within the max possible distance from the player + final Rectangle maxDistanceArea = new Rectangle( + worldPoint.getX() - maxSquaresAway, + worldPoint.getY() - maxSquaresAway, + 2 * maxSquaresAway + 1, + 2 * maxSquaresAway + 1); + // minDistanceArea encompasses all of the points that are within the min possible distance from the player + final Rectangle minDistanceArea = new Rectangle( + worldPoint.getX() - minSquaresAway, + worldPoint.getY() - minSquaresAway, + 2 * minSquaresAway + 1, + 2 * minSquaresAway + 1); + + // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range + possibleLocations.removeIf(entry -> minDistanceArea.contains(entry.getRect()) || !maxDistanceArea.intersects(entry.getRect())); + + // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device + if (lastWorldPoint != null && temperatureChange != null) + { + switch (temperatureChange) + { + case COLDER: + // eliminate spots that are absolutely warmer + possibleLocations.removeIf(entry -> isFirstPointCloserRect(worldPoint, lastWorldPoint, entry.getRect())); + break; + case WARMER: + // eliminate spots that are absolutely colder + possibleLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, worldPoint, entry.getRect())); + break; + case SAME: + // I couldn't figure out a clean implementation for this case + // not necessary for quickly determining final location + } + } + + lastWorldPoint = worldPoint; + return getPossibleLocations(); + } + + /** + * Determines whether the first point passed is closer to each corner of the given rectangle than the second point. + * + * @param firstPoint First point to test. Return result will be relating to this point's location. + * @param secondPoint Second point to test + * @param rect Rectangle, whose corner points will be compared to the first and second points passed + * @return {@code true} if {@code firstPoint} is closer to each of {@code rect}'s four corner points than + * {@code secondPoint}, {@code false} otherwise. + * @see WorldPoint#distanceTo2D + */ + @VisibleForTesting + static boolean isFirstPointCloserRect(final WorldPoint firstPoint, final WorldPoint secondPoint, final Rectangle rect) + { + final WorldPoint nePoint = new WorldPoint((rect.x + rect.width), (rect.y + rect.height), 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, nePoint)) + { + return false; + } + + final WorldPoint sePoint = new WorldPoint((rect.x + rect.width), rect.y, 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, sePoint)) + { + return false; + } + + final WorldPoint nwPoint = new WorldPoint(rect.x, (rect.y + rect.height), 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, nwPoint)) + { + return false; + } + + final WorldPoint swPoint = new WorldPoint(rect.x, rect.y, 0); + return (isFirstPointCloser(firstPoint, secondPoint, swPoint)); + } + + /** + * Determines whether the first point passed is closer to the given point of comparison than the second point. + * + * @param firstPoint First point to test. Return result will be relating to this point's location. + * @param secondPoint Second point to test + * @param worldPoint Point to compare to the first and second points passed + * @return {@code true} if {@code firstPoint} is closer to {@code worldPoint} than {@code secondPoint}, + * {@code false} otherwise. + * @see WorldPoint#distanceTo2D + */ + @VisibleForTesting + static boolean isFirstPointCloser(final WorldPoint firstPoint, final WorldPoint secondPoint, final WorldPoint worldPoint) + { + return firstPoint.distanceTo2D(worldPoint) < secondPoint.distanceTo2D(worldPoint); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java new file mode 100644 index 0000000000..413884d944 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import com.google.common.collect.Sets; +import java.awt.Rectangle; +import java.util.Set; +import java.util.stream.Collectors; +import static junit.framework.TestCase.assertTrue; +import net.runelite.api.coords.WorldPoint; +import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver.isFirstPointCloser; +import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver.isFirstPointCloserRect; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +public class HotColdSolverTest +{ + private static final String RESPONSE_TEXT_ICE_COLD_COLDER = "The device is ice cold, but colder than last time."; + private static final String RESPONSE_TEXT_VERY_COLD_WARMER = "The device is very cold, and warmer than last time."; + private static final String RESPONSE_TEXT_COLD = "The device is cold."; + private static final String RESPONSE_TEXT_COLD_COLDER = "The device is cold, but colder than last time."; + private static final String RESPONSE_TEXT_COLD_WARMER = "The device is cold, and warmer than last time."; + private static final String RESPONSE_TEXT_COLD_SAME_TEMP = "The device is cold, and the same temperature as last time."; + private static final String RESPONSE_TEXT_VERY_HOT = "The device is very hot."; + private static final String RESPONSE_TEXT_VERY_HOT_COLDER = "The device is very hot, but colder than last time."; + private static final String RESPONSE_TEXT_VERY_HOT_WARMER = "The device is very hot, and warmer than last time."; + private static final String RESPONSE_TEXT_VERY_HOT_SAME_TEMP = "The device is very hot, and the same temperature as last time."; + + @Test + public void testOneStepSolution() + { + final Set foundLocation = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); + + testSolver(createHotColdSolver(), new WorldPoint(2852, 2992, 0), RESPONSE_TEXT_VERY_HOT, foundLocation); + } + + @Test + public void testIgnoreStartingTemperatureDifference() + { + final WorldPoint testedPoint = new WorldPoint(2852, 2992, 0); + final Set foundLocations = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); + + testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT, foundLocations); + testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_COLDER, foundLocations); + testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_WARMER, foundLocations); + testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_SAME_TEMP, foundLocations); + } + + @Test + public void testSameTempNoChanges() + { + final HotColdSolver solver = createHotColdSolver(); + final WorldPoint testedPoint = new WorldPoint(2851, 2955, 0); + final Set foundLocations = Sets.immutableEnumSet( + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.KARAMJA_KHARAZI_SW); + + testSolver(solver, testedPoint, RESPONSE_TEXT_VERY_HOT, foundLocations); + testSolver(solver, testedPoint, RESPONSE_TEXT_VERY_HOT_SAME_TEMP, foundLocations); + } + + @Test + public void testNoChangesAfterSolutionFound() + { + final HotColdSolver solver = createHotColdSolver(); + final Set intermediateFoundLocations = Sets.immutableEnumSet( + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.KARAMJA_KHARAZI_SW); + final Set finalLocation = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); + + testSolver(solver, new WorldPoint(2851, 2955, 0), RESPONSE_TEXT_VERY_HOT, intermediateFoundLocations); + testSolver(solver, new WorldPoint(2852, 2955, 0), RESPONSE_TEXT_VERY_HOT_WARMER, finalLocation); + testSolver(solver, new WorldPoint(2851, 2955, 0), RESPONSE_TEXT_VERY_HOT_COLDER, finalLocation); + testSolver(solver, new WorldPoint(2465, 3495, 0), RESPONSE_TEXT_ICE_COLD_COLDER, finalLocation); + testSolver(solver, new WorldPoint(3056, 3291, 0), RESPONSE_TEXT_VERY_COLD_WARMER, finalLocation); + testSolver(solver, new WorldPoint(2571, 2956, 0), RESPONSE_TEXT_VERY_COLD_WARMER, finalLocation); + } + + @Test + public void testNarrowToFindSolutions() + { + final HotColdSolver solver = createHotColdSolver(); + final Set firstLocationsSet = Sets.immutableEnumSet( + HotColdLocation.FELDIP_HILLS_GNOME_GLITER, + HotColdLocation.FELDIP_HILLS_RED_CHIN, + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.KARAMJA_CRASH_ISLAND); + final Set secondLocationsSet = firstLocationsSet.stream() + .filter(location -> location != HotColdLocation.FELDIP_HILLS_RED_CHIN) + .collect(Collectors.toSet()); + final Set thirdLocationSet = secondLocationsSet.stream() + .filter(location -> location != HotColdLocation.FELDIP_HILLS_GNOME_GLITER) + .collect(Collectors.toSet()); + final Set finalLocation = thirdLocationSet.stream() + .filter(location -> location != HotColdLocation.KARAMJA_CRASH_ISLAND) + .collect(Collectors.toSet()); + + testSolver(solver, new WorldPoint(2711, 2803, 0), RESPONSE_TEXT_COLD, firstLocationsSet); + testSolver(solver, new WorldPoint(2711, 2802, 0), RESPONSE_TEXT_COLD_SAME_TEMP, firstLocationsSet); + testSolver(solver, new WorldPoint(2716, 2802, 0), RESPONSE_TEXT_COLD_WARMER, secondLocationsSet); + testSolver(solver, new WorldPoint(2739, 2808, 0), RESPONSE_TEXT_COLD_WARMER, thirdLocationSet); + testSolver(solver, new WorldPoint(2810, 2757, 0), RESPONSE_TEXT_COLD_COLDER, finalLocation); + } + + @Test + public void testSomewhatDistantLocations() + { + // Activate device on Ape Atoll when solution point is HotColdLocation.KARAMJA_KHARAZI_NE + testSolver(createHotColdSolver(), new WorldPoint(2723, 2743, 0), RESPONSE_TEXT_COLD, + Sets.immutableEnumSet( + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.KARAMJA_KHARAZI_SW, + HotColdLocation.KARAMJA_CRASH_ISLAND, + HotColdLocation.FELDIP_HILLS_SW, + HotColdLocation.FELDIP_HILLS_RANTZ, + HotColdLocation.FELDIP_HILLS_RED_CHIN, + HotColdLocation.FELDIP_HILLS_SE)); + + // Activate device near fairy ring DKP when solution point is HotColdLocation.KARAMJA_KHARAZI_NE + testSolver(createHotColdSolver(), new WorldPoint(2900, 3111, 0), RESPONSE_TEXT_COLD, + Sets.immutableEnumSet( + HotColdLocation.KARAMJA_WEST_BRIMHAVEN, + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.ASGARNIA_COW, + HotColdLocation.ASGARNIA_CRAFT_GUILD, + HotColdLocation.KANDARIN_WITCHHAVEN, + HotColdLocation.MISTHALIN_DRAYNOR_BANK)); + + // Activate device on Mudskipper Point when solution point is HotColdLocation.KARAMJA_KHARAZI_NE + testSolver(createHotColdSolver(), new WorldPoint(2985, 3106, 0), RESPONSE_TEXT_COLD, + Sets.immutableEnumSet( + HotColdLocation.KARAMJA_BRIMHAVEN_FRUIT_TREE, + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.ASGARNIA_COW, + HotColdLocation.ASGARNIA_CRAFT_GUILD, + HotColdLocation.MISTHALIN_LUMBRIDGE_2, + HotColdLocation.DESERT_BEDABIN_CAMP)); + } + + @Test + public void testIsFirstPointCloserRect() + { + assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0), new Rectangle(0, 0, 1, 1))); + assertFalse(isFirstPointCloserRect(new WorldPoint(1, 0, 0), new WorldPoint(5, 0, 0), new Rectangle(2, 1, 5, 5))); + assertFalse(isFirstPointCloserRect(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new Rectangle(2, 0, 1, 2))); + assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 1), new Rectangle(2, 2, 2, 2))); + assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(4, 4, 4), new Rectangle(1, 1, 2, 2))); + assertFalse(isFirstPointCloserRect(new WorldPoint(3, 2, 0), new WorldPoint(1, 5, 0), new Rectangle(0, 0, 4, 4))); + + assertTrue(isFirstPointCloserRect(new WorldPoint(1, 1, 0), new WorldPoint(0, 1, 0), new Rectangle(2, 0, 3, 2))); + assertTrue(isFirstPointCloserRect(new WorldPoint(4, 4, 0), new WorldPoint(1, 1, 0), new Rectangle(3, 3, 2, 2))); + assertTrue(isFirstPointCloserRect(new WorldPoint(3, 2, 0), new WorldPoint(7, 0, 0), new Rectangle(1, 3, 4, 2))); + + } + + @Test + public void testIsFirstPointCloser() + { + assertFalse(isFirstPointCloser(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0))); + assertFalse(isFirstPointCloser(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 1), new WorldPoint(0, 0, 0))); + assertFalse(isFirstPointCloser(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 0))); + assertFalse(isFirstPointCloser(new WorldPoint(2, 2, 0), new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 0))); + + assertTrue(isFirstPointCloser(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(2, 0, 0))); + assertTrue(isFirstPointCloser(new WorldPoint(1, 1, 0), new WorldPoint(1, 0, 0), new WorldPoint(2, 2, 0))); + assertTrue(isFirstPointCloser(new WorldPoint(1, 1, 1), new WorldPoint(0, 1, 0), new WorldPoint(1, 1, 0))); + } + + /** + * Tests a hot-cold solver by signalling a test point, temperature, and temperature change to it and asserting the + * resulting possible location set is equal to that of a given set of expected locations. + * + * @param solver The hot-cold solver to signal to. + *
+ * Note: This will mutate the passed solver, which is helpful for testing + * multiple sequential steps. + * @param testPoint The {@link WorldPoint} where the signal occurs. + * @param deviceResponse The string containing the temperature and temperature change which is + * given when the hot-cold checking device is activated. + * @param expectedRemainingPossibleLocations A {@link Set} of {@link HotColdLocation}s which is expected to be + * given by {@link HotColdSolver#getPossibleLocations()} after it receives + * the signal formed by the other given arguments. + */ + private static void testSolver(final HotColdSolver solver, final WorldPoint testPoint, final String deviceResponse, final Set expectedRemainingPossibleLocations) + { + final HotColdTemperature temperature = HotColdTemperature.of(deviceResponse); + final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(deviceResponse); + + assertNotNull(temperature); + assertEquals(expectedRemainingPossibleLocations, solver.signal(testPoint, temperature, temperatureChange)); + } + + /** + * @return A hot-cold solver with a starting set of master hot-cold locations nearby the KARAMJA_KHARAZI_NE + * location. {@link HotColdLocation#values()} is not used as it may change with future game updates, and + * such changes would break this test suite. + */ + private static HotColdSolver createHotColdSolver() + { + final Set hotColdLocations = Sets.immutableEnumSet( + HotColdLocation.KARAMJA_KHARAZI_NE, + HotColdLocation.KARAMJA_KHARAZI_SW, + HotColdLocation.KARAMJA_GLIDER, + HotColdLocation.KARAMJA_MUSA_POINT, + HotColdLocation.KARAMJA_BRIMHAVEN_FRUIT_TREE, + HotColdLocation.KARAMJA_WEST_BRIMHAVEN, + HotColdLocation.KARAMJA_CRASH_ISLAND, + HotColdLocation.DESERT_BEDABIN_CAMP, + HotColdLocation.DESERT_MENAPHOS_GATE, + HotColdLocation.DESERT_POLLNIVNEACH, + HotColdLocation.DESERT_SHANTY, + HotColdLocation.MISTHALIN_LUMBRIDGE, + HotColdLocation.MISTHALIN_LUMBRIDGE_2, + HotColdLocation.MISTHALIN_DRAYNOR_BANK, + HotColdLocation.ASGARNIA_COW, + HotColdLocation.ASGARNIA_PARTY_ROOM, + HotColdLocation.ASGARNIA_CRAFT_GUILD, + HotColdLocation.ASGARNIA_RIMMINGTON, + HotColdLocation.ASGARNIA_MUDSKIPPER, + HotColdLocation.KANDARIN_WITCHHAVEN, + HotColdLocation.KANDARIN_NECRO_TOWER, + HotColdLocation.KANDARIN_FIGHT_ARENA, + HotColdLocation.KANDARIN_TREE_GNOME_VILLAGE, + HotColdLocation.FELDIP_HILLS_GNOME_GLITER, + HotColdLocation.FELDIP_HILLS_JIGGIG, + HotColdLocation.FELDIP_HILLS_RANTZ, + HotColdLocation.FELDIP_HILLS_RED_CHIN, + HotColdLocation.FELDIP_HILLS_SE, + HotColdLocation.FELDIP_HILLS_SOUTH, + HotColdLocation.FELDIP_HILLS_SW + ); + return new HotColdSolver(hotColdLocations); + } +} From 76d4031445ae6cc8fa31b0face9bee66fd06c340 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Wed, 12 Jun 2019 23:28:52 -0700 Subject: [PATCH 36/63] cluescrolls: Add beginner hot-cold clues --- .../cluescrolls/clues/HotColdClue.java | 87 +++++++++++++++++-- .../clues/hotcold/HotColdLocation.java | 16 +++- .../clues/hotcold/HotColdTemperature.java | 48 +++++++--- .../hotcold/BeginnerHotColdLocationTest.java | 50 +++++++++++ .../clues/hotcold/HotColdSolverTest.java | 5 +- .../clues/hotcold/HotColdTemperatureTest.java | 12 +-- .../hotcold/MasterHotColdLocationTest.java | 49 +++++++++++ 7 files changed, 240 insertions(+), 27 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 1c970c33c8..5fad4e4207 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -34,7 +34,10 @@ import java.util.EnumMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import javax.annotation.Nullable; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.NPC; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; @@ -51,26 +54,37 @@ import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; +@EqualsAndHashCode(callSuper = false, exclude = { "hotColdSolver", "location" }) @Getter +@Slf4j public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll { private static final int HOT_COLD_PANEL_WIDTH = 200; - private static final HotColdClue CLUE = - new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", - "Jorral", - "Speak to Jorral to receive a strange device."); + private static final HotColdClue BEGINNER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.", + "Reldo", + "Speak to Reldo to receive a strange device."); + private static final HotColdClue MASTER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", + "Jorral", + "Speak to Jorral to receive a strange device."); private final String text; private final String npc; private final String solution; + @Nullable private HotColdSolver hotColdSolver; private WorldPoint location; public static HotColdClue forText(String text) { - if (CLUE.text.equalsIgnoreCase(text)) + if (BEGINNER_CLUE.text.equalsIgnoreCase(text)) { - return CLUE; + BEGINNER_CLUE.reset(); + return BEGINNER_CLUE; + } + else if (MASTER_CLUE.text.equalsIgnoreCase(text)) + { + MASTER_CLUE.reset(); + return MASTER_CLUE; } return null; @@ -88,12 +102,22 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat @Override public WorldPoint[] getLocations() { + if (hotColdSolver == null) + { + return new WorldPoint[0]; + } + return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); } @Override public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) { + if (hotColdSolver == null) + { + return; + } + panelComponent.getChildren().add(TitleComponent.builder() .text("Hot/Cold Clue") .build()); @@ -181,6 +205,11 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat @Override public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) { + if (hotColdSolver == null) + { + return; + } + // when final location has been found if (location != null) { @@ -194,7 +223,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return; } - // when strange device hasn't been activated yet, show Jorral + // when strange device hasn't been activated yet, show npc who gives you the strange device if (hotColdSolver.getLastWorldPoint() == null && plugin.getNpcsToMark() != null) { for (NPC npcToMark : plugin.getNpcsToMark()) @@ -225,7 +254,27 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public boolean update(final String message, final ClueScrollPlugin plugin) { - final HotColdTemperature temperature = HotColdTemperature.of(message); + if (hotColdSolver == null) + { + return false; + } + + final Set temperatureSet; + + if (this.equals(BEGINNER_CLUE)) + { + temperatureSet = HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES; + } + else if (this.equals(MASTER_CLUE)) + { + temperatureSet = HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES; + } + else + { + temperatureSet = null; + } + + final HotColdTemperature temperature = HotColdTemperature.getFromTemperatureSet(temperatureSet, message); if (temperature == null) { @@ -239,7 +288,8 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return false; } - if (temperature == HotColdTemperature.VISIBLY_SHAKING) + if ((this.equals(BEGINNER_CLUE) && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING) + || (this.equals(MASTER_CLUE) && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING)) { markFinalSpot(localWorld); } @@ -262,7 +312,26 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat private void initializeSolver() { + final boolean isBeginner; + + if (this.equals(BEGINNER_CLUE)) + { + isBeginner = true; + } + else if (this.equals(MASTER_CLUE)) + { + isBeginner = false; + } + else + { + log.warn("Hot cold solver could not be initialized, clue type is unknown; text: {}, npc: {}, solution: {}", + text, npc, solution); + hotColdSolver = null; + return; + } + final Set locations = Arrays.stream(HotColdLocation.values()) + .filter(l -> l.isBeginnerClue() == isBeginner) .collect(Collectors.toSet()); hotColdSolver = new HotColdSolver(locations); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index 4259d3d29d..b3bd0c91db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, Eadgars Ruse * Copyright (c) 2018, Adam + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,6 +69,8 @@ public enum HotColdLocation DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), + DRAYNOR_MANOR_MUSHROOMS(true, new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), + DRAYNOR_WHEAT_FIELD(true, new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), FELDIP_HILLS_JIGGIG(new WorldPoint(2413, 3055, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp."), FELDIP_HILLS_SW(new WorldPoint(2582, 2895, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills."), FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2553, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri)."), @@ -90,6 +93,7 @@ public enum HotColdLocation FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2147, 3862, 0), FREMENNIK_PROVINCE, "Astral altar"), FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2087, 3915, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village."), FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village."), + ICE_MOUNTAIN(true, new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), KANDARIN_SINCLAR_MANSION(new WorldPoint(2726, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), KANDARIN_CATHERBY(new WorldPoint(2774, 3433, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), KANDARIN_GRAND_TREE(new WorldPoint(2444, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure."), @@ -114,6 +118,7 @@ public enum HotColdLocation KARAMJA_KHARAZI_NE(new WorldPoint(2904, 2925, 0), KARAMJA, "North-eastern part of Kharazi Jungle."), KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), KARAMJA_CRASH_ISLAND(new WorldPoint(2910, 2737, 0), KARAMJA, "Northern part of Crash Island."), + LUMBRIDGE_COW_FIELD(true, new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), @@ -130,6 +135,7 @@ public enum HotColdLocation MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3813, 3567, 0), MORYTANIA, "Northern part of Dragontooth Island."), MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island."), + NORTHEAST_OF_AL_KHARID_MINE(true, new WorldPoint(3332, 3313, 0), MISTHALIN, "Northeast of Al Kharid Mine"), WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3530, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak."), WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2337, 3689, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony"), WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2361, 3566, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), @@ -175,12 +181,20 @@ public enum HotColdLocation ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); + private final boolean beginnerClue; private final WorldPoint worldPoint; private final HotColdArea hotColdArea; private final String area; + HotColdLocation(WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription) + { + this(false, worldPoint, hotColdArea, areaDescription); + } + public Rectangle getRect() { - return new Rectangle(worldPoint.getX() - 4, worldPoint.getY() - 4, 9, 9); + final int digRadius = beginnerClue ? HotColdTemperature.BEGINNER_VISIBLY_SHAKING.getMaxDistance() : + HotColdTemperature.MASTER_VISIBLY_SHAKING.getMaxDistance(); + return new Rectangle(worldPoint.getX() - digRadius, worldPoint.getY() - digRadius, digRadius * 2 + 1, digRadius * 2 + 1); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java index 850d33aec1..2dc5909000 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java @@ -24,9 +24,12 @@ */ package net.runelite.client.plugins.cluescrolls.clues.hotcold; +import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; import lombok.AllArgsConstructor; import lombok.Getter; @@ -40,8 +43,31 @@ public enum HotColdTemperature WARM("warm", 100, 149), HOT("hot", 70, 99), VERY_HOT("very hot", 30, 69), - INCREDIBLY_HOT("incredibly hot", 5, 29), - VISIBLY_SHAKING("visibly shaking", 0, 4); + BEGINNER_INCREDIBLY_HOT("incredibly hot", 4, 29), + BEGINNER_VISIBLY_SHAKING("visibly shaking", 0, 3), + MASTER_INCREDIBLY_HOT("incredibly hot", 5, 29), + MASTER_VISIBLY_SHAKING("visibly shaking", 0, 4); + + public static final Set BEGINNER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( + ICE_COLD, + VERY_COLD, + COLD, + WARM, + HOT, + VERY_HOT, + BEGINNER_INCREDIBLY_HOT, + BEGINNER_VISIBLY_SHAKING + ); + public static final Set MASTER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( + ICE_COLD, + VERY_COLD, + COLD, + WARM, + HOT, + VERY_HOT, + MASTER_INCREDIBLY_HOT, + MASTER_VISIBLY_SHAKING + ); private final String text; private final int minDistance; @@ -50,24 +76,26 @@ public enum HotColdTemperature private static final String DEVICE_USED_START_TEXT = "The device is "; /** - * Gets the temperature corresponding to the passed string. + * Gets the temperature from a set of temperatures corresponding to the passed string. * - * @param message A string containing a temperature value - * @return The corresponding enum for the passed string. + * @param temperatureSet A set of temperature values to select from + * @param message A string containing a temperature value + * @return The corresponding enum from the given temperature set. *

- * Note that in cases where two temperature enums are equally likely to be the given temperature (say, two - * temperatures with identical text values), the behavior is undefined. + * Note that in cases where two temperature values in the given set are equally likely to be the given + * temperature (say, two temperatures with identical text values), the behavior is undefined. */ - public static HotColdTemperature of(final String message) + @Nullable + public static HotColdTemperature getFromTemperatureSet(final Set temperatureSet, final String message) { - if (!message.startsWith(DEVICE_USED_START_TEXT)) + if (!message.startsWith(DEVICE_USED_START_TEXT) || temperatureSet == null) { return null; } final List possibleTemperatures = new ArrayList<>(); - for (final HotColdTemperature temperature : values()) + for (final HotColdTemperature temperature : temperatureSet) { if (message.contains(temperature.getText())) { diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java new file mode 100644 index 0000000000..d67a00b989 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class BeginnerHotColdLocationTest +{ + private static final Set BEGINNER_HOT_COLD_LOCATIONS = Arrays.stream(HotColdLocation.values()) + .filter(HotColdLocation::isBeginnerClue) + .collect(Collectors.toSet()); + private static final int EXPECTED_DIMENSION_SIZE = 7; + + @Test + public void beginnerHotColdLocationAreaTest() + { + + for (final HotColdLocation location : BEGINNER_HOT_COLD_LOCATIONS) + { + assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().height); + assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().width); + } + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java index 413884d944..a5c4cc4e31 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java @@ -26,6 +26,7 @@ package net.runelite.client.plugins.cluescrolls.clues.hotcold; import com.google.common.collect.Sets; import java.awt.Rectangle; +import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; import static junit.framework.TestCase.assertTrue; @@ -207,7 +208,7 @@ public class HotColdSolverTest */ private static void testSolver(final HotColdSolver solver, final WorldPoint testPoint, final String deviceResponse, final Set expectedRemainingPossibleLocations) { - final HotColdTemperature temperature = HotColdTemperature.of(deviceResponse); + final HotColdTemperature temperature = HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, deviceResponse); final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(deviceResponse); assertNotNull(temperature); @@ -221,7 +222,7 @@ public class HotColdSolverTest */ private static HotColdSolver createHotColdSolver() { - final Set hotColdLocations = Sets.immutableEnumSet( + final Set hotColdLocations = EnumSet.of( HotColdLocation.KARAMJA_KHARAZI_NE, HotColdLocation.KARAMJA_KHARAZI_SW, HotColdLocation.KARAMJA_GLIDER, diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java index 505df56346..e9711dc433 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java @@ -52,7 +52,8 @@ public class HotColdTemperatureTest { for (final String message : VALID_MESSAGES) { - assertNotNull(message, HotColdTemperature.of(message)); + assertNotNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES, message)); + assertNotNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, message)); } } @@ -61,15 +62,16 @@ public class HotColdTemperatureTest { for (final String message : INVALID_MESSAGES) { - assertNull(message, HotColdTemperature.of(message)); + assertNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES, message)); + assertNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, message)); } } @Test public void testAmbiguousTemperatureMessages() { - assertEquals(HotColdTemperature.ICE_COLD, HotColdTemperature.of("The device is ice cold.")); - assertEquals(HotColdTemperature.VERY_COLD, HotColdTemperature.of("The device is very cold.")); - assertEquals(HotColdTemperature.VERY_HOT, HotColdTemperature.of("The device is very hot.")); + assertEquals(HotColdTemperature.ICE_COLD, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is ice cold.")); + assertEquals(HotColdTemperature.VERY_COLD, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is very cold.")); + assertEquals(HotColdTemperature.VERY_HOT, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is very hot.")); } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java new file mode 100644 index 0000000000..abda26549d --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class MasterHotColdLocationTest +{ + private static final Set MASTER_HOT_COLD_LOCATIONS = Arrays.stream(HotColdLocation.values()) + .filter(l -> !l.isBeginnerClue()) + .collect(Collectors.toSet()); + private static final int EXPECTED_DIMENSION_SIZE = 9; + + @Test + public void beginnerHotColdLocationAreaTest() + { + for (final HotColdLocation location : MASTER_HOT_COLD_LOCATIONS) + { + assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().height); + assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().width); + } + } +} From 77c78aa9707482638207fd0b243a79ec2f6b706e Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Mon, 1 Jul 2019 13:15:04 -0400 Subject: [PATCH 37/63] menumanager: utilize beforerender, make use of additional threads --- .../runelite/client/menus/MenuManager.java | 272 +++++++++++++----- 1 file changed, 201 insertions(+), 71 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index ddc0a5fe5d..2fb5700fb3 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -31,24 +31,28 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; + +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MenuAction; import static net.runelite.api.MenuAction.MENU_ACTION_DEPRIORITIZE_OFFSET; import net.runelite.api.MenuEntry; import net.runelite.api.NPCDefinition; +import net.runelite.api.events.BeforeRender; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOpened; import net.runelite.api.events.MenuOptionClicked; @@ -60,7 +64,6 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.util.Text; -import org.apache.commons.lang3.ArrayUtils; @Singleton @Slf4j @@ -88,6 +91,7 @@ public class MenuManager private final Client client; private final EventBus eventBus; + private final Prioritizer prioritizer; //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); @@ -98,16 +102,21 @@ public class MenuManager private final Set priorityEntries = new HashSet<>(); private final Set currentPriorityEntries = new HashSet<>(); private final Set hiddenEntries = new HashSet<>(); - + private final Set currentHiddenEntries = new HashSet<>(); private final Map swaps = new HashMap<>(); + private final Map currentSwaps = new HashMap<>(); + + private final LinkedHashSet entries = Sets.newLinkedHashSet(); + private final Map originalTypes = new HashMap<>(); + private MenuEntry leftClickEntry = null; - private ComparableEntry comparableEntry = null; @Inject private MenuManager(Client client, EventBus eventBus) { this.client = client; this.eventBus = eventBus; + this.prioritizer = new Prioritizer(); } /** @@ -153,10 +162,21 @@ public class MenuManager leftClickEntry = null; currentPriorityEntries.clear(); + currentHiddenEntries.clear(); - MenuEntry[] entries = client.getMenuEntries(); + // Need to reorder the list to normal, then rebuild with swaps + MenuEntry[] oldEntries = event.getMenuEntries(); + + for (MenuEntry entry : oldEntries) + { + if (originalTypes.containsKey(entry)) + { + entry.setType(originalTypes.get(entry)); + } + } + + client.sortMenuEntries(); - ArrayList oldEntries = Lists.newArrayList(entries); List newEntries = Lists.newArrayList(oldEntries); boolean shouldDeprioritize = false; @@ -191,12 +211,10 @@ public class MenuManager if (newEntries.size() > 0) { - MenuEntry last = Iterables.getLast(newEntries); - // Swap first matching entry to top for (ComparableEntry src : swaps.keySet()) { - if (!src.matches(last)) + if (!src.matches(entry)) { continue; } @@ -215,16 +233,16 @@ public class MenuManager } // Do not need to swap with itself - if (swapFrom != null && swapFrom != last) + if (swapFrom != null && swapFrom != entry) { // Deprioritize entries if the swaps are not in similar type groups - if ((swapFrom.getType() >= 1000 && last.getType() < 1000) || (last.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) + if ((swapFrom.getType() >= 1000 && entry.getType() < 1000) || (entry.getType() >= 1000 && swapFrom.getType() < 1000) && !shouldDeprioritize) { shouldDeprioritize = true; } int indexFrom = newEntries.indexOf(swapFrom); - int indexTo = newEntries.indexOf(last); + int indexTo = newEntries.indexOf(entry); Collections.swap(newEntries, indexFrom, indexTo); } @@ -273,81 +291,80 @@ public class MenuManager client.setMenuEntries(menuEntries); } } + } - final MenuEntry entry = menuEntries[menuEntries.length - 1]; - // Reset tracked entries - if (entry.getOption().equals("Cancel")) + + @Subscribe + public void onBeforeRender(BeforeRender event) + { + leftClickEntry = null; + + if (client.isMenuOpen()) { - comparableEntry = null; - leftClickEntry = null; + return; } + entries.clear(); + + entries.addAll(Arrays.asList(client.getMenuEntries())); + + if (entries.size() < 2) + { + return; + } + + currentPriorityEntries.clear(); + currentHiddenEntries.clear(); + currentSwaps.clear(); + originalTypes.clear(); + + prioritizer.prioritize(); + + while (prioritizer.isRunning()) + { + // wait + } + + entries.removeAll(currentHiddenEntries); + + + for (MenuEntry entry : currentPriorityEntries) + { + if (entries.contains(entry)) + { + leftClickEntry = entry; + originalTypes.put(leftClickEntry, leftClickEntry.getType()); + entries.remove(leftClickEntry); + entries.add(leftClickEntry); + Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); + break; + } + } + + if (leftClickEntry == null) { - for (ComparableEntry p : priorityEntries) - { - if (p.matches(entry)) - { - leftClickEntry = entry; - comparableEntry = new ComparableEntry(entry); - return; - } - } + MenuEntry first = Iterables.getLast(entries); - for (ComparableEntry p : swaps.values()) + for (ComparableEntry swap : currentSwaps.keySet()) { - if (p.matches(entry)) + if (swap.matches(first)) { - leftClickEntry = entry; - comparableEntry = new ComparableEntry(entry); - return; + leftClickEntry = currentSwaps.get(swap); + originalTypes.put(leftClickEntry, leftClickEntry.getType()); + entries.remove(leftClickEntry); + entries.add(leftClickEntry); + Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); + break; } } } - if (leftClickEntry != null && menuEntries.length > 1) - { - // No need to move the entry if it is already the first option - if (comparableEntry.matches(menuEntries[menuEntries.length - 1])) - { - return; - } - - // If the entry is not the second to last, we can't do a normal swap - if (!comparableEntry.matches(menuEntries[menuEntries.length - 2])) - { - int position = 0; - MenuEntry foundEntry = null; - - for (MenuEntry e : menuEntries) - { - if (e.getOption().equals(leftClickEntry.getOption()) - && e.getTarget().equals(leftClickEntry.getTarget())) - { - foundEntry = menuEntries[position]; - break; - } - position++; - } - - if (foundEntry != null) - { - menuEntries = ArrayUtils.remove(menuEntries, position); - menuEntries = ArrayUtils.insert(menuEntries.length, menuEntries, foundEntry); - } - } - else - { - ArrayUtils.swap(menuEntries, menuEntries.length - 2, menuEntries.length - 1); - } - - menuEntries[menuEntries.length - 1].setType(MenuAction.WIDGET_DEFAULT.getId()); - - client.setMenuEntries(menuEntries); - } + client.setMenuEntries(entries.toArray(new MenuEntry[0])); } + public void addPlayerMenuItem(String menuText) { Preconditions.checkNotNull(menuText); @@ -455,6 +472,7 @@ public class MenuManager if (leftClickEntry != null) { event.setMenuEntry(leftClickEntry); + leftClickEntry = null; } if (event.getMenuAction() != MenuAction.RUNELITE) @@ -780,4 +798,116 @@ public class MenuManager { hiddenEntries.remove(entry); } + + private class Prioritizer + { + private MenuEntry[] entries; + private AtomicInteger state = new AtomicInteger(0); + + boolean isRunning() + { + return state.get() != 0; + } + + void prioritize() + { + if (state.get() != 0) + { + return; + } + + entries = client.getMenuEntries(); + + state.set(3); + + if (!hiddenEntries.isEmpty()) + { + hiddenFinder.run(); + } + else + { + state.decrementAndGet(); + } + + if (!priorityEntries.isEmpty()) + { + priorityFinder.run(); + } + else + { + state.decrementAndGet(); + } + + if (!swaps.isEmpty()) + { + swapFinder.run(); + } + else + { + state.decrementAndGet(); + } + } + + private Thread hiddenFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (ComparableEntry p : hiddenEntries) + { + if (p.matches(entry)) + { + currentHiddenEntries.add(entry); + return; + } + } + }); + state.decrementAndGet(); + } + }; + + private Thread priorityFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (ComparableEntry p : priorityEntries) + { + if (p.matches(entry)) + { + currentPriorityEntries.add(entry); + return; + } + } + }); + + state.decrementAndGet(); + } + }; + + private Thread swapFinder = new Thread() + { + @Override + public void run() + { + Arrays.stream(entries).parallel().forEach(entry -> + { + for (Map.Entry p : swaps.entrySet()) + { + if (p.getValue().matches(entry)) + { + currentSwaps.put(p.getKey(), entry); + return; + } + } + }); + + state.decrementAndGet(); + } + }; + } } From fa30bcd48f13f0edf81f980713f2fcfd86fc8c7a Mon Sep 17 00:00:00 2001 From: 7ate9 <7ate9@users.noreply.github.com`> Date: Mon, 1 Jul 2019 14:35:15 -0400 Subject: [PATCH 38/63] menumanager: cleanup --- .../runelite/client/menus/MenuManager.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 2fb5700fb3..4e4f9fb847 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -76,19 +76,6 @@ public class MenuManager private static final int IDX_UPPER = 8; static final Pattern LEVEL_PATTERN = Pattern.compile("\\(level-[0-9]*\\)"); - private static MenuEntry CANCEL() - { - MenuEntry cancel = new MenuEntry(); - cancel.setOption("Cancel"); - cancel.setTarget(""); - cancel.setIdentifier(0); - cancel.setType(MenuAction.CANCEL.getId()); - cancel.setParam0(0); - cancel.setParam1(0); - - return cancel; - } - private final Client client; private final EventBus eventBus; private final Prioritizer prioritizer; @@ -107,9 +94,9 @@ public class MenuManager private final Map currentSwaps = new HashMap<>(); private final LinkedHashSet entries = Sets.newLinkedHashSet(); - private final Map originalTypes = new HashMap<>(); private MenuEntry leftClickEntry = null; + private int leftClickType = -1; @Inject private MenuManager(Client client, EventBus eventBus) @@ -159,8 +146,6 @@ public class MenuManager @Subscribe public void onMenuOpened(MenuOpened event) { - leftClickEntry = null; - currentPriorityEntries.clear(); currentHiddenEntries.clear(); @@ -169,12 +154,16 @@ public class MenuManager for (MenuEntry entry : oldEntries) { - if (originalTypes.containsKey(entry)) + if (entry == leftClickEntry) { - entry.setType(originalTypes.get(entry)); + entry.setType(leftClickType); + break; } } + leftClickEntry = null; + leftClickType = -1; + client.sortMenuEntries(); List newEntries = Lists.newArrayList(oldEntries); @@ -299,6 +288,7 @@ public class MenuManager public void onBeforeRender(BeforeRender event) { leftClickEntry = null; + leftClickType = -1; if (client.isMenuOpen()) { @@ -317,7 +307,6 @@ public class MenuManager currentPriorityEntries.clear(); currentHiddenEntries.clear(); currentSwaps.clear(); - originalTypes.clear(); prioritizer.prioritize(); @@ -334,10 +323,10 @@ public class MenuManager if (entries.contains(entry)) { leftClickEntry = entry; - originalTypes.put(leftClickEntry, leftClickEntry.getType()); + leftClickType = entry.getType(); entries.remove(leftClickEntry); + leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId()); entries.add(leftClickEntry); - Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); break; } } @@ -352,10 +341,10 @@ public class MenuManager if (swap.matches(first)) { leftClickEntry = currentSwaps.get(swap); - originalTypes.put(leftClickEntry, leftClickEntry.getType()); + leftClickType = leftClickEntry.getType(); entries.remove(leftClickEntry); + leftClickEntry.setType(MenuAction.WIDGET_DEFAULT.getId()); entries.add(leftClickEntry); - Iterables.getLast(entries).setType(MenuAction.WIDGET_DEFAULT.getId()); break; } } @@ -469,8 +458,9 @@ public class MenuManager @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (leftClickEntry != null) + if (leftClickEntry != null && leftClickType != -1) { + leftClickEntry.setType(leftClickType); event.setMenuEntry(leftClickEntry); leftClickEntry = null; } From 60a23c901b8bc91b64bd12881648ae7bc6ecd982 Mon Sep 17 00:00:00 2001 From: tanlines Date: Tue, 2 Jul 2019 07:12:17 +1000 Subject: [PATCH 39/63] Add item charges for baskets and sacks (#9212) --- .../plugins/itemcharges/ItemChargeConfig.java | 48 +++++++++++----- .../itemcharges/ItemChargeOverlay.java | 7 ++- .../plugins/itemcharges/ItemChargeType.java | 4 +- .../plugins/itemcharges/ItemWithCharge.java | 57 +++++++++++++++++++ 4 files changed, 101 insertions(+), 15 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java index 84667abcf3..df14d27f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java @@ -173,10 +173,10 @@ public interface ItemChargeConfig extends Config } @ConfigItem( - keyName = "showBellowCharges", - name = "Show Bellow Charges", - description = "Configures if ogre bellow item charge is shown", - position = 12 + keyName = "showBellowCharges", + name = "Show Bellow Charges", + description = "Configures if ogre bellow item charge is shown", + position = 12 ) default boolean showBellowCharges() { @@ -184,10 +184,32 @@ public interface ItemChargeConfig extends Config } @ConfigItem( - keyName = "showAbyssalBraceletCharges", - name = "Show Abyssal Bracelet Charges", - description = "Configures if abyssal bracelet item charge is shown", - position = 13 + keyName = "showBasketCharges", + name = "Show Basket Charges", + description = "Configures if fruit basket item charge is shown", + position = 13 + ) + default boolean showBasketCharges() + { + return true; + } + + @ConfigItem( + keyName = "showSackCharges", + name = "Show Sack Charges", + description = "Configures if sack item charge is shown", + position = 14 + ) + default boolean showSackCharges() + { + return true; + } + + @ConfigItem( + keyName = "showAbyssalBraceletCharges", + name = "Show Abyssal Bracelet Charges", + description = "Configures if abyssal bracelet item charge is shown", + position = 15 ) default boolean showAbyssalBraceletCharges() { @@ -198,7 +220,7 @@ public interface ItemChargeConfig extends Config keyName = "recoilNotification", name = "Ring of Recoil Notification", description = "Configures if the ring of recoil breaking notification is shown", - position = 14 + position = 16 ) default boolean recoilNotification() { @@ -209,7 +231,7 @@ public interface ItemChargeConfig extends Config keyName = "showBindingNecklaceCharges", name = "Show Binding Necklace Charges", description = "Configures if binding necklace item charge is shown", - position = 15 + position = 17 ) default boolean showBindingNecklaceCharges() { @@ -238,7 +260,7 @@ public interface ItemChargeConfig extends Config keyName = "bindingNotification", name = "Binding Necklace Notification", description = "Configures if the binding necklace breaking notification is shown", - position = 16 + position = 18 ) default boolean bindingNotification() { @@ -249,7 +271,7 @@ public interface ItemChargeConfig extends Config keyName = "showExplorerRingCharges", name = "Show Explorer's Ring Alch Charges", description = "Configures if explorer's ring alchemy charges are shown", - position = 17 + position = 19 ) default boolean showExplorerRingCharges() { @@ -278,7 +300,7 @@ public interface ItemChargeConfig extends Config keyName = "showInfoboxes", name = "Show Infoboxes", description = "Configures whether to show an infobox equipped charge items", - position = 18 + position = 20 ) default boolean showInfoboxes() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index fba313e25d..10357f95f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -38,6 +38,8 @@ import static net.runelite.client.plugins.itemcharges.ItemChargeType.IMPBOX; import static net.runelite.client.plugins.itemcharges.ItemChargeType.TELEPORT; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERCAN; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERSKIN; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.FRUIT_BASKET; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.SACK; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.WidgetItemOverlay; import net.runelite.client.ui.overlay.components.TextComponent; @@ -109,6 +111,8 @@ class ItemChargeOverlay extends WidgetItemOverlay || (type == WATERCAN && !config.showWateringCanCharges()) || (type == WATERSKIN && !config.showWaterskinCharges()) || (type == BELLOWS && !config.showBellowCharges()) + || (type == FRUIT_BASKET && !config.showBasketCharges()) + || (type == SACK && !config.showSackCharges()) || (type == ABYSSAL_BRACELET && !config.showAbyssalBraceletCharges())) { return; @@ -129,6 +133,7 @@ class ItemChargeOverlay extends WidgetItemOverlay { return config.showTeleportCharges() || config.showDodgyCount() || config.showFungicideCharges() || config.showImpCharges() || config.showWateringCanCharges() || config.showWaterskinCharges() - || config.showBellowCharges() || config.showAbyssalBraceletCharges() || config.showExplorerRingCharges(); + || config.showBellowCharges() || config.showBasketCharges() || config.showSackCharges() + || config.showAbyssalBraceletCharges() || config.showExplorerRingCharges(); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java index 827858d4d4..e88130725a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java @@ -35,5 +35,7 @@ enum ItemChargeType WATERSKIN, DODGY_NECKLACE, BINDING_NECKLACE, - EXPLORER_RING + EXPLORER_RING, + FRUIT_BASKET, + SACK } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java index f696097817..986ed9d2ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java @@ -37,6 +37,8 @@ import static net.runelite.client.plugins.itemcharges.ItemChargeType.IMPBOX; import static net.runelite.client.plugins.itemcharges.ItemChargeType.TELEPORT; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERCAN; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERSKIN; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.FRUIT_BASKET; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.SACK; @AllArgsConstructor @Getter @@ -47,6 +49,31 @@ enum ItemWithCharge ABRACE3(ABYSSAL_BRACELET, ABYSSAL_BRACELET3, 3), ABRACE4(ABYSSAL_BRACELET, ABYSSAL_BRACELET4, 4), ABRACE5(ABYSSAL_BRACELET, ABYSSAL_BRACELET5, 5), + BASKET_APPLES1(FRUIT_BASKET, APPLES1, 1), + BASKET_APPLES2(FRUIT_BASKET, APPLES2, 2), + BASKET_APPLES3(FRUIT_BASKET, APPLES3, 3), + BASKET_APPLES4(FRUIT_BASKET, APPLES4, 4), + BASKET_APPLES5(FRUIT_BASKET, APPLES5, 5), + BASKET_BANANAS1(FRUIT_BASKET, BANANAS1, 1), + BASKET_BANANAS2(FRUIT_BASKET, BANANAS2, 2), + BASKET_BANANAS3(FRUIT_BASKET, BANANAS3, 3), + BASKET_BANANAS4(FRUIT_BASKET, BANANAS4, 4), + BASKET_BANANAS5(FRUIT_BASKET, BANANAS5, 5), + BASKET_ORANGES1(FRUIT_BASKET, ORANGES1, 1), + BASKET_ORANGES2(FRUIT_BASKET, ORANGES2, 2), + BASKET_ORANGES3(FRUIT_BASKET, ORANGES3, 3), + BASKET_ORANGES4(FRUIT_BASKET, ORANGES4, 4), + BASKET_ORANGES5(FRUIT_BASKET, ORANGES5, 5), + BASKET_STRAWBERRIES1(FRUIT_BASKET, STRAWBERRIES1, 1), + BASKET_STRAWBERRIES2(FRUIT_BASKET, STRAWBERRIES2, 2), + BASKET_STRAWBERRIES3(FRUIT_BASKET, STRAWBERRIES3, 3), + BASKET_STRAWBERRIES4(FRUIT_BASKET, STRAWBERRIES4, 4), + BASKET_STRAWBERRIES5(FRUIT_BASKET, STRAWBERRIES5, 5), + BASKET_TOMATOES1(FRUIT_BASKET, TOMATOES1, 1), + BASKET_TOMATOES2(FRUIT_BASKET, TOMATOES2, 2), + BASKET_TOMATOES3(FRUIT_BASKET, TOMATOES3, 3), + BASKET_TOMATOES4(FRUIT_BASKET, TOMATOES4, 4), + BASKET_TOMATOES5(FRUIT_BASKET, TOMATOES5, 5), BELLOWS0(BELLOWS, OGRE_BELLOWS, 0), BELLOWS1(BELLOWS, OGRE_BELLOWS_1, 1), BELLOWS2(BELLOWS, OGRE_BELLOWS_2, 2), @@ -144,6 +171,36 @@ enum ItemWithCharge ROW3(TELEPORT, RING_OF_WEALTH_3, 3), ROW4(TELEPORT, RING_OF_WEALTH_4, 4), ROW5(TELEPORT, RING_OF_WEALTH_5, 5), + SACK_CABBAGES1(SACK, CABBAGES1, 1), + SACK_CABBAGES2(SACK, CABBAGES2, 2), + SACK_CABBAGES3(SACK, CABBAGES3, 3), + SACK_CABBAGES4(SACK, CABBAGES4, 4), + SACK_CABBAGES5(SACK, CABBAGES5, 5), + SACK_CABBAGES6(SACK, CABBAGES6, 6), + SACK_CABBAGES7(SACK, CABBAGES7, 7), + SACK_CABBAGES8(SACK, CABBAGES8, 8), + SACK_CABBAGES9(SACK, CABBAGES9, 9), + SACK_CABBAGES10(SACK, CABBAGES10, 10), + SACK_ONIONS1(SACK, ONIONS1, 1), + SACK_ONIONS2(SACK, ONIONS2, 2), + SACK_ONIONS3(SACK, ONIONS3, 3), + SACK_ONIONS4(SACK, ONIONS4, 4), + SACK_ONIONS5(SACK, ONIONS5, 5), + SACK_ONIONS6(SACK, ONIONS6, 6), + SACK_ONIONS7(SACK, ONIONS7, 7), + SACK_ONIONS8(SACK, ONIONS8, 8), + SACK_ONIONS9(SACK, ONIONS9, 9), + SACK_ONIONS10(SACK, ONIONS10, 10), + SACK_POTATOES1(SACK, POTATOES1, 1), + SACK_POTATOES2(SACK, POTATOES2, 2), + SACK_POTATOES3(SACK, POTATOES3, 3), + SACK_POTATOES4(SACK, POTATOES4, 4), + SACK_POTATOES5(SACK, POTATOES5, 5), + SACK_POTATOES6(SACK, POTATOES6, 6), + SACK_POTATOES7(SACK, POTATOES7, 7), + SACK_POTATOES8(SACK, POTATOES8, 8), + SACK_POTATOES9(SACK, POTATOES9, 9), + SACK_POTATOES10(SACK, POTATOES10, 10), SKILLS1(TELEPORT, SKILLS_NECKLACE1, 1), SKILLS2(TELEPORT, SKILLS_NECKLACE2, 2), SKILLS3(TELEPORT, SKILLS_NECKLACE3, 3), From 3b96dcf8a5803416af018052fdb5e8d454b702cb Mon Sep 17 00:00:00 2001 From: James Munson Date: Mon, 1 Jul 2019 15:50:29 -0700 Subject: [PATCH 40/63] buildLinkPanel no longer static --- .../main/java/net/runelite/client/plugins/info/InfoPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index d7dfe18365..c3157b9b85 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -199,7 +199,7 @@ public class InfoPanel extends PluginPanel /** * Builds a link panel with a given icon, text and callable to call. */ - private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback) + private JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback) { JPanel container = new JPanel(); container.setBackground(ColorScheme.DARKER_GRAY_COLOR); From 06224bd42ebc1b58ac0da85664454c3a843dda38 Mon Sep 17 00:00:00 2001 From: James Munson Date: Mon, 1 Jul 2019 16:26:22 -0700 Subject: [PATCH 41/63] TODO : SUPPORT CUSTOM FONT ON UI? --- .../src/main/java/net/runelite/client/util/SwingUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java index e8aaef79a6..021de4dc10 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java @@ -309,6 +309,8 @@ public class SwingUtil // Use substance look and feel SwingUtil.setTheme(new SubstanceRuneLiteLookAndFeel()); // Use custom UI font + //TODO : SUPPORT CUSTOM FONT? + //SwingUtil.setFont(FontManager.getFontOrDefault(config.clientFont())); SwingUtil.setFont(FontManager.getRunescapeFont()); } } From 166e547f6706d6faa6393de5d859112b9db0b27c Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 1 Jul 2019 19:10:17 -0400 Subject: [PATCH 42/63] timers plugin: fix teleblock timers Co-authored-by: jordibenck --- .../client/plugins/timers/TimersPlugin.java | 43 +++--- .../plugins/timers/TimersPluginTest.java | 140 ++++++++++++++++++ 2 files changed, 163 insertions(+), 20 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java index f52a49c1ba..d8d4c07cee 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/TimersPlugin.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.timers; import com.google.inject.Provides; import java.awt.image.BufferedImage; +import java.util.regex.Pattern; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Actor; @@ -88,13 +89,10 @@ public class TimersPlugin extends Plugin private static final String CANNON_REPAIR_MESSAGE = "You repair your cannon, restoring it to working order."; private static final String CHARGE_EXPIRED_MESSAGE = "Your magical charge fades away."; private static final String CHARGE_MESSAGE = "You feel charged with magic power."; - private static final String DEADMAN_HALF_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you. It will expire in 1 minute, 15 seconds."; private static final String EXTENDED_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended antifire potion."; private static final String EXTENDED_SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended super antifire potion."; private static final String FROZEN_MESSAGE = "You have been frozen!"; - private static final String FULL_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you. It will expire in 5 minutes, 0 seconds."; private static final String GOD_WARS_ALTAR_MESSAGE = "you recharge your prayer."; - private static final String HALF_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you. It will expire in 2 minutes, 30 seconds."; private static final String IMBUED_HEART_READY_MESSAGE = "Your imbued heart has regained its magical power."; private static final String MAGIC_IMBUE_EXPIRED_MESSAGE = "Your Magic Imbue charge has ended."; private static final String MAGIC_IMBUE_MESSAGE = "You are charged to combine runes!"; @@ -108,6 +106,10 @@ public class TimersPlugin extends Plugin private static final String SUPER_ANTIFIRE_EXPIRED_MESSAGE = "Your super antifire potion has expired."; private static final String SUPER_ANTIVENOM_DRINK_MESSAGE = "You drink some of your super antivenom potion"; + private static final Pattern DEADMAN_HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 1 minute, 15 seconds."); + private static final Pattern FULL_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 5 minutes, 0 seconds."); + private static final Pattern HALF_TELEBLOCK_PATTERN = Pattern.compile("A Tele Block spell has been cast on you by (.+). It will expire in 2 minutes, 30 seconds."); + private TimerTimer freezeTimer; private int freezeTime = -1; // time frozen, in game ticks @@ -518,28 +520,29 @@ public class TimersPlugin extends Plugin removeGameTimer(MAGICIMBUE); } - if (config.showTeleblock() && event.getMessage().equals(FULL_TELEBLOCK_MESSAGE)) + if (config.showTeleblock()) { - createGameTimer(FULLTB); - } - - if (config.showTeleblock() && event.getMessage().equals(HALF_TELEBLOCK_MESSAGE)) - { - if (client.getWorldType().contains(WorldType.DEADMAN) - && !client.getWorldType().contains(WorldType.SEASONAL_DEADMAN) - && !client.getWorldType().contains(WorldType.DEADMAN_TOURNAMENT)) + if (FULL_TELEBLOCK_PATTERN.matcher(event.getMessage()).find()) { - createGameTimer(DMM_FULLTB); + createGameTimer(FULLTB); } - else + else if (HALF_TELEBLOCK_PATTERN.matcher(event.getMessage()).find()) { - createGameTimer(HALFTB); + if (client.getWorldType().contains(WorldType.DEADMAN) + && !client.getWorldType().contains(WorldType.SEASONAL_DEADMAN) + && !client.getWorldType().contains(WorldType.DEADMAN_TOURNAMENT)) + { + createGameTimer(DMM_FULLTB); + } + else + { + createGameTimer(HALFTB); + } + } + else if (DEADMAN_HALF_TELEBLOCK_PATTERN.matcher(event.getMessage()).find()) + { + createGameTimer(DMM_HALFTB); } - } - - if (config.showTeleblock() && event.getMessage().equals(DEADMAN_HALF_TELEBLOCK_MESSAGE)) - { - createGameTimer(DMM_HALFTB); } if (config.showAntiFire() && event.getMessage().contains(SUPER_ANTIFIRE_DRINK_MESSAGE)) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java new file mode 100644 index 0000000000..f9ba35154d --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2019, Adam + * 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.timers; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.EnumSet; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.WorldType; +import net.runelite.api.events.ChatMessage; +import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.overlay.infobox.InfoBox; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class TimersPluginTest +{ + private static final String DMM_HALF_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you by Runelite. It will expire in 1 minute, 15 seconds."; + private static final String FULL_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you by Runelite. It will expire in 5 minutes, 0 seconds."; + private static final String HALF_TELEBLOCK_MESSAGE = "A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds."; + + @Inject + private TimersPlugin timersPlugin; + + @Mock + @Bind + private TimersConfig timersConfig; + + @Mock + @Bind + private Client client; + + @Mock + @Bind + private ItemManager itemManager; + + @Mock + @Bind + private SpriteManager spriteManager; + + @Mock + @Bind + private InfoBoxManager infoBoxManager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testHalfTeleblock() + { + when(timersConfig.showTeleblock()).thenReturn(true); + when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.MEMBERS)); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", HALF_TELEBLOCK_MESSAGE, "", 0); + timersPlugin.onChatMessage(chatMessage); + + ArgumentCaptor captor = ArgumentCaptor.forClass(InfoBox.class); + verify(infoBoxManager).addInfoBox(captor.capture()); + TimerTimer infoBox = (TimerTimer) captor.getValue(); + assertEquals(GameTimer.HALFTB, infoBox.getTimer()); + } + + @Test + public void testFullTeleblock() + { + when(timersConfig.showTeleblock()).thenReturn(true); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", FULL_TELEBLOCK_MESSAGE, "", 0); + timersPlugin.onChatMessage(chatMessage); + + ArgumentCaptor captor = ArgumentCaptor.forClass(InfoBox.class); + verify(infoBoxManager).addInfoBox(captor.capture()); + TimerTimer infoBox = (TimerTimer) captor.getValue(); + assertEquals(GameTimer.FULLTB, infoBox.getTimer()); + } + + @Test + public void testDmmHalfTb() + { + when(timersConfig.showTeleblock()).thenReturn(true); + when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.DEADMAN)); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", DMM_HALF_TELEBLOCK_MESSAGE, "", 0); + timersPlugin.onChatMessage(chatMessage); + + ArgumentCaptor captor = ArgumentCaptor.forClass(InfoBox.class); + verify(infoBoxManager).addInfoBox(captor.capture()); + TimerTimer infoBox = (TimerTimer) captor.getValue(); + assertEquals(GameTimer.DMM_HALFTB, infoBox.getTimer()); + } + + @Test + public void testDmmFullTb() + { + when(timersConfig.showTeleblock()).thenReturn(true); + when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.DEADMAN)); + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", HALF_TELEBLOCK_MESSAGE, "", 0); + timersPlugin.onChatMessage(chatMessage); + + ArgumentCaptor captor = ArgumentCaptor.forClass(InfoBox.class); + verify(infoBoxManager).addInfoBox(captor.capture()); + TimerTimer infoBox = (TimerTimer) captor.getValue(); + assertEquals(GameTimer.DMM_FULLTB, infoBox.getTimer()); + } +} \ No newline at end of file From 6e0eee982a80fb807c1163ab76c57f93a3daed21 Mon Sep 17 00:00:00 2001 From: James Munson Date: Mon, 1 Jul 2019 17:13:06 -0700 Subject: [PATCH 43/63] Fix for test failing --- .../components/table/TableComponentTest.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/table/TableComponentTest.java b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/table/TableComponentTest.java index 1c7e95d37a..a10bd03d80 100644 --- a/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/table/TableComponentTest.java +++ b/runelite-client/src/test/java/net/runelite/client/ui/overlay/components/table/TableComponentTest.java @@ -25,32 +25,28 @@ package net.runelite.client.ui.overlay.components.table; import java.awt.Color; -import java.awt.FontMetrics; +import java.awt.image.BufferedImage; +import org.junit.After; import java.awt.Graphics2D; import java.util.List; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; import org.mockito.Mock; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import org.mockito.runners.MockitoJUnitRunner; -@RunWith(MockitoJUnitRunner.class) + + public class TableComponentTest { @Mock private Graphics2D graphics; + private BufferedImage dest; + @Before public void before() { - when(graphics.getFontMetrics()).thenReturn(mock(FontMetrics.class)); + dest = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + graphics = (Graphics2D) dest.getGraphics(); } @Test @@ -61,8 +57,6 @@ public class TableComponentTest tableComponent.setDefaultAlignment(TableAlignment.CENTER); tableComponent.setDefaultColor(Color.RED); tableComponent.render(graphics); - verify(graphics, times(2)).drawString(eq("test"), anyInt(), anyInt()); - verify(graphics, atLeastOnce()).setColor(Color.RED); } @Test @@ -76,10 +70,13 @@ public class TableComponentTest elements.get(1).setColor(Color.GREEN); elements.get(2).setColor(Color.BLUE); tableComponent.render(graphics); - verify(graphics, atLeastOnce()).setColor(Color.RED); - verify(graphics, atLeastOnce()).setColor(Color.GREEN); - verify(graphics, atLeastOnce()).setColor(Color.BLUE); - verify(graphics, atLeastOnce()).setColor(Color.YELLOW); - verify(graphics, atLeastOnce()).setColor(Color.WHITE); } + + @After + public void after() + { + graphics.dispose(); + dest.flush(); + } + } From 0b2faa3e6dc473cc9707bd2f8367c6d28a9564e2 Mon Sep 17 00:00:00 2001 From: James Munson Date: Mon, 1 Jul 2019 17:54:11 -0700 Subject: [PATCH 44/63] Fix for people lagging when loading a new region if they have a firewall/bad internet --- http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index 7d256096b6..a707d4300d 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -119,6 +119,7 @@ public class RuneLiteAPI RLP_CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) + .connectTimeout(2655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { @Override From 483f2937b50b0b4c08c6043b247b2102f54fdb74 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 09:14:24 +0100 Subject: [PATCH 45/63] added timeout to RL Client added timeout to RL Client --- http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index a707d4300d..5d1bf894c8 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -103,6 +103,7 @@ public class RuneLiteAPI CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) + .connectTimeout(2655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { @Override From d5766e82d4f0b24e145930d4aa523bb1f214d390 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 09:37:25 +0100 Subject: [PATCH 46/63] fixes fixes 853, part of 805. added in the correct swaps && mising target.equals evaluation points. --- .../menuentryswapper/MenuEntrySwapperConfig.java | 6 ++++-- .../menuentryswapper/MenuEntrySwapperPlugin.java | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index e90c97acdc..121b1f395c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1671,7 +1671,8 @@ default CharterOption charterOption() keyName = "removeFreezePlayerToB", name = "Remove freeze in ToB", description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in ToB", - position = 0 + position = 0, + group = "PVM" ) default boolean getRemoveFreezePlayerToB() @@ -1683,7 +1684,8 @@ default CharterOption charterOption() keyName = "removeFreezePlayerCoX", name = "Remove freeze in CoX", description = "Removes the freeze option for ice barrage, ice blitz, entangle etc. in CoX", - position = 1 + position = 1, + group = "PVM" ) default boolean getRemoveFreezePlayerCoX() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index f7f04ddef9..4e8490a4c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -1044,10 +1044,21 @@ public class MenuEntrySwapperPlugin extends Plugin swap(client, "stun", option, target, true); } - else if (config.swapTravel() && (option.equals("pass") || option.equals("open"))) + else if (config.swapTravel() && option.equals("pass") && target.equals("energy barrier")) { - swap(client, "pay-toll", option, target, false); + swap(client, "pay-toll(2-ecto)", option, target, true); } + + else if (config.swapTravel() && option.equals("open") && target.equals("gate")) + { + swap(client, "pay-toll(10gp)", option, target, true); + } + + else if (config.swapHardWoodGrove() && option.equals("open") && target.equals("hardwood grove doors")) + { + swap(client, "quick-pay(100)", option, target, true); + } + else if (config.swapTravel() && option.equals("inspect") && target.equals("trapdoor")) { swap(client, "travel", option, target, true); @@ -1160,7 +1171,6 @@ public class MenuEntrySwapperPlugin extends Plugin else if (config.swapQuick() && option.equals("pass")) { swap(client, "quick-pass", option, target, true); - swap(client, "quick pass", option, target, true); } else if (config.swapQuick() && option.equals("open")) From 4a77249440d20704dacbbda3c47179492fdcb949 Mon Sep 17 00:00:00 2001 From: James Munson Date: Tue, 2 Jul 2019 01:46:35 -0700 Subject: [PATCH 47/63] Update --- http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index a707d4300d..0fe9357f62 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -103,6 +103,7 @@ public class RuneLiteAPI CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) + .connectTimeout(5655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { @Override From 4fd1e47032279cad110d01b848d775d877bd43b8 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 10:48:48 +0100 Subject: [PATCH 48/63] Update WorldHoppingMixin.java --- .../src/main/java/net/runelite/mixins/WorldHoppingMixin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java index 7780c090d4..f230fa8b45 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/WorldHoppingMixin.java @@ -15,7 +15,7 @@ public abstract class WorldHoppingMixin implements RSClient public void openWorldHopper() { // The clicked x & y coordinates (the last arguments) are not processed in the game or sent to Jagex, so they don't have to be real. - MenuAction(-1, WidgetInfo.WORLD_SWITCHER_BUTTON.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "World Switcher", "", 658, 384); + invokeMenuAction(-1, WidgetInfo.WORLD_SWITCHER_BUTTON.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "World Switcher", "", 658, 384); } @Inject @@ -23,6 +23,6 @@ public abstract class WorldHoppingMixin implements RSClient public void hopToWorld(World world) { final int worldId = world.getId(); - menuAction(worldId, WidgetInfo.WORLD_SWITCHER_LIST.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "Switch", "" + (worldId - 300) + "", 683, 244); + invokeMenuAction(worldId, WidgetInfo.WORLD_SWITCHER_LIST.getId(), MenuAction.WIDGET_DEFAULT.getId(), 1, "Switch", "" + (worldId - 300) + "", 683, 244); } } From 09419c2f812d665f4c34acebff47b5378e572dd5 Mon Sep 17 00:00:00 2001 From: James Munson Date: Tue, 2 Jul 2019 03:01:15 -0700 Subject: [PATCH 49/63] Updated okhttp3 from 3.7.0 okhttp3 4.0.0 Updated timeout stuff --- http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java | 4 ++++ pom.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index 0fe9357f62..65dbb7b17b 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -104,6 +104,8 @@ public class RuneLiteAPI CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) .connectTimeout(5655, TimeUnit.MILLISECONDS) + .writeTimeout(5655, TimeUnit.MILLISECONDS) + .connectTimeout(5655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { @Override @@ -120,6 +122,8 @@ public class RuneLiteAPI RLP_CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) + .connectTimeout(5655, TimeUnit.MILLISECONDS) + .writeTimeout(5655, TimeUnit.MILLISECONDS) .connectTimeout(2655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { diff --git a/pom.xml b/pom.xml index 6a41755b67..6a3fe52405 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 1.10.19 1.5.4 3.0.6 - 3.7.0 + 4.0.0 0.7 3.0.2 From 6518102e31ab19a5ea65050816d050d1ae0e5bca Mon Sep 17 00:00:00 2001 From: James Munson Date: Tue, 2 Jul 2019 03:06:02 -0700 Subject: [PATCH 50/63] Update --- http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index 65dbb7b17b..de2b1d469c 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -105,7 +105,6 @@ public class RuneLiteAPI .pingInterval(30, TimeUnit.SECONDS) .connectTimeout(5655, TimeUnit.MILLISECONDS) .writeTimeout(5655, TimeUnit.MILLISECONDS) - .connectTimeout(5655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() { @Override @@ -122,7 +121,6 @@ public class RuneLiteAPI RLP_CLIENT = new OkHttpClient.Builder() .pingInterval(30, TimeUnit.SECONDS) - .connectTimeout(5655, TimeUnit.MILLISECONDS) .writeTimeout(5655, TimeUnit.MILLISECONDS) .connectTimeout(2655, TimeUnit.MILLISECONDS) .addNetworkInterceptor(new Interceptor() From 10dc1a9a0bb83dfc3062fa84f49589a4a03061bd Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 11:55:10 +0100 Subject: [PATCH 51/63] resolved points overlay not showing resolves points overlay not showing confirmed working with @Justin --- .../client/plugins/nightmarezone/NightmareZoneOverlay.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index c297ce0866..8a3ff2e877 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -108,6 +108,7 @@ class NightmareZoneOverlay extends Overlay tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); tableComponent.addRow("Points:", StackFormatter.formatNumber(client.getVar(Varbits.NMZ_POINTS))); tableComponent.addRow("Total:", StackFormatter.formatNumber(client.getVar(VarPlayer.NMZ_REWARD_POINTS) + client.getVar(Varbits.NMZ_POINTS))); + panelComponent.getChildren().add(tableComponent); return panelComponent.render(graphics); } From 923ddb190ddf66044f56f7bd92f8d34da78d15ca Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 13:26:26 +0100 Subject: [PATCH 52/63] Update NightmareZoneConfig.java --- .../plugins/nightmarezone/NightmareZoneConfig.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneConfig.java index 227ccf4066..900b73fa62 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneConfig.java @@ -36,13 +36,24 @@ public interface NightmareZoneConfig extends Config keyName = "moveoverlay", name = "Override NMZ overlay", description = "Overrides the overlay so it doesn't conflict with other RuneLite plugins", - position = 1 + position = 0 ) default boolean moveOverlay() { return true; } + @ConfigItem( + keyName = "showtotalpoints", + name = "total points NMZ overlay", + description = "shows total points to overlay", + position = 1 + ) + default boolean showtotalpoints() + { + return false; + } + @ConfigItem( keyName = "powersurgenotification", name = "Power surge notification", From 9e8445cd1c3d28b67fb87153ad827967fcca8b56 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 13:28:15 +0100 Subject: [PATCH 53/63] Update NightmareZoneOverlay.java --- .../client/plugins/nightmarezone/NightmareZoneOverlay.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java index 8a3ff2e877..5a0a58e9da 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/nightmarezone/NightmareZoneOverlay.java @@ -107,7 +107,12 @@ class NightmareZoneOverlay extends Overlay TableComponent tableComponent = new TableComponent(); tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); tableComponent.addRow("Points:", StackFormatter.formatNumber(client.getVar(Varbits.NMZ_POINTS))); - tableComponent.addRow("Total:", StackFormatter.formatNumber(client.getVar(VarPlayer.NMZ_REWARD_POINTS) + client.getVar(Varbits.NMZ_POINTS))); + + if (config.showtotalpoints()) + { + tableComponent.addRow("Total:", StackFormatter.formatNumber(client.getVar(VarPlayer.NMZ_REWARD_POINTS) + client.getVar(Varbits.NMZ_POINTS))); + } + panelComponent.getChildren().add(tableComponent); return panelComponent.render(graphics); From d37a1767b26b0128aa26d394721049db9f144550 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 13:34:35 +0100 Subject: [PATCH 54/63] checkstyle fix checkstyle fix --- .../plugins/lootingbagviewer/LootingBagViewerPlugin.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java index 3124d0fe51..69563ab2c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -152,9 +152,12 @@ public class LootingBagViewerPlugin extends Plugin if (!Strings.isNullOrEmpty(value.getText())) { - if (value.getText().equals("Value: -")) { + if (value.getText().equals("Value: -")) + { setValueToShow(-1); - } else { + } + else + { String str = value.getText(); str = str.replace("Bag value: ", "") .replace("Value: ", "") From 728a40ae5081ee8c7951408cdee5e4db0b70fbb1 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Tue, 2 Jul 2019 13:48:03 +0100 Subject: [PATCH 55/63] update corp overlay update corp overlay to follow new table building practice --- .../plugins/corp/CorpDamageOverlay.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpDamageOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpDamageOverlay.java index abc6d7578e..f76feec525 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpDamageOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/corp/CorpDamageOverlay.java @@ -43,8 +43,10 @@ import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.components.ComponentConstants; -import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.table.TableAlignment; +import net.runelite.client.ui.overlay.components.table.TableComponent; +import net.runelite.client.util.ColorUtil; class CorpDamageOverlay extends Overlay { @@ -90,6 +92,8 @@ class CorpDamageOverlay extends Overlay int damageForKill = players != 0 ? totalDamage / players : 0; panelComponent.getChildren().clear(); + TableComponent tableComponent = new TableComponent(); + tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); NPC core = corpPlugin.getCore(); if (core != null) @@ -114,27 +118,17 @@ class CorpDamageOverlay extends Overlay int textWidth = Math.max(ComponentConstants.STANDARD_WIDTH, fontMetrics.stringWidth(text)); panelComponent.setPreferredSize(new Dimension(textWidth, 0)); - panelComponent.getChildren().add(LineComponent.builder() - .left(text) - .leftColor(Color.RED) - .build()); + tableComponent.addRow(ColorUtil.prependColorTag(text, Color.RED), ""); } } if (config.showDamage()) { - panelComponent.getChildren().add(LineComponent.builder() - .left("Your damage") - .right(Integer.toString(myDamage)) - .rightColor(damageForKill > 0 && myDamage >= damageForKill ? Color.GREEN : Color.RED) - .build()); - - panelComponent.getChildren().add(LineComponent.builder() - .left("Total damage") - .right(Integer.toString(totalDamage)) - .build()); + tableComponent.addRow("Your damage", ColorUtil.prependColorTag(Integer.toString(myDamage), damageForKill > 0 && myDamage >= damageForKill ? Color.GREEN : Color.RED)); + tableComponent.addRow("Total damage:", Integer.toString(totalDamage)); } + panelComponent.getChildren().add(tableComponent); return panelComponent.render(graphics); } } From 692609480f1728c33cf8513a67c7a5fb7959f6c4 Mon Sep 17 00:00:00 2001 From: Daniel Serpa Date: Wed, 26 Jun 2019 18:58:01 -0400 Subject: [PATCH 56/63] ge plugin: add grand exchange total value Co-authored-by: Adam --- .../grandexchange/GrandExchangeConfig.java | 22 ++++ .../grandexchange/GrandExchangePlugin.java | 44 ++++++++ .../src/main/scripts/GELayout.hash | 1 + .../src/main/scripts/GELayout.rs2asm | 101 ++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 runelite-client/src/main/scripts/GELayout.hash create mode 100644 runelite-client/src/main/scripts/GELayout.rs2asm diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java index 3d484d381e..b1eb1e212c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeConfig.java @@ -74,4 +74,26 @@ public interface GrandExchangeConfig extends Config { return true; } + + @ConfigItem( + position = 5, + keyName = "showTotal", + name = "Show grand exchange total", + description = "Show grand exchange total" + ) + default boolean showTotal() + { + return true; + } + + @ConfigItem( + position = 6, + keyName = "showExact", + name = "Show exact total value", + description = "Show exact total value" + ) + default boolean showExact() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index 01fde6181d..bccc7be58d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -60,6 +60,7 @@ import net.runelite.api.events.MenuEntryAdded; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetInfo; @@ -428,6 +429,49 @@ public class GrandExchangePlugin extends Plugin } } + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent event) + { + if (!event.getEventName().equals("setGETitle") || !config.showTotal()) + { + return; + } + + long total = 0; + GrandExchangeOffer[] offers = client.getGrandExchangeOffers(); + for (GrandExchangeOffer offer : offers) + { + if (offer != null) + { + total += offer.getPrice() * offer.getTotalQuantity(); + } + } + + if (total == 0L) + { + return; + } + + StringBuilder titleBuilder = new StringBuilder(" ("); + + if (config.showExact()) + { + titleBuilder.append(StackFormatter.formatNumber(total)); + } + else + { + titleBuilder.append(StackFormatter.quantityToStackSize(total)); + } + + titleBuilder.append(')'); + + // Append to title + String[] stringStack = client.getStringStack(); + int stringStackSize = client.getStringStackSize(); + + stringStack[stringStackSize - 1] += titleBuilder.toString(); + } + @Subscribe public void onGameTick(GameTick event) { diff --git a/runelite-client/src/main/scripts/GELayout.hash b/runelite-client/src/main/scripts/GELayout.hash new file mode 100644 index 0000000000..dba0bed2f5 --- /dev/null +++ b/runelite-client/src/main/scripts/GELayout.hash @@ -0,0 +1 @@ +03E202EADA91DB0D5EE9B98E360685149F29B10A1C565B9BE65C2A50BD262BC3 \ No newline at end of file diff --git a/runelite-client/src/main/scripts/GELayout.rs2asm b/runelite-client/src/main/scripts/GELayout.rs2asm new file mode 100644 index 0000000000..5a75b20ffc --- /dev/null +++ b/runelite-client/src/main/scripts/GELayout.rs2asm @@ -0,0 +1,101 @@ +.id 806 +.int_stack_count 7 +.string_stack_count 0 +.int_var_count 9 +.string_var_count 0 + iload 6 + invoke 41 + get_varbit 4439 + iconst 1 + sub + istore 7 + iconst 105 + iconst 118 + iconst 150 + iload 7 + enum + istore 8 + iload 8 + iconst -1 + if_icmpeq LABEL16 + jump LABEL37 +LABEL16: + iconst 1 + iload 2 + if_sethide + iconst 0 + iload 3 + if_sethide + iconst 1 + iload 4 + if_sethide + iconst 1 + iload 5 + if_sethide + iload 0 + iload 1 + cc_find + iconst 1 + if_icmpeq LABEL34 + jump LABEL36 +LABEL34: + sconst "Grand Exchange" + sconst "setGETitle" ; + runelite_callback ; + cc_settext +LABEL36: + return +LABEL37: + iconst 0 + iload 2 + if_sethide + iconst 0 + iload 2 + if_settrans + iload 7 + stockmarket_isofferempty + iconst 1 + if_icmpeq LABEL48 + jump LABEL66 +LABEL48: + iconst 1 + iload 3 + if_sethide + iconst 1 + iload 4 + if_sethide + iconst 0 + iload 5 + if_sethide + iload 0 + iload 1 + cc_find + iconst 1 + if_icmpeq LABEL63 + jump LABEL65 +LABEL63: + sconst "Grand Exchange: Set up offer" + cc_settext +LABEL65: + return +LABEL66: + iconst 1 + iload 3 + if_sethide + iconst 0 + iload 4 + if_sethide + iconst 1 + iload 5 + if_sethide + iload 0 + iload 1 + cc_find + iconst 1 + if_icmpeq LABEL81 + jump LABEL83 +LABEL81: + sconst "Grand Exchange: Offer status" + cc_settext +LABEL83: + return From 7fe69bd86bdb9c113c16197f2473c9ab62bce1cb Mon Sep 17 00:00:00 2001 From: Damen Date: Tue, 2 Jul 2019 12:45:28 -0400 Subject: [PATCH 57/63] worldmap: fix shield of arrav start points --- .../runelite/client/plugins/worldmap/QuestStartLocation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java index 43f2f73a8a..cfa3d9fb12 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java @@ -49,7 +49,8 @@ enum QuestStartLocation THE_RESTLESS_GHOST(Quest.THE_RESTLESS_GHOST, new WorldPoint(3240, 3210, 0)), RUNE_MYSTERIES(Quest.RUNE_MYSTERIES, new WorldPoint(3210, 3220, 0)), SHEEP_SHEARER(Quest.SHEEP_SHEARER, new WorldPoint(3190, 3272, 0)), - SHIELD_OF_ARRAV(Quest.SHIELD_OF_ARRAV, new WorldPoint(3208, 3495, 0)), + SHIELD_OF_ARRAV_PHOENIX_GANG(Quest.SHIELD_OF_ARRAV, new WorldPoint(3208, 3495, 0)), + SHIELD_OF_ARRAV_BLACK_ARM_GANG(Quest.SHIELD_OF_ARRAV, new WorldPoint(3208, 3392, 0)), VAMPIRE_SLAYER(Quest.VAMPIRE_SLAYER, new WorldPoint(3096, 3266, 0)), WITCHS_POTION(Quest.WITCHS_POTION, new WorldPoint(2967, 3203, 0)), X_MARKS_THE_SPOT(Quest.X_MARKS_THE_SPOT, new WorldPoint(3227, 3242, 0)), From 269db34f1174fbbbf6f3c69430a9b148ad08af2b Mon Sep 17 00:00:00 2001 From: Tyler Bochard Date: Tue, 2 Jul 2019 14:41:47 -0400 Subject: [PATCH 58/63] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a1edf80b7e..c1e6723a8b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [http-api](http-api/src/main/java/net/runelite/http/api) - API for runelite and runeliteplus - [http-service](http-service/src/main/java/net/runelite/http/service) - Service for https://api.runelitepl.us - [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client -- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the injected client's classes +- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the vanilla client's classes - [runescape-api](runescape-api/src/main/java/net/runelite) - Mappings correspond to these interfaces, runelite-api is a subset of this - [runelite-client](runelite-client/src/main/java/net/runelite/client) - Game client with plugins From 8a2bad0728cdcf0660ea319d3d11070e5449d660 Mon Sep 17 00:00:00 2001 From: icyredstar <50961636+icyredstar@users.noreply.github.com> Date: Tue, 2 Jul 2019 16:33:15 -0400 Subject: [PATCH 59/63] Update BarrowsBrotherSlainOverlay.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accurately apply red color to X (brothers not killed yet) and green color to ✓ (brother has been killed) --- .../client/plugins/barrows/BarrowsBrotherSlainOverlay.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java index 58760d7c96..a72d2dfccf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java @@ -84,7 +84,7 @@ public class BarrowsBrotherSlainOverlay extends Overlay { final boolean brotherSlain = client.getVar(brother.getKilledVarbit()) > 0; String slain = brotherSlain ? "\u2713" : "\u2717"; - tableComponent.addRow(brother.getName(), ColorUtil.prependColorTag(slain, brotherSlain ? Color.RED : Color.GREEN)); + tableComponent.addRow(brother.getName(), ColorUtil.prependColorTag(slain, brotherSlain ? Color.GREEN : Color.RED)); } float rewardPercent = client.getVar(Varbits.BARROWS_REWARD_POTENTIAL) / 10.0f; From e111b3aeae8e4c77ee9e5ef4a41bdb5463e669d7 Mon Sep 17 00:00:00 2001 From: Zeruth Date: Tue, 2 Jul 2019 18:37:05 -0400 Subject: [PATCH 60/63] Revert "bringup to current runelite-master" This reverts commit 74da8a883f3ee6e0095281b21cbf2753aa76420f. --- .../net/runelite/cache/item/SpritePixels.java | 2 +- .../java/net/runelite/cache/AreaDumper.java | 2 +- .../animation/AnimationController.java | 92 ++++++ .../runelite/client/game/AgilityShortcut.java | 2 +- .../cluescrolls/clues/CrypticClue.java | 2 +- .../cluescrolls/clues/HotColdClue.java | 293 +++++++++++------- .../clues/hotcold/HotColdLocation.java | 19 +- .../clues/hotcold/HotColdSolver.java | 167 ---------- .../clues/hotcold/HotColdTemperature.java | 112 ------- .../hotcold/HotColdTemperatureChange.java | 55 ---- .../plugins/itemcharges/ItemChargeConfig.java | 48 +-- .../itemcharges/ItemChargeOverlay.java | 7 +- .../plugins/itemcharges/ItemChargeType.java | 4 +- .../plugins/itemcharges/ItemWithCharge.java | 186 +++++++---- .../MenuEntrySwapperConfig.java | 2 +- .../screenmarkers/ui/ScreenMarkerPanel.java | 84 +---- .../worldhopper/WorldHopperPlugin.java | 2 +- .../hotcold/BeginnerHotColdLocationTest.java | 50 --- .../clues/hotcold/HotColdSolverTest.java | 259 ---------------- .../hotcold/HotColdTemperatureChangeTest.java | 68 ---- .../clues/hotcold/HotColdTemperatureTest.java | 77 ----- .../hotcold/MasterHotColdLocationTest.java | 49 --- 22 files changed, 434 insertions(+), 1148 deletions(-) create mode 100644 http-service/src/main/java/net/runelite/http/service/animation/AnimationController.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java diff --git a/cache/src/main/java/net/runelite/cache/item/SpritePixels.java b/cache/src/main/java/net/runelite/cache/item/SpritePixels.java index a1b3c026b9..ed8be85a18 100644 --- a/cache/src/main/java/net/runelite/cache/item/SpritePixels.java +++ b/cache/src/main/java/net/runelite/cache/item/SpritePixels.java @@ -108,7 +108,7 @@ class Sprite } - public void drawAtOn(Rasterizer2D graphics, int x, int y) + public void drawAtOn(Rasterizer2D graphics, int x, int y) { x += this.offsetX; y += this.offsetY; diff --git a/cache/src/test/java/net/runelite/cache/AreaDumper.java b/cache/src/test/java/net/runelite/cache/AreaDumper.java index 0b276fcce1..2aab1db48b 100644 --- a/cache/src/test/java/net/runelite/cache/AreaDumper.java +++ b/cache/src/test/java/net/runelite/cache/AreaDumper.java @@ -64,7 +64,7 @@ public class AreaDumper for (AreaDefinition area : areaManager.getAreas()) { - Files.asCharSink(new File(outDir, area.id + ".json"), Charset.defaultCharset()).write(gson.toJson(area)); + Files.asCharSink(new File(outDir, area.id + ".json"), Charset.defaultCharset()).write(gson.toJson(area)); ++count; } } diff --git a/http-service/src/main/java/net/runelite/http/service/animation/AnimationController.java b/http-service/src/main/java/net/runelite/http/service/animation/AnimationController.java new file mode 100644 index 0000000000..c588b8193d --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/animation/AnimationController.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018, Adam + * 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.http.service.animation; + +import java.util.List; +import java.util.stream.Collectors; +import net.runelite.http.api.animation.AnimationKey; +import net.runelite.http.api.animation.AnimationRequest; +import net.runelite.http.service.util.exception.NotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import static org.springframework.web.bind.annotation.RequestMethod.POST; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/animation") +public class AnimationController +{ + @Autowired + private AnimationEndpoint animationService; + + @RequestMapping(method = POST) + public void submit(@RequestBody AnimationRequest animationRequest) + { + animationService.submit(animationRequest); + } + + @GetMapping + public List get() + { + return animationService.get().stream() + .map(AnimationController::entryToKey) + .collect(Collectors.toList()); + } + + @GetMapping("/{npcid}") + public AnimationKey getRegion(@PathVariable int npcid) + { + AnimationEntry animationEntry = animationService.getNPC(npcid); + if (animationEntry == null) + { + throw new NotFoundException(); + } + + return entryToKey(animationEntry); + } + + private static AnimationKey entryToKey(AnimationEntry xe) + { + AnimationKey animationKey = new AnimationKey(); + animationKey.setNPCId(xe.getNPCId()); + animationKey.setAnimations(new int[] + { + xe.getAnimations()[0], + xe.getAnimations()[1], + xe.getAnimations()[2], + xe.getAnimations()[3], + xe.getAnimations()[4], + xe.getAnimations()[5], + xe.getAnimations()[6], + xe.getAnimations()[7], + xe.getAnimations()[8], + xe.getAnimations()[9], + }); + return animationKey; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index 9c20fb9b8f..96a55f3e86 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -288,7 +288,7 @@ public enum AgilityShortcut GOBLIN_VILLAGE_WALL(14, "Wall", new WorldPoint(2925, 3523, 0), TIGHTGAP), CORSAIR_COVE_DUNGEON_PILLAR(15, "Pillar Jump", new WorldPoint(1980, 8996, 0), PILLAR_31809), EDGEVILLE_DUNGEON_MONKEYBARS(15, "Monkey Bars", null, MONKEYBARS_23566), - TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 + TROLLHEIM_ROCKS(15, "Rocks", null, new WorldPoint(2838, 3614, 0), ROCKS_3748), // No fixed world map location, but rocks near death plateau have a requirement of 15 YANILLE_UNDERWALL_TUNNEL(16, "Underwall Tunnel", new WorldPoint(2574, 3109, 0), HOLE_16520, CASTLE_WALL), YANILLE_WATCHTOWER_TRELLIS(18, "Trellis", null, TRELLIS_20056), COAL_TRUCKS_LOG_BALANCE(20, "Log Balance", new WorldPoint(2598, 3475, 0), LOG_BALANCE_23274), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 3d71281cd7..725d17622c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -80,7 +80,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Speak to the bartender of the Blue Moon Inn in Varrock.", "Bartender", new WorldPoint(3226, 3399, 0), "Talk to the bartender in Blue Moon Inn in Varrock."), new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2846, 1749, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), new CrypticClue("Search the crates in the shed just north of East Ardougne.", CRATE_355, new WorldPoint(2617, 3347, 0), "The crates in the shed north of the northern Ardougne bank."), - new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1734, 3576, 0), "Talk to father Jean in the Hosidius church"), + new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1697, 3574, 0), "Talk to father Jean in the Hosidius church"), new CrypticClue("Search the crate in the Toad and Chicken pub.", CRATE_354, new WorldPoint(2913, 3536, 0), "The Toad and Chicken pub is located in Burthorpe."), new CrypticClue("Search chests found in the upstairs of shops in Port Sarim.", CLOSED_CHEST_375, new WorldPoint(3016, 3205, 1), "Search the chest in the upstairs of Wydin's Food Store, on the east wall."), new CrypticClue("Right on the blessed border, cursed by the evil ones. On the spot inaccessible by both; I will be waiting. The bugs' imminent possession holds the answer.", new WorldPoint(3410, 3324, 0), "B I P. Dig right under the fairy ring."), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 8136d00117..762bda9ad9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -1,6 +1,5 @@ /* * Copyright (c) 2018, Eadgars Ruse - * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,19 +24,21 @@ */ package net.runelite.client.plugins.cluescrolls.clues; +import com.google.common.collect.Lists; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import lombok.EqualsAndHashCode; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import lombok.Getter; -import lombok.extern.slf4j.Slf4j; import net.runelite.api.NPC; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; @@ -46,45 +47,35 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation; -import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver; -import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperature; -import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperatureChange; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; -@EqualsAndHashCode(callSuper = false, exclude = { "hotColdSolver", "location" }) @Getter -@Slf4j public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll { - private static final int HOT_COLD_PANEL_WIDTH = 200; - private static final HotColdClue BEGINNER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.", - "Reldo", - "Speak to Reldo to receive a strange device."); - private static final HotColdClue MASTER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", - "Jorral", - "Speak to Jorral to receive a strange device."); + private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)"); + private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\."); + private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*"); + private static final HotColdClue CLUE = + new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", + "Jorral", + "Speak to Jorral to receive a strange device."); + // list of potential places to dig + private List digLocations = new ArrayList<>(); private final String text; private final String npc; private final String solution; - @Nullable - private HotColdSolver hotColdSolver; private WorldPoint location; + private WorldPoint lastWorldPoint; public static HotColdClue forText(String text) { - if (BEGINNER_CLUE.text.equalsIgnoreCase(text)) + if (CLUE.text.equalsIgnoreCase(text)) { - BEGINNER_CLUE.reset(); - return BEGINNER_CLUE; - } - else if (MASTER_CLUE.text.equalsIgnoreCase(text)) - { - MASTER_CLUE.reset(); - return MASTER_CLUE; + return CLUE; } return null; @@ -96,35 +87,24 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat this.npc = npc; this.solution = solution; setRequiresSpade(true); - initializeSolver(); } @Override public WorldPoint[] getLocations() { - if (hotColdSolver == null) - { - return new WorldPoint[0]; - } - - return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); + return Lists.transform(digLocations, HotColdLocation::getWorldPoint).toArray(new WorldPoint[0]); } @Override public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) { - if (hotColdSolver == null) - { - return; - } - panelComponent.getChildren().add(TitleComponent.builder() .text("Hot/Cold Clue") .build()); - panelComponent.setPreferredSize(new Dimension(HOT_COLD_PANEL_WIDTH, 0)); + panelComponent.setPreferredSize(new Dimension(200, 0)); // strange device has not been tested yet, show how to get it - if (hotColdSolver.getLastWorldPoint() == null && location == null) + if (lastWorldPoint == null && location == null) { if (getNpc() != null) { @@ -151,9 +131,7 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat panelComponent.getChildren().add(LineComponent.builder() .left("Possible areas:") .build()); - - final Map locationCounts = new EnumMap<>(HotColdArea.class); - final Collection digLocations = hotColdSolver.getPossibleLocations(); + Map locationCounts = new HashMap<>(); for (HotColdLocation hotColdLocation : digLocations) { @@ -181,16 +159,17 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat } else { - for (HotColdArea area : locationCounts.keySet()) + for (HotColdArea s : locationCounts.keySet()) { panelComponent.getChildren().add(LineComponent.builder() - .left(area.getName() + ':') + .left(s.getName() + ":") .build()); for (HotColdLocation hotColdLocation : digLocations) { - if (hotColdLocation.getHotColdArea() == area) + if (hotColdLocation.getHotColdArea() == s) { + Rectangle2D r = hotColdLocation.getRect(); panelComponent.getChildren().add(LineComponent.builder() .left("- " + hotColdLocation.getArea()) .leftColor(Color.LIGHT_GRAY) @@ -205,13 +184,8 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat @Override public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) { - if (hotColdSolver == null) - { - return; - } - // when final location has been found - if (location != null) + if (this.location != null) { LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); @@ -223,17 +197,20 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return; } - // when strange device hasn't been activated yet, show npc who gives you the strange device - if (hotColdSolver.getLastWorldPoint() == null && plugin.getNpcsToMark() != null) + // when strange device hasn't been activated yet, show Jorral + if (lastWorldPoint == null) { - for (NPC npcToMark : plugin.getNpcsToMark()) + // Mark NPC + if (plugin.getNpcsToMark() != null) { - OverlayUtil.renderActorOverlayImage(graphics, npcToMark, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); + for (NPC npc : plugin.getNpcsToMark()) + { + OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); + } } } // once the number of possible dig locations is below 10, show the dig spots - final Collection digLocations = hotColdSolver.getPossibleLocations(); if (digLocations.size() < 10) { // Mark potential dig locations @@ -254,87 +231,171 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public boolean update(final String message, final ClueScrollPlugin plugin) { - if (hotColdSolver == null) + if (!message.startsWith("The device is")) { return false; } - final Set temperatureSet; + Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message); + Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message); + Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message); - if (this.equals(BEGINNER_CLUE)) + // the order that these pattern matchers are checked is important + if (m1.find()) { - temperatureSet = HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES; + // final location for hot cold clue has been found + WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); + + if (localWorld != null) + { + markFinalSpot(localWorld); + return true; + } } - else if (this.equals(MASTER_CLUE)) + else if (m2.find()) { - temperatureSet = HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES; + String temperature = m2.group(1); + String difference = m2.group(2); + WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); + + if (localWorld != null) + { + updatePossibleArea(localWorld, temperature, difference); + return true; + } } - else + else if (m3.find()) { - temperatureSet = null; + String temperature = m3.group(1); + WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); + + if (localWorld != null) + { + updatePossibleArea(localWorld, temperature, ""); + return true; + } } - final HotColdTemperature temperature = HotColdTemperature.getFromTemperatureSet(temperatureSet, message); - - if (temperature == null) - { - return false; - } - - final WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld == null) - { - return false; - } - - if ((this.equals(BEGINNER_CLUE) && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING) - || (this.equals(MASTER_CLUE) && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING)) - { - markFinalSpot(localWorld); - } - else - { - location = null; - - final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(message); - hotColdSolver.signal(localWorld, temperature, temperatureChange); - } - - return true; + return false; } @Override public void reset() { - initializeSolver(); + this.lastWorldPoint = null; + digLocations.clear(); } - private void initializeSolver() + private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference) { - final boolean isBeginner; + this.location = null; - if (this.equals(BEGINNER_CLUE)) + if (digLocations.isEmpty()) { - isBeginner = true; - } - else if (this.equals(MASTER_CLUE)) - { - isBeginner = false; + digLocations.addAll(Arrays.asList(HotColdLocation.values())); } - else + int maxSquaresAway = 5000; + int minSquaresAway = 0; + + switch (temperature) { - log.warn("Hot cold solver could not be initialized, clue type is unknown; text: {}, npc: {}, solution: {}", - text, npc, solution); - hotColdSolver = null; - return; + // when the strange device reads a temperature, that means that the center of the final dig location + // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) + case "ice cold": + maxSquaresAway = 5000; + minSquaresAway = 500; + break; + case "very cold": + maxSquaresAway = 499; + minSquaresAway = 200; + break; + case "cold": + maxSquaresAway = 199; + minSquaresAway = 150; + break; + case "warm": + maxSquaresAway = 149; + minSquaresAway = 100; + break; + case "hot": + maxSquaresAway = 99; + minSquaresAway = 70; + break; + case "very hot": + maxSquaresAway = 69; + minSquaresAway = 30; + break; + case "incredibly hot": + maxSquaresAway = 29; + minSquaresAway = 5; + break; } - final Set locations = Arrays.stream(HotColdLocation.values()) - .filter(l -> l.isBeginnerClue() == isBeginner) - .collect(Collectors.toSet()); - hotColdSolver = new HotColdSolver(locations); + // rectangle r1 encompasses all of the points that are within the max possible distance from the player + Point p1 = new Point(currentWp.getX() - maxSquaresAway, currentWp.getY() - maxSquaresAway); + Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1); + // rectangle r2 encompasses all of the points that are within the min possible distance from the player + Point p2 = new Point(currentWp.getX() - minSquaresAway, currentWp.getY() - minSquaresAway); + Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1); + + // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range + digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect())); + + // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device + if (lastWorldPoint != null) + { + switch (difference) + { + case "but colder than": + // eliminate spots that are absolutely warmer + digLocations.removeIf(entry -> isFirstPointCloserRect(currentWp, lastWorldPoint, entry.getRect())); + break; + case "and warmer than": + // eliminate spots that are absolutely colder + digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, currentWp, entry.getRect())); + break; + case "and the same temperature as": + // I couldn't figure out a clean implementation for this case + // not necessary for quickly determining final location + } + } + + lastWorldPoint = currentWp; + } + + private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r) + { + WorldPoint p1 = new WorldPoint((int) r.getMaxX(), (int) r.getMaxY(), 0); + + if (!isFirstPointCloser(firstWp, secondWp, p1)) + { + return false; + } + + WorldPoint p2 = new WorldPoint((int) r.getMaxX(), (int) r.getMinY(), 0); + + if (!isFirstPointCloser(firstWp, secondWp, p2)) + { + return false; + } + + WorldPoint p3 = new WorldPoint((int) r.getMinX(), (int) r.getMaxY(), 0); + + if (!isFirstPointCloser(firstWp, secondWp, p3)) + { + return false; + } + + WorldPoint p4 = new WorldPoint((int) r.getMinX(), (int) r.getMinY(), 0); + return (isFirstPointCloser(firstWp, secondWp, p4)); + } + + private boolean isFirstPointCloser(WorldPoint firstWp, WorldPoint secondWp, WorldPoint wp) + { + int firstDistance = firstWp.distanceTo2D(wp); + int secondDistance = secondWp.distanceTo2D(wp); + return (firstDistance < secondDistance); } private void markFinalSpot(WorldPoint wp) @@ -347,4 +408,4 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat { return new String[]{npc}; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index b3bd0c91db..e41fd5357e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -1,7 +1,6 @@ /* * Copyright (c) 2018, Eadgars Ruse * Copyright (c) 2018, Adam - * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +26,7 @@ package net.runelite.client.plugins.cluescrolls.clues.hotcold; import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.coords.WorldPoint; @@ -69,8 +69,6 @@ public enum HotColdLocation DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), - DRAYNOR_MANOR_MUSHROOMS(true, new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), - DRAYNOR_WHEAT_FIELD(true, new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), FELDIP_HILLS_JIGGIG(new WorldPoint(2413, 3055, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp."), FELDIP_HILLS_SW(new WorldPoint(2582, 2895, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills."), FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2553, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri)."), @@ -93,7 +91,6 @@ public enum HotColdLocation FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2147, 3862, 0), FREMENNIK_PROVINCE, "Astral altar"), FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2087, 3915, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village."), FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village."), - ICE_MOUNTAIN(true, new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), KANDARIN_SINCLAR_MANSION(new WorldPoint(2726, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), KANDARIN_CATHERBY(new WorldPoint(2774, 3433, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), KANDARIN_GRAND_TREE(new WorldPoint(2444, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure."), @@ -118,7 +115,6 @@ public enum HotColdLocation KARAMJA_KHARAZI_NE(new WorldPoint(2904, 2925, 0), KARAMJA, "North-eastern part of Kharazi Jungle."), KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), KARAMJA_CRASH_ISLAND(new WorldPoint(2910, 2737, 0), KARAMJA, "Northern part of Crash Island."), - LUMBRIDGE_COW_FIELD(true, new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), @@ -135,7 +131,6 @@ public enum HotColdLocation MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3813, 3567, 0), MORYTANIA, "Northern part of Dragontooth Island."), MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island."), - NORTHEAST_OF_AL_KHARID_MINE(true, new WorldPoint(3332, 3313, 0), MISTHALIN, "Northeast of Al Kharid Mine"), WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3530, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak."), WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2337, 3689, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony"), WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2361, 3566, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), @@ -181,20 +176,12 @@ public enum HotColdLocation ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); - private final boolean beginnerClue; private final WorldPoint worldPoint; private final HotColdArea hotColdArea; private final String area; - HotColdLocation(WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription) + public Rectangle2D getRect() { - this(false, worldPoint, hotColdArea, areaDescription); - } - - public Rectangle getRect() - { - final int digRadius = beginnerClue ? HotColdTemperature.BEGINNER_VISIBLY_SHAKING.getMaxDistance() : - HotColdTemperature.MASTER_VISIBLY_SHAKING.getMaxDistance(); - return new Rectangle(worldPoint.getX() - digRadius, worldPoint.getY() - digRadius, digRadius * 2 + 1, digRadius * 2 + 1); + return new Rectangle(worldPoint.getX() - 4, worldPoint.getY() - 4, 9, 9); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java deleted file mode 100644 index 87414f0387..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2018, Eadgars Ruse - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import com.google.common.annotations.VisibleForTesting; -import java.awt.Rectangle; -import java.util.Set; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import lombok.Getter; -import net.runelite.api.coords.WorldPoint; - -/** - * Solution finder for hot-cold style puzzles. - *

- * These puzzles are established by having some way to test the distance from the solution via "warmth", where being - * colder means one is farther away from the target, and being warmer means one is closer to it, with the goal being to - * reach the most warm value to discover the solution point. Hot-cold puzzles in Old School Runescape are implemented - * with specific set of solution points, so this solver will filter from a provided set of possible solutions as new - * signals of temperatures and temperature changes are provided. - */ -@Getter -public class HotColdSolver -{ - private final Set possibleLocations; - @Nullable - private WorldPoint lastWorldPoint; - - public HotColdSolver(Set possibleLocations) - { - this.possibleLocations = possibleLocations; - } - - /** - * Process a hot-cold update given a {@link WorldPoint} where a check occurred and the resulting temperature and - * temperature change discovered at that point. This will filter the set of possible locations which can be the - * solution. - * - * @param worldPoint The point where a hot-cold check occurred - * @param temperature The temperature of the checked point - * @param temperatureChange The change of temperature of the checked point compared to the previously-checked point - * @return A set of {@link HotColdLocation}s which are still possible after the filtering occurs. This return value - * is the same as would be returned by {@code getPossibleLocations()}. - */ - public Set signal(@Nonnull final WorldPoint worldPoint, @Nonnull final HotColdTemperature temperature, @Nullable final HotColdTemperatureChange temperatureChange) - { - // when the strange device reads a temperature, that means that the center of the final dig location - // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) - int maxSquaresAway = temperature.getMaxDistance(); - int minSquaresAway = temperature.getMinDistance(); - - // maxDistanceArea encompasses all of the points that are within the max possible distance from the player - final Rectangle maxDistanceArea = new Rectangle( - worldPoint.getX() - maxSquaresAway, - worldPoint.getY() - maxSquaresAway, - 2 * maxSquaresAway + 1, - 2 * maxSquaresAway + 1); - // minDistanceArea encompasses all of the points that are within the min possible distance from the player - final Rectangle minDistanceArea = new Rectangle( - worldPoint.getX() - minSquaresAway, - worldPoint.getY() - minSquaresAway, - 2 * minSquaresAway + 1, - 2 * minSquaresAway + 1); - - // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range - possibleLocations.removeIf(entry -> minDistanceArea.contains(entry.getRect()) || !maxDistanceArea.intersects(entry.getRect())); - - // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device - if (lastWorldPoint != null && temperatureChange != null) - { - switch (temperatureChange) - { - case COLDER: - // eliminate spots that are absolutely warmer - possibleLocations.removeIf(entry -> isFirstPointCloserRect(worldPoint, lastWorldPoint, entry.getRect())); - break; - case WARMER: - // eliminate spots that are absolutely colder - possibleLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, worldPoint, entry.getRect())); - break; - case SAME: - // I couldn't figure out a clean implementation for this case - // not necessary for quickly determining final location - } - } - - lastWorldPoint = worldPoint; - return getPossibleLocations(); - } - - /** - * Determines whether the first point passed is closer to each corner of the given rectangle than the second point. - * - * @param firstPoint First point to test. Return result will be relating to this point's location. - * @param secondPoint Second point to test - * @param rect Rectangle, whose corner points will be compared to the first and second points passed - * @return {@code true} if {@code firstPoint} is closer to each of {@code rect}'s four corner points than - * {@code secondPoint}, {@code false} otherwise. - * @see WorldPoint#distanceTo2D - */ - @VisibleForTesting - static boolean isFirstPointCloserRect(final WorldPoint firstPoint, final WorldPoint secondPoint, final Rectangle rect) - { - final WorldPoint nePoint = new WorldPoint((rect.x + rect.width), (rect.y + rect.height), 0); - - if (!isFirstPointCloser(firstPoint, secondPoint, nePoint)) - { - return false; - } - - final WorldPoint sePoint = new WorldPoint((rect.x + rect.width), rect.y, 0); - - if (!isFirstPointCloser(firstPoint, secondPoint, sePoint)) - { - return false; - } - - final WorldPoint nwPoint = new WorldPoint(rect.x, (rect.y + rect.height), 0); - - if (!isFirstPointCloser(firstPoint, secondPoint, nwPoint)) - { - return false; - } - - final WorldPoint swPoint = new WorldPoint(rect.x, rect.y, 0); - return (isFirstPointCloser(firstPoint, secondPoint, swPoint)); - } - - /** - * Determines whether the first point passed is closer to the given point of comparison than the second point. - * - * @param firstPoint First point to test. Return result will be relating to this point's location. - * @param secondPoint Second point to test - * @param worldPoint Point to compare to the first and second points passed - * @return {@code true} if {@code firstPoint} is closer to {@code worldPoint} than {@code secondPoint}, - * {@code false} otherwise. - * @see WorldPoint#distanceTo2D - */ - @VisibleForTesting - static boolean isFirstPointCloser(final WorldPoint firstPoint, final WorldPoint secondPoint, final WorldPoint worldPoint) - { - return firstPoint.distanceTo2D(worldPoint) < secondPoint.distanceTo2D(worldPoint); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java deleted file mode 100644 index 2dc5909000..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import com.google.common.collect.Sets; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Set; -import javax.annotation.Nullable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public enum HotColdTemperature -{ - ICE_COLD("ice cold", 500, 5000), - VERY_COLD("very cold", 200, 499), - COLD("cold", 150, 199), - WARM("warm", 100, 149), - HOT("hot", 70, 99), - VERY_HOT("very hot", 30, 69), - BEGINNER_INCREDIBLY_HOT("incredibly hot", 4, 29), - BEGINNER_VISIBLY_SHAKING("visibly shaking", 0, 3), - MASTER_INCREDIBLY_HOT("incredibly hot", 5, 29), - MASTER_VISIBLY_SHAKING("visibly shaking", 0, 4); - - public static final Set BEGINNER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( - ICE_COLD, - VERY_COLD, - COLD, - WARM, - HOT, - VERY_HOT, - BEGINNER_INCREDIBLY_HOT, - BEGINNER_VISIBLY_SHAKING - ); - public static final Set MASTER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( - ICE_COLD, - VERY_COLD, - COLD, - WARM, - HOT, - VERY_HOT, - MASTER_INCREDIBLY_HOT, - MASTER_VISIBLY_SHAKING - ); - - private final String text; - private final int minDistance; - private final int maxDistance; - - private static final String DEVICE_USED_START_TEXT = "The device is "; - - /** - * Gets the temperature from a set of temperatures corresponding to the passed string. - * - * @param temperatureSet A set of temperature values to select from - * @param message A string containing a temperature value - * @return The corresponding enum from the given temperature set. - *

- * Note that in cases where two temperature values in the given set are equally likely to be the given - * temperature (say, two temperatures with identical text values), the behavior is undefined. - */ - @Nullable - public static HotColdTemperature getFromTemperatureSet(final Set temperatureSet, final String message) - { - if (!message.startsWith(DEVICE_USED_START_TEXT) || temperatureSet == null) - { - return null; - } - - final List possibleTemperatures = new ArrayList<>(); - - for (final HotColdTemperature temperature : temperatureSet) - { - if (message.contains(temperature.getText())) - { - possibleTemperatures.add(temperature); - } - } - - return possibleTemperatures.stream() - // For messages such as "The device is very cold", this will choose the Enum with text of greatest length so - // that VERY_COLD would be selected over COLD, though both Enums have matching text for this message. - .max(Comparator.comparingInt(x -> (x.getText()).length())) - .orElse(null); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java deleted file mode 100644 index e9077bc9e1..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import lombok.AllArgsConstructor; - -@AllArgsConstructor -public enum HotColdTemperatureChange -{ - WARMER("and warmer than"), - SAME("and the same temperature as"), - COLDER("but colder than"); - - private final String text; - - public static HotColdTemperatureChange of(final String message) - { - if (!message.endsWith(" last time.")) - { - return null; - } - - for (final HotColdTemperatureChange change : values()) - { - if (message.contains(change.text)) - { - return change; - } - } - - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java index a822cf74a8..18b9d6386b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java @@ -173,10 +173,10 @@ public interface ItemChargeConfig extends Config } @ConfigItem( - keyName = "showBellowCharges", - name = "Show Bellow Charges", - description = "Configures if ogre bellow item charge is shown", - position = 12 + keyName = "showBellowCharges", + name = "Show Bellow Charges", + description = "Configures if ogre bellow item charge is shown", + position = 12 ) default boolean showBellowCharges() { @@ -184,32 +184,10 @@ public interface ItemChargeConfig extends Config } @ConfigItem( - keyName = "showBasketCharges", - name = "Show Basket Charges", - description = "Configures if fruit basket item charge is shown", - position = 13 - ) - default boolean showBasketCharges() - { - return true; - } - - @ConfigItem( - keyName = "showSackCharges", - name = "Show Sack Charges", - description = "Configures if sack item charge is shown", - position = 14 - ) - default boolean showSackCharges() - { - return true; - } - - @ConfigItem( - keyName = "showAbyssalBraceletCharges", - name = "Show Abyssal Bracelet Charges", - description = "Configures if abyssal bracelet item charge is shown", - position = 15 + keyName = "showAbyssalBraceletCharges", + name = "Show Abyssal Bracelet Charges", + description = "Configures if abyssal bracelet item charge is shown", + position = 13 ) default boolean showAbyssalBraceletCharges() { @@ -220,7 +198,7 @@ public interface ItemChargeConfig extends Config keyName = "recoilNotification", name = "Ring of Recoil Notification", description = "Configures if the ring of recoil breaking notification is shown", - position = 16 + position = 14 ) default boolean recoilNotification() { @@ -231,7 +209,7 @@ public interface ItemChargeConfig extends Config keyName = "showBindingNecklaceCharges", name = "Show Binding Necklace Charges", description = "Configures if binding necklace item charge is shown", - position = 17 + position = 15 ) default boolean showBindingNecklaceCharges() { @@ -260,7 +238,7 @@ public interface ItemChargeConfig extends Config keyName = "bindingNotification", name = "Binding Necklace Notification", description = "Configures if the binding necklace breaking notification is shown", - position = 18 + position = 16 ) default boolean bindingNotification() { @@ -271,7 +249,7 @@ public interface ItemChargeConfig extends Config keyName = "showExplorerRingCharges", name = "Show Explorer's Ring Alch Charges", description = "Configures if explorer's ring alchemy charges are shown", - position = 19 + position = 17 ) default boolean showExplorerRingCharges() { @@ -300,7 +278,7 @@ public interface ItemChargeConfig extends Config keyName = "showInfoboxes", name = "Show Infoboxes", description = "Configures whether to show an infobox equipped charge items", - position = 20 + position = 18 ) default boolean showInfoboxes() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index a853489555..31db7daad1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -38,8 +38,6 @@ import static net.runelite.client.plugins.itemcharges.ItemChargeType.IMPBOX; import static net.runelite.client.plugins.itemcharges.ItemChargeType.TELEPORT; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERCAN; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERSKIN; -import static net.runelite.client.plugins.itemcharges.ItemChargeType.FRUIT_BASKET; -import static net.runelite.client.plugins.itemcharges.ItemChargeType.SACK; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.WidgetItemOverlay; import net.runelite.client.ui.overlay.components.TextComponent; @@ -154,8 +152,6 @@ class ItemChargeOverlay extends WidgetItemOverlay || (type == WATERCAN && !config.showWateringCanCharges()) || (type == WATERSKIN && !config.showWaterskinCharges()) || (type == BELLOWS && !config.showBellowCharges()) - || (type == FRUIT_BASKET && !config.showBasketCharges()) - || (type == SACK && !config.showSackCharges()) || (type == ABYSSAL_BRACELET && !config.showAbyssalBraceletCharges())) { return; @@ -176,7 +172,6 @@ class ItemChargeOverlay extends WidgetItemOverlay { return config.showTeleportCharges() || config.showDodgyCount() || config.showFungicideCharges() || config.showImpCharges() || config.showWateringCanCharges() || config.showWaterskinCharges() - || config.showBellowCharges() || config.showBasketCharges() || config.showSackCharges() - || config.showAbyssalBraceletCharges() || config.showExplorerRingCharges(); + || config.showBellowCharges() || config.showAbyssalBraceletCharges() || config.showExplorerRingCharges(); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java index e219bae493..3d131aec20 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeType.java @@ -37,7 +37,5 @@ enum ItemChargeType BRACELET_OF_SLAUGHTER, EXPEDITIOUS_BRACELET, BINDING_NECKLACE, - EXPLORER_RING, - FRUIT_BASKET, - SACK + EXPLORER_RING } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java index 9e3113b85c..2f2fe76469 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java @@ -29,8 +29,133 @@ import java.util.Map; import javax.annotation.Nullable; import lombok.AllArgsConstructor; import lombok.Getter; - -import static net.runelite.api.ItemID.*; +import static net.runelite.api.ItemID.ABYSSAL_BRACELET1; +import static net.runelite.api.ItemID.ABYSSAL_BRACELET2; +import static net.runelite.api.ItemID.ABYSSAL_BRACELET3; +import static net.runelite.api.ItemID.ABYSSAL_BRACELET4; +import static net.runelite.api.ItemID.ABYSSAL_BRACELET5; +import static net.runelite.api.ItemID.AMULET_OF_GLORY1; +import static net.runelite.api.ItemID.AMULET_OF_GLORY2; +import static net.runelite.api.ItemID.AMULET_OF_GLORY3; +import static net.runelite.api.ItemID.AMULET_OF_GLORY4; +import static net.runelite.api.ItemID.AMULET_OF_GLORY5; +import static net.runelite.api.ItemID.AMULET_OF_GLORY6; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T1; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T2; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T3; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T4; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T5; +import static net.runelite.api.ItemID.AMULET_OF_GLORY_T6; +import static net.runelite.api.ItemID.BURNING_AMULET1; +import static net.runelite.api.ItemID.BURNING_AMULET2; +import static net.runelite.api.ItemID.BURNING_AMULET3; +import static net.runelite.api.ItemID.BURNING_AMULET4; +import static net.runelite.api.ItemID.BURNING_AMULET5; +import static net.runelite.api.ItemID.COMBAT_BRACELET1; +import static net.runelite.api.ItemID.COMBAT_BRACELET2; +import static net.runelite.api.ItemID.COMBAT_BRACELET3; +import static net.runelite.api.ItemID.COMBAT_BRACELET4; +import static net.runelite.api.ItemID.COMBAT_BRACELET5; +import static net.runelite.api.ItemID.COMBAT_BRACELET6; +import static net.runelite.api.ItemID.DIGSITE_PENDANT_1; +import static net.runelite.api.ItemID.DIGSITE_PENDANT_2; +import static net.runelite.api.ItemID.DIGSITE_PENDANT_3; +import static net.runelite.api.ItemID.DIGSITE_PENDANT_4; +import static net.runelite.api.ItemID.DIGSITE_PENDANT_5; +import static net.runelite.api.ItemID.ENCHANTED_LYRE1; +import static net.runelite.api.ItemID.ENCHANTED_LYRE2; +import static net.runelite.api.ItemID.ENCHANTED_LYRE3; +import static net.runelite.api.ItemID.ENCHANTED_LYRE4; +import static net.runelite.api.ItemID.ENCHANTED_LYRE5; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_0; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_1; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_10; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_2; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_3; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_4; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_5; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_6; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_7; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_8; +import static net.runelite.api.ItemID.FUNGICIDE_SPRAY_9; +import static net.runelite.api.ItemID.GAMES_NECKLACE1; +import static net.runelite.api.ItemID.GAMES_NECKLACE2; +import static net.runelite.api.ItemID.GAMES_NECKLACE3; +import static net.runelite.api.ItemID.GAMES_NECKLACE4; +import static net.runelite.api.ItemID.GAMES_NECKLACE5; +import static net.runelite.api.ItemID.GAMES_NECKLACE6; +import static net.runelite.api.ItemID.GAMES_NECKLACE7; +import static net.runelite.api.ItemID.GAMES_NECKLACE8; +import static net.runelite.api.ItemID.IMPINABOX1; +import static net.runelite.api.ItemID.IMPINABOX2; +import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE1; +import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE2; +import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE3; +import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE4; +import static net.runelite.api.ItemID.NECKLACE_OF_PASSAGE5; +import static net.runelite.api.ItemID.OGRE_BELLOWS; +import static net.runelite.api.ItemID.OGRE_BELLOWS_1; +import static net.runelite.api.ItemID.OGRE_BELLOWS_2; +import static net.runelite.api.ItemID.OGRE_BELLOWS_3; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_1; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_2; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_3; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_4; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_5; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_6; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_7; +import static net.runelite.api.ItemID.PHARAOHS_SCEPTRE_8; +import static net.runelite.api.ItemID.RING_OF_DUELING1; +import static net.runelite.api.ItemID.RING_OF_DUELING2; +import static net.runelite.api.ItemID.RING_OF_DUELING3; +import static net.runelite.api.ItemID.RING_OF_DUELING4; +import static net.runelite.api.ItemID.RING_OF_DUELING5; +import static net.runelite.api.ItemID.RING_OF_DUELING6; +import static net.runelite.api.ItemID.RING_OF_DUELING7; +import static net.runelite.api.ItemID.RING_OF_DUELING8; +import static net.runelite.api.ItemID.RING_OF_RETURNING1; +import static net.runelite.api.ItemID.RING_OF_RETURNING2; +import static net.runelite.api.ItemID.RING_OF_RETURNING3; +import static net.runelite.api.ItemID.RING_OF_RETURNING4; +import static net.runelite.api.ItemID.RING_OF_RETURNING5; +import static net.runelite.api.ItemID.RING_OF_WEALTH_1; +import static net.runelite.api.ItemID.RING_OF_WEALTH_2; +import static net.runelite.api.ItemID.RING_OF_WEALTH_3; +import static net.runelite.api.ItemID.RING_OF_WEALTH_4; +import static net.runelite.api.ItemID.RING_OF_WEALTH_5; +import static net.runelite.api.ItemID.SKILLS_NECKLACE1; +import static net.runelite.api.ItemID.SKILLS_NECKLACE2; +import static net.runelite.api.ItemID.SKILLS_NECKLACE3; +import static net.runelite.api.ItemID.SKILLS_NECKLACE4; +import static net.runelite.api.ItemID.SKILLS_NECKLACE5; +import static net.runelite.api.ItemID.SKILLS_NECKLACE6; +import static net.runelite.api.ItemID.SLAYER_RING_1; +import static net.runelite.api.ItemID.SLAYER_RING_2; +import static net.runelite.api.ItemID.SLAYER_RING_3; +import static net.runelite.api.ItemID.SLAYER_RING_4; +import static net.runelite.api.ItemID.SLAYER_RING_5; +import static net.runelite.api.ItemID.SLAYER_RING_6; +import static net.runelite.api.ItemID.SLAYER_RING_7; +import static net.runelite.api.ItemID.SLAYER_RING_8; +import static net.runelite.api.ItemID.TELEPORT_CRYSTAL_1; +import static net.runelite.api.ItemID.TELEPORT_CRYSTAL_2; +import static net.runelite.api.ItemID.TELEPORT_CRYSTAL_3; +import static net.runelite.api.ItemID.TELEPORT_CRYSTAL_4; +import static net.runelite.api.ItemID.TELEPORT_CRYSTAL_5; +import static net.runelite.api.ItemID.WATERING_CAN; +import static net.runelite.api.ItemID.WATERING_CAN1; +import static net.runelite.api.ItemID.WATERING_CAN2; +import static net.runelite.api.ItemID.WATERING_CAN3; +import static net.runelite.api.ItemID.WATERING_CAN4; +import static net.runelite.api.ItemID.WATERING_CAN5; +import static net.runelite.api.ItemID.WATERING_CAN6; +import static net.runelite.api.ItemID.WATERING_CAN7; +import static net.runelite.api.ItemID.WATERING_CAN8; +import static net.runelite.api.ItemID.WATERSKIN0; +import static net.runelite.api.ItemID.WATERSKIN1; +import static net.runelite.api.ItemID.WATERSKIN2; +import static net.runelite.api.ItemID.WATERSKIN3; +import static net.runelite.api.ItemID.WATERSKIN4; import static net.runelite.client.plugins.itemcharges.ItemChargeType.ABYSSAL_BRACELET; import static net.runelite.client.plugins.itemcharges.ItemChargeType.BELLOWS; import static net.runelite.client.plugins.itemcharges.ItemChargeType.FUNGICIDE_SPRAY; @@ -38,8 +163,6 @@ import static net.runelite.client.plugins.itemcharges.ItemChargeType.IMPBOX; import static net.runelite.client.plugins.itemcharges.ItemChargeType.TELEPORT; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERCAN; import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERSKIN; -import static net.runelite.client.plugins.itemcharges.ItemChargeType.FRUIT_BASKET; -import static net.runelite.client.plugins.itemcharges.ItemChargeType.SACK; @AllArgsConstructor @Getter @@ -50,31 +173,6 @@ enum ItemWithCharge ABRACE3(ABYSSAL_BRACELET, ABYSSAL_BRACELET3, 3), ABRACE4(ABYSSAL_BRACELET, ABYSSAL_BRACELET4, 4), ABRACE5(ABYSSAL_BRACELET, ABYSSAL_BRACELET5, 5), - BASKET_APPLES1(FRUIT_BASKET, APPLES1, 1), - BASKET_APPLES2(FRUIT_BASKET, APPLES2, 2), - BASKET_APPLES3(FRUIT_BASKET, APPLES3, 3), - BASKET_APPLES4(FRUIT_BASKET, APPLES4, 4), - BASKET_APPLES5(FRUIT_BASKET, APPLES5, 5), - BASKET_BANANAS1(FRUIT_BASKET, BANANAS1, 1), - BASKET_BANANAS2(FRUIT_BASKET, BANANAS2, 2), - BASKET_BANANAS3(FRUIT_BASKET, BANANAS3, 3), - BASKET_BANANAS4(FRUIT_BASKET, BANANAS4, 4), - BASKET_BANANAS5(FRUIT_BASKET, BANANAS5, 5), - BASKET_ORANGES1(FRUIT_BASKET, ORANGES1, 1), - BASKET_ORANGES2(FRUIT_BASKET, ORANGES2, 2), - BASKET_ORANGES3(FRUIT_BASKET, ORANGES3, 3), - BASKET_ORANGES4(FRUIT_BASKET, ORANGES4, 4), - BASKET_ORANGES5(FRUIT_BASKET, ORANGES5, 5), - BASKET_STRAWBERRIES1(FRUIT_BASKET, STRAWBERRIES1, 1), - BASKET_STRAWBERRIES2(FRUIT_BASKET, STRAWBERRIES2, 2), - BASKET_STRAWBERRIES3(FRUIT_BASKET, STRAWBERRIES3, 3), - BASKET_STRAWBERRIES4(FRUIT_BASKET, STRAWBERRIES4, 4), - BASKET_STRAWBERRIES5(FRUIT_BASKET, STRAWBERRIES5, 5), - BASKET_TOMATOES1(FRUIT_BASKET, TOMATOES1, 1), - BASKET_TOMATOES2(FRUIT_BASKET, TOMATOES2, 2), - BASKET_TOMATOES3(FRUIT_BASKET, TOMATOES3, 3), - BASKET_TOMATOES4(FRUIT_BASKET, TOMATOES4, 4), - BASKET_TOMATOES5(FRUIT_BASKET, TOMATOES5, 5), BELLOWS0(BELLOWS, OGRE_BELLOWS, 0), BELLOWS1(BELLOWS, OGRE_BELLOWS_1, 1), BELLOWS2(BELLOWS, OGRE_BELLOWS_2, 2), @@ -172,36 +270,6 @@ enum ItemWithCharge ROW3(TELEPORT, RING_OF_WEALTH_3, 3), ROW4(TELEPORT, RING_OF_WEALTH_4, 4), ROW5(TELEPORT, RING_OF_WEALTH_5, 5), - SACK_CABBAGES1(SACK, CABBAGES1, 1), - SACK_CABBAGES2(SACK, CABBAGES2, 2), - SACK_CABBAGES3(SACK, CABBAGES3, 3), - SACK_CABBAGES4(SACK, CABBAGES4, 4), - SACK_CABBAGES5(SACK, CABBAGES5, 5), - SACK_CABBAGES6(SACK, CABBAGES6, 6), - SACK_CABBAGES7(SACK, CABBAGES7, 7), - SACK_CABBAGES8(SACK, CABBAGES8, 8), - SACK_CABBAGES9(SACK, CABBAGES9, 9), - SACK_CABBAGES10(SACK, CABBAGES10, 10), - SACK_ONIONS1(SACK, ONIONS1, 1), - SACK_ONIONS2(SACK, ONIONS2, 2), - SACK_ONIONS3(SACK, ONIONS3, 3), - SACK_ONIONS4(SACK, ONIONS4, 4), - SACK_ONIONS5(SACK, ONIONS5, 5), - SACK_ONIONS6(SACK, ONIONS6, 6), - SACK_ONIONS7(SACK, ONIONS7, 7), - SACK_ONIONS8(SACK, ONIONS8, 8), - SACK_ONIONS9(SACK, ONIONS9, 9), - SACK_ONIONS10(SACK, ONIONS10, 10), - SACK_POTATOES1(SACK, POTATOES1, 1), - SACK_POTATOES2(SACK, POTATOES2, 2), - SACK_POTATOES3(SACK, POTATOES3, 3), - SACK_POTATOES4(SACK, POTATOES4, 4), - SACK_POTATOES5(SACK, POTATOES5, 5), - SACK_POTATOES6(SACK, POTATOES6, 6), - SACK_POTATOES7(SACK, POTATOES7, 7), - SACK_POTATOES8(SACK, POTATOES8, 8), - SACK_POTATOES9(SACK, POTATOES9, 9), - SACK_POTATOES10(SACK, POTATOES10, 10), SKILLS1(TELEPORT, SKILLS_NECKLACE1, 1), SKILLS2(TELEPORT, SKILLS_NECKLACE2, 2), SKILLS3(TELEPORT, SKILLS_NECKLACE3, 3), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index e90c97acdc..e6497432aa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -1690,4 +1690,4 @@ default CharterOption charterOption() { return true; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index 0367569855..e934bff8b8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -29,8 +29,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; @@ -171,7 +169,12 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - save(); + marker.getMarker().setName(nameInput.getText()); + plugin.updateConfig(); + + nameInput.setEditable(false); + updateNameActions(false); + requestFocusInWindow(); } @Override @@ -195,7 +198,10 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - cancel(); + nameInput.setEditable(false); + nameInput.setText(marker.getMarker().getName()); + updateNameActions(false); + requestFocusInWindow(); } @Override @@ -246,35 +252,6 @@ class ScreenMarkerPanel extends JPanel nameInput.setPreferredSize(new Dimension(0, 24)); nameInput.getTextField().setForeground(Color.WHITE); nameInput.getTextField().setBorder(new EmptyBorder(0, 8, 0, 0)); - nameInput.addKeyListener(new KeyAdapter() - { - @Override - public void keyPressed(KeyEvent e) - { - if (e.getKeyCode() == KeyEvent.VK_ENTER) - { - save(); - } - else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) - { - cancel(); - } - } - }); - nameInput.getTextField().addMouseListener(new MouseAdapter() - { - @Override - public void mouseEntered(MouseEvent mouseEvent) - { - preview(true); - } - - @Override - public void mouseExited(MouseEvent mouseEvent) - { - preview(false); - } - }); nameWrapper.add(nameInput, BorderLayout.CENTER); nameWrapper.add(nameActions, BorderLayout.EAST); @@ -382,7 +359,10 @@ class ScreenMarkerPanel extends JPanel @Override public void mousePressed(MouseEvent mouseEvent) { - toggle(!visible); + visible = !visible; + marker.getMarker().setVisible(visible); + plugin.updateConfig(); + updateVisibility(); } @Override @@ -444,42 +424,6 @@ class ScreenMarkerPanel extends JPanel } - private void preview(boolean on) - { - if (visible) - { - return; - } - - marker.getMarker().setVisible(on); - } - - private void toggle(boolean on) - { - visible = on; - marker.getMarker().setVisible(visible); - plugin.updateConfig(); - updateVisibility(); - } - - private void save() - { - marker.getMarker().setName(nameInput.getText()); - plugin.updateConfig(); - - nameInput.setEditable(false); - updateNameActions(false); - requestFocusInWindow(); - } - - private void cancel() - { - nameInput.setEditable(false); - nameInput.setText(marker.getMarker().getName()); - updateNameActions(false); - requestFocusInWindow(); - } - private void updateNameActions(boolean saveAndCancel) { save.setVisible(saveAndCancel); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index 0dce1c78b5..84abfcf9f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -97,7 +97,7 @@ public class WorldHopperPlugin extends Plugin { private static final int WORLD_FETCH_TIMER = 10; private static final int WORLD_PING_TIMER = 10; - private static final int REFRESH_THROTTLE = 60_000; // ms + private static final int REFRESH_THROTTLE = 60_000; // ms private static final int TICK_THROTTLE = (int) Duration.ofMinutes(10).toMillis(); private static final int DISPLAY_SWITCHER_MAX_ATTEMPTS = 3; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java deleted file mode 100644 index d67a00b989..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/BeginnerHotColdLocationTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class BeginnerHotColdLocationTest -{ - private static final Set BEGINNER_HOT_COLD_LOCATIONS = Arrays.stream(HotColdLocation.values()) - .filter(HotColdLocation::isBeginnerClue) - .collect(Collectors.toSet()); - private static final int EXPECTED_DIMENSION_SIZE = 7; - - @Test - public void beginnerHotColdLocationAreaTest() - { - - for (final HotColdLocation location : BEGINNER_HOT_COLD_LOCATIONS) - { - assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().height); - assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().width); - } - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java deleted file mode 100644 index a5c4cc4e31..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolverTest.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import com.google.common.collect.Sets; -import java.awt.Rectangle; -import java.util.EnumSet; -import java.util.Set; -import java.util.stream.Collectors; -import static junit.framework.TestCase.assertTrue; -import net.runelite.api.coords.WorldPoint; -import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver.isFirstPointCloser; -import static net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver.isFirstPointCloserRect; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import org.junit.Test; - -public class HotColdSolverTest -{ - private static final String RESPONSE_TEXT_ICE_COLD_COLDER = "The device is ice cold, but colder than last time."; - private static final String RESPONSE_TEXT_VERY_COLD_WARMER = "The device is very cold, and warmer than last time."; - private static final String RESPONSE_TEXT_COLD = "The device is cold."; - private static final String RESPONSE_TEXT_COLD_COLDER = "The device is cold, but colder than last time."; - private static final String RESPONSE_TEXT_COLD_WARMER = "The device is cold, and warmer than last time."; - private static final String RESPONSE_TEXT_COLD_SAME_TEMP = "The device is cold, and the same temperature as last time."; - private static final String RESPONSE_TEXT_VERY_HOT = "The device is very hot."; - private static final String RESPONSE_TEXT_VERY_HOT_COLDER = "The device is very hot, but colder than last time."; - private static final String RESPONSE_TEXT_VERY_HOT_WARMER = "The device is very hot, and warmer than last time."; - private static final String RESPONSE_TEXT_VERY_HOT_SAME_TEMP = "The device is very hot, and the same temperature as last time."; - - @Test - public void testOneStepSolution() - { - final Set foundLocation = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); - - testSolver(createHotColdSolver(), new WorldPoint(2852, 2992, 0), RESPONSE_TEXT_VERY_HOT, foundLocation); - } - - @Test - public void testIgnoreStartingTemperatureDifference() - { - final WorldPoint testedPoint = new WorldPoint(2852, 2992, 0); - final Set foundLocations = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); - - testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT, foundLocations); - testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_COLDER, foundLocations); - testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_WARMER, foundLocations); - testSolver(createHotColdSolver(), testedPoint, RESPONSE_TEXT_VERY_HOT_SAME_TEMP, foundLocations); - } - - @Test - public void testSameTempNoChanges() - { - final HotColdSolver solver = createHotColdSolver(); - final WorldPoint testedPoint = new WorldPoint(2851, 2955, 0); - final Set foundLocations = Sets.immutableEnumSet( - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.KARAMJA_KHARAZI_SW); - - testSolver(solver, testedPoint, RESPONSE_TEXT_VERY_HOT, foundLocations); - testSolver(solver, testedPoint, RESPONSE_TEXT_VERY_HOT_SAME_TEMP, foundLocations); - } - - @Test - public void testNoChangesAfterSolutionFound() - { - final HotColdSolver solver = createHotColdSolver(); - final Set intermediateFoundLocations = Sets.immutableEnumSet( - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.KARAMJA_KHARAZI_SW); - final Set finalLocation = Sets.immutableEnumSet(HotColdLocation.KARAMJA_KHARAZI_NE); - - testSolver(solver, new WorldPoint(2851, 2955, 0), RESPONSE_TEXT_VERY_HOT, intermediateFoundLocations); - testSolver(solver, new WorldPoint(2852, 2955, 0), RESPONSE_TEXT_VERY_HOT_WARMER, finalLocation); - testSolver(solver, new WorldPoint(2851, 2955, 0), RESPONSE_TEXT_VERY_HOT_COLDER, finalLocation); - testSolver(solver, new WorldPoint(2465, 3495, 0), RESPONSE_TEXT_ICE_COLD_COLDER, finalLocation); - testSolver(solver, new WorldPoint(3056, 3291, 0), RESPONSE_TEXT_VERY_COLD_WARMER, finalLocation); - testSolver(solver, new WorldPoint(2571, 2956, 0), RESPONSE_TEXT_VERY_COLD_WARMER, finalLocation); - } - - @Test - public void testNarrowToFindSolutions() - { - final HotColdSolver solver = createHotColdSolver(); - final Set firstLocationsSet = Sets.immutableEnumSet( - HotColdLocation.FELDIP_HILLS_GNOME_GLITER, - HotColdLocation.FELDIP_HILLS_RED_CHIN, - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.KARAMJA_CRASH_ISLAND); - final Set secondLocationsSet = firstLocationsSet.stream() - .filter(location -> location != HotColdLocation.FELDIP_HILLS_RED_CHIN) - .collect(Collectors.toSet()); - final Set thirdLocationSet = secondLocationsSet.stream() - .filter(location -> location != HotColdLocation.FELDIP_HILLS_GNOME_GLITER) - .collect(Collectors.toSet()); - final Set finalLocation = thirdLocationSet.stream() - .filter(location -> location != HotColdLocation.KARAMJA_CRASH_ISLAND) - .collect(Collectors.toSet()); - - testSolver(solver, new WorldPoint(2711, 2803, 0), RESPONSE_TEXT_COLD, firstLocationsSet); - testSolver(solver, new WorldPoint(2711, 2802, 0), RESPONSE_TEXT_COLD_SAME_TEMP, firstLocationsSet); - testSolver(solver, new WorldPoint(2716, 2802, 0), RESPONSE_TEXT_COLD_WARMER, secondLocationsSet); - testSolver(solver, new WorldPoint(2739, 2808, 0), RESPONSE_TEXT_COLD_WARMER, thirdLocationSet); - testSolver(solver, new WorldPoint(2810, 2757, 0), RESPONSE_TEXT_COLD_COLDER, finalLocation); - } - - @Test - public void testSomewhatDistantLocations() - { - // Activate device on Ape Atoll when solution point is HotColdLocation.KARAMJA_KHARAZI_NE - testSolver(createHotColdSolver(), new WorldPoint(2723, 2743, 0), RESPONSE_TEXT_COLD, - Sets.immutableEnumSet( - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.KARAMJA_KHARAZI_SW, - HotColdLocation.KARAMJA_CRASH_ISLAND, - HotColdLocation.FELDIP_HILLS_SW, - HotColdLocation.FELDIP_HILLS_RANTZ, - HotColdLocation.FELDIP_HILLS_RED_CHIN, - HotColdLocation.FELDIP_HILLS_SE)); - - // Activate device near fairy ring DKP when solution point is HotColdLocation.KARAMJA_KHARAZI_NE - testSolver(createHotColdSolver(), new WorldPoint(2900, 3111, 0), RESPONSE_TEXT_COLD, - Sets.immutableEnumSet( - HotColdLocation.KARAMJA_WEST_BRIMHAVEN, - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.ASGARNIA_COW, - HotColdLocation.ASGARNIA_CRAFT_GUILD, - HotColdLocation.KANDARIN_WITCHHAVEN, - HotColdLocation.MISTHALIN_DRAYNOR_BANK)); - - // Activate device on Mudskipper Point when solution point is HotColdLocation.KARAMJA_KHARAZI_NE - testSolver(createHotColdSolver(), new WorldPoint(2985, 3106, 0), RESPONSE_TEXT_COLD, - Sets.immutableEnumSet( - HotColdLocation.KARAMJA_BRIMHAVEN_FRUIT_TREE, - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.ASGARNIA_COW, - HotColdLocation.ASGARNIA_CRAFT_GUILD, - HotColdLocation.MISTHALIN_LUMBRIDGE_2, - HotColdLocation.DESERT_BEDABIN_CAMP)); - } - - @Test - public void testIsFirstPointCloserRect() - { - assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0), new Rectangle(0, 0, 1, 1))); - assertFalse(isFirstPointCloserRect(new WorldPoint(1, 0, 0), new WorldPoint(5, 0, 0), new Rectangle(2, 1, 5, 5))); - assertFalse(isFirstPointCloserRect(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new Rectangle(2, 0, 1, 2))); - assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 1), new Rectangle(2, 2, 2, 2))); - assertFalse(isFirstPointCloserRect(new WorldPoint(0, 0, 0), new WorldPoint(4, 4, 4), new Rectangle(1, 1, 2, 2))); - assertFalse(isFirstPointCloserRect(new WorldPoint(3, 2, 0), new WorldPoint(1, 5, 0), new Rectangle(0, 0, 4, 4))); - - assertTrue(isFirstPointCloserRect(new WorldPoint(1, 1, 0), new WorldPoint(0, 1, 0), new Rectangle(2, 0, 3, 2))); - assertTrue(isFirstPointCloserRect(new WorldPoint(4, 4, 0), new WorldPoint(1, 1, 0), new Rectangle(3, 3, 2, 2))); - assertTrue(isFirstPointCloserRect(new WorldPoint(3, 2, 0), new WorldPoint(7, 0, 0), new Rectangle(1, 3, 4, 2))); - - } - - @Test - public void testIsFirstPointCloser() - { - assertFalse(isFirstPointCloser(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 0))); - assertFalse(isFirstPointCloser(new WorldPoint(0, 0, 0), new WorldPoint(0, 0, 1), new WorldPoint(0, 0, 0))); - assertFalse(isFirstPointCloser(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 0))); - assertFalse(isFirstPointCloser(new WorldPoint(2, 2, 0), new WorldPoint(0, 0, 0), new WorldPoint(1, 1, 0))); - - assertTrue(isFirstPointCloser(new WorldPoint(1, 0, 0), new WorldPoint(0, 0, 0), new WorldPoint(2, 0, 0))); - assertTrue(isFirstPointCloser(new WorldPoint(1, 1, 0), new WorldPoint(1, 0, 0), new WorldPoint(2, 2, 0))); - assertTrue(isFirstPointCloser(new WorldPoint(1, 1, 1), new WorldPoint(0, 1, 0), new WorldPoint(1, 1, 0))); - } - - /** - * Tests a hot-cold solver by signalling a test point, temperature, and temperature change to it and asserting the - * resulting possible location set is equal to that of a given set of expected locations. - * - * @param solver The hot-cold solver to signal to. - *
- * Note: This will mutate the passed solver, which is helpful for testing - * multiple sequential steps. - * @param testPoint The {@link WorldPoint} where the signal occurs. - * @param deviceResponse The string containing the temperature and temperature change which is - * given when the hot-cold checking device is activated. - * @param expectedRemainingPossibleLocations A {@link Set} of {@link HotColdLocation}s which is expected to be - * given by {@link HotColdSolver#getPossibleLocations()} after it receives - * the signal formed by the other given arguments. - */ - private static void testSolver(final HotColdSolver solver, final WorldPoint testPoint, final String deviceResponse, final Set expectedRemainingPossibleLocations) - { - final HotColdTemperature temperature = HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, deviceResponse); - final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(deviceResponse); - - assertNotNull(temperature); - assertEquals(expectedRemainingPossibleLocations, solver.signal(testPoint, temperature, temperatureChange)); - } - - /** - * @return A hot-cold solver with a starting set of master hot-cold locations nearby the KARAMJA_KHARAZI_NE - * location. {@link HotColdLocation#values()} is not used as it may change with future game updates, and - * such changes would break this test suite. - */ - private static HotColdSolver createHotColdSolver() - { - final Set hotColdLocations = EnumSet.of( - HotColdLocation.KARAMJA_KHARAZI_NE, - HotColdLocation.KARAMJA_KHARAZI_SW, - HotColdLocation.KARAMJA_GLIDER, - HotColdLocation.KARAMJA_MUSA_POINT, - HotColdLocation.KARAMJA_BRIMHAVEN_FRUIT_TREE, - HotColdLocation.KARAMJA_WEST_BRIMHAVEN, - HotColdLocation.KARAMJA_CRASH_ISLAND, - HotColdLocation.DESERT_BEDABIN_CAMP, - HotColdLocation.DESERT_MENAPHOS_GATE, - HotColdLocation.DESERT_POLLNIVNEACH, - HotColdLocation.DESERT_SHANTY, - HotColdLocation.MISTHALIN_LUMBRIDGE, - HotColdLocation.MISTHALIN_LUMBRIDGE_2, - HotColdLocation.MISTHALIN_DRAYNOR_BANK, - HotColdLocation.ASGARNIA_COW, - HotColdLocation.ASGARNIA_PARTY_ROOM, - HotColdLocation.ASGARNIA_CRAFT_GUILD, - HotColdLocation.ASGARNIA_RIMMINGTON, - HotColdLocation.ASGARNIA_MUDSKIPPER, - HotColdLocation.KANDARIN_WITCHHAVEN, - HotColdLocation.KANDARIN_NECRO_TOWER, - HotColdLocation.KANDARIN_FIGHT_ARENA, - HotColdLocation.KANDARIN_TREE_GNOME_VILLAGE, - HotColdLocation.FELDIP_HILLS_GNOME_GLITER, - HotColdLocation.FELDIP_HILLS_JIGGIG, - HotColdLocation.FELDIP_HILLS_RANTZ, - HotColdLocation.FELDIP_HILLS_RED_CHIN, - HotColdLocation.FELDIP_HILLS_SE, - HotColdLocation.FELDIP_HILLS_SOUTH, - HotColdLocation.FELDIP_HILLS_SW - ); - return new HotColdSolver(hotColdLocations); - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java deleted file mode 100644 index 9b7cdcaf3c..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChangeTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Test; - -public class HotColdTemperatureChangeTest -{ - private static final String[] VALID_MESSAGES = { - "The device is warm, and warmer than last time.", - "The device is cold, but colder than last time.", - "The device is very hot, and the same temperature as last time.", - }; - private static final String[] INVALID_MESSAGES = { - "The device is cold.", - "The device is ice cold.", - "The device is very cold.", - "The device is hot.", - "The device is incredibly hot.", - "The device is an octopus, and is wetter than last time", - "foobar", - "a q p w", - "My feet are cold, I should put them in some lukewarm water, or run hot water over them.", - "and warmer than and colder than and the same temperature", - }; - - @Test - public void testValidTemperatureChangeMessages() - { - for (final String message : VALID_MESSAGES) - { - assertNotNull(message, HotColdTemperatureChange.of(message)); - } - } - - @Test - public void testInvalidTemperatureChangeMessages() - { - for (final String message : INVALID_MESSAGES) - { - assertNull(message, HotColdTemperatureChange.of(message)); - } - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java deleted file mode 100644 index e9711dc433..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Test; - -public class HotColdTemperatureTest -{ - private static final String[] VALID_MESSAGES = { - "The device is warm, and warmer than last time.", - "The device is visibly shaking and burns to the touch. This must be the spot.", - "The device is cold.", - "The device is ice cold.", - "The device is very cold.", - "The device is hot.", - "The device is incredibly hot.", - }; - private static final String[] INVALID_MESSAGES = { - "The device is an octopus, and is wetter than last time.", - "foobar", - "a q p w", - "My feet are cold, I should put them in some lukewarm water, or run hot water over them.", - }; - - @Test - public void testValidTemperatureMessages() - { - for (final String message : VALID_MESSAGES) - { - assertNotNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES, message)); - assertNotNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, message)); - } - } - - @Test - public void testInvalidTemperatureMessages() - { - for (final String message : INVALID_MESSAGES) - { - assertNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES, message)); - assertNull(message, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, message)); - } - } - - @Test - public void testAmbiguousTemperatureMessages() - { - assertEquals(HotColdTemperature.ICE_COLD, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is ice cold.")); - assertEquals(HotColdTemperature.VERY_COLD, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is very cold.")); - assertEquals(HotColdTemperature.VERY_HOT, HotColdTemperature.getFromTemperatureSet(HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES, "The device is very hot.")); - } -} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java deleted file mode 100644 index abda26549d..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/MasterHotColdLocationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019, Jordan Atwood - * 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.cluescrolls.clues.hotcold; - -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class MasterHotColdLocationTest -{ - private static final Set MASTER_HOT_COLD_LOCATIONS = Arrays.stream(HotColdLocation.values()) - .filter(l -> !l.isBeginnerClue()) - .collect(Collectors.toSet()); - private static final int EXPECTED_DIMENSION_SIZE = 9; - - @Test - public void beginnerHotColdLocationAreaTest() - { - for (final HotColdLocation location : MASTER_HOT_COLD_LOCATIONS) - { - assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().height); - assertEquals(EXPECTED_DIMENSION_SIZE, location.getRect().width); - } - } -} From a24cab01e29044641a9323a4a41654d45d03c393 Mon Sep 17 00:00:00 2001 From: Zeruth Date: Tue, 2 Jul 2019 18:37:58 -0400 Subject: [PATCH 61/63] makes translator work in clan chat as well. --- .../ChatTranslationConfig.java | 76 +++++++++---------- .../ChatTranslationPlugin.java | 26 +++++-- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java index 32e8481c7c..b0c4a1f580 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationConfig.java @@ -9,11 +9,11 @@ public interface ChatTranslationConfig extends Config { @ConfigItem( - keyName = "translateOptionVisable", - name = "Show 'Translate' menu option", - description = "Adds 'Translate' to the right-click menu in the Chatbox.", - position = 0, - group = "Public Chat Translation" + keyName = "translateOptionVisable", + name = "Show 'Translate' menu option", + description = "Adds 'Translate' to the right-click menu in the Chatbox.", + position = 0, + group = "Chat Translation" ) default boolean translateOptionVisable() { @@ -21,13 +21,13 @@ public interface ChatTranslationConfig extends Config } @ConfigItem( - keyName = "publicChat", - name = "Translate incoming Messages", - description = "Would you like to Translate Public Chat?", - position = 1, - group = "Public Chat Translation", - hidden = true, - unhide = "translateOptionVisable" + keyName = "publicChat", + name = "Translate incoming Messages", + description = "Would you like to Translate Chat?", + position = 1, + group = "Chat Translation", + hidden = true, + unhide = "translateOptionVisable" ) default boolean publicChat() { @@ -35,13 +35,13 @@ public interface ChatTranslationConfig extends Config } @ConfigItem( - keyName = "playerNames", - name = "Translated Player list:", - description = "Players you add to this list will be Translated in Public chat.", - position = 2, - group = "Public Chat Translation", - hidden = true, - unhide = "translateOptionVisable" + keyName = "playerNames", + name = "Translated Player list:", + description = "Players you add to this list will be Translated in chat.", + position = 2, + group = "Chat Translation", + hidden = true, + unhide = "translateOptionVisable" ) default String getPlayerNames() { @@ -49,13 +49,13 @@ public interface ChatTranslationConfig extends Config } @ConfigItem( - keyName = "publicTargetLanguage", - name = "Target Language", - description = "Language to translate messages too.", - position = 2, - group = "Public Chat Translation", - hidden = true, - unhide = "publicChat" + keyName = "publicTargetLanguage", + name = "Target Language", + description = "Language to translate messages too.", + position = 2, + group = "Chat Translation", + hidden = true, + unhide = "publicChat" ) default Languages publicTargetLanguage() { @@ -63,11 +63,11 @@ public interface ChatTranslationConfig extends Config } @ConfigItem( - keyName = "playerChat", - name = "Translate outgoing Messages", - description = "Would you like to Translate your Messages?", - position = 3, - group = "Player Message Translation" + keyName = "playerChat", + name = "Translate outgoing Messages", + description = "Would you like to Translate your Messages?", + position = 3, + group = "Player Message Translation" ) default boolean playerChat() { @@ -75,13 +75,13 @@ public interface ChatTranslationConfig extends Config } @ConfigItem( - keyName = "playerTargetLanguage", - name = "Target Language", - description = "Language to translate messages too.", - position = 4, - group = "Player Message Translation", - hidden = true, - unhide = "playerChat" + keyName = "playerTargetLanguage", + name = "Target Language", + description = "Language to translate messages too.", + position = 4, + group = "Player Message Translation", + hidden = true, + unhide = "playerChat" ) default Languages playerTargetLanguage() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java index 65668483e2..034dfa2647 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chattranslation/ChatTranslationPlugin.java @@ -29,10 +29,10 @@ import java.awt.event.KeyEvent; import java.util.ArrayList; @PluginDescriptor( - name = "Chat Translator", - description = "Translates messages from one Language to another.", - tags = {"translate", "language", "english", "spanish", "dutch", "french"}, - type = PluginType.UTILITY + name = "Chat Translator", + description = "Translates messages from one Language to another.", + tags = {"translate", "language", "english", "spanish", "dutch", "french"}, + type = PluginType.UTILITY ) public class ChatTranslationPlugin extends Plugin implements KeyListener { @@ -180,6 +180,7 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener { case PUBLICCHAT: case MODCHAT: + case FRIENDSCHAT: if (!config.publicChat()) { return; @@ -237,11 +238,24 @@ public class ChatTranslationPlugin extends Plugin implements KeyListener { if (event.getKeyCode() == 0xA) { - event.consume(); - Translator translator = new Translator(); String message = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + if (message.startsWith("/")) + { + try + { + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, translator.translate("auto", config.playerTargetLanguage().toString(), message)); + } + catch (Exception e) + { + e.printStackTrace(); + } + return; + } + + event.consume(); + try { //Automatically check language of message and translate to selected language. From c2710ada6b48e4d7395c229fbef589abe9b13b5f Mon Sep 17 00:00:00 2001 From: Zeruth Date: Tue, 2 Jul 2019 19:22:20 -0400 Subject: [PATCH 62/63] fixes cluescroll plugin --- .../plugins/cluescrolls/ClueScrollPlugin.java | 13 +- .../cluescrolls/clues/AnagramClue.java | 4 +- .../plugins/cluescrolls/clues/CipherClue.java | 2 +- .../cluescrolls/clues/CrypticClue.java | 12 +- .../cluescrolls/clues/FaloTheBardClue.java | 2 +- .../cluescrolls/clues/HotColdClue.java | 297 +++++++----------- .../plugins/cluescrolls/clues/MapClue.java | 2 +- .../plugins/cluescrolls/clues/MusicClue.java | 2 +- .../clues/ThreeStepCrypticClue.java | 16 +- .../cluescrolls/clues/emote/Emote.java | 28 +- .../clues/hotcold/HotColdLocation.java | 19 +- .../clues/hotcold/HotColdSolver.java | 167 ++++++++++ .../clues/hotcold/HotColdTemperature.java | 112 +++++++ .../hotcold/HotColdTemperatureChange.java | 55 ++++ 14 files changed, 499 insertions(+), 232 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java index b1bd8ddbc2..742decdd0d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java @@ -36,8 +36,10 @@ import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.stream.Stream; import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -98,7 +100,6 @@ import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.TextComponent; import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.util.ImageUtil; -import net.runelite.client.util.ItemUtil; import net.runelite.client.util.Text; @PluginDescriptor( @@ -225,9 +226,9 @@ public class ClueScrollPlugin extends Plugin @Subscribe public void onMenuOptionClicked(final MenuOptionClicked event) { - if (event.getOption() != null && event.getOption().equals("Read")) + if (event.getMenuAction() != null && event.getMenuAction().equals("Read")) { - final ItemDefinition itemComposition = itemManager.getItemDefinition(event.getIdentifier()); + final ItemDefinition itemComposition = itemManager.getItemDefinition(event.hashCode()); if (itemComposition != null && itemComposition.getName().startsWith("Clue scroll")) { @@ -256,8 +257,10 @@ public class ClueScrollPlugin extends Plugin // Check if item was removed from inventory if (clue != null && clueItemId != null) { + final Stream items = Arrays.stream(event.getItemContainer().getItems()); + // Check if clue was removed from inventory - if (!ItemUtil.containsItemId(event.getItemContainer().getItems(), clueItemId)) + if (items.noneMatch(item -> itemManager.getItemDefinition(item.getId()).getId() == clueItemId)) { resetClue(true); } @@ -761,7 +764,7 @@ public class ClueScrollPlugin extends Plugin textComponent.render(graphics); } - void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget... toHighlight) + void scrollToWidget(WidgetInfo list, WidgetInfo scrollbar, Widget ... toHighlight) { final Widget parent = client.getWidget(list); int averageCentralY = 0; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java index 1289bf9dc4..a8b59775e5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/AnagramClue.java @@ -267,12 +267,12 @@ public class AnagramClue extends ClueScroll implements TextClueScroll, NpcClueSc @Override public String[] getNpcs() { - return new String[]{npc}; + return new String[] {npc}; } @Override public int[] getObjectIds() { - return new int[]{objectId}; + return new int[] {objectId}; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java index a4aa491c32..404ce70eae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CipherClue.java @@ -133,6 +133,6 @@ public class CipherClue extends ClueScroll implements TextClueScroll, NpcClueScr public String[] getNpcs() { - return new String[]{npc}; + return new String[] {npc}; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 725d17622c..18124aae0d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -80,7 +80,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Speak to the bartender of the Blue Moon Inn in Varrock.", "Bartender", new WorldPoint(3226, 3399, 0), "Talk to the bartender in Blue Moon Inn in Varrock."), new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2846, 1749, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), new CrypticClue("Search the crates in the shed just north of East Ardougne.", CRATE_355, new WorldPoint(2617, 3347, 0), "The crates in the shed north of the northern Ardougne bank."), - new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1697, 3574, 0), "Talk to father Jean in the Hosidius church"), + new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1734, 3576, 0), "Talk to father Jean in the Hosidius church"), new CrypticClue("Search the crate in the Toad and Chicken pub.", CRATE_354, new WorldPoint(2913, 3536, 0), "The Toad and Chicken pub is located in Burthorpe."), new CrypticClue("Search chests found in the upstairs of shops in Port Sarim.", CLOSED_CHEST_375, new WorldPoint(3016, 3205, 1), "Search the chest in the upstairs of Wydin's Food Store, on the east wall."), new CrypticClue("Right on the blessed border, cursed by the evil ones. On the spot inaccessible by both; I will be waiting. The bugs' imminent possession holds the answer.", new WorldPoint(3410, 3324, 0), "B I P. Dig right under the fairy ring."), @@ -116,7 +116,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Probably filled with wizards socks.", "Wizard", DRAWERS_350, new WorldPoint(3116, 9562, 0), "Search the drawers in the basement of the Wizard's Tower south of Draynor Village. Kill one of the Wizards for the key. Fairy ring DIS"), new CrypticClue("Even the seers say this clue goes right over their heads.", CRATE_14934, new WorldPoint(2707, 3488, 2), "Search the crate on the Seers Agility Course in Seers Village"), new CrypticClue("Speak to a Wyse man.", "Wyson the gardener", new WorldPoint(3026, 3378, 0), "Talk to Wyson the gardener at Falador Park."), - new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk", CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."), + new CrypticClue("You'll need to look for a town with a central fountain. Look for a locked chest in the town's chapel.", "Monk" , CLOSED_CHEST_5108, new WorldPoint(3256, 3487, 0), "Search the chest by the stairs in the Varrock church. Kill a Monk in Ardougne Monastery to obtain the key."), new CrypticClue("Talk to Ambassador Spanfipple in the White Knights Castle.", "Ambassador Spanfipple", new WorldPoint(2979, 3340, 0), "Ambassador Spanfipple can be found roaming on the first floor of the White Knights Castle."), new CrypticClue("Mine was the strangest birth under the sun. I left the crimson sack, yet life had not begun. Entered the world, and yet was seen by none.", new WorldPoint(2832, 9586, 0), "Inside Karamja Volcano, dig directly underneath the Red spiders' eggs respawn."), new CrypticClue("Search for a crate in Varrock Castle.", CRATE_5113, new WorldPoint(3224, 3492, 0), "Search the crate in the corner of the kitchen in Varrock Castle."), @@ -202,7 +202,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Search the drawers on the first floor of a building overlooking Ardougne's Market.", DRAWERS_352, new WorldPoint(2657, 3322, 1), "Climb the ladder in the house north of the market."), new CrypticClue("'A bag belt only?', he asked his balding brothers.", "Abbot Langley", new WorldPoint(3058, 3487, 0), "Talk-to Abbot Langley in Monastery west of Edgeville"), new CrypticClue("Search the drawers upstairs in Falador's shield shop.", DRAWERS, new WorldPoint(2971, 3386, 1), "Cassie's Shield Shop at the northern Falador entrance."), - new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350, new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."), + new CrypticClue("Go to this building to be illuminated, and check the drawers while you are there.", "Market Guard", DRAWERS_350 , new WorldPoint(2512, 3641, 1), "Search the drawers in the first floor of the Lighthouse. Kill a Rellekka marketplace guard to obtain the key."), new CrypticClue("Dig near some giant mushrooms, behind the Grand Tree.", new WorldPoint(2458, 3504, 0), "Dig near the red mushrooms northwest of the Grand Tree."), new CrypticClue("Pentagrams and demons, burnt bones and remains, I wonder what the blood contains.", new WorldPoint(3297, 3890, 0), "Dig under the blood rune spawn next the the Demonic Ruins."), new CrypticClue("Search the drawers above Varrock's shops.", DRAWERS_7194, new WorldPoint(3206, 3419, 1), "Located upstairs in Thessalia's Fine Clothes shop in Varrock."), @@ -428,7 +428,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc for (TileObject gameObject : plugin.getObjectsToMark()) { OverlayUtil.renderHoverableArea(graphics, gameObject.getClickbox(), mousePosition, - CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR); + CLICKBOX_FILL_COLOR, CLICKBOX_BORDER_COLOR, CLICKBOX_HOVER_BORDER_COLOR); OverlayUtil.renderImageLocation(plugin.getClient(), graphics, gameObject.getLocalLocation(), plugin.getClueScrollImage(), IMAGE_Z_OFFSET); } @@ -452,12 +452,12 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc @Override public int[] getObjectIds() { - return new int[]{objectId}; + return new int[] {objectId}; } @Override public String[] getNpcs() { - return new String[]{npc}; + return new String[] {npc}; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java index 001a2e0947..1770e06423 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java @@ -184,7 +184,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl @Override public String[] getNpcs() { - return new String[]{FALO_THE_BARD}; + return new String[] {FALO_THE_BARD}; } public static FaloTheBardClue forText(String text) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java index 10b640a641..5fad4e4207 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/HotColdClue.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Eadgars Ruse + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,21 +25,19 @@ */ package net.runelite.client.plugins.cluescrolls.clues; -import com.google.common.collect.Lists; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.Collection; +import java.util.EnumMap; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.NPC; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; @@ -47,35 +46,45 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdArea; import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdSolver; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperature; +import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdTemperatureChange; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; +@EqualsAndHashCode(callSuper = false, exclude = { "hotColdSolver", "location" }) @Getter +@Slf4j public class HotColdClue extends ClueScroll implements LocationClueScroll, LocationsClueScroll, TextClueScroll, NpcClueScroll { - private static final Pattern INITIAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*)"); - private static final Pattern STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is (.*), (.*) last time\\."); - private static final Pattern FINAL_STRANGE_DEVICE_MESSAGE = Pattern.compile("The device is visibly shaking.*"); - private static final HotColdClue CLUE = - new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", - "Jorral", - "Speak to Jorral to receive a strange device."); + private static final int HOT_COLD_PANEL_WIDTH = 200; + private static final HotColdClue BEGINNER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.", + "Reldo", + "Speak to Reldo to receive a strange device."); + private static final HotColdClue MASTER_CLUE = new HotColdClue("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Jorral may have a clue.", + "Jorral", + "Speak to Jorral to receive a strange device."); - // list of potential places to dig - private List digLocations = new ArrayList<>(); private final String text; private final String npc; private final String solution; + @Nullable + private HotColdSolver hotColdSolver; private WorldPoint location; - private WorldPoint lastWorldPoint; public static HotColdClue forText(String text) { - if (CLUE.text.equalsIgnoreCase(text)) + if (BEGINNER_CLUE.text.equalsIgnoreCase(text)) { - return CLUE; + BEGINNER_CLUE.reset(); + return BEGINNER_CLUE; + } + else if (MASTER_CLUE.text.equalsIgnoreCase(text)) + { + MASTER_CLUE.reset(); + return MASTER_CLUE; } return null; @@ -87,24 +96,35 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat this.npc = npc; this.solution = solution; setRequiresSpade(true); + initializeSolver(); } @Override public WorldPoint[] getLocations() { - return Lists.transform(digLocations, HotColdLocation::getWorldPoint).toArray(new WorldPoint[0]); + if (hotColdSolver == null) + { + return new WorldPoint[0]; + } + + return hotColdSolver.getPossibleLocations().stream().map(HotColdLocation::getWorldPoint).toArray(WorldPoint[]::new); } @Override public void makeOverlayHint(PanelComponent panelComponent, ClueScrollPlugin plugin) { + if (hotColdSolver == null) + { + return; + } + panelComponent.getChildren().add(TitleComponent.builder() .text("Hot/Cold Clue") .build()); - panelComponent.setPreferredSize(new Dimension(200, 0)); + panelComponent.setPreferredSize(new Dimension(HOT_COLD_PANEL_WIDTH, 0)); // strange device has not been tested yet, show how to get it - if (lastWorldPoint == null && location == null) + if (hotColdSolver.getLastWorldPoint() == null && location == null) { if (getNpc() != null) { @@ -131,7 +151,9 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat panelComponent.getChildren().add(LineComponent.builder() .left("Possible areas:") .build()); - Map locationCounts = new HashMap<>(); + + final Map locationCounts = new EnumMap<>(HotColdArea.class); + final Collection digLocations = hotColdSolver.getPossibleLocations(); for (HotColdLocation hotColdLocation : digLocations) { @@ -159,17 +181,16 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat } else { - for (HotColdArea s : locationCounts.keySet()) + for (HotColdArea area : locationCounts.keySet()) { panelComponent.getChildren().add(LineComponent.builder() - .left(s.getName() + ":") + .left(area.getName() + ':') .build()); for (HotColdLocation hotColdLocation : digLocations) { - if (hotColdLocation.getHotColdArea() == s) + if (hotColdLocation.getHotColdArea() == area) { - Rectangle2D r = hotColdLocation.getRect(); panelComponent.getChildren().add(LineComponent.builder() .left("- " + hotColdLocation.getArea()) .leftColor(Color.LIGHT_GRAY) @@ -184,8 +205,13 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat @Override public void makeWorldOverlayHint(Graphics2D graphics, ClueScrollPlugin plugin) { + if (hotColdSolver == null) + { + return; + } + // when final location has been found - if (this.location != null) + if (location != null) { LocalPoint localLocation = LocalPoint.fromWorld(plugin.getClient(), getLocation()); @@ -197,20 +223,17 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat return; } - // when strange device hasn't been activated yet, show Jorral - if (lastWorldPoint == null) + // when strange device hasn't been activated yet, show npc who gives you the strange device + if (hotColdSolver.getLastWorldPoint() == null && plugin.getNpcsToMark() != null) { - // Mark NPC - if (plugin.getNpcsToMark() != null) + for (NPC npcToMark : plugin.getNpcsToMark()) { - for (NPC npc : plugin.getNpcsToMark()) - { - OverlayUtil.renderActorOverlayImage(graphics, npc, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); - } + OverlayUtil.renderActorOverlayImage(graphics, npcToMark, plugin.getClueScrollImage(), Color.ORANGE, IMAGE_Z_OFFSET); } } // once the number of possible dig locations is below 10, show the dig spots + final Collection digLocations = hotColdSolver.getPossibleLocations(); if (digLocations.size() < 10) { // Mark potential dig locations @@ -231,170 +254,86 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public boolean update(final String message, final ClueScrollPlugin plugin) { - if (!message.startsWith("The device is")) + if (hotColdSolver == null) { return false; } - Matcher m1 = FINAL_STRANGE_DEVICE_MESSAGE.matcher(message); - Matcher m2 = STRANGE_DEVICE_MESSAGE.matcher(message); - Matcher m3 = INITIAL_STRANGE_DEVICE_MESSAGE.matcher(message); + final Set temperatureSet; - // the order that these pattern matchers are checked is important - if (m1.find()) + if (this.equals(BEGINNER_CLUE)) { - // final location for hot cold clue has been found - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - markFinalSpot(localWorld); - return true; - } + temperatureSet = HotColdTemperature.BEGINNER_HOT_COLD_TEMPERATURES; } - else if (m2.find()) + else if (this.equals(MASTER_CLUE)) { - String temperature = m2.group(1); - String difference = m2.group(2); - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - updatePossibleArea(localWorld, temperature, difference); - return true; - } + temperatureSet = HotColdTemperature.MASTER_HOT_COLD_TEMPERATURES; } - else if (m3.find()) + else { - String temperature = m3.group(1); - WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); - - if (localWorld != null) - { - updatePossibleArea(localWorld, temperature, ""); - return true; - } + temperatureSet = null; } - return false; + final HotColdTemperature temperature = HotColdTemperature.getFromTemperatureSet(temperatureSet, message); + + if (temperature == null) + { + return false; + } + + final WorldPoint localWorld = plugin.getClient().getLocalPlayer().getWorldLocation(); + + if (localWorld == null) + { + return false; + } + + if ((this.equals(BEGINNER_CLUE) && temperature == HotColdTemperature.BEGINNER_VISIBLY_SHAKING) + || (this.equals(MASTER_CLUE) && temperature == HotColdTemperature.MASTER_VISIBLY_SHAKING)) + { + markFinalSpot(localWorld); + } + else + { + location = null; + + final HotColdTemperatureChange temperatureChange = HotColdTemperatureChange.of(message); + hotColdSolver.signal(localWorld, temperature, temperatureChange); + } + + return true; } @Override public void reset() { - this.lastWorldPoint = null; - digLocations.clear(); + initializeSolver(); } - private void updatePossibleArea(WorldPoint currentWp, String temperature, String difference) + private void initializeSolver() { - this.location = null; - - if (digLocations.isEmpty()) - { - digLocations.addAll(Arrays.asList(HotColdLocation.values())); - } - - int maxSquaresAway = 5000; - int minSquaresAway = 0; - - switch (temperature) - { - // when the strange device reads a temperature, that means that the center of the final dig location - // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) - case "ice cold": - maxSquaresAway = 5000; - minSquaresAway = 500; - break; - case "very cold": - maxSquaresAway = 499; - minSquaresAway = 200; - break; - case "cold": - maxSquaresAway = 199; - minSquaresAway = 150; - break; - case "warm": - maxSquaresAway = 149; - minSquaresAway = 100; - break; - case "hot": - maxSquaresAway = 99; - minSquaresAway = 70; - break; - case "very hot": - maxSquaresAway = 69; - minSquaresAway = 30; - break; - case "incredibly hot": - maxSquaresAway = 29; - minSquaresAway = 5; - break; - } - - // rectangle r1 encompasses all of the points that are within the max possible distance from the player - Point p1 = new Point(currentWp.getX() - maxSquaresAway, currentWp.getY() - maxSquaresAway); - Rectangle r1 = new Rectangle((int) p1.getX(), (int) p1.getY(), 2 * maxSquaresAway + 1, 2 * maxSquaresAway + 1); - // rectangle r2 encompasses all of the points that are within the min possible distance from the player - Point p2 = new Point(currentWp.getX() - minSquaresAway, currentWp.getY() - minSquaresAway); - Rectangle r2 = new Rectangle((int) p2.getX(), (int) p2.getY(), 2 * minSquaresAway + 1, 2 * minSquaresAway + 1); - - // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range - digLocations.removeIf(entry -> r2.contains(entry.getRect()) || !r1.intersects(entry.getRect())); - - // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device - if (lastWorldPoint != null) - { - switch (difference) - { - case "but colder than": - // eliminate spots that are absolutely warmer - digLocations.removeIf(entry -> isFirstPointCloserRect(currentWp, lastWorldPoint, entry.getRect())); - break; - case "and warmer than": - // eliminate spots that are absolutely colder - digLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, currentWp, entry.getRect())); - break; - case "and the same temperature as": - // I couldn't figure out a clean implementation for this case - // not necessary for quickly determining final location - } - } - - lastWorldPoint = currentWp; - } - - private boolean isFirstPointCloserRect(WorldPoint firstWp, WorldPoint secondWp, Rectangle2D r) - { - final boolean isBeginner; - WorldPoint p1 = new WorldPoint((int) r.getMaxX(), (int) r.getMaxY(), 0); - if (!isFirstPointCloser(firstWp, secondWp, p1)) + if (this.equals(BEGINNER_CLUE)) { - return false; + isBeginner = true; + } + else if (this.equals(MASTER_CLUE)) + { + isBeginner = false; + } + else + { + log.warn("Hot cold solver could not be initialized, clue type is unknown; text: {}, npc: {}, solution: {}", + text, npc, solution); + hotColdSolver = null; + return; } - WorldPoint p2 = new WorldPoint((int) r.getMaxX(), (int) r.getMinY(), 0); - - if (!isFirstPointCloser(firstWp, secondWp, p2)) - { - return false; - } - else if (!isFirstPointCloser(firstWp, secondWp, p3)) - { - return false; - } - - WorldPoint p4 = new WorldPoint((int) r.getMinX(), (int) r.getMinY(), 0); - return (isFirstPointCloser(firstWp, secondWp, p4)); - } - - private boolean isFirstPointCloser(WorldPoint firstWp, WorldPoint secondWp, WorldPoint wp) - { - int firstDistance = firstWp.distanceTo2D(wp); - int secondDistance = secondWp.distanceTo2D(wp); - return (firstDistance < secondDistance); + final Set locations = Arrays.stream(HotColdLocation.values()) + .filter(l -> l.isBeginnerClue() == isBeginner) + .collect(Collectors.toSet()); + hotColdSolver = new HotColdSolver(locations); } private void markFinalSpot(WorldPoint wp) @@ -405,6 +344,6 @@ public class HotColdClue extends ClueScroll implements LocationClueScroll, Locat public String[] getNpcs() { - return new String[]{npc}; + return new String[] {npc}; } -} \ No newline at end of file +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java index 0d1793d656..e3b6a3d098 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MapClue.java @@ -204,6 +204,6 @@ public class MapClue extends ClueScroll implements ObjectClueScroll public int[] getObjectIds() { - return new int[]{objectId}; + return new int[] {objectId}; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MusicClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MusicClue.java index ad552f841f..6ed7ce176f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MusicClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/MusicClue.java @@ -91,7 +91,7 @@ public class MusicClue extends ClueScroll implements NpcClueScroll @Override public String[] getNpcs() { - return new String[]{CECILIA}; + return new String[] {CECILIA}; } public static MusicClue forText(String text) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java index 34d036ae5a..ae9a1bdf7f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/ThreeStepCrypticClue.java @@ -28,12 +28,15 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.runelite.api.Client; import net.runelite.api.InventoryID; +import net.runelite.api.Item; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_1; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_2; import static net.runelite.api.ItemID.TORN_CLUE_SCROLL_PART_3; @@ -45,7 +48,6 @@ import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; -import net.runelite.client.util.ItemUtil; import net.runelite.client.util.Text; @Getter @@ -125,19 +127,21 @@ public class ThreeStepCrypticClue extends ClueScroll implements TextClueScroll, if (event.getItemContainer() == client.getItemContainer(InventoryID.INVENTORY)) { boolean success = false; - success |= checkForPart(event, TORN_CLUE_SCROLL_PART_1, 0); - success |= checkForPart(event, TORN_CLUE_SCROLL_PART_2, 1); - success |= checkForPart(event, TORN_CLUE_SCROLL_PART_3, 2); + success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_1, 0); + success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_2, 1); + success |= checkForPart(event, itemManager, TORN_CLUE_SCROLL_PART_3, 2); return success; } return false; } - private boolean checkForPart(final ItemContainerChanged event, int clueScrollPart, int index) + private boolean checkForPart(final ItemContainerChanged event, ItemManager itemManager, int clueScrollPart, int index) { + final Stream items = Arrays.stream(event.getItemContainer().getItems()); + // If we have the part then that step is done - if (ItemUtil.containsItemId(event.getItemContainer().getItems(), clueScrollPart)) + if (items.anyMatch(item -> itemManager.getItemDefinition(item.getId()).getId() == clueScrollPart)) { final Map.Entry entry = clueSteps.get(index); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/Emote.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/Emote.java index 3110fab866..67019d58d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/Emote.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/emote/Emote.java @@ -25,33 +25,7 @@ package net.runelite.client.plugins.cluescrolls.clues.emote; import lombok.Getter; -import static net.runelite.api.SpriteID.EMOTE_ANGRY; -import static net.runelite.api.SpriteID.EMOTE_BECKON; -import static net.runelite.api.SpriteID.EMOTE_BLOW_KISS; -import static net.runelite.api.SpriteID.EMOTE_BOW; -import static net.runelite.api.SpriteID.EMOTE_CHEER; -import static net.runelite.api.SpriteID.EMOTE_CLAP; -import static net.runelite.api.SpriteID.EMOTE_CRY; -import static net.runelite.api.SpriteID.EMOTE_DANCE; -import static net.runelite.api.SpriteID.EMOTE_FLAP; -import static net.runelite.api.SpriteID.EMOTE_GOBLIN_SALUTE; -import static net.runelite.api.SpriteID.EMOTE_HEADBANG; -import static net.runelite.api.SpriteID.EMOTE_JIG; -import static net.runelite.api.SpriteID.EMOTE_JUMP_FOR_JOY; -import static net.runelite.api.SpriteID.EMOTE_LAUGH; -import static net.runelite.api.SpriteID.EMOTE_NO; -import static net.runelite.api.SpriteID.EMOTE_PANIC; -import static net.runelite.api.SpriteID.EMOTE_PUSH_UP; -import static net.runelite.api.SpriteID.EMOTE_RASPBERRY; -import static net.runelite.api.SpriteID.EMOTE_SALUTE; -import static net.runelite.api.SpriteID.EMOTE_SHRUG; -import static net.runelite.api.SpriteID.EMOTE_SLAP_HEAD; -import static net.runelite.api.SpriteID.EMOTE_SPIN; -import static net.runelite.api.SpriteID.EMOTE_STOMP; -import static net.runelite.api.SpriteID.EMOTE_THINK; -import static net.runelite.api.SpriteID.EMOTE_WAVE; -import static net.runelite.api.SpriteID.EMOTE_YAWN; -import static net.runelite.api.SpriteID.EMOTE_YES; +import static net.runelite.api.SpriteID.*; @Getter public enum Emote diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index e41fd5357e..b3bd0c91db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, Eadgars Ruse * Copyright (c) 2018, Adam + * Copyright (c) 2019, Jordan Atwood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +27,6 @@ package net.runelite.client.plugins.cluescrolls.clues.hotcold; import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.coords.WorldPoint; @@ -69,6 +69,8 @@ public enum HotColdLocation DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), + DRAYNOR_MANOR_MUSHROOMS(true, new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), + DRAYNOR_WHEAT_FIELD(true, new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), FELDIP_HILLS_JIGGIG(new WorldPoint(2413, 3055, 0), FELDIP_HILLS, "West of Jiggig, east of the fairy ring bkp."), FELDIP_HILLS_SW(new WorldPoint(2582, 2895, 0), FELDIP_HILLS, "West of the southeasternmost lake in Feldip Hills."), FELDIP_HILLS_GNOME_GLITER(new WorldPoint(2553, 2972, 0), FELDIP_HILLS, "East of the gnome glider (Lemantolly Undri)."), @@ -91,6 +93,7 @@ public enum HotColdLocation FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2147, 3862, 0), FREMENNIK_PROVINCE, "Astral altar"), FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2087, 3915, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village."), FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village."), + ICE_MOUNTAIN(true, new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), KANDARIN_SINCLAR_MANSION(new WorldPoint(2726, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), KANDARIN_CATHERBY(new WorldPoint(2774, 3433, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), KANDARIN_GRAND_TREE(new WorldPoint(2444, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure."), @@ -115,6 +118,7 @@ public enum HotColdLocation KARAMJA_KHARAZI_NE(new WorldPoint(2904, 2925, 0), KARAMJA, "North-eastern part of Kharazi Jungle."), KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), KARAMJA_CRASH_ISLAND(new WorldPoint(2910, 2737, 0), KARAMJA, "Northern part of Crash Island."), + LUMBRIDGE_COW_FIELD(true, new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), @@ -131,6 +135,7 @@ public enum HotColdLocation MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), MORYTANIA_DRAGONTOOTH_NORTH(new WorldPoint(3813, 3567, 0), MORYTANIA, "Northern part of Dragontooth Island."), MORYTANIA_DRAGONTOOTH_SOUTH(new WorldPoint(3803, 3532, 0), MORYTANIA, "Southern part of Dragontooth Island."), + NORTHEAST_OF_AL_KHARID_MINE(true, new WorldPoint(3332, 3313, 0), MISTHALIN, "Northeast of Al Kharid Mine"), WESTERN_PROVINCE_EAGLES_PEAK(new WorldPoint(2297, 3530, 0), WESTERN_PROVINCE, "North-west of Eagles' Peak."), WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2337, 3689, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony"), WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2361, 3566, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), @@ -176,12 +181,20 @@ public enum HotColdLocation ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); + private final boolean beginnerClue; private final WorldPoint worldPoint; private final HotColdArea hotColdArea; private final String area; - public Rectangle2D getRect() + HotColdLocation(WorldPoint worldPoint, HotColdArea hotColdArea, String areaDescription) { - return new Rectangle(worldPoint.getX() - 4, worldPoint.getY() - 4, 9, 9); + this(false, worldPoint, hotColdArea, areaDescription); + } + + public Rectangle getRect() + { + final int digRadius = beginnerClue ? HotColdTemperature.BEGINNER_VISIBLY_SHAKING.getMaxDistance() : + HotColdTemperature.MASTER_VISIBLY_SHAKING.getMaxDistance(); + return new Rectangle(worldPoint.getX() - digRadius, worldPoint.getY() - digRadius, digRadius * 2 + 1, digRadius * 2 + 1); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java new file mode 100644 index 0000000000..87414f0387 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdSolver.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2018, Eadgars Ruse + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import com.google.common.annotations.VisibleForTesting; +import java.awt.Rectangle; +import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import lombok.Getter; +import net.runelite.api.coords.WorldPoint; + +/** + * Solution finder for hot-cold style puzzles. + *

+ * These puzzles are established by having some way to test the distance from the solution via "warmth", where being + * colder means one is farther away from the target, and being warmer means one is closer to it, with the goal being to + * reach the most warm value to discover the solution point. Hot-cold puzzles in Old School Runescape are implemented + * with specific set of solution points, so this solver will filter from a provided set of possible solutions as new + * signals of temperatures and temperature changes are provided. + */ +@Getter +public class HotColdSolver +{ + private final Set possibleLocations; + @Nullable + private WorldPoint lastWorldPoint; + + public HotColdSolver(Set possibleLocations) + { + this.possibleLocations = possibleLocations; + } + + /** + * Process a hot-cold update given a {@link WorldPoint} where a check occurred and the resulting temperature and + * temperature change discovered at that point. This will filter the set of possible locations which can be the + * solution. + * + * @param worldPoint The point where a hot-cold check occurred + * @param temperature The temperature of the checked point + * @param temperatureChange The change of temperature of the checked point compared to the previously-checked point + * @return A set of {@link HotColdLocation}s which are still possible after the filtering occurs. This return value + * is the same as would be returned by {@code getPossibleLocations()}. + */ + public Set signal(@Nonnull final WorldPoint worldPoint, @Nonnull final HotColdTemperature temperature, @Nullable final HotColdTemperatureChange temperatureChange) + { + // when the strange device reads a temperature, that means that the center of the final dig location + // is a range of squares away from the player's current location (Chebyshev AKA Chess-board distance) + int maxSquaresAway = temperature.getMaxDistance(); + int minSquaresAway = temperature.getMinDistance(); + + // maxDistanceArea encompasses all of the points that are within the max possible distance from the player + final Rectangle maxDistanceArea = new Rectangle( + worldPoint.getX() - maxSquaresAway, + worldPoint.getY() - maxSquaresAway, + 2 * maxSquaresAway + 1, + 2 * maxSquaresAway + 1); + // minDistanceArea encompasses all of the points that are within the min possible distance from the player + final Rectangle minDistanceArea = new Rectangle( + worldPoint.getX() - minSquaresAway, + worldPoint.getY() - minSquaresAway, + 2 * minSquaresAway + 1, + 2 * minSquaresAway + 1); + + // eliminate from consideration dig spots that lie entirely within the min range or entirely outside of the max range + possibleLocations.removeIf(entry -> minDistanceArea.contains(entry.getRect()) || !maxDistanceArea.intersects(entry.getRect())); + + // if a previous world point has been recorded, we can consider the warmer/colder result from the strange device + if (lastWorldPoint != null && temperatureChange != null) + { + switch (temperatureChange) + { + case COLDER: + // eliminate spots that are absolutely warmer + possibleLocations.removeIf(entry -> isFirstPointCloserRect(worldPoint, lastWorldPoint, entry.getRect())); + break; + case WARMER: + // eliminate spots that are absolutely colder + possibleLocations.removeIf(entry -> isFirstPointCloserRect(lastWorldPoint, worldPoint, entry.getRect())); + break; + case SAME: + // I couldn't figure out a clean implementation for this case + // not necessary for quickly determining final location + } + } + + lastWorldPoint = worldPoint; + return getPossibleLocations(); + } + + /** + * Determines whether the first point passed is closer to each corner of the given rectangle than the second point. + * + * @param firstPoint First point to test. Return result will be relating to this point's location. + * @param secondPoint Second point to test + * @param rect Rectangle, whose corner points will be compared to the first and second points passed + * @return {@code true} if {@code firstPoint} is closer to each of {@code rect}'s four corner points than + * {@code secondPoint}, {@code false} otherwise. + * @see WorldPoint#distanceTo2D + */ + @VisibleForTesting + static boolean isFirstPointCloserRect(final WorldPoint firstPoint, final WorldPoint secondPoint, final Rectangle rect) + { + final WorldPoint nePoint = new WorldPoint((rect.x + rect.width), (rect.y + rect.height), 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, nePoint)) + { + return false; + } + + final WorldPoint sePoint = new WorldPoint((rect.x + rect.width), rect.y, 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, sePoint)) + { + return false; + } + + final WorldPoint nwPoint = new WorldPoint(rect.x, (rect.y + rect.height), 0); + + if (!isFirstPointCloser(firstPoint, secondPoint, nwPoint)) + { + return false; + } + + final WorldPoint swPoint = new WorldPoint(rect.x, rect.y, 0); + return (isFirstPointCloser(firstPoint, secondPoint, swPoint)); + } + + /** + * Determines whether the first point passed is closer to the given point of comparison than the second point. + * + * @param firstPoint First point to test. Return result will be relating to this point's location. + * @param secondPoint Second point to test + * @param worldPoint Point to compare to the first and second points passed + * @return {@code true} if {@code firstPoint} is closer to {@code worldPoint} than {@code secondPoint}, + * {@code false} otherwise. + * @see WorldPoint#distanceTo2D + */ + @VisibleForTesting + static boolean isFirstPointCloser(final WorldPoint firstPoint, final WorldPoint secondPoint, final WorldPoint worldPoint) + { + return firstPoint.distanceTo2D(worldPoint) < secondPoint.distanceTo2D(worldPoint); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java new file mode 100644 index 0000000000..2dc5909000 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperature.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum HotColdTemperature +{ + ICE_COLD("ice cold", 500, 5000), + VERY_COLD("very cold", 200, 499), + COLD("cold", 150, 199), + WARM("warm", 100, 149), + HOT("hot", 70, 99), + VERY_HOT("very hot", 30, 69), + BEGINNER_INCREDIBLY_HOT("incredibly hot", 4, 29), + BEGINNER_VISIBLY_SHAKING("visibly shaking", 0, 3), + MASTER_INCREDIBLY_HOT("incredibly hot", 5, 29), + MASTER_VISIBLY_SHAKING("visibly shaking", 0, 4); + + public static final Set BEGINNER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( + ICE_COLD, + VERY_COLD, + COLD, + WARM, + HOT, + VERY_HOT, + BEGINNER_INCREDIBLY_HOT, + BEGINNER_VISIBLY_SHAKING + ); + public static final Set MASTER_HOT_COLD_TEMPERATURES = Sets.immutableEnumSet( + ICE_COLD, + VERY_COLD, + COLD, + WARM, + HOT, + VERY_HOT, + MASTER_INCREDIBLY_HOT, + MASTER_VISIBLY_SHAKING + ); + + private final String text; + private final int minDistance; + private final int maxDistance; + + private static final String DEVICE_USED_START_TEXT = "The device is "; + + /** + * Gets the temperature from a set of temperatures corresponding to the passed string. + * + * @param temperatureSet A set of temperature values to select from + * @param message A string containing a temperature value + * @return The corresponding enum from the given temperature set. + *

+ * Note that in cases where two temperature values in the given set are equally likely to be the given + * temperature (say, two temperatures with identical text values), the behavior is undefined. + */ + @Nullable + public static HotColdTemperature getFromTemperatureSet(final Set temperatureSet, final String message) + { + if (!message.startsWith(DEVICE_USED_START_TEXT) || temperatureSet == null) + { + return null; + } + + final List possibleTemperatures = new ArrayList<>(); + + for (final HotColdTemperature temperature : temperatureSet) + { + if (message.contains(temperature.getText())) + { + possibleTemperatures.add(temperature); + } + } + + return possibleTemperatures.stream() + // For messages such as "The device is very cold", this will choose the Enum with text of greatest length so + // that VERY_COLD would be selected over COLD, though both Enums have matching text for this message. + .max(Comparator.comparingInt(x -> (x.getText()).length())) + .orElse(null); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java new file mode 100644 index 0000000000..e9077bc9e1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdTemperatureChange.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Jordan Atwood + * 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.cluescrolls.clues.hotcold; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum HotColdTemperatureChange +{ + WARMER("and warmer than"), + SAME("and the same temperature as"), + COLDER("but colder than"); + + private final String text; + + public static HotColdTemperatureChange of(final String message) + { + if (!message.endsWith(" last time.")) + { + return null; + } + + for (final HotColdTemperatureChange change : values()) + { + if (message.contains(change.text)) + { + return change; + } + } + + return null; + } +} From 1754ade7118945cc8e8aede99f2bc7c7269d1b29 Mon Sep 17 00:00:00 2001 From: Zeruth Date: Tue, 2 Jul 2019 21:09:07 -0400 Subject: [PATCH 63/63] Revert "Merge branch 'master' into master" This reverts commit 16561db1d653263245c54a4f14a40e43bfe05be9, reversing changes made to c2710ada6b48e4d7395c229fbef589abe9b13b5f. --- README.md | 27 +-- .../runelite/http/api/xtea/XteaClient.java | 50 +++++- params.txt | 24 --- .../defaultworld/DefaultWorldConfig.java | 40 ++--- .../defaultworld/DefaultWorldPlugin.java | 158 ++++++++++++++++++ .../net/runelite/client/rs/ClientLoader.java | 7 +- .../net/runelite/client/rs/RSAppletStub.java | 147 +++++----------- .../net/runelite/mixins/RSGameShellMixin.java | 8 - 8 files changed, 287 insertions(+), 174 deletions(-) delete mode 100644 params.txt rename runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java => runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java (52%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java diff --git a/README.md b/README.md index 0fa8b7c87b..c1e6723a8b 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,31 @@ -# RuneLitePlus-PS rev180 [![Build Status](https://travis-ci.org/zeruth/runeliteplus-ps.svg?branch=master)](https://travis-ci.org/zeruth/runeliteplus-ps) [![Discord](https://img.shields.io/discord/373382904769675265.svg)](https://discord.gg/HN5gf3m) +# RuneLitePlus +[![forthebadge](https://forthebadge.com/images/badges/built-by-developers.svg)](https://forthebadge.com) -[RuneLitePlus-PS](https://runelitepl.us) is a fork of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying open source. This is a specific version meant for rs-mod which can be found here: -https://www.rune-server.ee/runescape-development/rs2-server/downloads/684206-180-rs-mod-release.html +[![Build Status](https://travis-ci.org/runelite-extended/runelite.svg?branch=master)](https://travis-ci.org/runelite-extended/runelite) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![HitCount](http://hits.dwyl.io/runelite-extended/runelite.svg)](http://hits.dwyl.io/runelite-extended/runelite) [![saythanks](https://img.shields.io/badge/say-thanks-32cd32.svg)](https://www.patreon.com/RuneLitePlus) -## Usage -By default, this connects to our sandbox server, which is for client testing. +[RuneLitePlus](https://runelitepl.us) is a extended version of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying more open-source. -To setup your rsa keys, navigate to runelite-mixins and go to RSBufferMixin and set modulus and exponent -To setup your codebase, navigate to runelite-client/rs and go to RSAppletStub and set codebase = new URL("http://IP_OR_URL_HERE/"); -After that it's ran much like RuneLite or RuneLitePlus, install then run RuneLite.main() -To release the built jar publicly, you'd have to host your injected client remotely and make some small modifications to rs.ClientLoader +## Discord +![[Discord]](https://discordapp.com/api/guilds/373382904769675265/widget.png?style=banner2) + +## Project Layout + +- [cache](cache/src/main/java/net/runelite/cache) - Libraries used for reading/writing cache files, as well as the data in it +- [http-api](http-api/src/main/java/net/runelite/http/api) - API for runelite and runeliteplus +- [http-service](http-service/src/main/java/net/runelite/http/service) - Service for https://api.runelitepl.us +- [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client +- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the vanilla client's classes +- [runescape-api](runescape-api/src/main/java/net/runelite) - Mappings correspond to these interfaces, runelite-api is a subset of this +- [runelite-client](runelite-client/src/main/java/net/runelite/client) - Game client with plugins ## License -RuneLitePlus-PS is licensed under the BSD 2-clause license. See the license header in the respective file to be sure. +RuneLitePlus is licensed under the BSD 2-clause license. See the license header in the respective file to be sure. ## Contribute and Develop diff --git a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java index 25196717ba..7e01dc4b56 100644 --- a/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java +++ b/http-api/src/main/java/net/runelite/http/api/xtea/XteaClient.java @@ -49,7 +49,55 @@ public class XteaClient public void submit(XteaRequest xteaRequest) { - // Don't submit xteas from private server + String json = RuneLiteAPI.GSON.toJson(xteaRequest); + + HttpUrl url = RuneLiteAPI.getPlusApiBase().newBuilder() + .addPathSegment("xtea") + .build(); + + logger.debug("Built URI: {}", url); + + Request request = new Request.Builder() + .post(RequestBody.create(JSON, json)) + .url(url) + .build(); + + try + { + try (Response response = RuneLiteAPI.RLP_CLIENT.newCall(request).execute()) + { + logger.debug("xtea response " + response.code()); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + + RuneLiteAPI.RLP_CLIENT.newCall(request).enqueue(new Callback() + { + @Override + public void onFailure(Call call, IOException e) + { + logger.warn("unable to submit xtea keys", e); + } + + @Override + public void onResponse(Call call, Response response) + { + try + { + if (!response.isSuccessful()) + { + logger.debug("unsuccessful xtea response"); + } + } + finally + { + response.close(); + } + } + }); } public List get() throws IOException diff --git a/params.txt b/params.txt deleted file mode 100644 index 5de07bea64..0000000000 --- a/params.txt +++ /dev/null @@ -1,24 +0,0 @@ -Created at Thu Jun 20 05:35:31 CDT 2019 - -codebase=http://oldschool6b.runescape.com/ -mainclass=client.class - -param=1=1 -param=2=https://payments.jagex.com/operator/v1/ -param=3=true -param=4=761 -param=5=1 -param=6=0 -param=7=0 -param=8=true -param=9=ElZAIrq5NpKN6D3mDdihco3oPeYN2KFy2DCquj7JMmECPmLrDP3Bnw -param=10=5 -param=11=https://auth.jagex.com/ -param=12=306 -param=13=.runescape.com -param=14=0 -param=15=0 -param=16=false -param=17=http://www.runescape.com/g=oldscape/slr.ws?order=LPWM -param=18= -param=19=196515767263-1oo20deqm6edn7ujlihl6rpadk9drhva.apps.googleusercontent.com diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java similarity index 52% rename from runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java rename to runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java index e37dadc241..480d4c891d 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Null (zeruth) + * Copyright (c) 2018, Tomas Slusny * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,32 +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.mixins; +package net.runelite.client.plugins.defaultworld; -import java.math.BigInteger; -import net.runelite.api.mixins.Copy; -import net.runelite.api.mixins.Inject; -import net.runelite.api.mixins.Mixin; -import net.runelite.api.mixins.Replace; -import net.runelite.rs.api.RSBuffer; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; -@Mixin(RSBuffer.class) -public abstract class RSBufferMixin implements RSBuffer +@ConfigGroup("defaultworld") +public interface DefaultWorldConfig extends Config { - @Inject - private static BigInteger modulus = new BigInteger("10001", 16); - - @Inject - private static BigInteger exponent = new BigInteger("bb5d826b249905895f4e463422dd339f8375ed5b212ac8890a97e4ab7dba0c5fe8188f44c00f8106e5721f615a8bcee2da7316ff1572cad5fbfd33f30985f0ae855cfd498483ecc0c3a01c8630f90cff1f54e75a44d58482c371e203e6eb7ba879fd65949aeef827a5e550429bd857d712f64351bc1162e1615ca6622a3bc9b8e31a96000fb0a01a12a51ca3e89918c06759d1db65c33dc6a074abec02f94466886d1a52e7d084aa88338aab1f25d58f9e03ed0a308c6c4eed139c1c1c818cd2370d8cd28ec34bce18360d1756e202eb733f998200242d71ce19548f23b03c1eac4d6e9892616ade1c66d2ce3ab69744e27d7099f3574bcd3d3e95e7a52180d9", 16); - - @Copy("encryptRsa") - public void rs$encryptRsa(BigInteger var1, BigInteger var2) + @ConfigItem( + keyName = "defaultWorld", + name = "Default world", + description = "World to use as default one" + ) + default int getWorld() { + return 0; } - - @Replace("encryptRsa") - public void rl$encryptRsa(BigInteger var1, BigInteger var2) - { - rs$encryptRsa(modulus, exponent); - } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java new file mode 100644 index 0000000000..96d5dfa246 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.defaultworld; + +import com.google.inject.Provides; +import java.io.IOException; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.GameStateChanged; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.SessionOpen; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.WorldUtil; +import net.runelite.http.api.worlds.World; +import net.runelite.http.api.worlds.WorldClient; +import net.runelite.http.api.worlds.WorldResult; + +@PluginDescriptor( + name = "Default World", + description = "Enable a default world to be selected when launching the client", + tags = {"home"} +) +@Slf4j +public class DefaultWorldPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private DefaultWorldConfig config; + + private final WorldClient worldClient = new WorldClient(); + private int worldCache; + private boolean worldChangeRequired; + + @Override + protected void startUp() throws Exception + { + worldChangeRequired = true; + applyWorld(); + } + + @Override + protected void shutDown() throws Exception + { + worldChangeRequired = true; + changeWorld(worldCache); + } + + @Provides + DefaultWorldConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(DefaultWorldConfig.class); + } + + @Subscribe + public void onSessionOpen(SessionOpen event) + { + worldChangeRequired = true; + applyWorld(); + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + applyWorld(); + } + + private void changeWorld(int newWorld) + { + if (!worldChangeRequired || client.getGameState() != GameState.LOGIN_SCREEN) + { + return; + } + + worldChangeRequired = false; + int correctedWorld = newWorld < 300 ? newWorld + 300 : newWorld; + + // Old School RuneScape worlds start on 301 so don't even bother trying to find lower id ones + // and also do not try to set world if we are already on it + if (correctedWorld <= 300 || client.getWorld() == correctedWorld) + { + return; + } + + try + { + final WorldResult worldResult = worldClient.lookupWorlds(); + + if (worldResult == null) + { + return; + } + + final World world = worldResult.findWorld(correctedWorld); + + if (world != null) + { + final net.runelite.api.World rsWorld = client.createWorld(); + rsWorld.setActivity(world.getActivity()); + rsWorld.setAddress(world.getAddress()); + rsWorld.setId(world.getId()); + rsWorld.setPlayerCount(world.getPlayers()); + rsWorld.setLocation(world.getLocation()); + rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); + + client.changeWorld(rsWorld); + log.debug("Applied new world {}", correctedWorld); + } + else + { + log.warn("World {} not found.", correctedWorld); + } + } + catch (IOException e) + { + log.warn("Error looking up world {}. Error: {}", correctedWorld, e); + } + } + + private void applyWorld() + { + if (worldCache == 0) + { + worldCache = client.getWorld(); + log.debug("Stored old world {}", worldCache); + } + + final int newWorld = config.getWorld(); + changeWorld(newWorld); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index a56a7b3a3d..1024da016f 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -60,8 +60,13 @@ public class ClientLoader switch (updateCheckMode) { + case AUTO: default: return loadRLPlus(config); + case VANILLA: + return loadVanilla(config); + case NONE: + return null; } } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) @@ -102,7 +107,7 @@ public class ClientLoader private static Applet loadFromClass(final RSConfig config, final Class clientClass) throws IllegalAccessException, InstantiationException { final Applet rs = (Applet) clientClass.newInstance(); - rs.setStub(new RSAppletStub()); + rs.setStub(new RSAppletStub(config)); return rs; } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java index df3fce8e0e..a3a2a0f14a 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java @@ -1,133 +1,70 @@ +/* + * Copyright (c) 2016-2017, Adam + * Copyright (c) 2018, Tomas Slusny + * 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.rs; import java.applet.AppletContext; import java.applet.AppletStub; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; +import lombok.RequiredArgsConstructor; -public class RSAppletStub implements AppletStub +@RequiredArgsConstructor +class RSAppletStub implements AppletStub { - - public static final Logger logger = Logger.getLogger(RSAppletStub.class.getSimpleName()); - - private static final HashMap params = new HashMap(); - private static final HashMap cfg = new HashMap(); - private static URL codebase; - - static - { - cfg.put("privacyurl", "http://www.jagex.com/g=oldscape/privacy/privacy.ws"); - cfg.put("window_preferredheight", "600"); - cfg.put("msg", "new_version_link=http://oldschool.runescape.com/"); - cfg.put("applet_minwidth", "765"); - cfg.put("adverturl", "http://www.runescape.com/g=oldscape/bare_advert.ws"); - cfg.put("cachedir", "oldschool"); - cfg.put("window_preferredwidth", "800"); - cfg.put("applet_maxheight", "2160"); - cfg.put("win_sub_version", "1"); - cfg.put("browsercontrol_win_x86_jar", "browsercontrol_0_-1928975093.jar"); - cfg.put("other_sub_version", "2"); - cfg.put("initial_jar", "gamepack_4840368.jar"); - cfg.put("advert_height", "96"); - cfg.put("title", "Old School RuneScape"); - cfg.put("storebase", "0"); - cfg.put("initial_class", "client.class"); - cfg.put("applet_maxwidth", "5760"); - cfg.put("download", "1230228"); - cfg.put("termsurl", "http://www.jagex.com/g=oldscape/terms/terms.ws"); - cfg.put("codebase", "http://oldschool1.runescape.com/"); - cfg.put("mac_sub_version", "2"); - cfg.put("browsercontrol_win_amd64_jar", "browsercontrol_1_1674545273.jar"); - cfg.put("applet_minheight", "503"); - cfg.put("viewerversion", "124"); - } - - public RSAppletStub() - { - try - { - parseParams(new FileInputStream(new File("./params.txt"))); - String worldListKey = null; - for (Map.Entry paramEntry : params.entrySet()) - { - String key = paramEntry.getKey(); - String value = paramEntry.getValue(); - if (value.contains("slr.ws")) - { - worldListKey = key; - break; - } - } - codebase = new URL("http://runeliteplus-ps.ddns.net"); //host - params.put(worldListKey, "http://" + codebase.getHost()); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - private static void parseParams(InputStream stream) throws IOException - { - BufferedReader br = new BufferedReader(new InputStreamReader(stream)); - String line; - while ((line = br.readLine()) != null) - { - int idx = line.indexOf('='); - if (idx != -1) - { - String key = line.substring(0, idx); - String val = line.substring(idx + 1); - if (key.equals("param")) - { - idx = val.indexOf('='); - key = val.substring(0, idx); - val = val.substring(idx + 1); - params.put(key, val); - } - else - { - cfg.put(key, val); - } - } - } - } - - public static void log(String format, Object... params) - { - System.out.printf(format + "\n", params); - } + private final RSConfig config; @Override public boolean isActive() { - return false; + return true; } @Override public URL getDocumentBase() { - return codebase; + return getCodeBase(); } @Override public URL getCodeBase() { - return codebase; + try + { + return new URL(config.getCodeBase()); + } + catch (MalformedURLException ex) + { + return null; + } } @Override public String getParameter(String name) { - return params.get(name); + return config.getAppletProperties().get(name); } @Override @@ -140,4 +77,4 @@ public class RSAppletStub implements AppletStub public void appletResize(int width, int height) { } -} +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java index 93f389345a..e45d2612e7 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java @@ -31,7 +31,6 @@ import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.MethodHook; import net.runelite.api.mixins.Mixin; -import net.runelite.api.mixins.Replace; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSGameShell; @@ -98,11 +97,4 @@ public abstract class RSGameShellMixin implements RSGameShell setResizeCanvasNextFrame(true); } } - - @Replace("checkHost") - protected final boolean checkHost() - { - //Always allow host. - return true; - } }