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;
}
}
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;
}
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();
}
}
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;
}
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();
}
}
Aggregations