Skip to content

Instantly share code, notes, and snippets.

@WesJD
Last active February 4, 2017 20:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WesJD/80b10ca18db6adff22b0cb3d63c5ea09 to your computer and use it in GitHub Desktop.
Save WesJD/80b10ca18db6adff22b0cb3d63c5ea09 to your computer and use it in GitHub Desktop.
public class PayloadAdapter extends PacketAdapter {
private static final Method ARRAY_METHOD;
static {
try {
ARRAY_METHOD = Class.forName("io.netty.buffer.UnpooledHeapByteBuf").getMethod("array");
} catch (NoSuchMethodException | ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
}
private final Map<String, Class<? extends Payload>> channels = new HashMap<>();
private final PayloadDirection direction;
public PayloadAdapter(Plugin plugin, PayloadDirection direction) {
super(plugin, ListenerPriority.NORMAL, direction.getPayloadPacket());
this.direction = direction;
}
public void bind(Class<? extends Payload> payload, String... channels) {
Arrays.stream(channels).forEach(channel -> this.channels.put(channel, payload));
}
private Payload newPayload(String channel, byte[] bytes) {
try {
final Class<? extends Payload> clazz = channels.getOrDefault(channel, Payload.class);
if (!clazz.equals(Payload.class)) return clazz.getConstructor(byte[].class).newInstance((Object) bytes);
else return clazz.getConstructor(byte[].class, BiFunction.class).newInstance(bytes, (BiFunction<ByteBuffer, Integer, Object>) (buffer, index) -> null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException ex) {
throw new RuntimeException(ex);
}
}
private void handleInternal(PacketEvent event) {
try {
final PacketContainer container = event.getPacket();
final String channel = container.getStrings().readSafely(0);
final byte[] bytes = (byte[]) ARRAY_METHOD.invoke(container.getModifier().readSafely(1));
Bukkit.getPluginManager().callEvent(new PayloadInOutEvent(event.getPlayer(), direction, channel, newPayload(channel, bytes)));
} catch (IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
@Override
public void onPacketSending(PacketEvent event) {
if(direction == PayloadDirection.SERVERBOUND) handleInternal(event);
}
@Override
public void onPacketReceiving(PacketEvent event) {
if(direction == PayloadDirection.CLIENTBOUND) handleInternal(event);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment