Skip to content

Commit

Permalink
SafeSpotTeleport was setting home location async
Browse files Browse the repository at this point in the history
This could cause a race condition setting home to null.

If home was null during a new island creation, then the new island tasks
would not be run because SafeSpotTeleport was not given the runnable.

May be related to:
BentoBoxWorld/BSkyBlock#312
  • Loading branch information
tastybento committed May 2, 2020
1 parent 31de515 commit 3b50b01
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ public void homeTeleport(@NonNull World world, @NonNull Player player, boolean n
*/
public void homeTeleport(@NonNull World world, @NonNull Player player, int number, boolean newIsland) {
User user = User.getInstance(player);
user.sendMessage("commands.island.go.teleport");
Location home = getSafeHomeLocation(world, user, number);
// Stop any gliding
player.setGliding(false);
Expand All @@ -694,14 +695,14 @@ public void homeTeleport(@NonNull World world, @NonNull Player player, int numbe
.entity(player)
.island(plugin.getIslands().getIsland(world, user))
.homeNumber(number)
.thenRun(() -> teleported(world, user, number, newIsland))
.build();
return;
}
// Add home
if (plugin.getPlayers().getHomeLocations(world, player.getUniqueId()).isEmpty()) {
plugin.getPlayers().setHomeLocation(player.getUniqueId(), home);
}
user.sendMessage("commands.island.go.teleport");
PaperLib.teleportAsync(player, home).thenAccept(b -> {
// Only run the commands if the player is successfully teleported
if (b) teleported(world, user, number, newIsland);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class SafeSpotTeleport {
this.portal = builder.isPortal();
this.homeNumber = builder.getHomeNumber();
this.runnable = builder.getRunnable();

// If there is no portal scan required, try the desired location immediately
if (plugin.getIslands().isSafeLocation(location)) {
if (portal) {
Expand All @@ -74,7 +75,6 @@ public class SafeSpotTeleport {
return;
}
}

// Get chunks to scan
chunksToScan = getChunksToScan();

Expand Down Expand Up @@ -114,34 +114,34 @@ private void gatherChunks(String failureMessage) {
}

private void tidyUp(Entity entity, String failureMessage) {
// Still Async!
// Nothing left to check and still not canceled
task.cancel();
// Check portal
if (portal && bestSpot != null) {
// Portals found, teleport to the best spot we found
teleportEntity(bestSpot);
} else if (entity instanceof Player) {
// Failed, no safe spot
if (!failureMessage.isEmpty()) {
User.getInstance(entity).notify(failureMessage);
}
if (!plugin.getIWM().inWorld(entity.getLocation())) {
// Last resort
if (Bukkit.getServer().isPrimaryThread()) {
((Player)entity).performCommand("spawn");
} else {
Bukkit.getScheduler().runTask(plugin, () -> ((Player)entity).performCommand("spawn"));
// Return to main thread and teleport the player
Bukkit.getScheduler().runTask(plugin, () -> {
// Failed, no safe spot
if (!failureMessage.isEmpty()) {
User.getInstance(entity).notify(failureMessage);
}
} else {
// Create a spot for the player to be
if (location.getWorld().getEnvironment().equals(Environment.NETHER)) {
makeAndTelport(Material.NETHERRACK);
} else if (location.getWorld().getEnvironment().equals(Environment.THE_END)) {
makeAndTelport(Material.END_STONE);
if (!plugin.getIWM().inWorld(entity.getLocation())) {
// Last resort
((Player)entity).performCommand("spawn");
} else {
makeAndTelport(Material.COBBLESTONE);
// Create a spot for the player to be
if (location.getWorld().getEnvironment().equals(Environment.NETHER)) {
makeAndTelport(Material.NETHERRACK);
} else if (location.getWorld().getEnvironment().equals(Environment.THE_END)) {
makeAndTelport(Material.END_STONE);
} else {
makeAndTelport(Material.COBBLESTONE);
}
}
}
});
}
}

Expand Down Expand Up @@ -227,14 +227,16 @@ private boolean scanChunk(ChunkSnapshot chunk) {
*/
private void teleportEntity(final Location loc) {
task.cancel();
if (!portal && entity instanceof Player && homeNumber > 0) {
// Set home if so marked
plugin.getPlayers().setHomeLocation(User.getInstance(entity), loc, homeNumber);
}
// Return to main thread and teleport the player
Bukkit.getScheduler().runTask(plugin, () -> Util.teleportAsync(entity, loc).thenRun(() -> {
if (runnable != null) Bukkit.getScheduler().runTask(plugin, runnable);
}));
Bukkit.getScheduler().runTask(plugin, () -> {
if (!portal && entity instanceof Player && homeNumber > 0) {
// Set home if so marked
plugin.getPlayers().setHomeLocation(User.getInstance(entity), loc, homeNumber);
}
Util.teleportAsync(entity, loc).thenRun(() -> {
if (runnable != null) Bukkit.getScheduler().runTask(plugin, runnable);
});
});
}

/**
Expand Down

0 comments on commit 3b50b01

Please sign in to comment.