diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java index 3552580d8..eaa0bafd6 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java @@ -37,7 +37,7 @@ public boolean canExecute(User user, String label, List args) { // Check if mid-teleport if (getIslands().isGoingHome(user)) { // Tell them again that it's in progress - user.sendMessage("commands.island.go.teleport"); + user.sendMessage("commands.island.go.in-progress"); return false; } List islands = getIslands().getIslands(getWorld(), user.getUniqueId()); @@ -76,7 +76,15 @@ public boolean execute(User user, String label, List args) { getIslands().setPrimaryIsland(user.getUniqueId(), info.island); if (!info.islandName) { this.delayCommand(user, () -> getIslands().homeTeleportAsync(getWorld(), user.getPlayer(), name) - .thenAccept((r) -> getIslands().setPrimaryIsland(user.getUniqueId(), info.island))); + .thenAccept((r) -> { + if (r.booleanValue()) { + // Success + getIslands().setPrimaryIsland(user.getUniqueId(), info.island); + } else { + user.sendMessage("commands.island.go.failure"); + getPlugin().logError(user.getName() + " could not teleprot to their island - async teleport issue"); + } + })); return true; } } diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 3c303572b..3c4420a0d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -650,6 +650,7 @@ public Optional getProtectedIslandAt(@NonNull Location location) { */ private CompletableFuture getAsyncSafeHomeLocation(@NonNull World world, @NonNull User user, String homeName) { + BentoBox.getInstance().logDebug("Getting safe home location for " + user.getName()); CompletableFuture result = new CompletableFuture<>(); // Check if the world is a gamemode world and the player has an island Location islandLoc = getIslandLocation(world, user.getUniqueId()); @@ -669,10 +670,16 @@ private CompletableFuture getAsyncSafeHomeLocation(@NonNull World worl Location namedHome = homeName.isBlank() ? null : getHomeLocation(world, user, name); Location l = namedHome != null ? namedHome : defaultHome; if (l != null) { + BentoBox.getInstance().logDebug("Loading the destination chunk asyc for " + user.getName()); + long time = System.currentTimeMillis(); Util.getChunkAtAsync(l).thenRun(() -> { + long duration = System.currentTimeMillis() - time; + BentoBox.getInstance().logDebug("Chunk loaded asyc for " + user.getName() + " in " + duration + "ms"); + BentoBox.getInstance().logDebug("Checking if the location is safe for " + user.getName()); // Check if it is safe if (isSafeLocation(l)) { result.complete(l); + BentoBox.getInstance().logDebug("Location is safe for " + user.getName()); return; } // To cover slabs, stairs and other half blocks, try one block above @@ -681,6 +688,7 @@ private CompletableFuture getAsyncSafeHomeLocation(@NonNull World worl // Adjust the home location accordingly setHomeLocation(user, lPlusOne, name); result.complete(lPlusOne); + BentoBox.getInstance().logDebug("Location is safe for " + user.getName()); return; } // Try island @@ -688,25 +696,33 @@ private CompletableFuture getAsyncSafeHomeLocation(@NonNull World worl }); return result; } + BentoBox.getInstance().logDebug("No home locations found for " + user.getName()); // Try island tryIsland(result, islandLoc, user, name); return result; } private void tryIsland(CompletableFuture result, Location islandLoc, @NonNull User user, String name) { + BentoBox.getInstance().logDebug(user.getName() + ": we need to try other locations on the island. Load the island center chunk async..."); + long time = System.currentTimeMillis(); Util.getChunkAtAsync(islandLoc).thenRun(() -> { + long duration = System.currentTimeMillis() - time; + BentoBox.getInstance().logDebug("Island center chunk loaded for " + user.getName() + " in " + duration + "ms"); World w = islandLoc.getWorld(); if (isSafeLocation(islandLoc)) { + BentoBox.getInstance().logDebug("Location is safe for " + user.getName()); setHomeLocation(user, islandLoc, name); result.complete(islandLoc.clone().add(new Vector(0.5D, 0, 0.5D))); return; } else { + BentoBox.getInstance().logDebug("Location is not safe for " + user.getName()); // If these island locations are not safe, then we need to get creative // Try the default location Location dl = islandLoc.clone().add(new Vector(0.5D, 5D, 2.5D)); if (isSafeLocation(dl)) { setHomeLocation(user, dl, name); result.complete(dl); + BentoBox.getInstance().logDebug("Found that the default spot is safe " + user.getName()); return; } // Try just above the bedrock @@ -714,18 +730,22 @@ private void tryIsland(CompletableFuture result, Location islandLoc, @ if (isSafeLocation(dl)) { setHomeLocation(user, dl, name); result.complete(dl); + BentoBox.getInstance().logDebug("Location above bedrock is safe for " + user.getName()); return; } + BentoBox.getInstance().logDebug("Trying all locations up to max height above bedrock for " + user.getName()); // Try all the way up to the sky for (int y = islandLoc.getBlockY(); y < w.getMaxHeight(); y++) { dl = new Location(w, islandLoc.getX() + 0.5D, y, islandLoc.getZ() + 0.5D); if (isSafeLocation(dl)) { setHomeLocation(user, dl, name); result.complete(dl); + BentoBox.getInstance().logDebug("Location is safe for " + user.getName()); return; } } } + BentoBox.getInstance().logDebug("Nowhere is safe for " + user.getName()); result.complete(null); }); @@ -1051,21 +1071,27 @@ private CompletableFuture homeTeleportAsync(@NonNull World world, @NonN user.sendMessage("commands.island.go.teleport"); goingHome.add(user.getUniqueId()); readyPlayer(player); + BentoBox.getInstance().logDebug(user.getName() + " is going home"); this.getAsyncSafeHomeLocation(world, user, name).thenAccept(home -> { Island island = getIsland(world, user); if (home == null) { + BentoBox.getInstance().logDebug("Try to fix this teleport location and teleport the player if possible " + user.getName()); // Try to fix this teleport location and teleport the player if possible new SafeSpotTeleport.Builder(plugin).entity(player).island(island).homeName(name) .thenRun(() -> teleported(world, user, name, newIsland, island)) .ifFail(() -> goingHome.remove(user.getUniqueId())).buildFuture().thenAccept(result::complete); return; } + BentoBox.getInstance().logDebug("Teleporting " + player.getName() + " async"); + long time = System.currentTimeMillis(); PaperLib.teleportAsync(Objects.requireNonNull(player), home).thenAccept(b -> { // Only run the commands if the player is successfully teleported if (Boolean.TRUE.equals(b)) { + BentoBox.getInstance().logDebug("Teleported " + player.getName() + " async - took " + (System.currentTimeMillis() - time) + "ms"); teleported(world, user, name, newIsland, island); result.complete(true); } else { + BentoBox.getInstance().logDebug("Failed to teleport " + player.getName() + " async! - took " + (System.currentTimeMillis() - time) + "ms"); // Remove from mid-teleport set goingHome.remove(user.getUniqueId()); result.complete(false); diff --git a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java index 057cff418..24899f3b4 100644 --- a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java +++ b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java @@ -279,7 +279,11 @@ void teleportEntity(final Location loc) { task.cancel(); // Return to main thread and teleport the player Bukkit.getScheduler().runTask(plugin, () -> { + BentoBox.getInstance().logDebug("Home number = " + homeNumber + " Home name = '" + homeName + "'"); + plugin.getIslands().getIslandAt(loc).ifPresent(is -> + plugin.getIslands().getHomeLocations(is).forEach((k,v) -> BentoBox.getInstance().logDebug("'" + k + "' => " + v))); if (!portal && entity instanceof Player && (homeNumber > 0 || !homeName.isEmpty())) { + BentoBox.getInstance().logDebug("Setting home"); // Set home if so marked plugin.getIslands().setHomeLocation(User.getInstance(entity), loc, homeName); } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index bd5529aee..6eb43f344 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -548,7 +548,9 @@ commands: parameters: '[home name]' description: teleport you to your island teleport: '&a Teleporting you to your island.' + in-progress: '&a Teleporting in progress, please wait...' teleported: '&a Teleported you to home &e [number].' + failure: '&c Teleporting failed for some reason. Please try again later.' unknown-home: '&c Unknown home name!' help: description: the main island command