minecraft-src/net/minecraft/server/commands/SetBlockCommand.java
2025-07-04 03:45:38 +03:00

132 lines
4.5 KiB
Java

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<CommandSourceStack> dispatcher, CommandBuildContext buildContext) {
Predicate<BlockInWorld> 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<BlockInWorld> 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;
}
}