diff --git a/src/main/java/org/mvplugins/multiverse/inventories/commands/AddWorldsCommand.java b/src/main/java/org/mvplugins/multiverse/inventories/commands/AddWorldsCommand.java index 194e1b43..53f5d467 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/commands/AddWorldsCommand.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/commands/AddWorldsCommand.java @@ -1,7 +1,12 @@ package org.mvplugins.multiverse.inventories.commands; +import org.bukkit.Bukkit; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.core.command.MVCommandIssuer; +import org.mvplugins.multiverse.core.command.flag.CommandFlag; +import org.mvplugins.multiverse.core.command.flag.CommandFlagsManager; +import org.mvplugins.multiverse.core.command.flag.FlagBuilder; +import org.mvplugins.multiverse.core.command.flag.ParsedCommandFlags; import org.mvplugins.multiverse.core.utils.REPatterns; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -13,6 +18,7 @@ import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; +import org.mvplugins.multiverse.inventories.util.GroupWorldNameValidator; import org.mvplugins.multiverse.inventories.util.MVInvi18n; import java.util.Arrays; @@ -24,16 +30,24 @@ final class AddWorldsCommand extends InventoriesCommand { private final WorldGroupManager worldGroupManager; + private final GroupWorldNameValidator groupWorldNameValidator; + private final Flags flags; @Inject - AddWorldsCommand(@NotNull WorldGroupManager worldGroupManager) { + AddWorldsCommand( + @NotNull WorldGroupManager worldGroupManager, + @NotNull GroupWorldNameValidator groupWorldNameValidator, + @NotNull Flags flags + ) { this.worldGroupManager = worldGroupManager; + this.groupWorldNameValidator = groupWorldNameValidator; + this.flags = flags; } @Subcommand("add-worlds") @CommandPermission("multiverse.inventories.addworlds") - @CommandCompletion("@worldGroups @mvworlds:multiple,scope=both") - @Syntax(" ") + @CommandCompletion("@worldGroups @mvworlds:multiple,scope=both, @flags:groupName=" + Flags.NAME) + @Syntax(" [--skip-exist-check]") @Description("Adds a World to a World Group.") void onAddWorldCommand( MVCommandIssuer issuer, @@ -42,14 +56,25 @@ void onAddWorldCommand( @Description("Group you want to add the world to.") WorldGroup group, - @Single @Syntax("") @Description("World name to add.") - String worlds + String worlds, + + @Syntax("[--skip-exist-check]") + String[] flagArray ) { + ParsedCommandFlags parsedFlags = flags.parse(flagArray); List worldNames = Arrays.stream(REPatterns.COMMA.split(worlds)) .map(String::toLowerCase) .toList(); + if (!parsedFlags.hasFlag(flags.skipExistCheck)) { + for (String worldName : worldNames) { + if (!groupWorldNameValidator.validateWorldName(worldName)) { + issuer.sendError(MVInvi18n.ERROR_NOWORLD, replace("{world}").with(worldName)); + return; + } + } + } String worldNamesString = String.join(", ", worldNames); if (!group.getConfigWorlds().addAll(worldNames)) { issuer.sendError(MVInvi18n.ADDWORLD_WORLDALREADYEXISTS, @@ -62,4 +87,18 @@ void onAddWorldCommand( replace("{group}").with(group.getName()), replace("{world}").with(worldNamesString)); } + + @Service + private static final class Flags extends FlagBuilder { + private static final String NAME = "mvinvaddworlds"; + + @Inject + private Flags(@NotNull CommandFlagsManager flagsManager) { + super(NAME, flagsManager); + } + + private final CommandFlag skipExistCheck = flag(CommandFlag.builder("--skip-exist-check") + .addAlias("-s") + .build()); + } } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/commands/prompts/GroupWorldsPrompt.java b/src/main/java/org/mvplugins/multiverse/inventories/commands/prompts/GroupWorldsPrompt.java index 34b8cd42..1ae9b581 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/commands/prompts/GroupWorldsPrompt.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/commands/prompts/GroupWorldsPrompt.java @@ -10,6 +10,7 @@ import org.bukkit.World; import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.Prompt; +import org.mvplugins.multiverse.inventories.util.GroupWorldNameValidator; import org.mvplugins.multiverse.inventories.util.MVInvi18n; import java.util.HashSet; @@ -23,6 +24,7 @@ final class GroupWorldsPrompt extends InventoriesPrompt { protected final Prompt nextPrompt; protected final boolean isCreating; protected final Set worlds; + private final GroupWorldNameValidator groupWorldNameValidator; public GroupWorldsPrompt(final MultiverseInventories plugin, final MVCommandIssuer issuer, final WorldGroup group, final Prompt nextPrompt, @@ -32,6 +34,7 @@ public GroupWorldsPrompt(final MultiverseInventories plugin, final MVCommandIssu this.nextPrompt = nextPrompt; this.isCreating = creatingGroup; this.worlds = new HashSet<>(group.getConfigWorlds()); + this.groupWorldNameValidator = plugin.getServiceLocator().getService(GroupWorldNameValidator.class); } @NotNull @@ -70,28 +73,25 @@ public Prompt acceptInput(@NotNull final ConversationContext conversationContext return nextPrompt; } - boolean negative = false; - World world = Bukkit.getWorld(input); - if (world == null && input.startsWith("-") && input.length() > 1) { - negative = true; - world = Bukkit.getWorld(input.substring(1)); - } - - if (world == null) { + boolean negative = input.startsWith("-"); + String worldName = negative ? input.substring(1) : input; + if (!groupWorldNameValidator.validateWorldName(worldName)) { issuer.sendError(MVInvi18n.ERROR_NOWORLD, replace("{world}").with(input)); return this; } + if (negative) { - if (!worlds.contains(world.getName())) { + if (!worlds.contains(worldName)) { issuer.sendError(MVInvi18n.REMOVEWORLD_WORLDNOTINGROUP, replace("{world}").with(input), replace("{group}").with(group.getName())); return this; } - worlds.remove(world.getName()); + worlds.remove(worldName); return this; } - worlds.add(world.getName()); + + worlds.add(worldName); return this; } } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/profile/group/YamlWorldGroupManager.java b/src/main/java/org/mvplugins/multiverse/inventories/profile/group/YamlWorldGroupManager.java index e775da92..881425f5 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/profile/group/YamlWorldGroupManager.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/profile/group/YamlWorldGroupManager.java @@ -2,8 +2,10 @@ import com.dumptruckman.minecraft.util.Logging; import com.google.common.collect.Lists; +import org.apache.logging.log4j.util.Strings; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.core.command.MVCommandManager; +import org.mvplugins.multiverse.core.utils.StringFormatter; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.external.commentedconfiguration.CommentedConfiguration; import org.mvplugins.multiverse.external.jakarta.inject.Inject; @@ -14,12 +16,11 @@ import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider; import org.mvplugins.multiverse.inventories.share.Sharables; import org.mvplugins.multiverse.inventories.util.DeserializationException; -import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.EventPriority; +import org.mvplugins.multiverse.inventories.util.GroupWorldNameValidator; import java.io.File; import java.util.ArrayList; @@ -38,6 +39,8 @@ final class YamlWorldGroupManager extends AbstractWorldGroupManager { "# No support will be given for those who manually edit these groups." }; + private final GroupWorldNameValidator groupWorldNameValidator; + private CommentedConfiguration groupsConfig; @Inject @@ -46,8 +49,10 @@ final class YamlWorldGroupManager extends AbstractWorldGroupManager { @NotNull MVCommandManager commandManager, @NotNull InventoriesConfig inventoriesConfig, @NotNull ProfileContainerStoreProvider profileContainerStoreProvider, - @NotNull WorldManager worldManager) { + @NotNull WorldManager worldManager, + @NotNull GroupWorldNameValidator groupWorldNameValidator) { super(plugin, commandManager, inventoriesConfig, profileContainerStoreProvider, worldManager); + this.groupWorldNameValidator = groupWorldNameValidator; } @Override @@ -151,25 +156,23 @@ private WorldGroup deserializeGroup(final String name, final Map Logging.fine("No worlds for group: " + name); } else { if (!(worldListObj instanceof List)) { - Logging.fine("World list formatted incorrectly for world group: " + name); + Logging.warning("World list formatted incorrectly for world group: " + name); } else { - final StringBuilder builder = new StringBuilder(); + final List invalidWorlds = new ArrayList<>(); for (Object worldNameObj : (List) worldListObj) { if (worldNameObj == null) { - Logging.fine("Error with a world listed in group: " + name); + Logging.warning("Error with a world listed in group: " + name); continue; } - profile.addWorld(worldNameObj.toString(), false); - World world = Bukkit.getWorld(worldNameObj.toString()); - if (world == null) { - if (!builder.isEmpty()) { - builder.append(", "); - } - builder.append(worldNameObj); + String worldName = worldNameObj.toString(); + profile.addWorld(worldName, false); + if (!groupWorldNameValidator.validateWorldName(worldName)) { + invalidWorlds.add(worldName); } } - if (!builder.isEmpty()) { - Logging.config("The following worlds for group '%s' are not loaded: %s", name, builder.toString()); + if (!invalidWorlds.isEmpty()) { + Logging.warning("The following worlds for group '%s' does not exist: %s", + name, StringFormatter.join(invalidWorlds, ", ")); } } } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/util/GroupWorldNameValidator.java b/src/main/java/org/mvplugins/multiverse/inventories/util/GroupWorldNameValidator.java new file mode 100644 index 00000000..1b6aec96 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/util/GroupWorldNameValidator.java @@ -0,0 +1,32 @@ +package org.mvplugins.multiverse.inventories.util; + +import org.bukkit.Bukkit; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.world.WorldManager; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; + +@Service +@ApiStatus.Internal +public class GroupWorldNameValidator { + + private final WorldManager worldManager; + + @Inject + GroupWorldNameValidator(@NotNull WorldManager worldManager) { + this.worldManager = worldManager; + } + + @ApiStatus.Internal + public boolean validateWorldName(String worldName) { + if (worldName == null || worldName.isEmpty()) { + return false; + } + // For the new wildcard and regex support + if (worldName.contains("*") || worldName.startsWith("r=")) { + return true; + } + return worldManager.isWorld(worldName) || Bukkit.getWorld(worldName) != null; + } +}