Search in sources :

Example 1 with TileEntityPipeline

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

the class ServerLevelMixin_Tracker method shadow$addBlockEntity.

@SuppressWarnings({ "ConstantConditions", "RedundantCast" })
@Override
public boolean shadow$addBlockEntity(final net.minecraft.world.level.block.entity.BlockEntity tileEntity) {
    if (this.bridge$isFake() || PhaseTracker.SERVER.getSidedThread() != Thread.currentThread()) {
        // out whoever is trying to remove tile entities asynchronously....
        return super.shadow$addBlockEntity(tileEntity);
    }
    // Otherwise, let's go on and check if we're recording transactions,
    // and if so, log the tile entity removal (may associate with an existing transaction,
    // or create a new transaction.
    final PhaseContext<@NonNull ?> current = PhaseTracker.SERVER.getPhaseContext();
    if (current.doesBlockEventTracking()) {
        final BlockPos immutable = tileEntity.getBlockPos().immutable();
        if (tileEntity.getLevel() != (ServerLevel) (Object) this) {
            tileEntity.setLevelAndPosition((ServerLevel) (Object) this, immutable);
        }
        final ChunkAccess iChunk = this.shadow$getChunk(immutable.getX() >> 4, immutable.getZ() >> 4, ChunkStatus.FULL, false);
        if (!(iChunk instanceof LevelChunk)) {
            return super.shadow$addBlockEntity(tileEntity);
        }
        final LevelChunk chunk = this.shadow$getChunkAt(immutable);
        if (current.getTransactor().logTileAddition(tileEntity, () -> (ServerLevel) (Object) this, chunk)) {
            final TileEntityPipeline pipeline = TileEntityPipeline.kickOff((ServerLevel) (Object) this, immutable).addEffect(AddTileEntityToWorldWhileProcessingEffect.getInstance()).addEffect(AddTileEntityToLoadedListInWorldEffect.getInstance()).addEffect(AddTileEntityToTickableListEffect.getInstance()).addEffect(TileOnLoadDuringAddToWorldEffect.getInstance()).build();
            return pipeline.processEffects(current, new PipelineCursor(tileEntity.getBlockState(), 0, immutable, tileEntity, (Entity) null, Constants.World.DEFAULT_BLOCK_CHANGE_LIMIT));
        }
    }
    return super.shadow$addBlockEntity(tileEntity);
}
Also used : ChunkAccess(net.minecraft.world.level.chunk.ChunkAccess) ServerLevel(net.minecraft.server.level.ServerLevel) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) RemoveBlockEntity(org.spongepowered.common.event.tracking.context.transaction.block.RemoveBlockEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) Entity(net.minecraft.world.entity.Entity) TileEntityPipeline(org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) PipelineCursor(org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor) BlockPos(net.minecraft.core.BlockPos)

Example 2 with TileEntityPipeline

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

the class ServerLevelMixin_Tracker method shadow$setBlockEntity.

@SuppressWarnings({ "RedundantCast", "ConstantConditions" })
@Override
public void shadow$setBlockEntity(final BlockPos pos, final net.minecraft.world.level.block.entity.@Nullable BlockEntity proposed) {
    final BlockPos immutable = pos.immutable();
    if (this.bridge$isFake() || PhaseTracker.SERVER.getSidedThread() != Thread.currentThread()) {
        // If we're fake or not on the server thread, well, we could effectively call
        // out whoever is trying to remove tile entities asynchronously....
        super.shadow$setBlockEntity(pos, proposed);
        return;
    }
    if (proposed != null) {
        if (proposed.getLevel() != (ServerLevel) (Object) this) {
            proposed.setLevelAndPosition((ServerLevel) (Object) this, immutable);
        } else {
            proposed.setPosition(pos);
        }
    }
    // Otherwise, let's go on and check if we're recording transactions,
    // and if so, log the tile entity removal (may associate with an existing transaction,
    // or create a new transaction.
    final PhaseContext<@NonNull ?> current = PhaseTracker.SERVER.getPhaseContext();
    if (current.doesBlockEventTracking()) {
        final net.minecraft.world.level.block.entity.@Nullable BlockEntity existing = this.shadow$getChunkAt(immutable).getBlockEntity(immutable);
        if (current.getTransactor().logTileReplacement(immutable, existing, proposed, () -> (ServerLevel) (Object) this)) {
            final TileEntityPipeline pipeline = TileEntityPipeline.kickOff((ServerLevel) (Object) this, immutable).addEffect(RemoveProposedTileEntitiesDuringSetIfWorldProcessingEffect.getInstance()).addEffect(ReplaceTileEntityInWorldEffect.getInstance()).build();
            pipeline.processEffects(current, new PipelineCursor(proposed.getBlockState(), 0, immutable, proposed, (Entity) null, Constants.World.DEFAULT_BLOCK_CHANGE_LIMIT));
            return;
        }
    }
    super.shadow$setBlockEntity(immutable, proposed);
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) RemoveBlockEntity(org.spongepowered.common.event.tracking.context.transaction.block.RemoveBlockEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) Entity(net.minecraft.world.entity.Entity) TileEntityPipeline(org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline) PipelineCursor(org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor) BlockPos(net.minecraft.core.BlockPos) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with TileEntityPipeline

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

the class ServerLevelMixin_Tracker method shadow$removeBlockEntity.

/**
 * 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
 * block transactional recording, go ahead and record transactions.
 * <p>In the event that we are performing transaction recording, the following
 * must be true:
 * <ul>
 *     <li>This world instance is managed and verified by Sponge</li>
 *     <li>This world must {@link LevelBridge#bridge$isFake()} return {@code false}</li>
 *     <li>The {@link PhaseTracker#SERVER}'s {@link PhaseTracker#getSidedThread()} must be {@code ==} {@link Thread#currentThread()}</li
 *     <li>The current {@link IPhaseState} must be allowing to record transactions with an applicable {@link org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier}</li>
 * </ul>
 * After which, we may be able to appropriately associate the {@link net.minecraft.world.level.block.entity.BlockEntity}
 * being removed with either an existing {@link ChangeBlock},
 * or generate a new {@link RemoveBlockEntity} transaction
 * that would otherwise be able to associate with either the current {@link IPhaseState} or a parent {@link GameTransaction}
 * if this call is the result of a {@link org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect}..
 *
 * @param pos The position of the tile entity to remove
 * @author gabizou - July 31st, 2020 - Minecraft 1.14.3
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void shadow$removeBlockEntity(final BlockPos pos) {
    final BlockPos immutable = pos.immutable();
    final net.minecraft.world.level.block.entity.BlockEntity tileentity = this.shadow$getBlockEntity(immutable);
    if (tileentity == null) {
        return;
    }
    if (this.bridge$isFake() || PhaseTracker.SERVER.getSidedThread() != Thread.currentThread()) {
        // If we're fake or not on the server thread, well, we could effectively call
        // out whoever is trying to remove tile entities asynchronously....
        super.shadow$removeBlockEntity(immutable);
        return;
    }
    // Otherwise, let's go on and check if we're recording transactions,
    // and if so, log the tile entity removal (may associate with an existing transaction,
    // or create a new transaction.
    final PhaseContext<@NonNull ?> current = PhaseTracker.SERVER.getPhaseContext();
    if (current.getTransactor().logTileRemoval(tileentity, () -> (ServerLevel) (Object) this)) {
        final TileEntityPipeline pipeline = TileEntityPipeline.kickOff((ServerLevel) (Object) this, immutable).addEffect(RemoveTileEntityFromWorldEffect.getInstance()).addEffect(RemoveTileEntityFromChunkEffect.getInstance()).build();
        pipeline.processEffects(current, new PipelineCursor(tileentity.getBlockState(), 0, immutable, tileentity, (Entity) null, Constants.World.DEFAULT_BLOCK_CHANGE_LIMIT));
        return;
    }
    super.shadow$removeBlockEntity(immutable);
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) RemoveBlockEntity(org.spongepowered.common.event.tracking.context.transaction.block.RemoveBlockEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) Entity(net.minecraft.world.entity.Entity) TileEntityPipeline(org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline) PipelineCursor(org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor) BlockPos(net.minecraft.core.BlockPos)

Aggregations

BlockPos (net.minecraft.core.BlockPos)3 ServerLevel (net.minecraft.server.level.ServerLevel)3 Entity (net.minecraft.world.entity.Entity)3 TickableBlockEntity (net.minecraft.world.level.block.entity.TickableBlockEntity)3 BlockEntity (org.spongepowered.api.block.entity.BlockEntity)3 RemoveBlockEntity (org.spongepowered.common.event.tracking.context.transaction.block.RemoveBlockEntity)3 PipelineCursor (org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor)3 TileEntityPipeline (org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline)3 ChunkAccess (net.minecraft.world.level.chunk.ChunkAccess)1 LevelChunk (net.minecraft.world.level.chunk.LevelChunk)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1