Search in sources :

Example 16 with SpongeBlockSnapshot

use of org.spongepowered.common.block.SpongeBlockSnapshot in project SpongeCommon by SpongePowered.

the class TransactionSink method logBlockDrops.

@SuppressWarnings("ConstantConditions")
default EffectTransactor logBlockDrops(final Level serverWorld, final BlockPos pos, final BlockState state, @Nullable final BlockEntity tileEntity) {
    final WeakReference<ServerLevel> worldRef = new WeakReference<>((ServerLevel) serverWorld);
    final Supplier<ServerLevel> worldSupplier = () -> Objects.requireNonNull(worldRef.get(), "ServerWorld dereferenced");
    final SpongeBlockSnapshot original = TrackingUtil.createPooledSnapshot(state, pos, BlockChangeFlags.NONE, Constants.World.DEFAULT_BLOCK_CHANGE_LIMIT, tileEntity, worldSupplier, Optional::empty, Optional::empty);
    original.blockChange = BlockChange.MODIFY;
    final PrepareBlockDropsTransaction transaction = new PrepareBlockDropsTransaction(pos, state, original);
    this.logTransaction(transaction);
    return this.pushEffect(new ResultingTransactionBySideEffect(PrepareBlockDrops.getInstance()));
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) Optional(java.util.Optional) PrepareBlockDropsTransaction(org.spongepowered.common.event.tracking.context.transaction.block.PrepareBlockDropsTransaction) WeakReference(java.lang.ref.WeakReference)

Example 17 with SpongeBlockSnapshot

use of org.spongepowered.common.block.SpongeBlockSnapshot in project SpongeCommon by SpongePowered.

the class BlockEventBasedTransaction method generateEvent.

@Override
public final Optional<ChangeBlockEvent.All> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ChangeBlockEvent.All>> transactions, final Cause currentCause) {
    final Optional<ServerWorld> o = ((SpongeServer) SpongeCommon.server()).worldManager().world(this.worldKey);
    if (!o.isPresent()) {
        return Optional.empty();
    }
    final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
    for (final GameTransaction<@NonNull ?> transaction : transactions) {
        final BlockEventBasedTransaction blockTransaction = (BlockEventBasedTransaction) transaction;
        if (!positions.containsKey(blockTransaction.affectedPosition)) {
            positions.put(blockTransaction.affectedPosition, blockTransaction.getOriginalSnapshot());
        }
        if (blockTransaction.getResultingSnapshot() != null) {
            positions.put(blockTransaction.affectedPosition, blockTransaction.getResultingSnapshot());
        }
    }
    final ImmutableList<BlockTransaction> eventTransactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
        final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
        if (snapshots.isEmpty() || snapshots.size() < 2) {
            // Error case
            return Optional.<BlockTransaction>empty();
        }
        final SpongeBlockSnapshot original = snapshots.get(0);
        final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
        final ImmutableList<BlockSnapshot> intermediary;
        if (snapshots.size() > 2) {
            intermediary = ImmutableList.copyOf(snapshots.subList(1, snapshots.size() - 2));
        } else {
            intermediary = ImmutableList.of();
        }
        final Operation operation = context.getBlockOperation(original, result);
        final BlockTransaction eventTransaction = new BlockTransaction(original, result, intermediary, operation);
        return Optional.of(eventTransaction);
    }).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
    if (eventTransactions.isEmpty()) {
        return Optional.empty();
    }
    return Optional.of(SpongeEventFactory.createChangeBlockEventAll(currentCause, eventTransactions, o.get()));
}
Also used : NonNull(org.checkerframework.checker.nullness.qual.NonNull) ServerWorld(org.spongepowered.api.world.server.ServerWorld) ListMultimap(com.google.common.collect.ListMultimap) ChangeBlockEvent(org.spongepowered.api.event.block.ChangeBlockEvent) SpongeServer(org.spongepowered.common.SpongeServer) BlockState(net.minecraft.world.level.block.state.BlockState) TransactionTypes(org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction) ResourceKey(org.spongepowered.api.ResourceKey) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Transaction(org.spongepowered.api.data.Transaction) LinkedListMultimap(com.google.common.collect.LinkedListMultimap) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) SpongeCommon(org.spongepowered.common.SpongeCommon) Cause(org.spongepowered.api.event.Cause) List(java.util.List) GameTransaction(org.spongepowered.common.event.tracking.context.transaction.GameTransaction) WorldBasedTransaction(org.spongepowered.common.event.tracking.context.transaction.world.WorldBasedTransaction) BlockPos(net.minecraft.core.BlockPos) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) Optional(java.util.Optional) Operation(org.spongepowered.api.block.transaction.Operation) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) Vector3i(org.spongepowered.math.vector.Vector3i) Optional(java.util.Optional) ImmutableList(com.google.common.collect.ImmutableList) Operation(org.spongepowered.api.block.transaction.Operation) ServerWorld(org.spongepowered.api.world.server.ServerWorld) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockPos(net.minecraft.core.BlockPos) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) BlockTransaction(org.spongepowered.api.block.transaction.BlockTransaction)

Example 18 with SpongeBlockSnapshot

use of org.spongepowered.common.block.SpongeBlockSnapshot in project SpongeCommon by SpongePowered.

the class RemoveBlockEntity method captureState.

@Override
protected void captureState() {
    super.captureState();
    final SpongeBlockSnapshot snapshot = TrackingUtil.createPooledSnapshot(this.originalState, this.affectedPosition, BlockChangeFlags.NONE, Constants.World.DEFAULT_BLOCK_CHANGE_LIMIT, this.removed, this.levelSupplier, Optional::empty, Optional::empty);
    snapshot.blockChange = BlockChange.MODIFY;
    this.tileSnapshot = snapshot;
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) Optional(java.util.Optional)

Example 19 with SpongeBlockSnapshot

use of org.spongepowered.common.block.SpongeBlockSnapshot in project SpongeCommon by SpongePowered.

the class TrackingUtil method associateTrackerToTarget.

public static void associateTrackerToTarget(final BlockChange blockChange, final BlockTransactionReceipt receipt, final UUID uuid) {
    final BlockSnapshot finalSnapshot = receipt.finalBlock();
    final SpongeBlockSnapshot spongeSnapshot = (SpongeBlockSnapshot) finalSnapshot;
    final BlockPos pos = spongeSnapshot.getBlockPos();
    final Block block = ((net.minecraft.world.level.block.state.BlockState) spongeSnapshot.state()).getBlock();
    spongeSnapshot.getServerWorld().map(world -> world.getChunkAt(pos)).map(chunk -> (LevelChunkBridge) chunk).ifPresent(spongeChunk -> {
        final PlayerTracker.Type trackerType = blockChange == BlockChange.PLACE ? PlayerTracker.Type.CREATOR : PlayerTracker.Type.NOTIFIER;
        spongeChunk.bridge$addTrackedBlockPosition(block, pos, uuid, trackerType);
    });
}
Also used : ViewableInventoryBridge(org.spongepowered.common.bridge.world.inventory.ViewableInventoryBridge) Level(org.apache.logging.log4j.Level) Random(java.util.Random) SpongeCommonEventFactory(org.spongepowered.common.event.SpongeCommonEventFactory) RedstoneTorchBlock(net.minecraft.world.level.block.RedstoneTorchBlock) BlockTransactionReceipt(org.spongepowered.api.block.transaction.BlockTransactionReceipt) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) TrackedWorldBridge(org.spongepowered.common.bridge.world.TrackedWorldBridge) ActiveChunkReferantBridge(org.spongepowered.common.bridge.world.level.chunk.ActiveChunkReferantBridge) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TickPhase(org.spongepowered.common.event.tracking.phase.tick.TickPhase) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) TimingBridge(org.spongepowered.common.bridge.TimingBridge) Transaction(org.spongepowered.api.data.Transaction) LocatableBlock(org.spongepowered.api.world.LocatableBlock) BlockEntityBridge(org.spongepowered.common.bridge.world.level.block.entity.BlockEntityBridge) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) Set(java.util.Set) UUID(java.util.UUID) BlockChange(org.spongepowered.common.world.BlockChange) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) BlockState(org.spongepowered.api.block.BlockState) MarkerManager(org.apache.logging.log4j.MarkerManager) Keys(org.spongepowered.api.data.Keys) List(java.util.List) CompoundTag(net.minecraft.nbt.CompoundTag) BlockPos(net.minecraft.core.BlockPos) FluidState(net.minecraft.world.level.material.FluidState) BlockEventData(net.minecraft.world.level.BlockEventData) Optional(java.util.Optional) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) TrackableBlockEventDataBridge(org.spongepowered.common.bridge.world.level.TrackableBlockEventDataBridge) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) NonNull(org.checkerframework.checker.nullness.qual.NonNull) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) ServerLevel(net.minecraft.server.level.ServerLevel) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ServerPlayer(net.minecraft.server.level.ServerPlayer) BlockChangeFlag(org.spongepowered.api.world.BlockChangeFlag) TrackableBridge(org.spongepowered.common.bridge.TrackableBridge) RepeaterBlock(net.minecraft.world.level.block.RepeaterBlock) TrackedLevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge) FluidTickContext(org.spongepowered.common.event.tracking.phase.tick.FluidTickContext) Marker(org.apache.logging.log4j.Marker) Nullable(org.checkerframework.checker.nullness.qual.Nullable) RedstoneLampBlock(net.minecraft.world.level.block.RedstoneLampBlock) Timing(co.aikar.timings.Timing) BlockTickContext(org.spongepowered.common.event.tracking.phase.tick.BlockTickContext) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) PlayerTracker(org.spongepowered.common.entity.PlayerTracker) ShouldFire(org.spongepowered.common.event.ShouldFire) SpongeLocatableBlockBuilder(org.spongepowered.common.world.server.SpongeLocatableBlockBuilder) SpongeCommon(org.spongepowered.common.SpongeCommon) Entity(org.spongepowered.api.entity.Entity) TickBlockEvent(org.spongepowered.api.event.block.TickBlockEvent) Consumer(java.util.function.Consumer) BlockChangeFlags(org.spongepowered.api.world.BlockChangeFlags) VecHelper(org.spongepowered.common.util.VecHelper) Block(net.minecraft.world.level.block.Block) BlockEventTickContext(org.spongepowered.common.event.tracking.phase.tick.BlockEventTickContext) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockState(org.spongepowered.api.block.BlockState) PlayerTracker(org.spongepowered.common.entity.PlayerTracker) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) RedstoneTorchBlock(net.minecraft.world.level.block.RedstoneTorchBlock) LocatableBlock(org.spongepowered.api.world.LocatableBlock) RepeaterBlock(net.minecraft.world.level.block.RepeaterBlock) RedstoneLampBlock(net.minecraft.world.level.block.RedstoneLampBlock) Block(net.minecraft.world.level.block.Block) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) TrackedLevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge)

Example 20 with SpongeBlockSnapshot

use of org.spongepowered.common.block.SpongeBlockSnapshot in project SpongeCommon by SpongePowered.

the class ServerLevelMixin_Tracker method bridge$createSnapshot.

@Override
public SpongeBlockSnapshot bridge$createSnapshot(final net.minecraft.world.level.block.state.BlockState state, final BlockPos pos, final BlockChangeFlag updateFlag) {
    final SpongeBlockSnapshot.BuilderImpl builder = SpongeBlockSnapshot.BuilderImpl.pooled();
    builder.reset();
    builder.blockState(state).world((ServerLevel) (Object) this).position(VecHelper.toVector3i(pos));
    final LevelChunk chunk = this.shadow$getChunkAt(pos);
    if (chunk == null) {
        return builder.flag(updateFlag).build();
    }
    final Optional<UUID> creator = ((LevelChunkBridge) chunk).bridge$getBlockCreatorUUID(pos);
    final Optional<UUID> notifier = ((LevelChunkBridge) chunk).bridge$getBlockNotifierUUID(pos);
    creator.ifPresent(builder::creator);
    notifier.ifPresent(builder::notifier);
    final boolean hasTileEntity = ((BlockStateBridge) state).bridge$hasTileEntity();
    final net.minecraft.world.level.block.entity.BlockEntity tileEntity = chunk.getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
    if (hasTileEntity || tileEntity != null) {
        // We MUST only check to see if a TE exists to avoid creating a new one.
        if (tileEntity != null) {
            // TODO - custom data.
            final CompoundTag nbt = new CompoundTag();
            // Some mods like OpenComputers assert if attempting to save robot while moving
            try {
                tileEntity.save(nbt);
                builder.addUnsafeCompound(nbt);
            } catch (final Throwable t) {
            // ignore
            }
        }
    }
    builder.flag(updateFlag);
    return builder.build();
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) TrackedLevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge) UUID(java.util.UUID) CompoundTag(net.minecraft.nbt.CompoundTag) BlockStateBridge(org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge)

Aggregations

SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)20 Optional (java.util.Optional)10 IBlockState (net.minecraft.block.state.IBlockState)6 ServerLevel (net.minecraft.server.level.ServerLevel)6 Nullable (org.checkerframework.checker.nullness.qual.Nullable)6 BlockPos (net.minecraft.core.BlockPos)5 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)5 LevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)5 WeakReference (java.lang.ref.WeakReference)4 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)4 NonNull (org.checkerframework.checker.nullness.qual.NonNull)4 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 UUID (java.util.UUID)3 WorldServer (net.minecraft.world.WorldServer)3 Block (net.minecraft.world.level.block.Block)3 BlockState (net.minecraft.world.level.block.state.BlockState)3 Entity (org.spongepowered.api.entity.Entity)3 SpongeEventFactory (org.spongepowered.api.event.SpongeEventFactory)3