Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9184d54cb7 | ||
|
|
ca43582e4f | ||
|
|
a1552990bf | ||
|
|
99c9f50dfb | ||
|
|
565e14ecf3 | ||
|
|
521a8e0777 | ||
|
|
0141db4a64 | ||
|
|
9ed9db88b7 | ||
|
|
f52a05b477 | ||
|
|
8936204849 |
No files matched your search
@@ -4,10 +4,6 @@ A lightweight spigot packetlistener & packetsender coded by retrooper.
|
||||
|
||||
## Credit
|
||||
|
||||
PacketEvents uses [TinyProtocol](https://github.com/dmulloy2/ProtocolLib/blob/master/TinyProtocol)'s [Reflection](https://github.com/dmulloy2/ProtocolLib/blob/master/TinyProtocol/src/main/java/com/comphenix/tinyprotocol/Reflection.java) util class.
|
||||
|
||||
[Find it here in our source](https://github.com/retrooper/packetevents/blob/master/src/main/java/io/github/retrooper/packetevents/reflectionutils/Reflection.java)
|
||||
|
||||
PacketEvents forked [Atlas](https://github.com/funkemunky/Atlas)' [Packet](https://github.com/funkemunky/Atlas/blob/master/AtlasParent/Atlas/src/main/java/cc/funkemunky/api/tinyprotocol/api/Packet.java) class.
|
||||
|
||||
[Find our forked version](https://github.com/retrooper/packetevents/blob/master/src/main/java/io/github/retrooper/packetevents/packet/PacketType.java)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>packetevents</name>
|
||||
<properties>
|
||||
@@ -89,13 +89,5 @@
|
||||
<version>4fdd683</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.50.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -6,7 +6,10 @@ import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.event.impl.BukkitMoveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.ServerTickEvent;
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
import io.github.retrooper.packetevents.handler.NettyPacketHandler;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
@@ -29,13 +32,12 @@ public final class PacketEvents implements PacketListener, Listener {
|
||||
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
private static final EventManager eventManager = new EventManager();
|
||||
private static final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
private static boolean hasRegistered;
|
||||
private static PacketEvents instance;
|
||||
private static int currentTick;
|
||||
private static BukkitTask serverTickTask;
|
||||
|
||||
private static final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
|
||||
public static EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
@@ -146,7 +148,7 @@ public final class PacketEvents implements PacketListener, Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* When to use this(nano / 1 million) over {@link System#currentTimeMillis()}
|
||||
* When to use this(nano / 1 million) vs {@link System#currentTimeMillis()}
|
||||
* This is preciser than System.currentTimeMillis(), System.currentTimeMillis() can be up to 50ms off on some operating systems, but using this isn't cheap.
|
||||
* Java documentation recommend using nano time if you are measuring elapsed time.
|
||||
* In this function nanoTime is divided by 1 million giving us milliseconds.
|
||||
@@ -159,15 +161,6 @@ public final class PacketEvents implements PacketListener, Listener {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is deprecated, use {@link #highlyPreciseMillis()} as they do the same thing, I just renamed the method.
|
||||
*/
|
||||
@Deprecated
|
||||
public static long currentCalculatedMS() {
|
||||
return System.nanoTime() / 1000000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the player's version.
|
||||
* Do not call this method in the PlayerInjectEvent, it is safe to call it in the PostPlayerInjectEvent.
|
||||
@@ -231,16 +224,6 @@ public final class PacketEvents implements PacketListener, Listener {
|
||||
public void onReceive(final PacketReceiveEvent e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, please do not use this anymore
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
@PacketHandler
|
||||
public void onPostInject(final PostPlayerInjectEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
injectPlayer(e.getPlayer());
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum ClientVersion {
|
||||
LESS_THAN_V_1_7_10, v_1_7_10, v_1_8, v_1_9, v_1_9_1, v_1_9_2, v_1_9_3, v_1_10, v_1_11, v_1_11_1, v_1_12, v_1_12_1, v_1_12_2,
|
||||
v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1, v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, HIGHER_THAN_V_1_15_2, INVALID, ACCESS_FAILURE;
|
||||
v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1, v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_1, HIGHER_THAN_V_1_16_1, INVALID, ACCESS_FAILURE;
|
||||
|
||||
public static ClientVersion fromProtocolVersion(final int protocolVersion) {
|
||||
int remainder = -1;
|
||||
@@ -58,11 +58,15 @@ public enum ClientVersion {
|
||||
return v_1_15_1;
|
||||
case 578:
|
||||
return v_1_15_2;
|
||||
case 735:
|
||||
return v_1_16;
|
||||
case 736:
|
||||
return v_1_16_1;
|
||||
default:
|
||||
remainder = protocolVersion;
|
||||
}
|
||||
if (remainder > 578) {
|
||||
return HIGHER_THAN_V_1_15_2;
|
||||
return HIGHER_THAN_V_1_16_1;
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
@@ -86,7 +90,7 @@ public enum ClientVersion {
|
||||
*/
|
||||
public boolean isLowerThan(final ClientVersion version) {
|
||||
if (version == this) return false;
|
||||
byte len = (byte) values().length;
|
||||
final int len = values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ClientVersion v = values()[i];
|
||||
if (v == this) {
|
||||
|
||||
@@ -9,7 +9,7 @@ public enum Direction {
|
||||
SOUTH_SOUTH_EAST, SOUTH_SOUTH_WEST,
|
||||
WEST_SOUTH_WEST, SELF, NULL;
|
||||
|
||||
public static Direction get(final byte i) {
|
||||
public static Direction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum Hand {
|
||||
MAIN_HAND,
|
||||
OFF_HAND
|
||||
}
|
||||
@@ -1,28 +1,54 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
|
||||
/**
|
||||
* @author retrooper
|
||||
*/
|
||||
public enum ServerVersion {
|
||||
v_1_7_10, v_1_8, v_1_8_3, v_1_8_8, v_1_9, v_1_9_4, v_1_10, v_1_11, v_1_12, v_1_13, v_1_13_2, v_1_14, v_1_15, v_1_16,
|
||||
ERROR;
|
||||
|
||||
v_1_7_10, v_1_8, v_1_8_3, v_1_8_8, v_1_9, v_1_9_4, v_1_10, v_1_11, v_1_12, v_1_13, v_1_13_2, v_1_14, v_1_15, v_1_16_1,
|
||||
ERROR, EMPTY;
|
||||
|
||||
private static final ServerVersion[] reversedValues;
|
||||
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
private static ServerVersion cachedVersion = ServerVersion.EMPTY;
|
||||
|
||||
static {
|
||||
reversedValues = reverse(values());
|
||||
}
|
||||
|
||||
public static ServerVersion getVersion() {
|
||||
ServerVersion[] vals = values();
|
||||
ArrayUtils.reverse(vals);
|
||||
for (ServerVersion val : vals) {
|
||||
if (cachedVersion != ServerVersion.EMPTY) {
|
||||
return cachedVersion;
|
||||
}
|
||||
for (final ServerVersion val : reversedValues) {
|
||||
String valName = val.name().substring(2).replace("_", ".");
|
||||
if (Bukkit.getBukkitVersion().contains(valName)) {
|
||||
cachedVersion = val;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
private static ServerVersion[] reverse(final ServerVersion[] arr) {
|
||||
ServerVersion[] array = arr.clone();
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
ServerVersion tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String getNmsSuffix() {
|
||||
return nmsVersionSuffix;
|
||||
}
|
||||
@@ -54,7 +80,7 @@ public enum ServerVersion {
|
||||
*/
|
||||
public boolean isLowerThan(final ServerVersion version) {
|
||||
if (version == this) return false;
|
||||
byte len = (byte) values().length;
|
||||
final int len = values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ServerVersion v = values()[i];
|
||||
if (v == this) {
|
||||
@@ -67,4 +93,3 @@ public enum ServerVersion {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum EntityAnimationType {
|
||||
SWING_MAIN_ARM, DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT;
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum EntityUseAction {
|
||||
INTERACT, INTERACT_AT, ATTACK, INVALID;
|
||||
|
||||
public static EntityUseAction get(final byte i) {
|
||||
public static EntityUseAction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum Hand {
|
||||
MAIN_HAND,
|
||||
OFF_HAND
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerAction {
|
||||
START_SNEAKING,
|
||||
@@ -19,7 +19,7 @@ public enum PlayerAction {
|
||||
|
||||
START_FALL_FLYING;
|
||||
|
||||
public static PlayerAction get(final byte i) {
|
||||
public static PlayerAction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerDigType {
|
||||
|
||||
@@ -18,7 +18,7 @@ public enum PlayerDigType {
|
||||
|
||||
WRONG_PACKET;
|
||||
|
||||
public static PlayerDigType get(final byte i) {
|
||||
public static PlayerDigType get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -34,15 +34,10 @@ public final class PacketReceiveEvent extends PacketEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is deprecated, please us {@link #getNMSPacket()}
|
||||
* Get the raw NMS packet object
|
||||
*
|
||||
* @return packet
|
||||
* @return packet object
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
public Object getNMSPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
@@ -26,20 +26,11 @@ public final class PacketSendEvent extends PacketEvent {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is deprecated, please us {@link #getNMSPacket()}
|
||||
*
|
||||
* @return packet
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
* Get the raw NMS packet object
|
||||
*
|
||||
* @return packet
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return this.packet;
|
||||
|
||||
@@ -7,8 +7,8 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerInjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private boolean cancelled;
|
||||
private final ClientVersion clientVersion;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerInjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
|
||||
@@ -11,10 +11,6 @@ public final class PlayerUninjectEvent extends PacketEvent {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
}
|
||||
@@ -23,6 +19,10 @@ public final class PlayerUninjectEvent extends PacketEvent {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Please use {@link PlayerInjectEvent}
|
||||
*/
|
||||
@Deprecated
|
||||
public final class PostPlayerInjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
|
||||
public PostPlayerInjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,9 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public final class EventManager {
|
||||
|
||||
private static final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
private final HashMap<PacketListener, List<Method>> registeredMethods = new HashMap<PacketListener, List<Method>>();
|
||||
|
||||
public void callEvent(final PacketEvent e) {
|
||||
@@ -36,9 +33,6 @@ public final class EventManager {
|
||||
}
|
||||
|
||||
public void registerListener(final PacketListener e) {
|
||||
if (registeredMethods.containsKey(e)) {
|
||||
return;
|
||||
}
|
||||
final List<Method> methods = new ArrayList<Method>();
|
||||
for (final Method m : e.getClass().getMethods()) {
|
||||
if (m.isAnnotationPresent(PacketHandler.class)
|
||||
|
||||
@@ -3,17 +3,19 @@ package io.github.retrooper.packetevents.example;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MainExample extends JavaPlugin {
|
||||
public class MainExample extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PacketEvents.start(this);
|
||||
|
||||
PacketEvents.getServerTickTask().cancel();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
PacketEvents.stop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,13 +2,16 @@ package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerUninjectEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
public static final String handlerName = "PacketListener";
|
||||
public static final String handlerName = "packet_handler";
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
@@ -20,7 +23,6 @@ public class NettyPacketHandler {
|
||||
} else {
|
||||
NettyPacketHandler_8.injectPlayer(player);
|
||||
}
|
||||
PacketEvents.getEventManager().callEvent(new PostPlayerInjectEvent(player));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +39,9 @@ public class NettyPacketHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
public static Object write(final Player sender, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(receiver, packetName, packet);
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(sender, packetName, packet);
|
||||
PacketEvents.getEventManager().callEvent(packetSendEvent);
|
||||
if (!packetSendEvent.isCancelled()) {
|
||||
return packet;
|
||||
@@ -47,9 +49,9 @@ public class NettyPacketHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object write(final Player sender, final Object packet) {
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(sender, packetName, packet);
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(receiver, packetName, packet);
|
||||
PacketEvents.getEventManager().callEvent(packetReceiveEvent);
|
||||
if (!packetReceiveEvent.isCancelled()) {
|
||||
return packet;
|
||||
|
||||
@@ -13,7 +13,7 @@ final class NettyPacketHandler_7 {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if(packet == null) {
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
@@ -22,7 +22,7 @@ final class NettyPacketHandler_7 {
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if(packet == null) {
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
|
||||
@@ -10,12 +10,13 @@ import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_8 {
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if(packet == null) {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
@@ -23,8 +24,8 @@ final class NettyPacketHandler_8 {
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if(packet == null) {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
@Deprecated
|
||||
public final class Packet {
|
||||
|
||||
private static Class<?> packetPlayInFlying, packetPlayInPosition, packetPlayInPositionLook, packetPlayInLook;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetPlayInFlying = NMSUtils.getNMSClass(Client.FLYING);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, they are on 1.9+
|
||||
}
|
||||
try {
|
||||
packetPlayInPosition = NMSUtils.getNMSClass(Client.POSITION);
|
||||
packetPlayInPositionLook = NMSUtils.getNMSClass(Client.POSITION_LOOK);
|
||||
packetPlayInLook = NMSUtils.getNMSClass(Client.LOOK);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS packet an instanceof the "PacketPlayInFlying" packet in the 1.8 protocol?
|
||||
* Supports 1.9->1.15.2 too!
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return If the nms packet provided is an instanceof the "PacketPlayInFlying" packet in the 1.8 protocol!
|
||||
*/
|
||||
public static boolean isInstanceOfFlyingPacket(Object nmsPacket) {
|
||||
//1.7->1.8.8
|
||||
if (packetPlayInFlying != null) {
|
||||
return packetPlayInFlying.isInstance(nmsPacket);
|
||||
} else {
|
||||
//1.9->1.15.2
|
||||
return packetPlayInPosition.isInstance(nmsPacket)
|
||||
|| packetPlayInPositionLook.isInstance(nmsPacket)
|
||||
|| packetPlayInLook.isInstance(nmsPacket);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS Packet an instanceof the "PacketPlayInPosition" or "PacketPlayInPositionLook"
|
||||
* @param nmsPacket
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInstanceOfPositionOrPositionLook(final Object nmsPacket) {
|
||||
return packetPlayInPosition.isInstance(nmsPacket) || packetPlayInPositionLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
public static boolean isInstanceOfLook(final Object nmsPacket) {
|
||||
return packetPlayInLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
|
||||
public static class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
|
||||
@Deprecated
|
||||
public static final String FLYING = c + "Flying";
|
||||
|
||||
|
||||
public static final String POSITION = c + "Position";
|
||||
|
||||
public static final String POSITION_LOOK = c + "PositionLook";
|
||||
|
||||
public static final String LOOK = c + "Look";
|
||||
public static final String CLIENT_COMMAND = c + "ClientCommand";
|
||||
|
||||
public static final String TRANSACTION = c + "Transaction";
|
||||
public static final String BLOCK_DIG = c + "BlockDig";
|
||||
public static final String ENTITY_ACTION = c + "EntityAction";
|
||||
public static final String USE_ENTITY = c + "UseEntity";
|
||||
public static final String WINDOW_CLICK = c + "WindowClick";
|
||||
public static final String STEER_VEHICLE = c + "SteerVehicle";
|
||||
public static final String CUSTOM_PAYLOAD = c + "CustomPayload";
|
||||
public static final String ARM_ANIMATION = c + "ArmAnimation";
|
||||
/**
|
||||
* The packet name of the block place depending on your server version, "PacketPlayInBlockPlace" or "PacketPlayInUseItem"
|
||||
*/
|
||||
public static final String BLOCK_PLACE = c + ((ServerVersion.getVersion().isHigherThan(ServerVersion.v_1_8_8)) ? "UseItem" : "BlockPlace");
|
||||
|
||||
public static final String ABILITIES = c + "Abilities";
|
||||
public static final String HELD_ITEM_SLOT = c + "HeldItemSlot";
|
||||
public static final String CLOSE_WINDOW = c + "CloseWindow";
|
||||
public static final String TAB_COMPLETE = c + "TabComplete";
|
||||
public static final String CHAT = c + "Chat";
|
||||
public static final String SET_CREATIVE_SLOT = c + "SetCreativeSlot";
|
||||
|
||||
public static final String KEEP_ALIVE = c + "KeepAlive";
|
||||
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
|
||||
public static final String ANIMATION = s + "Animation";
|
||||
public static final String KEEP_ALIVE = s + "KeepAlive";
|
||||
public static final String CHAT = s + "Chat";
|
||||
public static final String POSITION = s + "Position";
|
||||
public static final String TRANSACTION = s + "Transaction";
|
||||
public static final String NAMED_ENTITY_SPAWN = s + "NamedEntitySpawn";
|
||||
public static final String SPAWN_ENTITY_LIVING = s + "SpawnEntityLiving";
|
||||
public static final String SPAWN_ENTITY = s + "SpawnEntity";
|
||||
public static final String CUSTOM_PAYLOAD = s + "CustomPayload";
|
||||
public static final String ABILITIES = s + "Abilities";
|
||||
public static final String ENTITY_METADATA = s + "EntityMetadata";
|
||||
public static final String ENTITY_VELOCITY = s + "EntityVelocity";
|
||||
public static final String ENTITY_DESTROY = s + "EntityDestroy";
|
||||
public static final String ENTITY_HEAD_ROTATION = s + "EntityHeadRotation";
|
||||
public static final String BLOCK_CHANGE = s + "BlockChange";
|
||||
public static final String CLOSE_WINDOW = s + "CloseWindow";
|
||||
public static final String HELD_ITEM_SLOT = s + "HeldItemSlot";
|
||||
public static final String TAB_COMPLETE = s + "TabComplete";
|
||||
public static final String RESPAWN = s + "Respawn";
|
||||
public static final String WORLD_PARTICLES = s + "WorldParticles";
|
||||
public static final String COMMANDS = s + "Commands";
|
||||
public static final String OPEN_WINDOW = s + "OpenWindow";
|
||||
public static final String LOGIN = s + "Login";
|
||||
public static final String SERVER_DIFFICULTY = s + "ServerDifficulty";
|
||||
}
|
||||
|
||||
public static class Login {
|
||||
public static final String HANDSHAKE = "PacketHandshakingInSetProtocol";
|
||||
public static final String PING = "PacketStatusInPing";
|
||||
public static final String START = "PacketStatusInStart";
|
||||
public static final String SUCCESS = "PacketLoginOutSuccess";
|
||||
public static final String ENCRYPTION_BEGIN_IN = "PacketLoginInEncryptionBegin";
|
||||
public static final String ENCRYPTION_BEGIN_OUT = "PacketLoginOutEncryptionBegin";
|
||||
|
||||
public static final String[] LOGIN_PACKETS = new String[]{"PacketHandshakingInSetProtocol", "PacketLoginInStart", "PacketLoginInEncryptionBegin"};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class PacketType {
|
||||
@@ -9,6 +10,33 @@ public final class PacketType {
|
||||
|
||||
|
||||
public static final class Util {
|
||||
private static Class<?> packetPlayInFlying, packetPlayInPosition, packetPlayInPositionLook, packetPlayInLook, packetPlayInUseEntity;
|
||||
|
||||
static {
|
||||
try {
|
||||
//Only exists in 1.7->1.8.8 & 1.16 protocol
|
||||
packetPlayInFlying = NMSUtils.getNMSClass(Client.FLYING);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, they are on 1.9->1.15.2
|
||||
}
|
||||
try {
|
||||
packetPlayInPosition = NMSUtils.getNMSClass(Client.POSITION);
|
||||
packetPlayInPositionLook = NMSUtils.getNMSClass(Client.POSITION_LOOK);
|
||||
packetPlayInLook = NMSUtils.getNMSClass(Client.LOOK);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
packetPlayInPosition = Reflection.getSubClass(packetPlayInFlying, Client.POSITION);
|
||||
packetPlayInPositionLook = Reflection.getSubClass(packetPlayInFlying, Client.POSITION_LOOK);
|
||||
packetPlayInLook = Reflection.getSubClass(packetPlayInFlying, Client.LOOK);
|
||||
}
|
||||
|
||||
try {
|
||||
packetPlayInUseEntity = NMSUtils.getNMSClass(Client.USE_ENTITY);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS packet an instance of the "PacketPlayInFlying" packet?
|
||||
* Supports 1.9->1.15.2 too!
|
||||
@@ -69,46 +97,13 @@ public final class PacketType {
|
||||
public static boolean isInstanceOfUseEntity(final Object nmsPacket) {
|
||||
return packetPlayInUseEntity.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
private static Class<?> packetPlayInFlying, packetPlayInPosition, packetPlayInPositionLook, packetPlayInLook, packetPlayInUseEntity;
|
||||
|
||||
static {
|
||||
try {
|
||||
//Only exists in 1.7->1.8.8 & 1.16 protocol
|
||||
packetPlayInFlying = NMSUtils.getNMSClass(Client.FLYING);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, they are on 1.9->1.15.2
|
||||
}
|
||||
try {
|
||||
packetPlayInPosition = NMSUtils.getNMSClass(Client.POSITION);
|
||||
packetPlayInPositionLook = NMSUtils.getNMSClass(Client.POSITION_LOOK);
|
||||
packetPlayInLook = NMSUtils.getNMSClass(Client.LOOK);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
for (final Class<?> cls : packetPlayInFlying.getDeclaredClasses()) {
|
||||
if (cls.getSimpleName().equals(Client.POSITION)) {
|
||||
packetPlayInPosition = cls;
|
||||
} else if (cls.getSimpleName().equals(Client.POSITION_LOOK)) {
|
||||
packetPlayInPositionLook = cls;
|
||||
} else if (cls.getSimpleName().equals(Client.LOOK)) {
|
||||
packetPlayInLook = cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
packetPlayInUseEntity = NMSUtils.getNMSClass(Client.USE_ENTITY);
|
||||
}
|
||||
catch(ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
|
||||
@Deprecated
|
||||
/*
|
||||
* Only exists in 1.7.10->1.8.8 & 1.16+
|
||||
*/
|
||||
public static final String FLYING = c + "Flying";
|
||||
|
||||
|
||||
|
||||
+7
-36
@@ -1,13 +1,11 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
private static Class<?> abilitiesClass;
|
||||
private static final Field[] fields = new Field[6];
|
||||
|
||||
static {
|
||||
|
||||
@@ -16,24 +14,6 @@ public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = abilitiesClass.getDeclaredField("a");
|
||||
fields[1] = abilitiesClass.getDeclaredField("b");
|
||||
fields[2] = abilitiesClass.getDeclaredField("c");
|
||||
fields[3] = abilitiesClass.getDeclaredField("d");
|
||||
fields[4] = abilitiesClass.getDeclaredField("e");
|
||||
fields[5] = abilitiesClass.getDeclaredField("f");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVulnerable;
|
||||
@@ -50,12 +30,12 @@ public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.isVulnerable = fields[0].getBoolean(packet);
|
||||
this.isFlying = fields[1].getBoolean(packet);
|
||||
this.allowFly = fields[2].getBoolean(packet);
|
||||
this.instantBuild = fields[3].getBoolean(packet);
|
||||
this.flySpeed = fields[4].getFloat(packet);
|
||||
this.walkSpeed = fields[5].getFloat(packet);
|
||||
this.isVulnerable = Reflection.getField(abilitiesClass, boolean.class, 0).getBoolean(packet);
|
||||
this.isFlying = Reflection.getField(abilitiesClass, boolean.class, 1).getBoolean(packet);
|
||||
this.allowFly = Reflection.getField(abilitiesClass, boolean.class, 2).getBoolean(packet);
|
||||
this.instantBuild = Reflection.getField(abilitiesClass, boolean.class, 3).getBoolean(packet);
|
||||
this.flySpeed = Reflection.getField(abilitiesClass, float.class, 0).getFloat(packet);
|
||||
this.walkSpeed = Reflection.getField(abilitiesClass, float.class, 1).getFloat(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -73,15 +53,6 @@ public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
return allowFly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link WrappedPacketInAbilities#isFlightAllowed()}
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canFly() {
|
||||
return allowFly;
|
||||
}
|
||||
|
||||
public boolean canInstantlyBuild() {
|
||||
return instantBuild;
|
||||
}
|
||||
|
||||
+27
-59
@@ -1,70 +1,38 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockdig;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.Direction;
|
||||
import io.github.retrooper.packetevents.enums.PlayerDigType;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.PlayerDigType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayInBlockDig;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
//ALL
|
||||
private static Class<?> blockDigClass;
|
||||
//1.8
|
||||
private static final Field[] fields = new Field[3];
|
||||
private static Class<?> blockPositionClass;
|
||||
private static final Reflection.FieldAccessor<Integer>[] blockPosXYZ = new Reflection.FieldAccessor[3];
|
||||
//1.7
|
||||
private static Field face;
|
||||
private static Field e;
|
||||
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
blockDigClass = NMSUtils.getNMSClass("PacketPlayInBlockDig");
|
||||
if (version != ServerVersion.v_1_7_10) {
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
enumDirectionClass = NMSUtils.getNMSClass("EnumDirection");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
//blockpos
|
||||
fields[0] = blockDigClass.getDeclaredField("a");
|
||||
//direction
|
||||
fields[1] = blockDigClass.getDeclaredField("b");
|
||||
//digtype
|
||||
fields[2] = blockDigClass.getDeclaredField("c");
|
||||
|
||||
if (version != ServerVersion.v_1_7_10) {
|
||||
blockPosXYZ[0] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 0);
|
||||
blockPosXYZ[1] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 1);
|
||||
blockPosXYZ[2] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 2);
|
||||
} else {
|
||||
face = blockDigClass.getDeclaredField("face");
|
||||
e = blockDigClass.getDeclaredField("e");
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
digTypeClass = NMSUtils.getNMSClass("EnumPlayerDigType");
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (e != null) {
|
||||
e.setAccessible(true);
|
||||
}
|
||||
|
||||
if (face != null) {
|
||||
face.setAccessible(true);
|
||||
catch(ClassNotFoundException e) {
|
||||
//It is probably a subclass
|
||||
digTypeClass = Reflection.getSubClass(blockDigClass, "EnumPlayerDigType");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,26 +50,18 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
PlayerDigType enumDigType = null;
|
||||
//1.7.10
|
||||
try {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
final int x = fields[0].getInt(packet);
|
||||
final int y = fields[1].getInt(packet);
|
||||
final int z = fields[2].getInt(packet);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
|
||||
enumDirection = Direction.get((byte) face.getInt(packet));
|
||||
enumDigType = PlayerDigType.get((byte) e.getInt(packet));
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
setupCoordinates(blockDigClass, packet);
|
||||
enumDirection = Direction.get(Reflection.getField(digTypeClass, int.class, 3).getInt(packet));
|
||||
enumDigType = PlayerDigType.get(Reflection.getField(digTypeClass, int.class, 4).getInt(packet));
|
||||
} else {
|
||||
//1.8+
|
||||
final Object blockPosObj = fields[0].get(packet);
|
||||
final Object enumDirectionObj = fields[1].get(packet);
|
||||
final Object digTypeObj = fields[2].get(packet);
|
||||
final Object blockPosObj = Reflection.getField(blockDigClass, blockPositionClass, 0).get(packet);
|
||||
final Object enumDirectionObj = Reflection.getField(blockDigClass, enumDirectionClass, 0).get(packet);
|
||||
final Object digTypeObj = Reflection.getField(blockDigClass, digTypeClass, 0).get(packet);
|
||||
|
||||
final int x = blockPosXYZ[0].get(blockPosObj);
|
||||
final int y = blockPosXYZ[1].get(blockPosObj);
|
||||
final int z = blockPosXYZ[2].get(blockPosObj);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
Class<?> blockPosSuper = blockPositionClass;
|
||||
setupCoordinates(blockPosSuper, blockPosObj);
|
||||
|
||||
enumDirection = Direction.valueOf(((Enum) enumDirectionObj).name());
|
||||
enumDigType = PlayerDigType.valueOf(((Enum) digTypeObj).name());
|
||||
@@ -113,6 +73,14 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
this.digType = enumDigType;
|
||||
}
|
||||
|
||||
private void setupCoordinates(final Class<?> cls, final Object object) throws IllegalAccessException {
|
||||
final int x = Reflection.getField(cls, int.class, 0).getInt(object);
|
||||
final int y = Reflection.getField(cls, int.class, 1).getInt(object);
|
||||
final int z = Reflection.getField(cls, int.class, 2).getInt(object);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
+8
-11
@@ -9,6 +9,12 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
static {
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
WrappedPacketInBlockPlace_1_8.initStatic();
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
@@ -27,12 +33,11 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
final Block block = blockPlace_1_9.getBlock();
|
||||
position = new Vector3i(block.getX(), block.getY(), block.getZ());
|
||||
itemStack = new ItemStack(block.getType());
|
||||
} else if(version.isHigherThan(ServerVersion.v_1_7_10)){
|
||||
} else if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
final WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
position = blockPlace_1_8.getBlockPosition();
|
||||
itemStack = blockPlace_1_8.getItemStack();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(getPlayer(), packet);
|
||||
position = blockPlace_1_7_10.getBlockPosition();
|
||||
this.itemStack = blockPlace_1_7_10.getItemStack();
|
||||
@@ -56,12 +61,4 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
static {
|
||||
if (version.isHigherThan(ServerVersion.v_1_8_8)) {
|
||||
WrappedPacketInBlockPlace_1_9.initStatic();
|
||||
} else if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
WrappedPacketInBlockPlace_1_8.initStatic();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+14
-16
@@ -6,10 +6,10 @@ import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
private static final Reflection.MethodInvoker[] blockPositionXYZInvoker = new Reflection.MethodInvoker[3];
|
||||
private static Class<?> blockPlaceClass, blockPositionClass;
|
||||
private static Reflection.FieldAccessor<?> blockPositionAccessor, itemStackFieldAccessor;
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
@@ -25,27 +25,25 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
itemStackFieldAccessor = Reflection.getField(blockPlaceClass, NMSUtils.nmsItemStackClass, 0);
|
||||
|
||||
blockPositionAccessor = Reflection.getField(blockPlaceClass, blockPositionClass, 1);
|
||||
|
||||
blockPositionXYZInvoker[0] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getX");
|
||||
blockPositionXYZInvoker[1] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getY");
|
||||
blockPositionXYZInvoker[2] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getZ");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
Object nmsBlockPos = blockPositionAccessor.get(packet);
|
||||
try {
|
||||
Object nmsBlockPos = Reflection.getField(blockPlaceClass, blockPositionClass, 1).get(packet);
|
||||
|
||||
int x = (int) blockPositionXYZInvoker[0].invoke(nmsBlockPos);
|
||||
int y = (int) blockPositionXYZInvoker[1].invoke(nmsBlockPos);
|
||||
int z = (int) blockPositionXYZInvoker[2].invoke(nmsBlockPos);
|
||||
final int[] coords = new int[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final String s = "get" + (i == 0 ? "X" : i == 1 ? "Y" : "Z");
|
||||
coords[i] = (int) Reflection.getMethod(blockPositionClass.getSuperclass(), s, 0).invoke(nmsBlockPos);
|
||||
}
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
this.blockPosition = new Vector3i(coords[0], coords[1], coords[2]);
|
||||
|
||||
this.itemStack = NMSUtils.toBukkitItemStack(itemStackFieldAccessor.get(packet));
|
||||
this.itemStack = NMSUtils.toBukkitItemStack(Reflection.getField(blockPlaceClass, NMSUtils.nmsItemStackClass, 0).get(packet));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
|
||||
+3
-18
@@ -2,7 +2,8 @@ package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.BlockIteratorUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -14,30 +15,14 @@ import java.util.HashSet;
|
||||
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
|
||||
private Block block;
|
||||
|
||||
private static Method getTargetBlockMethod;
|
||||
|
||||
public WrappedPacketInBlockPlace_1_9(final Player player, final Object packet) {
|
||||
super(player, packet);
|
||||
}
|
||||
|
||||
protected static void initStatic() {
|
||||
try {
|
||||
getTargetBlockMethod = Player.class.getMethod("getTargetBlock", HashSet.class, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.block = (Block) getTargetBlockMethod.invoke(getPlayer(), null, 3);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.block = BlockIteratorUtils.getBlockLookingAt(getPlayer(), 3);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
|
||||
+2
-20
@@ -1,30 +1,18 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInChat extends WrappedPacket {
|
||||
private static Class<?> chatPacketClass;
|
||||
private static Field field;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
chatPacketClass = NMSUtils.getNMSClass("PacketPlayInChat");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
field = chatPacketClass.getDeclaredField(getChatFieldName());
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
private String message;
|
||||
@@ -33,17 +21,11 @@ public final class WrappedPacketInChat extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
private static String getChatFieldName() {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
return "message";
|
||||
}
|
||||
return "a";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final Object obj = field.get(packet);
|
||||
final Object obj = Reflection.getField(chatPacketClass, String.class, 0).get(packet);
|
||||
this.message = obj.toString();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
+13
-27
@@ -1,19 +1,17 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.entityaction;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.PlayerAction;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.PlayerAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
private static Class<?> entityActionClass;
|
||||
@Nullable
|
||||
private static Class<?> enumPlayerActionClass;
|
||||
private static final Field[] fields = new Field[3];
|
||||
@Nullable
|
||||
private static Object[] enumPlayerActionConstants;
|
||||
|
||||
@@ -21,27 +19,16 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
try {
|
||||
entityActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumPlayerActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction$EnumPlayerAction");
|
||||
for (final Class<?> sub : entityActionClass.getDeclaredClasses()) {
|
||||
if (sub.getSimpleName().equals("EnumPlayerAction")) {
|
||||
enumPlayerActionClass = sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
//ints in 1.7.10, EnumPlayerAction in 1.8+
|
||||
fields[0] = entityActionClass.getDeclaredField("a");
|
||||
fields[1] = entityActionClass.getDeclaredField("animation");
|
||||
fields[2] = entityActionClass.getDeclaredField("c");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumPlayerActionConstants = enumPlayerActionClass.getEnumConstants();
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
@@ -56,16 +43,16 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final int entityId = fields[0].getInt(packet);
|
||||
final int jumpBoost = fields[2].getInt(packet);
|
||||
final int entityId = Reflection.getField(entityActionClass, int.class, 0).getInt(packet);
|
||||
final int jumpBoost = Reflection.getField(entityActionClass, int.class, 2).getInt(packet);
|
||||
|
||||
int animationIndex = -1;
|
||||
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
animationIndex = fields[1].getInt(packet);
|
||||
animationIndex = Reflection.getField(entityActionClass, int.class, 1).getInt(packet);
|
||||
} else {
|
||||
final Object enumObj = fields[1].get(packet);
|
||||
final Object enumObj = Reflection.getField(entityActionClass, enumPlayerActionClass, 0);
|
||||
|
||||
final Object[] enumValues = enumPlayerActionConstants;
|
||||
final int len = enumValues.length;
|
||||
@@ -80,9 +67,8 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
|
||||
|
||||
this.entityId = entityId;
|
||||
this.action = action;
|
||||
this.jumpBoost = jumpBoost;
|
||||
this.action = PlayerAction.get((byte) animationIndex);
|
||||
this.action = PlayerAction.get(animationIndex);
|
||||
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
} catch (IllegalAccessException e) {
|
||||
|
||||
+57
-40
@@ -1,15 +1,12 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.flying;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class WrappedPacketInFlying extends WrappedPacket {
|
||||
private static Class<?> flyingClass;
|
||||
private static final Field[] fields = new Field[8]; //x, y, z, yaw pitch, onGround, isPositionPacket, isLookPacket
|
||||
|
||||
static {
|
||||
|
||||
@@ -18,26 +15,6 @@ public class WrappedPacketInFlying extends WrappedPacket {
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = flyingClass.getDeclaredField("x");
|
||||
fields[1] = flyingClass.getDeclaredField("y");
|
||||
fields[2] = flyingClass.getDeclaredField("z");
|
||||
fields[3] = flyingClass.getDeclaredField("yaw");
|
||||
fields[4] = flyingClass.getDeclaredField("pitch");
|
||||
fields[5] = flyingClass.getDeclaredField(getOnGroundFieldName());
|
||||
fields[6] = flyingClass.getDeclaredField("hasPos");
|
||||
fields[7] = flyingClass.getDeclaredField("hasLook");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double x;
|
||||
@@ -53,27 +30,21 @@ public class WrappedPacketInFlying extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
private static String getOnGroundFieldName() {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
return "g";
|
||||
}
|
||||
return "f";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.x = fields[0].getDouble(packet);
|
||||
this.y = fields[1].getDouble(packet);
|
||||
this.z = fields[2].getDouble(packet);
|
||||
//x, y, z, yaw pitch, onGround, isPosition, isLook
|
||||
this.x = Reflection.getField(flyingClass, double.class, 0).getDouble(packet);
|
||||
this.y = Reflection.getField(flyingClass, double.class, 1).getDouble(packet);
|
||||
this.z = Reflection.getField(flyingClass, double.class, 2).getDouble(packet);
|
||||
|
||||
this.yaw = fields[3].getFloat(packet);
|
||||
this.pitch = fields[4].getFloat(packet);
|
||||
this.yaw = Reflection.getField(flyingClass, float.class, 0).getFloat(packet);
|
||||
this.pitch = Reflection.getField(flyingClass, float.class, 1).getFloat(packet);
|
||||
|
||||
this.onGround = fields[5].getBoolean(packet);
|
||||
this.onGround = Reflection.getField(flyingClass, boolean.class, 0).getBoolean(packet);
|
||||
|
||||
this.isPosition = fields[6].getBoolean(packet);
|
||||
this.isLook = fields[7].getBoolean(packet);
|
||||
this.isPosition = Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
this.isLook = Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -118,11 +89,21 @@ public class WrappedPacketInFlying extends WrappedPacket {
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -133,14 +114,50 @@ public class WrappedPacketInFlying extends WrappedPacket {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketInLook extends WrappedPacketInFlying {
|
||||
|
||||
public WrappedPacketInLook(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-13
@@ -2,14 +2,11 @@ package io.github.retrooper.packetevents.packetwrappers.in.keepalive;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
private static Class<?> keepAliveClass;
|
||||
//1.7.10->1.12.2 has int field "a", rest as long field "a"
|
||||
private static Field idField;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -17,13 +14,6 @@ public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
idField = keepAliveClass.getDeclaredField("a");
|
||||
idField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private long id;
|
||||
@@ -36,9 +26,9 @@ public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
protected void setup() {
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_12)) {
|
||||
this.id = idField.getLong(packet);
|
||||
this.id = Reflection.getField(keepAliveClass, long.class, 0).getLong(packet);
|
||||
} else {
|
||||
this.id = idField.getInt(packet);
|
||||
this.id = Reflection.getField(keepAliveClass, int.class, 0).getInt(packet);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
+19
-21
@@ -5,18 +5,34 @@ import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
|
||||
public WrappedPacketInTransaction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = windowIdAccessor.get(packet);
|
||||
this.actionNumber = actionNumberAccessor.get(packet);
|
||||
this.accepted = acceptedAccessor.get(packet);
|
||||
try {
|
||||
this.windowId = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
this.actionNumber = Reflection.getField(packetClass, short.class, 0).getShort(packet);
|
||||
this.accepted = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getWindowId() {
|
||||
@@ -30,22 +46,4 @@ public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
public boolean isAccepted() {
|
||||
return accepted;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> windowIdAccessor;
|
||||
private static final Reflection.FieldAccessor<Short> actionNumberAccessor;
|
||||
private static final Reflection.FieldAccessor<Boolean> acceptedAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
windowIdAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
actionNumberAccessor = Reflection.getField(packetClass, short.class, 0);
|
||||
acceptedAccessor= Reflection.getField(packetClass, boolean.class, 0);
|
||||
}
|
||||
}
|
||||
+13
-20
@@ -1,41 +1,34 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.useentity;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.EntityUseAction;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.EntityUseAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInUseEntity extends WrappedPacket {
|
||||
private static Class<?> useEntityClass, entityClass;
|
||||
private static final Field[] fields = new Field[2];
|
||||
private static Class<?> useEntityClass, entityClass, enumEntityUseActionClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
useEntityClass = NMSUtils.getNMSClass("PacketPlayInUseEntity");
|
||||
entityClass = NMSUtils.getNMSClass("Entity");
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = useEntityClass.getDeclaredField("a");
|
||||
fields[1] = useEntityClass.getDeclaredField("action");
|
||||
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
for (final Class<?> sub : useEntityClass.getDeclaredClasses()) {
|
||||
if (sub.getSimpleName().equals("EnumEntityUseAction")) {
|
||||
enumEntityUseActionClass = sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int entityId;
|
||||
@@ -49,9 +42,9 @@ public final class WrappedPacketInUseEntity extends WrappedPacket {
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.entityId = fields[0].getInt(packet);
|
||||
this.entityId = Reflection.getField(useEntityClass, int.class, 0).getInt(packet);
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
final Object useActionEnum = fields[1].get(packet);
|
||||
final Object useActionEnum = Reflection.getField(useEntityClass, enumEntityUseActionClass, 0).get(packet);
|
||||
this.action = EntityUseAction.valueOf(useActionEnum.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
+11
-25
@@ -7,28 +7,9 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class PlayerAbilitiesUtils {
|
||||
|
||||
public static Class<?> playerAbilitiesClass;
|
||||
|
||||
public static Constructor<?> playerAbilitiesConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Boolean>[] booleanFieldAccessors = new Reflection.FieldAccessor[4];
|
||||
private static final Reflection.FieldAccessor<Float>[] floatFieldAccessors = new Reflection.FieldAccessor[2];
|
||||
|
||||
public static Object getPlayerAbilities(final boolean isVulnerable, final boolean isFlying, final boolean allowFlight, final boolean canBuildInstantly,
|
||||
final float flySpeed, final float walkSpeed) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
final Object instance = playerAbilitiesConstructor.newInstance();
|
||||
booleanFieldAccessors[0].set(instance, isVulnerable);
|
||||
booleanFieldAccessors[1].set(instance, isFlying);
|
||||
booleanFieldAccessors[2].set(instance, allowFlight);
|
||||
booleanFieldAccessors[3].set(instance, canBuildInstantly);
|
||||
|
||||
floatFieldAccessors[0].set(instance, flySpeed);
|
||||
floatFieldAccessors[1].set(instance, walkSpeed);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
playerAbilitiesClass = NMSUtils.getNMSClass("PlayerAbilities");
|
||||
@@ -40,13 +21,18 @@ final class PlayerAbilitiesUtils {
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = 0; i < booleanFieldAccessors.length; i++) {
|
||||
booleanFieldAccessors[i] = Reflection.getField(playerAbilitiesClass, boolean.class, i);
|
||||
}
|
||||
public static Object getPlayerAbilities(final boolean isVulnerable, final boolean isFlying, final boolean allowFlight, final boolean canBuildInstantly,
|
||||
final float flySpeed, final float walkSpeed) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
final Object instance = playerAbilitiesConstructor.newInstance();
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 0).setBoolean(instance, isVulnerable);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 1).setBoolean(instance, isFlying);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 2).setBoolean(instance, allowFlight);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 3).setBoolean(instance, canBuildInstantly);
|
||||
|
||||
for (byte i = 0; i < floatFieldAccessors.length; i++) {
|
||||
floatFieldAccessors[i] = Reflection.getField(playerAbilitiesClass, float.class, i);
|
||||
}
|
||||
Reflection.getField(playerAbilitiesClass, float.class, 0).setFloat(instance, flySpeed);
|
||||
Reflection.getField(playerAbilitiesClass, float.class, 1).setFloat(instance, walkSpeed);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
+28
-35
@@ -9,6 +9,23 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutAbilities extends WrappedPacket implements Sendable {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean vulnerable, flying, allowFlight, instantBuild;
|
||||
private float flySpeed, walkSpeed;
|
||||
|
||||
@@ -29,13 +46,18 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.vulnerable = booleanFieldAccessors[0].get(packet);
|
||||
this.flying = booleanFieldAccessors[1].get(packet);
|
||||
this.allowFlight = booleanFieldAccessors[2].get(packet);
|
||||
this.instantBuild = booleanFieldAccessors[3].get(packet);
|
||||
try {
|
||||
this.vulnerable = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
this.flying = Reflection.getField(packetClass, boolean.class, 1).getBoolean(packet);
|
||||
this.allowFlight = Reflection.getField(packetClass, boolean.class, 2).getBoolean(packet);
|
||||
this.instantBuild = Reflection.getField(packetClass, boolean.class, 3).getBoolean(packet);
|
||||
|
||||
this.flySpeed = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
|
||||
this.walkSpeed = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.flySpeed = floatFieldAccessors[0].get(packet);
|
||||
this.walkSpeed = floatFieldAccessors[1].get(packet);
|
||||
}
|
||||
|
||||
public boolean isVulnerable() {
|
||||
@@ -62,35 +84,6 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
|
||||
return walkSpeed;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Boolean>[] booleanFieldAccessors = new Reflection.FieldAccessor[4];
|
||||
private static final Reflection.FieldAccessor<Float>[] floatFieldAccessors = new Reflection.FieldAccessor[2];
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (byte i = 0; i < booleanFieldAccessors.length; i++) {
|
||||
booleanFieldAccessors[i] = Reflection.getField(packetClass, boolean.class, i);
|
||||
}
|
||||
|
||||
for (byte i = 0; i < floatFieldAccessors.length; i++) {
|
||||
floatFieldAccessors[i] = Reflection.getField(packetClass, float.class, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
|
||||
+4
-16
@@ -1,19 +1,18 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.animation;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.EntityAnimationType;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.EntityAnimationType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutAnimation extends WrappedPacket implements Sendable {
|
||||
private static Class<?> animationClass, nmsEntityClass;
|
||||
private static Constructor<?> animationConstructor;
|
||||
private static final Field[] fields = new Field[2];
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -28,17 +27,6 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
fields[0] = animationClass.getDeclaredField("a");
|
||||
fields[1] = animationClass.getDeclaredField("b");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
@@ -61,9 +49,9 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
|
||||
try {
|
||||
//a - ID
|
||||
//b - TYPE
|
||||
this.entityID = fields[0].getInt(packet);
|
||||
this.entityID = Reflection.getField(animationClass, int.class, 0).getInt(packet);
|
||||
this.entity = NMSUtils.getEntityById(this.entityID);
|
||||
this.type = EntityAnimationType.get(fields[1].getInt(packet));
|
||||
this.type = EntityAnimationType.get(Reflection.getField(animationClass, int.class, 1).getInt(packet));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+14
-44
@@ -1,60 +1,40 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class WrappedPacketOutChat extends WrappedPacket implements Sendable {
|
||||
private static Constructor<?> chatClassConstructor;
|
||||
private static Class<?> chatClass, iChatBaseComponentClass, chatSerializerClass;
|
||||
private static Field iChatBaseField;
|
||||
private static Method serialize, getStringOfIChatBase;
|
||||
|
||||
static {
|
||||
try {
|
||||
chatClass = NMSUtils.getNMSClass("PacketPlayOutChat");
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
|
||||
//In 1.8.3+ the ChatSerializer class is declared in the IChatBaseComponent class, so we have to handle tahat
|
||||
if (version.isHigherThan(ServerVersion.v_1_8)) {
|
||||
for (final Class<?> cls : iChatBaseComponentClass.getDeclaredClasses()) {
|
||||
if (cls.getSimpleName().equals("ChatSerializer")) {
|
||||
chatSerializerClass = cls;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chatSerializerClass = NMSUtils.getNMSClass("ChatSerializer");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//In 1.8.3+ the ChatSerializer class is declared in the IChatBaseComponent class, so we have to handle that
|
||||
try {
|
||||
chatSerializerClass = NMSUtils.getNMSClass("ChatSerializer");
|
||||
}
|
||||
catch(ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
chatSerializerClass = Reflection.getSubClass(iChatBaseComponentClass, "ChatSerializer");
|
||||
}
|
||||
|
||||
try {
|
||||
chatClassConstructor = chatClass.getConstructor(iChatBaseComponentClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
serialize = chatSerializerClass.getMethod("a", String.class);
|
||||
getStringOfIChatBase = iChatBaseComponentClass.getMethod(getTextMethodName());
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
iChatBaseField = chatClass.getDeclaredField("a");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
iChatBaseField.setAccessible(true);
|
||||
|
||||
}
|
||||
|
||||
@@ -71,7 +51,7 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
|
||||
public static String toStringFromIChatBaseComponent(Object obj) {
|
||||
try {
|
||||
return getStringOfIChatBase.invoke(obj).toString();
|
||||
return Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(obj).toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -80,30 +60,20 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
|
||||
public static Object toIChatBaseComponent(String msg) {
|
||||
try {
|
||||
return serialize.invoke(null, msg);
|
||||
return Reflection.getMethod(chatSerializerClass, 0, String.class).invoke(null, msg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getTextMethodName() {
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
return "e"; //or c
|
||||
} else {
|
||||
return "getText";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
//all fields are IChatBaseComponents, and named 'a'
|
||||
|
||||
try {
|
||||
Object iChatBaseObj = iChatBaseField.get(packet);
|
||||
final Object iChatBaseObj = Reflection.getField(chatClass, iChatBaseComponentClass, 0).get(packet);
|
||||
|
||||
Object contentString = getStringOfIChatBase.invoke(iChatBaseObj);
|
||||
final Object contentString = Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(iChatBaseObj);
|
||||
|
||||
this.message = contentString.toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
|
||||
+12
-30
@@ -3,17 +3,16 @@ package io.github.retrooper.packetevents.packetwrappers.out.entityvelocity;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements Sendable {
|
||||
private static Constructor<?> velocityConstructor, vec3dConstructor;
|
||||
private static Class<?> velocityClass, vec3dClass;
|
||||
private static final Field[] fields = new Field[4];
|
||||
|
||||
/**
|
||||
* Velocity Constructor parameter types:
|
||||
@@ -32,35 +31,18 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
|
||||
}
|
||||
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That is fine, just a newer version
|
||||
try {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, vec3dClass);
|
||||
//vec3d constructor
|
||||
vec3dConstructor = vec3dClass.getConstructor(double.class, double.class, double.class);
|
||||
} else {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
|
||||
} catch (NoSuchMethodException e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
//entity id
|
||||
fields[0] = velocityClass.getDeclaredField("a");
|
||||
//x
|
||||
fields[1] = velocityClass.getDeclaredField("b");
|
||||
//y
|
||||
fields[2] = velocityClass.getDeclaredField("c");
|
||||
//z
|
||||
fields[3] = velocityClass.getDeclaredField("d");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
@@ -84,11 +66,11 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
|
||||
protected void setup() {
|
||||
try {
|
||||
int i = 0;
|
||||
final int entityId = fields[0].getInt(packet);
|
||||
final int entityId = Reflection.getField(velocityClass, int.class, 0).getInt(packet);
|
||||
|
||||
final int x = fields[1].getInt(packet);
|
||||
final int y = fields[2].getInt(packet);
|
||||
final int z = fields[3].getInt(packet);
|
||||
final int x = Reflection.getField(velocityClass, int.class, 1).getInt(packet);
|
||||
final int y = Reflection.getField(velocityClass, int.class, 2).getInt(packet);
|
||||
final int z = Reflection.getField(velocityClass, int.class, 3).getInt(packet);
|
||||
|
||||
this.entityId = entityId;
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
|
||||
+5
-3
@@ -10,7 +10,6 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutKickDisconnect extends WrappedPacket implements Sendable {
|
||||
private static final Reflection.FieldAccessor<?> iChatBaseComponentAccessor;
|
||||
private static Class<?> packetClass, iChatBaseComponentClass;
|
||||
private static Constructor<?> kickDisconnectConstructor;
|
||||
|
||||
@@ -27,7 +26,6 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
iChatBaseComponentAccessor = Reflection.getField(packetClass, iChatBaseComponentClass, 0);
|
||||
}
|
||||
|
||||
private String kickMessage;
|
||||
@@ -43,7 +41,11 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.kickMessage = WrappedPacketOutChat.toStringFromIChatBaseComponent(iChatBaseComponentAccessor.get(packet));
|
||||
try {
|
||||
this.kickMessage = WrappedPacketOutChat.toStringFromIChatBaseComponent(Reflection.getField(packetClass, iChatBaseComponentClass, 0).get(packet));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getKickMessage() {
|
||||
|
||||
+27
-29
@@ -9,9 +9,27 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutTransaction extends WrappedPacket implements Sendable {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
|
||||
public WrappedPacketOutTransaction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
@@ -22,11 +40,17 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
|
||||
this.actionNumber = actionNumber;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = windowIdAccessor.get(packet);
|
||||
this.actionNumber = actionNumberAccessor.get(packet);
|
||||
this.accepted = acceptedAccessor.get(packet);
|
||||
try {
|
||||
this.windowId = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
this.actionNumber = Reflection.getField(packetClass, short.class, 0).getShort(packet);
|
||||
this.accepted = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getWindowId() {
|
||||
@@ -51,30 +75,4 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> windowIdAccessor;
|
||||
private static final Reflection.FieldAccessor<Short> actionNumberAccessor;
|
||||
private static final Reflection.FieldAccessor<Boolean> acceptedAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
windowIdAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
actionNumberAccessor = Reflection.getField(packetClass, short.class, 0);
|
||||
acceptedAccessor= Reflection.getField(packetClass, boolean.class, 0);
|
||||
}
|
||||
|
||||
}
|
||||
+28
-30
@@ -9,30 +9,54 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements Sendable {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutUpdateHealth");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private float health, foodSaturation;
|
||||
private int food;
|
||||
|
||||
public WrappedPacketOutUpdateHealth(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://wiki.vg/Protocol#Update_Health
|
||||
*
|
||||
* @param health
|
||||
* @param food
|
||||
* @param foodSaturation
|
||||
*/
|
||||
public WrappedPacketOutUpdateHealth(final float health, final int food, final float foodSaturation) {
|
||||
super(null);
|
||||
this.health= health;
|
||||
this.health = health;
|
||||
this.food = food;
|
||||
this.foodSaturation = foodSaturation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.health = healthAccessor.get(packet);
|
||||
this.foodSaturation = foodSaturationAccessor.get(packet);
|
||||
this.food = foodAccessor.get(packet);
|
||||
try {
|
||||
this.health = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
|
||||
this.foodSaturation = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
|
||||
this.food = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public float getHealth() {
|
||||
@@ -56,30 +80,4 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Float> healthAccessor, foodSaturationAccessor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> foodAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutUpdateHealth");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
healthAccessor = Reflection.getField(packetClass, float.class, 0);
|
||||
foodSaturationAccessor = Reflection.getField(packetClass, float.class, 1);
|
||||
foodAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,401 +1,194 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import io.github.retrooper.packetevents.reflectionutils.fielddata.FieldWithIndex;
|
||||
import io.github.retrooper.packetevents.reflectionutils.fielddata.FieldWithName;
|
||||
import io.github.retrooper.packetevents.reflectionutils.fielddata.FieldWithTypeAndIndex;
|
||||
import io.github.retrooper.packetevents.reflectionutils.methoddata.MethodWithIndexAndParams;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* An utility class that simplifies reflection in Bukkit plugins.
|
||||
*
|
||||
* @author Kristian
|
||||
* @author retrooper
|
||||
*/
|
||||
public final class Reflection {
|
||||
// Deduce the net.minecraft.server.v* package
|
||||
private static final String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static final String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static final String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
|
||||
// Variable replacement
|
||||
private static final Pattern MATCH_VARIABLE = Pattern.compile("\\{([^\\}]+)\\}");
|
||||
private Reflection() {
|
||||
// Seal class
|
||||
private static final HashMap<Class<?>, Field[]> cachedFields = new HashMap<Class<?>, Field[]>();
|
||||
private static final HashMap<Class<?>, Method[]> cachedMethods = new HashMap<Class<?>, Method[]>();
|
||||
private static final HashMap<Class<?>, Class<?>[]> cachedSubclasses = new HashMap<Class<?>, Class<?>[]>();
|
||||
|
||||
|
||||
//FIELDS
|
||||
|
||||
public static Field[] getFields(final Class<?> cls) {
|
||||
if (cachedFields.containsKey(cls)) {
|
||||
return cachedFields.get(cls);
|
||||
} else {
|
||||
final Field[] fields = cls.getDeclaredFields();
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
cachedFields.put(cls, fields);
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param target - the target type.
|
||||
* @param name - the name of the field, or NULL to ignore.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType) {
|
||||
return getField(target, name, fieldType, 0);
|
||||
private static final HashMap<FieldWithName, Field> fieldWithNameHashMap = new HashMap<FieldWithName, Field>();
|
||||
|
||||
public static Field getField(final Class<?> cls, final String name) {
|
||||
final FieldWithName fwn = new FieldWithName(cls, name);
|
||||
if (!fieldWithNameHashMap.containsKey(fwn)) {
|
||||
for (final Field f : getFields(cls)) {
|
||||
if (f.getName().equals(name)) {
|
||||
fieldWithNameHashMap.put(fwn, f);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fieldWithNameHashMap.get(fwn);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param name - the name of the field, or NULL to ignore.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(String className, String name, Class<T> fieldType) {
|
||||
return getField(getClass(className), name, fieldType, 0);
|
||||
}
|
||||
private static final HashMap<FieldWithTypeAndIndex, Field> fieldWithTypeAndIndexHashMap = new HashMap<FieldWithTypeAndIndex, Field>();
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param target - the target type.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @param index - the number of compatible fields to skip.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index) {
|
||||
return getField(target, null, fieldType, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @param index - the number of compatible fields to skip.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(String className, Class<T> fieldType, int index) {
|
||||
return getField(getClass(className), fieldType, index);
|
||||
}
|
||||
|
||||
// Common method
|
||||
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index) {
|
||||
for (final Field field : target.getDeclaredFields()) {
|
||||
if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) {
|
||||
field.setAccessible(true);
|
||||
|
||||
// A function for retrieving a specific field value
|
||||
return new FieldAccessor<T>() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T get(Object target) {
|
||||
try {
|
||||
return (T) field.get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
}
|
||||
public static Field getField(final Class<?> cls, final Class<?> dataType, final int index) {
|
||||
final FieldWithTypeAndIndex fwtai = new FieldWithTypeAndIndex(cls, dataType, index);
|
||||
if (!fieldWithTypeAndIndexHashMap.containsKey(fwtai)) {
|
||||
int i = 0;
|
||||
for (final Field f : getFields(cls)) {
|
||||
if (f.getType().equals(dataType)) {
|
||||
if (i++ == index) {
|
||||
fieldWithTypeAndIndexHashMap.put(fwtai, f);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fieldWithTypeAndIndexHashMap.get(fwtai);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object target, Object value) {
|
||||
try {
|
||||
field.set(target, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
private static final HashMap<FieldWithIndex, Field> fieldWithIndexHashMap = new HashMap<FieldWithIndex, Field>();
|
||||
|
||||
@Override
|
||||
public boolean hasField(Object target) {
|
||||
// target instanceof DeclaringClass
|
||||
return field.getDeclaringClass().isAssignableFrom(target.getClass());
|
||||
}
|
||||
};
|
||||
public static Field getField(final Class<?> cls, final int index) {
|
||||
final FieldWithIndex fwi = new FieldWithIndex(cls, index);
|
||||
if (!fieldWithIndexHashMap.containsKey(fwi)) {
|
||||
int i = 0;
|
||||
for (final Field f : getFields(cls)) {
|
||||
if (index == i++) {
|
||||
fieldWithIndexHashMap.put(fwi, f);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fieldWithIndexHashMap.get(fwi);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//METHODS
|
||||
public static Method[] getMethods(final Class<?> cls) {
|
||||
if (cachedMethods.containsKey(cls)) {
|
||||
return cachedMethods.get(cls);
|
||||
} else {
|
||||
final Method[] methods = cls.getDeclaredMethods();
|
||||
for (final Method m : methods) {
|
||||
m.setAccessible(true);
|
||||
}
|
||||
cachedMethods.put(cls, methods);
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
||||
private static final HashMap<MethodWithIndexAndParams, Method> methodWithIndexAndParamsHashMap = new HashMap<MethodWithIndexAndParams, Method>();
|
||||
|
||||
public static Method getMethod(final Class<?> cls, final int index, final Class<?>... params) {
|
||||
final MethodWithIndexAndParams mwiap = new MethodWithIndexAndParams(cls, index, params);
|
||||
if (!methodWithIndexAndParamsHashMap.containsKey(mwiap)) {
|
||||
int i = 0;
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (Arrays.equals(m.getParameterTypes(), params) && index == i++) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return methodWithIndexAndParamsHashMap.get(mwiap);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//THE REST LATER
|
||||
|
||||
public static Method getMethod(final Class<?> cls, final String name, Class<?> returning, Class<?>... params) {
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getName().equals(name) && Arrays.equals(m.getParameterTypes(), params) && m.getReturnType().equals(returning)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
// Search in parent classes
|
||||
if (target.getSuperclass() != null)
|
||||
return getField(target.getSuperclass(), name, fieldType, index);
|
||||
|
||||
throw new IllegalArgumentException("Cannot find field with type " + fieldType);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getMethod(String className, String methodName, Class<?>... params) {
|
||||
return getTypedMethod(getClass(className), methodName, null, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getMethod(Class<?> clazz, String methodName, Class<?>... params) {
|
||||
return getTypedMethod(clazz, methodName, null, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param returnType - the expected return type, or NULL to ignore.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getTypedMethod(Class<?> clazz, String methodName, Class<?> returnType, Class<?>... params) {
|
||||
for (final Method method : clazz.getDeclaredMethods()) {
|
||||
if ((methodName == null || method.getName().equals(methodName))
|
||||
&& (returnType == null || method.getReturnType().equals(returnType))
|
||||
&& Arrays.equals(method.getParameterTypes(), params)) {
|
||||
method.setAccessible(true);
|
||||
|
||||
return new MethodInvoker() {
|
||||
|
||||
@Override
|
||||
public Object invoke(Object target, Object... arguments) {
|
||||
try {
|
||||
return method.invoke(target, arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke method " + method, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
public static Method getMethod(final Class<?> cls, final String name, final int index) {
|
||||
int i = 0;
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getName().equals(name) && index == i++) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
// Search in every superclass
|
||||
if (clazz.getSuperclass() != null)
|
||||
return getMethod(clazz.getSuperclass(), methodName, params);
|
||||
|
||||
throw new IllegalStateException(String.format("Unable to find method %s (%s).", methodName, Arrays.asList(params)));
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined constructor of the given name and parameter count.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this constructor.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static ConstructorInvoker getConstructor(String className, Class<?>... params) {
|
||||
return getConstructor(getClass(className), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined constructor of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this constructor.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static ConstructorInvoker getConstructor(Class<?> clazz, Class<?>... params) {
|
||||
for (final Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||
if (Arrays.equals(constructor.getParameterTypes(), params)) {
|
||||
constructor.setAccessible(true);
|
||||
|
||||
return new ConstructorInvoker() {
|
||||
|
||||
@Override
|
||||
public Object invoke(Object... arguments) {
|
||||
try {
|
||||
return constructor.newInstance(arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke constructor " + constructor, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
public static Method getMethod(final Class<?> cls, final Class<?> returning, final int index) {
|
||||
int i = 0;
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getReturnType().equals(returning) && index == i++) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Unable to find constructor for %s (%s).", clazz, Arrays.asList(params)));
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class from its full name, without knowing its type on compile time.
|
||||
* <p>
|
||||
* This is useful when looking up fields by a NMS or OBC type.
|
||||
* <p>
|
||||
*
|
||||
* @param lookupName - the class name with variables.
|
||||
* @return The class.
|
||||
* @see {@link #getClass()} for more information.
|
||||
*/
|
||||
public static Class<Object> getUntypedClass(String lookupName) {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
Class<Object> clazz = (Class) getClass(lookupName);
|
||||
return clazz;
|
||||
public static Method getMethod(final Class<?> cls, final String name, final Class<?> returning) {
|
||||
int i = 0;
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getName().equals(name) && m.getReturnType().equals(returning)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class from its full name.
|
||||
* <p>
|
||||
* Strings enclosed with curly brackets - such as {TEXT} - will be replaced according to the following table:
|
||||
* <p>
|
||||
* <table border="1">
|
||||
* <tr>
|
||||
* <th>Variable</th>
|
||||
* <th>Content</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{nms}</td>
|
||||
* <td>Actual package name of net.minecraft.server.VERSION</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{obc}</td>
|
||||
* <td>Actual pacakge name of org.bukkit.craftbukkit.VERSION</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{version}</td>
|
||||
* <td>The current Minecraft package VERSION, if any.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param lookupName - the class name with variables.
|
||||
* @return The looked up class.
|
||||
* @throws IllegalArgumentException If a variable or class could not be found.
|
||||
*/
|
||||
public static Class<?> getClass(String lookupName) {
|
||||
return getCanonicalClass(expandVariables(lookupName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class in the net.minecraft.server.VERSION.* package.
|
||||
*
|
||||
* @param name - the name of the class, excluding the package.
|
||||
* @throws IllegalArgumentException If the class doesn't exist.
|
||||
*/
|
||||
public static Class<?> getMinecraftClass(String name) {
|
||||
return getCanonicalClass(NMS_PREFIX + "." + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class in the org.bukkit.craftbukkit.VERSION.* package.
|
||||
*
|
||||
* @param name - the name of the class, excluding the package.
|
||||
* @throws IllegalArgumentException If the class doesn't exist.
|
||||
*/
|
||||
public static Class<?> getCraftBukkitClass(String name) {
|
||||
return getCanonicalClass(OBC_PREFIX + "." + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class by its canonical name.
|
||||
*
|
||||
* @param canonicalName - the canonical name.
|
||||
* @return The class.
|
||||
*/
|
||||
private static Class<?> getCanonicalClass(String canonicalName) {
|
||||
try {
|
||||
return Class.forName(canonicalName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException("Cannot find " + canonicalName, e);
|
||||
public static Class<?>[] getSubClasses(final Class<?> cls) {
|
||||
if (cachedSubclasses.containsKey(cls)) {
|
||||
return cachedSubclasses.get(cls);
|
||||
} else {
|
||||
final Class<?>[] subclasses = cls.getDeclaredClasses();
|
||||
cachedSubclasses.put(cls, subclasses);
|
||||
return subclasses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand variables such as "{nms}" and "{obc}" to their corresponding packages.
|
||||
*
|
||||
* @param name - the full name of the class.
|
||||
* @return The expanded string.
|
||||
*/
|
||||
private static String expandVariables(String name) {
|
||||
StringBuffer output = new StringBuffer();
|
||||
Matcher matcher = MATCH_VARIABLE.matcher(name);
|
||||
|
||||
while (matcher.find()) {
|
||||
String variable = matcher.group(1);
|
||||
String replacement = "";
|
||||
|
||||
// Expand all detected variables
|
||||
if ("nms".equalsIgnoreCase(variable))
|
||||
replacement = NMS_PREFIX;
|
||||
else if ("obc".equalsIgnoreCase(variable))
|
||||
replacement = OBC_PREFIX;
|
||||
else if ("version".equalsIgnoreCase(variable))
|
||||
replacement = VERSION;
|
||||
else
|
||||
throw new IllegalArgumentException("Unknown variable: " + variable);
|
||||
|
||||
// Assume the expanded variables are all packages, and append a dot
|
||||
if (replacement.length() > 0 && matcher.end() < name.length() && name.charAt(matcher.end()) != '.')
|
||||
replacement += ".";
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(replacement));
|
||||
public static Class<?> getSubClass(final Class<?> cls, final String name) {
|
||||
for (final Class<?> subclass : getSubClasses(cls)) {
|
||||
if (subclass.getSimpleName().equals(name)) {
|
||||
return subclass;
|
||||
}
|
||||
}
|
||||
|
||||
matcher.appendTail(output);
|
||||
return output.toString();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for invoking a specific constructor.
|
||||
*/
|
||||
public interface ConstructorInvoker {
|
||||
/**
|
||||
* Invoke a constructor for a specific class.
|
||||
*
|
||||
* @param arguments - the arguments to pass to the constructor.
|
||||
* @return The constructed object.
|
||||
*/
|
||||
Object invoke(Object... arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for invoking a specific method.
|
||||
*/
|
||||
public interface MethodInvoker {
|
||||
/**
|
||||
* Invoke a method on a specific target object.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static method.
|
||||
* @param arguments - the arguments to pass to the method.
|
||||
* @return The return value, or NULL if is void.
|
||||
*/
|
||||
Object invoke(Object target, Object... arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for retrieving the field content.
|
||||
*
|
||||
* @param <T> - field type.
|
||||
*/
|
||||
public interface FieldAccessor<T> {
|
||||
/**
|
||||
* Retrieve the content of a field.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static field.
|
||||
* @return The value of the field.
|
||||
*/
|
||||
T get(Object target);
|
||||
|
||||
/**
|
||||
* Set the content of a field.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static field.
|
||||
* @param value - the new value of the field.
|
||||
*/
|
||||
void set(Object target, Object value);
|
||||
|
||||
/**
|
||||
* Determine if the given object has this field.
|
||||
*
|
||||
* @param target - the object to test.
|
||||
* @return TRUE if it does, FALSE otherwise.
|
||||
*/
|
||||
boolean hasField(Object target);
|
||||
public static Class<?> getSubClass(final Class<?> cls, final int index) {
|
||||
final Class<?>[] subclasses = getSubClasses(cls);
|
||||
for (int i = 0; i < index + 1; i++) {
|
||||
final Class<?> c = subclasses[i];
|
||||
if (i == index) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
public class FieldWithIndex {
|
||||
private final Class<?> cls;
|
||||
private final int index;
|
||||
|
||||
public FieldWithIndex(Class<?> cls, int index) {
|
||||
this.cls = cls;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
public class FieldWithName {
|
||||
|
||||
private final Class<?> cls;
|
||||
private final String name;
|
||||
public FieldWithName(Class<?> cls, String name) {
|
||||
this.cls = cls;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
public class FieldWithTypeAndIndex {
|
||||
private final Class<?> cls, type;
|
||||
private final int index;
|
||||
|
||||
public FieldWithTypeAndIndex(Class<?> cls, Class<?> type, int index) {
|
||||
this.cls = cls;
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.methoddata;
|
||||
|
||||
public class MethodWithIndexAndParams {
|
||||
private final Class<?> cls;
|
||||
private final int index;
|
||||
private final Class<?>[] params;
|
||||
|
||||
public MethodWithIndexAndParams(Class<?> cls, int index, Class<?>[] params) {
|
||||
this.cls = cls;
|
||||
this.index = index;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public Class<?> getCls() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public Class<?>[] getParams() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
|
||||
public class BlockIteratorUtils {
|
||||
public static Block getBlockLookingAt(final Player player, final int distance) {
|
||||
final Location location = player.getEyeLocation();
|
||||
final BlockIterator blocksToAdd = new BlockIterator(location, 0.0D, distance);
|
||||
Block block = null;
|
||||
while(blocksToAdd.hasNext()) {
|
||||
block = blocksToAdd.next();
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
@@ -16,21 +16,15 @@ import java.lang.reflect.Method;
|
||||
|
||||
public final class NMSUtils {
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
|
||||
|
||||
public static final String nettyPrefix = version.isLowerThan(ServerVersion.v_1_8) ? "net.minecraft.util.io.netty" : "io.netty";
|
||||
private static final String nmsDir = ServerVersion.getNMSDirectory();
|
||||
private static final String obcDir = ServerVersion.getOBCDirectory();
|
||||
|
||||
public static Class<?> minecraftServerClass, craftWorldsClass,
|
||||
packetClass, entityPlayerClass, playerConnectionClass,
|
||||
craftPlayerClass, serverConnectionClass, craftEntityClass,
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
private static Method getServerMethod, getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
|
||||
private static Field recentTPSField, entityPlayerPingField, playerConnectionField;
|
||||
public static final Reflection.FieldAccessor<?> networkManagerFieldAccesssor, channelFieldAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -71,9 +65,6 @@ public final class NMSUtils {
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
networkManagerFieldAccesssor = Reflection.getField(playerConnectionClass, networkManagerClass, 0);
|
||||
channelFieldAccessor = Reflection.getField(networkManagerClass, nettyChannelClass, 0);
|
||||
}
|
||||
|
||||
public static Object getMinecraftServerInstance() throws InvocationTargetException, IllegalAccessException {
|
||||
@@ -142,7 +133,7 @@ public final class NMSUtils {
|
||||
|
||||
public static Object getPlayerConnection(final Player player) {
|
||||
try {
|
||||
return playerConnectionField.get( getEntityPlayer(player));
|
||||
return playerConnectionField.get(getEntityPlayer(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -150,11 +141,21 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Object getNetworkManager(final Player player) {
|
||||
return networkManagerFieldAccesssor.get(getPlayerConnection(player));
|
||||
try {
|
||||
return Reflection.getField(playerConnectionClass, networkManagerClass, 0).get(getPlayerConnection(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getChannel(final Player player) {
|
||||
return channelFieldAccessor.get(getNetworkManager(player));
|
||||
try {
|
||||
return Reflection.getField(networkManagerClass, nettyChannelClass, 0).get(getNetworkManager(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getPlayerPing(final Player player) {
|
||||
|
||||
Reference in new issue
Block a user