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; 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.common.eventbus.EventBus;
import com.google.inject.Injector; import com.google.inject.Injector;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.ChatMessageType; import net.runelite.api.ChatMessageType;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameObject;
import net.runelite.api.MainBufferProvider; import net.runelite.api.MainBufferProvider;
import net.runelite.api.MenuAction; import net.runelite.api.MenuAction;
import net.runelite.api.MessageNode; import net.runelite.api.MessageNode;
import net.runelite.api.PacketBuffer; import net.runelite.api.PacketBuffer;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.Projectile; import net.runelite.api.Projectile;
import net.runelite.api.Skill;
import net.runelite.api.Tile;
import net.runelite.client.RuneLite; import net.runelite.client.RuneLite;
import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.events.*;
import net.runelite.client.game.DeathChecker; import net.runelite.client.game.DeathChecker;
import net.runelite.client.task.Scheduler; import net.runelite.client.task.Scheduler;
import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.OverlayRenderer;
@@ -57,7 +58,7 @@ public class Hooks
private static final Injector injector = RuneLite.getInjector(); private static final Injector injector = RuneLite.getInjector();
private static final Client client = injector.getInstance(Client.class); 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 Scheduler scheduler = injector.getInstance(Scheduler.class);
private static final InfoBoxManager infoBoxManager = injector.getInstance(InfoBoxManager.class); private static final InfoBoxManager infoBoxManager = injector.getInstance(InfoBoxManager.class);
private static final ChatMessageManager chatMessageManager = injector.getInstance(ChatMessageManager.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) 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. /* 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 lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.GameState; import net.runelite.api.GameState;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.task.Schedule; 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.client.config.ConfigManager;
import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.MenuOptionClicked;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;

View File

@@ -41,6 +41,12 @@
<groupId>net.runelite.rs</groupId> <groupId>net.runelite.rs</groupId>
<artifactId>api</artifactId> <artifactId>api</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency> </dependency>
</dependencies> </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.Player;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.SpritePixels; import net.runelite.api.SpritePixels;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow; 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.RSActor;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSCombatInfo1; import net.runelite.rs.api.RSCombatInfo1;
@@ -173,4 +176,13 @@ public abstract class RSActorMixin implements RSActor
{ {
return Perspective.worldToMiniMap(client, getX(), getY()); 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.Prayer;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.api.Varbits; import net.runelite.api.Varbits;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo; 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.RSClient;
import net.runelite.rs.api.RSIndexedSprite; import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSWidget; import net.runelite.rs.api.RSWidget;
@@ -48,6 +58,9 @@ import net.runelite.rs.api.RSWidget;
@Mixin(RSClient.class) @Mixin(RSClient.class)
public abstract class RSClientMixin implements RSClient public abstract class RSClientMixin implements RSClient
{ {
@Shadow("clientInstance")
private static RSClient client;
@Inject @Inject
@Override @Override
public List<Player> getPlayers() public List<Player> getPlayers()
@@ -324,4 +337,73 @@ public abstract class RSClientMixin implements RSClient
{ {
setRSModIcons((RSIndexedSprite[]) modIcons); 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; package net.runelite.mixins;
import net.runelite.api.GameObject;
import net.runelite.api.Perspective; import net.runelite.api.Perspective;
import net.runelite.api.Point; import net.runelite.api.Point;
import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow; 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.RSClient;
import net.runelite.rs.api.RSTile; import net.runelite.rs.api.RSTile;
@@ -60,4 +64,21 @@ public abstract class RSTileMixin implements RSTile
Point regionLocation = getRegionLocation(); Point regionLocation = getRegionLocation();
return Perspective.regionToLocal(client, regionLocation); 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; package net.runelite.mapping;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -32,8 +33,9 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target( @Target(
{ {
ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR ElementType.METHOD, ElementType.CONSTRUCTOR
}) })
@Documented
public @interface Hook public @interface Hook
{ {
String value(); String value();