Search in sources :

Example 1 with CPacketUseEntity

use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.

the class MixinNetHandlerPlayServer method processUseEntity.

/**
 * @author blood - April 5th, 2016
 *
 * @reason Due to all the changes we now do for this packet, it is much easier
 * to read it all with an overwrite. Information detailing on why each change
 * was made can be found in comments below.
 *
 * @param packetIn The entity use packet
 */
@Overwrite
public void processUseEntity(CPacketUseEntity packetIn) {
    // All packets received by server are handled first on the Netty Thread
    if (!SpongeImpl.getServer().isCallingFromMinecraftThread()) {
        if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT) {
            // when INTERACT_AT does not return a successful result.
            return;
        } else {
            // queue packet for main thread
            PacketThreadUtil.checkThreadAndEnqueue(packetIn, (NetHandlerPlayServer) (Object) this, this.player.getServerWorld());
            return;
        }
    }
    // Sponge end
    WorldServer worldserver = this.serverController.getWorld(this.player.dimension);
    Entity entity = packetIn.getEntityFromWorld(worldserver);
    this.player.markPlayerActive();
    if (entity != null) {
        boolean flag = this.player.canEntityBeSeen(entity);
        // 6 blocks
        double d0 = 36.0D;
        if (!flag) {
            // 1.5 blocks
            d0 = 9.0D;
        }
        if (this.player.getDistanceSq(entity) < d0) {
            if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) {
                // Sponge start - Fire interact events
                EnumHand hand = packetIn.getHand();
                ItemStack itemstack = hand != null ? this.player.getHeldItem(hand) : ItemStack.EMPTY;
                Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(itemstack));
                SpongeCommonEventFactory.lastSecondaryPacketTick = this.serverController.getTickCounter();
                // Is interaction allowed with item in hand
                if (SpongeCommonEventFactory.callInteractItemEventSecondary(this.player, itemstack, hand, VecHelper.toVector3d(packetIn.getHitVec()), entity).isCancelled() || SpongeCommonEventFactory.callInteractEntityEventSecondary(this.player, entity, hand, VecHelper.toVector3d(entity.getPositionVector().add(packetIn.getHitVec()))).isCancelled()) {
                    // Restore held item in hand
                    int index = ((IMixinInventoryPlayer) this.player.inventory).getHeldItemIndex(hand);
                    Slot slot = this.player.openContainer.getSlotFromInventory(this.player.inventory, index);
                    sendPacket(new SPacketSetSlot(this.player.openContainer.windowId, slot.slotNumber, itemstack));
                    // which means that we need to force an update
                    if (itemstack.getItem() == Items.LEAD) {
                        // Detach entity again
                        sendPacket(new SPacketEntityAttach(entity, null));
                    } else {
                        // Other cases may involve a specific DataParameter of the entity
                        // We fix the client state by marking it as dirty so it will be updated on the client the next tick
                        DataParameter<?> parameter = findModifiedEntityInteractDataParameter(itemstack, entity);
                        if (parameter != null) {
                            entity.getDataManager().setDirty(parameter);
                        }
                    }
                    return;
                }
                // If INTERACT_AT is not successful, run the INTERACT logic
                if (entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), hand) != EnumActionResult.SUCCESS) {
                    this.player.interactOn(entity, hand);
                }
            // Sponge end
            } else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) {
                // Sponge start - Call interact event
                // Will be null in the packet during ATTACK
                EnumHand hand = EnumHand.MAIN_HAND;
                ItemStack itemstack = this.player.getHeldItem(hand);
                SpongeCommonEventFactory.lastPrimaryPacketTick = this.serverController.getTickCounter();
                Vector3d hitVec = null;
                if (packetIn.getHitVec() == null) {
                    final RayTraceResult result = SpongeImplHooks.rayTraceEyes(player, SpongeImplHooks.getBlockReachDistance(player));
                    hitVec = result == null ? null : VecHelper.toVector3d(result.hitVec);
                }
                if (SpongeCommonEventFactory.callInteractItemEventPrimary(this.player, itemstack, hand, hitVec, entity).isCancelled()) {
                    ((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
                    return;
                }
                if (entity instanceof EntityItem || entity instanceof EntityXPOrb || entity instanceof EntityArrow || entity == this.player) {
                    this.disconnect(new TextComponentTranslation("multiplayer.disconnect.invalid_entity_attacked"));
                    this.serverController.logWarning("Player " + this.player.getName() + " tried to attack an invalid entity");
                    return;
                }
                // Sponge start
                if (entity instanceof Player && !((World) this.player.world).getProperties().isPVPEnabled()) {
                    // PVP is disabled, ignore
                    return;
                }
                if (SpongeCommonEventFactory.callInteractEntityEventPrimary(this.player, entity, hand, hitVec).isCancelled()) {
                    ((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
                    return;
                }
                // Sponge end
                this.player.attackTargetEntityWithCurrentItem(entity);
            }
        }
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(net.minecraft.entity.Entity) EntityArrow(net.minecraft.entity.projectile.EntityArrow) TextComponentTranslation(net.minecraft.util.text.TextComponentTranslation) Player(org.spongepowered.api.entity.living.player.Player) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityPlayer(net.minecraft.entity.player.EntityPlayer) CPacketPlayer(net.minecraft.network.play.client.CPacketPlayer) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) RayTraceResult(net.minecraft.util.math.RayTraceResult) WorldServer(net.minecraft.world.WorldServer) World(org.spongepowered.api.world.World) SPacketEntityAttach(net.minecraft.network.play.server.SPacketEntityAttach) IMixinInventoryPlayer(org.spongepowered.common.interfaces.entity.player.IMixinInventoryPlayer) Vector3d(com.flowpowered.math.vector.Vector3d) EnumHand(net.minecraft.util.EnumHand) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) Slot(net.minecraft.inventory.Slot) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) EntityItem(net.minecraft.entity.item.EntityItem) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 2 with CPacketUseEntity

use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.

the class AttackEntityPacketState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final EntityPlayerMP player = context.getPacketPlayer();
    final CPacketUseEntity useEntityPacket = context.getPacket();
    final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
    if (entity == null) {
        // Something happened?
        return;
    }
    final World spongeWorld = EntityUtil.getSpongeWorld(player);
    EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
    context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
        // For destruction, this should be empty, however, some
        // times,
        // it may not be?
        final PrettyPrinter printer = new PrettyPrinter(60);
        printer.add("Processing Attack Entity").centre().hr();
        printer.add("There are some captured items after the entity was destructed!");
        printer.addWrapped(60, "%s : %s", "Items captured", items);
        printer.add("Stacktrace:");
        printer.add(new Exception("Stack trace"));
        printer.trace(System.err, SpongeImpl.getLogger(), Level.TRACE);
    });
    context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(blocks -> TrackingUtil.processBlockCaptures(blocks, this, context));
    context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
        for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
            final UUID key = entry.getKey();
            final Optional<Entity> affectedEntity = spongeWorld.getEntity(key);
            if (!affectedEntity.isPresent()) {
                continue;
            }
            final Collection<ItemDropData> itemStacks = entry.getValue();
            if (itemStacks.isEmpty()) {
                return;
            }
            final List<ItemDropData> items = new ArrayList<>(itemStacks);
            if (!items.isEmpty()) {
                try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                    final List<Entity> itemEntities = items.stream().map(data -> data.create(((WorldServer) player.world))).map(EntityUtil::fromNative).collect(Collectors.toList());
                    Sponge.getCauseStackManager().pushCause(player);
                    Sponge.getCauseStackManager().pushCause(affectedEntity.get());
                    Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
                    final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), itemEntities);
                    SpongeImpl.postEvent(destruct);
                    if (!destruct.isCancelled()) {
                        processSpawnedEntities(player, destruct);
                    }
                }
            }
        }
    });
    context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
        try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            Sponge.getCauseStackManager().pushCause(player);
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
            for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
                final UUID key = entry.getKey();
                final Optional<Entity> attackedEntities = spongeWorld.getEntity(key);
                if (!attackedEntities.isPresent()) {
                    continue;
                }
                final List<Entity> items = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
                SpongeImpl.postEvent(destruct);
                if (!destruct.isCancelled()) {
                    processSpawnedEntities(player, destruct);
                }
            }
        }
    });
}
Also used : CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) UUID(java.util.UUID) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map)

Example 3 with CPacketUseEntity

use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.

the class InteractAtEntityPacketState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final EntityPlayerMP player = context.getPacketPlayer();
    final CPacketUseEntity useEntityPacket = context.getPacket();
    final net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(player.world);
    if (entity == null) {
        // Something happened?
        return;
    }
    final World spongeWorld = EntityUtil.getSpongeWorld(player);
    EntityUtil.toMixin(entity).setNotifier(player.getUniqueID());
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PLACEMENT);
        context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
        context.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> items = entities.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), items);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                processSpawnedEntities(player, event);
            }
        });
        context.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
            final PrettyPrinter printer = new PrettyPrinter(80);
            printer.add("Processing Interact At Entity").centre().hr();
            printer.add("The item stacks captured are: ");
            for (Map.Entry<UUID, Collection<ItemDropData>> entry : map.asMap().entrySet()) {
                printer.add("  - Entity with UUID: %s", entry.getKey());
                for (ItemDropData stack : entry.getValue()) {
                    printer.add("    - %s", stack);
                }
            }
            printer.trace(System.err);
        });
        context.getCapturedEntityItemDropSupplier().acceptIfNotEmpty(map -> {
            for (Map.Entry<UUID, Collection<EntityItem>> entry : map.asMap().entrySet()) {
                final UUID entityUuid = entry.getKey();
                final net.minecraft.entity.Entity entityFromUuid = player.getServerWorld().getEntityFromUuid(entityUuid);
                if (entityFromUuid != null) {
                    final List<Entity> entities = entry.getValue().stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                    if (!entities.isEmpty()) {
                        DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                        SpongeImpl.postEvent(event);
                        if (!event.isCancelled()) {
                            processSpawnedEntities(player, event);
                        }
                    }
                }
            }
        });
        context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
            final List<EntityItem> items = drops.stream().map(drop -> drop.create(player.getServerWorld())).collect(Collectors.toList());
            final List<Entity> entities = items.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
            if (!entities.isEmpty()) {
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    processSpawnedEntities(player, event);
                }
            }
        });
    }
    context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(snapshots -> TrackingUtil.processBlockCaptures(snapshots, this, context));
}
Also used : SpongeImpl(org.spongepowered.common.SpongeImpl) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) ItemStack(org.spongepowered.api.item.inventory.ItemStack) TrackingUtil(org.spongepowered.common.event.tracking.TrackingUtil) Map(java.util.Map) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Nullable(javax.annotation.Nullable) EntityItem(net.minecraft.entity.item.EntityItem) Packet(net.minecraft.network.Packet) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) UUID(java.util.UUID) InternalSpawnTypes(org.spongepowered.common.registry.type.event.InternalSpawnTypes) Entity(org.spongepowered.api.entity.Entity) Collectors(java.util.stream.Collectors) EntityUtil(org.spongepowered.common.entity.EntityUtil) List(java.util.List) World(org.spongepowered.api.world.World) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) World(org.spongepowered.api.world.World) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) UUID(java.util.UUID) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) EntityItem(net.minecraft.entity.item.EntityItem)

Example 4 with CPacketUseEntity

use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.

the class InteractAtEntityPacketState method isPacketIgnored.

@Override
public boolean isPacketIgnored(Packet<?> packetIn, EntityPlayerMP packetPlayer) {
    final CPacketUseEntity useEntityPacket = (CPacketUseEntity) packetIn;
    // There are cases where a player is interacting with an entity that doesn't exist on the server.
    @Nullable net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(packetPlayer.world);
    return entity == null;
}
Also used : CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Nullable(javax.annotation.Nullable)

Example 5 with CPacketUseEntity

use of net.minecraft.network.play.client.CPacketUseEntity in project SpongeCommon by SpongePowered.

the class AttackEntityPacketState method isPacketIgnored.

@Override
public boolean isPacketIgnored(Packet<?> packetIn, EntityPlayerMP packetPlayer) {
    final CPacketUseEntity useEntityPacket = (CPacketUseEntity) packetIn;
    // There are cases where a player is interacting with an entity that
    // doesn't exist on the server.
    @Nullable net.minecraft.entity.Entity entity = useEntityPacket.getEntityFromWorld(packetPlayer.world);
    return entity == null;
}
Also used : CPacketUseEntity(net.minecraft.network.play.client.CPacketUseEntity) Nullable(javax.annotation.Nullable)

Aggregations

CPacketUseEntity (net.minecraft.network.play.client.CPacketUseEntity)9 Nullable (javax.annotation.Nullable)4 World (org.spongepowered.api.world.World)4 Collection (java.util.Collection)3 Map (java.util.Map)3 UUID (java.util.UUID)3 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)3 Entity (org.spongepowered.api.entity.Entity)3 CauseStackManager (org.spongepowered.api.event.CauseStackManager)3 ItemStack (org.spongepowered.api.item.inventory.ItemStack)3 PrettyPrinter (org.spongepowered.asm.util.PrettyPrinter)3 ItemDropData (org.spongepowered.common.event.tracking.context.ItemDropData)3 EntityItem (net.minecraft.entity.item.EntityItem)2 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)2 DropItemEvent (org.spongepowered.api.event.item.inventory.DropItemEvent)2 Vector3d (com.flowpowered.math.vector.Vector3d)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 Entity (net.minecraft.entity.Entity)1