From 123ca8efe9133c57e7aca017fea21f078c510811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 19 May 2020 17:33:59 +0200 Subject: [PATCH] Update more commands and add proper request timeouts --- .../bukkit/placeholder/Placeholders.java | 4 +- .../com/plotsquared/core/PlotSquared.java | 4 +- .../com/plotsquared/core/command/Add.java | 8 +- .../com/plotsquared/core/command/Alias.java | 6 +- .../com/plotsquared/core/command/Cluster.java | 47 ++++--- .../com/plotsquared/core/command/Deny.java | 5 +- .../com/plotsquared/core/command/Remove.java | 120 ++++++++---------- .../com/plotsquared/core/command/Trust.java | 104 ++++++++------- .../com/plotsquared/core/command/Visit.java | 9 +- .../core/configuration/Captions.java | 1 + .../core/configuration/Settings.java | 4 + .../com/plotsquared/core/util/MainUtil.java | 7 +- .../plotsquared/core/uuid/UUIDPipeline.java | 54 +++++++- 13 files changed, 226 insertions(+), 147 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/placeholder/Placeholders.java b/Bukkit/src/main/java/com/plotsquared/bukkit/placeholder/Placeholders.java index f8a155d21..0ae44fbcb 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/placeholder/Placeholders.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/placeholder/Placeholders.java @@ -26,6 +26,7 @@ package com.plotsquared.bukkit.placeholder; import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import me.clip.placeholderapi.PlaceholderAPIPlugin; @@ -123,7 +124,8 @@ public class Placeholders extends PlaceholderExpansion { return ""; } - String name = PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(uid, 5L); + String name = PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(uid, + Settings.UUID.BLOCKING_TIMEOUT); if (name != null) { return name; diff --git a/Core/src/main/java/com/plotsquared/core/PlotSquared.java b/Core/src/main/java/com/plotsquared/core/PlotSquared.java index a19f167d7..67c5cab90 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotSquared.java +++ b/Core/src/main/java/com/plotsquared/core/PlotSquared.java @@ -963,7 +963,7 @@ public class PlotSquared { * @return Set of Plot */ public Set getPlots(String world, String player) { - final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, 10L); + final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, Settings.UUID.BLOCKING_TIMEOUT); return getPlots(world, uuid); } @@ -975,7 +975,7 @@ public class PlotSquared { * @return Set of Plot */ public Set getPlots(PlotArea area, String player) { - final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, 10L); + final UUID uuid = this.impromptuUUIDPipeline.getSingle(player, Settings.UUID.BLOCKING_TIMEOUT); return getPlots(area, uuid); } diff --git a/Core/src/main/java/com/plotsquared/core/command/Add.java b/Core/src/main/java/com/plotsquared/core/command/Add.java index 32750f8d9..bbd0b5559 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Add.java +++ b/Core/src/main/java/com/plotsquared/core/command/Add.java @@ -38,6 +38,7 @@ import com.plotsquared.core.util.task.RunnableVal3; import java.util.Iterator; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeoutException; @CommandDeclaration(command = "add", description = "Allow a user to build in a plot while the plot owner is online.", @@ -65,7 +66,11 @@ public class Add extends Command { final CompletableFuture future = new CompletableFuture<>(); MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { if (throwable != null) { - Captions.INVALID_PLAYER.send(player, args[0]); + if (throwable instanceof TimeoutException) { + Captions.FETCHING_PLAYERS_TIMEOUT.send(player); + } else { + Captions.INVALID_PLAYER.send(player, args[0]); + } future.completeExceptionally(throwable); return; } else { @@ -121,4 +126,5 @@ public class Add extends Command { }); return future; } + } diff --git a/Core/src/main/java/com/plotsquared/core/command/Alias.java b/Core/src/main/java/com/plotsquared/core/command/Alias.java index 1df9848d0..3f1273014 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Alias.java +++ b/Core/src/main/java/com/plotsquared/core/command/Alias.java @@ -34,6 +34,8 @@ import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.Permissions; +import java.util.concurrent.TimeoutException; + @CommandDeclaration(command = "setalias", permission = "plots.alias", description = "Set the plot name", @@ -115,7 +117,9 @@ public class Alias extends SubCommand { } } PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> { - if (uuid != null) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (uuid != null) { MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN); } else { plot.setAlias(alias); diff --git a/Core/src/main/java/com/plotsquared/core/command/Cluster.java b/Core/src/main/java/com/plotsquared/core/command/Cluster.java index 82f602493..c9ce3d5ef 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Cluster.java +++ b/Core/src/main/java/com/plotsquared/core/command/Cluster.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.util.UUID; +import java.util.concurrent.TimeoutException; @CommandDeclaration(command = "cluster", aliases = "clusters", @@ -373,7 +374,9 @@ public class Cluster extends SubCommand { PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(args[1], (uuid, throwable) -> { - if (throwable != null) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (throwable != null) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[1]); } else { if (!cluster.isAdded(uuid)) { @@ -426,7 +429,9 @@ public class Cluster extends SubCommand { // check uuid PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(args[1], (uuid, throwable) -> { - if (throwable != null) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (throwable != null) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[1]); } else { // Can't kick if the player is yourself, the owner, or not added to the cluster @@ -542,7 +547,9 @@ public class Cluster extends SubCommand { PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(args[2], (uuid, throwable) -> { - if (throwable != null) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (throwable != null) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[2]); } else { if (args[1].equalsIgnoreCase("add")) { @@ -631,23 +638,27 @@ public class Cluster extends SubCommand { PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(cluster.owner, (username, throwable) -> { - final String owner; - if (username == null) { - owner = "unknown"; + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); } else { - owner = username; + final String owner; + if (username == null) { + owner = "unknown"; + } else { + owner = username; + } + String name = cluster.getName(); + String size = (cluster.getP2().x - cluster.getP1().x + 1) + "x" + ( + cluster.getP2().y - cluster.getP1().y + 1); + String rights = cluster.isAdded(player.getUUID()) + ""; + String message = Captions.CLUSTER_INFO.getTranslated(); + message = message.replaceAll("%id%", id); + message = message.replaceAll("%owner%", owner); + message = message.replaceAll("%name%", name); + message = message.replaceAll("%size%", size); + message = message.replaceAll("%rights%", rights); + MainUtil.sendMessage(player, message); } - String name = cluster.getName(); - String size = (cluster.getP2().x - cluster.getP1().x + 1) + "x" + ( - cluster.getP2().y - cluster.getP1().y + 1); - String rights = cluster.isAdded(player.getUUID()) + ""; - String message = Captions.CLUSTER_INFO.getTranslated(); - message = message.replaceAll("%id%", id); - message = message.replaceAll("%owner%", owner); - message = message.replaceAll("%name%", name); - message = message.replaceAll("%size%", size); - message = message.replaceAll("%rights%", rights); - MainUtil.sendMessage(player, message); }); return true; } diff --git a/Core/src/main/java/com/plotsquared/core/command/Deny.java b/Core/src/main/java/com/plotsquared/core/command/Deny.java index 072975226..3cf742f0c 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Deny.java +++ b/Core/src/main/java/com/plotsquared/core/command/Deny.java @@ -37,6 +37,7 @@ import com.plotsquared.core.util.WorldUtil; import com.sk89q.worldedit.world.gamemode.GameModes; import java.util.UUID; +import java.util.concurrent.TimeoutException; @CommandDeclaration(command = "deny", aliases = {"d", "ban"}, @@ -68,7 +69,9 @@ public class Deny extends SubCommand { } MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { - if (throwable != null || uuids.isEmpty()) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (throwable != null || uuids.isEmpty()) { MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); } else { for (UUID uuid : uuids) { diff --git a/Core/src/main/java/com/plotsquared/core/command/Remove.java b/Core/src/main/java/com/plotsquared/core/command/Remove.java index 2ed34aca9..1a079f709 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Remove.java +++ b/Core/src/main/java/com/plotsquared/core/command/Remove.java @@ -33,12 +33,9 @@ import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.Permissions; -import com.plotsquared.core.util.uuid.UUIDHandler; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; +import java.util.concurrent.TimeoutException; @CommandDeclaration(command = "remove", aliases = {"r", "untrust", "ut", "undeny", "unban", "ud"}, @@ -68,74 +65,59 @@ public class Remove extends SubCommand { MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); return true; } - int count = 0; - switch (args[0]) { - case "unknown": { - HashSet all = new HashSet<>(); - all.addAll(plot.getMembers()); - all.addAll(plot.getTrusted()); - all.addAll(plot.getDenied()); - ArrayList toRemove = new ArrayList<>(); - for (UUID uuid : all) { - if (UUIDHandler.getName(uuid) == null) { - toRemove.add(uuid); - count++; - } - } - for (UUID uuid : toRemove) { - plot.removeDenied(uuid); - plot.removeTrusted(uuid); - plot.removeMember(uuid); - } - break; - } - default: - Set uuids = MainUtil.getUUIDsFromString(args[0]); - if (!uuids.isEmpty()) { - for (UUID uuid : uuids) { - if (plot.getTrusted().contains(uuid)) { - if (plot.removeTrusted(uuid)) { - PlotSquared.get().getEventDispatcher() - .callTrusted(player, plot, uuid, false); - count++; - } - } else if (plot.getMembers().contains(uuid)) { - if (plot.removeMember(uuid)) { - PlotSquared.get().getEventDispatcher() - .callMember(player, plot, uuid, false); - count++; - } - } else if (plot.getDenied().contains(uuid)) { - if (plot.removeDenied(uuid)) { - PlotSquared.get().getEventDispatcher() - .callDenied(player, plot, uuid, false); - count++; - } - } else if (uuid == DBFunc.EVERYONE) { - if (plot.removeTrusted(uuid)) { - PlotSquared.get().getEventDispatcher() - .callTrusted(player, plot, uuid, false); - count++; - } else if (plot.removeMember(uuid)) { - PlotSquared.get().getEventDispatcher() - .callMember(player, plot, uuid, false); - count++; - } else if (plot.removeDenied(uuid)) { - PlotSquared.get().getEventDispatcher() - .callDenied(player, plot, uuid, false); - count++; - } + + MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { + int count = 0; + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + return; + } else if (throwable != null) { + MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); + return; + } else if (!uuids.isEmpty()) { + for (UUID uuid : uuids) { + if (plot.getTrusted().contains(uuid)) { + if (plot.removeTrusted(uuid)) { + PlotSquared.get().getEventDispatcher() + .callTrusted(player, plot, uuid, false); + count++; + } + } else if (plot.getMembers().contains(uuid)) { + if (plot.removeMember(uuid)) { + PlotSquared.get().getEventDispatcher() + .callMember(player, plot, uuid, false); + count++; + } + } else if (plot.getDenied().contains(uuid)) { + if (plot.removeDenied(uuid)) { + PlotSquared.get().getEventDispatcher() + .callDenied(player, plot, uuid, false); + count++; + } + } else if (uuid == DBFunc.EVERYONE) { + if (plot.removeTrusted(uuid)) { + PlotSquared.get().getEventDispatcher() + .callTrusted(player, plot, uuid, false); + count++; + } else if (plot.removeMember(uuid)) { + PlotSquared.get().getEventDispatcher() + .callMember(player, plot, uuid, false); + count++; + } else if (plot.removeDenied(uuid)) { + PlotSquared.get().getEventDispatcher() + .callDenied(player, plot, uuid, false); + count++; } } } - break; - } - if (count == 0) { - MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); - return false; - } else { - MainUtil.sendMessage(player, Captions.REMOVED_PLAYERS, count + ""); - } + } + if (count == 0) { + MainUtil.sendMessage(player, Captions.INVALID_PLAYER, args[0]); + } else { + MainUtil.sendMessage(player, Captions.REMOVED_PLAYERS, count + ""); + } + }); return true; } + } diff --git a/Core/src/main/java/com/plotsquared/core/command/Trust.java b/Core/src/main/java/com/plotsquared/core/command/Trust.java index 8a93e6cd8..8bcaced4e 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Trust.java +++ b/Core/src/main/java/com/plotsquared/core/command/Trust.java @@ -36,9 +36,9 @@ import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal3; import java.util.Iterator; -import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeoutException; @CommandDeclaration(command = "trust", aliases = {"t"}, @@ -65,51 +65,65 @@ public class Trust extends Command { .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST), Captions.NO_PLOT_PERMS); checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); - final Set uuids = MainUtil.getUUIDsFromString(args[0]); - checkTrue(!uuids.isEmpty(), Captions.INVALID_PLAYER, args[0]); - Iterator iterator = uuids.iterator(); - int size = currentPlot.getTrusted().size() + currentPlot.getMembers().size(); - while (iterator.hasNext()) { - UUID uuid = iterator.next(); - if (uuid == DBFunc.EVERYONE && !( - Permissions.hasPermission(player, Captions.PERMISSION_TRUST_EVERYONE) || Permissions - .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST))) { - MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid)); - iterator.remove(); - continue; - } - if (currentPlot.isOwner(uuid)) { - MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid)); - iterator.remove(); - continue; - } - if (currentPlot.getTrusted().contains(uuid)) { - MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid)); - iterator.remove(); - continue; - } - size += currentPlot.getMembers().contains(uuid) ? 0 : 1; - } - checkTrue(!uuids.isEmpty(), null); - checkTrue(size <= currentPlot.getArea().getMaxPlotMembers() || Permissions - .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST), - Captions.PLOT_MAX_MEMBERS); - // Success - confirm.run(this, () -> { - for (UUID uuid : uuids) { - if (uuid != DBFunc.EVERYONE) { - if (!currentPlot.removeMember(uuid)) { - if (currentPlot.getDenied().contains(uuid)) { - currentPlot.removeDenied(uuid); - } - } - } - currentPlot.addTrusted(uuid); - PlotSquared.get().getEventDispatcher().callTrusted(player, currentPlot, uuid, true); - MainUtil.sendMessage(player, Captions.TRUSTED_ADDED); - } - }, null); + final CompletableFuture future = new CompletableFuture<>(); + MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { + if (throwable != null) { + if (throwable instanceof TimeoutException) { + Captions.FETCHING_PLAYERS_TIMEOUT.send(player); + } else { + Captions.INVALID_PLAYER.send(player, args[0]); + } + future.completeExceptionally(throwable); + return; + } else { + checkTrue(!uuids.isEmpty(), Captions.INVALID_PLAYER, args[0]); + Iterator iterator = uuids.iterator(); + int size = currentPlot.getTrusted().size() + currentPlot.getMembers().size(); + while (iterator.hasNext()) { + UUID uuid = iterator.next(); + if (uuid == DBFunc.EVERYONE && !( + Permissions.hasPermission(player, Captions.PERMISSION_TRUST_EVERYONE) || Permissions + .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST))) { + MainUtil.sendMessage(player, Captions.INVALID_PLAYER, MainUtil.getName(uuid)); + iterator.remove(); + continue; + } + if (currentPlot.isOwner(uuid)) { + MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid)); + iterator.remove(); + continue; + } + if (currentPlot.getTrusted().contains(uuid)) { + MainUtil.sendMessage(player, Captions.ALREADY_ADDED, MainUtil.getName(uuid)); + iterator.remove(); + continue; + } + size += currentPlot.getMembers().contains(uuid) ? 0 : 1; + } + checkTrue(!uuids.isEmpty(), null); + checkTrue(size <= currentPlot.getArea().getMaxPlotMembers() || Permissions + .hasPermission(player, Captions.PERMISSION_ADMIN_COMMAND_TRUST), + Captions.PLOT_MAX_MEMBERS); + // Success + confirm.run(this, () -> { + for (UUID uuid : uuids) { + if (uuid != DBFunc.EVERYONE) { + if (!currentPlot.removeMember(uuid)) { + if (currentPlot.getDenied().contains(uuid)) { + currentPlot.removeDenied(uuid); + } + } + } + currentPlot.addTrusted(uuid); + PlotSquared.get().getEventDispatcher().callTrusted(player, currentPlot, uuid, true); + MainUtil.sendMessage(player, Captions.TRUSTED_ADDED); + } + }, null); + } + future.complete(true); + }); return CompletableFuture.completedFuture(true); } + } diff --git a/Core/src/main/java/com/plotsquared/core/command/Visit.java b/Core/src/main/java/com/plotsquared/core/command/Visit.java index 0c31076f2..78acbd88e 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Visit.java +++ b/Core/src/main/java/com/plotsquared/core/command/Visit.java @@ -46,6 +46,7 @@ import java.util.HashSet; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @@ -156,7 +157,9 @@ public class Visit extends Command { } MainUtil.getUUIDsFromString(args[0], (uuids, throwable) -> { - if (throwable != null || uuids.size() != 1) { + if (throwable instanceof TimeoutException) { + Captions.FETCHING_PLAYERS_TIMEOUT.send(player); + } else if (throwable != null || uuids.size() != 1) { Captions.COMMAND_SYNTAX.send(player, getUsage()); } else { unsortedPre.addAll(PlotSquared.get().getBasePlots((UUID) uuids.toArray()[0])); @@ -188,7 +191,9 @@ public class Visit extends Command { if (args[0].length() >= 2) { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> { - if (uuid != null && !PlotSquared.get().hasPlot(uuid)) { + if (throwable instanceof TimeoutException) { + MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); + } else if (uuid != null && !PlotSquared.get().hasPlot(uuid)) { uuidConsumer.accept(null); } else { uuidConsumer.accept(uuid); 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 9d9251c61..98cb8b9ce 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -451,6 +451,7 @@ public enum Captions implements Caption { DEBUG_REPORT_CREATED("$1Uploaded a full debug to: $1%url%", "Paste"), PURGE_SUCCESS("$4Successfully purged %s plots", "Purge"), FETCHING_PLAYER("$1PlotSquared is attempting to find the specified player from your argument(s). This may take a while.", "Players"), + FETCHING_PLAYERS_TIMEOUT("$2The specified users did not exist in the cache and will be fetched in the background. Please wait a couple of minutes.", "Players"), // TRIM_IN_PROGRESS("A world trim task is already in progress!", "Trim"), // 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 fff645253..85e493088 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -245,6 +245,10 @@ public class Settings extends Config { public static int BACKGROUND_LIMIT = 200; @Comment("Rate limit (per 10 minutes) for random UUID fetching from the Mojang API") public static int IMPROMPTU_LIMIT = 300; + @Comment("Timeout (in milliseconds) for non-blocking UUID requests (mostly commands)") + public static long NON_BLOCKING_TIMEOUT = 3000L; + @Comment("Timeout (in milliseconds) for blocking UUID requests (events)") + public static long BLOCKING_TIMEOUT = 10L; } diff --git a/Core/src/main/java/com/plotsquared/core/util/MainUtil.java b/Core/src/main/java/com/plotsquared/core/util/MainUtil.java index 4e887fead..e214e382a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/MainUtil.java +++ b/Core/src/main/java/com/plotsquared/core/util/MainUtil.java @@ -383,7 +383,7 @@ public class MainUtil { if (owner.equals(DBFunc.SERVER)) { return Captions.SERVER.getTranslated(); } - String name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, 10L); + String name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, Settings.UUID.BLOCKING_TIMEOUT); if (name == null) { return Captions.UNKNOWN.getTranslated(); } @@ -454,7 +454,7 @@ public class MainUtil { for (String term : split) { try { - UUID uuid = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(term, 10L); + UUID uuid = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(term, Settings.UUID.BLOCKING_TIMEOUT); if (uuid == null) { uuid = UUID.fromString(term); } @@ -752,7 +752,8 @@ public class MainUtil { if (request.isEmpty()) { consumer.accept(result, null); } else { - PlotSquared.get().getImpromptuUUIDPipeline().getUUIDs(request).whenComplete((uuids, throwable) -> { + PlotSquared.get().getImpromptuUUIDPipeline().getUUIDs(request, Settings.UUID.NON_BLOCKING_TIMEOUT) + .whenComplete((uuids, throwable) -> { if (throwable != null) { consumer.accept(null, throwable); } else { diff --git a/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java b/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java index 6d85db51f..12d49abaa 100644 --- a/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java +++ b/Core/src/main/java/com/plotsquared/core/uuid/UUIDPipeline.java @@ -27,6 +27,7 @@ package com.plotsquared.core.uuid; import com.google.common.collect.Lists; import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.util.ThreadUtils; import com.plotsquared.core.util.task.TaskManager; import org.jetbrains.annotations.NotNull; @@ -42,10 +43,13 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; /** * An UUID pipeline is essentially an ordered list of @@ -60,6 +64,7 @@ public class UUIDPipeline { private final Executor executor; private final List serviceList; private final List>> consumerList; + private final ScheduledExecutorService timeoutExecutor; /** * Construct a new UUID pipeline @@ -71,6 +76,7 @@ public class UUIDPipeline { this.executor = executor; this.serviceList = Lists.newLinkedList(); this.consumerList = Lists.newLinkedList(); + this.timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); } /** @@ -184,8 +190,10 @@ public class UUIDPipeline { * @param username Username * @param uuid UUID consumer */ - public void getSingle(@NotNull final String username, @NotNull final BiConsumer uuid) { - this.getUUIDs(Collections.singletonList(username)).whenComplete((uuids, throwable) -> { + public void getSingle(@NotNull final String username, + @NotNull final BiConsumer uuid) { + this.getUUIDs(Collections.singletonList(username)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity()) + .whenComplete((uuids, throwable) -> { if (throwable != null) { uuid.accept(null, throwable); } else { @@ -204,8 +212,10 @@ public class UUIDPipeline { * @param uuid UUID * @param username Username consumer */ - public void getSingle(@NotNull final UUID uuid, @NotNull final BiConsumer username) { - this.getNames(Collections.singletonList(uuid)).whenComplete((uuids, throwable) -> { + public void getSingle(@NotNull final UUID uuid, + @NotNull final BiConsumer username) { + this.getNames(Collections.singletonList(uuid)).applyToEither(timeoutAfter(Settings.UUID.NON_BLOCKING_TIMEOUT), Function.identity()) + .whenComplete((uuids, throwable) -> { if (throwable != null) { username.accept(null, throwable); } else { @@ -218,6 +228,42 @@ public class UUIDPipeline { }); } + /** + * Asynchronously attempt to fetch the mapping from a list of UUIDs. + *

+ * This will timeout after the specified time and throws a {@link TimeoutException} + * if this happens + * + * @param requests UUIDs + * @param timeout Timeout in milliseconds + * @return Mappings + */ + public CompletableFuture> getNames(@NotNull final Collection requests, + final long timeout) { + return this.getNames(requests).applyToEither(timeoutAfter(timeout), Function.identity()); + } + + /** + * Asynchronously attempt to fetch the mapping from a list of names. + *

+ * This will timeout after the specified time and throws a {@link TimeoutException} + * if this happens + * + * @param requests Names + * @param timeout Timeout in milliseconds + * @return Mappings + */ + public CompletableFuture> getUUIDs(@NotNull final Collection requests, + final long timeout) { + return this.getUUIDs(requests).applyToEither(timeoutAfter(timeout), Function.identity()); + } + + private CompletableFuture> timeoutAfter(final long timeout) { + final CompletableFuture> result = new CompletableFuture<>(); + this.timeoutExecutor.schedule(() -> result.completeExceptionally(new TimeoutException()), timeout, TimeUnit.MILLISECONDS); + return result; + } + /** * Asynchronously attempt to fetch the mapping from a list of UUIDs *