Uses PaperLib to get chunks async.

Appears to work fine on regular Spigot too.
This commit is contained in:
tastybento 2019-11-10 15:48:20 -08:00
parent e383f79e3e
commit 18030acb36
2 changed files with 44 additions and 51 deletions

32
pom.xml
View File

@ -147,6 +147,10 @@
<id>codemc-public</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
@ -182,6 +186,12 @@
<version>${bentobox.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@ -278,6 +288,28 @@
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>world.bentobox.level.paperlib</shadedPattern> <!-- Replace this -->
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>

View File

@ -16,13 +16,13 @@ import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Slab;
import org.bukkit.scheduler.BukkitTask;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multiset.Entry;
import com.google.common.collect.Multisets;
import io.papermc.lib.PaperLib;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Pair;
import world.bentobox.bentobox.util.Util;
@ -31,11 +31,7 @@ import world.bentobox.level.Level;
public class CalcIslandLevel {
private final int maxChunks;
private final long speed;
private static final String LINE_BREAK = "==================================";
private boolean checking;
private final BukkitTask task;
private final Level addon;
@ -49,6 +45,8 @@ public class CalcIslandLevel {
private final World world;
private final List<World> worlds;
private int count;
/**
* Calculate the island's level
@ -80,54 +78,19 @@ public class CalcIslandLevel {
// Set the initial island handicap
result.initialLevel = addon.getInitialIslandLevel(island);
speed = addon.getSettings().getUpdateTickDelay();
maxChunks = addon.getSettings().getChunksPerTick();
// Get chunks to scan
chunksToScan = getChunksToScan(island);
// Start checking
checking = true;
// Start a recurring task until done or cancelled
task = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
Set<ChunkSnapshot> chunkSnapshot = new HashSet<>();
if (checking) {
Iterator<Pair<Integer, Integer>> it = chunksToScan.iterator();
if (!it.hasNext()) {
// Nothing left
tidyUp();
return;
count = 0;
chunksToScan.forEach(c -> {
PaperLib.getChunkAtAsync(world, c.x, c.z).thenAccept(ch -> {
if (ch != null) {
this.scanChunk(ch.getChunkSnapshot());
}
// Add chunk snapshots to the list
while (it.hasNext() && chunkSnapshot.size() < maxChunks) {
Pair<Integer, Integer> pair = it.next();
for (World worldToScan : worlds) {
if (!worldToScan.isChunkLoaded(pair.x, pair.z)) {
//worldToScan.loadChunk(pair.x, pair.z);
chunkSnapshot.add(worldToScan.getChunkAt(pair.x, pair.z).getChunkSnapshot());
worldToScan.unloadChunk(pair.x, pair.z, false);
} else {
chunkSnapshot.add(worldToScan.getChunkAt(pair.x, pair.z).getChunkSnapshot());
}
}
it.remove();
count++;
if (count == chunksToScan.size()) {
this.tidyUp();
}
// Move to next step
checking = false;
checkChunksAsync(chunkSnapshot);
}
}, 0L, speed);
}
private void checkChunksAsync(final Set<ChunkSnapshot> chunkSnapshot) {
// Run async task to scan chunks
addon.getServer().getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
for (ChunkSnapshot chunk: chunkSnapshot) {
scanChunk(chunk);
}
// Nothing happened, change state
checking = true;
});
});
}
@ -231,8 +194,6 @@ public class CalcIslandLevel {
}
private void tidyUp() {
// Cancel
task.cancel();
// Finalize calculations
result.rawBlockCount += (long)(result.underWaterBlockCount * addon.getSettings().getUnderWaterMultiplier());