package net.minecraft.commands.arguments.blocks; import java.util.Set; import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.pattern.BlockInWorld; import net.minecraft.world.level.block.state.properties.Property; import org.jetbrains.annotations.Nullable; public class BlockInput implements Predicate { private final BlockState state; private final Set> properties; @Nullable private final CompoundTag tag; public BlockInput(BlockState state, Set> properties, @Nullable CompoundTag tag) { this.state = state; this.properties = properties; this.tag = tag; } public BlockState getState() { return this.state; } public Set> getDefinedProperties() { return this.properties; } public boolean test(BlockInWorld block) { BlockState blockState = block.getState(); if (!blockState.is(this.state.getBlock())) { return false; } else { for (Property property : this.properties) { if (blockState.getValue(property) != this.state.getValue(property)) { return false; } } if (this.tag == null) { return true; } else { BlockEntity blockEntity = block.getEntity(); return blockEntity != null && NbtUtils.compareNbt(this.tag, blockEntity.saveWithFullMetadata(block.getLevel().registryAccess()), true); } } } public boolean test(ServerLevel level, BlockPos pos) { return this.test(new BlockInWorld(level, pos, false)); } public boolean place(ServerLevel level, BlockPos pos, int flags) { BlockState blockState = (flags & 16) != 0 ? this.state : Block.updateFromNeighbourShapes(this.state, level, pos); if (blockState.isAir()) { blockState = this.state; } blockState = this.overwriteWithDefinedProperties(blockState); boolean bl = false; if (level.setBlock(pos, blockState, flags)) { bl = true; } if (this.tag != null) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity != null) { CompoundTag compoundTag = blockEntity.saveWithoutMetadata(level.registryAccess()); blockEntity.loadWithComponents(this.tag, level.registryAccess()); CompoundTag compoundTag2 = blockEntity.saveWithoutMetadata(level.registryAccess()); if (!compoundTag2.equals(compoundTag)) { bl = true; blockEntity.setChanged(); level.getChunkSource().blockChanged(pos); } } } return bl; } private BlockState overwriteWithDefinedProperties(BlockState state) { if (state == this.state) { return state; } else { for (Property property : this.properties) { state = copyProperty(state, this.state, property); } return state; } } private static > BlockState copyProperty(BlockState source, BlockState target, Property property) { return source.trySetValue(property, target.getValue(property)); } }