diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java index fb78d7ccd..1c7b9d5f5 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java @@ -2993,7 +2993,6 @@ public class PlayerEvents extends PlotListener implements Listener { } } - @EventHandler public void onDeath(final PlayerDeathEvent event) { final Plot plot = BukkitUtil.getPlayer(event.getEntity()).getCurrentPlot(); if (plot != null && plot.getFlag(KeepInventoryFlag.class)) { diff --git a/Core/src/main/java/com/plotsquared/core/command/Biome.java b/Core/src/main/java/com/plotsquared/core/command/Biome.java index c7df94a48..4af7fdfd3 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Biome.java +++ b/Core/src/main/java/com/plotsquared/core/command/Biome.java @@ -30,9 +30,14 @@ import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.StringMan; +import com.sk89q.worldedit.command.util.SuggestionHelper; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; +import java.util.Collection; +import java.util.Locale; +import java.util.stream.Collectors; + @CommandDeclaration(command = "setbiome", permission = "plots.set.biome", description = "Set the plot biome", @@ -68,4 +73,13 @@ public class Biome extends SetCommand { }); return true; } + + @Override public Collection tab(final PlotPlayer player, final String[] args, final boolean space) { + return SuggestionHelper.getNamespacedRegistrySuggestions(BiomeType.REGISTRY, args[0]) + .map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", "")) + .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) + .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) + .collect(Collectors.toList()); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/command/Set.java b/Core/src/main/java/com/plotsquared/core/command/Set.java index 700c0854a..6e2bed2f7 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Set.java +++ b/Core/src/main/java/com/plotsquared/core/command/Set.java @@ -28,6 +28,7 @@ package com.plotsquared.core.command; import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.Captions; +import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotManager; @@ -37,10 +38,17 @@ import com.plotsquared.core.util.PatternUtil; import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringMan; import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.world.block.BlockCategory; +import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.Stream; @CommandDeclaration(command = "set", description = "Set a plot value", @@ -72,6 +80,34 @@ public class Set extends SubCommand { String material = StringMan.join(Arrays.copyOfRange(args, 1, args.length), ",").trim(); + final List forbiddenTypes = Settings.General.INVALID_BLOCKS; + if (!Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_ALLOW_UNSAFE) && + !forbiddenTypes.isEmpty()) { + for (String forbiddenType : forbiddenTypes) { + forbiddenType = forbiddenType.toLowerCase(Locale.ENGLISH); + if (forbiddenType.startsWith("minecraft:")) { + forbiddenType = forbiddenType.substring(10); + } + for (String blockType : material.split(",")) { + blockType = blockType.toLowerCase(Locale.ENGLISH); + if (blockType.startsWith("minecraft:")) { + blockType = blockType.substring(10); + } + + if (blockType.startsWith("##")) { + final BlockCategory category = BlockCategory.REGISTRY.get(blockType.substring(2).toLowerCase(Locale.ROOT)); + if (category == null || !category.contains(BlockTypes.get(forbiddenType))) { + continue; + } + } else if (!blockType.contains(forbiddenType)) { + continue; + } + Captions.COMPONENT_ILLEGAL_BLOCK.send(player, forbiddenType); + return true; + } + } + } + for (String component : components) { if (component.equalsIgnoreCase(args[0])) { if (!Permissions.hasPermission(player, CaptionUtility @@ -87,7 +123,8 @@ public class Set extends SubCommand { return true; } - Pattern pattern = PatternUtil.parse(player, material); + Pattern pattern = PatternUtil.parse(player, material, false); + if (plot.getRunning() > 0) { MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER); return false; @@ -106,6 +143,16 @@ public class Set extends SubCommand { } return false; } + + @Override + public Collection tab(final PlotPlayer player, final String[] args, final boolean space) { + return PatternUtil.getSuggestions(player, StringMan.join(args, ",").trim()) + .stream() + .map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", "")) + .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) + .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) + .collect(Collectors.toList()); + } }; } @@ -147,4 +194,38 @@ public class Set extends SubCommand { } return noArgs(player); } + + @Override public Collection tab(final PlotPlayer player, final String[] args, final boolean space) { + if (args.length == 1) { + return Stream + .of("biome", "alias", "home", "main", "floor", "air", "all", "border", "wall", "outline", "middle") + .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) + .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) + .collect(Collectors.toList()); + } else if (args.length > 1) { + // Additional checks + Plot plot = player.getCurrentPlot(); + if (plot == null) { + return new ArrayList<>(); + } + + final String[] newArgs = new String[args.length - 1]; + System.arraycopy(args, 1, newArgs, 0, newArgs.length); + + final Command cmd = MainCommand.getInstance().getCommand("set" + args[0]); + if (cmd != null) { + if (!Permissions.hasPermission(player, cmd.getPermission(), true)) { + return new ArrayList<>(); + } + return cmd.tab(player, newArgs, space); + } + + // components + HashSet components = new HashSet<>(Arrays.asList(plot.getManager().getPlotComponents(plot.getId()))); + if (components.contains(args[0].toLowerCase())) { + return this.component.tab(player, newArgs, space); + } + } + return tabOf(player, args, space); + } } diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java index 58b1638ca..c7c65b58d 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -189,6 +189,7 @@ public enum Captions implements Caption { PERMISSION_BACKUP_LIST("plots.backup.list", "static.permissions"), PERMISSION_BACKUP_LOAD("plots.backup.load", "static.permissions"), PERMISSION_ADMIN_BACKUP_OTHER("plots.admin.backup.other", "static.permissions"), + PERMISSION_ADMIN_ALLOW_UNSAFE("plots.admin.unsafe", "static.permissions"), // // EXPIRED_CONFIRM("$2Confirmation has expired, please run the command again!", "Confirm"), @@ -430,6 +431,7 @@ public enum Captions implements Caption { COMMAND_SYNTAX("$1Usage: $2%s", "CommandConfig"), // // + COMPONENT_ILLEGAL_BLOCK("$2You are not allowed to generate a component containg the block '%s'", "Invalid"), INVALID_PLAYER("$2Player not found: $1%s$2.", "Errors"), INVALID_PLAYER_OFFLINE("$2The player must be online: $1%s.", "Errors"), INVALID_COMMAND_FLAG("$2Invalid command flag: %s0", "Errors"), @@ -749,29 +751,6 @@ public enum Captions implements Caption { false, "Info"), // - // - BACKUP_USAGE("$1Usage: $2/plot backup save/list/load", "Backups"), - BACKUP_IMPOSSIBLE("$2Backups are not enabled for this plot: %s", "Backups"), - BACKUP_SAVE_SUCCESS("$1The backup was created successfully", "Backups"), - BACKUP_SAVE_FAILED("$2The backup could not be created: %s", "Backups"), - BACKUP_LOAD_SUCCESS("$1The backup was restored successfully", "Backups"), - BACKUP_LOAD_FAILURE("$2The backup could not be restored: %s", "Backups"), - BACKUP_LOAD_USAGE("$1Usage: $2/plot backup load [#]", "Backups"), - BACKUP_LIST_HEADER("$1Available backups for plot $2%s", "Backups"), - BACKUP_LIST_ENTRY("$3- $1#%s0 $2%s1", "Backups"), - BACKUP_LIST_FAILED("$2Backup listing failed: %s", "Backups"), - BACKUP_AUTOMATIC_STARTED("$1Backing up the plot...", "Backups"), - BACKUP_AUTOMATIC_FINISHED("$1The automatic backup process finished successfully!", "Backups"), - BACKUP_AUTOMATIC_FAILURE("$2The automatic backup process failed. Your pending action has been canceled. Reason: %s", "Backups"), - // - - // - GENERIC_OTHER("other", "Generic"), - GENERIC_MERGED("merged", "Generic"), - GENERIC_UNOWNED("unowned", "Generic"), - GENERIC_INVALID_CHOICE("invalid choice", "Generic"), - // - /** * Legacy Configuration Conversion */ diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 1e24cc1cf..9f4fc694d 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -29,6 +29,7 @@ import com.plotsquared.core.configuration.file.YamlConfiguration; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -245,6 +246,8 @@ public class Settings extends Config { public static final class General { @Comment("Display scientific numbers (4.2E8)") public static boolean SCIENTIFIC = false; @Comment("Replace wall when merging") public static boolean MERGE_REPLACE_WALL = true; + @Comment("Blocks that may not be used in plot components") public static List INVALID_BLOCKS = + Arrays.asList("command_block", "chain_command_block", "repeating_command_block"); } diff --git a/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java b/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java index a5a3911cc..ee390cc04 100644 --- a/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java @@ -43,6 +43,9 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + public class PatternUtil { public static BaseBlock apply(@NotNull Pattern pattern, int x, int y, int z) { @@ -56,6 +59,18 @@ public class PatternUtil { } public static Pattern parse(PlotPlayer plotPlayer, String input) { + return parse(plotPlayer, input, true); + } + + public static List getSuggestions(PlotPlayer plotPlayer, String input) { + try { + return WorldEdit.getInstance().getPatternFactory().getSuggestions(input); + } catch (final Exception ignored) { + } + return new ArrayList<>(); + } + + public static Pattern parse(PlotPlayer plotPlayer, String input, boolean allowLegacy) { ParserContext context = new ParserContext(); if (plotPlayer != null) { Actor actor = plotPlayer.toActor(); @@ -69,7 +84,7 @@ public class PatternUtil { context.setRestricted(false); } context.setPreferringWildcard(false); - context.setTryLegacy(true); + context.setTryLegacy(allowLegacy); try { return WorldEdit.getInstance().getPatternFactory().parseFromInput(input, context); } catch (InputParseException e) {