Search in sources :

Example 6 with EffectTransactor

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

the class AbstractContainerMenuMixin_Inventory method inventory$wrapDoClickWithTransaction.

@Redirect(method = "clicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AbstractContainerMenu;doClick(IILnet/minecraft/world/inventory/ClickType;Lnet/minecraft/world/entity/player/Player;)Lnet/minecraft/world/item/ItemStack;"))
private ItemStack inventory$wrapDoClickWithTransaction(final AbstractContainerMenu menu, final int slotId, final int dragType, final ClickType clickType, final Player player) {
    if (((LevelBridge) player.level).bridge$isFake()) {
        return this.shadow$doClick(slotId, dragType, clickType, player);
    }
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    try (final EffectTransactor ignored = transactor.logClickContainer(menu, slotId, dragType, clickType, player)) {
        this.impl$isClicking = true;
        return this.shadow$doClick(slotId, dragType, clickType, player);
    } finally {
        this.impl$isClicking = false;
    }
}
Also used : LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 7 with EffectTransactor

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

the class ServerPlayerMixin_Inventory_API method closeInventory.

@Override
public boolean closeInventory() throws IllegalArgumentException {
    final net.minecraft.world.inventory.AbstractContainerMenu openContainer = this.containerMenu;
    if (((ContainerBridge) openContainer).bridge$isInUse()) {
        throw new UnsupportedOperationException("This player is currently modifying an open container. Closing it must be delayed!");
    }
    // Create Close_Window to capture item drops
    final net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer) (Object) this;
    try (final PhaseContext<@NonNull ?> ctx = PacketPhase.General.CLOSE_WINDOW.createPhaseContext(PhaseTracker.SERVER).source(this).packetPlayer(player)) {
        ctx.buildAndSwitch();
        try (final EffectTransactor ignored = ctx.getTransactor().logCloseInventory(player, false)) {
            // Drop & capture cursor item
            this.containerMenu.removed(player);
            this.containerMenu.broadcastChanges();
        }
        if (!TrackingUtil.processBlockCaptures(ctx)) {
            return false;
        }
    }
    return true;
}
Also used : ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) ContainerBridge(org.spongepowered.common.bridge.world.inventory.container.ContainerBridge)

Example 8 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor 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 9 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor 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 10 with EffectTransactor

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

the class LivingEntityMixin_Tracker method tracker$enterDeathPhase.

/**
 * @author i509VCB
 * @author gabizou
 *
 * @reason We can enter in to the entity drops transaction here which will
 * successfully batch the side effects (this is effectively a singular side
 * effect/transaction instead of a pipeline) to perform some things around
 * the entity's death. This successfully records the transactions associated
 * with this entity entering into the death state.
 */
@Redirect(method = "baseTick()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;tickDeath()V"))
private void tracker$enterDeathPhase(final LivingEntity livingEntity) {
    final PhaseTracker instance = PhaseTracker.SERVER;
    if (!instance.onSidedThread()) {
        this.shadow$tickDeath();
        return;
    }
    if (((LevelBridge) this.level).bridge$isFake()) {
        this.shadow$tickDeath();
        return;
    }
    final PhaseContext<@NonNull ?> context = instance.getPhaseContext();
    if (!context.doesBlockEventTracking()) {
        this.shadow$tickDeath();
        return;
    }
    try (final EffectTransactor ignored = context.getTransactor().ensureEntityDropTransactionEffect((LivingEntity) (Object) this)) {
        this.shadow$tickDeath();
    }
}
Also used : PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

EffectTransactor (org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)24 TransactionalCaptureSupplier (org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)16 Redirect (org.spongepowered.asm.mixin.injection.Redirect)13 ResultingTransactionBySideEffect (org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect)4 ServerPlayer (org.spongepowered.api.entity.living.player.server.ServerPlayer)3 Inventory (org.spongepowered.api.item.inventory.Inventory)3 LevelBridge (org.spongepowered.common.bridge.world.level.LevelBridge)3 ServerLevel (net.minecraft.server.level.ServerLevel)2 ServerPlayer (net.minecraft.server.level.ServerPlayer)2 ItemStack (net.minecraft.world.item.ItemStack)2 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)2 Nullable (org.checkerframework.checker.nullness.qual.Nullable)2 CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)2 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)2 EffectResult (org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult)2 Audience (net.kyori.adventure.audience.Audience)1 Component (net.kyori.adventure.text.Component)1 MutableComponent (net.minecraft.network.chat.MutableComponent)1 TextComponent (net.minecraft.network.chat.TextComponent)1 TranslatableComponent (net.minecraft.network.chat.TranslatableComponent)1