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