Add /iris language and /iris debugdump on both platforms

/iris language opens a locale menu and sets the language for the caller
or, for a gamemaster, the server default; /iris debugdump writes a
diagnostic report and optionally uploads it. Neither needs iris.all, so
a plain player can reach them. Every modded command now executes inside
a language audience scope, and the Bukkit dispatcher opens one around
execution, tab completion and help. Permissions, message keys and the
shipped locales follow.
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-03 05:03:28 -04:00
1 parent b25937f986
commit 657aaeaccf
39 files changed
+654 -226

No files matched your search

@@ -435,6 +435,7 @@ public final class ModdedEngineBootstrap {
}
private static void restorePlatform(IrisPlatform platform) {
IrisLanguage.shutdown();
IrisPlatforms.unbind();
if (platform != null) {
IrisPlatforms.bind(platform);
@@ -18,7 +18,10 @@
package art.arcane.iris.modded.command;
import art.arcane.volmlib.util.localization.LanguageAudience;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import net.minecraft.server.level.ServerPlayer;
import com.mojang.brigadier.arguments.LongArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
@@ -66,16 +69,17 @@ final class ModdedCommandTree {
static LiteralArgumentBuilder<CommandSourceStack> rootTree() {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal("iris");
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), ""));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "")));
root.then(helpTree());
root.then(ModdedLanguageCommands.tree());
root.then(Commands.literal("version").requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.version(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.version(context.getSource()))));
root.then(Commands.literal("info").requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null)))
.then(Commands.argument("dimension", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.DIMENSION_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), StringArgumentType.getString(context, "dimension")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), StringArgumentType.getString(context, "dimension"))))));
// ModdedWhatCommands.tree() gates itself at LEVEL_GAMEMASTERS and keeps that gate:
// "what markers" drives lease-gated 9x9 mantle scans, and the Bukkit twin puts the
@@ -86,27 +90,27 @@ final class ModdedCommandTree {
root.then(teleportTree("tp"));
root.then(Commands.literal("evacuate").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.evacuate(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.evacuate(context.getSource(), null)))
.then(Commands.argument("dimension", DimensionArgument.dimension()).suggests(ModdedCommandSuggestions.DIMENSION_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.evacuate(context.getSource(), DimensionArgument.getDimension(context, "dimension")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.evacuate(context.getSource(), DimensionArgument.getDimension(context, "dimension"))))));
root.then(Commands.literal("debug").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.debug(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.debug(context.getSource()))));
root.then(Commands.literal("reload").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.reload(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.reload(context.getSource()))));
root.then(Commands.literal("height").requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.height(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.height(context.getSource()))));
root.then(Commands.literal("worlds").requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null))));
root.then(Commands.literal("accesslist").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.info(context.getSource(), null))));
root.then(gotoTree("goto"));
root.then(gotoTree("find"));
root.then(Commands.literal("seed").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.seed(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.seed(context.getSource()))));
root.then(goldenhashTree("goldenhash"));
root.then(goldenhashTree("gold"));
@@ -124,11 +128,11 @@ final class ModdedCommandTree {
root.then(pregenTree("pregenerate"));
root.then(Commands.literal("wand").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveWand(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveWand(context.getSource()))));
root.then(Commands.literal("dust").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveDust(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveDust(context.getSource()))));
root.then(Commands.literal("d").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveDust(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedObjectCommands.giveDust(context.getSource()))));
root.then(ModdedObjectCommands.tree("object"));
root.then(ModdedObjectCommands.tree("o"));
root.then(editTree());
@@ -155,122 +159,131 @@ final class ModdedCommandTree {
return root;
}
static Command<CommandSourceStack> localized(Command<CommandSourceStack> command) {
return context -> {
ServerPlayer player = context.getSource().getPlayer();
try (LanguageAudience.Scope audience = LanguageAudience.open(player == null ? null : player.getUUID())) {
return command.run(context);
}
};
}
private static LiteralArgumentBuilder<CommandSourceStack> createTree(String name) {
return Commands.literal(name).requires(GATE)
.then(Commands.argument("name", StringArgumentType.word())
.executes((CommandContext<CommandSourceStack> context) ->
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
ModdedWorldCommands.createWorld(
context.getSource(),
StringArgumentType.getString(context, "name"),
"overworld",
1337L))
1337L)))
.then(Commands.argument("pack", StringArgumentType.string()).suggests(ModdedCommandSuggestions.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> ModdedWorldCommands.createWorld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedWorldCommands.createWorld(context.getSource(),
StringArgumentType.getString(context, "name"),
StringArgumentType.getString(context, "pack"),
1337L))
1337L)))
.then(Commands.argument("seed", LongArgumentType.longArg())
.executes((CommandContext<CommandSourceStack> context) -> ModdedWorldCommands.createWorld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedWorldCommands.createWorld(context.getSource(),
StringArgumentType.getString(context, "name"),
StringArgumentType.getString(context, "pack"),
LongArgumentType.getLong(context, "seed"))))));
LongArgumentType.getLong(context, "seed")))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> teleportTree(String name) {
return Commands.literal(name).requires(GATE)
.then(Commands.argument("dimension", DimensionArgument.dimension()).suggests(ModdedCommandSuggestions.DIMENSION_NAMES)
.executes((CommandContext<CommandSourceStack> context) ->
IrisModdedCommands.tp(context.getSource(), DimensionArgument.getDimension(context, "dimension"), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
IrisModdedCommands.tp(context.getSource(), DimensionArgument.getDimension(context, "dimension"), null)))
.then(Commands.argument("player", EntityArgument.player())
.executes((CommandContext<CommandSourceStack> context) ->
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
IrisModdedCommands.tp(context.getSource(), DimensionArgument.getDimension(context, "dimension"),
EntityArgument.getPlayer(context, "player")))));
EntityArgument.getPlayer(context, "player"))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> helpTree() {
return Commands.literal("help").requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), ""))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "")))
.then(Commands.argument("section", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), StringArgumentType.getString(context, "section"))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), StringArgumentType.getString(context, "section")))));
}
private static LiteralArgumentBuilder<CommandSourceStack> downloadTree(String name) {
return Commands.literal(name).requires(GATE)
.then(Commands.argument("source", StringArgumentType.greedyString()).suggests(DOWNLOAD_SOURCES)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.download(
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.download(
context.getSource(),
StringArgumentType.getString(context, "source")
)));
))));
}
private static LiteralArgumentBuilder<CommandSourceStack> metricsTree(String name) {
return Commands.literal(name).requires(READ_ONLY)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.metrics(context.getSource()));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.metrics(context.getSource())));
}
private static LiteralArgumentBuilder<CommandSourceStack> regenTree(String name) {
return Commands.literal(name).requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.regen(context.getSource(), 0))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.regen(context.getSource(), 0)))
.then(Commands.argument("radius", IntegerArgumentType.integer(0, 64))
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.regen(context.getSource(), IntegerArgumentType.getInteger(context, "radius"))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.regen(context.getSource(), IntegerArgumentType.getInteger(context, "radius")))));
}
private static LiteralArgumentBuilder<CommandSourceStack> gotoTree(String name) {
return Commands.literal(name).requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)))
.then(Commands.literal("biome")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.BIOME_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoBiome(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoBiome(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("region")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.REGION_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoRegion(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoRegion(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("object")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoObject(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoObject(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("river")
.then(Commands.argument("type", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.HYDROLOGY_TYPES)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoRiver(context.getSource(), StringArgumentType.getString(context, "type")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoRiver(context.getSource(), StringArgumentType.getString(context, "type"))))))
.then(Commands.literal("unregistered")
.executes((CommandContext<CommandSourceStack> context) ->
ModdedUnregisteredStructures.print(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
ModdedUnregisteredStructures.print(context.getSource()))))
.then(Commands.literal("structure")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.STRUCTURE_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoStructure(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoStructure(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("poi")
.then(Commands.argument("type", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.POI_TYPES)
.executes((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoPoi(context.getSource(), StringArgumentType.getString(context, "type")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedLocateCommands.gotoPoi(context.getSource(), StringArgumentType.getString(context, "type"))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> pregenTree(String name) {
RequiredArgumentBuilder<CommandSourceStack, Integer> radius = Commands.argument("radius", IntegerArgumentType.integer(1, 100000))
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, false, false, false, false, false));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, false, false, false, false, false)));
attachPregenCenter(radius, false);
attachPregenFlags(radius, false, false, false, false, false);
RequiredArgumentBuilder<CommandSourceStack, Identifier> dimension = Commands.argument("dimension", DimensionArgument.dimension()).suggests(ModdedCommandSuggestions.DIMENSION_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, true, false, false, false, false));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, true, false, false, false, false)));
attachPregenCenter(dimension, true);
attachPregenFlags(dimension, true, false, false, false, false);
radius.then(dimension);
return Commands.literal(name).requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)))
.then(Commands.literal("start")
.then(radius))
.then(Commands.literal("stop")
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStop(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStop(context.getSource()))))
.then(Commands.literal("x")
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStop(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStop(context.getSource()))))
.then(Commands.literal("pause")
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenPause(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenPause(context.getSource()))))
.then(Commands.literal("resume")
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenPause(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenPause(context.getSource()))))
.then(Commands.literal("status")
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStatus(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStatus(context.getSource()))));
}
private static void attachPregenCenter(ArgumentBuilder<CommandSourceStack, ?> node, boolean withDimension) {
RequiredArgumentBuilder<CommandSourceStack, Integer> z = Commands.argument("z", IntegerArgumentType.integer())
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, withDimension, true, false, false, false));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, withDimension, true, false, false, false)));
attachPregenFlags(z, withDimension, true, false, false, false);
node.then(Commands.literal("at")
.then(Commands.argument("x", IntegerArgumentType.integer())
@@ -291,22 +304,22 @@ final class ModdedCommandTree {
private static LiteralArgumentBuilder<CommandSourceStack> pregenFlagNode(String name, boolean withDimension, boolean withCenter, boolean gui, boolean sync, boolean nocache) {
LiteralArgumentBuilder<CommandSourceStack> flag = Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, withDimension, withCenter, gui, sync, nocache));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedPregenCommands.pregenStart(context, withDimension, withCenter, gui, sync, nocache)));
attachPregenFlags(flag, withDimension, withCenter, gui, sync, nocache);
return flag;
}
private static LiteralArgumentBuilder<CommandSourceStack> goldenhashTree(String name) {
LiteralArgumentBuilder<CommandSourceStack> radiusAndThreads = Commands.literal(name).requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), 8, 8, ModdedGoldenHash.Mode.AUTO));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), 8, 8, ModdedGoldenHash.Mode.AUTO)));
attachModes(radiusAndThreads, (CommandContext<CommandSourceStack> context) -> 8, (CommandContext<CommandSourceStack> context) -> 8);
com.mojang.brigadier.builder.RequiredArgumentBuilder<CommandSourceStack, Integer> radius = Commands.argument("radius", IntegerArgumentType.integer(0, 256))
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), IntegerArgumentType.getInteger(context, "radius"), 8, ModdedGoldenHash.Mode.AUTO));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), IntegerArgumentType.getInteger(context, "radius"), 8, ModdedGoldenHash.Mode.AUTO)));
attachModes(radius, (CommandContext<CommandSourceStack> context) -> IntegerArgumentType.getInteger(context, "radius"), (CommandContext<CommandSourceStack> context) -> 8);
com.mojang.brigadier.builder.RequiredArgumentBuilder<CommandSourceStack, Integer> threads = Commands.argument("threads", IntegerArgumentType.integer(1, 64))
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), IntegerArgumentType.getInteger(context, "radius"), IntegerArgumentType.getInteger(context, "threads"), ModdedGoldenHash.Mode.AUTO));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), IntegerArgumentType.getInteger(context, "radius"), IntegerArgumentType.getInteger(context, "threads"), ModdedGoldenHash.Mode.AUTO)));
attachModes(threads, (CommandContext<CommandSourceStack> context) -> IntegerArgumentType.getInteger(context, "radius"), (CommandContext<CommandSourceStack> context) -> IntegerArgumentType.getInteger(context, "threads"));
radius.then(threads);
@@ -320,33 +333,33 @@ final class ModdedCommandTree {
private static void attachModes(com.mojang.brigadier.builder.ArgumentBuilder<CommandSourceStack, ?> node, IntExtractor radius, IntExtractor threads) {
node.then(Commands.literal("capture")
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), radius.extract(context), threads.extract(context), ModdedGoldenHash.Mode.CAPTURE)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), radius.extract(context), threads.extract(context), ModdedGoldenHash.Mode.CAPTURE))));
node.then(Commands.literal("verify")
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), radius.extract(context), threads.extract(context), ModdedGoldenHash.Mode.VERIFY)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.goldenhash(context.getSource(), radius.extract(context), threads.extract(context), ModdedGoldenHash.Mode.VERIFY))));
}
private static LiteralArgumentBuilder<CommandSourceStack> editTree() {
return Commands.literal("edit").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "edit"))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "edit")))
.then(Commands.literal("biome")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), null)))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.BIOME_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("b")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), null)))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.BIOME_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editBiome(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("region")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), null)))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.REGION_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("r")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), null)))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ModdedCommandSuggestions.REGION_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), StringArgumentType.getString(context, "key")))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editRegion(context.getSource(), StringArgumentType.getString(context, "key"))))))
.then(Commands.literal("dimension")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editDimension(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editDimension(context.getSource()))))
.then(Commands.literal("d")
.executes((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editDimension(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedEditCommands.editDimension(context.getSource()))));
}
}
@@ -64,18 +64,18 @@ public final class ModdedDatapackCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(Commands.literal("status")
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource()))));
root.then(Commands.literal("install")
.executes((CommandContext<CommandSourceStack> context) -> install(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> install(context.getSource()))));
root.then(Commands.literal("list")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(Commands.literal("ls")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(message("ingest", "Managed Modrinth datapack ingest is Bukkit-only. On modded servers install the datapack folder or zip in world/datapacks, enable it, restart, then use /iris datapack list to confirm it is enabled. Registered structures generate natively in Iris dimensions."));
root.then(message("pull", "Managed Modrinth datapack ingest is Bukkit-only. On modded servers install the datapack folder or zip in world/datapacks, enable it, restart, then use /iris datapack list to confirm it is enabled. Registered structures generate natively in Iris dimensions."));
@@ -88,15 +88,15 @@ public final class ModdedDatapackCommands {
private static LiteralArgumentBuilder<CommandSourceStack> message(String name, String text) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
})
}))
.then(Commands.argument("args", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
}));
})));
}
private static File worldDatapacksFolder(MinecraftServer server) {
@@ -42,11 +42,11 @@ final class ModdedDeveloperCommands {
static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
return Commands.literal(name).requires(GATE)
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "developer"))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "developer")))
.then(Commands.literal("network")
.executes((CommandContext<CommandSourceStack> context) -> network(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> network(context.getSource()))))
.then(Commands.literal("ip")
.executes((CommandContext<CommandSourceStack> context) -> network(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> network(context.getSource()))));
}
private static int network(CommandSourceStack source) {
@@ -0,0 +1,92 @@
package art.arcane.iris.modded.command;
import art.arcane.iris.core.localization.IrisLanguage;
import art.arcane.iris.spi.IrisLogging;
import art.arcane.volmlib.util.director.help.DirectorHelpMessages;
import art.arcane.volmlib.util.localization.PluginLanguageService;
import art.arcane.volmlib.util.localization.VolmitLocales;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
final class ModdedLanguageCommands {
private ModdedLanguageCommands() {
}
static LiteralArgumentBuilder<CommandSourceStack> tree() {
return Commands.literal("language")
.executes(ModdedCommandTree.localized(context -> open(context.getSource())))
.then(scope("self", false))
.then(scope("server", true).requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS)));
}
private static LiteralArgumentBuilder<CommandSourceStack> scope(String name, boolean server) {
return Commands.literal(name)
.then(Commands.argument("locale", StringArgumentType.word())
.suggests((context, builder) -> SharedSuggestionProvider.suggest(IrisLanguage.availableLocales(), builder))
.executes(ModdedCommandTree.localized(context -> select(context.getSource(), server, StringArgumentType.getString(context, "locale")))));
}
private static int open(CommandSourceStack source) {
ModdedCommandFeedback.clear(source);
ModdedCommandFeedback.send(source, ModdedCommandFeedback.banner("/iris language"));
ModdedCommandFeedback.send(source, ModdedCommandFeedback.button(
"〈 " + IrisLanguage.plain(DirectorHelpMessages.BACK), "/iris", "Iris", true));
ModdedCommandFeedback.send(source, ModdedCommandFeedback.text(
"Iris language: " + IrisLanguage.activeLocale(), ModdedCommandFeedback.DESCRIPTION));
for (String locale : IrisLanguage.availableLocales()) {
String name = VolmitLocales.displayName(locale).orElse(locale);
ModdedCommandFeedback.send(source, ModdedCommandFeedback.text("⇀ ", ModdedCommandFeedback.DARK_GREEN)
.append(ModdedCommandFeedback.button(name + " [me]", "/iris language self " + locale, "Use " + name, true))
.append(ModdedCommandTree.isGamemaster(source)
? ModdedCommandFeedback.button(" [server]", "/iris language server " + locale, "Set the server default", true)
: Component.empty()));
}
ModdedCommandFeedback.send(source, ModdedCommandFeedback.button(
"Use server default", "/iris language self reset", "Clear your personal language", true));
ModdedCommandFeedback.ok(source, ModdedCommandFeedback.footer());
return 1;
}
private static int select(CommandSourceStack source, boolean server, String locale) {
PluginLanguageService service = IrisLanguage.selections();
if (service == null) {
source.sendFailure(Component.literal("Iris language service is unavailable."));
return 0;
}
CompletableFuture<String> selection;
if (server) {
selection = service.selectDefault(locale).thenApply(ignored -> service.defaultLocale());
} else {
ServerPlayer player = source.getPlayer();
if (player == null) {
source.sendFailure(Component.literal("Personal language selection requires a player."));
return 0;
}
UUID playerId = player.getUUID();
CompletableFuture<Void> personal = locale.equals("reset")
? service.clearPlayer(playerId) : service.selectPlayer(playerId, locale);
selection = personal.thenApply(ignored -> service.effectiveLocale(playerId));
}
selection.whenComplete((activeLocale, failure) -> source.getServer().execute(() -> {
if (failure != null) {
IrisLogging.reportError(failure);
source.sendFailure(Component.literal("Language selection failed. See the server log."));
} else if (!locale.equals("reset")
&& !locale.replace('-', '_').equalsIgnoreCase(activeLocale.replace('-', '_'))) {
source.sendSuccess(() -> Component.literal("Iris: " + locale
+ " unavailable; using English (" + activeLocale + ")."), false);
} else {
source.sendSuccess(() -> Component.literal("Language updated: " + activeLocale), false);
}
}));
return 1;
}
}
@@ -107,21 +107,21 @@ public final class ModdedObjectCommands {
ModdedObjectUndo.init();
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(Commands.literal("wand")
.executes((CommandContext<CommandSourceStack> context) -> giveWand(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> giveWand(context.getSource()))));
root.then(Commands.literal("dust")
.executes((CommandContext<CommandSourceStack> context) -> giveDust(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> giveDust(context.getSource()))));
root.then(Commands.literal("d")
.executes((CommandContext<CommandSourceStack> context) -> giveDust(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> giveDust(context.getSource()))));
root.then(Commands.literal("save")
.then(Commands.literal("overwrite")
.then(Commands.argument("name", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> save(context.getSource(), StringArgumentType.getString(context, "name"), true))))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> save(context.getSource(), StringArgumentType.getString(context, "name"), true)))))
.then(Commands.argument("name", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> save(context.getSource(), StringArgumentType.getString(context, "name"), false))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> save(context.getSource(), StringArgumentType.getString(context, "name"), false)))));
root.then(pasteTree());
@@ -131,13 +131,13 @@ public final class ModdedObjectCommands {
root.then(resizeTree("shift", ResizeOp.SHIFT));
root.then(Commands.literal("xpy")
.executes((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), false)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), false))));
root.then(Commands.literal("x+y")
.executes((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), false)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), false))));
root.then(Commands.literal("xay")
.executes((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), true)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), true))));
root.then(Commands.literal("x&y")
.executes((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), true)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> autoSelect(context.getSource(), true))));
root.then(positionTree("position1", true));
root.then(positionTree("p1", true));
@@ -146,27 +146,27 @@ public final class ModdedObjectCommands {
root.then(Commands.literal("analyze")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> analyze(context.getSource(), StringArgumentType.getString(context, "key")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> analyze(context.getSource(), StringArgumentType.getString(context, "key"))))));
root.then(Commands.literal("shrink")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> shrink(context.getSource(), StringArgumentType.getString(context, "key")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> shrink(context.getSource(), StringArgumentType.getString(context, "key"))))));
root.then(Commands.literal("undo")
.executes((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), 1))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), 1)))
.then(Commands.argument("amount", IntegerArgumentType.integer(1, 32))
.executes((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), IntegerArgumentType.getInteger(context, "amount")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), IntegerArgumentType.getInteger(context, "amount"))))));
root.then(Commands.literal("u")
.executes((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), 1))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), 1)))
.then(Commands.argument("amount", IntegerArgumentType.integer(1, 32))
.executes((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), IntegerArgumentType.getInteger(context, "amount")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> undo(context.getSource(), IntegerArgumentType.getInteger(context, "amount"))))));
root.then(bukkitOnly("we", "WorldEdit selection import requires the Bukkit plugin with WorldEdit installed."));
root.then(bukkitOnly("studio", "The object studio world requires the Bukkit studio toolchain; it is not available on modded servers."));
root.then(bukkitOnly("convert", "Schematic conversion (.schem -> .iob) requires the Bukkit plugin."));
root.then(Commands.literal("plausibilize")
.then(Commands.argument("args", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> plausibilize(context.getSource(), StringArgumentType.getString(context, "args")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> plausibilize(context.getSource(), StringArgumentType.getString(context, "args"))))));
return root;
}
@@ -174,12 +174,12 @@ public final class ModdedObjectCommands {
private static LiteralArgumentBuilder<CommandSourceStack> pasteTree() {
LiteralArgumentBuilder<CommandSourceStack> paste = Commands.literal("paste");
paste.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"), 0, null)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"), 0, null))));
paste.then(Commands.literal("rotate")
.then(Commands.argument("degrees", IntegerArgumentType.integer(-270, 270)).suggests(ROTATIONS)
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"),
IntegerArgumentType.getInteger(context, "degrees"), null)))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"),
IntegerArgumentType.getInteger(context, "degrees"), null))))));
paste.then(Commands.literal("at")
.then(Commands.argument("x", IntegerArgumentType.integer())
.then(Commands.argument("y", IntegerArgumentType.integer())
@@ -187,35 +187,35 @@ public final class ModdedObjectCommands {
.then(Commands.literal("rotate")
.then(Commands.argument("degrees", IntegerArgumentType.integer(-270, 270)).suggests(ROTATIONS)
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"),
IntegerArgumentType.getInteger(context, "degrees"),
new BlockPos(IntegerArgumentType.getInteger(context, "x"), IntegerArgumentType.getInteger(context, "y"), IntegerArgumentType.getInteger(context, "z")))))))
new BlockPos(IntegerArgumentType.getInteger(context, "x"), IntegerArgumentType.getInteger(context, "y"), IntegerArgumentType.getInteger(context, "z"))))))))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(OBJECT_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"), 0,
new BlockPos(IntegerArgumentType.getInteger(context, "x"), IntegerArgumentType.getInteger(context, "y"), IntegerArgumentType.getInteger(context, "z")))))))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> paste(context.getSource(), StringArgumentType.getString(context, "key"), 0,
new BlockPos(IntegerArgumentType.getInteger(context, "x"), IntegerArgumentType.getInteger(context, "y"), IntegerArgumentType.getInteger(context, "z"))))))))));
return paste;
}
private static LiteralArgumentBuilder<CommandSourceStack> resizeTree(String name, ResizeOp op) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> resize(context.getSource(), 1, op))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> resize(context.getSource(), 1, op)))
.then(Commands.argument("amount", IntegerArgumentType.integer(1, 256))
.executes((CommandContext<CommandSourceStack> context) -> resize(context.getSource(), IntegerArgumentType.getInteger(context, "amount"), op)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> resize(context.getSource(), IntegerArgumentType.getInteger(context, "amount"), op))));
}
private static LiteralArgumentBuilder<CommandSourceStack> positionTree(String name, boolean first) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> position(context.getSource(), first, false))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> position(context.getSource(), first, false)))
.then(Commands.literal("look")
.executes((CommandContext<CommandSourceStack> context) -> position(context.getSource(), first, true)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> position(context.getSource(), first, true))));
}
private static LiteralArgumentBuilder<CommandSourceStack> bukkitOnly(String name, String message) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), message);
return 0;
});
}));
}
public static int giveWand(CommandSourceStack source) {
@@ -51,47 +51,47 @@ public final class ModdedPackCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(Commands.literal("validate")
.executes((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), StringArgumentType.getString(context, "pack")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), StringArgumentType.getString(context, "pack"))))));
root.then(Commands.literal("v")
.executes((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), StringArgumentType.getString(context, "pack")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> validate(context.getSource(), StringArgumentType.getString(context, "pack"))))));
root.then(Commands.literal("cleanup")
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), false))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), false)))
.then(Commands.literal("apply")
.executes((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), true)))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), true))))));
root.then(Commands.literal("c")
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), false))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), false)))
.then(Commands.literal("apply")
.executes((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), true)))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> cleanup(context.getSource(), StringArgumentType.getString(context, "pack"), true))))));
root.then(Commands.literal("restore")
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), false))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), false)))
.then(Commands.literal("apply")
.executes((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), true)))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), true))))));
root.then(Commands.literal("r")
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), false))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), false)))
.then(Commands.literal("apply")
.executes((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), true)))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> restore(context.getSource(), StringArgumentType.getString(context, "pack"), true))))));
root.then(Commands.literal("status")
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource(), StringArgumentType.getString(context, "pack")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource(), StringArgumentType.getString(context, "pack"))))));
root.then(Commands.literal("s")
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource(), StringArgumentType.getString(context, "pack")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource(), StringArgumentType.getString(context, "pack"))))));
return root;
}
@@ -63,23 +63,23 @@ public final class ModdedStructureCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(Commands.literal("list")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(Commands.literal("ls")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(Commands.literal("info")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(IRIS_STRUCTURE_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> info(context.getSource(), StringArgumentType.getString(context, "key")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> info(context.getSource(), StringArgumentType.getString(context, "key"))))));
root.then(Commands.literal("place")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(IRIS_STRUCTURE_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> place(context.getSource(), StringArgumentType.getString(context, "key")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> place(context.getSource(), StringArgumentType.getString(context, "key"))))));
root.then(Commands.literal("p")
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(IRIS_STRUCTURE_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> place(context.getSource(), StringArgumentType.getString(context, "key")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> place(context.getSource(), StringArgumentType.getString(context, "key"))))));
root.then(message("import", "Structure import rebuilds vanilla & datapack structures as editable Iris resources through Bukkit/NMS template managers; run /iris structure import on a Bukkit server against this pack, then copy the pack folder over."));
root.then(message("import-all", "Structure import rebuilds vanilla & datapack structures as editable Iris resources through Bukkit/NMS template managers; run /iris structure import on a Bukkit server against this pack, then copy the pack folder over."));
@@ -96,23 +96,23 @@ public final class ModdedStructureCommands {
private static LiteralArgumentBuilder<CommandSourceStack> verifyTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.verifyStructures(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.verifyStructures(context.getSource(), null)))
.then(Commands.argument("key", StringArgumentType.greedyString()).suggests(ALL_STRUCTURE_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.verifyStructures(
context.getSource(), StringArgumentType.getString(context, "key"))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> IrisModdedCommands.verifyStructures(
context.getSource(), StringArgumentType.getString(context, "key")))));
}
private static LiteralArgumentBuilder<CommandSourceStack> message(String name, String text) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
})
}))
.then(Commands.argument("args", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
}));
})));
}
private static IrisData dataFor(CommandSourceStack source) {
@@ -118,7 +118,7 @@ public final class ModdedStudioCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(createTree("create"));
root.then(createTree("+"));
@@ -127,27 +127,27 @@ public final class ModdedStudioCommands {
root.then(packageTree("pkg"));
root.then(Commands.literal("version")
.executes((CommandContext<CommandSourceStack> context) -> version(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> version(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> version(context.getSource(), StringArgumentType.getString(context, "pack")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> version(context.getSource(), StringArgumentType.getString(context, "pack"))))));
root.then(Commands.literal("regions")
.executes((CommandContext<CommandSourceStack> context) -> regions(context.getSource(), 500))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> regions(context.getSource(), 500)))
.then(Commands.argument("radius", IntegerArgumentType.integer(8, 1000))
.executes((CommandContext<CommandSourceStack> context) -> regions(context.getSource(), IntegerArgumentType.getInteger(context, "radius")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> regions(context.getSource(), IntegerArgumentType.getInteger(context, "radius"))))));
root.then(openTree("open"));
root.then(openTree("o"));
root.then(Commands.literal("close")
.executes((CommandContext<CommandSourceStack> context) -> close(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> close(context.getSource()))));
root.then(Commands.literal("x")
.executes((CommandContext<CommandSourceStack> context) -> close(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> close(context.getSource()))));
root.then(Commands.literal("tpstudio")
.executes((CommandContext<CommandSourceStack> context) -> tpStudio(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> tpStudio(context.getSource()))));
root.then(Commands.literal("stp")
.executes((CommandContext<CommandSourceStack> context) -> tpStudio(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> tpStudio(context.getSource()))));
root.then(Commands.literal("status")
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource()))));
root.then(workspaceTree("vscode", true));
root.then(workspaceTree("vsc", true));
root.then(workspaceTree("update", false));
@@ -172,26 +172,26 @@ public final class ModdedStudioCommands {
private static LiteralArgumentBuilder<CommandSourceStack> createTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) ->
create(context.getSource(), "studio", DEFAULT_TEMPLATE))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
create(context.getSource(), "studio", DEFAULT_TEMPLATE)))
.then(Commands.argument("name", StringArgumentType.word())
.executes((CommandContext<CommandSourceStack> context) ->
create(context.getSource(), StringArgumentType.getString(context, "name"), DEFAULT_TEMPLATE))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
create(context.getSource(), StringArgumentType.getString(context, "name"), DEFAULT_TEMPLATE)))
.then(Commands.argument("template", StringArgumentType.word())
.suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) ->
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
create(context.getSource(),
StringArgumentType.getString(context, "name"),
StringArgumentType.getString(context, "template")))));
StringArgumentType.getString(context, "template"))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> packageTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> pkg(context.getSource(), null))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> pkg(context.getSource(), null)))
.then(Commands.argument("pack", StringArgumentType.word())
.suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) ->
pkg(context.getSource(), StringArgumentType.getString(context, "pack"))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
pkg(context.getSource(), StringArgumentType.getString(context, "pack")))));
}
public static void clear() {
@@ -201,11 +201,11 @@ public final class ModdedStudioCommands {
private static LiteralArgumentBuilder<CommandSourceStack> openTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> openHelp(context.getSource()))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> openHelp(context.getSource())))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> open(context.getSource(), StringArgumentType.getString(context, "pack"), 1337L))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> open(context.getSource(), StringArgumentType.getString(context, "pack"), 1337L)))
.then(Commands.argument("seed", LongArgumentType.longArg())
.executes((CommandContext<CommandSourceStack> context) -> open(context.getSource(), StringArgumentType.getString(context, "pack"), LongArgumentType.getLong(context, "seed")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> open(context.getSource(), StringArgumentType.getString(context, "pack"), LongArgumentType.getLong(context, "seed"))))));
}
private static int openHelp(CommandSourceStack source) {
@@ -215,21 +215,21 @@ public final class ModdedStudioCommands {
private static LiteralArgumentBuilder<CommandSourceStack> noiseTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), null, 12345L))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), null, 12345L)))
.then(Commands.argument("generator", StringArgumentType.word()).suggests(GENERATOR_KEYS)
.executes((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), StringArgumentType.getString(context, "generator"), 12345L))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), StringArgumentType.getString(context, "generator"), 12345L)))
.then(Commands.argument("seed", LongArgumentType.longArg())
.executes((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), StringArgumentType.getString(context, "generator"), LongArgumentType.getLong(context, "seed")))));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> noise(context.getSource(), StringArgumentType.getString(context, "generator"), LongArgumentType.getLong(context, "seed"))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> mapTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> map(context.getSource()));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> map(context.getSource())));
}
private static LiteralArgumentBuilder<CommandSourceStack> imageMapTree(String name) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> imageMap(context.getSource()));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> imageMap(context.getSource())));
}
private static int noise(CommandSourceStack source, String generatorKey, long seed) {
@@ -306,9 +306,9 @@ public final class ModdedStudioCommands {
private static LiteralArgumentBuilder<CommandSourceStack> workspaceTree(String name, boolean open) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> workspace(context.getSource(), null, open))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> workspace(context.getSource(), null, open)))
.then(Commands.argument("pack", StringArgumentType.word()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> workspace(context.getSource(), StringArgumentType.getString(context, "pack"), open)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> workspace(context.getSource(), StringArgumentType.getString(context, "pack"), open))));
}
private static int workspace(CommandSourceStack source, String pack, boolean open) {
@@ -355,15 +355,15 @@ public final class ModdedStudioCommands {
private static LiteralArgumentBuilder<CommandSourceStack> message(String name, String text) {
return Commands.literal(name)
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
})
}))
.then(Commands.argument("args", StringArgumentType.greedyString())
.executes((CommandContext<CommandSourceStack> context) -> {
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> {
IrisModdedCommands.fail(context.getSource(), text);
return 0;
}));
})));
}
private static File resolvePack(CommandSourceStack source, String pack) {
@@ -905,6 +905,7 @@ public final class ModdedStudioCommands {
lootKeys.addAll(dimension.getLoot().getTables());
spawnerKeys.addAll(dimension.getEntitySpawners());
collectStructureKeys(structureKeys, dimension.getStructures());
objectKeys.addAll(PackExportClosure.collectStaticObjectKeys(dimension.getStaticObjects()));
for (String regionKey : regionKeys) {
IrisRegion region = dm.getRegionLoader().load(regionKey);
@@ -92,30 +92,30 @@ public final class ModdedWhatCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree() {
return Commands.literal("what").requires(GATE)
.executes((CommandContext<CommandSourceStack> context) ->
inspectHere(context.getSource()))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectHere(context.getSource())))
.then(Commands.literal("here")
.executes((CommandContext<CommandSourceStack> context) ->
inspectHere(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectHere(context.getSource()))))
.then(Commands.literal("biome")
.executes((CommandContext<CommandSourceStack> context) ->
inspectBiome(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectBiome(context.getSource()))))
.then(Commands.literal("region")
.executes((CommandContext<CommandSourceStack> context) ->
inspectRegion(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectRegion(context.getSource()))))
.then(Commands.literal("block")
.executes((CommandContext<CommandSourceStack> context) ->
inspectBlock(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectBlock(context.getSource()))))
.then(Commands.literal("hand")
.executes((CommandContext<CommandSourceStack> context) ->
inspectHand(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectHand(context.getSource()))))
.then(Commands.literal("markers")
.then(Commands.argument("marker", StringArgumentType.greedyString())
.suggests(MARKER_TYPES)
.executes((CommandContext<CommandSourceStack> context) ->
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) ->
inspectMarkers(
context.getSource(),
StringArgumentType.getString(context, "marker")))));
StringArgumentType.getString(context, "marker"))))));
}
static void clear() {
@@ -67,14 +67,14 @@ public final class ModdedWorldCommands {
public static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(name).requires(GATE);
root.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name));
root.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), name)));
root.then(Commands.literal("status")
.executes((CommandContext<CommandSourceStack> context) -> status(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> status(context.getSource()))));
root.then(Commands.literal("list")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(Commands.literal("ls")
.executes((CommandContext<CommandSourceStack> context) -> list(context.getSource())));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> list(context.getSource()))));
root.then(enableTree("enable"));
root.then(enableTree("create"));
@@ -93,53 +93,53 @@ public final class ModdedWorldCommands {
return Commands.literal(name)
.then(Commands.argument("dimension", IdentifierArgument.id())
.then(Commands.argument("pack", StringArgumentType.string()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> enable(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> enable(context.getSource(),
dimensionArgument(context),
StringArgumentType.getString(context, "pack"),
null))
null)))
.then(Commands.argument("seed", StringArgumentType.word())
.executes((CommandContext<CommandSourceStack> context) -> enable(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> enable(context.getSource(),
dimensionArgument(context),
StringArgumentType.getString(context, "pack"),
StringArgumentType.getString(context, "seed"))))));
StringArgumentType.getString(context, "seed")))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> disableTree() {
return Commands.literal("disable")
.then(Commands.argument("dimension", IdentifierArgument.id()).suggests(LOADED_DIMENSIONS)
.executes((CommandContext<CommandSourceStack> context) -> disable(context.getSource(), dimensionArgument(context), false)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> disable(context.getSource(), dimensionArgument(context), false))));
}
private static LiteralArgumentBuilder<CommandSourceStack> deleteTree(String name) {
return Commands.literal(name)
.then(Commands.argument("dimension", IdentifierArgument.id()).suggests(LOADED_DIMENSIONS)
.executes((CommandContext<CommandSourceStack> context) -> disable(context.getSource(), dimensionArgument(context), true)));
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> disable(context.getSource(), dimensionArgument(context), true))));
}
private static LiteralArgumentBuilder<CommandSourceStack> replaceOverworldTree() {
return Commands.literal("replace-overworld")
.then(Commands.argument("pack", StringArgumentType.string()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> replaceOverworld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> replaceOverworld(context.getSource(),
StringArgumentType.getString(context, "pack"),
null))
null)))
.then(Commands.argument("seed", StringArgumentType.word())
.executes((CommandContext<CommandSourceStack> context) -> replaceOverworld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> replaceOverworld(context.getSource(),
StringArgumentType.getString(context, "pack"),
StringArgumentType.getString(context, "seed")))));
StringArgumentType.getString(context, "seed"))))));
}
private static LiteralArgumentBuilder<CommandSourceStack> mainWorldTree() {
return Commands.literal("mainworld")
.then(Commands.literal("off")
.executes((CommandContext<CommandSourceStack> context) -> clearMainWorld(context.getSource())))
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> clearMainWorld(context.getSource()))))
.then(Commands.argument("pack", StringArgumentType.string()).suggests(IrisModdedCommands.PACK_NAMES)
.executes((CommandContext<CommandSourceStack> context) -> mainWorld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> mainWorld(context.getSource(),
StringArgumentType.getString(context, "pack"),
null))
null)))
.then(Commands.argument("seed", StringArgumentType.word())
.executes((CommandContext<CommandSourceStack> context) -> mainWorld(context.getSource(),
.executes(ModdedCommandTree.localized((CommandContext<CommandSourceStack> context) -> mainWorld(context.getSource(),
StringArgumentType.getString(context, "pack"),
StringArgumentType.getString(context, "seed")))));
StringArgumentType.getString(context, "seed"))))));
}
public static int createWorld(CommandSourceStack source, String name, String pack, long seed) {
@@ -30,6 +30,10 @@ public class IrisModdedCommandParityTest {
IrisModdedCommands.register(dispatcher);
CommandNode<CommandSourceStack> iris = child(dispatcher.getRoot(), "iris");
CommandNode<CommandSourceStack> language = child(iris, "language");
assertNotNull(language.getCommand());
child(child(language, "self"), "locale");
child(child(language, "server"), "locale");
CommandNode<CommandSourceStack> what = child(iris, "what");
child(what, "here");
child(what, "biome");
@@ -0,0 +1,125 @@
package art.arcane.iris.modded.command;
import art.arcane.iris.core.localization.IrisLanguage;
import art.arcane.volmlib.util.director.help.DirectorHelpMessages;
import art.arcane.volmlib.util.localization.PluginLanguageService;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.SharedConstants;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.server.Bootstrap;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import org.junit.Test;
import org.mockito.MockedStatic;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
public class ModdedLanguageCommandsTest {
@Test
public void personalFailureReportsTheCommittedEnglishFallback() throws Exception {
assertPersonalCompletion("de_DE", "en_US", "Iris: de_DE unavailable; using English (en_US).");
}
@Test
public void personalResetReportsTheInheritedLanguage() throws Exception {
assertPersonalCompletion("reset", "fr_FR", "Language updated: fr_FR");
}
@Test
public void personalSuccessReportsTheSelectedLanguage() throws Exception {
assertPersonalCompletion("de_DE", "de_DE", "Language updated: de_DE");
}
@Test
public void pickerRendersTheNativeHelpFrameAndLanguageActions() throws Exception {
SharedConstants.tryDetectVersion();
Bootstrap.bootStrap();
CommandSourceStack source = mock(CommandSourceStack.class, RETURNS_DEEP_STUBS);
when(source.getPlayer()).thenReturn(null);
List<Component> rendered = new ArrayList<>();
doAnswer(invocation -> {
Supplier<Component> message = invocation.getArgument(0);
rendered.add(message.get());
return null;
}).when(source).sendSuccess(any(), eq(false));
try (MockedStatic<IrisLanguage> language = mockStatic(IrisLanguage.class)) {
language.when(IrisLanguage::activeLocale).thenReturn("en_US");
language.when(IrisLanguage::availableLocales).thenReturn(Set.of("de_DE"));
language.when(() -> IrisLanguage.plain(DirectorHelpMessages.BACK)).thenReturn("Back");
CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
dispatcher.register(Commands.literal("iris").then(ModdedLanguageCommands.tree()));
assertEquals(1, dispatcher.execute("iris language", source));
}
assertEquals(6, rendered.size());
assertEquals(ModdedCommandFeedback.banner("/iris language"), rendered.getFirst());
assertEquals(new ClickEvent.RunCommand("/iris"), rendered.get(1).getStyle().getClickEvent());
assertEquals("Iris language: en_US", rendered.get(2).getString());
Component locale = rendered.get(3);
assertTrue(locale.getString().contains("[me]"));
assertFalse(locale.getString().contains("[server]"));
assertEquals(new ClickEvent.RunCommand("/iris language self de_DE"),
locale.getSiblings().getFirst().getStyle().getClickEvent());
assertEquals(new ClickEvent.RunCommand("/iris language self reset"), rendered.get(4).getStyle().getClickEvent());
assertEquals(ModdedCommandFeedback.footer(), rendered.getLast());
}
private void assertPersonalCompletion(String requested, String selected, String expected) throws Exception {
SharedConstants.tryDetectVersion();
Bootstrap.bootStrap();
CommandSourceStack source = mock(CommandSourceStack.class, RETURNS_DEEP_STUBS);
ServerPlayer player = mock(ServerPlayer.class);
UUID playerId = UUID.randomUUID();
when(source.getPlayer()).thenReturn(player);
when(player.getUUID()).thenReturn(playerId);
MinecraftServer server = source.getServer();
PluginLanguageService service = mock(PluginLanguageService.class);
CompletableFuture<Void> selection = new CompletableFuture<>();
when(service.selectPlayer(playerId, requested)).thenReturn(selection);
when(service.clearPlayer(playerId)).thenReturn(selection);
when(service.effectiveLocale(playerId)).thenReturn(selected);
List<Component> rendered = new ArrayList<>();
doAnswer(invocation -> {
Supplier<Component> message = invocation.getArgument(0);
rendered.add(message.get());
return null;
}).when(source).sendSuccess(any(), eq(false));
doAnswer(invocation -> {
Runnable task = invocation.getArgument(0);
task.run();
return null;
}).when(server).execute(any(Runnable.class));
try (MockedStatic<IrisLanguage> language = mockStatic(IrisLanguage.class)) {
language.when(IrisLanguage::selections).thenReturn(service);
CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
dispatcher.register(Commands.literal("iris").then(ModdedLanguageCommands.tree()));
assertEquals(1, dispatcher.execute("iris language self " + requested, source));
assertTrue(rendered.isEmpty());
selection.complete(null);
}
assertEquals(List.of(expected), rendered.stream().map(Component::getString).toList());
}
}