Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import com.github.retrooper.packetevents.util.TimeStampMode;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientAttack;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
Expand Down Expand Up @@ -382,31 +383,47 @@ public NpcUsePacketAdapter(@NotNull Platform<World, Player, ItemStack, Plugin> p

@Override
public void onPacketPlayReceive(@NotNull PacketPlayReceiveEvent event) {
// check for an entity use packet
Object player = event.getPlayer();
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {

int entityId;
InteractNpcEvent.Hand hand = null;
WrapperPlayClientInteractEntity.InteractAction action;

if (event.getPacketType() == PacketType.Play.Client.ATTACK) {
WrapperPlayClientAttack packet = new WrapperPlayClientAttack(event);
action = WrapperPlayClientInteractEntity.InteractAction.ATTACK;
entityId = packet.getEntityId();
} else if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
entityId = packet.getEntityId();
hand = Lazy.HAND_CONVERTER.get(packet.getHand());

action = packet.getAction();
if (packet.getServerVersion().isNewerThanOrEquals(ServerVersion.V_26_1)) {
action = WrapperPlayClientInteractEntity.InteractAction.INTERACT;
}
} else {
return;
}

// get the associated npc from the tracked entities
Npc<World, Player, ItemStack, Plugin> npc = this.platform.npcTracker().npcById(packet.getEntityId());
if (npc != null) {
// call the event
switch (packet.getAction()) {
case ATTACK:
this.platform.eventManager().post(DefaultAttackNpcEvent.attackNpc(npc, player));
break;
case INTERACT:
InteractNpcEvent.Hand hand = Lazy.HAND_CONVERTER.get(packet.getHand());
this.platform.eventManager().post(DefaultInteractNpcEvent.interactNpc(npc, player, hand));
break;
default:
// we don't handle INTERACT_AT as the client sends it alongside the interact packet (duplicate event call)
break;
}

// don't pass the packet to the server
event.setCancelled(true);
// get the associated npc from the tracked entities
Npc<World, Player, ItemStack, Plugin> npc = this.platform.npcTracker().npcById(entityId);
if (npc != null) {
// call the event
switch (action) {
case ATTACK:
this.platform.eventManager().post(DefaultAttackNpcEvent.attackNpc(npc, player));
break;
case INTERACT:
this.platform.eventManager().post(DefaultInteractNpcEvent.interactNpc(npc, player, hand));
break;
default:
// we don't handle INTERACT_AT as the client sends it alongside the interact packet
break;
}

// don't pass the packet to the server
event.setCancelled(true);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,10 @@ private static final class NpcUsePacketAdapter extends PacketAdapter {
private final Platform<World, Player, ItemStack, Plugin> platform;

public NpcUsePacketAdapter(@NotNull Platform<World, Player, ItemStack, Plugin> platform) {
super(PacketAdapter.params(platform.extension(), PacketType.Play.Client.USE_ENTITY).optionAsync());
super(PacketAdapter.params(
platform.extension(),
PacketType.Play.Client.USE_ENTITY,
PacketType.Play.Client.ATTACK).optionAsync());
this.platform = platform;
}

Expand All @@ -590,7 +593,16 @@ public void onPacketReceiving(@NotNull PacketEvent event) {
EnumWrappers.EntityUseAction action;
EnumWrappers.Hand hand = EnumWrappers.Hand.MAIN_HAND;

if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
if (MinecraftVersion.v26_1.atOrAbove()) {
// mc 26.1: action does not exist anymore as there are two separate packets
if (packet.getType() == PacketType.Play.Client.ATTACK) {
// attack packets always result in an attack action with the main hand
action = EnumWrappers.EntityUseAction.ATTACK;
} else {
action = EnumWrappers.EntityUseAction.INTERACT;
hand = packet.getHands().read(0);
}
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
// mc 1.17: hand & action are now in an internal wrapper class
WrappedEnumEntityUseAction useAction = packet.getEnumEntityUseActions().read(0);
action = useAction.getAction();
Expand Down
6 changes: 3 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ netty = "4.1.117.Final"

# platform api versions
sponge = "10.0.0"
paper = "1.21.11-R0.1-SNAPSHOT"
paper = "26.1.1.build.29-alpha"
minestom = "2026.03.03-1.21.11"

# fabric
Expand All @@ -24,8 +24,8 @@ fabricLoader = "0.18.4"
fabricApi = "0.141.3+1.21.11"

# platform extensions
packetEvents = "2.11.2"
protocolLib = "9417eee444"
packetEvents = "2.13.0"
protocolLib = "8eeb82f89d"


[libraries]
Expand Down
Loading