Overhall regenallroads method to make it work, make sure BukkitChunkCoordinator can/will finish

This commit is contained in:
dordsor21 2022-01-26 21:50:57 +00:00 committed by Jordan
parent a12fe280db
commit b9f6f9b2b8
2 changed files with 144 additions and 80 deletions

View File

@ -150,6 +150,13 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
Chunk chunk = this.availableChunks.poll(); Chunk chunk = this.availableChunks.poll();
if (chunk == null) { if (chunk == null) {
if (this.availableChunks.size() == 0) {
if (this.requestedChunks.size() == 0) {
finish();
} else {
requestBatch();
}
}
return; return;
} }
long[] iterationTime = new long[2]; long[] iterationTime = new long[2];

View File

@ -65,6 +65,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.File; import java.io.File;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@ -434,26 +435,29 @@ public class HybridUtils {
HybridUtils.area = area; HybridUtils.area = area;
HybridUtils.height = extend; HybridUtils.height = extend;
HybridUtils.chunks = chunks; HybridUtils.chunks = chunks;
final int initial = 1024 * regions.size() + chunks.size();
final AtomicInteger count = new AtomicInteger(0); final AtomicInteger count = new AtomicInteger(0);
TaskManager.runTask(new Runnable() { TaskManager.runTask(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!UPDATE) { if (!UPDATE) {
Iterator<BlockVector2> iter = chunks.iterator(); Iterator<BlockVector2> iter = chunks.iterator();
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
while (iter.hasNext()) { while (iter.hasNext()) {
BlockVector2 chunk = iter.next(); BlockVector2 chunk = iter.next();
iter.remove(); iter.remove();
boolean regenedRoad = regenerateRoad(area, chunk, extend); boolean regenedRoad = regenerateRoad(area, chunk, extend, queue);
if (!regenedRoad) { if (!regenedRoad) {
LOGGER.info("Failed to regenerate roads"); LOGGER.info(String.format("Failed to regenerate roads in chunk %s", chunk));
} }
} }
queue.enqueue();
LOGGER.info("Cancelled road task"); LOGGER.info("Cancelled road task");
return; return;
} }
count.incrementAndGet(); count.incrementAndGet();
if (count.intValue() % 20 == 0) { if (count.intValue() % 10 == 0) {
LOGGER.info("Progress: {}%", 100 * (2048 - chunks.size()) / 2048); LOGGER.info("Progress: {}%", 100 * (initial - (chunks.size() + 1024 * regions.size())) / initial);
} }
if (HybridUtils.regions.isEmpty() && chunks.isEmpty()) { if (HybridUtils.regions.isEmpty() && chunks.isEmpty()) {
regeneratePlotWalls(area); regeneratePlotWalls(area);
@ -465,7 +469,7 @@ public class HybridUtils {
final Runnable task = this; final Runnable task = this;
TaskManager.runTaskAsync(() -> { TaskManager.runTaskAsync(() -> {
try { try {
if (chunks.size() < 1024) { if (chunks.size() < 64) {
if (!HybridUtils.regions.isEmpty()) { if (!HybridUtils.regions.isEmpty()) {
Iterator<BlockVector2> iterator = HybridUtils.regions.iterator(); Iterator<BlockVector2> iterator = HybridUtils.regions.iterator();
BlockVector2 loc = iterator.next(); BlockVector2 loc = iterator.next();
@ -478,18 +482,35 @@ public class HybridUtils {
} }
if (!chunks.isEmpty()) { if (!chunks.isEmpty()) {
TaskManager.getPlatformImplementation().sync(() -> { TaskManager.getPlatformImplementation().sync(() -> {
long start = System.currentTimeMillis();
Iterator<BlockVector2> iterator = chunks.iterator(); Iterator<BlockVector2> iterator = chunks.iterator();
while (System.currentTimeMillis() - start < 20 && !chunks.isEmpty()) { if (chunks.size() >= 32) {
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
for (int i = 0; i < 32; i++) {
final BlockVector2 chunk = iterator.next();
iterator.remove();
boolean regenedRoads = regenerateRoad(area, chunk, extend, queue);
if (!regenedRoads) {
LOGGER.info(String.format("Failed to regenerate road in chunk %s", chunk));
}
}
queue.setCompleteTask(task);
queue.enqueue();
return null;
}
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
while (!chunks.isEmpty()) {
final BlockVector2 chunk = iterator.next(); final BlockVector2 chunk = iterator.next();
iterator.remove(); iterator.remove();
boolean regenedRoads = regenerateRoad(area, chunk, extend); boolean regenedRoads = regenerateRoad(area, chunk, extend, queue);
if (!regenedRoads) { if (!regenedRoads) {
LOGGER.info("Failed to regenerate road"); LOGGER.info(String.format("Failed to regenerate road in chunk %s", chunk));
} }
} }
queue.setCompleteTask(task);
queue.enqueue();
return null; return null;
}); });
return;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -572,7 +593,35 @@ public class HybridUtils {
return ey; return ey;
} }
/**
* Regenerate the road in a chunk in a plot area.
*
* @param area Plot area to regenerate road for
* @param chunk Chunk location to regenerate
* @param extend How far to extend setting air above the road
* @return if successful
* @deprecated use {@link HybridUtils#regenerateRoad(PlotArea, BlockVector2, int, QueueCoordinator)}
*/
@Deprecated(forRemoval = true, since = "TODO")
public boolean regenerateRoad(final PlotArea area, final BlockVector2 chunk, int extend) { public boolean regenerateRoad(final PlotArea area, final BlockVector2 chunk, int extend) {
return regenerateRoad(area, chunk, extend, null);
}
/**
* Regenerate the road in a chunk in a plot area.
*
* @param area Plot area to regenerate road for
* @param chunk Chunk location to regenerate
* @param extend How far to extend setting air above the road
* @param queueCoordinator {@link QueueCoordinator} to use to set the blocks. Null if one should be created and enqueued
* @return if successful
*/
public boolean regenerateRoad(
final PlotArea area,
final BlockVector2 chunk,
int extend,
@Nullable QueueCoordinator queueCoordinator
) {
int x = chunk.getX() << 4; int x = chunk.getX() << 4;
int z = chunk.getZ() << 4; int z = chunk.getZ() << 4;
int ex = x + 15; int ex = x + 15;
@ -598,92 +647,100 @@ public class HybridUtils {
z -= plotWorld.ROAD_OFFSET_Z; z -= plotWorld.ROAD_OFFSET_Z;
final int finalX = x; final int finalX = x;
final int finalZ = z; final int finalZ = z;
QueueCoordinator queue = this.blockQueue.getNewQueue(worldUtil.getWeWorld(plotWorld.getWorldName())); final boolean enqueue;
final QueueCoordinator queue;
if (queueCoordinator == null) {
queue = this.blockQueue.getNewQueue(worldUtil.getWeWorld(plotWorld.getWorldName()));
enqueue = true;
} else {
queue = queueCoordinator;
enqueue = false;
}
if (id1 == null || id2 == null || id1 != id2) { if (id1 == null || id2 == null || id1 != id2) {
this.chunkManager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> { 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.set(true);
toCheck.set(true);
}
} }
if (id2 != null && !toCheck.get()) { }
Plot p2 = area.getPlotAbs(id2); if (id2 != null && !toCheck.get()) {
if (p2 != null && p2.hasOwner() && p2.isMerged()) { Plot p2 = area.getPlotAbs(id2);
toCheck.set(true); if (p2 != null && p2.hasOwner() && p2.isMerged()) {
} toCheck.set(true);
} }
int size = plotWorld.SIZE; }
for (int X = 0; X < 16; X++) { int size = plotWorld.SIZE;
short absX = (short) ((finalX + X) % size); for (int X = 0; X < 16; X++) {
for (int Z = 0; Z < 16; Z++) { short absX = (short) ((finalX + X) % size);
short absZ = (short) ((finalZ + Z) % size); for (int Z = 0; Z < 16; Z++) {
if (absX < 0) { short absZ = (short) ((finalZ + Z) % size);
absX += size; if (absX < 0) {
} absX += size;
if (absZ < 0) { }
absZ += size; if (absZ < 0) {
} absZ += size;
boolean condition; }
if (toCheck.get()) { boolean condition;
condition = manager.getPlotId( if (toCheck.get()) {
finalX + X + plotWorld.ROAD_OFFSET_X, condition = manager.getPlotId(
1, finalX + X + plotWorld.ROAD_OFFSET_X,
finalZ + Z + plotWorld.ROAD_OFFSET_Z 1,
) == null; finalZ + Z + plotWorld.ROAD_OFFSET_Z
} else { ) == null;
boolean gx = absX > plotWorld.PATH_WIDTH_LOWER; } else {
boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER; boolean gx = absX > plotWorld.PATH_WIDTH_LOWER;
boolean lx = absX < plotWorld.PATH_WIDTH_UPPER; boolean gz = absZ > plotWorld.PATH_WIDTH_LOWER;
boolean lz = absZ < plotWorld.PATH_WIDTH_UPPER; boolean lx = absX < plotWorld.PATH_WIDTH_UPPER;
condition = !gx || !gz || !lx || !lz; boolean lz = absZ < plotWorld.PATH_WIDTH_UPPER;
} condition = !gx || !gz || !lx || !lz;
if (condition) { }
BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); if (condition) {
int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : area.getMinBuildHeight(); BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
int maxDy = Math.max(extend, blocks.length); int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : area.getMinBuildHeight();
for (int dy = 0; dy < maxDy; dy++) { int maxDy = Math.max(extend, blocks.length);
if (dy > blocks.length - 1) { for (int dy = 0; dy < maxDy; dy++) {
if (dy > blocks.length - 1) {
queue.setBlock(
finalX + X + plotWorld.ROAD_OFFSET_X,
minY + dy,
finalZ + Z + plotWorld.ROAD_OFFSET_Z,
WEExtent.AIRBASE
);
} else {
BaseBlock block = blocks[dy];
if (block != null) {
queue.setBlock(
finalX + X + plotWorld.ROAD_OFFSET_X,
minY + dy,
finalZ + Z + plotWorld.ROAD_OFFSET_Z,
block
);
} else {
queue.setBlock( queue.setBlock(
finalX + X + plotWorld.ROAD_OFFSET_X, finalX + X + plotWorld.ROAD_OFFSET_X,
minY + dy, minY + dy,
finalZ + Z + plotWorld.ROAD_OFFSET_Z, finalZ + Z + plotWorld.ROAD_OFFSET_Z,
WEExtent.AIRBASE WEExtent.AIRBASE
); );
} else {
BaseBlock block = blocks[dy];
if (block != null) {
queue.setBlock(
finalX + X + plotWorld.ROAD_OFFSET_X,
minY + dy,
finalZ + Z + plotWorld.ROAD_OFFSET_Z,
block
);
} else {
queue.setBlock(
finalX + X + plotWorld.ROAD_OFFSET_X,
minY + dy,
finalZ + Z + plotWorld.ROAD_OFFSET_Z,
WEExtent.AIRBASE
);
}
} }
} }
BiomeType biome = plotWorld.G_SCH_B.get(MathMan.pair(absX, absZ)); }
if (biome != null) { BiomeType biome = plotWorld.G_SCH_B.get(MathMan.pair(absX, absZ));
queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, finalZ + Z + plotWorld.ROAD_OFFSET_Z, biome); if (biome != null) {
} else { queue.setBiome(finalX + X + plotWorld.ROAD_OFFSET_X, finalZ + Z + plotWorld.ROAD_OFFSET_Z, biome);
queue.setBiome( } else {
finalX + X + plotWorld.ROAD_OFFSET_X, queue.setBiome(
finalZ + Z + plotWorld.ROAD_OFFSET_Z, finalX + X + plotWorld.ROAD_OFFSET_X,
plotWorld.getPlotBiome() finalZ + Z + plotWorld.ROAD_OFFSET_Z,
); plotWorld.getPlotBiome()
} );
} }
} }
} }
}
if (enqueue) {
queue.enqueue(); queue.enqueue();
}); }
return true; return true;
} }
return false; return false;