package net.minecraft.server.commands; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import java.util.function.Predicate; import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.blocks.BlockInput; import net.minecraft.commands.arguments.blocks.BlockStateArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.pattern.BlockInWorld; import org.jetbrains.annotations.Nullable; public class SetBlockCommand { private static final SimpleCommandExceptionType ERROR_FAILED = new SimpleCommandExceptionType(Component.translatable("commands.setblock.failed")); public static void register(CommandDispatcher dispatcher, CommandBuildContext buildContext) { Predicate predicate = blockInWorld -> blockInWorld.getLevel().isEmptyBlock(blockInWorld.getPos()); dispatcher.register( Commands.literal("setblock") .requires(commandSourceStack -> commandSourceStack.hasPermission(2)) .then( Commands.argument("pos", BlockPosArgument.blockPos()) .then( Commands.argument("block", BlockStateArgument.block(buildContext)) .executes( commandContext -> setBlock( commandContext.getSource(), BlockPosArgument.getLoadedBlockPos(commandContext, "pos"), BlockStateArgument.getBlock(commandContext, "block"), SetBlockCommand.Mode.REPLACE, null, false ) ) .then( Commands.literal("destroy") .executes( commandContext -> setBlock( commandContext.getSource(), BlockPosArgument.getLoadedBlockPos(commandContext, "pos"), BlockStateArgument.getBlock(commandContext, "block"), SetBlockCommand.Mode.DESTROY, null, false ) ) ) .then( Commands.literal("keep") .executes( commandContext -> setBlock( commandContext.getSource(), BlockPosArgument.getLoadedBlockPos(commandContext, "pos"), BlockStateArgument.getBlock(commandContext, "block"), SetBlockCommand.Mode.REPLACE, predicate, false ) ) ) .then( Commands.literal("replace") .executes( commandContext -> setBlock( commandContext.getSource(), BlockPosArgument.getLoadedBlockPos(commandContext, "pos"), BlockStateArgument.getBlock(commandContext, "block"), SetBlockCommand.Mode.REPLACE, null, false ) ) ) .then( Commands.literal("strict") .executes( commandContext -> setBlock( commandContext.getSource(), BlockPosArgument.getLoadedBlockPos(commandContext, "pos"), BlockStateArgument.getBlock(commandContext, "block"), SetBlockCommand.Mode.REPLACE, null, true ) ) ) ) ) ); } private static int setBlock( CommandSourceStack source, BlockPos pos, BlockInput block, SetBlockCommand.Mode mode, @Nullable Predicate filter, boolean strict ) throws CommandSyntaxException { ServerLevel serverLevel = source.getLevel(); if (serverLevel.isDebug()) { throw ERROR_FAILED.create(); } else if (filter != null && !filter.test(new BlockInWorld(serverLevel, pos, true))) { throw ERROR_FAILED.create(); } else { boolean bl; if (mode == SetBlockCommand.Mode.DESTROY) { serverLevel.destroyBlock(pos, true); bl = !block.getState().isAir() || !serverLevel.getBlockState(pos).isAir(); } else { bl = true; } if (bl && !block.place(serverLevel, pos, 2 | (strict ? 816 : 256))) { throw ERROR_FAILED.create(); } else { if (!strict) { serverLevel.updateNeighborsAt(pos, block.getState().getBlock()); } source.sendSuccess(() -> Component.translatable("commands.setblock.success", pos.getX(), pos.getY(), pos.getZ()), true); return 1; } } } public static enum Mode { REPLACE, DESTROY; } }