updateMode = parser
.accepts("rs", "Select client type")
@@ -209,6 +211,12 @@ public class RuneLite
logger.setLevel(Level.DEBUG);
}
+ if (options.has("flexo"))
+ {
+ System.out.println("[RuneLit] Flexo config enabled");
+ ConfigPanel.flexoConfigEnabled = true;
+ }
+
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
{
log.error("Uncaught exception:", throwable);
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 da48d2d116..78ec89a46f 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
@@ -71,7 +71,7 @@ public interface RuneLiteConfig extends Config
)
default boolean enablePlugins()
{
- return false;
+ return true;
}
@ConfigItem(
diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java b/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java
new file mode 100644
index 0000000000..298621b87e
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/flexo/Flexo.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+Modified java.awt.Robot for use with RuneLit. Hopefully we can make it stand far apart.
+Uses
+https://github.com/JoonasVali/NaturalMouseMotion
+for mouse motion.
+ */
+
+package net.runelite.client.flexo;
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.peer.RobotPeer;
+import java.util.Random;
+import java.util.logging.Logger;
+
+import com.github.joonasvali.naturalmouse.api.MouseMotionFactory;
+import net.runelite.api.Client;
+import net.runelite.client.plugins.flexo.FlexoOverlay;
+import net.runelite.client.ui.ClientUI;
+import sun.awt.ComponentFactory;
+import sun.awt.SunToolkit;
+
+public class Flexo extends java.awt.Robot{
+ public static double scale;
+ public static Client client;
+ public static int fixedWidth = 765;
+ public static int fixedHeight = 503;
+ public static boolean isStretched;
+ public static int minDelay = 45;
+ public static MouseMotionFactory currentMouseMotionFactory;
+ private static final int MAX_DELAY = 60000;
+ private RobotPeer peer;
+ private static int LEGAL_BUTTON_MASK = 0;
+
+ public Flexo() throws AWTException {
+ if (GraphicsEnvironment.isHeadless()) {
+ throw new AWTException("headless environment");
+ }
+ init(GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice());
+ }
+
+ private void init(GraphicsDevice screen) throws AWTException {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ if (toolkit instanceof ComponentFactory) {
+ peer = ((ComponentFactory)toolkit).createRobot(this, screen);
+ disposer = new RobotDisposer(peer);
+ sun.java2d.Disposer.addRecord(anchor, disposer);
+ }
+ initLegalButtonMask();
+ }
+
+ private static synchronized void initLegalButtonMask() {
+ if (LEGAL_BUTTON_MASK != 0) return;
+
+ int tmpMask = 0;
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ if (Toolkit.getDefaultToolkit() instanceof SunToolkit) {
+ final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
+ for (int i = 0; i < buttonsNumber; i++){
+ tmpMask |= InputEvent.getMaskForButton(i+1);
+ }
+ }
+ }
+ tmpMask |= InputEvent.BUTTON1_MASK|
+ InputEvent.BUTTON2_MASK|
+ InputEvent.BUTTON3_MASK|
+ InputEvent.BUTTON1_DOWN_MASK|
+ InputEvent.BUTTON2_DOWN_MASK|
+ InputEvent.BUTTON3_DOWN_MASK;
+ LEGAL_BUTTON_MASK = tmpMask;
+ }
+ private transient Object anchor = new Object();
+
+ static class RobotDisposer implements sun.java2d.DisposerRecord {
+ private final RobotPeer peer;
+ private RobotDisposer(RobotPeer peer) {
+ this.peer = peer;
+ }
+ public void dispose() {
+ if (peer != null) {
+ peer.dispose();
+ }
+ }
+ }
+
+ private RobotDisposer disposer;
+
+ @Override
+ public synchronized void mouseMove(int x, int y) {
+ try {
+ //TODO: Must be better way to determine titlebar width
+ currentMouseMotionFactory.build(ClientUI.frame.getX()+x, ClientUI.frame.getY()+y+20).move();
+ this.delay(getMinDelay());
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public synchronized void mousePress(int buttonID) {
+ if (buttonID<1 || buttonID >5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mousePress(InputEvent.getMaskForButton(buttonID));
+ resetOverlay();
+ this.delay(getMinDelay());
+ }
+
+ public void resetOverlay() {
+ FlexoOverlay.clickArea = null;
+ }
+
+ public synchronized void mousePressAndRelease(int buttonID) {
+ if (buttonID<1 || buttonID >5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mousePress(InputEvent.getMaskForButton(buttonID));
+ this.delay(getMinDelay());
+ peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
+ resetOverlay();
+ this.delay(getMinDelay());
+ }
+
+ @Override
+ public synchronized void mouseRelease(int buttonID) {
+ if (buttonID<1 || buttonID >5) {
+ Logger.getAnonymousLogger().warning("Invalid mouse button ID. please use 1-5.");
+ return;
+ }
+ peer.mouseRelease(InputEvent.getMaskForButton(buttonID));
+ resetOverlay();
+ this.delay(getMinDelay());
+ }
+
+ private int getMinDelay() {
+ Random random = new Random();
+ int random1 = random.nextInt(minDelay);
+ if (random1 < minDelay/2)
+ random1 = random.nextInt(minDelay/2) + minDelay/2+random.nextInt(minDelay/2);
+ return random1;
+ }
+
+ private int getWheelDelay() {
+ //TODO: implement random timer.
+ return 40;
+ }
+
+ /**
+ * Rotates the scroll wheel on wheel-equipped mice.
+ *
+ * @param wheelAmt number of "notches" to move the mouse wheel
+ * Negative values indicate movement up/away from the user,
+ * positive values indicate movement down/towards the user.
+ *
+ * @since 1.4
+ */
+ @Override
+ public synchronized void mouseWheel(int wheelAmt) {
+ for (int i : new int[wheelAmt]) {
+ peer.mouseWheel(wheelAmt);
+ this.delay(getWheelDelay());
+ }
+ }
+
+ /**
+ * Presses a given key. The key should be released using the
+ * keyRelease method.
+ *
+ * Key codes that have more than one physical key associated with them
+ * (e.g. KeyEvent.VK_SHIFT could mean either the
+ * left or right shift key) will map to the left key.
+ *
+ * @param keycode Key to press (e.g. KeyEvent.VK_A)
+ * @throws IllegalArgumentException if keycode is not
+ * a valid key
+ * @see #keyRelease(int)
+ * @see java.awt.event.KeyEvent
+ */
+ @Override
+ public synchronized void keyPress(int keycode) {
+ peer.keyPress(keycode);
+ this.delay(getMinDelay());
+ }
+
+ @Override
+ public synchronized void keyRelease(int keycode) {
+ peer.keyRelease(keycode);
+ this.delay(getMinDelay());
+ }
+
+ @Override
+ public synchronized Color getPixelColor(int x, int y) {
+ Color color = new Color(peer.getRGBPixel(x, y));
+ return color;
+ }
+
+ /**
+ * Sleeps for the specified time.
+ * To catch any InterruptedExceptions that occur,
+ * Thread.sleep() may be used instead.
+ * @param ms time to sleep in milliseconds
+ * @throws IllegalArgumentException if ms is not between 0 and 60,000 milliseconds inclusive
+ * @see java.lang.Thread#sleep
+ */
+ @Override
+ public synchronized void delay(int ms) {
+ checkDelayArgument(ms);
+ try {
+ Thread.sleep(ms);
+ } catch(InterruptedException ite) {
+ ite.printStackTrace();
+ }
+ }
+
+ private void checkDelayArgument(int ms) {
+ if (ms < 0 || ms > MAX_DELAY) {
+ throw new IllegalArgumentException("Delay must be to 0 to 60,000ms");
+ }
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java
new file mode 100644
index 0000000000..2ba6a92181
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoMouse.java
@@ -0,0 +1,88 @@
+package net.runelite.client.flexo;
+
+import net.runelite.api.Client;
+import net.runelite.api.Point;
+import net.runelite.client.ui.ClientUI;
+
+import java.awt.*;
+import java.util.Random;
+
+public class FlexoMouse {
+
+ /*
+ Should pass unstretched coords, handles all conversions here.
+ */
+ public static net.runelite.api.Point getClickPoint(Rectangle rect)
+ {
+ if (Flexo.isStretched)
+ {
+ double wScale;
+ double hScale;
+
+ if (Flexo.client.isResized()) {
+ wScale = (Flexo.client.getStretchedDimensions().width / Flexo.client.getRealDimensions().width);
+ hScale = (Flexo.client.getStretchedDimensions().height / Flexo.client.getRealDimensions().height);
+ } else {
+ wScale = ((double)Flexo.client.getStretchedDimensions().width) / Flexo.fixedWidth;
+ hScale = ((double)Flexo.client.getStretchedDimensions().height) / Flexo.fixedHeight;
+ }
+
+ int xPadding = (int)rect.getWidth()/8;
+ int yPadding = (int)rect.getHeight()/8;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding;
+ clickRect.height = rect.height-yPadding;
+ clickRect.x = rect.x+xPadding;
+ clickRect.y = rect.y+yPadding;
+ int x = clickRect.x+r.nextInt(clickRect.width);
+ int y = clickRect.y+r.nextInt(clickRect.height);
+ double tScale = 1 + (Flexo.scale / 100);
+
+ if (Flexo.client.isResized()) {
+ return new net.runelite.api.Point( (int)(x * wScale * tScale), (int)(y * hScale * tScale));
+ } else {
+ return new net.runelite.api.Point( (int)(x * wScale), (int)(y * hScale));
+ }
+
+ }
+ //Fixed, not stretched
+ else if (!Flexo.client.isResized()) {
+ int fixedWidth = 765;
+ int widthDif = ClientUI.frame.getWidth();
+
+ if (ClientUI.pluginToolbar.isVisible()) {
+ widthDif -= ClientUI.pluginToolbar.getWidth();
+ }
+ if (ClientUI.pluginPanel!=null)
+ widthDif -= ClientUI.pluginPanel.getWidth();
+
+ widthDif -= fixedWidth;
+ int xPadding = (int)rect.getWidth()/8;
+ int yPadding = (int)rect.getHeight()/8;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding;
+ clickRect.height = rect.height-yPadding;
+ clickRect.x = rect.x+xPadding+(widthDif/2);
+ clickRect.y = rect.y+yPadding;
+ int x = clickRect.x+r.nextInt(clickRect.width);
+ int y = clickRect.y+r.nextInt(clickRect.height);
+ return new net.runelite.api.Point(x, y);
+ }
+ //Resizable, not stretched
+ else {
+ int xPadding = (int)rect.getWidth()/8;
+ int yPadding = (int)rect.getHeight()/8;
+ Random r = new Random();
+ Rectangle clickRect = new Rectangle();
+ clickRect.width = rect.width-xPadding;
+ clickRect.height = rect.height-yPadding;
+ clickRect.x = rect.x+xPadding;
+ clickRect.y = rect.y+yPadding;
+ int x = clickRect.x+r.nextInt(clickRect.width);
+ int y = clickRect.y+r.nextInt(clickRect.height);
+ return new Point(x, y);
+ }
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java
new file mode 100644
index 0000000000..7c3c9e1637
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/flexo/FlexoUtils.java
@@ -0,0 +1,16 @@
+package net.runelite.client.flexo;
+
+import net.runelite.api.widgets.WidgetItem;
+import net.runelite.client.plugins.flexo.FlexoOverlay;
+
+import java.awt.*;
+
+public class FlexoUtils {
+
+ public static Rectangle getInvItemClickArea(WidgetItem item) {
+ Rectangle clickArea = item.getCanvasBounds();
+ FlexoOverlay.clickArea = clickArea;
+ return clickArea;
+ }
+
+}
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 6759c7fa58..ea8908b824 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
@@ -107,6 +107,7 @@ public class ConfigPanel extends PluginPanel
private static final String PINNED_PLUGINS_CONFIG_KEY = "pinnedPlugins";
private static final String RUNELITE_PLUGIN = "RuneLite";
private static final String CHAT_COLOR_PLUGIN = "Chat Color";
+ public static boolean flexoConfigEnabled = false;
private final PluginManager pluginManager;
private final ConfigManager configManager;
@@ -195,6 +196,26 @@ public class ConfigPanel extends PluginPanel
{
final List pinnedPlugins = getPinnedPluginNames();
+ List externalPlugins = new ArrayList<>();
+ // populate pluginList with all external Plugins
+ pluginManager.getPlugins().stream()
+ .filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("external"))
+ .forEach(plugin ->
+ {
+ final PluginDescriptor descriptor = plugin.getClass().getAnnotation(PluginDescriptor.class);
+ final Config config = pluginManager.getPluginConfigProxy(plugin);
+ final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
+
+ final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor);
+ System.out.println("Started "+listItem.getName());
+ listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
+ externalPlugins.add(listItem);
+ });
+
+ externalPlugins.sort(Comparator.comparing(PluginListItem::getName));
+ for (PluginListItem plugin : externalPlugins)
+ pluginList.add(plugin);
+
List pvmPlugins = new ArrayList<>();
// populate pluginList with all PVM Plugins
pluginManager.getPlugins().stream()
@@ -236,7 +257,7 @@ public class ConfigPanel extends PluginPanel
pluginList.add(plugin);
List utilPlugins = new ArrayList<>();
- // populate pluginList with all PVP Plugins
+ // populate pluginList with all utility Plugins
pluginManager.getPlugins().stream()
.filter(plugin -> plugin.getClass().getAnnotation(PluginDescriptor.class).type().equals("utility"))
.forEach(plugin ->
@@ -246,9 +267,16 @@ public class ConfigPanel extends PluginPanel
final ConfigDescriptor configDescriptor = config == null ? null : configManager.getConfigDescriptor(config);
final PluginListItem listItem = new PluginListItem(this, configManager, plugin, descriptor, config, configDescriptor);
+ if (listItem.getName().contains("Flexo") && flexoConfigEnabled) {
+ System.out.println("Started "+listItem.getName());
+ listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
+ utilPlugins.add(listItem);
+ } else if (!listItem.getName().contains("Flexo")) {
System.out.println("Started "+listItem.getName());
listItem.setPinned(pinnedPlugins.contains(listItem.getName()));
utilPlugins.add(listItem);
+ }
+
});
utilPlugins.sort(Comparator.comparing(PluginListItem::getName));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java
new file mode 100644
index 0000000000..b24a585f2e
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoConfig.java
@@ -0,0 +1,180 @@
+/*
+ * 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.plugins.flexo;
+
+import net.runelite.client.config.Config;
+import net.runelite.client.config.ConfigGroup;
+import net.runelite.client.config.ConfigItem;
+
+import java.awt.*;
+
+@ConfigGroup("flexo")
+public interface FlexoConfig extends Config {
+
+ @ConfigItem(
+ position = 0,
+ keyName = "overlayEnabled",
+ name = "Overlay Enabled",
+ description = "Shows clicking area and points etc."
+ )
+ default boolean overlayEnabled() {
+ return true;
+ }
+
+ @ConfigItem(
+ position = 1,
+ keyName = "minDelayAmount",
+ name = "Min Delay",
+ description = "Minimum delay that is applied to every action at the end (ms)"
+ )
+ default int minDelayAmt() {
+ return 45;
+ }
+
+
+ @ConfigItem(
+ position = 2,
+ keyName = "reactionTime",
+ name = "Reaction Time",
+ description = "The base time between actions (ms)"
+ )
+ default int getReactionTimeVariation() {
+ return 80;
+ }
+
+ @ConfigItem(
+ position = 3,
+ keyName = "mouseDragSpeed",
+ name = "Mouse drag speed",
+ description = "The speed at which steps are executed. Keep at 49? cuz jagex mouse recorder?"
+ )
+ default int getMouseDragSpeed() {
+ return 49;
+ }
+
+
+ @ConfigItem(
+ position = 4,
+ keyName = "overshoots",
+ name = "Overshoots",
+ description = "Higher number = more overshoots"
+ )
+ default int getOvershoots() {
+ return 4;
+ }
+
+ @ConfigItem(
+ position = 5,
+ keyName = "variatingFlow",
+ name = "Flow - Variating",
+ description = ""
+ )
+ default boolean getVariatingFlow() {
+ return true;
+ }
+
+ @ConfigItem(
+ position = 6,
+ keyName = "slowStartupFlow",
+ name = "Flow - Slow startup",
+ description = ""
+ )
+ default boolean getSlowStartupFlow() {
+ return true;
+ }
+
+
+ @ConfigItem(
+ position = 7,
+ keyName = "slowStartup2Flow",
+ name = "Flow - Slow startup 2",
+ description = ""
+ )
+ default boolean getSlowStartup2Flow() {
+ return true;
+ }
+
+ @ConfigItem(
+ position = 8,
+ keyName = "jaggedFlow",
+ name = "Flow - Jagged",
+ description = ""
+ )
+ default boolean getJaggedFlow() {
+ return true;
+ }
+
+ @ConfigItem(
+ position = 9,
+ keyName = "interruptedFlow",
+ name = "Flow - Interrupted",
+ description = ""
+ )
+ default boolean getInterruptedFlow() {
+ return false;
+ }
+
+
+ @ConfigItem(
+ position = 10,
+ keyName = "interruptedFlow2",
+ name = "Flow - Interrupted 2",
+ description = ""
+ )
+ default boolean getInterruptedFlow2() {
+ return false;
+ }
+
+ @ConfigItem(
+ position = 11,
+ keyName = "stoppingFlow",
+ name = "Flow - Stopping",
+ description = ""
+ )
+ default boolean getStoppingFlow() {
+ return false;
+ }
+
+ @ConfigItem(
+ position = 12,
+ keyName = "deviationSlopeDivider",
+ name = "Deviation slope divider",
+ description = ""
+ )
+ default int getDeviationSlope() {
+ return 10;
+ }
+
+
+ @ConfigItem(
+ position = 13,
+ keyName = "noisinessDivider",
+ name = "Noisiness divider",
+ description = ""
+ )
+ default String getNoisinessDivider() {
+ return "2.0D";
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java
new file mode 100644
index 0000000000..99072b88bf
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoOverlay.java
@@ -0,0 +1,42 @@
+package net.runelite.client.plugins.flexo;
+
+import net.runelite.api.Client;
+import net.runelite.client.ui.overlay.Overlay;
+import net.runelite.client.ui.overlay.OverlayLayer;
+import net.runelite.client.ui.overlay.OverlayPosition;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import java.awt.*;
+import java.awt.geom.Ellipse2D;
+
+public class FlexoOverlay extends Overlay {
+
+ public static Rectangle clickArea;
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private FlexoPlugin plugin;
+
+ @Inject
+ private FlexoConfig config;
+
+ @Inject
+ public FlexoOverlay(@Nullable Client client, FlexoPlugin plugin, FlexoConfig config) {
+ setPosition(OverlayPosition.DYNAMIC);
+ setLayer(OverlayLayer.ABOVE_WIDGETS);
+ this.client = client;
+ this.plugin = plugin;
+ this.config = config;
+ }
+
+
+ @Override
+ public Dimension render(Graphics2D graphics) {
+ if (clickArea!=null)
+ graphics.draw(clickArea);
+ return null;
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java
new file mode 100644
index 0000000000..7cd7b961bc
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/flexo/FlexoPlugin.java
@@ -0,0 +1,127 @@
+package net.runelite.client.plugins.flexo;
+
+import com.github.joonasvali.naturalmouse.api.MouseMotionFactory;
+import com.github.joonasvali.naturalmouse.support.DefaultNoiseProvider;
+import com.github.joonasvali.naturalmouse.support.DefaultOvershootManager;
+import com.github.joonasvali.naturalmouse.support.DefaultSpeedManager;
+import com.github.joonasvali.naturalmouse.support.Flow;
+import com.github.joonasvali.naturalmouse.support.SinusoidalDeviationProvider;
+import com.github.joonasvali.naturalmouse.util.FlowTemplates;
+import com.google.inject.Provides;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.Client;
+import net.runelite.api.events.ConfigChanged;
+import net.runelite.api.events.GameTick;
+import net.runelite.client.config.ConfigManager;
+import net.runelite.client.eventbus.Subscribe;
+import net.runelite.client.flexo.Flexo;
+import net.runelite.client.flexo.FlexoUtils;
+import net.runelite.client.plugins.Plugin;
+import net.runelite.client.plugins.PluginDescriptor;
+import net.runelite.client.plugins.stretchedmode.StretchedModeConfig;
+import net.runelite.client.ui.overlay.OverlayManager;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+
+@PluginDescriptor(
+ name = "Flexo Config",
+ description = "Customizes Flexo, the MouseInput Assistant ;)",
+ tags = {"flexo", "null"},
+ type = "utility"
+)
+@Slf4j
+public class FlexoPlugin extends Plugin {
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private ConfigManager configManager;
+
+ @Inject
+ private OverlayManager overlayManager;
+
+ @Inject
+ private FlexoOverlay overlay;
+
+ @Provides
+ FlexoConfig getConfig(ConfigManager configManager) {
+ return configManager.getConfig(FlexoConfig.class);
+ }
+
+ @Subscribe
+ private void onConfigChanged(ConfigChanged event) {
+ if (event.getKey().compareTo("overlayEnabled")==0) {
+ if (getConfig(configManager).overlayEnabled()) {
+ overlayManager.add(overlay);
+ } else {
+ overlayManager.remove(overlay);
+ }
+ }
+ updateMouseMotionFactory();
+ }
+
+ @Subscribe
+ public void onGameTick(GameTick event) {
+ Flexo.isStretched = client.isStretchedEnabled();
+ Flexo.scale = configManager.getConfig(StretchedModeConfig.class).scalingFactor();
+ }
+
+ private void updateMouseMotionFactory() {
+ Flexo.minDelay = getConfig(configManager).minDelayAmt();
+ MouseMotionFactory factory = new MouseMotionFactory();
+ //TODO:Add Options for various flows to allow more personalization
+ List flows = new ArrayList<>();
+
+ //Always add random
+ flows.add(new Flow(FlowTemplates.random()));
+
+ if (getConfig(configManager).getVariatingFlow())
+ flows.add(new Flow(FlowTemplates.variatingFlow()));
+
+ if (getConfig(configManager).getSlowStartupFlow())
+ flows.add(new Flow(FlowTemplates.slowStartupFlow()));
+
+ if (getConfig(configManager).getSlowStartup2Flow())
+ flows.add(new Flow(FlowTemplates.slowStartup2Flow()));
+
+ if (getConfig(configManager).getJaggedFlow())
+ flows.add(new Flow(FlowTemplates.jaggedFlow()));
+
+ if (getConfig(configManager).getInterruptedFlow())
+ flows.add(new Flow(FlowTemplates.interruptedFlow()));
+
+ if (getConfig(configManager).getInterruptedFlow2())
+ flows.add(new Flow(FlowTemplates.interruptedFlow2()));
+
+ if (getConfig(configManager).getStoppingFlow())
+ flows.add(new Flow(FlowTemplates.stoppingFlow()));
+
+ DefaultSpeedManager manager = new DefaultSpeedManager(flows);
+ //TODO:Add options for custom Deviation Provider and Noise Provider
+ factory.setDeviationProvider(new SinusoidalDeviationProvider(getConfig(configManager).getDeviationSlope()));
+ factory.setNoiseProvider(new DefaultNoiseProvider(Double.valueOf(getConfig(configManager).getNoisinessDivider())));
+ factory.getNature().setReactionTimeVariationMs(getConfig(configManager).getReactionTimeVariation());
+ manager.setMouseMovementBaseTimeMs(getConfig(configManager).getMouseDragSpeed());
+
+ DefaultOvershootManager overshootManager = (DefaultOvershootManager) factory.getOvershootManager();
+ overshootManager.setOvershoots(getConfig(configManager).getOvershoots());
+
+ factory.setSpeedManager(manager);
+ Flexo.currentMouseMotionFactory = factory;
+ }
+
+ @Override
+ protected void startUp() throws Exception {
+ Flexo.isStretched = client.isStretchedEnabled();
+ overlayManager.add(overlay);
+ updateMouseMotionFactory();
+ }
+
+ @Override
+ protected void shutDown() throws Exception {
+ overlayManager.remove(overlay);
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java
index 2287b5a0ef..0b910beea5 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterConfig.java
@@ -24,6 +24,17 @@ public interface PluginSorterConfig extends Config {
return pluginsHidden;
}
+ @ConfigItem(
+ position = 1,
+ keyName = "externalColor",
+ name = "External color",
+ description = "Configure the color of external plugins"
+ )
+ default Color externalColor()
+ {
+ return Color.MAGENTA;
+ }
+
@ConfigItem(
position = 1,
keyName = "pvmColor",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java
index ca7f54c836..99c4e3e02a 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/pluginsorter/PluginSorterPlugin.java
@@ -76,7 +76,9 @@ public class PluginSorterPlugin extends Plugin {
for (PluginListItem pli : ConfigPanel.pluginList) {
if (pli.getPlugin()!=null) {
if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type()!=null)
- if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM"))
+ if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("external"))
+ pli.nameLabel.setForeground(config.pvmColor());
+ else if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM"))
pli.nameLabel.setForeground(config.pvmColor());
else if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVP"))
pli.nameLabel.setForeground(config.pvpColor());
@@ -93,6 +95,11 @@ public class PluginSorterPlugin extends Plugin {
while (iter.hasNext()) {
PluginListItem pli = iter.next();
if (pli.getPlugin() != null) {
+ if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals(""))
+ if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("external")) {
+ iter.remove();
+ removedPlugins.add(pli);
+ }
if (!pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals(""))
if (pli.getPlugin().getClass().getAnnotation(PluginDescriptor.class).type().equals("PVM")) {
iter.remove();
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java
index 9c2fd7ea34..b1c93b09bb 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java
@@ -71,6 +71,8 @@ class SmeltingOverlay extends Overlay
public Dimension render(Graphics2D graphics)
{
SmeltingSession session = plugin.getSession();
+
+ if (session!=null)
if (session.getLastItemSmelted() == null)
{
return null;
@@ -78,6 +80,7 @@ class SmeltingOverlay extends Overlay
panelComponent.getChildren().clear();
+ if (session!=null)
if (isSmelting() || Duration.between(session.getLastItemSmelted(), Instant.now()).getSeconds() < SMELT_TIMEOUT)
{
panelComponent.getChildren().add(TitleComponent.builder()
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java
index 50c72491c3..9534129ad1 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java
@@ -114,6 +114,7 @@ public class SmeltingPlugin extends Plugin
@Subscribe
public void onGameTick(GameTick event)
{
+ if (session!=null)
if (session.getLastItemSmelted() != null)
{
final Duration statTimeout = Duration.ofMinutes(config.statTimeout());
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 4722b0027e..4cb09686b2 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
@@ -121,10 +121,10 @@ public class ClientUI
private boolean withTitleBar;
private BufferedImage sidebarOpenIcon;
private BufferedImage sidebarClosedIcon;
- private ContainableFrame frame;
+ public static ContainableFrame frame;
private JPanel navContainer;
- private PluginPanel pluginPanel;
- private ClientPluginToolbar pluginToolbar;
+ public static PluginPanel pluginPanel;
+ public static ClientPluginToolbar pluginToolbar;
private ClientTitleToolbar titleToolbar;
private JButton currentButton;
private NavigationButton currentNavButton;