diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java new file mode 100644 index 0000000000..22da14a8ff --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016-2017, Abel Briggs + * 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.api; + +// Note: This class is not complete: these animations were manually gathered +// through getAnimation(). Please add animations as you happen to use them. +public final class AnimationID +{ + public static final int IDLE = -1; + public static final int WOODCUTTING_BRONZE = 879; + public static final int WOODCUTTING_IRON = 877; + public static final int WOODCUTTING_STEEL = 875; + public static final int WOODCUTTING_BLACK = 873; + public static final int WOODCUTTING_MITHRIL = 871; + public static final int WOODCUTTING_ADAMANT = 869; + public static final int WOODCUTTING_RUNE = 867; + public static final int WOODCUTTING_DRAGON = 2846; + public static final int WOODCUTTING_INFERNAL = 0; // unknown - placeholder + public static final int CONSUMING = 829; // consuming consumables + public static final int FIREMAKING = 733; + public static final int COOKING_FIRE = 897; + public static final int COOKING_RANGE = 896; + public static final int FLETCHING_BOW_CUTTING = 1248; + public static final int FLETCHING_BOW_STRINGING = 6684; // ids are based on bow - incomplete! + public static final int GEM_CUTTING_OPAL = 890; + public static final int GEM_CUTTING_JADE = 891; + public static final int GEM_CUTTING_REDTOPAZ = 892; + public static final int GEM_CUTTING_SAPPHIRE = 888; + public static final int GEM_CUTTING_EMERALD = 889; + public static final int GEM_CUTTING_RUBY = 887; + public static final int GEM_CUTTING_DIAMOND = 886; + public static final int CRAFTING_LEATHER = 1249; // unknown if the anim is the same for all leathers + public static final int SMITHING_SMELTING = 899; + public static final int SMITHING_CANNONBALL = 827; //cball smithing uses this and SMITHING_SMELTING + public static final int SMITHING_ANVIL = 898; + public static final int FISHING_NET = 621; + public static final int FISHING_POLE_INITIAL = 622; //initial swing of pole + public static final int FISHING_POLE_CAST = 623; // pole is in the water + public static final int FISHING_CAGE = 619; + public static final int FISHING_HARPOON = 618; + public static final int MINING_BRONZE_PICKAXE = 625; + public static final int MINING_IRON_PICKAXE = 626; + public static final int MINING_STEEL_PICKAXE = 627; + public static final int MINING_BLACK_PICKAXE = 3873; + public static final int MINING_MITHRIL_PICKAXE = 629; + public static final int MINING_ADAMANT_PICKAXE = 628; + public static final int MINING_RUNE_PICKAXE = 624; + public static final int MINING_DRAGON_PICKAXE = 7139; + public static final int MINING_INFERNAL_PICKAXE = 0; //placeholder, unknown + public static final int MINING_MOTHERLODE_BRONZE = 6753; + public static final int MINING_MOTHERLODE_IRON = 6754; + public static final int MINING_MOTHERLODE_STEEL = 6755; + public static final int MINING_MOTHERLODE_BLACK = 3866; + public static final int MINING_MOTHERLODE_MITHRIL = 6757; + public static final int MINING_MOTHERLODE_ADAMANT = 6756; + public static final int MINING_MOTHERLODE_RUNE = 6752; + public static final int MINING_MOTHERLODE_DRAGON = 6758; + public static final int MINING_MOTHERLODE_INFERNAL = 0; // placeholder, unknown + public static final int HERBLORE_POTIONMAKING = 363; //used for both herb and secondary + public static final int MAGIC_CHARGING_ORBS = 726; +} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 43bbfe64b1..af61e85739 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -61,7 +61,7 @@ public class RuneLite private PluginManager pluginManager; private OverlayRenderer renderer; private EventBus eventBus = new EventBus(this::eventExceptionHandler); - private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4); static { diff --git a/runelite-client/src/main/java/net/runelite/client/events/AnimationChanged.java b/runelite-client/src/main/java/net/runelite/client/events/AnimationChanged.java new file mode 100644 index 0000000000..5d61071267 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/events/AnimationChanged.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016-2017, Abel Briggs + * 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.events; + +public class AnimationChanged +{ + private Object object; + + public Object getObject() + { + return object; + } + + public void setObject(Object object) + { + this.object = object; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 23d3df3e89..c8d6babb15 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -35,6 +35,7 @@ import net.runelite.client.plugins.devtools.DevTools; import net.runelite.client.plugins.fpsinfo.FPS; import net.runelite.client.plugins.gronditems.GroundItems; import net.runelite.client.plugins.hiscore.Hiscore; +import net.runelite.client.plugins.idlenotifier.IdleNotifier; import net.runelite.client.plugins.opponentinfo.OpponentInfo; import net.runelite.client.plugins.xtea.Xtea; import org.slf4j.Logger; @@ -60,6 +61,7 @@ public class PluginManager load(new Hiscore()); load(new BossTimers()); load(new Xtea()); + load(new IdleNotifier()); if (RuneLite.getOptions().has("developer-mode")) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifier.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifier.java new file mode 100644 index 0000000000..967f8b322a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifier.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016-2017, Abel Briggs + * 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.idlenotifier; + +import com.google.common.eventbus.Subscribe; +import java.awt.Toolkit; +import java.awt.TrayIcon; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import static net.runelite.api.AnimationID.*; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.RuneLite; +import net.runelite.client.events.AnimationChanged; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.ui.overlay.Overlay; + +public class IdleNotifier extends Plugin +{ + private static final String OPERATING_SYSTEM = System.getProperty("os.name"); + private static final int CHECK_INTERVAL = 2; + private static final Duration WAIT_DURATION = Duration.ofMillis(2500L); + + private final Client client = RuneLite.getClient(); + private final TrayIcon trayIcon = RuneLite.getTrayIcon(); + + private Instant lastAnimating; + private boolean notifyIdle = false; + + @Override + public Overlay getOverlay() + { + return null; + } + + public IdleNotifier() + { + ScheduledExecutorService executor = RuneLite.getRunelite().getExecutor(); + executor.scheduleAtFixedRate(this::checkIdle, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.SECONDS); + } + + @Subscribe + public void onAnimationChanged(AnimationChanged event) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + int animation = client.getLocalPlayer().getAnimation(); + + switch (animation) + { + case WOODCUTTING_BRONZE: + case WOODCUTTING_IRON: + case WOODCUTTING_STEEL: + case WOODCUTTING_BLACK: + case WOODCUTTING_MITHRIL: + case WOODCUTTING_ADAMANT: + case WOODCUTTING_RUNE: + case WOODCUTTING_DRAGON: + case COOKING_FIRE: + case COOKING_RANGE: + case GEM_CUTTING_OPAL: + case GEM_CUTTING_JADE: + case GEM_CUTTING_REDTOPAZ: + case GEM_CUTTING_SAPPHIRE: + case GEM_CUTTING_EMERALD: + case GEM_CUTTING_RUBY: + case GEM_CUTTING_DIAMOND: + case SMITHING_ANVIL: + case SMITHING_SMELTING: + case FISHING_NET: + case FISHING_HARPOON: + case FISHING_CAGE: + case FISHING_POLE_CAST: + case MINING_BRONZE_PICKAXE: + case MINING_IRON_PICKAXE: + case MINING_STEEL_PICKAXE: + case MINING_BLACK_PICKAXE: + case MINING_MITHRIL_PICKAXE: + case MINING_ADAMANT_PICKAXE: + case MINING_RUNE_PICKAXE: + case MINING_DRAGON_PICKAXE: + case MINING_MOTHERLODE_BRONZE: + case MINING_MOTHERLODE_IRON: + case MINING_MOTHERLODE_STEEL: + case MINING_MOTHERLODE_BLACK: + case MINING_MOTHERLODE_MITHRIL: + case MINING_MOTHERLODE_ADAMANT: + case MINING_MOTHERLODE_RUNE: + case MINING_MOTHERLODE_DRAGON: + case HERBLORE_POTIONMAKING: + case MAGIC_CHARGING_ORBS: + notifyIdle = true; + lastAnimating = Instant.now(); + break; + } + } + + private void checkIdle() + { + if (notifyIdle && client.getLocalPlayer().getAnimation() == IDLE + && Instant.now().compareTo(lastAnimating.plus(WAIT_DURATION)) >= 0) + { + trayIcon.displayMessage("RuneLite", "You are now idle.", TrayIcon.MessageType.NONE); + + if (OPERATING_SYSTEM.startsWith("Windows")) + { + Toolkit.getDefaultToolkit().beep(); + } + + notifyIdle = false; + } + } + +} diff --git a/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java b/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java index 217682fc3b..9670c1a539 100644 --- a/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/inject/callbacks/Hooks.java @@ -27,6 +27,7 @@ package net.runelite.inject.callbacks; import net.runelite.client.RuneLite; import net.runelite.client.events.ExperienceChanged; import net.runelite.client.events.MapRegionChanged; +import net.runelite.client.events.AnimationChanged; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +61,13 @@ public class Hooks runelite.getEventBus().post(regionChanged); break; } + case "animationChanged": + { + AnimationChanged animationChange = new AnimationChanged(); + animationChange.setObject(object); + runelite.getEventBus().post(animationChange); + break; + } default: logger.warn("Unknown event {} triggered on {}", name, object); return;