diff --git a/src/main/java/wtf/beatrice/limbomanager/listeners/PlayerTeleporter.java b/src/main/java/wtf/beatrice/limbomanager/listeners/PlayerTeleporter.java index aabcd6f..fb81abe 100644 --- a/src/main/java/wtf/beatrice/limbomanager/listeners/PlayerTeleporter.java +++ b/src/main/java/wtf/beatrice/limbomanager/listeners/PlayerTeleporter.java @@ -13,6 +13,7 @@ import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -21,12 +22,14 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import wtf.beatrice.limbomanager.Cache; import wtf.beatrice.limbomanager.LimboManager; +import wtf.beatrice.limbomanager.objects.AreaCleanerRunnable; import wtf.beatrice.limbomanager.objects.Coordinates; import wtf.beatrice.limbomanager.utils.LocationUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.UUID; public class PlayerTeleporter implements Listener { @@ -46,13 +49,16 @@ public class PlayerTeleporter implements Listener islandLocation.getWorld().loadChunk(islandLocation.getChunk().getX(), islandLocation.getChunk().getZ(), true); - String testSchematicPath = LimboManager.getSchematicsFolder().getAbsolutePath() + File.separator + "endcityship.schem"; + String testSchematicPath = LimboManager.getSchematicsFolder().getAbsolutePath() + File.separator + "default.schem"; File schematicFile = new File(testSchematicPath); if(!schematicFile.exists()) - System.out.println("no exist"); + { + LimboManager.getInstance().getLogger().severe("Missing schematic file. This will cause issues!"); + return; + } - // todo: check if exists, but this is just a test + // todo: improve and make as async as possible World islandWEWorld = BukkitAdapter.adapt(islandLocation.getWorld()); Clipboard shematicClipboard; @@ -86,9 +92,39 @@ public class PlayerTeleporter implements Listener @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - String playerName = event.getPlayer().getName(); + Player player = event.getPlayer(); + String playerName = player.getName(); + // clean the whole island space after the player left. + // we will go 20 blocks over the limit in case the location checker timer was extremely slow + // and let the player go that far out of them. + // + // this should never happen. + + int maxRange = Cache.islandWalkingRange + 20; + + Location islandSpawnLocation = LocationUtils.getPlayerSpawnLocation(player); + Location startFrom = new Location(islandSpawnLocation.getWorld(), + islandSpawnLocation.getX() - maxRange, + islandSpawnLocation.getWorld().getMinHeight(), + islandSpawnLocation.getZ() - maxRange); + + Location endAt = new Location(islandSpawnLocation.getWorld(), + islandSpawnLocation.getX() + maxRange, + islandSpawnLocation.getWorld().getMaxHeight(), + islandSpawnLocation.getZ() + maxRange); + + + // set the area as being "cleaned up". + UUID randomUUID = UUID.randomUUID(); + String cleanUpID = "cleanup-" + randomUUID.toString(); + Cache.playerIslands.put(cleanUpID, Cache.playerIslands.get(playerName)); Cache.playerIslands.remove(playerName); + + AreaCleanerRunnable cleanerRunnable = new AreaCleanerRunnable(startFrom, endAt, playerName, cleanUpID); + cleanerRunnable.task = Bukkit.getScheduler().runTaskTimerAsynchronously(LimboManager.getInstance(), + cleanerRunnable, + 20L,1L); } diff --git a/src/main/java/wtf/beatrice/limbomanager/objects/AreaCleanerRunnable.java b/src/main/java/wtf/beatrice/limbomanager/objects/AreaCleanerRunnable.java new file mode 100644 index 0000000..ba5085d --- /dev/null +++ b/src/main/java/wtf/beatrice/limbomanager/objects/AreaCleanerRunnable.java @@ -0,0 +1,169 @@ +package wtf.beatrice.limbomanager.objects; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.scheduler.BukkitTask; +import wtf.beatrice.limbomanager.Cache; +import wtf.beatrice.limbomanager.LimboManager; + +import java.util.ArrayList; +import java.util.List; + +public class AreaCleanerRunnable implements Runnable +{ + public BukkitTask task; + + + Location min, max; + List blocksList = new ArrayList<>(); + Location current; + int blocksPerRun = 384; + + String playerName, cleanUpID; + + public AreaCleanerRunnable(Location min, Location max, String playerName, String cleanUpID) + { + this.playerName = playerName; + this.cleanUpID = cleanUpID; + + this.min = min; + this.max = max; + + current = new Location(min.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ()); + + LimboManager.getInstance().getLogger().info(min.getBlockX() + " " + min.getBlockY() + " " + min.getBlockZ()); + LimboManager.getInstance().getLogger().info(max.getBlockX() + " " + max.getBlockY() + " " + max.getBlockZ()); + } + + + @Override + public void run() + { + boolean cancelled = false; + + for(int i = 0; i < blocksPerRun; i++) + { + if(cancelled) break; + + Bukkit.getScheduler().runTask(LimboManager.getInstance(), () -> + { + current.getBlock().setType(Material.AIR); + + if(current.getBlockY() < max.getBlockY()) { + current.setY(current.getBlockY() + 1 ); + } else { + current.setY(min.getBlockY()); + if (current.getBlockX() < max.getBlockX()) { + current.setX(current.getBlockX() + 1); + } else { + current.setX(min.getBlockX()); + if (current.getBlockZ() < max.getBlockZ()) { + current.setZ(current.getBlockZ() + 1); + LimboManager.getInstance().getLogger().info("c: " + current.getBlockX() + " " + current.getBlockY() + " " + current.getBlockZ()); + } else { + // we finished, free the location and cancel the task. + Cache.playerIslands.remove(cleanUpID); + LimboManager.getInstance().getLogger().info("finished cleaning area for " + playerName); + task.cancel(); + return; + } + } + } + }); + } + + + + + + + /* + int locationsDone = 0; + + for(int x = min.getBlockX(); x < max.getBlockX(); x++) { + for (int y = min.getBlockY(); y < max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z < max.getBlockZ(); z++) { + + if(locationsDone == blocksPerRun) + { + + } + + blocksList.add(new Location(min.getWorld(), x, y, z)); + locationsDone++; + } + } + } + + + if(blocksList.isEmpty()) + { + // we finished, free the location and cancel the task. + Cache.playerIslands.remove(playerName); // todo: what if player rejoins in the meanwhile + LimboManager.getInstance().getLogger().info("finished cleaning area for " + playerName); + task.cancel(); + } + + + for (int i = 0; i < blocksPerRun; i++) + { + if(i >= blocksList.size()) + { + // we finished, free the location and cancel the task. + Cache.playerIslands.remove(playerName); // todo: what if player rejoins in the meanwhile + LimboManager.getInstance().getLogger().info("finished cleaning area for " + playerName); + task.cancel(); + break; + } + + Location loc = blocksList.get(i); + + Bukkit.getScheduler().runTask(LimboManager.getInstance(), () -> + { + LimboManager.getInstance().getLogger().info("c: " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ()); + loc.getBlock().setType(Material.AIR); + }); + }*/ + + + + /*for(int i = 0; i < blocksPerRun; i++) + { + + // sync block write + Bukkit.getScheduler().runTask(LimboManager.getInstance(), () -> + { + LimboManager.getInstance().getLogger().info("c: " + current.getBlockX() + " " + current.getBlockY() + " " + current.getBlockZ()); + current.getBlock().setType(Material.AIR); + + // update current coordinates + if(current.getBlockX() < max.getBlockX()) + { + current.setX(current.getBlockX() + 1); + } + else { + current.setX(min.getBlockX()); + if(current.getBlockY() < max.getBlockY()) + { + current.setY(max.getBlockY() + 1); + } else { + current.setY(min.getBlockY()); + if(current.getBlockZ() < max.getBlockZ()) + { + current.setZ(max.getBlockZ() + 1); + } else { + // we finished, free the location and cancel the task. + Cache.playerIslands.remove(playerName); // todo: what if player rejoins in the meanwhile + LimboManager.getInstance().getLogger().info("finished cleaning area for " + playerName); + task.cancel(); + return; + } + } + } + + }); + + }*/ + } +} diff --git a/src/main/java/wtf/beatrice/limbomanager/utils/LocationUtils.java b/src/main/java/wtf/beatrice/limbomanager/utils/LocationUtils.java index edb1be5..453653e 100644 --- a/src/main/java/wtf/beatrice/limbomanager/utils/LocationUtils.java +++ b/src/main/java/wtf/beatrice/limbomanager/utils/LocationUtils.java @@ -22,7 +22,7 @@ public class LocationUtils { } - private static Location getPlayerSpawnLocation(Player player) { + public static Location getPlayerSpawnLocation(Player player) { String worldName = Cache.getConfiguration().getString("island.world-name"); if(worldName == null)