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.RefMethod;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
@ -168,23 +169,24 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
@EventHandler(priority = EventPriority.LOWEST) public void onItemSpawn(ItemSpawnEvent event) {
Item entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk();
if (chunk == this.lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
this.lastChunk = chunk;
} else {
this.lastChunk = null;
}
PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
if (chunk == this.lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
this.lastChunk = chunk;
} else {
this.lastChunk = null;
}
});
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -197,23 +199,24 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
@EventHandler(priority = EventPriority.LOWEST)
public void onEntitySpawn(CreatureSpawnEvent event) {
LivingEntity entity = event.getEntity();
Chunk chunk = entity.getLocation().getChunk();
if (chunk == this.lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
this.lastChunk = chunk;
} else {
this.lastChunk = null;
}
PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
if (chunk == this.lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
Entity[] entities = chunk.getEntities();
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
this.lastChunk = chunk;
} else {
this.lastChunk = null;
}
});
}
private void cleanChunk(final Chunk chunk) {
@ -223,8 +226,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated()
+ "&aSuccessfully processed and unloaded chunk!");
PlotSquared.debug("Successfully processed and unloaded chunk!");
chunk.unload(true);
return;
}
@ -232,8 +234,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated()
+ "&aSuccessfully processed and unloaded chunk!");
PlotSquared.debug("Successfully processed and unloaded chunk!");
chunk.unload(true);
return;
}
@ -243,8 +244,7 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.debug(Captions.PREFIX.getTranslated()
+ "&aSuccessfully processed and unloaded chunk!");
PlotSquared.debug("Successfully processed and unloaded chunk!");
chunk.unload(true);
return;
}
@ -267,17 +267,11 @@ import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils
ent.remove();
}
}
PlotSquared.debug(
Captions.PREFIX.getTranslated() + "&a detected unsafe chunk and processed: " + (
chunk.getX()
<< 4) + "," + (chunk.getX() << 4));
PlotSquared.debug("PlotSquared detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
}
if (tiles.length > Settings.Chunk_Processor.MAX_TILES) {
if (unload) {
PlotSquared.debug(
Captions.PREFIX.getTranslated() + "&c detected unsafe chunk: " + (chunk.getX()
<< 4) + ","
+ (chunk.getX() << 4));
PlotSquared.debug("PlotSquared detected unsafe chunk: " + (chunk.getX()<< 4) + "," + (chunk.getX() << 4));
cleanChunk(chunk);
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.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import io.papermc.lib.PaperLib;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.ArmorStand;
@ -75,7 +76,7 @@ public class EntitySpawnListener implements Listener {
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
try {
ignoreTP = true;
entity.teleport(origin);
PaperLib.teleportAsync(entity,origin);
} finally {
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.object.*;
import com.github.intellectualsites.plotsquared.plot.util.*;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.FluidCollisionMode;
@ -756,12 +757,12 @@ import java.util.regex.Pattern;
if (passengers != null) {
vehicle.eject();
vehicle.setVelocity(new Vector(0d, 0d, 0d));
vehicle.teleport(dest);
PaperLib.teleportAsync(vehicle, dest);
passengers.forEach(vehicle::addPassenger);
} else {
vehicle.eject();
vehicle.setVelocity(new Vector(0d, 0d, 0d));
vehicle.teleport(dest);
PaperLib.teleportAsync(vehicle, dest);
vehicle.addPassenger(player);
}
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,
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() {

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.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -26,6 +27,7 @@ import org.bukkit.entity.Player;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
public class BukkitChunkManager extends ChunkManager {
@ -152,19 +154,20 @@ public class BukkitChunkManager extends ChunkManager {
if (doWhole) {
for (Entity entity : entities) {
org.bukkit.Location location = entity.getLocation();
Chunk chunk = location.getChunk();
if (chunks.contains(chunk)) {
int X = chunk.getX();
int Z = chunk.getZ();
if (X > bx && X < tx && Z > bz && Z < tz) {
count(count, entity);
} else {
Plot other = area.getPlot(BukkitUtil.getLocation(location));
if (plot.equals(other)) {
PaperLib.getChunkAtAsync(location).thenAccept( chunk -> {
if (chunks.contains(chunk)) {
int X = chunk.getX();
int Z = chunk.getZ();
if (X > bx && X < tx && Z > bz && Z < tz) {
count(count, entity);
} else {
Plot other = area.getPlot(BukkitUtil.getLocation(location));
if (plot.equals(other)) {
count(count, entity);
}
}
}
}
});
}
} else {
for (Chunk chunk : chunks) {
@ -196,6 +199,8 @@ public class BukkitChunkManager extends ChunkManager {
final World oldWorld = Bukkit.getWorld(pos1.getWorld());
final BukkitWorld oldBukkitWorld = new BukkitWorld(oldWorld);
final World newWorld = Bukkit.getWorld(newPos.getWorld());
assert newWorld != null;
assert oldWorld != null;
final String newWorldName = newWorld.getName();
final ContentMap map = new ContentMap();
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]);
int cxx = loc.x << 4;
int czz = loc.z << 4;
Chunk chunk = oldWorld.getChunkAt(loc.x, loc.z);
map.saveEntitiesIn(chunk, region);
for (int x = bx & 15; x <= (tx & 15); x++) {
for (int z = bz & 15; z <= (tz & 15); z++) {
map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ);
PaperLib.getChunkAtAsync(oldWorld, loc.x, loc.z)
.thenAccept(chunk1 -> map.saveEntitiesIn(chunk1, region)).thenRun(() -> {
for (int x = bx & 15; x <= (tx & 15); x++) {
for (int z = bz & 15; z <= (tz & 15); z++) {
map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ);
}
}
}
});
}
}, () -> {
for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) {
@ -387,13 +393,12 @@ public class BukkitChunkManager extends ChunkManager {
return true;
}
@Override public boolean loadChunk(String world, ChunkLoc chunkLoc, boolean force) {
return BukkitUtil.getWorld(world).getChunkAt(chunkLoc.x, chunkLoc.z).load(force);
@Override public CompletableFuture loadChunk(String world, ChunkLoc chunkLoc, boolean force) {
return PaperLib.getChunkAtAsync(BukkitUtil.getWorld(world),chunkLoc.x, chunkLoc.z, force);
}
@Override
public void unloadChunk(final String world, final ChunkLoc chunkLoc, final boolean save,
final boolean safe) {
public void unloadChunk(final String world, final ChunkLoc chunkLoc, final boolean save) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask(
() -> 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.SetupObject;
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -61,7 +62,7 @@ public class BukkitSetupUtils extends SetupUtils {
}
World dw = Bukkit.getWorlds().get(0);
for (Player player : world.getPlayers()) {
player.teleport(dw.getSpawnLocation());
PaperLib.teleportAsync(player,dw.getSpawnLocation());
}
if (save) {
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.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -133,7 +134,7 @@ public class SendChunk {
ArrayList<Chunk> chunks = new ArrayList<>();
for (ChunkLoc loc : chunkLocations) {
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);

View File

@ -10,9 +10,9 @@ import com.github.intellectualsites.plotsquared.plot.util.block.BasicLocalBlockQ
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BaseBlock;
import io.papermc.lib.PaperLib;
import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
@ -75,44 +75,45 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
setBaseBlocks(lc);
}
public void setBaseBlocks(LocalChunk lc) throws ExecutionException, InterruptedException {
public void setBaseBlocks(LocalChunk localChunk) {
World worldObj = Bukkit.getWorld(getWorld());
if (worldObj == null) {
throw new NullPointerException("World cannot be null.");
}
//PaperLib.getChunkAtAsync(worldObj, lc.getX(), lc.getZ(), true).get();
Chunk chunk = worldObj.getChunkAt(lc.getX(), lc.getZ());
for (int layer = 0; layer < lc.baseblocks.length; layer++) {
BaseBlock[] blocksLayer = lc.baseblocks[layer];
if (blocksLayer != null) {
for (int j = 0; j < blocksLayer.length; j++) {
if (blocksLayer[j] != null) {
BaseBlock block = blocksLayer[j];
int x = MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = MainUtil.z_loc[layer][j];
PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
.thenAccept(chunk -> {
for (int layer = 0; layer < localChunk.baseblocks.length; layer++) {
BaseBlock[] blocksLayer = localChunk.baseblocks[layer];
if (blocksLayer != null) {
for (int j = 0; j < blocksLayer.length; j++) {
if (blocksLayer[j] != null) {
BaseBlock block = blocksLayer[j];
int x = MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = MainUtil.z_loc[layer][j];
BlockData blockData = BukkitAdapter.adapt(block);
BlockData blockData = BukkitAdapter.adapt(block);
Block existing = chunk.getBlock(x, y, z);
if (equals(PlotBlock.get(block), existing) && existing.getBlockData()
.matches(blockData)) {
continue;
}
Block existing = chunk.getBlock(x, y, z);
if (equals(PlotBlock.get(block), existing) && existing
.getBlockData().matches(blockData)) {
continue;
}
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
existing.setBlockData(blockData, false);
if (block.hasNbtData()) {
CompoundTag tag = block.getNbtData();
StateWrapper sw = new StateWrapper(tag);
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
existing.setBlockData(blockData, false);
if (block.hasNbtData()) {
CompoundTag tag = block.getNbtData();
StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(worldObj.getName(), existing.getX(), existing.getY(),
existing.getZ());
sw.restoreTag(worldObj.getName(), existing.getX(),
existing.getY(), existing.getZ());
}
}
}
}
}
}
}
});
}
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 =
"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,
requiredType = RequiredType.CONSOLE, permission = "plots.debugclaimtest")
+ "Execution time may vary", category = CommandCategory.DEBUG, requiredType = RequiredType.CONSOLE, permission = "plots.debugclaimtest")
public class DebugClaimTest extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
@ -57,56 +56,53 @@ public class DebugClaimTest extends SubCommand {
}
Location location = manager.getSignLoc(plot);
ChunkLoc chunk = new ChunkLoc(location.getX() >> 4, location.getZ() >> 4);
boolean result = ChunkManager.manager.loadChunk(area.worldname, chunk, false);
if (!result) {
continue;
}
String[] lines = WorldUtil.IMP.getSign(location);
if (lines != null) {
String line = lines[2];
if (line != null && line.length() > 2) {
line = line.substring(2);
BiMap<StringWrapper, UUID> map = UUIDHandler.getUuidMap();
UUID uuid = map.get(new StringWrapper(line));
if (uuid == null) {
for (Map.Entry<StringWrapper, UUID> stringWrapperUUIDEntry : map
.entrySet()) {
if (stringWrapperUUIDEntry.getKey().value.toLowerCase()
.startsWith(line.toLowerCase())) {
uuid = stringWrapperUUIDEntry.getValue();
break;
ChunkManager.manager.loadChunk(area.worldname, chunk, false).thenRun(() -> {
String[] lines = WorldUtil.IMP.getSign(location);
if (lines != null) {
String line = lines[2];
if (line != null && line.length() > 2) {
line = line.substring(2);
BiMap<StringWrapper, UUID> map = UUIDHandler.getUuidMap();
UUID uuid = map.get(new StringWrapper(line));
if (uuid == null) {
for (Map.Entry<StringWrapper, UUID> stringWrapperUUIDEntry : map
.entrySet()) {
if (stringWrapperUUIDEntry.getKey().value.toLowerCase()
.startsWith(line.toLowerCase())) {
uuid = stringWrapperUUIDEntry.getValue();
break;
}
}
}
}
if (uuid == null) {
uuid = UUIDHandler.getUUID(line, null);
}
if (uuid != null) {
MainUtil
.sendMessage(player, " - &aFound plot: " + plot.getId() + " : " + line);
plot.setOwner(uuid);
plots.add(plot);
} else {
MainUtil.sendMessage(player,
" - &cInvalid PlayerName: " + plot.getId() + " : " + line);
if (uuid == null) {
uuid = UUIDHandler.getUUID(line, null);
}
if (uuid != null) {
MainUtil.sendMessage(player,
" - &aFound plot: " + plot.getId() + " : " + line);
plot.setOwner(uuid);
plots.add(plot);
} else {
MainUtil.sendMessage(player,
" - &cInvalid PlayerName: " + plot.getId() + " : " + line);
}
}
}
}
}
if (!plots.isEmpty()) {
MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: &7Updating '" + plots.size() + "' plots!");
DBFunc.createPlotsAndData(plots, new Runnable() {
@Override public void run() {
MainUtil.sendMessage(player, "&6Database update finished!");
}).thenRun(() -> {
if (!plots.isEmpty()) {
MainUtil.sendMessage(player,
"&3Sign Block&8->&3Plot&8: &7Updating '" + plots.size() + "' plots!");
DBFunc.createPlotsAndData(plots,
() -> MainUtil.sendMessage(player, "&6Database update finished!"));
for (Plot plot1 : plots) {
plot.create();
}
MainUtil.sendMessage(player, "&3Sign Block&8->&3Plot&8: &7Complete!");
} else {
MainUtil.sendMessage(player, "No plots were found for the given search.");
}
});
for (Plot plot : plots) {
plot.create();
}
MainUtil.sendMessage(player, "&3Sign Block&8->&3Plot&8: &7Complete!");
} else {
MainUtil.sendMessage(player, "No plots were found for the given search.");
return true;
}
return true;
}

View File

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

View File

@ -10,6 +10,22 @@ public class ChunkLoc {
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() {
return (x << 16) | (z & 0xFFFF);
}

View File

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

View File

@ -16,6 +16,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
public abstract class ChunkManager {
@ -109,9 +110,7 @@ public abstract class ChunkManager {
TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() {
@Override public void run(ChunkLoc value) {
if (manager.loadChunk(world, value, false)) {
task.run(value);
}
manager.loadChunk(world, value, false).thenRun(()-> task.run(value));
}
}, whenDone);
});
@ -212,9 +211,9 @@ public abstract class ChunkManager {
*/
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) {
File folder =

View File

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