240 lines
10 KiB
Java
240 lines
10 KiB
Java
package net.minecraft.server.commands;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
|
import com.mojang.brigadier.context.CommandContext;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
|
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
|
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.commands.Commands;
|
|
import net.minecraft.commands.SharedSuggestionProvider;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.chat.ComponentUtils;
|
|
import net.minecraft.server.packs.repository.Pack;
|
|
import net.minecraft.server.packs.repository.PackRepository;
|
|
import net.minecraft.server.packs.repository.PackSource;
|
|
import net.minecraft.world.flag.FeatureFlagSet;
|
|
import net.minecraft.world.flag.FeatureFlags;
|
|
|
|
public class DataPackCommand {
|
|
private static final DynamicCommandExceptionType ERROR_UNKNOWN_PACK = new DynamicCommandExceptionType(
|
|
object -> Component.translatableEscape("commands.datapack.unknown", object)
|
|
);
|
|
private static final DynamicCommandExceptionType ERROR_PACK_ALREADY_ENABLED = new DynamicCommandExceptionType(
|
|
object -> Component.translatableEscape("commands.datapack.enable.failed", object)
|
|
);
|
|
private static final DynamicCommandExceptionType ERROR_PACK_ALREADY_DISABLED = new DynamicCommandExceptionType(
|
|
object -> Component.translatableEscape("commands.datapack.disable.failed", object)
|
|
);
|
|
private static final DynamicCommandExceptionType ERROR_CANNOT_DISABLE_FEATURE = new DynamicCommandExceptionType(
|
|
object -> Component.translatableEscape("commands.datapack.disable.failed.feature", object)
|
|
);
|
|
private static final Dynamic2CommandExceptionType ERROR_PACK_FEATURES_NOT_ENABLED = new Dynamic2CommandExceptionType(
|
|
(object, object2) -> Component.translatableEscape("commands.datapack.enable.failed.no_flags", object, object2)
|
|
);
|
|
private static final SuggestionProvider<CommandSourceStack> SELECTED_PACKS = (commandContext, suggestionsBuilder) -> SharedSuggestionProvider.suggest(
|
|
commandContext.getSource().getServer().getPackRepository().getSelectedIds().stream().map(StringArgumentType::escapeIfRequired), suggestionsBuilder
|
|
);
|
|
private static final SuggestionProvider<CommandSourceStack> UNSELECTED_PACKS = (commandContext, suggestionsBuilder) -> {
|
|
PackRepository packRepository = commandContext.getSource().getServer().getPackRepository();
|
|
Collection<String> collection = packRepository.getSelectedIds();
|
|
FeatureFlagSet featureFlagSet = commandContext.getSource().enabledFeatures();
|
|
return SharedSuggestionProvider.suggest(
|
|
packRepository.getAvailablePacks()
|
|
.stream()
|
|
.filter(pack -> pack.getRequestedFeatures().isSubsetOf(featureFlagSet))
|
|
.map(Pack::getId)
|
|
.filter(string -> !collection.contains(string))
|
|
.map(StringArgumentType::escapeIfRequired),
|
|
suggestionsBuilder
|
|
);
|
|
};
|
|
|
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
|
dispatcher.register(
|
|
Commands.literal("datapack")
|
|
.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
|
|
.then(
|
|
Commands.literal("enable")
|
|
.then(
|
|
Commands.argument("name", StringArgumentType.string())
|
|
.suggests(UNSELECTED_PACKS)
|
|
.executes(
|
|
commandContext -> enablePack(
|
|
commandContext.getSource(),
|
|
getPack(commandContext, "name", true),
|
|
(list, pack) -> pack.getDefaultPosition().insert(list, pack, Pack::selectionConfig, false)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("after")
|
|
.then(
|
|
Commands.argument("existing", StringArgumentType.string())
|
|
.suggests(SELECTED_PACKS)
|
|
.executes(
|
|
commandContext -> enablePack(
|
|
commandContext.getSource(),
|
|
getPack(commandContext, "name", true),
|
|
(list, pack) -> list.add(list.indexOf(getPack(commandContext, "existing", false)) + 1, pack)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("before")
|
|
.then(
|
|
Commands.argument("existing", StringArgumentType.string())
|
|
.suggests(SELECTED_PACKS)
|
|
.executes(
|
|
commandContext -> enablePack(
|
|
commandContext.getSource(),
|
|
getPack(commandContext, "name", true),
|
|
(list, pack) -> list.add(list.indexOf(getPack(commandContext, "existing", false)), pack)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
.then(Commands.literal("last").executes(commandContext -> enablePack(commandContext.getSource(), getPack(commandContext, "name", true), List::add)))
|
|
.then(
|
|
Commands.literal("first")
|
|
.executes(commandContext -> enablePack(commandContext.getSource(), getPack(commandContext, "name", true), (list, pack) -> list.add(0, pack)))
|
|
)
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("disable")
|
|
.then(
|
|
Commands.argument("name", StringArgumentType.string())
|
|
.suggests(SELECTED_PACKS)
|
|
.executes(commandContext -> disablePack(commandContext.getSource(), getPack(commandContext, "name", false)))
|
|
)
|
|
)
|
|
.then(
|
|
Commands.literal("list")
|
|
.executes(commandContext -> listPacks(commandContext.getSource()))
|
|
.then(Commands.literal("available").executes(commandContext -> listAvailablePacks(commandContext.getSource())))
|
|
.then(Commands.literal("enabled").executes(commandContext -> listEnabledPacks(commandContext.getSource())))
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Enables the given pack.
|
|
*
|
|
* @return The number of packs that are loaded after this operation.
|
|
*/
|
|
private static int enablePack(CommandSourceStack source, Pack pack, DataPackCommand.Inserter priorityCallback) throws CommandSyntaxException {
|
|
PackRepository packRepository = source.getServer().getPackRepository();
|
|
List<Pack> list = Lists.<Pack>newArrayList(packRepository.getSelectedPacks());
|
|
priorityCallback.apply(list, pack);
|
|
source.sendSuccess(() -> Component.translatable("commands.datapack.modify.enable", pack.getChatLink(true)), true);
|
|
ReloadCommand.reloadPacks((Collection<String>)list.stream().map(Pack::getId).collect(Collectors.toList()), source);
|
|
return list.size();
|
|
}
|
|
|
|
/**
|
|
* Disables the given pack.
|
|
*
|
|
* @return The number of packs that are loaded after this operation.
|
|
*/
|
|
private static int disablePack(CommandSourceStack source, Pack pack) {
|
|
PackRepository packRepository = source.getServer().getPackRepository();
|
|
List<Pack> list = Lists.<Pack>newArrayList(packRepository.getSelectedPacks());
|
|
list.remove(pack);
|
|
source.sendSuccess(() -> Component.translatable("commands.datapack.modify.disable", pack.getChatLink(true)), true);
|
|
ReloadCommand.reloadPacks((Collection<String>)list.stream().map(Pack::getId).collect(Collectors.toList()), source);
|
|
return list.size();
|
|
}
|
|
|
|
/**
|
|
* Sends a list of both enabled and available packs to the user.
|
|
*
|
|
* @return The total number of packs.
|
|
*/
|
|
private static int listPacks(CommandSourceStack source) {
|
|
return listEnabledPacks(source) + listAvailablePacks(source);
|
|
}
|
|
|
|
/**
|
|
* Sends a list of available packs to the user.
|
|
*
|
|
* @return The number of available packs.
|
|
*/
|
|
private static int listAvailablePacks(CommandSourceStack source) {
|
|
PackRepository packRepository = source.getServer().getPackRepository();
|
|
packRepository.reload();
|
|
Collection<Pack> collection = packRepository.getSelectedPacks();
|
|
Collection<Pack> collection2 = packRepository.getAvailablePacks();
|
|
FeatureFlagSet featureFlagSet = source.enabledFeatures();
|
|
List<Pack> list = collection2.stream().filter(pack -> !collection.contains(pack) && pack.getRequestedFeatures().isSubsetOf(featureFlagSet)).toList();
|
|
if (list.isEmpty()) {
|
|
source.sendSuccess(() -> Component.translatable("commands.datapack.list.available.none"), false);
|
|
} else {
|
|
source.sendSuccess(
|
|
() -> Component.translatable("commands.datapack.list.available.success", list.size(), ComponentUtils.formatList(list, pack -> pack.getChatLink(false))),
|
|
false
|
|
);
|
|
}
|
|
|
|
return list.size();
|
|
}
|
|
|
|
/**
|
|
* Sends a list of enabled packs to the user.
|
|
*
|
|
* @return The number of enabled packs.
|
|
*/
|
|
private static int listEnabledPacks(CommandSourceStack source) {
|
|
PackRepository packRepository = source.getServer().getPackRepository();
|
|
packRepository.reload();
|
|
Collection<? extends Pack> collection = packRepository.getSelectedPacks();
|
|
if (collection.isEmpty()) {
|
|
source.sendSuccess(() -> Component.translatable("commands.datapack.list.enabled.none"), false);
|
|
} else {
|
|
source.sendSuccess(
|
|
() -> Component.translatable(
|
|
"commands.datapack.list.enabled.success", collection.size(), ComponentUtils.formatList(collection, pack -> pack.getChatLink(true))
|
|
),
|
|
false
|
|
);
|
|
}
|
|
|
|
return collection.size();
|
|
}
|
|
|
|
private static Pack getPack(CommandContext<CommandSourceStack> context, String name, boolean enabling) throws CommandSyntaxException {
|
|
String string = StringArgumentType.getString(context, name);
|
|
PackRepository packRepository = context.getSource().getServer().getPackRepository();
|
|
Pack pack = packRepository.getPack(string);
|
|
if (pack == null) {
|
|
throw ERROR_UNKNOWN_PACK.create(string);
|
|
} else {
|
|
boolean bl = packRepository.getSelectedPacks().contains(pack);
|
|
if (enabling && bl) {
|
|
throw ERROR_PACK_ALREADY_ENABLED.create(string);
|
|
} else if (!enabling && !bl) {
|
|
throw ERROR_PACK_ALREADY_DISABLED.create(string);
|
|
} else {
|
|
FeatureFlagSet featureFlagSet = context.getSource().enabledFeatures();
|
|
FeatureFlagSet featureFlagSet2 = pack.getRequestedFeatures();
|
|
if (!enabling && !featureFlagSet2.isEmpty() && pack.getPackSource() == PackSource.FEATURE) {
|
|
throw ERROR_CANNOT_DISABLE_FEATURE.create(string);
|
|
} else if (!featureFlagSet2.isSubsetOf(featureFlagSet)) {
|
|
throw ERROR_PACK_FEATURES_NOT_ENABLED.create(string, FeatureFlags.printMissingFlags(featureFlagSet, featureFlagSet2));
|
|
} else {
|
|
return pack;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
interface Inserter {
|
|
void apply(List<Pack> list, Pack pack) throws CommandSyntaxException;
|
|
}
|
|
}
|