Parse world flags in command execution itself.

This commit is contained in:
benwoo1110 2020-12-26 17:16:13 +08:00
parent 538cdb1a69
commit 3e1d3e776b
5 changed files with 153 additions and 142 deletions

View File

@ -16,7 +16,6 @@ import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
import com.onarandombox.MultiverseCore.commands.GeneratorCommand;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
import org.bukkit.Bukkit;
@ -24,17 +23,12 @@ import org.bukkit.ChatColor;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldType;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@ -55,7 +49,6 @@ public class MVCommandContexts extends PaperCommandContexts {
registerContext(CommandPlayer.class, this::deriveCommandPlayer);
registerIssuerAwareContext(Player.class, this::derivePlayer);
registerContext(World.Environment.class, this::deriveEnvironment);
registerIssuerAwareContext(WorldFlags.class, this::deriveWorldFlags);
registerIssuerAwareContext(GameRuleProperty.class, this::deriveGameRuleProperty);
registerIssuerAwareContext(MVDestination.class, this::deriveMVDestination);
registerIssuerAwareContext(Location.class, this::deriveLocation);
@ -275,121 +268,6 @@ public class MVCommandContexts extends PaperCommandContexts {
}
}
@NotNull
private WorldFlags deriveWorldFlags(@NotNull BukkitCommandExecutionContext context) {
Map<String, String> flags = parseFlags(context.getArgs());
return new WorldFlags(
flags.keySet(),
flags.get("-s"),
validateGenerator(flags.get("-g"), context.getSender()),
getWorldType(flags.get("-t"), context.getSender()),
!flags.containsKey("-n"),
doGenerateStructures(flags.get("-a"))
);
}
@Nullable
private String validateGenerator(@Nullable String value,
@NotNull CommandSender sender) {
if (value == null) {
return null;
}
List<String> genArray = new ArrayList<>(Arrays.asList(value.split(":")));
if (genArray.size() < 2) {
// If there was only one arg specified, pad with another empty one.
genArray.add("");
}
if (this.worldManager.getChunkGenerator(genArray.get(0), genArray.get(1), "test") == null) {
sender.sendMessage(ChatColor.RED + "Invalid generator '" + value + "'.");
GeneratorCommand.showAvailableGenerator(sender);
throw new InvalidCommandArgument(false);
}
return value;
}
@NotNull
private WorldType getWorldType(@Nullable String type,
@NotNull CommandSender sender) {
if (type == null || type.length() == 0) {
return WorldType.NORMAL;
}
if (type.equalsIgnoreCase("normal")) {
type = "NORMAL";
}
else if (type.equalsIgnoreCase("flat")) {
type = "FLAT";
}
else if (type.equalsIgnoreCase("largebiomes")) {
type = "LARGE_BIOMES";
}
else if (type.equalsIgnoreCase("amplified")) {
type = "AMPLIFIED";
}
try {
return WorldType.valueOf(type);
}
catch (IllegalArgumentException e) {
sender.sendMessage(ChatColor.RED + "'" + type + "' is not a valid World Type.");
EnvironmentCommand.showWorldTypes(sender);
throw new InvalidCommandArgument(false);
}
}
private boolean doGenerateStructures(@Nullable String value) {
return value == null || value.equalsIgnoreCase("true");
}
@NotNull
private Map<String, String> parseFlags(@NotNull List<String> args) {
Map<String, String> flags = new HashMap<>();
if (!validateFlagArgs(args)) {
return flags;
}
mapOutTheArgs(args, flags);
return flags;
}
private boolean validateFlagArgs(@Nullable List<String> args) {
if (args == null || args.size() == 0) {
return false;
}
if (!isFlagKey(args.get(0))) {
throw new InvalidCommandArgument("No flag defined for value '" + args.get(0) + "'");
}
return true;
}
private void mapOutTheArgs(@NotNull List<String> args,
@NotNull Map<String, String> flags) {
String preFlagKey = args.remove(0);
StringBuilder flagValue = new StringBuilder();
for (String arg : args) {
if (!isFlagKey(arg)) {
flagValue.append(arg);
continue;
}
if (preFlagKey != null) {
flags.put(preFlagKey, flagValue.toString());
flagValue = new StringBuilder();
}
preFlagKey = arg;
}
flags.put(preFlagKey, flagValue.toString());
}
private boolean isFlagKey(@NotNull String value) {
return value.charAt(0) == '-';
}
@NotNull
private GameRuleProperty<?> deriveGameRuleProperty(@NotNull BukkitCommandExecutionContext context) {
int argLength = context.getArgs().size();

View File

@ -7,34 +7,157 @@
package com.onarandombox.MultiverseCore.commandTools;
import co.aikar.commands.InvalidCommandArgument;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
import com.onarandombox.MultiverseCore.commands.GeneratorCommand;
import org.bukkit.ChatColor;
import org.bukkit.WorldType;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class WorldFlags {
private final Set<String> flagsUsed;
private final String seed;
private final String generator;
private final WorldType worldType;
private final boolean spawnAdjust;
private final boolean generateStructures;
private final Map<String, String> parsedFlags;
public WorldFlags(Set<String> flagsUsed,
String seed, String generator,
WorldType worldType,
boolean spawnAdjust,
boolean generateStructures) {
private static final Set<String> FLAG_KEYS = Collections.unmodifiableSet(new HashSet<String>() {{
add("-s");
add("-g");
add("-t");
add("-n");
add("-a");
}});
this.flagsUsed = flagsUsed;
this.seed = seed;
this.generator = generator;
this.worldType = worldType;
this.spawnAdjust = spawnAdjust;
this.generateStructures = generateStructures;
public WorldFlags(@NotNull CommandSender sender,
@NotNull MultiverseCore plugin,
@Nullable String[] args) {
Map<String, String> flags = parseFlags(args);
Logging.finer("World flags: " + flags.toString());
this.parsedFlags = flags;
this.seed = flags.get("-s");
this.generator = validateGenerator(flags.get("-g"), sender, plugin);
this.worldType = getWorldType(flags.get("-t"), sender);
this.spawnAdjust = !flags.containsKey("-n");
this.generateStructures = doGenerateStructures(flags.get("-a"));
}
@Nullable
private static String validateGenerator(@Nullable String value,
@NotNull CommandSender sender,
@NotNull MultiverseCore plugin) {
if (value == null) {
return null;
}
List<String> genArray = new ArrayList<>(Arrays.asList(value.split(":")));
if (genArray.size() < 2) {
// If there was only one arg specified, pad with another empty one.
genArray.add("");
}
if (plugin.getMVWorldManager().getChunkGenerator(genArray.get(0), genArray.get(1), "test") == null) {
sender.sendMessage(ChatColor.RED + "Invalid generator '" + value + "'.");
GeneratorCommand.showAvailableGenerator(sender);
throw new InvalidCommandArgument(false);
}
return value;
}
@NotNull
private static WorldType getWorldType(@Nullable String type,
@NotNull CommandSender sender) {
if (type == null || type.length() == 0) {
return WorldType.NORMAL;
}
if (type.equalsIgnoreCase("normal")) {
type = "NORMAL";
}
else if (type.equalsIgnoreCase("flat")) {
type = "FLAT";
}
else if (type.equalsIgnoreCase("largebiomes")) {
type = "LARGE_BIOMES";
}
else if (type.equalsIgnoreCase("amplified")) {
type = "AMPLIFIED";
}
try {
return WorldType.valueOf(type);
}
catch (IllegalArgumentException e) {
sender.sendMessage(ChatColor.RED + "'" + type + "' is not a valid World Type.");
EnvironmentCommand.showWorldTypes(sender);
throw new InvalidCommandArgument(false);
}
}
private static boolean doGenerateStructures(@Nullable String value) {
return value == null || value.equalsIgnoreCase("true");
}
@NotNull
private static Map<String, String> parseFlags(@Nullable String[] args) {
Map<String, String> flags = new HashMap<>();
if (args == null || args.length == 0) {
return flags;
}
mapOutTheArgs(args, flags);
return flags;
}
private static void mapOutTheArgs(@NotNull String[] args,
@NotNull Map<String, String> flags) {
String currentFlagKey = null;
for (String arg : args) {
if (isValidFlagKey(arg)) {
if (currentFlagKey != null) {
flags.put(currentFlagKey, null);
}
currentFlagKey = arg;
continue;
}
if (currentFlagKey == null) {
throw new InvalidCommandArgument("'" + arg + "' is not a valid flag key.");
}
flags.put(currentFlagKey, arg);
currentFlagKey = null;
}
if (currentFlagKey != null) {
flags.put(currentFlagKey, null);
}
}
private static boolean isValidFlagKey(@Nullable String value) {
return value != null && FLAG_KEYS.contains(value.toLowerCase());
}
public boolean hasFlag(String flag) {
return flagsUsed.contains(flag);
return parsedFlags.containsKey(flag);
}
public String getSeed() {

View File

@ -13,6 +13,7 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Conditions;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
@ -22,6 +23,7 @@ import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@CommandAlias("mv")
public class CreateCommand extends MultiverseCommand {
@ -33,19 +35,20 @@ public class CreateCommand extends MultiverseCommand {
@Subcommand("create")
@CommandPermission("multiverse.core.create")
@Syntax("<name> <env> -s [seed] -g [generator[:id]] -t [worldtype] [-n] -a [true|false]")
@CommandCompletion(" @environments")
@CommandCompletion("@empty @environments") //TODO: Add flags tab-complete
@Description("Creates a new world and loads it.")
public void onCreateCommand(@NotNull CommandSender sender,
@NotNull @Flags("trim") @Conditions("creatableWorldName") String worldName,
@NotNull World.Environment environment,
@NotNull WorldFlags flags) {
@Nullable @Optional String[] flagsArray) {
WorldFlags flags = new WorldFlags(sender, this.plugin, flagsArray);
Command.broadcastCommandMessage(sender, "Starting creation of world '" + worldName + "'...");
// TODO: Should Allow WorldFlags object to be passed directly
Command.broadcastCommandMessage(sender, (this.plugin.getMVWorldManager().addWorld(
worldName,
environment,
// TODO: Should Allow WorldFlags object to be passed directly
flags.getSeed(),
flags.getWorldType(),
flags.isGenerateStructures(),

View File

@ -13,6 +13,7 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Conditions;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
@ -22,6 +23,7 @@ import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@CommandAlias("mv")
public class ImportCommand extends MultiverseCommand {
@ -38,10 +40,11 @@ public class ImportCommand extends MultiverseCommand {
public void onImportCommand(@NotNull CommandSender sender,
@NotNull @Flags("trim") @Conditions("importableWorldName") String worldName,
@NotNull World.Environment environment,
@NotNull WorldFlags flags) {
@Nullable @Optional String[] flagsArray) {
WorldFlags flags = new WorldFlags(sender, this.plugin, flagsArray);
Command.broadcastCommandMessage(sender, "Starting import of world '" + worldName + "'...");
String resultMessage = (this.plugin.getMVWorldManager().addWorld(worldName,
environment,
null,

View File

@ -12,6 +12,7 @@ import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
@ -20,6 +21,7 @@ import com.onarandombox.MultiverseCore.commandTools.WorldFlags;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@CommandAlias("mv")
public class RegenCommand extends MultiverseCommand {
@ -36,7 +38,9 @@ public class RegenCommand extends MultiverseCommand {
public void onRegenCommand(@NotNull CommandSender sender,
//TODO: Allow regen of unloaded worlds.
@NotNull @Flags("other") MultiverseWorld world,
@NotNull WorldFlags flags) {
@Nullable @Optional String[] flagsArray) {
WorldFlags flags = new WorldFlags(sender, this.plugin, flagsArray);
this.plugin.getMVCommandManager().getQueueManager().addToQueue(
sender,