diff --git a/SpongeAPI b/SpongeAPI index cb4ee935103..ab94acf7c6b 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit cb4ee935103e4cd09e9bcb7a4e8cd649e0287fc9 +Subproject commit ab94acf7c6b27a71ce6da210636ec546e3be22c0 diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml deleted file mode 100644 index 665e527ab06..00000000000 --- a/gradle/verification-metadata.xml +++ /dev/null @@ -1,3669 +0,0 @@ - - - - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java b/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java index fbc9060b94c..4b17c828fcd 100644 --- a/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java @@ -26,11 +26,16 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.phys.BlockHitResult; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.world.BlockChangeFlag; @@ -41,6 +46,7 @@ import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge; import org.spongepowered.common.event.tracking.PhaseContext; import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; +import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline; import java.util.Optional; @@ -111,4 +117,5 @@ public interface TrackedWorldBridge { */ SpongeBlockSnapshot bridge$createSnapshotWithEntity(BlockState state, BlockPos pos, BlockChangeFlag updateFlag, @Nullable BlockEntity tileEntity); + InteractItemPipeline bridge$startInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack); } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java index cabf97ef8ca..b1e025c7e73 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java @@ -30,13 +30,13 @@ import java.util.Deque; public class EffectTransactor implements AutoCloseable { - final @Nullable ResultingTransactionBySideEffect previousEffect; + final @Nullable ResultingTransactionBySideEffect previousEffect; public final @Nullable GameTransaction<@NonNull ?> parent; private final TransactionalCaptureSupplier supplier; - private final ResultingTransactionBySideEffect effect; + private final ResultingTransactionBySideEffect effect; - EffectTransactor(final ResultingTransactionBySideEffect effect, final @Nullable GameTransaction<@NonNull ?> parent, - final @Nullable ResultingTransactionBySideEffect previousEffect, final TransactionalCaptureSupplier transactor) { + EffectTransactor(final ResultingTransactionBySideEffect effect, final @Nullable GameTransaction<@NonNull ?> parent, + final @Nullable ResultingTransactionBySideEffect previousEffect, final TransactionalCaptureSupplier transactor) { /* | ChangeBlock(1) <- head will be RemoveTileEntity(1), tail is still RemoveTileentity(1) | |- RemoveTileEntity <- Head will be ChangeBlock(2) tail is still ChangeBlock(2) @@ -55,7 +55,7 @@ public void close() { && this.parent.sideEffects != null && this.parent.getEffects().peekLast() == this.effect ) { - final Deque effects = this.parent.getEffects(); + final Deque> effects = this.parent.getEffects(); effects.removeLast(); if (effects.isEmpty()) { this.parent.sideEffects = null; diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java index d546d535e8e..fd733d01d77 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java @@ -54,7 +54,7 @@ public abstract class GameTransaction implements protected boolean cancelled = false; // Children Definitions - @Nullable LinkedList sideEffects; + @Nullable LinkedList> sideEffects; // LinkedList node definitions @Nullable GameTransaction<@NonNull ?> previous; @@ -75,14 +75,14 @@ public final TransactionType getTransactionType() { return this.transactionType; } - final Deque getEffects() { + final Deque> getEffects() { if (this.sideEffects == null) { this.sideEffects = new LinkedList<>(); } return this.sideEffects; } - public final void addLast(final ResultingTransactionBySideEffect effect) { + public final void addLast(final ResultingTransactionBySideEffect effect) { if (this.sideEffects == null) { this.sideEffects = new LinkedList<>(); } @@ -97,7 +97,7 @@ public final boolean hasAnyPrimaryChildrenTransactions() { if (this.sideEffects == null) { return false; } - for (final ResultingTransactionBySideEffect sideEffect : this.sideEffects) { + for (final ResultingTransactionBySideEffect sideEffect : this.sideEffects) { @Nullable GameTransaction<@NonNull ?> transaction = sideEffect.head; while (transaction != null) { if (transaction.transactionType.isPrimary() || transaction.hasChildTransactions()) { @@ -131,10 +131,17 @@ public abstract Optional generateEvent( public final void markCancelled() { this.cancelled = true; this.childIterator().forEachRemaining(GameTransaction::markCancelled); + if (this.next != null && this.next.hasUnknownChainRequiringCancellation()) { + this.next.markCancelled(); + } } public abstract boolean markCancelledTransactions(E event, ImmutableList> transactions); + protected boolean hasUnknownChainRequiringCancellation() { + return false; + } + public void postProcessEvent(final PhaseContext<@NonNull ?> context, final E event) { } @@ -183,16 +190,16 @@ protected void captureState() { } private static class ChildIterator implements Iterator> { - private final Iterator effectIterator; + private final Iterator> effectIterator; private @Nullable GameTransaction<@NonNull ?> cachedNext; private @MonotonicNonNull GameTransaction<@NonNull ?> pointer; private boolean hasNoRemainingElements = false; - ChildIterator(final Iterator iterator) { + ChildIterator(final Iterator> iterator) { // We're going to search the iterator's effects until we find the first at least this.effectIterator = iterator; while (this.effectIterator.hasNext()) { - final ResultingTransactionBySideEffect next = this.effectIterator.next(); + final ResultingTransactionBySideEffect next = this.effectIterator.next(); if (next.head != null) { this.cachedNext = next.head; this.pointer = next.head; @@ -219,7 +226,7 @@ public boolean hasNext() { // start search for the next, sadly because effects don't make a clean chain, // there can be many effects with no transactions recorded while (this.effectIterator.hasNext()) { - final ResultingTransactionBySideEffect next = this.effectIterator.next(); + final ResultingTransactionBySideEffect next = this.effectIterator.next(); if (next.head != null) { this.cachedNext = next.head; return true; @@ -250,16 +257,16 @@ public boolean hasNext() { private static class ReverseChildIterator implements Iterator> { - private final Iterator effectIterator; + private final Iterator> effectIterator; private @Nullable GameTransaction<@NonNull ?> cachedPrevious; private @MonotonicNonNull GameTransaction<@NonNull ?> pointer; private boolean hasNoRemainingElements = false; - ReverseChildIterator(final Iterator iterator) { + ReverseChildIterator(final Iterator> iterator) { // We're going to search the iterator's effects until we find the first at least this.effectIterator = iterator; while (this.effectIterator.hasNext()) { - final ResultingTransactionBySideEffect next = this.effectIterator.next(); + final ResultingTransactionBySideEffect next = this.effectIterator.next(); if (next.tail != null) { this.pointer = next.tail; this.cachedPrevious = next.tail; @@ -287,7 +294,7 @@ public boolean hasNext() { // start search for the next, sadly because effects don't make a clean chain, // there can be many effects with no transactions recorded while (this.effectIterator.hasNext()) { - final ResultingTransactionBySideEffect next = this.effectIterator.next(); + final ResultingTransactionBySideEffect next = this.effectIterator.next(); if (next.tail != null) { this.cachedPrevious = next.tail; return true; diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java index c224628dbbc..3cae058b582 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java @@ -33,12 +33,12 @@ import java.util.Iterator; import java.util.Optional; -public class ResultingTransactionBySideEffect { - public final ProcessingSideEffect effect; +public class ResultingTransactionBySideEffect { + public final ProcessingSideEffect effect; @Nullable GameTransaction<@NonNull ?> head; @Nullable GameTransaction<@NonNull ?> tail; - public ResultingTransactionBySideEffect(final ProcessingSideEffect effect) { + public ResultingTransactionBySideEffect(final ProcessingSideEffect effect) { this.effect = effect; } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java index baa4a79567a..b12eba91265 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java @@ -27,6 +27,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -45,12 +46,14 @@ import net.minecraft.world.ticks.ScheduledTick; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.event.cause.entity.SpawnType; import org.spongepowered.api.item.inventory.Inventory; import org.spongepowered.api.item.inventory.ItemStackSnapshot; import org.spongepowered.api.item.inventory.Slot; import org.spongepowered.api.item.inventory.crafting.CraftingInventory; import org.spongepowered.api.item.inventory.transaction.SlotTransaction; +import org.spongepowered.api.util.Direction; import org.spongepowered.api.world.BlockChangeFlag; import org.spongepowered.api.world.BlockChangeFlags; import org.spongepowered.common.SpongeCommon; @@ -72,6 +75,7 @@ import org.spongepowered.common.event.tracking.context.transaction.effect.EntityPerformingDropsEffect; import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect; import org.spongepowered.common.event.tracking.context.transaction.effect.PrepareBlockDrops; +import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect; import org.spongepowered.common.event.tracking.context.transaction.inventory.ClickCreativeMenuTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.ClickMenuTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.CloseMenuTransaction; @@ -80,6 +84,7 @@ import org.spongepowered.common.event.tracking.context.transaction.inventory.CraftingTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.DropFromPlayerInventoryTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.ExplicitInventoryOmittedTransaction; +import org.spongepowered.common.event.tracking.context.transaction.inventory.InteractItemTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.InventoryTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.OpenMenuTransaction; import org.spongepowered.common.event.tracking.context.transaction.inventory.PlaceRecipeTransaction; @@ -97,6 +102,7 @@ import org.spongepowered.common.world.BlockChange; import org.spongepowered.common.world.SpongeBlockChangeFlag; import org.spongepowered.common.world.volume.VolumeStreamUtils; +import org.spongepowered.math.vector.Vector3d; import java.lang.ref.WeakReference; import java.util.Objects; @@ -121,7 +127,7 @@ interface TransactionSink { @Deprecated void logTransaction(StatefulTransaction transaction); - EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect); + EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect); default ChangeBlock logBlockChange(final SpongeBlockSnapshot originalBlockSnapshot, final BlockState newState, final BlockChangeFlag flags @@ -174,7 +180,7 @@ default EffectTransactor logBlockDrops( original.blockChange = BlockChange.MODIFY; final PrepareBlockDropsTransaction transaction = new PrepareBlockDropsTransaction(pos, state, original); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(PrepareBlockDrops.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(PrepareBlockDrops.getInstance())); } @SuppressWarnings("ConstantConditions") @@ -258,7 +264,7 @@ default boolean logTileRemoval(final @Nullable BlockEntity tileentity, final Sup final EntityPerformingDropsTransaction transaction = new EntityPerformingDropsTransaction(entity); this.logTransaction(transaction); if (transaction.recorded()) { - return this.pushEffect(new ResultingTransactionBySideEffect(EntityPerformingDropsEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(EntityPerformingDropsEffect.getInstance())); } return null; } @@ -334,44 +340,44 @@ default EffectTransactor logClickContainer( final ClickMenuTransaction transaction = new ClickMenuTransaction( player, menu, slotNum, buttonNum, clickType, slot, ItemStackUtil.snapshotOf(player.containerMenu.getCarried())); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logPlayerInventoryChangeWithEffect(final Player player, final PlayerInventoryTransaction.EventCreator eventCreator) { final PlayerInventoryTransaction transaction = new PlayerInventoryTransaction(player, eventCreator); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logCreativeClickContainer(final int slotNum, final ItemStackSnapshot creativeStack, final Player player) { final ClickCreativeMenuTransaction transaction = new ClickCreativeMenuTransaction(player, slotNum, creativeStack); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logDropFromPlayerInventory(final ServerPlayer player, final boolean dropAll) { final DropFromPlayerInventoryTransaction transaction = new DropFromPlayerInventoryTransaction(player, dropAll); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logOpenInventory(final Player player) { final OpenMenuTransaction transaction = new OpenMenuTransaction(player); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logCloseInventory(final Player player, final boolean clientSource) { final CloseMenuTransaction transaction = new CloseMenuTransaction(player, clientSource); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logPlaceRecipe(final boolean shift, final RecipeHolder> recipe, final ServerPlayer player, final CraftingInventory craftInv) { final PlaceRecipeTransaction transaction = new PlaceRecipeTransaction(player, shift, recipe, craftInv); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default void logSelectTrade(final ServerPlayer player, final int item) { @@ -403,12 +409,20 @@ default void logCrafting(final Player player, @Nullable final ItemStack craftedS default EffectTransactor logIgnoredInventory(AbstractContainerMenu containerMenu) { final ExplicitInventoryOmittedTransaction transaction = new ExplicitInventoryOmittedTransaction(containerMenu); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } default EffectTransactor logInventoryTransaction(final AbstractContainerMenu containerMenu) { final InventoryTransaction transaction = new InventoryTransaction((Inventory) containerMenu); this.logTransaction(transaction); - return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance())); + return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance())); } + + default void logSecondaryInteractionTransaction( + final ServerPlayer playerIn, final ItemStack stackIn, final Vector3d hitVec, + final BlockSnapshot snapshot, final Direction direction, final InteractionHand handIn) { + final InteractItemTransaction transaction = new InteractItemTransaction(playerIn, stackIn, hitVec, snapshot, direction, handIn); + this.logTransaction(transaction); + } + } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java index 29288ef3395..9a32ad5960b 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java @@ -38,6 +38,7 @@ import org.spongepowered.common.event.tracking.PhaseTracker; import org.spongepowered.common.event.tracking.context.ICaptureSupplier; import org.spongepowered.common.event.tracking.context.transaction.effect.PrepareBlockDrops; +import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect; import org.spongepowered.common.event.tracking.context.transaction.type.TransactionType; import java.util.Collections; @@ -94,9 +95,9 @@ public boolean isEmpty() { */ @Override - public EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect) { + public EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect) { final GameTransaction<@NonNull ?> parentTransaction = Optional.ofNullable(this.effect) - .map(child -> (GameTransaction) child.tail) + .map(child -> child.tail) .orElse(Objects.requireNonNull(this.tail, "Somehow pushing a new effect without an owning Transaction")); final EffectTransactor effectTransactor = new EffectTransactor(effect, parentTransaction, this.effect, this); this.effect = effect; diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java index 51e1a40d109..b5d84553284 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java @@ -40,7 +40,7 @@ import org.spongepowered.common.util.VecHelper; import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class AddBlockLootDropsEffect implements ProcessingSideEffect { +public final class AddBlockLootDropsEffect implements ProcessingSideEffect { private static final class Holder { static final AddBlockLootDropsEffect INSTANCE = new AddBlockLootDropsEffect(); @@ -54,9 +54,11 @@ public static AddBlockLootDropsEffect getInstance() { @Override public EffectResult processSideEffect( - final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag, - final int limit + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final BlockState newState = args.newState(); + final SpongeBlockChangeFlag flag = args.flag(); + final int limit = args.limit(); final PhaseContext<@NonNull ?> phaseContext = PhaseTracker.getInstance().getPhaseContext(); final ServerLevel world = pipeline.getServerWorld(); diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java index bb2a8c66667..1519511ee19 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java @@ -25,11 +25,12 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class BlockAddedEffect implements ProcessingSideEffect { +public final class BlockAddedEffect implements ProcessingSideEffect { private static final class Holder { static final BlockAddedEffect INSTANCE = new BlockAddedEffect(); @@ -42,9 +43,11 @@ public static BlockAddedEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final var flag = args.flag(); + final var newState = args.newState(); // Vanilla will check if this is the server // if (!this.level.isClientSide) { // var2.onPlace(this.level, var1, var11, var3); @@ -55,6 +58,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli if (flag.performBlockPhysics()) { newState.onPlace(pipeline.getServerWorld(), oldState.pos, oldState.state, flag.movingBlocks()); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java new file mode 100644 index 00000000000..3c011a8a4e6 --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java @@ -0,0 +1,37 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.effect; + +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.common.world.SpongeBlockChangeFlag; + +public record BlockChangeArgs( + BlockState newState, + SpongeBlockChangeFlag flag, + int limit +) implements ProcessingSideEffect.Args { + +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java index 8664482ce9b..5d4300c3fb2 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java @@ -25,14 +25,14 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class BroadcastInventoryChangesEffect implements ProcessingSideEffect { +public final class BroadcastInventoryChangesEffect implements ProcessingSideEffect { private static final class Holder { static final BroadcastInventoryChangesEffect INSTANCE = new BroadcastInventoryChangesEffect(); @@ -41,16 +41,16 @@ public static BroadcastInventoryChangesEffect getInstance() { return Holder.INSTANCE; } public static EffectTransactor transact(final TransactionalCaptureSupplier transactor) { - return transactor.pushEffect(new ResultingTransactionBySideEffect(BroadcastInventoryChangesEffect.getInstance())); + return transactor.pushEffect(new ResultingTransactionBySideEffect<>(BroadcastInventoryChangesEffect.getInstance())); } BroadcastInventoryChangesEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java index f3693379738..c97e9417f9e 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java @@ -26,11 +26,11 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunkSection; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class CheckBlockPostPlacementIsSameEffect implements ProcessingSideEffect { +public final class CheckBlockPostPlacementIsSameEffect implements ProcessingSideEffect { private static final class Holder { static final CheckBlockPostPlacementIsSameEffect INSTANCE = new CheckBlockPostPlacementIsSameEffect(); } @@ -40,9 +40,10 @@ public static CheckBlockPostPlacementIsSameEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final var newState = args.newState(); final LevelChunkSection chunkSection = pipeline.getAffectedSection(); final int x = oldState.pos.getX() & 15; final int y = oldState.pos.getY() & 15; @@ -51,6 +52,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli if (!currentState.is(newState.getBlock())) { return new EffectResult(newState, true); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java index eecb265b5b7..b283c89e7ca 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java @@ -30,11 +30,12 @@ import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class ChunkChangeCompleteEffect implements ProcessingSideEffect { +public final class ChunkChangeCompleteEffect implements ProcessingSideEffect { private static final class Holder { static final ChunkChangeCompleteEffect INSTANCE = new ChunkChangeCompleteEffect(); } + ChunkChangeCompleteEffect() { } @@ -43,10 +44,9 @@ public static ChunkChangeCompleteEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { - final LevelChunk chunk = pipeline.getAffectedChunk(); // this.unsaved = true; // Vanilla, we'll just call the accessor available chunk.setUnsaved(true); diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java index 3ceacfb2e23..e6076ae2b0b 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java @@ -25,30 +25,35 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.BlockState; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Collections; import java.util.List; -public final class EffectResult { +public final class EffectResult<@Nullable R> { - public static final EffectResult NULL_RETURN = new EffectResult(null, true); - public static final EffectResult NULL_PASS = new EffectResult(null, false); + public static <@Nullable T> EffectResult nullReturn() { + return new EffectResult<>(null, true); + } + + public static <@Nullable T> EffectResult nullPass() { + return new EffectResult<>(null, false); + } - public final @Nullable BlockState resultingState; + public final @Nullable R resultingState; public final List drops; public final boolean hasResult; - public EffectResult(final @Nullable BlockState resultingState, final boolean hasResult) { + public EffectResult(final @Nullable R resultingState, final boolean hasResult) { this.resultingState = resultingState; this.hasResult = hasResult; this.drops = Collections.emptyList(); } - public EffectResult(final @Nullable BlockState resultingState, final List drops, final boolean hasResult) { + public EffectResult(final @Nullable R resultingState, final List drops, final boolean hasResult) { this.resultingState = resultingState; this.drops = drops; this.hasResult = hasResult; } + } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java index eeb7ee4e4e5..4d9d4065a3d 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java @@ -25,11 +25,11 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class EntityPerformingDropsEffect implements ProcessingSideEffect { +public final class EntityPerformingDropsEffect implements ProcessingSideEffect { private static final class Holder { static final EntityPerformingDropsEffect INSTANCE = new EntityPerformingDropsEffect(); @@ -40,10 +40,10 @@ public static EntityPerformingDropsEffect getInstance() { EntityPerformingDropsEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java index baaf064fadd..bfc7c1610ac 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java @@ -28,14 +28,14 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.PhaseContext; import org.spongepowered.common.event.tracking.PhaseTracker; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.event.tracking.phase.general.ExplosionContext; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class ExplodeBlockEffect implements ProcessingSideEffect { +public final class ExplodeBlockEffect implements ProcessingSideEffect { private static final class Holder { static final ExplodeBlockEffect INSTANCE = new ExplodeBlockEffect(); @@ -47,11 +47,9 @@ public static ExplodeBlockEffect getInstance() { ExplodeBlockEffect() {} - @SuppressWarnings({"unchecked", "rawtypes"}) @Override - public EffectResult processSideEffect( - final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag, - final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final PhaseContext<@NonNull ?> phaseContext = PhaseTracker.getInstance().getPhaseContext(); @@ -61,6 +59,6 @@ public EffectResult processSideEffect( oldState.state.getBlock().wasExploded(world, pos, ((ExplosionContext) phaseContext).getExplosion()); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java new file mode 100644 index 00000000000..14247da9acd --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java @@ -0,0 +1,43 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.effect; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public record InteractionArgs( + Level world, + ServerPlayer player, + InteractionHand hand, + BlockHitResult blockRaytraceResult, + BlockState blockstate, + ItemStack copiedStack +) implements ProcessingSideEffect.Args { +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java new file mode 100644 index 00000000000..baec608bece --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java @@ -0,0 +1,60 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.effect; + +import net.minecraft.world.InteractionResult; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; +import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline; + +public final class InteractionUseItemEffect implements ProcessingSideEffect { + + private static final class Holder { + static final InteractionUseItemEffect INSTANCE = new InteractionUseItemEffect(); + } + + public static InteractionUseItemEffect getInstance() { + return Holder.INSTANCE; + } + + @Override + public EffectResult processSideEffect( + InteractItemPipeline pipeline, InteractionResult oldState, InteractionArgs args + ) { + final var player = args.player(); + final var hand = args.hand(); + final var world = args.world(); + final var blockRaytraceResult = args.blockRaytraceResult(); + final var blockstate = args.blockstate(); + final InteractionResult result = blockstate.use(world, player, hand, blockRaytraceResult); + pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD); + try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) { + args.player().containerMenu.broadcastChanges(); + } + return new EffectResult<>(result, true); + } + +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java index 459b9c9c038..e58f1cb2849 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java @@ -25,11 +25,11 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class InventoryEffect implements ProcessingSideEffect { +public final class InventoryEffect implements ProcessingSideEffect { private static final class Holder { static final InventoryEffect INSTANCE = new InventoryEffect(); @@ -40,10 +40,10 @@ public static InventoryEffect getInstance() { InventoryEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java index 63f49fc4df6..ab322ffc648 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java @@ -32,7 +32,7 @@ import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class NotifyClientEffect implements ProcessingSideEffect { +public final class NotifyClientEffect implements ProcessingSideEffect { private static final class Holder { static final NotifyClientEffect INSTANCE = new NotifyClientEffect(); @@ -45,9 +45,11 @@ public static NotifyClientEffect getInstance() { NotifyClientEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final BlockState newState = args.newState(); + final SpongeBlockChangeFlag flag = args.flag(); final LevelChunk chunk = pipeline.getAffectedChunk(); final ServerLevel world = pipeline.getServerWorld(); @@ -58,7 +60,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli // this.notifyBlockUpdate(pos, blockstate, newWorldState, flags); world.sendBlockUpdated(oldState.pos, oldState.state, newState, flag.getRawFlag()); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java index 8702afdf483..309f7f8d8a1 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java @@ -26,11 +26,11 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class NotifyNeighborSideEffect implements ProcessingSideEffect { +public final class NotifyNeighborSideEffect implements ProcessingSideEffect { private static final class Holder { static final NotifyNeighborSideEffect INSTANCE = new NotifyNeighborSideEffect(); @@ -44,9 +44,11 @@ public static NotifyNeighborSideEffect getInstance() { @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final var flag = args.flag(); + final var newState = args.newState(); final ServerLevel world = pipeline.getServerWorld(); // Vanilla isClientSide is redundant @@ -59,7 +61,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli world.updateNeighbourForOutputSignal(oldState.pos, newState.getBlock()); } } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java index ffaaf61c60b..60be05b5664 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java @@ -25,11 +25,11 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class OldBlockOnReplaceEffect implements ProcessingSideEffect { +public final class OldBlockOnReplaceEffect implements ProcessingSideEffect { private static final class Holder { static final OldBlockOnReplaceEffect INSTANCE = new OldBlockOnReplaceEffect(); } @@ -42,9 +42,8 @@ public static OldBlockOnReplaceEffect getInstance() { } @Override - public EffectResult processSideEffect( - final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { // Normally, vanilla does this: // boolean var14 = var11.hasBlockEntity(); @@ -56,7 +55,9 @@ public EffectResult processSideEffect( // However, since we know we're not on the client (ChunkPipeline is not // used outside of server world context) // we can safely just do oldState.onRemove(this.level, var1, var2, var3). + final var flag = args.flag(); + final var newState = args.newState(); oldState.state.onRemove(pipeline.getServerWorld(), oldState.pos, newState, flag.movingBlocks()); - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java index 0e6a2b9d443..04439d1ccac 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java @@ -27,11 +27,11 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class PerformBlockDropsFromDestruction implements ProcessingSideEffect { +public final class PerformBlockDropsFromDestruction implements ProcessingSideEffect { private static final class Holder { static final PerformBlockDropsFromDestruction INSTANCE = new PerformBlockDropsFromDestruction(); @@ -43,11 +43,11 @@ public static PerformBlockDropsFromDestruction getInstance() { PerformBlockDropsFromDestruction() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { Block.dropResources(oldState.state, pipeline.getServerWorld(), oldState.pos, oldState.tileEntity, oldState.destroyer, ItemStack.EMPTY); - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java new file mode 100644 index 00000000000..153730d812f --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.effect; + +import net.minecraft.world.InteractionResult; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; +import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline; + +public final class PlayerContainerRefreshEffect implements ProcessingSideEffect { + + private static final class Holder { + static final PlayerContainerRefreshEffect INSTANCE = new PlayerContainerRefreshEffect(); + } + + public static PlayerContainerRefreshEffect getInstance() { + return Holder.INSTANCE; + } + + @Override + public EffectResult processSideEffect( + InteractItemPipeline pipeline, InteractionResult oldState, InteractionArgs args + ) { + pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD); + try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) { + args.player().containerMenu.broadcastChanges(); + } + return EffectResult.nullPass(); + } +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java index 9c3c772729e..4ea2225adf3 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java @@ -25,11 +25,11 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class PrepareBlockDrops implements ProcessingSideEffect { +public final class PrepareBlockDrops implements ProcessingSideEffect { private static final class Holder { static final PrepareBlockDrops INSTANCE = new PrepareBlockDrops(); @@ -41,10 +41,10 @@ public static PrepareBlockDrops getInstance() { PrepareBlockDrops() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java index 2d62b184f61..ecbea460ff5 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java @@ -24,16 +24,13 @@ */ package org.spongepowered.common.event.tracking.context.transaction.effect; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; -import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; +import org.checkerframework.checker.nullness.qual.Nullable; @FunctionalInterface -public interface ProcessingSideEffect { +public interface ProcessingSideEffect { - EffectResult processSideEffect(BlockPipeline pipeline, PipelineCursor oldState, BlockState newState, SpongeBlockChangeFlag flag, - int limit - ); + EffectResult processSideEffect(T pipeline, C oldState, A args); + + sealed interface Args permits BlockChangeArgs, InteractionArgs {} } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java index cc118789df8..4080bed5029 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java @@ -28,9 +28,8 @@ import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class RemoveTileEntityFromChunkEffect implements ProcessingSideEffect { +public final class RemoveTileEntityFromChunkEffect implements ProcessingSideEffect { private static final class Holder { static final RemoveTileEntityFromChunkEffect INSTANCE = new RemoveTileEntityFromChunkEffect(); @@ -43,14 +42,14 @@ public static RemoveTileEntityFromChunkEffect getInstance() { RemoveTileEntityFromChunkEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final BlockEntity tileEntity = oldState.tileEntity; if (tileEntity == null) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } pipeline.getAffectedChunk().removeBlockEntity(oldState.pos); - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java index 7733123bc27..10e1d5813ee 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java @@ -31,9 +31,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class SetAndRegisterBlockEntityToLevelChunk implements ProcessingSideEffect { +public final class SetAndRegisterBlockEntityToLevelChunk implements ProcessingSideEffect { private static final class Holder { static final SetAndRegisterBlockEntityToLevelChunk INSTANCE = new SetAndRegisterBlockEntityToLevelChunk(); @@ -46,17 +45,16 @@ public static SetAndRegisterBlockEntityToLevelChunk getInstance() { SetAndRegisterBlockEntityToLevelChunk() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, - final int limit + public EffectResult processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final ServerLevel serverWorld = pipeline.getServerWorld(); final @Nullable BlockEntity blockEntity = oldState.tileEntity; final BlockPos pos = oldState.pos; if (serverWorld.isOutsideBuildHeight(pos)) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } pipeline.getAffectedChunk().addAndRegisterBlockEntity(blockEntity); - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java index 6db0b84c8fa..390b88b3278 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java @@ -28,9 +28,8 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class SetBlockToChunkSectionEffect implements ProcessingSideEffect { +public final class SetBlockToChunkSectionEffect implements ProcessingSideEffect { private static final class Holder { private static final SetBlockToChunkSectionEffect INSTANCE = new SetBlockToChunkSectionEffect(); @@ -42,17 +41,17 @@ public static SetBlockToChunkSectionEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final BlockState newState = args.newState(); final LevelChunkSection chunkSection = pipeline.getAffectedSection(); final int x = oldState.pos.getX() & 15; final int y = oldState.pos.getY() & 15; final int z = oldState.pos.getZ() & 15; final BlockState oldStateReturned = chunkSection.setBlockState(x, y, z, newState); if (oldStateReturned == newState) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java index b167636ec06..5b5304022cf 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java @@ -29,13 +29,13 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; import java.util.List; -public final class SpawnDestructBlocksEffect implements ProcessingSideEffect { +public final class SpawnDestructBlocksEffect implements ProcessingSideEffect { private static final class Holder { static final SpawnDestructBlocksEffect INSTANCE = new SpawnDestructBlocksEffect(); @@ -47,11 +47,9 @@ public static SpawnDestructBlocksEffect getInstance() { SpawnDestructBlocksEffect() {} - @SuppressWarnings({"unchecked", "rawtypes"}) @Override - public EffectResult processSideEffect( - final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag, - final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final ServerLevel world = pipeline.getServerWorld(); final BlockPos pos = oldState.pos; @@ -60,6 +58,6 @@ public EffectResult processSideEffect( drops.forEach(drop -> Block.popResource(world, pos, drop)); - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java index b27cfad1ec7..9a665d98ebc 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java @@ -26,11 +26,11 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunkSection; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class UpdateChunkLightManagerEffect implements ProcessingSideEffect { +public final class UpdateChunkLightManagerEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateChunkLightManagerEffect INSTANCE = new UpdateChunkLightManagerEffect(); @@ -43,9 +43,8 @@ public static UpdateChunkLightManagerEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, - final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final LevelChunkSection chunkSection = pipeline.getAffectedSection(); final boolean wasEmpty = pipeline.wasEmpty(); @@ -53,6 +52,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli if (wasEmpty != isStillEmpty) { pipeline.getServerWorld().getChunkSource().getLightEngine().updateSectionStatus(oldState.pos, isStillEmpty); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java index ca520619017..7bc888a6774 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java @@ -27,11 +27,11 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class UpdateConnectingBlocksEffect implements ProcessingSideEffect { +public final class UpdateConnectingBlocksEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateConnectingBlocksEffect INSTANCE = new UpdateConnectingBlocksEffect(); @@ -44,11 +44,14 @@ public static UpdateConnectingBlocksEffect getInstance() { UpdateConnectingBlocksEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { final ServerLevel world = pipeline.getServerWorld(); final BlockPos pos = oldState.pos; + final var flag = args.flag(); + final var newState = args.newState(); + final var limit = args.limit(); if (flag.updateNeighboringShapes() && limit > 0) { // int i = p_241211_3_ & -34; // Vanilla negates 34 to flip neighbor notification and and "state drops" final int withoutNeighborDropsAndNestedNeighborUpdates = flag.asNestedNeighborUpdates().getRawFlag(); @@ -60,7 +63,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli newState.updateIndirectNeighbourShapes(world, pos, withoutNeighborDropsAndNestedNeighborUpdates, limit - 1); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java index 00693ff8e4a..8d33d0815a9 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java @@ -26,14 +26,14 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.Heightmap; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.accessor.world.level.chunk.ChunkAccessAccessor; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; import java.util.Map; -public final class UpdateHeightMapEffect implements ProcessingSideEffect { +public final class UpdateHeightMapEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateHeightMapEffect INSTANCE = new UpdateHeightMapEffect(); @@ -46,9 +46,10 @@ public static UpdateHeightMapEffect getInstance() { } @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final var newState = args.newState(); final Map heightMap = ((ChunkAccessAccessor) pipeline.getAffectedChunk()).accessor$heightmaps(); if (heightMap == null) { throw new IllegalStateException("Heightmap dereferenced!"); @@ -60,6 +61,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli heightMap.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, newState); heightMap.get(Heightmap.Types.OCEAN_FLOOR).update(x, y, z, newState); heightMap.get(Heightmap.Types.WORLD_SURFACE).update(x, y, z, newState); - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java index 38c38aeaed3..b58ed1430c8 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java @@ -26,11 +26,11 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class UpdateLightSideEffect implements ProcessingSideEffect { +public final class UpdateLightSideEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateLightSideEffect INSTANCE = new UpdateLightSideEffect(); @@ -44,12 +44,13 @@ public static UpdateLightSideEffect getInstance() { } @Override - public EffectResult processSideEffect( + public EffectResult<@Nullable BlockState> processSideEffect( final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + final BlockChangeArgs args ) { + final var flag = args.flag(); if (!flag.updateLighting()) { - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } final int originalOpactiy = oldState.opacity; final ServerLevel serverWorld = pipeline.getServerWorld(); @@ -80,7 +81,7 @@ public EffectResult processSideEffect( // this.profiler.endSection(); serverWorld.getProfiler().pop(); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java index 0ecc8ef372d..00137c776da 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java @@ -33,9 +33,8 @@ import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class UpdateOrCreateNewTileEntityPostPlacementEffect implements ProcessingSideEffect { +public final class UpdateOrCreateNewTileEntityPostPlacementEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateOrCreateNewTileEntityPostPlacementEffect INSTANCE = new UpdateOrCreateNewTileEntityPostPlacementEffect(); @@ -49,9 +48,10 @@ public static UpdateOrCreateNewTileEntityPostPlacementEffect getInstance() { @SuppressWarnings("deprecation") @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final var newState = args.newState(); final ServerLevel serverWorld = pipeline.getServerWorld(); final LevelChunk chunk = pipeline.getAffectedChunk(); if (((BlockStateBridge) newState).bridge$hasTileEntity()) { @@ -69,6 +69,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli ((LevelChunkAccessor) chunk).accessor$updateBlockEntityTicker(maybeNewTileEntity); } } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java index 67608577360..6f58022fb8e 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java @@ -25,11 +25,11 @@ package org.spongepowered.common.event.tracking.context.transaction.effect; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class UpdateWorldRendererEffect implements ProcessingSideEffect { +public final class UpdateWorldRendererEffect implements ProcessingSideEffect { private static final class Holder { static final UpdateWorldRendererEffect INSTANCE = new UpdateWorldRendererEffect(); @@ -42,12 +42,13 @@ public static UpdateWorldRendererEffect getInstance() { UpdateWorldRendererEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, - final BlockState newState, final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, + final BlockChangeArgs args ) { + final var newState = args.newState(); if (oldState.state != newState) { pipeline.getServerWorld().setBlocksDirty(oldState.pos, oldState.state, newState); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java index 3afdc4e476f..28552ca395b 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java @@ -29,7 +29,7 @@ import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class WorldBlockChangeCompleteEffect implements ProcessingSideEffect{ +public final class WorldBlockChangeCompleteEffect implements ProcessingSideEffect { private static final class Holder { static final WorldBlockChangeCompleteEffect INSTANCE = new WorldBlockChangeCompleteEffect(); @@ -42,9 +42,10 @@ public static WorldBlockChangeCompleteEffect getInstance() { WorldBlockChangeCompleteEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { + final BlockState newState = args.newState(); + final SpongeBlockChangeFlag flag = args.flag(); if (flag.notifyPathfinding()) { pipeline.getServerWorld().onBlockStateChange(oldState.pos, oldState.state, newState); } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java index d1dafaa2841..2bb6737698e 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java @@ -27,11 +27,11 @@ import net.minecraft.world.level.block.BaseFireBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; -import org.spongepowered.common.world.SpongeBlockChangeFlag; -public final class WorldDestroyBlockLevelEffect implements ProcessingSideEffect { +public final class WorldDestroyBlockLevelEffect implements ProcessingSideEffect { private static final class Holder { static final WorldDestroyBlockLevelEffect INSTANCE = new WorldDestroyBlockLevelEffect(); @@ -44,12 +44,12 @@ public static WorldDestroyBlockLevelEffect getInstance() { WorldDestroyBlockLevelEffect() {} @Override - public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, - final SpongeBlockChangeFlag flag, final int limit + public EffectResult<@Nullable BlockState> processSideEffect( + final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args ) { if (!(oldState.state.getBlock() instanceof BaseFireBlock)) { pipeline.getServerWorld().levelEvent(2001, oldState.pos, Block.getId(oldState.state)); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); } } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java new file mode 100644 index 00000000000..b02cfaaba3f --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java @@ -0,0 +1,102 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.inventory; + +import com.google.common.collect.ImmutableList; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.block.BlockSnapshot; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.CauseStackManager; +import org.spongepowered.api.event.block.InteractBlockEvent; +import org.spongepowered.api.item.inventory.ItemStackSnapshot; +import org.spongepowered.api.util.Direction; +import org.spongepowered.common.event.tracking.PhaseContext; +import org.spongepowered.common.event.tracking.context.transaction.GameTransaction; +import org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes; +import org.spongepowered.common.item.util.ItemStackUtil; +import org.spongepowered.common.util.PrettyPrinter; +import org.spongepowered.math.vector.Vector3d; + +import java.util.Optional; +import java.util.function.BiConsumer; + +public class InteractItemTransaction extends GameTransaction { + + + private final Vector3d hitVec; + private final BlockSnapshot snapshot; + private final Direction direction; + private final InteractionHand hand; + private final ItemStackSnapshot stack; + + public InteractItemTransaction(ServerPlayer playerIn, ItemStack stackIn, Vector3d hitVec, BlockSnapshot snapshot, Direction direction, InteractionHand handIn) { + super(TransactionTypes.INTERACT_BLOCK_SECONDARY.get()); + this.stack = ItemStackUtil.snapshotOf(stackIn); + this.hitVec = hitVec; + this.snapshot = snapshot; + this.direction = direction; + this.hand = handIn; + } + + + @Override + public Optional, CauseStackManager.StackFrame>> getFrameMutator( + @Nullable GameTransaction<@NonNull ?> parent + ) { + return Optional.empty(); + } + + @Override + public void addToPrinter(PrettyPrinter printer) { + + } + + @Override + public Optional generateEvent( + final PhaseContext<@NonNull ?> context, + final @Nullable GameTransaction<@NonNull ?> parent, + final ImmutableList> gameTransactions, + final Cause currentCause + ) { + return Optional.empty(); + } + + @Override + public void restore(PhaseContext<@NonNull ?> context, InteractBlockEvent.Secondary.Composite event) { + + } + + @Override + public boolean markCancelledTransactions( + final InteractBlockEvent.Secondary.Composite event, + final ImmutableList> gameTransactions) { + return false; + } +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java index 45672accf3a..be736521434 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java @@ -67,6 +67,11 @@ protected InventoryBasedTransaction(final Inventory inventory) { this.inventory = inventory; } + @Override + protected boolean hasUnknownChainRequiringCancellation() { + return true; + } + @Override public Optional, CauseStackManager.StackFrame>> getFrameMutator( @Nullable final GameTransaction<@NonNull ?> parent diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java index a6b34239bc1..7c33c35b7af 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java @@ -37,6 +37,7 @@ import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; import org.spongepowered.common.event.tracking.context.transaction.block.ChangeBlock; +import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs; import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult; import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect; import org.spongepowered.common.world.SpongeBlockChangeFlag; @@ -118,12 +119,11 @@ public LevelChunkSection getAffectedSection() { for (final ResultingTransactionBySideEffect effect : this.chunkEffects) { try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) { - final EffectResult result = effect.effect.processSideEffect( + final var args = new BlockChangeArgs(proposedState, flag, limit); + final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect( this, formerState, - proposedState, - flag, - limit + args ); if (result.hasResult) { return result.resultingState; diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java new file mode 100644 index 00000000000..51a6733693e --- /dev/null +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java @@ -0,0 +1,101 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package org.spongepowered.common.event.tracking.context.transaction.pipeline; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.common.event.tracking.PhaseContext; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; +import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; +import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult; +import org.spongepowered.common.event.tracking.context.transaction.effect.InteractionArgs; +import org.spongepowered.common.event.tracking.context.transaction.effect.InteractionUseItemEffect; + +import java.util.List; +import java.util.Objects; + +public final class InteractItemPipeline { + + private final ServerLevel worldIn; + private final ServerPlayer player; + private final InteractionHand hand; + private final BlockHitResult blockRaytraceResult; + private final BlockState blockstate; + private final ItemStack copiedStack; + private final List> effects; + private final TransactionalCaptureSupplier transactor; + + + public InteractItemPipeline(ServerLevel worldIn, + ServerPlayer playerIn, + InteractionHand handIn, + BlockHitResult blockRaytraceResultIn, + BlockState blockstate, + ItemStack copiedStack, + final TransactionalCaptureSupplier transactor) { + + this.worldIn = worldIn; + this.player = playerIn; + this.hand = handIn; + this.blockRaytraceResult = blockRaytraceResultIn; + this.blockstate = blockstate; + this.copiedStack = copiedStack; + this.effects = List.of( + new ResultingTransactionBySideEffect<>(InteractionUseItemEffect.getInstance()) + ); + this.transactor = transactor; + } + + public InteractionResult processInteraction(PhaseContext context) { + var interaction = InteractionResult.PASS; + for (final var effect : this.effects) { + try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) { + final InteractionArgs args = new InteractionArgs(this.worldIn, this.player, this.hand, this.blockRaytraceResult, this.blockstate, this.copiedStack); + final EffectResult result = effect.effect.processSideEffect( + this, + interaction, + args + ); + if (result.hasResult) { + final @Nullable InteractionResult resultingState = result.resultingState; + interaction = Objects.requireNonNullElse(resultingState, interaction); + } + } + } + return interaction; + } + + public TransactionalCaptureSupplier transactor() { + return this.transactor; + } +} diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java index ac6fdd6ac4b..35b6b4d1360 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java @@ -26,6 +26,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import org.checkerframework.checker.nullness.qual.Nullable; @@ -33,6 +34,7 @@ import org.spongepowered.common.event.tracking.PhaseContext; import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; +import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs; import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult; import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect; import org.spongepowered.common.world.SpongeBlockChangeFlag; @@ -49,7 +51,7 @@ public final class TileEntityPipeline implements BlockPipeline { private final @Nullable Supplier chunkSupplier; private final @Nullable Supplier serverWorld; private final @Nullable Supplier sectionSupplier; - private final List effects; + private final List> effects; private TileEntityPipeline(final Builder builder) { this.chunkSupplier = builder.chunkSupplier; @@ -98,15 +100,18 @@ public boolean wasEmpty() { public boolean processEffects(final PhaseContext context, final PipelineCursor initialCursor) { PipelineCursor currentCursor = initialCursor; - for (final ResultingTransactionBySideEffect effect : this.effects) { + for (final ResultingTransactionBySideEffect effect : this.effects) { try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) { - final EffectResult result = effect.effect.processSideEffect( - this, - currentCursor, + final BlockChangeArgs args = new BlockChangeArgs( currentCursor.state, (SpongeBlockChangeFlag) BlockChangeFlags.NONE, currentCursor.limit ); + final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect( + this, + currentCursor, + args + ); if (result.resultingState != currentCursor.state) { currentCursor = new PipelineCursor( result.resultingState, @@ -130,13 +135,13 @@ public static final class Builder { @Nullable Supplier serverWorld; @Nullable Supplier chunkSupplier; @Nullable Supplier sectionSupplier; - List effects; + List> effects; - public Builder addEffect(final ProcessingSideEffect effect) { + public Builder addEffect(final ProcessingSideEffect effect) { if (this.effects == null) { this.effects = new LinkedList<>(); } - this.effects.add(new ResultingTransactionBySideEffect(Objects.requireNonNull(effect, "Effect is null"))); + this.effects.add(new ResultingTransactionBySideEffect<>(Objects.requireNonNull(effect, "Effect is null"))); return this; } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java index 81165311770..62ab2617393 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java @@ -36,6 +36,7 @@ import org.spongepowered.common.event.tracking.PhaseContext; import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; +import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs; import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult; import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect; import org.spongepowered.common.world.SpongeBlockChangeFlag; @@ -52,7 +53,7 @@ public final class WorldPipeline implements BlockPipeline { private final Supplier serverWorld; private final Supplier sectionSupplier; private final boolean wasEmpty; - private final List worldEffects; + private final List> worldEffects; private final ChunkPipeline chunkPipeline; WorldPipeline(final Builder builder) { @@ -101,14 +102,13 @@ public boolean processEffects(final PhaseContext context, final BlockState cu final int oldOpacity = oldState.getLightBlock(serverWorld, pos); PipelineCursor formerState = new PipelineCursor(oldState, oldOpacity, pos, existing, destroyer, limit); - for (final ResultingTransactionBySideEffect effect : this.worldEffects) { + for (final ResultingTransactionBySideEffect effect : this.worldEffects) { try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) { - final EffectResult result = effect.effect.processSideEffect( + final var args = new BlockChangeArgs(newProposedState, flag, limit); + final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect( this, formerState, - newProposedState, - flag, - limit + args ); if (result.hasResult) { return result.resultingState != null; @@ -134,8 +134,8 @@ public static final class Builder { final Supplier serverWorld; final Supplier chunkSupplier; - final Supplier sectionSupplier; - @MonotonicNonNull List effects; + final Supplier<@Nullable LevelChunkSection> sectionSupplier; + @MonotonicNonNull List> effects; final ChunkPipeline chunkPipeline; Builder(final ChunkPipeline chunkPipeline) { @@ -145,11 +145,11 @@ public static final class Builder { this.chunkPipeline = chunkPipeline; } - public Builder addEffect(final ProcessingSideEffect effect) { + public Builder addEffect(final ProcessingSideEffect effect) { if (this.effects == null) { this.effects = new LinkedList<>(); } - this.effects.add(new ResultingTransactionBySideEffect(Objects.requireNonNull(effect, "Effect is null"))); + this.effects.add(new ResultingTransactionBySideEffect<>(Objects.requireNonNull(effect, "Effect is null"))); return this; } diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java index 7e628429740..83bb4d3ceb8 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java +++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java @@ -29,6 +29,7 @@ import org.spongepowered.api.event.Cancellable; import org.spongepowered.api.event.Event; import org.spongepowered.api.event.block.ChangeBlockEvent; +import org.spongepowered.api.event.block.InteractBlockEvent; import org.spongepowered.api.event.block.NotifyNeighborBlockEvent; import org.spongepowered.api.event.entity.HarvestEntityEvent; import org.spongepowered.api.event.entity.SpawnEntityEvent; @@ -65,6 +66,8 @@ public final class TransactionTypes { public static final DefaultedRegistryReference> CHANGE_INVENTORY_EVENT = TransactionTypes.key(ResourceKey.sponge("change_inventory")); public static final DefaultedRegistryReference> SLOT_CHANGE = TransactionTypes.key(ResourceKey.sponge("slot_change")); + public static final DefaultedRegistryReference> INTERACT_BLOCK_SECONDARY = TransactionTypes.key(ResourceKey.sponge("interact_block_secondary")); + // SORTFIELDS:OFF // @formatter:on diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java index 82e86c1939a..4b8cf417095 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java @@ -56,14 +56,14 @@ public abstract class RunAroundLikeCrazyGoalMixin extends GoalMixin { */ @Overwrite public void tick() { - if (!this.horse.isTamed() && this.horse.getRandom().nextInt(50) == 0) { + if (!this.horse.isTamed() && this.horse.getRandom().nextInt(this.shadow$adjustedTickDelay(50)) == 0) { Entity entity = this.horse.getPassengers().get(0); if (entity == null) { return; } - if (entity instanceof Player) { + if (entity instanceof Player p) { int i = this.horse.getTemper(); int j = this.horse.getMaxTemper(); @@ -76,7 +76,7 @@ public void tick() { } } // Sponge end - this.horse.tameWithName((Player)entity); + this.horse.tameWithName(p); return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java index 223e6986d28..6391f478d61 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java @@ -36,7 +36,9 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockEventData; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.block.Block; @@ -46,6 +48,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.ticks.ScheduledTick; import net.minecraft.world.ticks.TickPriority; @@ -105,6 +108,7 @@ import org.spongepowered.common.event.tracking.context.transaction.effect.WorldBlockChangeCompleteEffect; import org.spongepowered.common.event.tracking.context.transaction.effect.WorldDestroyBlockLevelEffect; import org.spongepowered.common.event.tracking.context.transaction.pipeline.ChunkPipeline; +import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor; import org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline; import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline; @@ -458,11 +462,11 @@ public void scheduleTick(final BlockPos pos, final Fluid fluid, final int trigge // Then build and use the BlockPipeline final ChunkPipeline chunkPipeline = mixinChunk.bridge$createChunkPipeline(pos, newState, currentState, spongeFlag, limit); final WorldPipeline.Builder worldPipelineBuilder = WorldPipeline.builder(chunkPipeline); - worldPipelineBuilder.addEffect((pipeline, oldState, newState1, flag1, cursorLimit) -> { + worldPipelineBuilder.addEffect((pipeline, oldState, args) -> { if (oldState == null) { - return EffectResult.NULL_RETURN; + return EffectResult.nullReturn(); } - return EffectResult.NULL_PASS; + return EffectResult.nullPass(); }) .addEffect(UpdateLightSideEffect.getInstance()) .addEffect(CheckBlockPostPlacementIsSameEffect.getInstance()) @@ -588,6 +592,31 @@ public boolean destroyBlock(final BlockPos pos, final boolean doDrops, @Nullable return builder.build(); } + @Override + public InteractItemPipeline bridge$startInteractionChange(net.minecraft.world.level.Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack) { + if (this.shadow$isDebug()) { // isClientSide is always false since this is WorldServer + return null; + } + if (this.bridge$isFake()) { + return null; + } + + final var instance = PhaseTracker.getInstance(); + if (instance.getSidedThread() != PhaseTracker.SERVER.getSidedThread() && instance != PhaseTracker.SERVER) { + throw new UnsupportedOperationException("Cannot perform a tracked Block Change on a ServerWorld while not on the main thread!"); + } + final var pipeline = new InteractItemPipeline( + (ServerLevel) worldIn, + playerIn, + handIn, + blockRaytraceResultIn, + blockstate, + copiedStack, + instance.getPhaseContext().getTransactor() + ); + return pipeline; + } + /** * Technically an overwrite, but because this is simply an override, we can * effectively do as we need to, which is determine if we are performing diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java index 1a4121bf4a0..43a78ad6ae2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java @@ -55,6 +55,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.bridge.server.level.ServerPlayerGameModeBridge; +import org.spongepowered.common.bridge.world.TrackedWorldBridge; import org.spongepowered.common.bridge.world.inventory.container.ContainerBridge; import org.spongepowered.common.event.SpongeCommonEventFactory; import org.spongepowered.common.event.inventory.InventoryEventFactory; @@ -65,6 +66,7 @@ import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect; import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; +import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline; import org.spongepowered.common.registry.provider.DirectionFacingProvider; import org.spongepowered.common.util.VecHelper; import org.spongepowered.math.vector.Vector3d; @@ -104,6 +106,8 @@ public InteractionResult useItemOn(final ServerPlayer playerIn, final Level worl final BlockSnapshot snapshot = ((ServerWorld) (worldIn)).createSnapshot(VecHelper.toVector3i(blockpos)); final Vector3d hitVec = Vector3d.from(blockRaytraceResultIn.getBlockPos().getX(), blockRaytraceResultIn.getBlockPos().getY(), blockRaytraceResultIn.getBlockPos().getZ()); final org.spongepowered.api.util.Direction direction = DirectionFacingProvider.INSTANCE.getKey(blockRaytraceResultIn.getDirection()).get(); + final PhaseContext phaseContext = PhaseTracker.getInstance().getPhaseContext(); + phaseContext.getTransactor().logSecondaryInteractionTransaction(playerIn, stackIn, hitVec, snapshot, direction, handIn); final InteractBlockEvent.Secondary event = SpongeCommonEventFactory.callInteractBlockEventSecondary(playerIn, stackIn, hitVec, snapshot, direction, handIn); final Tristate useItem = event.useItemResult(); final Tristate useBlock = event.useBlockResult(); @@ -112,90 +116,99 @@ public InteractionResult useItemOn(final ServerPlayer playerIn, final Level worl player.inventoryMenu.sendAllDataToRemote(); return InteractionResult.FAIL; } - // Sponge end - if (this.gameModeForPlayer == GameType.SPECTATOR) { - final MenuProvider inamedcontainerprovider = blockstate.getMenuProvider(worldIn, blockpos); - if (inamedcontainerprovider != null) { - playerIn.openMenu(inamedcontainerprovider); - final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos()); - final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos); - try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { - frame.pushCause(playerIn); - frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld)(worldIn)).createSnapshot(pos)); - ((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location); - if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) { - return InteractionResult.SUCCESS; - } - } - return InteractionResult.SUCCESS; - } else { - return InteractionResult.PASS; - } - } else { - final boolean flag = !playerIn.getMainHandItem().isEmpty() || !playerIn.getOffhandItem().isEmpty(); - final boolean flag1 = playerIn.isSecondaryUseActive() && flag; - final ItemStack copiedStack = stackIn.copy(); - if (useBlock != Tristate.FALSE && !flag1) { // Sponge check useBlock - final AbstractContainerMenu lastOpenContainer = playerIn.containerMenu; - final InteractionResult result = blockstate.use(worldIn, playerIn, handIn, blockRaytraceResultIn); - if (result.consumesAction() && lastOpenContainer != playerIn.containerMenu) { + try (final var frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { + frame.pushCause(event); + // Sponge end + if (this.gameModeForPlayer == GameType.SPECTATOR) { + final MenuProvider inamedcontainerprovider = blockstate.getMenuProvider(worldIn, blockpos); + if (inamedcontainerprovider != null) { + playerIn.openMenu(inamedcontainerprovider); final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos()); final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos); - try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { - frame.pushCause(playerIn); - frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos)); + try (final CauseStackManager.StackFrame blockHit = PhaseTracker.getCauseStackManager().pushCauseFrame()) { + blockHit.pushCause(playerIn); + blockHit.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos)); ((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location); if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) { - return InteractionResult.FAIL; + return InteractionResult.SUCCESS; } } - } - if (result.consumesAction()) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack); - return result; - } - } - - if (!stackIn.isEmpty() && !playerIn.getCooldowns().isOnCooldown(stackIn.getItem())) { - // Sponge start - if (useItem == Tristate.FALSE) { - ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true); + return InteractionResult.SUCCESS; + } else { return InteractionResult.PASS; } - // Sponge end - final UseOnContext itemusecontext = new UseOnContext(playerIn, handIn, blockRaytraceResultIn); - final InteractionResult result; - if (this.isCreative()) { - final int i = stackIn.getCount(); - result = stackIn.useOn(itemusecontext); - stackIn.setCount(i); - } else { - result = stackIn.useOn(itemusecontext); - // Sponge start - log change in hand - final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); - final TransactionalCaptureSupplier transactor = context.getTransactor(); - if (!transactor.isEmpty()) { //TODO: Add effect to attach the transaction to be the child of the parents - try (final EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) { - transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD); - this.player.inventoryMenu.broadcastChanges(); + } else { + final boolean flag = !playerIn.getMainHandItem().isEmpty() || !playerIn.getOffhandItem().isEmpty(); + final boolean flag1 = playerIn.isSecondaryUseActive() && flag; + final ItemStack copiedStack = stackIn.copy(); + if (useBlock != Tristate.FALSE && !flag1) { // Sponge check useBlock + final AbstractContainerMenu lastOpenContainer = playerIn.containerMenu; + final var interaction = ((TrackedWorldBridge) level).bridge$startInteractionChange(worldIn, playerIn, handIn, blockRaytraceResultIn, blockstate, copiedStack); + if (interaction == null) { + return InteractionResult.FAIL; + } + final PhaseContext<@NonNull ?> context = phaseContext; + final InteractionResult result = interaction.processInteraction(context); + + if (result.consumesAction() && lastOpenContainer != playerIn.containerMenu) { + final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos()); + final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos); + try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { + frame.pushCause(playerIn); + frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos)); + ((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location); + if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) { + return InteractionResult.FAIL; + } } } - // Sponge end + if (result.consumesAction()) { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack); + return result; + } } - if (result.consumesAction()) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack); - } + if (!stackIn.isEmpty() && !playerIn.getCooldowns().isOnCooldown(stackIn.getItem())) { + // Sponge start + if (useItem == Tristate.FALSE) { + ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true); + return InteractionResult.PASS; + } + // Sponge end + final UseOnContext itemusecontext = new UseOnContext(playerIn, handIn, blockRaytraceResultIn); + final InteractionResult result; + if (this.isCreative()) { + final int i = stackIn.getCount(); + result = stackIn.useOn(itemusecontext); + stackIn.setCount(i); + } else { + result = stackIn.useOn(itemusecontext); + // Sponge start - log change in hand + final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); + final TransactionalCaptureSupplier transactor = context.getTransactor(); + if (!transactor.isEmpty()) { //TODO: Add effect to attach the transaction to be the child of the parents + try (final EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) { + transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD); + this.player.inventoryMenu.broadcastChanges(); + } + } + // Sponge end + } - return result; - } else { - // Sponge start - if(useBlock == Tristate.FALSE && !flag1) { - ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true); - } - // Sponge end + if (result.consumesAction()) { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack); + } - return InteractionResult.PASS; + return result; + } else { + // Sponge start + if (useBlock == Tristate.FALSE && !flag1) { + ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true); + } + // Sponge end + + return InteractionResult.PASS; + } } } } diff --git a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java index ae2d2435294..6af34f1d593 100644 --- a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java +++ b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java @@ -325,8 +325,7 @@ void testTransformationsOfPositions( .sub(VolumePositionTranslators.BLOCK_OFFSET); final Vector3i invertedBlockPos = invertedTransformedPos.toInt(); final Vector3i expectedPos; - Assertions.assertTrue( - type instanceof StubState, + Assertions.assertInstanceOf(StubState.class, type, () -> String.format("expected state to be a stub state for pos: [%f, %f, %f] but got %s", x, y, z, type )