Skip to content

Instantly share code, notes, and snippets.

@WizardlyBump17
Last active June 15, 2022 00:22
Show Gist options
  • Save WizardlyBump17/61118dd9c14bb30e58aac46bce145f33 to your computer and use it in GitHub Desktop.
Save WizardlyBump17/61118dd9c14bb30e58aac46bce145f33 to your computer and use it in GitHub Desktop.
Simple packet listener for 1.17.1
@RequiredArgsConstructor
public class Example extends PacketListener {
private static final java.lang.Class<?> CLAZZ;
static {
try {
CLAZZ = java.lang.Class.forName("net.minecraft.network.protocol.game.PacketPlayInUseEntity$d");
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
private final OmgCoolPlugin plugin;
@Override
public void onReceive(PacketEvent event) {
Player player = event.getPlayer();
if (!(event.getPacket() instanceof PacketPlayInUseEntity packet) || !plugin.getPacketListenerPlayers().contains(player))
return;
Bukkit.getScheduler().runTask(plugin, () -> {
try {
World world = player.getWorld();
net.minecraft.world.entity.Entity entity = packet.a(((CraftWorld) world).getHandle());
if (entity == null)
return;
Field bField = packet.getClass().getDeclaredField("b");
bField.setAccessible(true);
Object object = bField.get(packet);
if (!CLAZZ.isInstance(object))
return;
Field aField = object.getClass().getDeclaredField("a");
aField.setAccessible(true);
EnumHand hand = (EnumHand) aField.get(object);
if (hand != EnumHand.a)
return;
Configuration.getNPC(entity.getBukkitEntity()).ifPresent(npc -> Bukkit.getPluginManager().callEvent(new PlayerInteractEntityEvent(player, entity.getBukkitEntity())));
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@Data
public class PacketEvent {
private final Packet<?> packet;
private final Player player;
private boolean cancelled;
}
@RequiredArgsConstructor
@Getter
public class PacketHandler extends ChannelDuplexHandler {
private final PacketInjector injector;
private final Player player;
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (!(msg instanceof Packet<?> packet)) {
super.write(ctx, msg, promise);
return;
}
PacketEvent event = new PacketEvent(packet, player);
injector.callSend(event);
if (!event.isCancelled())
super.write(ctx, msg, promise);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (!(msg instanceof Packet<?> packet)) {
super.channelRead(ctx, msg);
return;
}
PacketEvent event = new PacketEvent(packet, player);
injector.callReceive(event);
if (!event.isCancelled())
super.channelRead(ctx, msg);
}
public class PacketInjector {
private final List<PacketListener> listeners = new ArrayList<>();
public void addPlayer(Player player) {
ChannelPipeline pipeline = ((CraftPlayer) player).getHandle().b.a.k.pipeline();
if (pipeline.get("PacketInjector") == null)
pipeline.addBefore("packet_handler", "PacketInjector", new PacketHandler(this, player));
}
public void removePlayer(Player player) {
ChannelPipeline pipeline = ((CraftPlayer) player).getHandle().b.a.k.pipeline();
if (pipeline.get("PacketInjector") != null)
pipeline.remove("PacketInjector"); //baka
}
public void addListener(PacketListener listener) {
listeners.add(listener);
}
public void callReceive(PacketEvent event) {
for (PacketListener listener : listeners)
listener.onReceive(event);
}
public void callSend(PacketEvent event) {
for (PacketListener listener : listeners)
listener.onSend(event);
}
}
public abstract class PacketListener {
/**
* Called when a packet is received from the client, when the packet is SENT TO THE SERVER
* @param event the event
*/
public void onReceive(PacketEvent event) {
}
/**
* Called when a packet is sent to the client, when the packet is SENT TO THE PLAYER
* @param event the event
*/
public void onSend(PacketEvent event) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment