2025-11-24 22:52:51 +03:00

155 lines
10 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.collect.Lists
* com.mojang.brigadier.CommandDispatcher
* com.mojang.brigadier.Message
* com.mojang.brigadier.builder.ArgumentBuilder
* com.mojang.brigadier.builder.LiteralArgumentBuilder
* com.mojang.brigadier.context.CommandContext
* com.mojang.brigadier.exceptions.CommandSyntaxException
* com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType
* com.mojang.brigadier.exceptions.SimpleCommandExceptionType
* org.jspecify.annotations.Nullable
*/
package net.minecraft.server.commands;
import com.google.common.collect.Lists;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import java.util.ArrayList;
import java.util.Collections;
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.BlockPredicateArgument;
import net.minecraft.commands.arguments.blocks.BlockStateArgument;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.network.chat.Component;
import net.minecraft.server.commands.InCommandFunction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import org.jspecify.annotations.Nullable;
public class FillCommand {
private static final Dynamic2CommandExceptionType ERROR_AREA_TOO_LARGE = new Dynamic2CommandExceptionType((max, count) -> Component.translatableEscape("commands.fill.toobig", max, count));
private static final BlockInput HOLLOW_CORE = new BlockInput(Blocks.AIR.defaultBlockState(), Collections.emptySet(), null);
private static final SimpleCommandExceptionType ERROR_FAILED = new SimpleCommandExceptionType((Message)Component.translatable("commands.fill.failed"));
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext context) {
dispatcher.register((LiteralArgumentBuilder)((LiteralArgumentBuilder)Commands.literal("fill").requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS))).then(Commands.argument("from", BlockPosArgument.blockPos()).then(Commands.argument("to", BlockPosArgument.blockPos()).then(FillCommand.wrapWithMode(context, Commands.argument("block", BlockStateArgument.block(context)), c -> BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "from"), c -> BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "to"), c -> BlockStateArgument.getBlock((CommandContext<CommandSourceStack>)c, "block"), c -> null).then(((LiteralArgumentBuilder)Commands.literal("replace").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners(BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "from"), BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "to")), BlockStateArgument.getBlock((CommandContext<CommandSourceStack>)c, "block"), Mode.REPLACE, null, false))).then(FillCommand.wrapWithMode(context, Commands.argument("filter", BlockPredicateArgument.blockPredicate(context)), c -> BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "from"), c -> BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "to"), c -> BlockStateArgument.getBlock((CommandContext<CommandSourceStack>)c, "block"), c -> BlockPredicateArgument.getBlockPredicate((CommandContext<CommandSourceStack>)c, "filter")))).then(Commands.literal("keep").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners(BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "from"), BlockPosArgument.getLoadedBlockPos((CommandContext<CommandSourceStack>)c, "to")), BlockStateArgument.getBlock((CommandContext<CommandSourceStack>)c, "block"), Mode.REPLACE, b -> b.getLevel().isEmptyBlock(b.getPos()), false)))))));
}
private static ArgumentBuilder<CommandSourceStack, ?> wrapWithMode(CommandBuildContext context, ArgumentBuilder<CommandSourceStack, ?> builder, InCommandFunction<CommandContext<CommandSourceStack>, BlockPos> from, InCommandFunction<CommandContext<CommandSourceStack>, BlockPos> to, InCommandFunction<CommandContext<CommandSourceStack>, BlockInput> block, NullableCommandFunction<CommandContext<CommandSourceStack>, Predicate<BlockInWorld>> filter) {
return builder.executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners((Vec3i)from.apply(c), (Vec3i)to.apply(c)), (BlockInput)block.apply(c), Mode.REPLACE, (Predicate)filter.apply(c), false)).then(Commands.literal("outline").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners((Vec3i)from.apply(c), (Vec3i)to.apply(c)), (BlockInput)block.apply(c), Mode.OUTLINE, (Predicate)filter.apply(c), false))).then(Commands.literal("hollow").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners((Vec3i)from.apply(c), (Vec3i)to.apply(c)), (BlockInput)block.apply(c), Mode.HOLLOW, (Predicate)filter.apply(c), false))).then(Commands.literal("destroy").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners((Vec3i)from.apply(c), (Vec3i)to.apply(c)), (BlockInput)block.apply(c), Mode.DESTROY, (Predicate)filter.apply(c), false))).then(Commands.literal("strict").executes(c -> FillCommand.fillBlocks((CommandSourceStack)c.getSource(), BoundingBox.fromCorners((Vec3i)from.apply(c), (Vec3i)to.apply(c)), (BlockInput)block.apply(c), Mode.REPLACE, (Predicate)filter.apply(c), true)));
}
private static int fillBlocks(CommandSourceStack source, BoundingBox region, BlockInput target, Mode mode, @Nullable Predicate<BlockInWorld> predicate, boolean strict) throws CommandSyntaxException {
record UpdatedPosition(BlockPos pos, BlockState oldState) {
}
int limit;
int area = region.getXSpan() * region.getYSpan() * region.getZSpan();
if (area > (limit = source.getLevel().getGameRules().get(GameRules.MAX_BLOCK_MODIFICATIONS).intValue())) {
throw ERROR_AREA_TOO_LARGE.create((Object)limit, (Object)area);
}
ArrayList updatePositions = Lists.newArrayList();
ServerLevel level = source.getLevel();
if (level.isDebug()) {
throw ERROR_FAILED.create();
}
int count = 0;
for (BlockPos blockPos : BlockPos.betweenClosed(region.minX(), region.minY(), region.minZ(), region.maxX(), region.maxY(), region.maxZ())) {
BlockInput block;
if (predicate != null && !predicate.test(new BlockInWorld(level, blockPos, true))) continue;
BlockState oldState = level.getBlockState(blockPos);
boolean affected = false;
if (mode.affector.affect(level, blockPos)) {
affected = true;
}
if ((block = mode.filter.filter(region, blockPos, target, level)) == null) {
if (!affected) continue;
++count;
continue;
}
if (!block.place(level, blockPos, 2 | (strict ? 816 : 256))) {
if (!affected) continue;
++count;
continue;
}
if (!strict) {
updatePositions.add(new UpdatedPosition(blockPos.immutable(), oldState));
}
++count;
}
for (UpdatedPosition updatedPosition : updatePositions) {
level.updateNeighboursOnBlockSet(updatedPosition.pos, updatedPosition.oldState);
}
if (count == 0) {
throw ERROR_FAILED.create();
}
int finalCount = count;
source.sendSuccess(() -> Component.translatable("commands.fill.success", finalCount), true);
return count;
}
@FunctionalInterface
private static interface NullableCommandFunction<T, R> {
public @Nullable R apply(T var1) throws CommandSyntaxException;
}
private static enum Mode {
REPLACE(Affector.NOOP, Filter.NOOP),
OUTLINE(Affector.NOOP, (r, p, b, l) -> {
if (p.getX() == r.minX() || p.getX() == r.maxX() || p.getY() == r.minY() || p.getY() == r.maxY() || p.getZ() == r.minZ() || p.getZ() == r.maxZ()) {
return b;
}
return null;
}),
HOLLOW(Affector.NOOP, (r, p, b, l) -> {
if (p.getX() == r.minX() || p.getX() == r.maxX() || p.getY() == r.minY() || p.getY() == r.maxY() || p.getZ() == r.minZ() || p.getZ() == r.maxZ()) {
return b;
}
return HOLLOW_CORE;
}),
DESTROY((l, p) -> l.destroyBlock(p, true), Filter.NOOP);
public final Filter filter;
public final Affector affector;
private Mode(Affector affector, Filter filter) {
this.affector = affector;
this.filter = filter;
}
}
@FunctionalInterface
public static interface Affector {
public static final Affector NOOP = (l, p) -> false;
public boolean affect(ServerLevel var1, BlockPos var2);
}
@FunctionalInterface
public static interface Filter {
public static final Filter NOOP = (r, p, b, l) -> b;
public @Nullable BlockInput filter(BoundingBox var1, BlockPos var2, BlockInput var3, ServerLevel var4);
}
}