From 5547185b3f64beaaa170d8b906d8b3e5e2236b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 7 Apr 2020 20:19:39 +0200 Subject: [PATCH] Prevent synchronous chunk loading whenever possible --- .../bukkit/listeners/PlayerEvents.java | 2 +- .../bukkit/placeholders/Placeholders.java | 2 +- .../plotsquared/bukkit/util/BukkitUtil.java | 186 +++++++------ .../plotsquared/plot/commands/Area.java | 8 +- .../plotsquared/plot/commands/Auto.java | 2 +- .../plotsquared/plot/commands/Cluster.java | 2 +- .../plot/commands/DebugClaimTest.java | 2 +- .../plotsquared/plot/commands/Like.java | 2 +- .../plot/commands/MainCommand.java | 2 +- .../plotsquared/plot/commands/Middle.java | 2 +- .../plotsquared/plot/commands/Rate.java | 2 +- .../plotsquared/plot/commands/Target.java | 4 +- .../plotsquared/plot/commands/Visit.java | 7 +- .../plot/generator/HybridUtils.java | 2 +- .../plotsquared/plot/object/Plot.java | 244 ++++++++++++++---- .../plotsquared/plot/object/PlotCluster.java | 36 +-- .../plotsquared/plot/object/PlotPlayer.java | 22 +- .../plot/object/worlds/SinglePlot.java | 17 +- .../plot/util/EventDispatcher.java | 4 +- .../plotsquared/plot/util/MainUtil.java | 218 ++++++++-------- .../plot/util/SchematicHandler.java | 3 +- .../plotsquared/plot/util/WorldUtil.java | 41 ++- .../plot/util/block/LocalBlockQueue.java | 4 +- .../plot/util/expiry/ExpireManager.java | 2 +- 24 files changed, 503 insertions(+), 313 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java index 291c574ed..f72ab1f7e 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java @@ -776,7 +776,7 @@ public class PlayerEvents extends PlotListener implements Listener { // to is identical to the plot's home location, and untrusted-visit is true // i.e. untrusted-visit can override deny-teleport // this is acceptable, because otherwise it wouldn't make sense to have both flags set - if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHome() + if (!result && !(plot.getFlag(UntrustedVisitFlag.class) && plot.getHomeSynchronous() .equals(BukkitUtil.getLocationFull(to)))) { MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, Captions.PERMISSION_ADMIN_ENTRY_DENIED); diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/placeholders/Placeholders.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/placeholders/Placeholders.java index d9436ed7f..d8608463f 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/placeholders/Placeholders.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/placeholders/Placeholders.java @@ -162,7 +162,7 @@ public class Placeholders extends PlaceholderExpansion { if (pl.getCurrentPlot() == null) { return ""; } - return plot.getBiome() + ""; + return plot.getBiomeSynchronous() + ""; } default: break; diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java index bd77facdb..0fc021268 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java @@ -1,5 +1,6 @@ package com.github.intellectualsites.plotsquared.bukkit.util; +import com.github.intellectualsites.plotsquared.bukkit.BukkitMain; import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer; import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.config.Captions; @@ -7,7 +8,6 @@ import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; -import com.github.intellectualsites.plotsquared.plot.object.schematic.PlotItem; import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.StringComparison; @@ -20,8 +20,10 @@ import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; +import io.papermc.lib.PaperLib; import lombok.NonNull; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.World; @@ -33,18 +35,16 @@ import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashSet; -import java.util.UUID; import java.util.List; import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; @SuppressWarnings({"unused", "WeakerAccess"}) @@ -104,17 +104,6 @@ public class BukkitUtil extends WorldUtil { return getPlot(player.getLocation()); } - /** - * Get home location. - * - * @param plot Plot that you want to get the location for - * @return plot bottom location - * @see Plot - */ - public static org.bukkit.Location getHomeLocation(Plot plot) { - return BukkitUtil.getLocation(plot.getHome()); - } - /** * Get the PlotPlayer for an offline player. * @@ -219,7 +208,6 @@ public class BukkitUtil extends WorldUtil { * * @param player the recipient of the message * @param caption the message - * @see MainUtil#sendMessage(com.github.intellectualsites.plotsquared.commands.CommandCaller, Captions, String...) */ public static void sendMessage(Player player, Captions caption) { MainUtil.sendMessage(BukkitUtil.getPlayer(player), caption); @@ -303,11 +291,43 @@ public class BukkitUtil extends WorldUtil { return getWorld(worldName) != null; } - @Override public BiomeType getBiome(String world, int x, int z) { + @Override public void getBiome(String world, int x, int z, final Consumer result) { + ensureLoaded(world, x, z, chunk -> + result.accept(BukkitAdapter.adapt(getWorld(world).getBiome(x, z)))); + } + + @Override public BiomeType getBiomeSynchronous(String world, int x, int z) { return BukkitAdapter.adapt(getWorld(world).getBiome(x, z)); } - @Override public int getHighestBlock(@NonNull final String world, final int x, final int z) { + @Override public void getHighestBlock(@NonNull final String world, final int x, final int z, + final Consumer result) { + ensureLoaded(world, x, z, chunk -> { + final World bukkitWorld = getWorld(world); + // Skip top and bottom block + int air = 1; + for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) { + Block block = bukkitWorld.getBlockAt(x, y, z); + Material type = block.getType(); + if (type.isSolid()) { + if (air > 1) { + result.accept(y); + return; + } + air = 0; + } else { + if (block.isLiquid()) { + result.accept(y); + return; + } + air++; + } + } + result.accept(bukkitWorld.getMaxHeight() - 1); + }); + } + + @Override public int getHighestBlockSynchronous(String world, int x, int z) { final World bukkitWorld = getWorld(world); // Skip top and bottom block int air = 1; @@ -329,7 +349,17 @@ public class BukkitUtil extends WorldUtil { return bukkitWorld.getMaxHeight() - 1; } - @Override @Nullable public String[] getSign(@NonNull final Location location) { + @Override public void getSign(@NonNull final Location location, final Consumer result) { + ensureLoaded(location, chunk -> { + final Block block = chunk.getWorld().getBlockAt(getLocation(location)); + if (block.getState() instanceof Sign) { + Sign sign = (Sign) block.getState(); + result.accept(sign.getLines()); + } + }); + } + + @Override @Nullable public String[] getSignSynchronous(@NonNull final Location location) { Block block = getWorld(location.getWorld()) .getBlockAt(location.getX(), location.getY(), location.getZ()); return TaskManager.IMP.sync(new RunnableVal() { @@ -365,60 +395,42 @@ public class BukkitUtil extends WorldUtil { @Override @SuppressWarnings("deprecation") public void setSign(@NonNull final String worldName, final int x, final int y, final int z, @NonNull final String[] lines) { - final World world = getWorld(worldName); - final Block block = world.getBlockAt(x, y, z); - // block.setType(Material.AIR); - final Material type = block.getType(); - if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) { - BlockFace facing = BlockFace.EAST; - if (world.getBlockAt(x, y, z + 1).getType().isSolid()) { - facing = BlockFace.NORTH; - } else if (world.getBlockAt(x + 1, y, z).getType().isSolid()) { - facing = BlockFace.WEST; - } else if (world.getBlockAt(x, y, z - 1).getType().isSolid()) { - facing = BlockFace.SOUTH; + ensureLoaded(worldName, x, z, chunk -> { + final World world = getWorld(worldName); + final Block block = world.getBlockAt(x, y, z); + // block.setType(Material.AIR); + final Material type = block.getType(); + if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) { + BlockFace facing = BlockFace.EAST; + if (world.getBlockAt(x, y, z + 1).getType().isSolid()) { + facing = BlockFace.NORTH; + } else if (world.getBlockAt(x + 1, y, z).getType().isSolid()) { + facing = BlockFace.WEST; + } else if (world.getBlockAt(x, y, z - 1).getType().isSolid()) { + facing = BlockFace.SOUTH; + } + if (PlotSquared.get().IMP.getServerVersion()[1] == 13) { + block.setType(Material.valueOf("WALL_SIGN"), false); + } else { + block.setType(Material.valueOf("OAK_WALL_SIGN"), false); + } + if (!(block.getBlockData() instanceof WallSign)) { + PlotSquared.debug(block.getBlockData().getAsString()); + throw new RuntimeException("Something went wrong generating a sign"); + } + final Directional sign = (Directional) block.getBlockData(); + sign.setFacing(facing); + block.setBlockData(sign, false); } - if (PlotSquared.get().IMP.getServerVersion()[1] == 13) { - block.setType(Material.valueOf("WALL_SIGN"), false); - } else { - block.setType(Material.valueOf("OAK_WALL_SIGN"), false); + final org.bukkit.block.BlockState blockstate = block.getState(); + if (blockstate instanceof Sign) { + final Sign sign = (Sign) blockstate; + for (int i = 0; i < lines.length; i++) { + sign.setLine(i, lines[i]); + } + sign.update(true); } - if (!(block.getBlockData() instanceof WallSign)) { - PlotSquared.debug(block.getBlockData().getAsString()); - throw new RuntimeException("Something went wrong generating a sign"); - } - final Directional sign = (Directional) block.getBlockData(); - sign.setFacing(facing); - block.setBlockData(sign, false); - } - final org.bukkit.block.BlockState blockstate = block.getState(); - if (blockstate instanceof Sign) { - final Sign sign = (Sign) blockstate; - for (int i = 0; i < lines.length; i++) { - sign.setLine(i, lines[i]); - } - sign.update(true); - } - } - - @Override - public boolean addItems(@NonNull final String worldName, @NonNull final PlotItem items) { - final World world = getWorld(worldName); - final Block block = world.getBlockAt(items.x, items.y, items.z); - final org.bukkit.block.BlockState state = block.getState(); - if (state instanceof InventoryHolder) { - InventoryHolder holder = (InventoryHolder) state; - Inventory inv = holder.getInventory(); - for (int i = 0; i < items.types.length; i++) { - // ItemStack item = new ItemStack(LegacyMappings.fromLegacyId(items.id[i]).getMaterial(), items.amount[i], items.data[i]); - ItemStack item = - new ItemStack(BukkitAdapter.adapt(items.types[i]), items.amount[i]); - inv.addItem(item); - } - state.update(true); - return true; - } - return false; + }); } @Override public boolean isBlockSolid(@NonNull final BlockState block) { @@ -471,7 +483,15 @@ public class BukkitUtil extends WorldUtil { return new BukkitWorld(Bukkit.getWorld(world)); } - @Override public BlockState getBlock(@NonNull final Location location) { + @Override public void getBlock(@NonNull final Location location, final Consumer result) { + ensureLoaded(location, chunk -> { + final World world = getWorld(location.getWorld()); + final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ()); + result.accept(BukkitAdapter.asBlockType(block.getType()).getDefaultState()); + }); + } + + @Override public BlockState getBlockSynchronous(@NonNull final Location location) { final World world = getWorld(location.getWorld()); final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ()); return BukkitAdapter.asBlockType(block.getType()).getDefaultState(); @@ -496,4 +516,24 @@ public class BukkitUtil extends WorldUtil { @Override public void setFoodLevel(PlotPlayer player, int foodLevel) { Bukkit.getPlayer(player.getUUID()).setFoodLevel(foodLevel); } + + private static void ensureLoaded(final String world, final int x, final int z, final Consumer chunkConsumer) { + PaperLib.getChunkAtAsync(getWorld(world), x << 4, z << 4, true).thenAccept(chunk -> + ensureMainThread(chunkConsumer, chunk)); + } + + private static void ensureLoaded(final Location location, final Consumer chunkConsumer) { + PaperLib.getChunkAtAsync(getLocation(location), true).thenAccept(chunk -> + ensureMainThread(chunkConsumer, chunk)); + } + + private static void ensureMainThread(final Consumer consumer, final T value) { + if (Bukkit.isPrimaryThread()) { + consumer.accept(value); + } else { + Bukkit.getScheduler().runTask(BukkitMain.getPlugin(BukkitMain.class), () -> + consumer.accept(value)); + } + } + } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java index 92e7b9de6..b56a384f8 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Area.java @@ -471,16 +471,18 @@ public class Area extends SubCommand { Location center; if (area.getType() != PlotAreaType.PARTIAL) { center = WorldUtil.IMP.getSpawn(area.getWorldName()); + player.teleport(center, TeleportCause.COMMAND); } else { CuboidRegion region = area.getRegion(); center = new Location(area.getWorldName(), region.getMinimumPoint().getX() + (region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) / 2, 0, region.getMinimumPoint().getZ() + (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ()) / 2); - center.setY(1 + WorldUtil.IMP - .getHighestBlock(area.getWorldName(), center.getX(), center.getZ())); + WorldUtil.IMP.getHighestBlock(area.getWorldName(), center.getX(), center.getZ(), y -> { + center.setY(1 + y); + player.teleport(center, TeleportCause.COMMAND); + }); } - player.teleport(center, TeleportCause.COMMAND); return true; case "delete": case "remove": diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Auto.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Auto.java index 1d9709e7a..51c84f5b4 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Auto.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Auto.java @@ -94,7 +94,7 @@ public class Auto extends SubCommand { final String schematic) { Set plots = player.getPlots(); if (!plots.isEmpty()) { - plots.iterator().next().teleportPlayer(player, TeleportCause.COMMAND); + plots.iterator().next().teleportPlayer(player, TeleportCause.COMMAND, result -> {}); } else { autoClaimSafe(player, area, start, schematic); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Cluster.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Cluster.java index 2a5aa6a66..8c79e3515 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Cluster.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Cluster.java @@ -555,7 +555,7 @@ public class Cluster extends SubCommand { return false; } } - player.teleport(cluster.getHome(), TeleportCause.COMMAND); + cluster.getHome(home -> player.teleport(home, TeleportCause.COMMAND)); return MainUtil.sendMessage(player, Captions.CLUSTER_TELEPORTING); } case "i": diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/DebugClaimTest.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/DebugClaimTest.java index e1585a399..1331255f7 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/DebugClaimTest.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/DebugClaimTest.java @@ -71,7 +71,7 @@ public class DebugClaimTest extends SubCommand { Location location = manager.getSignLoc(plot); BlockVector2 chunk = BlockVector2.at(location.getX() >> 4, location.getZ() >> 4); ChunkManager.manager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> { - String[] lines = WorldUtil.IMP.getSign(location); + String[] lines = WorldUtil.IMP.getSignSynchronous(location); if (lines != null) { String line = lines[2]; if (line != null && line.length() > 2) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Like.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Like.java index e1751696e..b3af59f13 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Like.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Like.java @@ -47,7 +47,7 @@ public class Like extends SubCommand { for (final Plot plot : plots) { if ((!Settings.Done.REQUIRED_FOR_RATINGS || DoneFlag.isDone(plot)) && plot .isBasePlot() && (!plot.getLikes().containsKey(uuid))) { - plot.teleportPlayer(player, TeleportCause.COMMAND); + plot.teleportPlayer(player, TeleportCause.COMMAND, result -> {}); MainUtil.sendMessage(player, Captions.RATE_THIS); return true; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java index 1727d6890..9727303ef 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java @@ -208,7 +208,7 @@ public class MainCommand extends Command { .equals(area) || Permissions.hasPermission(player, Captions.PERMISSION_ADMIN) || Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_SUDO_AREA)) && !newPlot.isDenied(player.getUUID())) { - Location newLoc = newPlot.getCenter(); + Location newLoc = newPlot.getCenterSynchronous(); if (player.canTeleport(newLoc)) { // Save meta location = player.getMeta(PlotPlayer.META_LOCATION); diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Middle.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Middle.java index 9cc828f21..83b8236ed 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Middle.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Middle.java @@ -24,7 +24,7 @@ public class Middle extends SubCommand { if (plot == null) { return sendMessage(player, Captions.NOT_IN_PLOT); } - player.teleport(plot.getCenter(), TeleportCause.COMMAND); + plot.getCenter(center -> player.teleport(center, TeleportCause.COMMAND)); return true; } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Rate.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Rate.java index 88f455e7d..43c89f8ab 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Rate.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Rate.java @@ -61,7 +61,7 @@ public class Rate extends SubCommand { if ((!Settings.Done.REQUIRED_FOR_RATINGS || DoneFlag.isDone(p)) && p .isBasePlot() && (!p.getRatings().containsKey(uuid)) && !p .isAdded(uuid)) { - p.teleportPlayer(player, TeleportCause.COMMAND); + p.teleportPlayer(player, TeleportCause.COMMAND, result -> {}); MainUtil.sendMessage(player, Captions.RATE_THIS); return true; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Target.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Target.java index 6d9f618e2..7a449f7f1 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Target.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Target.java @@ -32,7 +32,7 @@ public class Target extends SubCommand { if (StringMan.isEqualIgnoreCaseToAny(args[0], "near", "nearest")) { int distance = Integer.MAX_VALUE; for (Plot plot : PlotSquared.get().getPlots(location.getWorld())) { - double current = plot.getCenter().getEuclideanDistanceSquared(location); + double current = plot.getCenterSynchronous().getEuclideanDistanceSquared(location); if (current < distance) { distance = (int) current; target = plot; @@ -45,7 +45,7 @@ public class Target extends SubCommand { } else if ((target = MainUtil.getPlotFromString(player, args[0], true)) == null) { return false; } - player.setCompassTarget(target.getCenter()); + target.getCenter(player::setCompassTarget); MainUtil.sendMessage(player, Captions.COMPASS_TARGET); return true; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Visit.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Visit.java index 0e70d2acc..24baab6b4 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Visit.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Visit.java @@ -149,13 +149,14 @@ public class Visit extends Command { return CompletableFuture.completedFuture(false); } } - confirm.run(this, () -> { - if (plot.teleportPlayer(player, TeleportCause.COMMAND)) { + confirm.run(this, () -> + plot.teleportPlayer(player, TeleportCause.COMMAND, result -> { + if (result) { whenDone.run(Visit.this, CommandResult.SUCCESS); } else { whenDone.run(Visit.this, CommandResult.FAILURE); } - }, () -> whenDone.run(Visit.this, CommandResult.FAILURE)); + }), () -> whenDone.run(Visit.this, CommandResult.FAILURE)); return CompletableFuture.completedFuture(true); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java index 7986883a1..128913f45 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/generator/HybridUtils.java @@ -363,7 +363,7 @@ public abstract class HybridUtils { } HybridUtils.UPDATE = true; Set regions = new HashSet<>(); - regions.add(ChunkManager.getRegion(plot.getCenter())); + regions.add(ChunkManager.getRegion(plot.getCenterSynchronous())); return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>()); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java index 4aac2dd11..1fcbd3005 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java @@ -1,7 +1,6 @@ package com.github.intellectualsites.plotsquared.plot.object; import com.github.intellectualsites.plotsquared.plot.PlotSquared; -import com.github.intellectualsites.plotsquared.plot.config.CaptionUtility; import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Configuration; import com.github.intellectualsites.plotsquared.plot.config.Settings; @@ -19,7 +18,14 @@ import com.github.intellectualsites.plotsquared.plot.generator.SquarePlotWorld; import com.github.intellectualsites.plotsquared.plot.listener.PlotListener; import com.github.intellectualsites.plotsquared.plot.object.comment.PlotComment; import com.github.intellectualsites.plotsquared.plot.object.schematic.Schematic; -import com.github.intellectualsites.plotsquared.plot.util.*; +import com.github.intellectualsites.plotsquared.plot.util.ChunkManager; +import com.github.intellectualsites.plotsquared.plot.util.MainUtil; +import com.github.intellectualsites.plotsquared.plot.util.MathMan; +import com.github.intellectualsites.plotsquared.plot.util.Permissions; +import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; +import com.github.intellectualsites.plotsquared.plot.util.TaskManager; +import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; +import com.github.intellectualsites.plotsquared.plot.util.WorldUtil; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.expiry.ExpireManager; @@ -60,6 +66,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import java.util.stream.Collectors; import static com.github.intellectualsites.plotsquared.plot.commands.SubCommand.sendMessage; @@ -1319,7 +1326,32 @@ public class Plot { return this.unlinkPlot(true, true); } - public Location getCenter() { + public void getCenter(final Consumer result) { + Location[] corners = getCorners(); + Location top = corners[0]; + Location bot = corners[1]; + Location location = + new Location(this.getWorldName(), MathMan.average(bot.getX(), top.getX()), + MathMan.average(bot.getY(), top.getY()), MathMan.average(bot.getZ(), top.getZ())); + if (!isLoaded()) { + result.accept(location); + return; + } + WorldUtil.IMP.getHighestBlock(getWorldName(), location.getX(), location.getZ(), y -> { + int height = y; + if (area.allowSigns()) { + height = Math.max(y, getManager().getSignLoc(this).getY()); + } + location.setY(1 + height); + result.accept(location); + }); + } + + /** + * @deprecated May cause synchronous chunk loads + */ + @Deprecated + public Location getCenterSynchronous() { Location[] corners = getCorners(); Location top = corners[0]; Location bot = corners[1]; @@ -1329,7 +1361,7 @@ public class Plot { if (!isLoaded()) { return location; } - int y = WorldUtil.IMP.getHighestBlock(getWorldName(), location.getX(), location.getZ()); + int y = WorldUtil.IMP.getHighestBlockSynchronous(getWorldName(), location.getX(), location.getZ()); if (area.allowSigns()) { y = Math.max(y, getManager().getSignLoc(this).getY()); } @@ -1337,28 +1369,54 @@ public class Plot { return location; } - public Location getSide() { + /** + * @deprecated May cause synchronous chunk loads + */ + @Deprecated + public Location getSideSynchronous() { CuboidRegion largest = getLargestRegion(); int x = (largest.getMaximumPoint().getX() >> 1) - (largest.getMinimumPoint().getX() >> 1) + largest.getMinimumPoint().getX(); int z = largest.getMinimumPoint().getZ() - 1; PlotManager manager = getManager(); - int y = isLoaded() ? WorldUtil.IMP.getHighestBlock(getWorldName(), x, z) : 62; + int y = isLoaded() ? WorldUtil.IMP.getHighestBlockSynchronous(getWorldName(), x, z) : 62; if (area.allowSigns() && (y <= 0 || y >= 255)) { y = Math.max(y, manager.getSignLoc(this).getY() - 1); } return new Location(getWorldName(), x, y + 1, z); } + public void getSide(Consumer result) { + CuboidRegion largest = getLargestRegion(); + int x = (largest.getMaximumPoint().getX() >> 1) - (largest.getMinimumPoint().getX() >> 1) + + largest.getMinimumPoint().getX(); + int z = largest.getMinimumPoint().getZ() - 1; + PlotManager manager = getManager(); + if (isLoaded()) { + WorldUtil.IMP.getHighestBlock(getWorldName(), x, z, y -> { + int height = y; + if (area.allowSigns() && (y <= 0 || y >= 255)) { + height = Math.max(y, manager.getSignLoc(this).getY() - 1); + } + result.accept(new Location(getWorldName(), x, height + 1, z)); + }); + } else { + int y = 62; + if (area.allowSigns()) { + y = Math.max(y, manager.getSignLoc(this).getY() - 1); + } + result.accept(new Location(getWorldName(), x, y + 1, z)); + } + } + /** - * Return the home location for the plot - * - * @return Home location + * @deprecated May cause synchronous chunk loading */ - public Location getHome() { + @Deprecated + public Location getHomeSynchronous() { BlockLoc home = this.getPosition(); if (home == null || home.getX() == 0 && home.getZ() == 0) { - return this.getDefaultHome(true); + return this.getDefaultHomeSynchronous(true); } else { Location bottom = this.getBottomAbs(); Location location = new Location(bottom.getWorld(), bottom.getX() + home.getX(), @@ -1367,15 +1425,46 @@ public class Plot { if (!isLoaded()) { return location; } - if (!WorldUtil.IMP.getBlock(location).getBlockType().getMaterial().isAir()) { + if (!WorldUtil.IMP.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) { location.setY(Math.max(1 + WorldUtil.IMP - .getHighestBlock(this.getWorldName(), location.getX(), location.getZ()), + .getHighestBlockSynchronous(this.getWorldName(), location.getX(), location.getZ()), bottom.getY())); } return location; } } + /** + * Return the home location for the plot + */ + public void getHome(final Consumer result) { + BlockLoc home = this.getPosition(); + if (home == null || home.getX() == 0 && home.getZ() == 0) { + this.getDefaultHome(result); + } else { + Location bottom = this.getBottomAbs(); + Location location = new Location(bottom.getWorld(), bottom.getX() + home.getX(), + bottom.getY() + home.getY(), bottom.getZ() + home.getZ(), home.getYaw(), + home.getPitch()); + if (!isLoaded()) { + result.accept(location); + return; + } + WorldUtil.IMP.getBlock(location, block -> { + if (!block.getBlockType().getMaterial().isAir()) { + WorldUtil.IMP + .getHighestBlock(this.getWorldName(), location.getX(), location.getZ(), y -> { + location.setY(Math.max(1 + y, + bottom.getY())); + result.accept(location); + }); + } else { + result.accept(location); + } + }); + } + } + /** * Sets the home location * @@ -1400,11 +1489,15 @@ public class Plot { * * @return Location */ - public Location getDefaultHome() { - return getDefaultHome(false); + public void getDefaultHome(Consumer result) { + getDefaultHome(false, result); } - public Location getDefaultHome(boolean member) { + /** + * @deprecated May cause synchronous chunk loads + */ + @Deprecated + public Location getDefaultHomeSynchronous(final boolean member) { Plot plot = this.getBasePlot(false); PlotLoc loc = member ? area.getDefaultHome() : area.getNonmemberHome(); if (loc != null) { @@ -1424,12 +1517,47 @@ public class Plot { z = bot.getZ() + loc.getZ(); } int y = loc.getY() < 1 ? - (isLoaded() ? WorldUtil.IMP.getHighestBlock(plot.getWorldName(), x, z) + 1 : 63) : + (isLoaded() ? WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(), x, z) + 1 : 63) : loc.getY(); return new Location(plot.getWorldName(), x, y, z); } // Side - return plot.getSide(); + return plot.getSideSynchronous(); + } + + public void getDefaultHome(boolean member, Consumer result) { + Plot plot = this.getBasePlot(false); + PlotLoc loc = member ? area.getDefaultHome() : area.getNonmemberHome(); + if (loc != null) { + int x; + int z; + if (loc.getX() == Integer.MAX_VALUE && loc.getZ() == Integer.MAX_VALUE) { + // center + CuboidRegion largest = plot.getLargestRegion(); + x = (largest.getMaximumPoint().getX() >> 1) - (largest.getMinimumPoint().getX() + >> 1) + largest.getMinimumPoint().getX(); + z = (largest.getMaximumPoint().getZ() >> 1) - (largest.getMinimumPoint().getZ() + >> 1) + largest.getMinimumPoint().getZ(); + } else { + // specific + Location bot = plot.getBottomAbs(); + x = bot.getX() + loc.getX(); + z = bot.getZ() + loc.getZ(); + } + if (loc.getY() < 1) { + if (isLoaded()) { + WorldUtil.IMP.getHighestBlock(plot.getWorldName(), x, z, y -> + result.accept(new Location(plot.getWorldName(), x, y + 1, z))); + } else { + result.accept(new Location(plot.getWorldName(), x, 63, z)); + } + } else { + result.accept(new Location(plot.getWorldName(), x, loc.getY(), z)); + } + return; + } + // Side + plot.getSide(result); } public double getVolume() { @@ -1599,7 +1727,7 @@ public class Plot { setSign(player.getName()); MainUtil.sendMessage(player, Captions.CLAIMED); if (teleport && Settings.Teleport.ON_CLAIM) { - teleportPlayer(player, TeleportCause.COMMAND); + teleportPlayer(player, TeleportCause.COMMAND, result -> {}); } PlotArea plotworld = getArea(); if (plotworld.isSchematicOnClaim()) { @@ -1696,9 +1824,18 @@ public class Plot { * * @return the name of the biome */ - public BiomeType getBiome() { - Location location = this.getCenter(); - return WorldUtil.IMP.getBiome(location.getWorld(), location.getX(), location.getZ()); + public void getBiome(Consumer result) { + this.getCenter(location -> + WorldUtil.IMP.getBiome(location.getWorld(), location.getX(), location.getZ(), result)); + } + + /** + * @deprecated May cause synchronous chunk loads + */ + @Deprecated + public BiomeType getBiomeSynchronous() { + final Location location = this.getCenterSynchronous(); + return WorldUtil.IMP.getBiomeSynchronous(location.getWorld(), location.getX(), location.getZ()); } //TODO Better documentation needed. @@ -2190,9 +2327,6 @@ public class Plot { /** * Gets the set home location or 0,0,0 if no location is set
* - Does not take the default home location into account - * - * @return - * @see #getHome() */ public BlockLoc getPosition() { return this.getSettings().getPosition(); @@ -2234,7 +2368,7 @@ public class Plot { @Override public void run(String[] value) { ChunkManager.manager .loadChunk(location.getWorld(), location.getBlockVector2(), false); - this.value = WorldUtil.IMP.getSign(location); + this.value = WorldUtil.IMP.getSignSynchronous(location); } }); if (lines == null) { @@ -2855,8 +2989,8 @@ public class Plot { * @param player the player * @return if the teleport succeeded */ - public boolean teleportPlayer(final PlotPlayer player) { - return teleportPlayer(player, TeleportCause.PLUGIN); + public void teleportPlayer(final PlotPlayer player, Consumer result) { + teleportPlayer(player, TeleportCause.PLUGIN, result); } /** @@ -2866,41 +3000,43 @@ public class Plot { * @param cause the cause of the teleport * @return if the teleport succeeded */ - public boolean teleportPlayer(final PlotPlayer player, TeleportCause cause) { + public void teleportPlayer(final PlotPlayer player, TeleportCause cause, Consumer resultConsumer) { Plot plot = this.getBasePlot(false); Result result = PlotSquared.get().getEventDispatcher().callTeleport(player, player.getLocation(), plot).getEventResult(); if (result == Result.DENY) { sendMessage(player, Captions.EVENT_DENIED, "Teleport"); - return false; + resultConsumer.accept(false); + return; } - final Location location; - if (this.area.isHomeAllowNonmember() || plot.isAdded(player.getUUID())) { - location = this.getHome(); - } else { - location = this.getDefaultHome(false); - } - if (Settings.Teleport.DELAY == 0 || Permissions - .hasPermission(player, "plots.teleport.delay.bypass")) { - MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); - player.teleport(location, cause); - return true; - } - MainUtil.sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + ""); - final String name = player.getName(); - TaskManager.TELEPORT_QUEUE.add(name); - TaskManager.runTaskLater(() -> { - if (!TaskManager.TELEPORT_QUEUE.contains(name)) { - MainUtil.sendMessage(player, Captions.TELEPORT_FAILED); - return; - } - TaskManager.TELEPORT_QUEUE.remove(name); - if (player.isOnline()) { + final Consumer locationConsumer = location -> { + if (Settings.Teleport.DELAY == 0 || Permissions.hasPermission(player, "plots.teleport.delay.bypass")) { MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); player.teleport(location, cause); + resultConsumer.accept(true); + return; } - }, Settings.Teleport.DELAY * 20); - return true; + MainUtil.sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + ""); + final String name = player.getName(); + TaskManager.TELEPORT_QUEUE.add(name); + TaskManager.runTaskLater(() -> { + if (!TaskManager.TELEPORT_QUEUE.contains(name)) { + MainUtil.sendMessage(player, Captions.TELEPORT_FAILED); + return; + } + TaskManager.TELEPORT_QUEUE.remove(name); + if (player.isOnline()) { + MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); + player.teleport(location, cause); + } + }, Settings.Teleport.DELAY * 20); + resultConsumer.accept(true); + }; + if (this.area.isHomeAllowNonmember() || plot.isAdded(player.getUUID())) { + this.getHome(locationConsumer); + } else { + this.getDefaultHome(false, locationConsumer); + } } /** diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotCluster.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotCluster.java index 108439edd..f2245d940 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotCluster.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotCluster.java @@ -7,6 +7,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import java.util.HashSet; import java.util.UUID; +import java.util.function.Consumer; public class PlotCluster { public PlotArea area; @@ -86,8 +87,6 @@ public class PlotCluster { /** * Get the area (in plots). - * - * @return */ public int getArea() { return (1 + this.pos2.x - this.pos1.x) * (1 + this.pos2.y - this.pos1.y); @@ -125,26 +124,31 @@ public class PlotCluster { + this.pos2.y; } - public Location getHome() { + public void getHome(Consumer result) { BlockLoc home = this.settings.getPosition(); - Location toReturn; + Consumer locationConsumer = toReturn -> { + MainUtil.getHeighestBlock(this.area.getWorldName(), toReturn.getX(), toReturn.getZ(), max -> { + if (max > toReturn.getY()) { + toReturn.setY(1 + max); + } + result.accept(toReturn); + }); + }; if (home.getY() == 0) { // default pos Plot center = getCenterPlot(); - toReturn = center.getHome(); - if (toReturn.getY() == 0) { - PlotManager manager = this.area.getPlotManager(); - Location location = manager.getSignLoc(center); - toReturn.setY(location.getY()); - } + center.getHome(location -> { + Location toReturn = location; + if (toReturn.getY() == 0) { + PlotManager manager = this.area.getPlotManager(); + Location locationSign = manager.getSignLoc(center); + toReturn.setY(locationSign.getY()); + } + locationConsumer.accept(toReturn); + }); } else { - toReturn = getClusterBottom().add(home.getX(), home.getY(), home.getZ()); + locationConsumer.accept(getClusterBottom().add(home.getX(), home.getY(), home.getZ())); } - int max = MainUtil.getHeighestBlock(this.area.getWorldName(), toReturn.getX(), toReturn.getZ()); - if (max > toReturn.getY()) { - toReturn.setY(1 + max); - } - return toReturn; } public PlotId getCenterPlotId() { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotPlayer.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotPlayer.java index f971d798e..bf6d1816e 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotPlayer.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/PlotPlayer.java @@ -628,19 +628,17 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer { }); } else if (!PlotSquared.get().isMainThread(Thread.currentThread())) { if (getMeta("teleportOnLogin", true)) { - if (plot.teleportPlayer(PlotPlayer.this)) { - TaskManager.runTask(() -> { - if (getMeta("teleportOnLogin", true)) { - if (plot.isLoaded()) { - teleport(location); - sendMessage(CaptionUtility.format(PlotPlayer.this, - Captions.TELEPORTED_TO_PLOT.getTranslated()) - + " (quitLoc-unloaded) (" + plotX + "," + plotZ - + ")"); - } + plot.teleportPlayer(PlotPlayer.this, result -> TaskManager.runTask(() -> { + if (getMeta("teleportOnLogin", true)) { + if (plot.isLoaded()) { + teleport(location); + sendMessage(CaptionUtility.format(PlotPlayer.this, + Captions.TELEPORTED_TO_PLOT.getTranslated()) + + " (quitLoc-unloaded) (" + plotX + "," + plotZ + + ")"); } - }); - } + } + })); } } } catch (Throwable e) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/worlds/SinglePlot.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/worlds/SinglePlot.java index c5207ca0a..ef29f37c2 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/worlds/SinglePlot.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/worlds/SinglePlot.java @@ -1,14 +1,11 @@ package com.github.intellectualsites.plotsquared.plot.object.worlds; -import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.flags.PlotFlag; import com.github.intellectualsites.plotsquared.plot.object.BlockLoc; import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotId; -import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; -import com.github.intellectualsites.plotsquared.plot.object.TeleportCause; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import org.jetbrains.annotations.NotNull; @@ -18,6 +15,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; public class SinglePlot extends Plot { private Set regions = Collections.singleton( @@ -51,17 +49,8 @@ public class SinglePlot extends Plot { return (SinglePlotArea) super.getArea(); } - public boolean teleportPlayer(final PlotPlayer player, TeleportCause cause) { - if (isLoaded()) { - return super.teleportPlayer(player, cause); - } else { - Captions.NOT_LOADED.send(player); - return false; - } - } - - @Override public Location getSide() { - return getCenter(); + @Override public void getSide(Consumer result) { + getCenter(result); } @Override protected boolean isLoaded() { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EventDispatcher.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EventDispatcher.java index 1b81a1468..b8de72882 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EventDispatcher.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EventDispatcher.java @@ -185,7 +185,7 @@ public class EventDispatcher { final Plot plot = player.getCurrentPlot(); if (Settings.Teleport.ON_LOGIN && plot != null && !(plot .getArea() instanceof SinglePlotArea)) { - TaskManager.runTask(() -> plot.teleportPlayer(player)); + TaskManager.runTask(() -> plot.teleportPlayer(player, result -> {})); MainUtil.sendMessage(player, CaptionUtility.format(player, Captions.TELEPORTED_TO_ROAD.getTranslated()) + " (on-login) " + "(" + plot.getId().x + ";" + plot.getId().y + ")"); @@ -195,7 +195,7 @@ public class EventDispatcher { public void doRespawnTask(final PlotPlayer player) { final Plot plot = player.getCurrentPlot(); if (Settings.Teleport.ON_DEATH && plot != null) { - TaskManager.runTask(() -> plot.teleportPlayer(player)); + TaskManager.runTask(() -> plot.teleportPlayer(player, result -> {})); MainUtil.sendMessage(player, Captions.TELEPORTED_TO_ROAD); } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/MainUtil.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/MainUtil.java index a8f24ae4b..2306b54b2 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/MainUtil.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/MainUtil.java @@ -55,6 +55,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Supplier; @@ -232,7 +233,7 @@ public class MainUtil { */ public static boolean resetBiome(PlotArea area, Location pos1, Location pos2) { BiomeType biome = area.getPlotBiome(); - if (!Objects.equals(WorldUtil.IMP.getBiome(area.getWorldName(), (pos1.getX() + pos2.getX()) / 2, + if (!Objects.equals(WorldUtil.IMP.getBiomeSynchronous(area.getWorldName(), (pos1.getX() + pos2.getX()) / 2, (pos1.getZ() + pos2.getZ()) / 2), biome)) { MainUtil.setBiome(area.getWorldName(), pos1.getX(), pos1.getZ(), pos2.getX(), pos2.getZ(), biome); @@ -589,18 +590,15 @@ public class MainUtil { /** * Get the highest block at a location. - * - * @param world - * @param x - * @param z - * @return */ - public static int getHeighestBlock(String world, int x, int z) { - int result = WorldUtil.IMP.getHighestBlock(world, x, z); - if (result == 0) { - return 63; - } - return result; + public static void getHeighestBlock(String world, int x, int z, Consumer result) { + WorldUtil.IMP.getHighestBlock(world, x, z, highest -> { + if (highest == 0) { + result.accept(63); + } else { + result.accept(highest); + } + }); } /** @@ -752,116 +750,118 @@ public class MainUtil { /** * Format a string with plot information. * - * @param info + * @param iInfo * @param plot * @param player * @param full * @param whenDone */ - public static void format(String info, final Plot plot, PlotPlayer player, final boolean full, + public static void format(final String iInfo, final Plot plot, PlotPlayer player, final boolean full, final RunnableVal whenDone) { int num = plot.getConnectedPlots().size(); String alias = !plot.getAlias().isEmpty() ? plot.getAlias() : Captions.NONE.getTranslated(); Location bot = plot.getCorners()[0]; - BiomeType biome = WorldUtil.IMP.getBiome(plot.getWorldName(), bot.getX(), bot.getZ()); - String trusted = getPlayerList(plot.getTrusted()); - String members = getPlayerList(plot.getMembers()); - String denied = getPlayerList(plot.getDenied()); - String seen; - if (Settings.Enabled_Components.PLOT_EXPIRY && ExpireManager.IMP != null) { - if (plot.isOnline()) { - seen = Captions.NOW.getTranslated(); - } else { - int time = (int) (ExpireManager.IMP.getAge(plot) / 1000); - if (time != 0) { - seen = MainUtil.secToTime(time); + WorldUtil.IMP.getBiome(plot.getWorldName(), bot.getX(), bot.getZ(), biome -> { + String info = iInfo; + String trusted = getPlayerList(plot.getTrusted()); + String members = getPlayerList(plot.getMembers()); + String denied = getPlayerList(plot.getDenied()); + String seen; + if (Settings.Enabled_Components.PLOT_EXPIRY && ExpireManager.IMP != null) { + if (plot.isOnline()) { + seen = Captions.NOW.getTranslated(); } else { - seen = Captions.UNKNOWN.getTranslated(); - } - } - } else { - seen = Captions.NEVER.getTranslated(); - } - - String description = plot.getFlag(DescriptionFlag.class); - if (description.isEmpty()) { - description = Captions.PLOT_NO_DESCRIPTION.getTranslated(); - } - - StringBuilder flags = new StringBuilder(); - Collection> flagCollection = plot.getApplicableFlags(true); - if (flagCollection.isEmpty()) { - flags.append(Captions.NONE.getTranslated()); - } else { - String prefix = " "; - for (final PlotFlag flag : flagCollection) { - Object value; - if (flag instanceof DoubleFlag && !Settings.General.SCIENTIFIC) { - value = FLAG_DECIMAL_FORMAT.format(flag.getValue()); - } else { - value = flag.toString(); - } - flags.append(prefix).append(CaptionUtility.format(player, Captions.PLOT_FLAG_LIST.getTranslated(), - flag.getName(), CaptionUtility.formatRaw(player, value.toString(), ""))); - prefix = ", "; - } - } - boolean build = plot.isAdded(player.getUUID()); - String owner = plot.getOwners().isEmpty() ? "unowned" : getPlayerList(plot.getOwners()); - if (plot.getArea() != null) { - info = info.replace("%area%", plot.getArea().getWorldName() + - (plot.getArea().getId() == null ? "" : "(" + plot.getArea().getId() + ")")); - } else { - info = info.replace("%area%", Captions.NONE.getTranslated()); - } - info = info.replace("%id%", plot.getId().toString()); - info = info.replace("%alias%", alias); - info = info.replace("%num%", String.valueOf(num)); - info = info.replace("%desc%", description); - info = info.replace("%biome%", biome.toString().toLowerCase()); - info = info.replace("%owner%", owner); - info = info.replace("%members%", members); - info = info.replace("%player%", player.getName()); - info = info.replace("%trusted%", trusted); - info = info.replace("%helpers%", members); - info = info.replace("%denied%", denied); - info = info.replace("%seen%", seen); - info = info.replace("%flags%", flags); - info = info.replace("%build%", String.valueOf(build)); - if (info.contains("%rating%")) { - final String newInfo = info; - TaskManager.runTaskAsync(() -> { - String info1; - if (Settings.Ratings.USE_LIKES) { - info1 = newInfo.replaceAll("%rating%", - String.format("%.0f%%", Like.getLikesPercentage(plot) * 100D)); - } else { - int max = 10; - if (Settings.Ratings.CATEGORIES != null && !Settings.Ratings.CATEGORIES - .isEmpty()) { - max = 8; - } - if (full && Settings.Ratings.CATEGORIES != null - && Settings.Ratings.CATEGORIES.size() > 1) { - double[] ratings = MainUtil.getAverageRatings(plot); - String rating = ""; - String prefix = ""; - for (int i = 0; i < ratings.length; i++) { - rating += prefix + Settings.Ratings.CATEGORIES.get(i) + '=' + String - .format("%.1f", ratings[i]); - prefix = ","; - } - info1 = newInfo.replaceAll("%rating%", rating); + int time = (int) (ExpireManager.IMP.getAge(plot) / 1000); + if (time != 0) { + seen = MainUtil.secToTime(time); } else { - info1 = newInfo.replaceAll("%rating%", - String.format("%.1f", plot.getAverageRating()) + '/' + max); + seen = Captions.UNKNOWN.getTranslated(); } } - whenDone.run(info1); - }); - return; - } - whenDone.run(info); + } else { + seen = Captions.NEVER.getTranslated(); + } + + String description = plot.getFlag(DescriptionFlag.class); + if (description.isEmpty()) { + description = Captions.PLOT_NO_DESCRIPTION.getTranslated(); + } + + StringBuilder flags = new StringBuilder(); + Collection> flagCollection = plot.getApplicableFlags(true); + if (flagCollection.isEmpty()) { + flags.append(Captions.NONE.getTranslated()); + } else { + String prefix = " "; + for (final PlotFlag flag : flagCollection) { + Object value; + if (flag instanceof DoubleFlag && !Settings.General.SCIENTIFIC) { + value = FLAG_DECIMAL_FORMAT.format(flag.getValue()); + } else { + value = flag.toString(); + } + flags.append(prefix).append(CaptionUtility.format(player, Captions.PLOT_FLAG_LIST.getTranslated(), + flag.getName(), CaptionUtility.formatRaw(player, value.toString(), ""))); + prefix = ", "; + } + } + boolean build = plot.isAdded(player.getUUID()); + String owner = plot.getOwners().isEmpty() ? "unowned" : getPlayerList(plot.getOwners()); + if (plot.getArea() != null) { + info = info.replace("%area%", plot.getArea().getWorldName() + + (plot.getArea().getId() == null ? "" : "(" + plot.getArea().getId() + ")")); + } else { + info = info.replace("%area%", Captions.NONE.getTranslated()); + } + info = info.replace("%id%", plot.getId().toString()); + info = info.replace("%alias%", alias); + info = info.replace("%num%", String.valueOf(num)); + info = info.replace("%desc%", description); + info = info.replace("%biome%", biome.toString().toLowerCase()); + info = info.replace("%owner%", owner); + info = info.replace("%members%", members); + info = info.replace("%player%", player.getName()); + info = info.replace("%trusted%", trusted); + info = info.replace("%helpers%", members); + info = info.replace("%denied%", denied); + info = info.replace("%seen%", seen); + info = info.replace("%flags%", flags); + info = info.replace("%build%", String.valueOf(build)); + if (info.contains("%rating%")) { + final String newInfo = info; + TaskManager.runTaskAsync(() -> { + String info1; + if (Settings.Ratings.USE_LIKES) { + info1 = newInfo.replaceAll("%rating%", + String.format("%.0f%%", Like.getLikesPercentage(plot) * 100D)); + } else { + int max = 10; + if (Settings.Ratings.CATEGORIES != null && !Settings.Ratings.CATEGORIES + .isEmpty()) { + max = 8; + } + if (full && Settings.Ratings.CATEGORIES != null + && Settings.Ratings.CATEGORIES.size() > 1) { + double[] ratings = MainUtil.getAverageRatings(plot); + String rating = ""; + String prefix = ""; + for (int i = 0; i < ratings.length; i++) { + rating += prefix + Settings.Ratings.CATEGORIES.get(i) + '=' + String + .format("%.1f", ratings[i]); + prefix = ","; + } + info1 = newInfo.replaceAll("%rating%", rating); + } else { + info1 = newInfo.replaceAll("%rating%", + String.format("%.1f", plot.getAverageRating()) + '/' + max); + } + } + whenDone.run(info1); + }); + return; + } + whenDone.run(info); + }); } public static boolean deleteDirectory(File directory) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java index 7492644d3..650451260 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java @@ -178,8 +178,7 @@ public abstract class SchematicHandler { if (pw instanceof ClassicPlotWorld) { y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT; } else { - y_offset_actual = yOffset + 1 + MainUtil - .getHeighestBlock(plot.getWorldName(), + y_offset_actual = yOffset + 1 + WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(), region.getMinimumPoint().getX() + 1, region.getMinimumPoint().getZ() + 1); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/WorldUtil.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/WorldUtil.java index 3d7188187..d83c95c27 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/WorldUtil.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/WorldUtil.java @@ -5,7 +5,6 @@ import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; -import com.github.intellectualsites.plotsquared.plot.object.schematic.PlotItem; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.NBTInputStream; @@ -15,6 +14,7 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; +import org.jetbrains.annotations.NotNull; import java.io.ByteArrayOutputStream; import java.io.File; @@ -25,11 +25,11 @@ import java.net.URL; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Consumer; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import org.jetbrains.annotations.NotNull; public abstract class WorldUtil { public static WorldUtil IMP; @@ -38,7 +38,13 @@ public abstract class WorldUtil { public abstract boolean isWorld(String worldName); - public abstract String[] getSign(Location location); + public abstract void getSign(Location location, Consumer result); + + /** + * @deprecated May result in synchronous chunk loading + */ + @Deprecated + public abstract String[] getSignSynchronous(Location location); public abstract Location getSpawn(String world); @@ -52,13 +58,29 @@ public abstract class WorldUtil { public abstract StringComparison.ComparisonResult getClosestBlock(String name); - public abstract BiomeType getBiome(String world, int x, int z); + public abstract void getBiome(String world, int x, int z, Consumer result); - public abstract BlockState getBlock(Location location); + /** + * @deprecated May result in synchronous chunk loading + */ + @Deprecated + public abstract BiomeType getBiomeSynchronous(String world, int x, int z); - public abstract int getHighestBlock(String world, int x, int z); + public abstract void getBlock(Location location, Consumer result); - public abstract boolean addItems(String world, PlotItem item); + /** + * @deprecated May result in synchronous chunk loading + */ + @Deprecated + public abstract BlockState getBlockSynchronous(Location location); + + public abstract void getHighestBlock(String world, int x, int z, final Consumer result); + + /** + * @deprecated May result in synchronous chunk loading + */ + @Deprecated + public abstract int getHighestBlockSynchronous(String world, int x, int z); public abstract void setSign(String world, int x, int y, int z, String[] lines); @@ -67,8 +89,7 @@ public abstract class WorldUtil { public abstract com.sk89q.worldedit.world.World getWeWorld(String world); public void upload(@NotNull final Plot plot, UUID uuid, String file, RunnableVal whenDone) { - final Location home = plot.getHome(); - MainUtil.upload(uuid, file, "zip", new RunnableVal() { + plot.getHome(home -> MainUtil.upload(uuid, file, "zip", new RunnableVal() { @Override public void run(OutputStream output) { try (final ZipOutputStream zos = new ZipOutputStream(output)) { File dat = getDat(plot.getWorldName()); @@ -135,7 +156,7 @@ public abstract class WorldUtil { e.printStackTrace(); } } - }, whenDone); + }, whenDone)); } public File getDat(String world) { diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java index 9072dd42b..95aed7897 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/block/LocalBlockQueue.java @@ -13,9 +13,9 @@ import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; +import org.jetbrains.annotations.NotNull; import java.util.Map; -import org.jetbrains.annotations.NotNull; public abstract class LocalBlockQueue { @@ -100,7 +100,7 @@ public abstract class LocalBlockQueue { .equals(loc)) { continue; } - pLoc.setY(WorldUtil.IMP.getHighestBlock(getWorld(), pLoc.getX(), pLoc.getZ())); + pLoc.setY(WorldUtil.IMP.getHighestBlockSynchronous(getWorld(), pLoc.getX(), pLoc.getZ())); pp.teleport(pLoc); } } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/expiry/ExpireManager.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/expiry/ExpireManager.java index 28283ce35..b595804b3 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/expiry/ExpireManager.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/expiry/ExpireManager.java @@ -119,7 +119,7 @@ public class ExpireManager { if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) { TaskManager.runTask(() -> { pp.setMeta("ignoreExpireTask", true); - pp.teleport(current.getCenter()); + current.getCenter(pp::teleport); pp.deleteMeta("ignoreExpireTask"); PlotMessage msg = new PlotMessage() .text(num + " " + (num > 1 ? "plots are" : "plot is") + " expired: ")