Fixes the major lag source from GlobalBlockQueue

This commit is contained in:
MattBDev 2019-09-11 19:04:29 -04:00
parent 2bf47478b2
commit 68a5166d2f
14 changed files with 231 additions and 214 deletions

View File

@ -9,6 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefCla
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField;
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
@ -168,7 +169,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
@EventHandler(priority = EventPriority.LOWEST) public void onItemSpawn(ItemSpawnEvent event) { @EventHandler(priority = EventPriority.LOWEST) public void onItemSpawn(ItemSpawnEvent event) {
Item entity = event.getEntity(); Item entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk(); PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
if (chunk == this.lastChunk) { if (chunk == this.lastChunk) {
event.getEntity().remove(); event.getEntity().remove();
event.setCancelled(true); event.setCancelled(true);
@ -185,6 +186,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
} else { } else {
this.lastChunk = null; this.lastChunk = null;
} }
});
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -197,7 +199,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onEntitySpawn(CreatureSpawnEvent event) { public void onEntitySpawn(CreatureSpawnEvent event) {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk(); PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
if (chunk == this.lastChunk) { if (chunk == this.lastChunk) {
event.getEntity().remove(); event.getEntity().remove();
event.setCancelled(true); event.setCancelled(true);
@ -214,6 +216,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
} else { } else {
this.lastChunk = null; this.lastChunk = null;
} }
});
} }
private void cleanChunk(final Chunk chunk) { private void cleanChunk(final Chunk chunk) {
@ -223,8 +226,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (!chunk.isLoaded()) { if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex); TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated() PlotSquared.debug("Successfully processed and unloaded chunk!");
+ "&aSuccessfully processed and unloaded chunk!");
chunk.unload(true); chunk.unload(true);
return; return;
} }
@ -232,8 +234,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (tiles.length == 0) { if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex); TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated() PlotSquared.debug("Successfully processed and unloaded chunk!");
+ "&aSuccessfully processed and unloaded chunk!");
chunk.unload(true); chunk.unload(true);
return; return;
} }
@ -243,8 +244,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (i >= tiles.length) { if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex); TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated() PlotSquared.debug("Successfully processed and unloaded chunk!");
+ "&aSuccessfully processed and unloaded chunk!");
chunk.unload(true); chunk.unload(true);
return; return;
} }
@ -267,17 +267,11 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
ent.remove(); ent.remove();
} }
} }
PlotSquared.debug( PlotSquared.debug("PlotSquared detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
Captions.PREFIX.getTranslated() + "&a detected unsafe chunk and processed: " + (
chunk.getX()
<< 4) + "," + (chunk.getX() << 4));
} }
if (tiles.length > Settings.Chunk_Processor.MAX_TILES) { if (tiles.length > Settings.Chunk_Processor.MAX_TILES) {
if (unload) { if (unload) {
PlotSquared.debug( PlotSquared.debug("PlotSquared detected unsafe chunk: " + (chunk.getX()<< 4) + "," + (chunk.getX() << 4));
Captions.PREFIX.getTranslated() + "&c detected unsafe chunk: " + (chunk.getX()
<< 4) + ","
+ (chunk.getX() << 4));
cleanChunk(chunk); cleanChunk(chunk);
return true; return true;
} }

View File

@ -7,6 +7,7 @@ import com.github.intellectualsites.plotsquared.plot.flag.Flags;
import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import io.papermc.lib.PaperLib;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
@ -75,7 +76,7 @@ public class EntitySpawnListener implements Listener {
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) { if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
try { try {
ignoreTP = true; ignoreTP = true;
entity.teleport(origin); PaperLib.teleportAsync(entity,origin);
} finally { } finally {
ignoreTP = false; ignoreTP = false;
} }

View File

@ -12,6 +12,7 @@ import com.github.intellectualsites.plotsquared.plot.listener.PlayerBlockEventTy
import com.github.intellectualsites.plotsquared.plot.listener.PlotListener; import com.github.intellectualsites.plotsquared.plot.listener.PlotListener;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.util.*; import com.github.intellectualsites.plotsquared.plot.util.*;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.FluidCollisionMode; import org.bukkit.FluidCollisionMode;
@ -756,12 +757,12 @@ import java.util.regex.Pattern;
if (passengers != null) { if (passengers != null) {
vehicle.eject(); vehicle.eject();
vehicle.setVelocity(new Vector(0d, 0d, 0d)); vehicle.setVelocity(new Vector(0d, 0d, 0d));
vehicle.teleport(dest); PaperLib.teleportAsync(vehicle, dest);
passengers.forEach(vehicle::addPassenger); passengers.forEach(vehicle::addPassenger);
} else { } else {
vehicle.eject(); vehicle.eject();
vehicle.setVelocity(new Vector(0d, 0d, 0d)); vehicle.setVelocity(new Vector(0d, 0d, 0d));
vehicle.teleport(dest); PaperLib.teleportAsync(vehicle, dest);
vehicle.addPassenger(player); vehicle.addPassenger(player);
} }
return; return;

View File

@ -189,7 +189,7 @@ public class BukkitPlayer extends PlotPlayer {
} }
final org.bukkit.Location bukkitLocation = new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX() + 0.5, final org.bukkit.Location bukkitLocation = new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX() + 0.5,
location.getY(), location.getZ() + 0.5, location.getYaw(), location.getPitch()); location.getY(), location.getZ() + 0.5, location.getYaw(), location.getPitch());
PaperLib.teleportAsync(player, bukkitLocation); PaperLib.teleportAsync(player, bukkitLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
} }
@Override public String getName() { @Override public String getName() {

View File

@ -14,6 +14,7 @@ import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlock
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@ -26,6 +27,7 @@ import org.bukkit.entity.Player;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
public class BukkitChunkManager extends ChunkManager { public class BukkitChunkManager extends ChunkManager {
@ -152,7 +154,7 @@ public class BukkitChunkManager extends ChunkManager {
if (doWhole) { if (doWhole) {
for (Entity entity : entities) { for (Entity entity : entities) {
org.bukkit.Location location = entity.getLocation(); org.bukkit.Location location = entity.getLocation();
Chunk chunk = location.getChunk(); PaperLib.getChunkAtAsync(location).thenAccept( chunk -> {
if (chunks.contains(chunk)) { if (chunks.contains(chunk)) {
int X = chunk.getX(); int X = chunk.getX();
int Z = chunk.getZ(); int Z = chunk.getZ();
@ -165,6 +167,7 @@ public class BukkitChunkManager extends ChunkManager {
} }
} }
} }
});
} }
} else { } else {
for (Chunk chunk : chunks) { for (Chunk chunk : chunks) {
@ -196,6 +199,8 @@ public class BukkitChunkManager extends ChunkManager {
final World oldWorld = Bukkit.getWorld(pos1.getWorld()); final World oldWorld = Bukkit.getWorld(pos1.getWorld());
final BukkitWorld oldBukkitWorld = new BukkitWorld(oldWorld); final BukkitWorld oldBukkitWorld = new BukkitWorld(oldWorld);
final World newWorld = Bukkit.getWorld(newPos.getWorld()); final World newWorld = Bukkit.getWorld(newPos.getWorld());
assert newWorld != null;
assert oldWorld != null;
final String newWorldName = newWorld.getName(); final String newWorldName = newWorld.getName();
final ContentMap map = new ContentMap(); final ContentMap map = new ContentMap();
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(newWorldName, false); final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(newWorldName, false);
@ -208,13 +213,14 @@ public class BukkitChunkManager extends ChunkManager {
ChunkLoc loc = new ChunkLoc(value[0], value[1]); ChunkLoc loc = new ChunkLoc(value[0], value[1]);
int cxx = loc.x << 4; int cxx = loc.x << 4;
int czz = loc.z << 4; int czz = loc.z << 4;
Chunk chunk = oldWorld.getChunkAt(loc.x, loc.z); PaperLib.getChunkAtAsync(oldWorld, loc.x, loc.z)
map.saveEntitiesIn(chunk, region); .thenAccept(chunk1 -> map.saveEntitiesIn(chunk1, region)).thenRun(() -> {
for (int x = bx & 15; x <= (tx & 15); x++) { for (int x = bx & 15; x <= (tx & 15); x++) {
for (int z = bz & 15; z <= (tz & 15); z++) { for (int z = bz & 15; z <= (tz & 15); z++) {
map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ); map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ);
} }
} }
});
} }
}, () -> { }, () -> {
for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) { for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) {
@ -387,13 +393,12 @@ public class BukkitChunkManager extends ChunkManager {
return true; return true;
} }
@Override public boolean loadChunk(String world, ChunkLoc chunkLoc, boolean force) { @Override public CompletableFuture loadChunk(String world, ChunkLoc chunkLoc, boolean force) {
return BukkitUtil.getWorld(world).getChunkAt(chunkLoc.x, chunkLoc.z).load(force); return PaperLib.getChunkAtAsync(BukkitUtil.getWorld(world),chunkLoc.x, chunkLoc.z, force);
} }
@Override @Override
public void unloadChunk(final String world, final ChunkLoc chunkLoc, final boolean save, public void unloadChunk(final String world, final ChunkLoc chunkLoc, final boolean save) {
final boolean safe) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) { if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask( TaskManager.runTask(
() -> BukkitUtil.getWorld(world).unloadChunk(chunkLoc.x, chunkLoc.z, save)); () -> BukkitUtil.getWorld(world).unloadChunk(chunkLoc.x, chunkLoc.z, save));

View File

@ -9,6 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.SetupObject; import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils; import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@ -61,7 +62,7 @@ public class BukkitSetupUtils extends SetupUtils {
} }
World dw = Bukkit.getWorlds().get(0); World dw = Bukkit.getWorlds().get(0);
for (Player player : world.getPlayers()) { for (Player player : world.getPlayers()) {
player.teleport(dw.getSpawnLocation()); PaperLib.teleportAsync(player,dw.getSpawnLocation());
} }
if (save) { if (save) {
for (Chunk chunk : world.getLoadedChunks()) { for (Chunk chunk : world.getLoadedChunks()) {

View File

@ -12,6 +12,7 @@ import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefFie
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod; import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@ -133,7 +134,7 @@ public class SendChunk {
ArrayList<Chunk> chunks = new ArrayList<>(); ArrayList<Chunk> chunks = new ArrayList<>();
for (ChunkLoc loc : chunkLocations) { for (ChunkLoc loc : chunkLocations) {
if (myWorld.isChunkLoaded(loc.x, loc.z)) { if (myWorld.isChunkLoaded(loc.x, loc.z)) {
chunks.add(myWorld.getChunkAt(loc.x, loc.z)); PaperLib.getChunkAtAsync(myWorld, loc.x, loc.z).thenAccept(chunks::add);
} }
} }
sendChunk(chunks); sendChunk(chunks);

View File

@ -10,9 +10,9 @@ import com.github.intellectualsites.plotsquared.plot.util.block.BasicLocalBlockQ
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import io.papermc.lib.PaperLib;
import lombok.NonNull; import lombok.NonNull;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
@ -75,15 +75,15 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
setBaseBlocks(lc); setBaseBlocks(lc);
} }
public void setBaseBlocks(LocalChunk lc) throws ExecutionException, InterruptedException { public void setBaseBlocks(LocalChunk localChunk) {
World worldObj = Bukkit.getWorld(getWorld()); World worldObj = Bukkit.getWorld(getWorld());
if (worldObj == null) { if (worldObj == null) {
throw new NullPointerException("World cannot be null."); throw new NullPointerException("World cannot be null.");
} }
//PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true).get(); PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
Chunk chunk = worldObj.getChunkAt(lc.getX(), lc.getZ()); .thenAccept(chunk -> {
for (int layer = 0; layer < lc.baseblocks.length; layer++) { for (int layer = 0; layer < localChunk.baseblocks.length; layer++) {
BaseBlock[] blocksLayer = lc.baseblocks[layer]; BaseBlock[] blocksLayer = localChunk.baseblocks[layer];
if (blocksLayer != null) { if (blocksLayer != null) {
for (int j = 0; j < blocksLayer.length; j++) { for (int j = 0; j < blocksLayer.length; j++) {
if (blocksLayer[j] != null) { if (blocksLayer[j] != null) {
@ -95,8 +95,8 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
BlockData blockData = BukkitAdapter.adapt(block); BlockData blockData = BukkitAdapter.adapt(block);
Block existing = chunk.getBlock(x, y, z); Block existing = chunk.getBlock(x, y, z);
if (equals(PlotBlock.get(block), existing) && existing.getBlockData() if (equals(PlotBlock.get(block), existing) && existing
.matches(blockData)) { .getBlockData().matches(blockData)) {
continue; continue;
} }
@ -106,13 +106,14 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
CompoundTag tag = block.getNbtData(); CompoundTag tag = block.getNbtData();
StateWrapper sw = new StateWrapper(tag); StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(worldObj.getName(), existing.getX(), existing.getY(), sw.restoreTag(worldObj.getName(), existing.getX(),
existing.getZ()); existing.getY(), existing.getZ());
} }
} }
} }
} }
} }
});
} }
private void setMaterial(@NonNull final PlotBlock plotBlock, @NonNull final Block block) { private void setMaterial(@NonNull final PlotBlock plotBlock, @NonNull final Block block) {

View File

@ -17,8 +17,7 @@ import java.util.UUID;
@CommandDeclaration(command = "debugclaimtest", description = @CommandDeclaration(command = "debugclaimtest", description =
"If you accidentally delete your database, this command will attempt to restore all plots based on the data from plot signs. " "If you accidentally delete your database, this command will attempt to restore all plots based on the data from plot signs. "
+ "Execution time may vary", category = CommandCategory.DEBUG, + "Execution time may vary", category = CommandCategory.DEBUG, requiredType = RequiredType.CONSOLE, permission = "plots.debugclaimtest")
requiredType = RequiredType.CONSOLE, permission = "plots.debugclaimtest")
public class DebugClaimTest extends SubCommand { public class DebugClaimTest extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public boolean onCommand(final PlotPlayer player, String[] args) {
@ -57,10 +56,7 @@ public class DebugClaimTest extends SubCommand {
} }
Location location = manager.getSignLoc(plot); Location location = manager.getSignLoc(plot);
ChunkLoc chunk = new ChunkLoc(location.getX() >> 4, location.getZ() >> 4); ChunkLoc chunk = new ChunkLoc(location.getX() >> 4, location.getZ() >> 4);
boolean result = ChunkManager.manager.loadChunk(area.worldname, chunk, false); ChunkManager.manager.loadChunk(area.worldname, chunk, false).thenRun(() -> {
if (!result) {
continue;
}
String[] lines = WorldUtil.IMP.getSign(location); String[] lines = WorldUtil.IMP.getSign(location);
if (lines != null) { if (lines != null) {
String line = lines[2]; String line = lines[2];
@ -82,8 +78,8 @@ public class DebugClaimTest extends SubCommand {
uuid = UUIDHandler.getUUID(line, null); uuid = UUIDHandler.getUUID(line, null);
} }
if (uuid != null) { if (uuid != null) {
MainUtil MainUtil.sendMessage(player,
.sendMessage(player, " - &aFound plot: " + plot.getId() + " : " + line); " - &aFound plot: " + plot.getId() + " : " + line);
plot.setOwner(uuid); plot.setOwner(uuid);
plots.add(plot); plots.add(plot);
} else { } else {
@ -92,22 +88,22 @@ public class DebugClaimTest extends SubCommand {
} }
} }
} }
} }).thenRun(() -> {
if (!plots.isEmpty()) { if (!plots.isEmpty()) {
MainUtil.sendMessage(player, MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: &7Updating '" + plots.size() + "' plots!"); "&3Sign Block&8->&3Plot&8: &7Updating '" + plots.size() + "' plots!");
DBFunc.createPlotsAndData(plots, new Runnable() { DBFunc.createPlotsAndData(plots,
@Override public void run() { () -> MainUtil.sendMessage(player, "&6Database update finished!"));
MainUtil.sendMessage(player, "&6Database update finished!"); for (Plot plot1 : plots) {
}
});
for (Plot plot : plots) {
plot.create(); plot.create();
} }
MainUtil.sendMessage(player, "&3Sign Block&8->&3Plot&8: &7Complete!"); MainUtil.sendMessage(player, "&3Sign Block&8->&3Plot&8: &7Complete!");
} else { } else {
MainUtil.sendMessage(player, "No plots were found for the given search."); MainUtil.sendMessage(player, "No plots were found for the given search.");
} }
});
return true;
}
return true; return true;
} }
} }

View File

@ -1,7 +1,6 @@
package com.github.intellectualsites.plotsquared.plot.generator; package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.flag.FlagManager; import com.github.intellectualsites.plotsquared.plot.flag.FlagManager;
import com.github.intellectualsites.plotsquared.plot.flag.Flags; import com.github.intellectualsites.plotsquared.plot.flag.Flags;
@ -20,6 +19,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public abstract class HybridUtils { public abstract class HybridUtils {
@ -144,8 +144,9 @@ public abstract class HybridUtils {
return scheduleRoadUpdate(plot.getArea(), regions, extend); return scheduleRoadUpdate(plot.getArea(), regions, extend);
} }
public boolean scheduleRoadUpdate(final PlotArea area, Set<ChunkLoc> rgs, final int extend) { public boolean scheduleRoadUpdate(final PlotArea area, Set<ChunkLoc> regions,
HybridUtils.regions = rgs; final int extend) {
HybridUtils.regions = regions;
HybridUtils.area = area; HybridUtils.area = area;
chunks = new HashSet<>(); chunks = new HashSet<>();
final AtomicInteger count = new AtomicInteger(0); final AtomicInteger count = new AtomicInteger(0);
@ -156,35 +157,39 @@ public abstract class HybridUtils {
while (iter.hasNext()) { while (iter.hasNext()) {
ChunkLoc chunk = iter.next(); ChunkLoc chunk = iter.next();
iter.remove(); iter.remove();
regenerateRoad(area, chunk, extend); boolean regenedRoad = regenerateRoad(area, chunk, extend);
ChunkManager.manager.unloadChunk(area.worldname, chunk, true, true); if (!regenedRoad) {
PlotSquared.debug("Failed to regenerate roads.");
} }
PlotSquared.debug("&cCancelled road task"); ChunkManager.manager.unloadChunk(area.worldname, chunk, true);
}
PlotSquared.debug("Cancelled road task");
return; return;
} }
count.incrementAndGet(); count.incrementAndGet();
if (count.intValue() % 20 == 0) { if (count.intValue() % 20 == 0) {
PlotSquared.debug("PROGRESS: " + 100 * (2048 - chunks.size()) / 2048 + "%"); PlotSquared.debug("PROGRESS: " + 100 * (2048 - chunks.size()) / 2048 + "%");
} }
if (regions.isEmpty() && chunks.isEmpty()) { if (HybridUtils.regions.isEmpty() && chunks.isEmpty()) {
PlotSquared.debug("&3Regenerating plot walls"); PlotSquared.debug("Regenerating plot walls");
regeneratePlotWalls(area); regeneratePlotWalls(area);
HybridUtils.UPDATE = false; HybridUtils.UPDATE = false;
PlotSquared.debug(Captions.PREFIX.getTranslated() + "Finished road conversion"); PlotSquared.debug("Finished road conversion");
// CANCEL TASK // CANCEL TASK
} else { } else {
final Runnable task = this; final Runnable task = this;
TaskManager.runTaskAsync(() -> { TaskManager.runTaskAsync(() -> {
try { try {
if (chunks.size() < 1024) { if (chunks.size() < 1024) {
if (!regions.isEmpty()) { if (!HybridUtils.regions.isEmpty()) {
Iterator<ChunkLoc> iterator = regions.iterator(); Iterator<ChunkLoc> iterator = HybridUtils.regions.iterator();
ChunkLoc loc = iterator.next(); ChunkLoc loc = iterator.next();
iterator.remove(); iterator.remove();
PlotSquared.debug("&3Updating .mcr: " + loc.x + ", " + loc.z PlotSquared.debug("Updating .mcr: " + loc.x + ", " + loc.z
+ " (approx 1024 chunks)"); + " (approx 1024 chunks)");
PlotSquared.debug(" - Remaining: " + regions.size()); PlotSquared
.debug(" - Remaining: " + HybridUtils.regions.size());
chunks.addAll(getChunks(loc)); chunks.addAll(getChunks(loc));
System.gc(); System.gc();
} }
@ -198,30 +203,33 @@ public abstract class HybridUtils {
.isEmpty()) { .isEmpty()) {
final ChunkLoc chunk = iterator.next(); final ChunkLoc chunk = iterator.next();
iterator.remove(); iterator.remove();
boolean regenedRoads =
regenerateRoad(area, chunk, extend); regenerateRoad(area, chunk, extend);
if (!regenedRoads) {
PlotSquared.debug("Failed to regenerate road.");
}
} }
} }
}); });
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Iterator<ChunkLoc> iterator = regions.iterator(); Iterator<ChunkLoc> iterator = HybridUtils.regions.iterator();
ChunkLoc loc = iterator.next(); ChunkLoc loc = iterator.next();
iterator.remove(); iterator.remove();
PlotSquared.debug( PlotSquared.debug(
"&c[ERROR]&7 Could not update '" + area.worldname + "/region/r." "[ERROR] Could not update '" + area.worldname + "/region/r." + loc.x
+ loc.x + "." + loc.z + ".mca' (Corrupt chunk?)"); + "." + loc.z + ".mca' (Corrupt chunk?)");
int sx = loc.x << 5; int sx = loc.x << 5;
int sz = loc.z << 5; int sz = loc.z << 5;
for (int x = sx; x < sx + 32; x++) { for (int x = sx; x < sx + 32; x++) {
for (int z = sz; z < sz + 32; z++) { for (int z = sz; z < sz + 32; z++) {
ChunkManager.manager ChunkManager.manager
.unloadChunk(area.worldname, new ChunkLoc(x, z), true, .unloadChunk(area.worldname, new ChunkLoc(x, z), true);
true);
} }
} }
PlotSquared.debug("&d - Potentially skipping 1024 chunks"); PlotSquared.debug(" - Potentially skipping 1024 chunks");
PlotSquared.debug("&d - TODO: recommend chunkster if corrupt"); PlotSquared.debug(" - TODO: recommend chunkster if corrupt");
} }
GlobalBlockQueue.IMP.addEmptyTask(() -> TaskManager.runTaskLater(task, 20)); GlobalBlockQueue.IMP.addEmptyTask(() -> TaskManager.runTaskLater(task, 20));
}); });
@ -304,42 +312,43 @@ public abstract class HybridUtils {
if (!plotWorld.ROAD_SCHEMATIC_ENABLED) { if (!plotWorld.ROAD_SCHEMATIC_ENABLED) {
return false; return false;
} }
boolean toCheck = false; AtomicBoolean toCheck = new AtomicBoolean(false);
if (plotWorld.TYPE == 2) { if (plotWorld.TYPE == 2) {
boolean c1 = area.contains(x, z); boolean chunk1 = area.contains(x, z);
boolean c2 = area.contains(ex, ez); boolean chunk2 = area.contains(ex, ez);
if (!c1 && !c2) { if (!chunk1 && !chunk2) {
return false; return false;
} else { } else {
toCheck = c1 ^ c2; toCheck.set(chunk1 ^ chunk2);
} }
} }
PlotManager manager = area.getPlotManager(); PlotManager manager = area.getPlotManager();
PlotId id1 = manager.getPlotId(x, 0, z); PlotId id1 = manager.getPlotId(x, 0, z);
PlotId id2 = manager.getPlotId(ex, 0, ez); PlotId id2 = manager.getPlotId(ex, 0, ez);
x -= plotWorld.ROAD_OFFSET_X; x = x - plotWorld.ROAD_OFFSET_X;
z -= plotWorld.ROAD_OFFSET_Z; z -= plotWorld.ROAD_OFFSET_Z;
final int finalX = x;
final int finalZ = z;
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(plotWorld.worldname, false); LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(plotWorld.worldname, false);
if (id1 == null || id2 == null || id1 != id2) { if (id1 == null || id2 == null || id1 != id2) {
boolean result = ChunkManager.manager.loadChunk(area.worldname, chunk, false); ChunkManager.manager.loadChunk(area.worldname, chunk, false).thenRun(() -> {
if (result) {
if (id1 != null) { if (id1 != null) {
Plot p1 = area.getPlotAbs(id1); Plot p1 = area.getPlotAbs(id1);
if (p1 != null && p1.hasOwner() && p1.isMerged()) { if (p1 != null && p1.hasOwner() && p1.isMerged()) {
toCheck = true; toCheck.set(true);
} }
} }
if (id2 != null && !toCheck) { if (id2 != null && !toCheck.get()) {
Plot p2 = area.getPlotAbs(id2); Plot p2 = area.getPlotAbs(id2);
if (p2 != null && p2.hasOwner() && p2.isMerged()) { if (p2 != null && p2.hasOwner() && p2.isMerged()) {
toCheck = true; toCheck.set(true);
} }
} }
int size = plotWorld.SIZE; int size = plotWorld.SIZE;
for (int X = 0; X < 16; X++) { for (int X = 0; X < 16; X++) {
short absX = (short) ((x + X) % size); short absX = (short) ((finalX + X) % size);
for (int Z = 0; Z < 16; Z++) { for (int Z = 0; Z < 16; Z++) {
short absZ = (short) ((z + Z) % size); short absZ = (short) ((finalZ + Z) % size);
if (absX < 0) { if (absX < 0) {
absX += size; absX += size;
} }
@ -347,11 +356,9 @@ public abstract class HybridUtils {
absZ += size; absZ += size;
} }
boolean condition; boolean condition;
if (toCheck) { if (toCheck.get()) {
condition = manager condition = manager.getPlotId(finalX + X + plotWorld.ROAD_OFFSET_X, 1,
.getPlotId(x + X + plotWorld.ROAD_OFFSET_X, 1, finalZ + Z + plotWorld.ROAD_OFFSET_Z) == null;
z + Z + plotWorld.ROAD_OFFSET_Z) == null;
// condition = MainUtil.isPlotRoad(new Location(plotworld.worldname, x + X, 1, z + Z));
} else { } else {
boolean gx = absX > plotWorld.PATH_WIDTH_LOWER; boolean gx = absX > plotWorld.PATH_WIDTH_LOWER;
boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER; boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER;
@ -362,26 +369,22 @@ public abstract class HybridUtils {
if (condition) { if (condition) {
BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
int minY = plotWorld.SCHEM_Y; int minY = plotWorld.SCHEM_Y;
if (!Settings.Schematics.PASTE_ON_TOP) if (!Settings.Schematics.PASTE_ON_TOP) {
minY = 1; minY = 1;
}
int maxY = Math.max(extend, blocks.length); int maxY = Math.max(extend, blocks.length);
if (blocks != null) {
for (int y = 0; y < maxY; y++) { for (int y = 0; y < maxY; y++) {
if (y > blocks.length - 1) { if (y > blocks.length - 1) {
queue.setBlock(x + X + plotWorld.ROAD_OFFSET_X, minY + y, queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y,
z + Z + plotWorld.ROAD_OFFSET_Z, WEExtent.AIRBASE); finalZ + Z + plotWorld.ROAD_OFFSET_Z, WEExtent.AIRBASE);
} else { } else {
BaseBlock block = blocks[y]; BaseBlock block = blocks[y];
if (block != null) { if (block != null) {
queue queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y,
.setBlock(x + X + plotWorld.ROAD_OFFSET_X, minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z, block);
z + Z + plotWorld.ROAD_OFFSET_Z, block);
} else { } else {
queue queue.setBlock(finalX + X + plotWorld.ROAD_OFFSET_X, minY + y,
.setBlock(x + X + plotWorld.ROAD_OFFSET_X, minY + y, finalZ + Z + plotWorld.ROAD_OFFSET_Z, WEExtent.AIRBASE);
z + Z + plotWorld.ROAD_OFFSET_Z,
WEExtent.AIRBASE);
}
} }
} }
} }
@ -389,9 +392,9 @@ public abstract class HybridUtils {
} }
} }
queue.enqueue(); queue.enqueue();
});
return true; return true;
} }
}
return false; return false;
} }

View File

@ -10,6 +10,22 @@ public class ChunkLoc {
this.z = z; this.z = z;
} }
public static long getChunkLong(int x, int z) {
return (long) x & 0xffffffffL | ((long) z & 0xffffffffL) << 32;
}
public long toLong() {
return getChunkLong(this.x,this.z);
}
public static int getX(long chunkLong) {
return (int)(chunkLong & 0xffffffffL);
}
public static int getZ(long chunkLong) {
return (int)(chunkLong >>> 32 & 0xffffffffL);
}
@Override public int hashCode() { @Override public int hashCode() {
return (x << 16) | (z & 0xFFFF); return (x << 16) | (z & 0xFFFF);
} }

View File

@ -924,7 +924,7 @@ public class Plot {
ChunkManager.manager.loadChunk(getWorldName(), loc, false); ChunkManager.manager.loadChunk(getWorldName(), loc, false);
MainUtil.setBiome(getWorldName(), value[2], value[3], value[4], value[5], MainUtil.setBiome(getWorldName(), value[2], value[3], value[4], value[5],
biome); biome);
ChunkManager.manager.unloadChunk(getWorldName(), loc, true, true); ChunkManager.manager.unloadChunk(getWorldName(), loc, true);
} }
}, this, 5); }, this, 5);

View File

@ -16,6 +16,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public abstract class ChunkManager { public abstract class ChunkManager {
@ -109,9 +110,7 @@ public abstract class ChunkManager {
TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() { TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() {
@Override public void run(ChunkLoc value) { @Override public void run(ChunkLoc value) {
if (manager.loadChunk(world, value, false)) { manager.loadChunk(world, value, false).thenRun(()-> task.run(value));
task.run(value);
}
} }
}, whenDone); }, whenDone);
}); });
@ -212,9 +211,9 @@ public abstract class ChunkManager {
*/ */
public abstract int[] countEntities(Plot plot); public abstract int[] countEntities(Plot plot);
public abstract boolean loadChunk(String world, ChunkLoc loc, boolean force); public abstract CompletableFuture loadChunk(String world, ChunkLoc loc, boolean force);
public abstract void unloadChunk(String world, ChunkLoc loc, boolean save, boolean safe); public abstract void unloadChunk(String world, ChunkLoc loc, boolean save);
public Set<ChunkLoc> getChunkChunks(String world) { public Set<ChunkLoc> getChunkChunks(String world) {
File folder = File folder =

View File

@ -50,8 +50,7 @@ public abstract class BasicLocalBlockQueue extends LocalBlockQueue {
LocalChunk chunk = chunks.poll(); LocalChunk chunk = chunks.poll();
if (chunk != null) { if (chunk != null) {
blockChunks.remove(chunk.longHash()); blockChunks.remove(chunk.longHash());
this.execute(chunk); return this.execute(chunk);
return true;
} }
} }
} catch (Throwable e) { } catch (Throwable e) {