Search in sources :

Example 1 with TransactionalCaptureSupplier

use of org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier in project SpongeCommon by SpongePowered.

the class InventoryEventFactory method callPlayerChangeInventoryPickupPreEvent.

public static boolean callPlayerChangeInventoryPickupPreEvent(final Player player, final ItemEntity itemToPickup) {
    final ItemStack stack = itemToPickup.getItem();
    final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(stack);
    final ChangeInventoryEvent.Pickup.Pre event = SpongeEventFactory.createChangeInventoryEventPickupPre(PhaseTracker.getCauseStackManager().currentCause(), Optional.empty(), Collections.singletonList(snapshot), ((Inventory) player.inventory), (Item) itemToPickup, snapshot);
    SpongeCommon.post(event);
    if (event.isCancelled()) {
        return false;
    }
    if (event.custom().isPresent()) {
        final List<ItemStackSnapshot> list = event.custom().get();
        if (list.isEmpty()) {
            itemToPickup.getItem().setCount(0);
            return false;
        }
        final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
        final TransactionalCaptureSupplier transactor = context.getTransactor();
        try (final EffectTransactor ignored = transactor.logPlayerInventoryChangeWithEffect(player, PlayerInventoryTransaction.EventCreator.PICKUP)) {
            for (final ItemStackSnapshot item : list) {
                final org.spongepowered.api.item.inventory.ItemStack itemStack = item.createStack();
                player.inventory.add(ItemStackUtil.toNative(itemStack));
                if (!itemStack.isEmpty()) {
                    // Modified pickup items do not fit inventory - pre-cancel ChangeInventoryEvent.Pickup
                    ignored.parent.markCancelled();
                    return false;
                }
            }
        }
        if (!TrackingUtil.processBlockCaptures(context)) {
            return false;
        }
        itemToPickup.getItem().setCount(0);
    }
    return true;
}
Also used : EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.world.item.ItemStack) CarriedInventory(org.spongepowered.api.item.inventory.type.CarriedInventory) ViewableInventory(org.spongepowered.api.item.inventory.type.ViewableInventory) Inventory(org.spongepowered.api.item.inventory.Inventory)

Example 2 with TransactionalCaptureSupplier

use of org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier in project SpongeCommon by SpongePowered.

the class ServerPlayerMixin_Vanilla method vanilla$onElytraUse.

// override from LivingEntityMixin_Vanilla
@Override
protected void vanilla$onElytraUse(final CallbackInfo ci) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    final net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer) (Object) this;
    try (final EffectTransactor ignored = transactor.logPlayerInventoryChangeWithEffect(player, PlayerInventoryTransaction.EventCreator.STANDARD)) {
        // capture
        player.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)

Example 3 with TransactionalCaptureSupplier

use of org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier in project SpongeCommon by SpongePowered.

the class ServerPlayerGameModeMixin_Forge_Tracker method forgeTracker$pushTransactionAndEffect.

// @formatter:on
@Redirect(method = "destroyBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;mineBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;)V"))
private void forgeTracker$pushTransactionAndEffect(final ItemStack itemStack, final Level level, final BlockState state, final BlockPos pos, final Player player) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    // Log the prepare drops here because Forge rewrites
    // this method to call mine block before calling destroy block
    // and mods will possibly already have performed modifications on
    // the block before we can capture it in level.destroy.
    transactor.logBlockDrops(level, pos, state, level.getBlockEntity(pos));
    itemStack.mineBlock(level, state, pos, player);
    // Needs to get logged as a sideeffect under the BlockChange
    try (EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) {
        transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD);
        this.player.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) ResultingTransactionBySideEffect(org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 4 with TransactionalCaptureSupplier

use of org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin_Forge method forge$onPlaceRecipe.

@SuppressWarnings({ "UnresolvedMixinReference", "unchecked", "rawtypes" })
@Redirect(method = "lambda$handlePlaceRecipe$11", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookMenu;handlePlacement(ZLnet/minecraft/world/item/crafting/Recipe;Lnet/minecraft/server/level/ServerPlayer;)V"))
private void forge$onPlaceRecipe(final RecipeBookMenu recipeBookMenu, final boolean shift, final Recipe<?> recipe, final net.minecraft.server.level.ServerPlayer player) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    final Inventory craftInv = ((Inventory) player.containerMenu).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    try (final EffectTransactor ignored = transactor.logPlaceRecipe(shift, recipe, player, (CraftingInventory) craftInv)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        player.containerMenu.broadcastChanges();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 5 with TransactionalCaptureSupplier

use of org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier in project SpongeCommon by SpongePowered.

the class PacketContext method close.

@Override
public void close() {
    // Make sure to call any broadcast changes to capture any inventory transactions
    // for events
    final TransactionalCaptureSupplier transactor = this.getTransactor();
    if (this.packetPlayer != null) {
        transactor.logPlayerInventoryChange(this.packetPlayer, PlayerInventoryTransaction.EventCreator.STANDARD);
        try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(transactor)) {
            this.packetPlayer.containerMenu.broadcastChanges();
        }
    }
    super.close();
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)

Aggregations

TransactionalCaptureSupplier (org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)25 EffectTransactor (org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)16 Redirect (org.spongepowered.asm.mixin.injection.Redirect)11 Inventory (org.spongepowered.api.item.inventory.Inventory)5 ServerPlayer (net.minecraft.server.level.ServerPlayer)4 ItemStack (net.minecraft.world.item.ItemStack)4 CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)4 Inject (org.spongepowered.asm.mixin.injection.Inject)4 InteractionResult (net.minecraft.world.InteractionResult)2 Player (net.minecraft.world.entity.player.Player)2 AbstractContainerMenu (net.minecraft.world.inventory.AbstractContainerMenu)2 Cause (org.spongepowered.api.event.Cause)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 ServerWorld (org.spongepowered.api.world.server.ServerWorld)2 Overwrite (org.spongepowered.asm.mixin.Overwrite)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 Audience (net.kyori.adventure.audience.Audience)1 Component (net.kyori.adventure.text.Component)1