diff --git a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java index 8d151fb10..e9304e53f 100644 --- a/Core/src/main/java/com/plotsquared/core/command/ListCmd.java +++ b/Core/src/main/java/com/plotsquared/core/command/ListCmd.java @@ -29,6 +29,7 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared.SortType; 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.PlotArea; @@ -44,20 +45,25 @@ import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.task.RunnableVal3; -import com.plotsquared.core.util.uuid.UUIDHandler; +import com.plotsquared.core.uuid.UUIDMapping; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map.Entry; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; @CommandDeclaration(command = "list", aliases = {"l", "find", "search"}, description = "List plots", permission = "plots.list", category = CommandCategory.INFO, - usage = "/plot list > [#]") + usage = "/plot list > [#]") public class ListCmd extends SubCommand { private String[] getArgumentList(PlotPlayer player) { @@ -84,9 +90,6 @@ public class ListCmd extends SubCommand { if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { args.add("unowned"); } - if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) { - args.add("unknown"); - } if (Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) { args.add(""); } @@ -115,25 +118,44 @@ public class ListCmd extends SubCommand { noArgs(player); return false; } - int page = 0; + + final int page; if (args.length > 1) { + int tempPage = -1; try { - page = Integer.parseInt(args[args.length - 1]); - --page; - if (page < 0) { - page = 0; + tempPage = Integer.parseInt(args[args.length - 1]); + --tempPage; + if (tempPage < 0) { + tempPage = 0; } } catch (NumberFormatException ignored) { - page = -1; } + page = tempPage; + } else { + page = 0; } - List plots = null; - String world = player.getLocation().getWorld(); PlotArea area = player.getApplicablePlotArea(); String arg = args[0].toLowerCase(); - boolean sort = true; + final boolean[] sort = new boolean[] {true}; + + final Consumer> plotConsumer = plots -> { + if (plots == null) { + sendMessage(player, Captions.DID_YOU_MEAN, + new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"}) + .getBestMatch()); + return; + } + + if (plots.isEmpty()) { + MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS); + return; + } + displayPlots(player, new ArrayList<>(plots), 12, page, area, args, sort[0]); + }; + + final List plots = new ArrayList<>(); switch (arg) { case "mine": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_MINE)) { @@ -141,8 +163,9 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_MINE); return false; } - sort = false; - plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player)); + sort[0] = false; + plotConsumer.accept( + PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getBasePlots(player))); break; case "shared": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_SHARED)) { @@ -150,13 +173,13 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_SHARED); return false; } - plots = new ArrayList<>(); for (Plot plot : PlotSquared.get().getPlots()) { if (plot.getTrusted().contains(player.getUUID()) || plot.getMembers() .contains(player.getUUID())) { plots.add(plot); } } + plotConsumer.accept(plots); break; case "world": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_WORLD)) { @@ -171,7 +194,7 @@ public class ListCmd extends SubCommand { world)); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots(world)); + plotConsumer.accept(PlotSquared.get().getPlots(world)); break; case "expired": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_EXPIRED)) { @@ -179,9 +202,9 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_EXPIRED); return false; } - plots = ExpireManager.IMP == null ? - new ArrayList() : - new ArrayList<>(ExpireManager.IMP.getPendingExpired()); + plotConsumer.accept(ExpireManager.IMP == null ? + new ArrayList<>() : + new ArrayList<>(ExpireManager.IMP.getPendingExpired())); break; case "area": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_AREA)) { @@ -196,7 +219,8 @@ public class ListCmd extends SubCommand { world)); return false; } - plots = area == null ? new ArrayList() : new ArrayList<>(area.getPlots()); + plotConsumer.accept( + area == null ? new ArrayList() : new ArrayList<>(area.getPlots())); break; case "all": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_ALL)) { @@ -204,7 +228,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_ALL); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots()); + plotConsumer.accept(new ArrayList<>(PlotSquared.get().getPlots())); break; case "done": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_DONE)) { @@ -212,7 +236,6 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_DONE); return false; } - plots = new ArrayList<>(); for (Plot plot : PlotSquared.get().getPlots()) { if (DoneFlag.isDone(plot)) { plots.add(plot); @@ -229,7 +252,8 @@ public class ListCmd extends SubCommand { } return 1; }); - sort = false; + sort[0] = false; + plotConsumer.accept(plots); break; case "top": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_TOP)) { @@ -237,7 +261,7 @@ public class ListCmd extends SubCommand { .sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_LIST_TOP); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots()); + plots.addAll(PlotSquared.get().getPlots()); plots.sort((p1, p2) -> { double v1 = 0; int p1s = p1.getSettings().getRatings().size(); @@ -262,7 +286,8 @@ public class ListCmd extends SubCommand { } return (int) Math.signum(v2 - v1); }); - sort = false; + sort[0] = false; + plotConsumer.accept(plots); break; case "forsale": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { @@ -273,12 +298,12 @@ public class ListCmd extends SubCommand { if (EconHandler.manager == null) { break; } - plots = new ArrayList<>(); for (Plot plot : PlotSquared.get().getPlots()) { if (plot.getFlag(PriceFlag.class) > 0) { plots.add(plot); } } + plotConsumer.accept(plots); break; case "unowned": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNOWNED)) { @@ -286,28 +311,12 @@ public class ListCmd extends SubCommand { Captions.PERMISSION_LIST_UNOWNED); return false; } - plots = new ArrayList<>(); for (Plot plot : PlotSquared.get().getPlots()) { if (plot.getOwner() == null) { plots.add(plot); } } - break; - case "unknown": - if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_UNKNOWN)) { - MainUtil.sendMessage(player, Captions.NO_PERMISSION, - Captions.PERMISSION_LIST_UNKNOWN); - return false; - } - plots = new ArrayList<>(); - for (Plot plot : PlotSquared.get().getPlots()) { - if (plot.getOwner() == null) { - continue; - } - if (UUIDHandler.getName(plot.getOwner()) == null) { - plots.add(plot); - } - } + plotConsumer.accept(plots); break; case "fuzzy": if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_FUZZY)) { @@ -325,8 +334,8 @@ public class ListCmd extends SubCommand { } else { term = StringMan.join(Arrays.copyOfRange(args, 1, args.length), " "); } - plots = MainUtil.getPlotsBySearch(term); - sort = false; + sort[0] = false; + plotConsumer.accept(MainUtil.getPlotsBySearch(term)); break; default: if (PlotSquared.get().hasPlotArea(args[0])) { @@ -343,40 +352,39 @@ public class ListCmd extends SubCommand { args[0])); return false; } - plots = new ArrayList<>(PlotSquared.get().getPlots(args[0])); - break; - } - UUID uuid = UUIDHandler.getUUID(args[0], null); - if (uuid == null) { - try { - uuid = UUID.fromString(args[0]); - } catch (Exception ignored) { - } - } - if (uuid != null) { - if (!Permissions.hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) { - MainUtil.sendMessage(player, Captions.NO_PERMISSION, - Captions.PERMISSION_LIST_PLAYER); - return false; - } - sort = false; - plots = PlotSquared.get().sortPlotsByTemp(PlotSquared.get().getPlots(uuid)); + plotConsumer.accept(new ArrayList<>(PlotSquared.get().getPlots(args[0]))); break; } + + PlotSquared.get().getImpromptuUUIDPipeline() + .getSingle(args[0], (uuid, throwable) -> { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (throwable != null) { + if (uuid == null) { + try { + uuid = UUID.fromString(args[0]); + } catch (Exception ignored) { + } + } + } + if (uuid == null) { + MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); + } else { + if (!Permissions + .hasPermission(player, Captions.PERMISSION_LIST_PLAYER)) { + MainUtil.sendMessage(player, Captions.NO_PERMISSION, + Captions.PERMISSION_LIST_PLAYER); + } else { + sort[0] = false; + plotConsumer.accept(PlotSquared.get() + .sortPlotsByTemp(PlotSquared.get().getPlots(uuid))); + } + } + }); + break; } - if (plots == null) { - sendMessage(player, Captions.DID_YOU_MEAN, - new StringComparison<>(args[0], new String[] {"mine", "shared", "world", "all"}) - .getBestMatch()); - return false; - } - - if (plots.isEmpty()) { - MainUtil.sendMessage(player, Captions.FOUND_NO_PLOTS); - return false; - } - displayPlots(player, plots, 12, page, area, args, sort); return true; } @@ -417,22 +425,25 @@ public class ListCmd extends SubCommand { .command("/plot info " + plot.getArea() + ";" + plot.getId()).color(color) .text(" - ").color("$2"); String prefix = ""; - for (UUID uuid : plot.getOwners()) { - String name = UUIDHandler.getName(uuid); - if (name == null) { - message = message.text(prefix).color("$4").text("unknown").color("$2") - .tooltip(uuid.toString()).suggest(uuid.toString()); - } else { - PlotPlayer pp = UUIDHandler.getPlayer(uuid); + + try { + final List names = PlotSquared.get().getImpromptuUUIDPipeline() + .getNames(plot.getOwners()).get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + for (final UUIDMapping uuidMapping : names) { + PlotPlayer pp = PlotSquared.imp().getPlayerManager().getPlayerIfExists(uuidMapping.getUuid()); if (pp != null) { - message = message.text(prefix).color("$4").text(name).color("$1") + message = message.text(prefix).color("$4").text(uuidMapping.getUsername()).color("$1") .tooltip(new PlotMessage("Online").color("$4")); } else { - message = message.text(prefix).color("$4").text(name).color("$1") + message = message.text(prefix).color("$4").text(uuidMapping.getUsername()).color("$1") .tooltip(new PlotMessage("Offline").color("$3")); } + prefix = ", "; } - prefix = ", "; + } catch (InterruptedException | ExecutionException e) { + MainUtil.sendMessage(player, Captions.INVALID_PLAYER); + } catch (TimeoutException e) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); } } }, "/plot list " + args[0], Captions.PLOT_LIST_HEADER_PAGED.getTranslated()); 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 413ae3e4b..bf5285691 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Set.java +++ b/Core/src/main/java/com/plotsquared/core/command/Set.java @@ -37,6 +37,7 @@ import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.PatternUtil; import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringMan; +import com.plotsquared.core.util.TabCompletions; import com.plotsquared.core.util.WorldUtil; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.world.block.BlockCategory; @@ -158,11 +159,7 @@ public class Set extends SubCommand { @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()); + return TabCompletions.completePatterns(StringMan.join(args, ",")); } }; } 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 ee390cc04..c8d18c136 100644 --- a/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/PatternUtil.java @@ -62,7 +62,7 @@ public class PatternUtil { return parse(plotPlayer, input, true); } - public static List getSuggestions(PlotPlayer plotPlayer, String input) { + public static List getSuggestions(String input) { try { return WorldEdit.getInstance().getPatternFactory().getSuggestions(input); } catch (final Exception ignored) { diff --git a/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java b/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java index a7c7c2a8f..0c1dbf4df 100644 --- a/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java +++ b/Core/src/main/java/com/plotsquared/core/util/TabCompletions.java @@ -45,7 +45,8 @@ import java.util.stream.Collectors; /** * Tab completion utilities */ -@UtilityClass public class TabCompletions { +@UtilityClass +public class TabCompletions { private final Cache> cachedCompletionValues = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); @@ -79,4 +80,19 @@ import java.util.stream.Collectors; }).collect(Collectors.toList()); } + /** + * Get a list of completions corresponding to WorldEdit(/FAWE) patterns. This uses + * WorldEdit's pattern completer internally. + * + * @param input Command input + * @return List of completions + */ + @NotNull public List completePatterns(@NotNull final String input) { + return PatternUtil.getSuggestions(input.trim()).stream() + .map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", "")) + .filter(value -> value.startsWith(input.toLowerCase(Locale.ENGLISH))) + .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) { + }).collect(Collectors.toList()); + } + }