Skip to content

Commit a3c9fa5

Browse files
committed
use reflection hacks to dodge bugs with inventory event
argh, spigot/java
1 parent 5a19a30 commit a3c9fa5

3 files changed

Lines changed: 31 additions & 21 deletions

File tree

src/main/java/org/mcmonkey/sentinel/SentinelEventHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.bukkit.event.player.*;
2020
import org.bukkit.inventory.ItemStack;
2121
import org.bukkit.projectiles.ProjectileSource;
22+
import org.mcmonkey.sentinel.utilities.SentinelNMSHelper;
2223
import org.mcmonkey.sentinel.utilities.VelocityTracker;
2324

2425
import java.util.ArrayList;
@@ -419,7 +420,7 @@ public void onPlayerMovesInRange(PlayerMoveEvent event) {
419420
*/
420421
@EventHandler
421422
public void onInvClose(InventoryCloseEvent event) {
422-
String invTitle = SentinelUtilities.getInventoryTitle(event);
423+
String invTitle = SentinelNMSHelper.getInventoryTitle(event);
423424
if (invTitle.startsWith(InvPrefix)) {
424425
int id = Integer.parseInt(invTitle.substring(InvPrefix.length()));
425426
NPC npc = CitizensAPI.getNPCRegistry().getById(id);

src/main/java/org/mcmonkey/sentinel/SentinelUtilities.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44
import net.citizensnpcs.api.ai.EntityTarget;
55
import net.citizensnpcs.api.npc.NPC;
66
import org.bukkit.*;
7-
import org.bukkit.block.Block;
8-
import org.bukkit.enchantments.Enchantment;
97
import org.bukkit.entity.Entity;
108
import org.bukkit.entity.LivingEntity;
119
import org.bukkit.entity.Player;
12-
import org.bukkit.event.inventory.InventoryCloseEvent;
1310
import org.bukkit.inventory.EntityEquipment;
1411
import org.bukkit.inventory.ItemStack;
1512
import org.bukkit.potion.PotionEffectType;
@@ -53,23 +50,6 @@ public static int getMaxWorldHeight(World world) {
5350
return world.getMaxHeight();
5451
}
5552

56-
/**
57-
* Gets the title of an inventory in an InventoryCloseEvent (compensates for code change between Spigot versions).
58-
*/
59-
public static String getInventoryTitle(InventoryCloseEvent event) {
60-
if (SentinelVersionCompat.v1_10) {
61-
return event.getView().getTitle();
62-
}
63-
try {
64-
Object inventory = event.getInventory();
65-
return (String) inventory.getClass().getMethod("getTitle").invoke(inventory);
66-
}
67-
catch (Exception e) {
68-
e.printStackTrace();
69-
}
70-
return null;
71-
}
72-
7353
/**
7454
* Gets the velocity for an entity. Uses a special tracker for players (since velocity doesn't network properly).
7555
*/

src/main/java/org/mcmonkey/sentinel/utilities/SentinelNMSHelper.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.bukkit.Bukkit;
55
import org.bukkit.entity.Enderman;
66
import org.bukkit.entity.IronGolem;
7+
import org.bukkit.event.inventory.InventoryEvent;
78

89
import java.lang.invoke.MethodHandle;
910
import java.lang.reflect.Field;
@@ -19,8 +20,14 @@ public class SentinelNMSHelper {
1920

2021
private static boolean nmsWorks = true, endermanValid = false;
2122

23+
public static MethodHandle INVENTORYCLOSEEVENT_GETVIEW, INVENTORYVIEW_GETTITLE;
24+
2225
public static void init() {
2326
try {
27+
if (SentinelVersionCompat.v1_10) {
28+
INVENTORYCLOSEEVENT_GETVIEW = NMS.getMethodHandle(InventoryEvent.class, "getView", true);
29+
INVENTORYVIEW_GETTITLE = NMS.getMethodHandle(INVENTORYCLOSEEVENT_GETVIEW.type().returnType(), "getTitle", true);
30+
}
2431
if (!SentinelVersionCompat.v1_12) {
2532
nmsWorks = false;
2633
return;
@@ -133,4 +140,26 @@ public static void setEndermanAngry(Enderman entity, boolean angry) {
133140
endermanValid = false;
134141
}
135142
}
143+
144+
145+
/**
146+
* Gets the title of an inventory in an InventoryEvent (compensates for code change between Spigot versions).
147+
*/
148+
public static String getInventoryTitle(InventoryEvent event) {
149+
try {
150+
if (SentinelVersionCompat.v1_10) {
151+
// Note: these methods are visible, but specific signatures change between versions, so reflection is only reliable inter-version option
152+
Object view = INVENTORYCLOSEEVENT_GETVIEW.invoke(event);
153+
return (String) INVENTORYVIEW_GETTITLE.invoke(view);
154+
}
155+
else {
156+
Object inventory = event.getInventory();
157+
return (String) inventory.getClass().getMethod("getTitle").invoke(inventory);
158+
}
159+
}
160+
catch (Throwable ex) {
161+
ex.printStackTrace();
162+
}
163+
return null;
164+
}
136165
}

0 commit comments

Comments
 (0)