Search in sources :

Example 1 with SPacketSetSlot

use of net.minecraft.network.play.server.SPacketSetSlot 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 SPacketSetSlot

use of net.minecraft.network.play.server.SPacketSetSlot in project SpongeCommon by SpongePowered.

the class MixinNetHandlerPlayServer method onPlayerDropItem.

@Nullable
@Redirect(method = "processPlayerDigging", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayerMP;dropItem(Z)Lnet/minecraft/entity/item/EntityItem;"))
public EntityItem onPlayerDropItem(EntityPlayerMP player, boolean dropAll) {
    EntityItem item = null;
    ItemStack stack = this.player.inventory.getCurrentItem();
    if (!stack.isEmpty()) {
        int size = stack.getCount();
        item = this.player.dropItem(dropAll);
        // force client itemstack update if drop event was cancelled
        if (item == null && ((IMixinEntityPlayer) player).shouldRestoreInventory()) {
            Slot slot = this.player.openContainer.getSlotFromInventory(this.player.inventory, this.player.inventory.currentItem);
            int windowId = this.player.openContainer.windowId;
            stack.setCount(size);
            this.sendPacket(new SPacketSetSlot(windowId, slot.slotNumber, stack));
        }
    }
    return item;
}
Also used : 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) Redirect(org.spongepowered.asm.mixin.injection.Redirect) Nullable(javax.annotation.Nullable)

Example 3 with SPacketSetSlot

use of net.minecraft.network.play.server.SPacketSetSlot in project SpongeCommon by SpongePowered.

the class MixinNetHandlerPlayServer method processCreativeInventoryAction.

/**
 * @author blood - June 6th, 2016
 * @author gabizou - June 20th, 2016 - Update for 1.9.4 and minor refactors.
 * @reason Since mojang handles creative packets different than survival, we need to
 * restructure this method to prevent any packets being sent to client as we will
 * not be able to properly revert them during drops.
 *
 * @param packetIn The creative inventory packet
 */
@Overwrite
public void processCreativeInventoryAction(CPacketCreativeInventoryAction packetIn) {
    PacketThreadUtil.checkThreadAndEnqueue(packetIn, (NetHandlerPlayServer) (Object) this, this.player.getServerWorld());
    if (this.player.interactionManager.isCreative()) {
        final PhaseData peek = PhaseTracker.getInstance().getCurrentPhaseData();
        final PacketContext<?> context = (PacketContext<?>) peek.context;
        final boolean ignoresCreative = context.getIgnoringCreative();
        boolean clickedOutside = packetIn.getSlotId() < 0;
        ItemStack itemstack = packetIn.getStack();
        if (!itemstack.isEmpty() && itemstack.hasTagCompound() && itemstack.getTagCompound().hasKey("BlockEntityTag", 10)) {
            NBTTagCompound nbttagcompound = itemstack.getTagCompound().getCompoundTag("BlockEntityTag");
            if (nbttagcompound.hasKey("x") && nbttagcompound.hasKey("y") && nbttagcompound.hasKey("z")) {
                BlockPos blockpos = new BlockPos(nbttagcompound.getInteger("x"), nbttagcompound.getInteger("y"), nbttagcompound.getInteger("z"));
                TileEntity tileentity = this.player.world.getTileEntity(blockpos);
                if (tileentity != null) {
                    NBTTagCompound nbttagcompound1 = new NBTTagCompound();
                    tileentity.writeToNBT(nbttagcompound1);
                    nbttagcompound1.removeTag("x");
                    nbttagcompound1.removeTag("y");
                    nbttagcompound1.removeTag("z");
                    itemstack.setTagInfo("BlockEntityTag", nbttagcompound1);
                }
            }
        }
        boolean clickedHotbar = packetIn.getSlotId() >= 1 && packetIn.getSlotId() <= 45;
        boolean itemValidCheck = itemstack.isEmpty() || itemstack.getMetadata() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
        // Sponge start - handle CreativeInventoryEvent
        if (itemValidCheck) {
            if (!ignoresCreative) {
                ClickInventoryEvent.Creative clickEvent = SpongeCommonEventFactory.callCreativeClickInventoryEvent(this.player, packetIn);
                if (clickEvent.isCancelled()) {
                    // Reset slot on client
                    if (packetIn.getSlotId() >= 0 && packetIn.getSlotId() < this.player.inventoryContainer.inventorySlots.size()) {
                        this.player.connection.sendPacket(new SPacketSetSlot(this.player.inventoryContainer.windowId, packetIn.getSlotId(), this.player.inventoryContainer.getSlot(packetIn.getSlotId()).getStack()));
                        this.player.connection.sendPacket(new SPacketSetSlot(-1, -1, ItemStack.EMPTY));
                    }
                    return;
                }
            }
            if (clickedHotbar) {
                if (itemstack.isEmpty()) {
                    this.player.inventoryContainer.putStackInSlot(packetIn.getSlotId(), ItemStack.EMPTY);
                } else {
                    this.player.inventoryContainer.putStackInSlot(packetIn.getSlotId(), itemstack);
                }
                this.player.inventoryContainer.setCanCraft(this.player, true);
            } else if (clickedOutside && this.itemDropThreshold < 200) {
                this.itemDropThreshold += 20;
                EntityItem entityitem = this.player.dropItem(itemstack, true);
                if (entityitem != null) {
                    entityitem.setAgeToCreativeDespawnTime();
                }
            }
        }
    // Sponge end
    }
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) TileEntity(net.minecraft.tileentity.TileEntity) PacketContext(org.spongepowered.common.event.tracking.phase.packet.PacketContext) BlockPos(net.minecraft.util.math.BlockPos) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) EntityItem(net.minecraft.entity.item.EntityItem) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 4 with SPacketSetSlot

use of net.minecraft.network.play.server.SPacketSetSlot in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callCraftEventPre.

public static CraftItemEvent.Preview callCraftEventPre(EntityPlayer player, CraftingInventory inventory, SlotTransaction previewTransaction, @Nullable CraftingRecipe recipe, Container container, List<SlotTransaction> transactions) {
    CraftItemEvent.Preview event = SpongeEventFactory.createCraftItemEventPreview(Sponge.getCauseStackManager().getCurrentCause(), inventory, previewTransaction, Optional.ofNullable(recipe), ((Inventory) container), transactions);
    SpongeImpl.postEvent(event);
    PacketPhaseUtil.handleSlotRestore(player, container, new ArrayList<>(transactions), event.isCancelled());
    if (player instanceof EntityPlayerMP) {
        if (event.getPreview().getCustom().isPresent() || event.isCancelled() || !event.getPreview().isValid()) {
            ItemStackSnapshot stack = event.getPreview().getFinal();
            if (event.isCancelled() || !event.getPreview().isValid()) {
                stack = event.getPreview().getOriginal();
            }
            // Resend modified output
            ((EntityPlayerMP) player).connection.sendPacket(new SPacketSetSlot(0, 0, ItemStackUtil.fromSnapshotToNative(stack)));
        }
    }
    return event;
}
Also used : CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinEntityPlayerMP(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP) SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) IMixinInventory(org.spongepowered.common.interfaces.IMixinInventory) OrderedInventory(org.spongepowered.api.item.inventory.type.OrderedInventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CarriedInventory(org.spongepowered.api.item.inventory.type.CarriedInventory) Inventory(org.spongepowered.api.item.inventory.Inventory) CustomInventory(org.spongepowered.common.item.inventory.custom.CustomInventory) IInventory(net.minecraft.inventory.IInventory)

Example 5 with SPacketSetSlot

use of net.minecraft.network.play.server.SPacketSetSlot in project SpongeCommon by SpongePowered.

the class MixinContainer method onDragDropSplit.

@Redirect(method = "slotClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;dropItem(Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/entity/item/EntityItem;", ordinal = 1))
public EntityItem onDragDropSplit(EntityPlayer player, ItemStack itemStackIn, boolean unused) {
    final EntityItem entityItem = player.dropItem(itemStackIn, unused);
    if (!((IMixinEntityPlayer) player).shouldRestoreInventory()) {
        return entityItem;
    }
    if (entityItem == null) {
        ItemStack original = null;
        if (player.inventory.getItemStack().isEmpty()) {
            original = itemStackIn;
        } else {
            player.inventory.getItemStack().grow(1);
            original = player.inventory.getItemStack();
        }
        player.inventory.setItemStack(original);
        ((EntityPlayerMP) player).connection.sendPacket(new SPacketSetSlot(-1, -1, original));
    }
    ((IMixinEntityPlayer) player).shouldRestoreInventory(false);
    return entityItem;
}
Also used : SPacketSetSlot(net.minecraft.network.play.server.SPacketSetSlot) ItemStack(net.minecraft.item.ItemStack) IMixinEntityPlayer(org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer) EntityItem(net.minecraft.entity.item.EntityItem) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

SPacketSetSlot (net.minecraft.network.play.server.SPacketSetSlot)15 ItemStack (net.minecraft.item.ItemStack)11 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)6 EntityItem (net.minecraft.entity.item.EntityItem)5 Slot (net.minecraft.inventory.Slot)4 Redirect (org.spongepowered.asm.mixin.injection.Redirect)3 IMixinEntityPlayer (org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayer)3 EntityPlayer (net.minecraft.entity.player.EntityPlayer)2 InventoryPlayer (net.minecraft.entity.player.InventoryPlayer)2 NetHandlerPlayServer (net.minecraft.network.NetHandlerPlayServer)2 TileEntity (net.minecraft.tileentity.TileEntity)2 CraftItemEvent (org.spongepowered.api.event.item.inventory.CraftItemEvent)2 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)2 Overwrite (org.spongepowered.asm.mixin.Overwrite)2 IMixinEntityPlayerMP (org.spongepowered.common.interfaces.entity.player.IMixinEntityPlayerMP)2 TileEntityBase (com.codetaylor.mc.artisanworktables.modules.worktables.tile.spi.TileEntityBase)1 SPacketTileEntityBase (com.codetaylor.mc.athenaeum.spi.packet.SPacketTileEntityBase)1 Vector3d (com.flowpowered.math.vector.Vector3d)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1