minecraft-src/net/minecraft/server/commands/RandomCommand.java
2025-07-04 01:41:11 +03:00

200 lines
8.6 KiB
Java

package net.minecraft.server.commands;
import com.google.common.collect.Lists;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import net.minecraft.advancements.critereon.MinMaxBounds;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.RangeArgument;
import net.minecraft.commands.arguments.ResourceLocationArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.RandomSequences;
import org.jetbrains.annotations.Nullable;
public class RandomCommand {
private static final SimpleCommandExceptionType ERROR_RANGE_TOO_LARGE = new SimpleCommandExceptionType(
Component.translatable("commands.random.error.range_too_large")
);
private static final SimpleCommandExceptionType ERROR_RANGE_TOO_SMALL = new SimpleCommandExceptionType(
Component.translatable("commands.random.error.range_too_small")
);
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(
Commands.literal("random")
.then(drawRandomValueTree("value", false))
.then(drawRandomValueTree("roll", true))
.then(
Commands.literal("reset")
.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
.then(
Commands.literal("*")
.executes(commandContext -> resetAllSequences(commandContext.getSource()))
.then(
Commands.argument("seed", IntegerArgumentType.integer())
.executes(
commandContext -> resetAllSequencesAndSetNewDefaults(commandContext.getSource(), IntegerArgumentType.getInteger(commandContext, "seed"), true, true)
)
.then(
Commands.argument("includeWorldSeed", BoolArgumentType.bool())
.executes(
commandContext -> resetAllSequencesAndSetNewDefaults(
commandContext.getSource(),
IntegerArgumentType.getInteger(commandContext, "seed"),
BoolArgumentType.getBool(commandContext, "includeWorldSeed"),
true
)
)
.then(
Commands.argument("includeSequenceId", BoolArgumentType.bool())
.executes(
commandContext -> resetAllSequencesAndSetNewDefaults(
commandContext.getSource(),
IntegerArgumentType.getInteger(commandContext, "seed"),
BoolArgumentType.getBool(commandContext, "includeWorldSeed"),
BoolArgumentType.getBool(commandContext, "includeSequenceId")
)
)
)
)
)
)
.then(
Commands.argument("sequence", ResourceLocationArgument.id())
.suggests(RandomCommand::suggestRandomSequence)
.executes(commandContext -> resetSequence(commandContext.getSource(), ResourceLocationArgument.getId(commandContext, "sequence")))
.then(
Commands.argument("seed", IntegerArgumentType.integer())
.executes(
commandContext -> resetSequence(
commandContext.getSource(),
ResourceLocationArgument.getId(commandContext, "sequence"),
IntegerArgumentType.getInteger(commandContext, "seed"),
true,
true
)
)
.then(
Commands.argument("includeWorldSeed", BoolArgumentType.bool())
.executes(
commandContext -> resetSequence(
commandContext.getSource(),
ResourceLocationArgument.getId(commandContext, "sequence"),
IntegerArgumentType.getInteger(commandContext, "seed"),
BoolArgumentType.getBool(commandContext, "includeWorldSeed"),
true
)
)
.then(
Commands.argument("includeSequenceId", BoolArgumentType.bool())
.executes(
commandContext -> resetSequence(
commandContext.getSource(),
ResourceLocationArgument.getId(commandContext, "sequence"),
IntegerArgumentType.getInteger(commandContext, "seed"),
BoolArgumentType.getBool(commandContext, "includeWorldSeed"),
BoolArgumentType.getBool(commandContext, "includeSequenceId")
)
)
)
)
)
)
)
);
}
private static LiteralArgumentBuilder<CommandSourceStack> drawRandomValueTree(String subcommand, boolean displayResult) {
return Commands.literal(subcommand)
.then(
Commands.argument("range", RangeArgument.intRange())
.executes(commandContext -> randomSample(commandContext.getSource(), RangeArgument.Ints.getRange(commandContext, "range"), null, displayResult))
.then(
Commands.argument("sequence", ResourceLocationArgument.id())
.suggests(RandomCommand::suggestRandomSequence)
.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
.executes(
commandContext -> randomSample(
commandContext.getSource(),
RangeArgument.Ints.getRange(commandContext, "range"),
ResourceLocationArgument.getId(commandContext, "sequence"),
displayResult
)
)
)
);
}
private static CompletableFuture<Suggestions> suggestRandomSequence(CommandContext<CommandSourceStack> context, SuggestionsBuilder suggestionsBuilder) {
List<String> list = Lists.<String>newArrayList();
context.getSource().getLevel().getRandomSequences().forAllSequences((resourceLocation, randomSequence) -> list.add(resourceLocation.toString()));
return SharedSuggestionProvider.suggest(list, suggestionsBuilder);
}
private static int randomSample(CommandSourceStack source, MinMaxBounds.Ints range, @Nullable ResourceLocation sequence, boolean displayResult) throws CommandSyntaxException {
RandomSource randomSource;
if (sequence != null) {
randomSource = source.getLevel().getRandomSequence(sequence);
} else {
randomSource = source.getLevel().getRandom();
}
int i = (Integer)range.min().orElse(Integer.MIN_VALUE);
int j = (Integer)range.max().orElse(Integer.MAX_VALUE);
long l = (long)j - i;
if (l == 0L) {
throw ERROR_RANGE_TOO_SMALL.create();
} else if (l >= 2147483647L) {
throw ERROR_RANGE_TOO_LARGE.create();
} else {
int k = Mth.randomBetweenInclusive(randomSource, i, j);
if (displayResult) {
source.getServer().getPlayerList().broadcastSystemMessage(Component.translatable("commands.random.roll", source.getDisplayName(), k, i, j), false);
} else {
source.sendSuccess(() -> Component.translatable("commands.random.sample.success", k), false);
}
return k;
}
}
private static int resetSequence(CommandSourceStack source, ResourceLocation sequence) throws CommandSyntaxException {
source.getLevel().getRandomSequences().reset(sequence);
source.sendSuccess(() -> Component.translatable("commands.random.reset.success", Component.translationArg(sequence)), false);
return 1;
}
private static int resetSequence(CommandSourceStack source, ResourceLocation sequence, int seed, boolean includeWorldSeed, boolean includeSequenceId) throws CommandSyntaxException {
source.getLevel().getRandomSequences().reset(sequence, seed, includeWorldSeed, includeSequenceId);
source.sendSuccess(() -> Component.translatable("commands.random.reset.success", Component.translationArg(sequence)), false);
return 1;
}
private static int resetAllSequences(CommandSourceStack source) {
int i = source.getLevel().getRandomSequences().clear();
source.sendSuccess(() -> Component.translatable("commands.random.reset.all.success", i), false);
return i;
}
private static int resetAllSequencesAndSetNewDefaults(CommandSourceStack source, int seed, boolean includeWorldSeed, boolean includeSequenceId) {
RandomSequences randomSequences = source.getLevel().getRandomSequences();
randomSequences.setSeedDefaults(seed, includeWorldSeed, includeSequenceId);
int i = randomSequences.clear();
source.sendSuccess(() -> Component.translatable("commands.random.reset.all.success", i), false);
return i;
}
}