Added implementation for an idle notifier plugin, animation hook, and thread pool (#23)

Added implementation for an idle notifier plugin and animation hook
This commit is contained in:
Abel Briggs
2017-04-16 15:06:07 -05:00
committed by Adam
parent 4d0e6e8247
commit b80d6b6ca5
6 changed files with 274 additions and 1 deletions

View File

@@ -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;
}

View File

@@ -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
{

View File

@@ -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;
}
}

View File

@@ -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"))
{

View File

@@ -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;
}
}
}

View File

@@ -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;