Move field hooks to mixins

This commit is contained in:
Adam
2018-01-08 19:17:29 -05:00
parent 16d08f62b8
commit 31c73e4d61
10 changed files with 209 additions and 111 deletions

View File

@@ -24,27 +24,28 @@
*/
package net.runelite.client.callback;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ProjectileMoved;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.api.events.SetMessage;
import com.google.common.eventbus.EventBus;
import com.google.inject.Injector;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.MainBufferProvider;
import net.runelite.api.MenuAction;
import net.runelite.api.MessageNode;
import net.runelite.api.PacketBuffer;
import net.runelite.api.Point;
import net.runelite.api.Projectile;
import net.runelite.api.Skill;
import net.runelite.api.Tile;
import net.runelite.client.RuneLite;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.events.*;
import net.runelite.client.game.DeathChecker;
import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.overlay.OverlayRenderer;
@@ -57,7 +58,7 @@ public class Hooks
private static final Injector injector = RuneLite.getInjector();
private static final Client client = injector.getInstance(Client.class);
private static final EventBus eventBus = injector.getInstance(EventBus.class);
public static final EventBus eventBus = injector.getInstance(EventBus.class);
private static final Scheduler scheduler = injector.getInstance(Scheduler.class);
private static final InfoBoxManager infoBoxManager = injector.getInstance(InfoBoxManager.class);
private static final ChatMessageManager chatMessageManager = injector.getInstance(ChatMessageManager.class);
@@ -111,109 +112,6 @@ public class Hooks
}
}
/**
*
* @param name Hook-name that was used in the @Hook-annotation.
* @param idx The index if hooked to an array. -1 if not hooked to an
* array.
* @param object The object where the hook was placed in, NOT the
* variable that was hooked to.
*/
public static void callHook(String name, int idx, Object object)
{
switch (name)
{
case "experienceChanged":
{
ExperienceChanged experienceChanged = new ExperienceChanged();
Skill[] possibleSkills = Skill.values();
// We subtract one here because 'Overall' isn't considered a skill that's updated.
if (idx < possibleSkills.length - 1)
{
Skill updatedSkill = possibleSkills[idx];
experienceChanged.setSkill(updatedSkill);
eventBus.post(experienceChanged);
}
break;
}
case "mapRegionsChanged":
{
MapRegionChanged regionChanged = new MapRegionChanged();
regionChanged.setIndex(idx);
eventBus.post(regionChanged);
break;
}
case "playerMenuOptionsChanged":
{
PlayerMenuOptionsChanged optionsChanged = new PlayerMenuOptionsChanged();
optionsChanged.setIndex(idx);
eventBus.post(optionsChanged);
break;
}
case "animationChanged":
{
Actor actor = (Actor) object;
AnimationChanged animationChange = new AnimationChanged();
animationChange.setActor(actor);
eventBus.post(animationChange);
break;
}
case "gameStateChanged":
{
GameStateChanged gameStateChange = new GameStateChanged();
gameStateChange.setGameState(client.getGameState());
eventBus.post(gameStateChange);
break;
}
case "varbitChanged":
{
VarbitChanged varbitChanged = new VarbitChanged();
eventBus.post(varbitChanged);
break;
}
case "clanMembersChanged":
{
ClanMembersChanged clanMembersChanged = new ClanMembersChanged();
eventBus.post(clanMembersChanged);
break;
}
case "resizeChanged":
{
//maybe couple with varbitChanged. resizeable may not be a varbit but it would fit with the other client settings.
ResizeableChanged resizeableChanged = new ResizeableChanged();
resizeableChanged.setResized(client.isResized());
eventBus.post(resizeableChanged);
break;
}
case "gameObjectsChanged":
if (idx != -1) // this happens from the field assignment
{
// GameObject that was changed.
GameObject go = ((Tile) object).getGameObjects()[idx];
if (go != null)
{
GameObjectsChanged gameObjectsChanged = new GameObjectsChanged();
gameObjectsChanged.setGameObject(go);
eventBus.post(gameObjectsChanged);
}
}
break;
default:
log.warn("Unknown event {} triggered on {}", name, object);
return;
}
if (object != null)
{
log.trace("Event {} (idx {}) triggered on {}", name, idx, object);
}
else
{
log.trace("Event {} (idx {}) triggered", name, idx);
}
}
public static void menuActionHook(int actionParam, int widgetId, int menuAction, int id, String menuOption, String menuTarget, int var6, int var7)
{
/* Along the way, the RuneScape client may change a menuAction by incrementing it with 2000.

View File

@@ -37,10 +37,10 @@ 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.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.task.Schedule;

View File

@@ -43,6 +43,7 @@ import net.runelite.api.ItemID;
import net.runelite.client.config.ConfigManager;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;

View File

@@ -41,6 +41,12 @@
<groupId>net.runelite.rs</groupId>
<artifactId>api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* 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.mixins;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface FieldHook
{
String value();
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* 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.callback;
import com.google.common.eventbus.EventBus;
/**
* Dummy class to make the mixins to compile.
*
* @author Adam
*/
public class Hooks
{
public static EventBus eventBus;
}

View File

@@ -34,9 +34,12 @@ import static net.runelite.api.Perspective.LOCAL_COORD_BITS;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.SpritePixels;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.api.events.AnimationChanged;
import static net.runelite.client.callback.Hooks.eventBus;
import net.runelite.rs.api.RSActor;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSCombatInfo1;
@@ -173,4 +176,13 @@ public abstract class RSActorMixin implements RSActor
{
return Perspective.worldToMiniMap(client, getX(), getY());
}
@FieldHook("animation")
@Inject
public void animationChanged(int idx)
{
AnimationChanged animationChange = new AnimationChanged();
animationChange.setActor(this);
eventBus.post(animationChange);
}
}

View File

@@ -37,10 +37,20 @@ import net.runelite.api.Point;
import net.runelite.api.Prayer;
import net.runelite.api.Skill;
import net.runelite.api.Varbits;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.events.ClanMembersChanged;
import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.MapRegionChanged;
import net.runelite.api.events.PlayerMenuOptionsChanged;
import net.runelite.api.events.ResizeableChanged;
import net.runelite.api.events.VarbitChanged;
import static net.runelite.client.callback.Hooks.eventBus;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSWidget;
@@ -48,6 +58,9 @@ import net.runelite.rs.api.RSWidget;
@Mixin(RSClient.class)
public abstract class RSClientMixin implements RSClient
{
@Shadow("clientInstance")
private static RSClient client;
@Inject
@Override
public List<Player> getPlayers()
@@ -324,4 +337,73 @@ public abstract class RSClientMixin implements RSClient
{
setRSModIcons((RSIndexedSprite[]) modIcons);
}
@FieldHook("skillExperiences")
@Inject
public static void experiencedChanged(int idx)
{
ExperienceChanged experienceChanged = new ExperienceChanged();
Skill[] possibleSkills = Skill.values();
// We subtract one here because 'Overall' isn't considered a skill that's updated.
if (idx < possibleSkills.length - 1)
{
Skill updatedSkill = possibleSkills[idx];
experienceChanged.setSkill(updatedSkill);
eventBus.post(experienceChanged);
}
}
@FieldHook("mapRegions")
@Inject
public static void mapRegionsChanged(int idx)
{
MapRegionChanged regionChanged = new MapRegionChanged();
regionChanged.setIndex(idx);
eventBus.post(regionChanged);
}
@FieldHook("playerOptions")
@Inject
public static void playerOptionsChanged(int idx)
{
PlayerMenuOptionsChanged optionsChanged = new PlayerMenuOptionsChanged();
optionsChanged.setIndex(idx);
eventBus.post(optionsChanged);
}
@FieldHook("gameState")
@Inject
public static void gameStateChanged(int idx)
{
GameStateChanged gameStateChange = new GameStateChanged();
gameStateChange.setGameState(client.getGameState());
eventBus.post(gameStateChange);
}
@FieldHook("settings")
@Inject
public static void settingsChanged(int idx)
{
VarbitChanged varbitChanged = new VarbitChanged();
eventBus.post(varbitChanged);
}
@FieldHook("clanMembers")
@Inject
public static void clanMembersChanged(int idx)
{
ClanMembersChanged clanMembersChanged = new ClanMembersChanged();
eventBus.post(clanMembersChanged);
}
@FieldHook("isResized")
@Inject
public static void resizeChanged(int idx)
{
//maybe couple with varbitChanged. resizeable may not be a varbit but it would fit with the other client settings.
ResizeableChanged resizeableChanged = new ResizeableChanged();
resizeableChanged.setResized(client.isResized());
eventBus.post(resizeableChanged);
}
}

View File

@@ -24,11 +24,15 @@
*/
package net.runelite.mixins;
import net.runelite.api.GameObject;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.api.events.GameObjectsChanged;
import static net.runelite.client.callback.Hooks.eventBus;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSTile;
@@ -60,4 +64,21 @@ public abstract class RSTileMixin implements RSTile
Point regionLocation = getRegionLocation();
return Perspective.regionToLocal(client, regionLocation);
}
@FieldHook("objects")
@Inject
public void animationChanged(int idx)
{
if (idx != -1) // this happens from the field assignment
{
// GameObject that was changed.
GameObject go = getGameObjects()[idx];
if (go != null)
{
GameObjectsChanged gameObjectsChanged = new GameObjectsChanged();
gameObjectsChanged.setGameObject(go);
eventBus.post(gameObjectsChanged);
}
}
}
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.mapping;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -32,8 +33,9 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(
{
ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR
ElementType.METHOD, ElementType.CONSTRUCTOR
})
@Documented
public @interface Hook
{
String value();