Skip to content

Commit

Permalink
Fix UseEntityCallback.EVENT not triggered
Browse files Browse the repository at this point in the history
  • Loading branch information
Mgazul committed Jan 26, 2025
1 parent 1f0072d commit a1cd459
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
package com.mohistmc.banner.eventhandler.dispatcher;

import com.mohistmc.banner.bukkit.BukkitSnapshotCaptures;
import com.mojang.datafixers.util.Pair;
import io.izzel.arclight.mixin.DecorationOps;
import java.util.Arrays;
import java.util.stream.Collectors;
import net.fabricmc.fabric.api.entity.event.v1.EntitySleepEvents;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.animal.Bucketable;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ExplosionDamageCalculator;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;

public class PlayerEventDispatcher {

Expand All @@ -26,10 +44,49 @@ public static void dispatcherPlayer() {
}
});
UseEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> {
ItemStack heldStack = player.getUseItem();
if (!CraftEventFactory.handlePlayerShearEntityEvent(player, entity, heldStack, hand)) {
return InteractionResult.PASS;
if (hitResult == null) return InteractionResult.PASS;
if (player instanceof ServerPlayer serverPlayer) {
PlayerInteractEntityEvent event;
Vec3 vec3 = hitResult.getLocation();
if (vec3 != null) {
event = new PlayerInteractAtEntityEvent((Player) serverPlayer.getBukkitEntity(), entity.getBukkitEntity(),
new org.bukkit.util.Vector(vec3.x, vec3.y, vec3.z), (hand == InteractionHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND);
} else {
event = new PlayerInteractEntityEvent((Player) serverPlayer.getBukkitEntity(), entity.getBukkitEntity(), (hand == InteractionHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND);
}
ItemStack itemInHand = serverPlayer.getItemInHand(hand);
boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob;
Item origItem = serverPlayer.getInventory().getSelected() == null ? null : serverPlayer.getInventory().getSelected().getItem();
Bukkit.getPluginManager().callEvent(event);

// Fish bucket - SPIGOT-4048
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || serverPlayer.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
serverPlayer.connection.send(new ClientboundAddEntityPacket(entity));
player.containerMenu.sendAllDataToRemote();
}

if (triggerLeashUpdate && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
// Refresh the current leash state
serverPlayer.connection.send(new ClientboundSetEntityLinkPacket(entity, ((Mob) entity).getLeashHolder()));
}

if (event.isCancelled() || serverPlayer.getInventory().getSelected() == null || serverPlayer.getInventory().getSelected().getItem() != origItem) {
// Refresh the current entity metadata
entity.getEntityData().refresh(serverPlayer);
if (entity instanceof Allay) {
serverPlayer.connection.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
serverPlayer.containerMenu.sendAllDataToRemote();
}
}

if (event.isCancelled()) {
return InteractionResult.PASS;
}
if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
serverPlayer.containerMenu.sendAllDataToRemote();
}
}

return InteractionResult.PASS;
});
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import com.mohistmc.banner.bukkit.BukkitSnapshotCaptures;
import com.mohistmc.banner.injection.server.network.InjectionServerGamePacketListenerImpl;
import com.mojang.brigadier.ParseResults;
import com.mojang.datafixers.util.Pair;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -18,9 +16,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import net.minecraft.ChatFormatting;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.commands.CommandSigningContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
Expand All @@ -38,15 +34,12 @@
import net.minecraft.network.chat.SignedMessageChain;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketUtils;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundDisconnectPacket;
import net.minecraft.network.protocol.game.ClientboundMoveVehiclePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket;
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
import net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundSystemChatPacket;
import net.minecraft.network.protocol.game.ServerGamePacketListener;
import net.minecraft.network.protocol.game.ServerboundAcceptTeleportationPacket;
Expand All @@ -57,7 +50,6 @@
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
import net.minecraft.network.protocol.game.ServerboundEditBookPacket;
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.network.protocol.game.ServerboundMoveVehiclePacket;
import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket;
Expand All @@ -79,26 +71,18 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.FilteredText;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.ServerGamePacketListenerImpl.EntityInteraction;
import net.minecraft.server.players.PlayerList;
import net.minecraft.util.FutureChain;
import net.minecraft.util.Mth;
import net.minecraft.util.StringUtil;
import net.minecraft.world.Container;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.RelativeMovement;
import net.minecraft.world.entity.animal.Bucketable;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.ChatVisiblity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MerchantMenu;
import net.minecraft.world.inventory.RecipeBookMenu;
Expand Down Expand Up @@ -145,8 +129,6 @@
import org.bukkit.event.player.PlayerAnimationType;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
Expand All @@ -158,7 +140,6 @@
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.SmithingInventory;
import org.jetbrains.annotations.Nullable;
Expand All @@ -181,7 +162,6 @@
@Mixin(ServerGamePacketListenerImpl.class)
public abstract class MixinServerGamePacketListenerImpl implements InjectionServerGamePacketListenerImpl {

@Shadow @Final public static double MAX_INTERACTION_DISTANCE;
@Shadow public ServerPlayer player;
@Mutable
@Shadow @Final private FutureChain chatMessageChain;
Expand Down Expand Up @@ -242,7 +222,6 @@ public abstract class MixinServerGamePacketListenerImpl implements InjectionServ
@Shadow protected abstract CompletableFuture<FilteredText> filterTextPacket(String text);
@Shadow protected abstract ParseResults<CommandSourceStack> parseCommand(String command);
@Shadow protected abstract Map<String, PlayerChatMessage> collectSignedArguments(ServerboundChatCommandPacket packet, SignableCommand<?> command, LastSeenMessages lastSeenMessages) throws SignedMessageChain.DecodeException;
@Shadow protected abstract void detectRateSpam();

@Shadow private int dropSpamTickCount;
@Shadow private int awaitingTeleport;
Expand Down Expand Up @@ -1380,121 +1359,6 @@ public boolean isDisconnected() {
}
}

/**
* @author wdog5
* @reason
*/
@Overwrite
public void handleInteract(ServerboundInteractPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, (ServerGamePacketListenerImpl) (Object) this, this.player.serverLevel());
if (this.player.isImmobile()) return; // CraftBukkit
final ServerLevel serverLevel = this.player.serverLevel();
final Entity entity = packet.getTarget(serverLevel);
if (entity == player && !player.isSpectator()) {
disconnect("Cannot interact with self!");
return;
}
this.player.resetLastActionTime();
this.player.setShiftKeyDown(packet.isUsingSecondaryAction());
if (entity != null) {
if (!serverLevel.getWorldBorder().isWithinBounds(entity.blockPosition())) {
return;
}
AABB aABB = entity.getBoundingBox();
class Handler implements ServerboundInteractPacket.Handler {

private void performInteraction(InteractionHand hand, EntityInteraction interaction, PlayerInteractEntityEvent event) { // CraftBukkit
var stack = player.getItemInHand(hand);

if (stack.isItemEnabled(serverLevel.enabledFeatures())) {
ItemStack itemstack = stack.copy();
// CraftBukkit start
ItemStack itemInHand = player.getItemInHand(hand);
boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob;
Item origItem = player.getInventory().getSelected() == null ? null : player.getInventory().getSelected().getItem();
Bukkit.getPluginManager().callEvent(event);

// Fish bucket - SPIGOT-4048
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
send(new ClientboundAddEntityPacket((LivingEntity) entity));
player.containerMenu.sendAllDataToRemote();
}

if (triggerLeashUpdate && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) {
// Refresh the current leash state
send(new ClientboundSetEntityLinkPacket(entity, ((Mob) entity).getLeashHolder()));
}

if (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem) {
// Refresh the current entity metadata
entity.getEntityData().refresh(player);
if (entity instanceof Allay) {
send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
player.containerMenu.sendAllDataToRemote();
}
}

if (event.isCancelled()) {
return;
}
// CraftBukkit end

InteractionResult enuminteractionresult = interaction.run(player, entity, hand);

// CraftBukkit start
if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
player.containerMenu.sendAllDataToRemote();
}
// CraftBukkit end

if (enuminteractionresult.consumesAction()) {
CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(player, itemstack, entity);
if (enuminteractionresult.shouldSwing()) {
player.swing(hand, true);
}
}
}

}

@Override
public void onInteraction(InteractionHand hand) {
this.performInteraction(hand, net.minecraft.world.entity.player.Player::interactOn,
new PlayerInteractEntityEvent(getCraftPlayer(), entity.getBukkitEntity(),
(hand == InteractionHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
}

@Override
public void onInteraction(InteractionHand hand, Vec3 vec) {
this.performInteraction(hand, (serverPlayer, entityx, interactionHand) -> {
return entityx.interactAt(serverPlayer, vec, interactionHand);
}, new PlayerInteractAtEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(vec.x, vec.y, vec.z), (hand == InteractionHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
}

@Override
public void onAttack() {
if (!(entity instanceof ItemEntity) && !(entity instanceof ExperienceOrb) && !(entity instanceof AbstractArrow) && (entity != player || player.isSpectator())) {
ItemStack itemStack = player.getMainHandItem();
if (itemStack.isItemEnabled(serverLevel.enabledFeatures())) {
player.attack(entity);
// CraftBukkit start
if (!itemStack.isEmpty() && itemStack.getCount() <= -1) {
player.containerMenu.sendAllDataToRemote();
}
// CraftBukkit end
}
} else {
disconnect(Component.translatable("multiplayer.disconnect.invalid_entity_attacked"));
LOGGER.warn("Player {} tried to attack an invalid entity", player.getName().getString());
}
}
}
if (aABB.distanceToSqr(this.player.getEyePosition()) < MAX_INTERACTION_DISTANCE) {
packet.dispatch(new Handler());
}
}
}

@Inject(method = "handleContainerClose", cancellable = true,
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;doCloseContainer()V"))
private void banner$invClose(ServerboundContainerClosePacket packetIn, CallbackInfo ci) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.mohistmc.banner.mixin.world.entity.animal;

import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.animal.MushroomCow;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.bukkit.craftbukkit.v1_20_R1.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(MushroomCow.class)
public abstract class MixinMushroomCow extends Animal {

protected MixinMushroomCow(EntityType<? extends Animal> entityType, Level level) {
super(entityType, level);
}

@Inject(method = "mobInteract", require = 0, cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/MushroomCow;shear(Lnet/minecraft/sounds/SoundSource;)V"))
private void banner$shear(Player player, InteractionHand hand, CallbackInfoReturnable<InteractionResult> cir, ItemStack stack) {
if (!CraftEventFactory.handlePlayerShearEntityEvent(player, (Entity) (Object) this, stack, hand)) {
cir.setReturnValue(InteractionResult.PASS);
}
}
}
Loading

0 comments on commit a1cd459

Please sign in to comment.