Search in sources :

Example 1 with IMixinContainer

use of org.spongepowered.common.interfaces.IMixinContainer in project SpongeCommon by SpongePowered.

the class MixinSlotCrafting method afterTake.

/**
 * Create CraftItemEvent.Post result is also handled by
 * {@link MixinContainer#redirectTransferStackInSlot} or
 * {@link MixinContainer#redirectOnTakeThrow}
 */
@Inject(method = "onTake", cancellable = true, at = @At("RETURN"))
private void afterTake(EntityPlayer thePlayer, ItemStack stack, CallbackInfoReturnable<ItemStack> cir) {
    if (((IMixinWorld) thePlayer.world).isFake()) {
        return;
    }
    ((IMixinContainer) thePlayer.openContainer).detectAndSendChanges(true);
    ((IMixinContainer) thePlayer.openContainer).setCaptureInventory(false);
    Container container = thePlayer.openContainer;
    Inventory craftInv = ((Inventory) container).query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        SpongeImpl.getLogger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    // retain only last slot-transactions on output slot
    SlotTransaction first = null;
    List<SlotTransaction> capturedTransactions = ((IMixinContainer) container).getCapturedTransactions();
    for (Iterator<SlotTransaction> iterator = capturedTransactions.iterator(); iterator.hasNext(); ) {
        SlotTransaction trans = iterator.next();
        Optional<SlotIndex> slotIndex = trans.getSlot().getInventoryProperty(SlotIndex.class);
        if (slotIndex.isPresent() && slotIndex.get().getValue() == 0) {
            iterator.remove();
            if (first == null) {
                first = trans;
            }
        }
    }
    ItemStackSnapshot craftedItem;
    // if we got a transaction on the crafting-slot use this
    if (first != null) {
        capturedTransactions.add(first);
        craftedItem = first.getOriginal().copy();
    } else {
        if (stack.isEmpty()) {
            // if stack is empty this was probably shift-crafting so we use the captured itemstack instead
            craftedItem = ItemStackUtil.snapshotOf(this.craftedStack);
        } else {
            craftedItem = ItemStackUtil.snapshotOf(stack);
        }
    }
    CraftingInventory craftingInventory = (CraftingInventory) craftInv;
    CraftItemEvent.Craft event = SpongeCommonEventFactory.callCraftEventPost(thePlayer, craftingInventory, craftedItem, this.lastRecipe, container, capturedTransactions);
    ((IMixinContainer) container).setLastCraft(event);
    ((IMixinContainer) container).setFirePreview(true);
    this.craftedStack = null;
    SlotTransaction last = new SlotTransaction(craftingInventory.getResult(), ItemStackSnapshot.NONE, ItemStackUtil.snapshotOf(this.getStack()));
    List<SlotTransaction> previewTransactions = ((IMixinContainer) container).getPreviewTransactions();
    CraftingRecipe newRecipe = Sponge.getRegistry().getCraftingRecipeRegistry().findMatchingRecipe(craftingInventory.getCraftingGrid(), ((World) player.world)).orElse(null);
    SpongeCommonEventFactory.callCraftEventPre(thePlayer, craftingInventory, last, newRecipe, container, previewTransactions);
    previewTransactions.clear();
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) Container(net.minecraft.inventory.Container) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) SlotIndex(org.spongepowered.api.item.inventory.property.SlotIndex) CraftItemEvent(org.spongepowered.api.event.item.inventory.CraftItemEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) IInventory(net.minecraft.inventory.IInventory) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 2 with IMixinContainer

use of org.spongepowered.common.interfaces.IMixinContainer in project SpongeCommon by SpongePowered.

the class EnchantItemPacketState method unwind.

@Override
public void unwind(InventoryPacketContext context) {
    // TODO - Pre changes of merging PacketFunction into the phase states, enchantments did NOT have any processing....
    final EntityPlayerMP player = context.getPacketPlayer();
    // The server will disable the player's crafting after receiving a
    // client packet
    // that did not pass validation (server click item != packet click item)
    // The server then sends a SPacketConfirmTransaction and waits for a
    // CPacketConfirmTransaction to re-enable crafting confirming that the
    // client
    // acknowledged the denied transaction.
    // To detect when this happens, we turn off capturing so we can avoid
    // firing
    // invalid events.
    // See MixinNetHandlerPlayServer processClickWindow redirect for rest of
    // fix.
    // --bloodmc
    final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
    if (!mixinContainer.capturingInventory()) {
        mixinContainer.getCapturedTransactions().clear();
        return;
    }
    // TODO clear this shit out of the context
    final CPacketEnchantItem packetIn = context.getPacket();
    final ItemStackSnapshot lastCursor = context.getCursor();
    final ItemStackSnapshot newCursor = ItemStackUtil.snapshotOf(player.inventory.getItemStack());
    final Transaction<ItemStackSnapshot> transaction = new Transaction<>(lastCursor, newCursor);
    final net.minecraft.inventory.Container openContainer = player.openContainer;
    final List<SlotTransaction> slotTransactions = mixinContainer.getCapturedTransactions();
    final int usedButton = packetIn.getButton();
    final List<Entity> capturedItems = new ArrayList<>();
    for (EntityItem entityItem : context.getCapturedItems()) {
        capturedItems.add(EntityUtil.fromNative(entityItem));
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(player);
        Sponge.getCauseStackManager().pushCause(openContainer);
        final ClickInventoryEvent inventoryEvent;
        inventoryEvent = this.createInventoryEvent(player, ContainerUtil.fromNative(openContainer), transaction, Lists.newArrayList(slotTransactions), capturedItems, usedButton);
        // If this happens and we captured no entities, avoid firing events
        if (mixinContainer.getCapturedTransactions().isEmpty() && capturedItems.isEmpty()) {
            mixinContainer.setCaptureInventory(false);
            return;
        }
        if (inventoryEvent != null) {
            // Don't fire inventory drop events when there are no entities
            if (inventoryEvent instanceof AffectEntityEvent && ((AffectEntityEvent) inventoryEvent).getEntities().isEmpty()) {
                slotTransactions.clear();
                mixinContainer.setCaptureInventory(false);
                return;
            }
            // packet has everything we want.
            if (!(inventoryEvent instanceof ClickInventoryEvent.Drag)) {
                PacketPhaseUtil.validateCapturedTransactions(packetIn.getWindowId(), openContainer, inventoryEvent.getTransactions());
            }
            SpongeImpl.postEvent(inventoryEvent);
            if (inventoryEvent.isCancelled() || PacketPhaseUtil.allTransactionsInvalid(inventoryEvent.getTransactions())) {
                if (inventoryEvent instanceof ClickInventoryEvent.Drop) {
                    capturedItems.clear();
                }
                // Restore cursor
                PacketPhaseUtil.handleCustomCursor(player, inventoryEvent.getCursorTransaction().getOriginal());
                // Restore target slots
                PacketPhaseUtil.handleSlotRestore(player, openContainer, inventoryEvent.getTransactions(), true);
            } else {
                PacketPhaseUtil.handleSlotRestore(player, openContainer, inventoryEvent.getTransactions(), false);
                // Handle cursor
                if (!inventoryEvent.getCursorTransaction().isValid()) {
                    PacketPhaseUtil.handleCustomCursor(player, inventoryEvent.getCursorTransaction().getOriginal());
                } else if (inventoryEvent.getCursorTransaction().getCustom().isPresent()) {
                    PacketPhaseUtil.handleCustomCursor(player, inventoryEvent.getCursorTransaction().getFinal());
                } else if (inventoryEvent instanceof ClickInventoryEvent.Drag) {
                    int increment;
                    increment = slotTransactions.stream().filter((t) -> !t.isValid()).mapToInt((t) -> t.getFinal().getQuantity()).sum();
                    final ItemStack cursor = inventoryEvent.getCursorTransaction().getFinal().createStack();
                    cursor.setQuantity(cursor.getQuantity() + increment);
                    PacketPhaseUtil.handleCustomCursor(player, cursor.createSnapshot());
                } else if (inventoryEvent instanceof ClickInventoryEvent.Double && !(inventoryEvent instanceof ClickInventoryEvent.Shift)) {
                    int decrement;
                    decrement = slotTransactions.stream().filter((t) -> !t.isValid()).mapToInt((t) -> t.getOriginal().getQuantity()).sum();
                    final ItemStack cursor = inventoryEvent.getCursorTransaction().getFinal().createStack();
                    cursor.setQuantity(cursor.getQuantity() - decrement);
                    PacketPhaseUtil.handleCustomCursor(player, cursor.createSnapshot());
                }
                if (inventoryEvent instanceof SpawnEntityEvent) {
                    processSpawnedEntities(player, (SpawnEntityEvent) inventoryEvent);
                } else if (!context.getCapturedEntitySupplier().isEmpty()) {
                    SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), context.getCapturedEntities());
                    SpongeImpl.postEvent(spawnEntityEvent);
                    if (!spawnEntityEvent.isCancelled()) {
                        processSpawnedEntities(player, spawnEntityEvent);
                    }
                }
            }
        }
    }
    slotTransactions.clear();
    mixinContainer.setCaptureInventory(false);
}
Also used : CPacketEnchantItem(net.minecraft.network.play.client.CPacketEnchantItem) EntityItem(net.minecraft.entity.item.EntityItem) SpongeImpl(org.spongepowered.common.SpongeImpl) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) CPacketEnchantItem(net.minecraft.network.play.client.CPacketEnchantItem) Sponge(org.spongepowered.api.Sponge) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Entity(org.spongepowered.api.entity.Entity) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) EntityUtil(org.spongepowered.common.entity.EntityUtil) ArrayList(java.util.ArrayList) ContainerUtil(org.spongepowered.common.item.inventory.util.ContainerUtil) ItemStack(org.spongepowered.api.item.inventory.ItemStack) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) List(java.util.List) Lists(com.google.common.collect.Lists) AffectEntityEvent(org.spongepowered.api.event.entity.AffectEntityEvent) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) Transaction(org.spongepowered.api.data.Transaction) Entity(org.spongepowered.api.entity.Entity) ArrayList(java.util.ArrayList) CauseStackManager(org.spongepowered.api.event.CauseStackManager) EntityItem(net.minecraft.entity.item.EntityItem) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) AffectEntityEvent(org.spongepowered.api.event.entity.AffectEntityEvent) ItemStack(org.spongepowered.api.item.inventory.ItemStack)

Example 3 with IMixinContainer

use of org.spongepowered.common.interfaces.IMixinContainer in project SpongeCommon by SpongePowered.

the class InteractionPacketState method unwind.

@Override
public void unwind(BasicPacketContext phaseContext) {
    final EntityPlayerMP player = phaseContext.getPacketPlayer();
    final ItemStack usedStack = phaseContext.getItemUsed();
    final ItemStackSnapshot usedSnapshot = ItemStackUtil.snapshotOf(usedStack);
    final Entity spongePlayer = EntityUtil.fromNative(player);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(spongePlayer);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        final boolean hasBlocks = !phaseContext.getCapturedBlockSupplier().isEmpty();
        final List<BlockSnapshot> capturedBlcoks = phaseContext.getCapturedBlocks();
        @Nullable final BlockSnapshot firstBlockChange = hasBlocks ? capturedBlcoks.get(0) : null;
        if (hasBlocks) {
            if (!TrackingUtil.processBlockCaptures(capturedBlcoks, this, phaseContext)) {
                // Stop entities like XP from being spawned
                return;
            }
        } else {
            phaseContext.getBlockItemDropSupplier().acceptIfNotEmpty(map -> {
                if (ShouldFire.DROP_ITEM_EVENT_DESTRUCT) {
                    for (BlockSnapshot blockChange : capturedBlcoks) {
                        final Location<World> location = blockChange.getLocation().get();
                        final Vector3d position = location.getPosition();
                        final BlockPos blockPos = VecHelper.toBlockPos(position);
                        final Collection<EntityItem> entityItems = map.get(blockPos);
                        if (!entityItems.isEmpty()) {
                            final List<Entity> items = entityItems.stream().map(EntityUtil::fromNative).collect(Collectors.toList());
                            final DropItemEvent.Destruct event = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), items);
                            SpongeImpl.postEvent(event);
                            if (!event.isCancelled()) {
                                processSpawnedEntities(player, event);
                            }
                        }
                    }
                } else {
                    for (BlockSnapshot blockChange : capturedBlcoks) {
                        final Location<World> location = blockChange.getLocation().get();
                        final Vector3d position = location.getPosition();
                        final BlockPos blockPos = VecHelper.toBlockPos(position);
                        final Collection<EntityItem> entityItems = map.get(blockPos);
                        if (!entityItems.isEmpty()) {
                            processEntities(player, (Collection<Entity>) (Collection<?>) entityItems);
                        }
                    }
                }
            });
        }
        phaseContext.getCapturedItemsSupplier().acceptAndClearIfNotEmpty(items -> {
            final ArrayList<Entity> entities = new ArrayList<>();
            for (EntityItem item : items) {
                entities.add(EntityUtil.fromNative(item));
            }
            final DropItemEvent.Dispense dispense = SpongeEventFactory.createDropItemEventDispense(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(dispense);
            if (!dispense.isCancelled()) {
                processSpawnedEntities(player, dispense);
            }
        });
        phaseContext.getCapturedEntityDropSupplier().acceptIfNotEmpty(map -> {
            if (map.isEmpty()) {
                return;
            }
            final PrettyPrinter printer = new PrettyPrinter(80);
            printer.add("Processing Interaction").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);
        });
        phaseContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
            final List<Entity> projectiles = new ArrayList<>(entities.size());
            final List<Entity> spawnEggs = new ArrayList<>(entities.size());
            final List<Entity> xpOrbs = new ArrayList<>(entities.size());
            final List<Entity> normalPlacement = new ArrayList<>(entities.size());
            final List<Entity> items = new ArrayList<>(entities.size());
            for (Entity entity : entities) {
                if (entity instanceof Projectile || entity instanceof EntityThrowable) {
                    projectiles.add(entity);
                } else if (usedSnapshot.getType() == ItemTypes.SPAWN_EGG) {
                    spawnEggs.add(entity);
                } else if (entity instanceof EntityItem) {
                    items.add(entity);
                } else if (entity instanceof EntityXPOrb) {
                    xpOrbs.add(entity);
                } else {
                    normalPlacement.add(entity);
                }
            }
            if (!projectiles.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (CauseStackManager.StackFrame frame2 = Sponge.getCauseStackManager().pushCauseFrame()) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                        Sponge.getCauseStackManager().pushCause(usedSnapshot);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), projectiles);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, projectiles);
                }
            }
            if (!spawnEggs.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (CauseStackManager.StackFrame frame2 = Sponge.getCauseStackManager().pushCauseFrame()) {
                        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.PROJECTILE);
                        Sponge.getCauseStackManager().pushCause(usedSnapshot);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), spawnEggs);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, spawnEggs);
                }
            }
            if (!items.isEmpty()) {
                if (ShouldFire.DROP_ITEM_EVENT_DISPENSE) {
                    final DropItemEvent.Dispense dispense = SpongeEventFactory.createDropItemEventDispense(Sponge.getCauseStackManager().getCurrentCause(), items);
                    if (!SpongeImpl.postEvent(dispense)) {
                        processSpawnedEntities(player, dispense);
                    }
                } else {
                    processEntities(player, items);
                }
            }
            if (!xpOrbs.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (final CauseStackManager.StackFrame stackFrame = Sponge.getCauseStackManager().pushCauseFrame()) {
                        if (firstBlockChange != null) {
                            stackFrame.pushCause(firstBlockChange);
                        }
                        stackFrame.addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), xpOrbs);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, xpOrbs);
                }
            }
            if (!normalPlacement.isEmpty()) {
                if (ShouldFire.SPAWN_ENTITY_EVENT) {
                    try (final CauseStackManager.StackFrame stackFrame = Sponge.getCauseStackManager().pushCauseFrame()) {
                        if (firstBlockChange != null) {
                            stackFrame.pushCause(firstBlockChange);
                        }
                        final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), normalPlacement);
                        if (!SpongeImpl.postEvent(event)) {
                            processSpawnedEntities(player, event);
                        }
                    }
                } else {
                    processEntities(player, normalPlacement);
                }
            }
        });
        final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
        mixinContainer.setCaptureInventory(false);
        mixinContainer.getCapturedTransactions().clear();
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) PrettyPrinter(org.spongepowered.asm.util.PrettyPrinter) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) UUID(java.util.UUID) EntityItem(net.minecraft.entity.item.EntityItem) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) EntityThrowable(net.minecraft.entity.projectile.EntityThrowable) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) Projectile(org.spongepowered.api.entity.projectile.Projectile) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) Vector3d(com.flowpowered.math.vector.Vector3d) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Collection(java.util.Collection) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) ItemStack(org.spongepowered.api.item.inventory.ItemStack) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) Map(java.util.Map) Nullable(javax.annotation.Nullable) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb)

Example 4 with IMixinContainer

use of org.spongepowered.common.interfaces.IMixinContainer in project SpongeCommon by SpongePowered.

the class PlaceBlockPacketState method unwind.

@Override
public void unwind(BasicPacketContext context) {
    final Packet<?> packet = context.getPacket();
    final EntityPlayerMP player = context.getPacketPlayer();
    final IMixinWorldServer mixinWorld = (IMixinWorldServer) player.world;
    // Note - CPacketPlayerTryUseItem is swapped with
    // CPacketPlayerBlockPlacement
    final ItemStack itemStack = context.getItemUsed();
    final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(itemStack);
    context.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
        try (@SuppressWarnings("unused") CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            Sponge.getCauseStackManager().pushCause(player);
            Sponge.getCauseStackManager().pushCause(snapshot);
            Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.SPAWN_EGG);
            final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(spawnEntityEvent);
            if (!spawnEntityEvent.isCancelled()) {
                processSpawnedEntities(player, spawnEntityEvent);
            }
        }
    });
    context.getCapturedBlockSupplier().acceptAndClearIfNotEmpty(originalBlocks -> {
        Sponge.getCauseStackManager().pushCause(player);
        boolean success = TrackingUtil.processBlockCaptures(originalBlocks, this, context);
        if (!success && snapshot != ItemTypeRegistryModule.NONE_SNAPSHOT) {
            Sponge.getCauseStackManager().pushCause(player);
            EnumHand hand = ((CPacketPlayerTryUseItemOnBlock) packet).getHand();
            PacketPhaseUtil.handlePlayerSlotRestore(player, (net.minecraft.item.ItemStack) itemStack, hand);
        }
        Sponge.getCauseStackManager().popCause();
    });
    context.getCapturedItemStackSupplier().acceptAndClearIfNotEmpty(drops -> {
        final List<Entity> entities = drops.stream().map(drop -> drop.create(player.getServerWorld())).map(EntityUtil::fromNative).collect(Collectors.toList());
        if (!entities.isEmpty()) {
            try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
                Sponge.getCauseStackManager().pushCause(player);
                DropItemEvent.Custom event = SpongeEventFactory.createDropItemEventCustom(Sponge.getCauseStackManager().getCurrentCause(), entities);
                SpongeImpl.postEvent(event);
                if (!event.isCancelled()) {
                    for (Entity droppedItem : event.getEntities()) {
                        droppedItem.setCreator(player.getUniqueID());
                        mixinWorld.forceSpawnEntity(droppedItem);
                    }
                }
            }
        }
    });
    final IMixinContainer mixinContainer = ContainerUtil.toMixin(player.openContainer);
    mixinContainer.setCaptureInventory(false);
    mixinContainer.getCapturedTransactions().clear();
}
Also used : Entity(org.spongepowered.api.entity.Entity) DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) CPacketPlayerTryUseItemOnBlock(net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) CauseStackManager(org.spongepowered.api.event.CauseStackManager) EnumHand(net.minecraft.util.EnumHand) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) ItemStack(org.spongepowered.api.item.inventory.ItemStack)

Example 5 with IMixinContainer

use of org.spongepowered.common.interfaces.IMixinContainer in project SpongeCommon by SpongePowered.

the class PlaceRecipePacketState method unwind.

@Override
public void unwind(InventoryPacketContext context) {
    CPacketPlaceRecipe packet = context.getPacket();
    boolean shift = packet.func_194319_c();
    IRecipe recipe = packet.func_194317_b();
    final EntityPlayerMP player = context.getPacketPlayer();
    ((IMixinContainer) player.openContainer).detectAndSendChanges(true);
    ((IMixinContainer) player.openContainer).setCaptureInventory(false);
    ((IMixinContainer) player.openContainer).setFirePreview(true);
    Inventory craftInv = ((Inventory) player.openContainer).query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        SpongeImpl.getLogger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    List<SlotTransaction> previewTransactions = ((IMixinContainer) player.openContainer).getPreviewTransactions();
    if (previewTransactions.isEmpty()) {
        CraftingOutput slot = ((CraftingInventory) craftInv).getResult();
        SlotTransaction st = new SlotTransaction(slot, ItemStackSnapshot.NONE, ItemStackUtil.snapshotOf(slot.peek().orElse(ItemStack.empty())));
        previewTransactions.add(st);
    }
    SpongeCommonEventFactory.callCraftEventPre(player, ((CraftingInventory) craftInv), previewTransactions.get(0), ((CraftingRecipe) recipe), player.openContainer, previewTransactions);
    previewTransactions.clear();
    final Entity spongePlayer = EntityUtil.fromNative(player);
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        frame.pushCause(spongePlayer);
        frame.pushCause(player.openContainer);
        List<SlotTransaction> transactions = ((IMixinContainer) player.openContainer).getCapturedTransactions();
        ItemStackSnapshot cursor = ItemStackUtil.snapshotOf(player.inventory.getItemStack());
        Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(cursor, cursor);
        ClickInventoryEvent event;
        if (shift) {
            event = SpongeEventFactory.createClickInventoryEventShiftPrimary(frame.getCurrentCause(), cursorTransaction, ((Container) player.openContainer), transactions);
        } else {
            event = SpongeEventFactory.createClickInventoryEventPrimary(frame.getCurrentCause(), cursorTransaction, ((Container) player.openContainer), transactions);
        }
        SpongeImpl.postEvent(event);
        if (event.isCancelled() || !event.getCursorTransaction().isValid()) {
            PacketPhaseUtil.handleCustomCursor(player, event.getCursorTransaction().getOriginal());
        } else {
            PacketPhaseUtil.handleCustomCursor(player, event.getCursorTransaction().getFinal());
        }
        PacketPhaseUtil.handleSlotRestore(player, player.openContainer, event.getTransactions(), event.isCancelled());
        event.getTransactions().clear();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Entity(org.spongepowered.api.entity.Entity) IRecipe(net.minecraft.item.crafting.IRecipe) CraftingOutput(org.spongepowered.api.item.inventory.crafting.CraftingOutput) CraftingRecipe(org.spongepowered.api.item.recipe.crafting.CraftingRecipe) ClickInventoryEvent(org.spongepowered.api.event.item.inventory.ClickInventoryEvent) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) IMixinContainer(org.spongepowered.common.interfaces.IMixinContainer) SlotTransaction(org.spongepowered.api.item.inventory.transaction.SlotTransaction) Transaction(org.spongepowered.api.data.Transaction) CauseStackManager(org.spongepowered.api.event.CauseStackManager) CPacketPlaceRecipe(net.minecraft.network.play.client.CPacketPlaceRecipe) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory)

Aggregations

IMixinContainer (org.spongepowered.common.interfaces.IMixinContainer)14 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)11 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)9 SlotTransaction (org.spongepowered.api.item.inventory.transaction.SlotTransaction)9 Transaction (org.spongepowered.api.data.Transaction)7 Entity (org.spongepowered.api.entity.Entity)7 CauseStackManager (org.spongepowered.api.event.CauseStackManager)7 ArrayList (java.util.ArrayList)5 EntityItem (net.minecraft.entity.item.EntityItem)5 ClickInventoryEvent (org.spongepowered.api.event.item.inventory.ClickInventoryEvent)5 ItemStack (org.spongepowered.api.item.inventory.ItemStack)5 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)4 Nullable (javax.annotation.Nullable)3 Container (net.minecraft.inventory.Container)3 IInventory (net.minecraft.inventory.IInventory)3 SPacketSetSlot (net.minecraft.network.play.server.SPacketSetSlot)3 DropItemEvent (org.spongepowered.api.event.item.inventory.DropItemEvent)3 Inventory (org.spongepowered.api.item.inventory.Inventory)3 CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)3 CraftingRecipe (org.spongepowered.api.item.recipe.crafting.CraftingRecipe)3