Merge pull request #1 from Trivernis/release/beta-0.10
Release/beta 0.10release/0.11-beta v0.10-beta
commit
d456f40124
@ -1,75 +0,0 @@
|
|||||||
package net.trivernis.chunkmaster.lib
|
|
||||||
|
|
||||||
import net.trivernis.chunkmaster.Chunkmaster
|
|
||||||
import org.bukkit.Chunk
|
|
||||||
import org.bukkit.World
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable
|
|
||||||
import org.bukkit.scheduler.BukkitTask
|
|
||||||
|
|
||||||
class GenerationTask(private val plugin: Chunkmaster, val world: World,
|
|
||||||
private val centerChunk: Chunk, private val startChunk: Chunk,
|
|
||||||
private val stopAfter: Int = -1): Runnable {
|
|
||||||
private val spiral: Spiral = Spiral(Pair(centerChunk.x, centerChunk.z), Pair(startChunk.x, startChunk.z))
|
|
||||||
private val loadedChunks: HashSet<Chunk> = HashSet()
|
|
||||||
private val chunkSkips = plugin.config.getInt("generation.chunks-skips-per-step")
|
|
||||||
private val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold")
|
|
||||||
|
|
||||||
var count = 0
|
|
||||||
private set
|
|
||||||
var lastChunk: Chunk = startChunk
|
|
||||||
private set
|
|
||||||
var endReached: Boolean = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the generation task. Every Iteration the next chunk will be generated if
|
|
||||||
* it hasn't been generated already.
|
|
||||||
* After 10 chunks have been generated, they will all be unloaded and saved.
|
|
||||||
*/
|
|
||||||
override fun run() {
|
|
||||||
if (plugin.mspt < msptThreshold) { // pause when tps < 2
|
|
||||||
if (loadedChunks.size > 10) {
|
|
||||||
for (chunk in loadedChunks) {
|
|
||||||
if (chunk.isLoaded) {
|
|
||||||
chunk.unload(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!world.worldBorder.isInside(lastChunk.getBlock(8, 0, 8).location) || (stopAfter in 1..count)) {
|
|
||||||
endReached = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var nextChunkCoords = spiral.next()
|
|
||||||
var chunk = world.getChunkAt(nextChunkCoords.first, nextChunkCoords.second)
|
|
||||||
|
|
||||||
for (i in 1 until chunkSkips) {
|
|
||||||
if (world.isChunkGenerated(chunk.x, chunk.z)) {
|
|
||||||
nextChunkCoords = spiral.next() // if the chunk is generated skip 10 chunks per step
|
|
||||||
chunk = world.getChunkAt(nextChunkCoords.first, nextChunkCoords.second)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!world.isChunkGenerated(chunk.x, chunk.z)) {
|
|
||||||
chunk.load(true)
|
|
||||||
loadedChunks.add(chunk)
|
|
||||||
}
|
|
||||||
lastChunk = chunk
|
|
||||||
count = spiral.count // set the count to the more accurate spiral count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels the generation task.
|
|
||||||
* This unloads all chunks that were generated but not unloaded yet.
|
|
||||||
*/
|
|
||||||
fun cancel() {
|
|
||||||
for (chunk in loadedChunks) {
|
|
||||||
if (chunk.isLoaded) {
|
|
||||||
chunk.unload(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,10 @@
|
|||||||
|
package net.trivernis.chunkmaster.lib.generation
|
||||||
|
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.World
|
||||||
|
|
||||||
|
class ChunkCoordinates(val x: Int, val z: Int) {
|
||||||
|
fun getCenterLocation(world: World): Location {
|
||||||
|
return Location(world, ((x*16) + 8).toDouble(), 1.0, ((x*16) + 8).toDouble())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package net.trivernis.chunkmaster.lib.generation
|
||||||
|
|
||||||
|
import net.trivernis.chunkmaster.Chunkmaster
|
||||||
|
import net.trivernis.chunkmaster.lib.Spiral
|
||||||
|
import org.bukkit.Chunk
|
||||||
|
import org.bukkit.World
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for generation tasks.
|
||||||
|
*/
|
||||||
|
abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChunk: Chunk) : Runnable {
|
||||||
|
|
||||||
|
abstract val stopAfter: Int
|
||||||
|
abstract val world: World
|
||||||
|
abstract val count: Int
|
||||||
|
abstract val endReached: Boolean
|
||||||
|
|
||||||
|
protected val spiral: Spiral =
|
||||||
|
Spiral(Pair(centerChunk.x, centerChunk.z), Pair(startChunk.x, startChunk.z))
|
||||||
|
protected val loadedChunks: HashSet<Chunk> = HashSet()
|
||||||
|
protected var lastChunkCoords = ChunkCoordinates(startChunk.x, startChunk.z)
|
||||||
|
protected val chunkSkips = plugin.config.getInt("generation.chunks-skips-per-step")
|
||||||
|
protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold")
|
||||||
|
protected val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks")
|
||||||
|
|
||||||
|
abstract override fun run()
|
||||||
|
abstract fun cancel()
|
||||||
|
|
||||||
|
val nextChunkCoordinates: ChunkCoordinates
|
||||||
|
get() {
|
||||||
|
val nextChunkCoords = spiral.next()
|
||||||
|
return ChunkCoordinates(nextChunkCoords.first, nextChunkCoords.second)
|
||||||
|
}
|
||||||
|
var lastChunk: Chunk = startChunk
|
||||||
|
get() {
|
||||||
|
return world.getChunkAt(lastChunkCoords.x, lastChunkCoords.z)
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
val nextChunk: Chunk
|
||||||
|
get() {
|
||||||
|
val next = nextChunkCoordinates
|
||||||
|
return world.getChunkAt(next.x, next.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the World border or the maximum chunk setting for the task is reached.
|
||||||
|
*/
|
||||||
|
protected fun borderReached(): Boolean {
|
||||||
|
return !world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) || (stopAfter in 1..count)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package net.trivernis.chunkmaster.lib.generation
|
||||||
|
|
||||||
|
import net.trivernis.chunkmaster.Chunkmaster
|
||||||
|
import org.bukkit.Chunk
|
||||||
|
import org.bukkit.World
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
import io.papermc.lib.PaperLib
|
||||||
|
|
||||||
|
class GenerationTaskPaper(
|
||||||
|
private val plugin: Chunkmaster, override val world: World,
|
||||||
|
centerChunk: Chunk, private val startChunk: Chunk,
|
||||||
|
override val stopAfter: Int = -1
|
||||||
|
) : GenerationTask(plugin, centerChunk, startChunk) {
|
||||||
|
|
||||||
|
private val maxPendingChunks = plugin.config.getInt("generation.max-pending-chunks")
|
||||||
|
|
||||||
|
private val pendingChunks = HashSet<CompletableFuture<Chunk>>()
|
||||||
|
|
||||||
|
override var count = 0
|
||||||
|
private set
|
||||||
|
override var endReached: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the generation task. Every Iteration the next chunk will be generated if
|
||||||
|
* it hasn't been generated already.
|
||||||
|
* After 10 chunks have been generated, they will all be unloaded and saved.
|
||||||
|
*/
|
||||||
|
override fun run() {
|
||||||
|
if (plugin.mspt < msptThreshold) { // pause when tps < 2
|
||||||
|
if (loadedChunks.size > maxLoadedChunks) {
|
||||||
|
for (chunk in loadedChunks) {
|
||||||
|
if (chunk.isLoaded) {
|
||||||
|
chunk.unload(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadedChunks.clear()
|
||||||
|
} else if (pendingChunks.size < maxPendingChunks) { // if more than 10 chunks are pending, wait.
|
||||||
|
if (borderReached()) {
|
||||||
|
endReached = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var chunk = nextChunkCoordinates
|
||||||
|
for (i in 1 until chunkSkips) {
|
||||||
|
if (PaperLib.isChunkGenerated(world, chunk.x, chunk.z)) {
|
||||||
|
chunk = nextChunkCoordinates
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PaperLib.isChunkGenerated(world, chunk.x, chunk.z)) {
|
||||||
|
pendingChunks.add(PaperLib.getChunkAtAsync(world, chunk.x, chunk.z, true))
|
||||||
|
}
|
||||||
|
lastChunkCoords = chunk
|
||||||
|
count = spiral.count // set the count to the more accurate spiral count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkChunksLoaded()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the generation task.
|
||||||
|
* This unloads all chunks that were generated but not unloaded yet.
|
||||||
|
*/
|
||||||
|
override fun cancel() {
|
||||||
|
for (pendingChunk in pendingChunks) {
|
||||||
|
if (pendingChunk.isDone) {
|
||||||
|
loadedChunks.add(pendingChunk.get())
|
||||||
|
} else {
|
||||||
|
pendingChunk.cancel(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pendingChunks.clear()
|
||||||
|
for (chunk in loadedChunks) {
|
||||||
|
if (chunk.isLoaded) {
|
||||||
|
chunk.unload(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if some chunks have been loaded and adds them to the loaded chunk set.
|
||||||
|
*/
|
||||||
|
private fun checkChunksLoaded() {
|
||||||
|
val completedEntrys = HashSet<CompletableFuture<Chunk>>()
|
||||||
|
for (pendingChunk in pendingChunks) {
|
||||||
|
if (pendingChunk.isDone) {
|
||||||
|
completedEntrys.add(pendingChunk)
|
||||||
|
loadedChunks.add(pendingChunk.get())
|
||||||
|
} else if (pendingChunk.isCompletedExceptionally || pendingChunk.isCancelled) {
|
||||||
|
completedEntrys.add(pendingChunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pendingChunks.removeAll(completedEntrys)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package net.trivernis.chunkmaster.lib.generation
|
||||||
|
|
||||||
|
import net.trivernis.chunkmaster.Chunkmaster
|
||||||
|
import org.bukkit.Chunk
|
||||||
|
import org.bukkit.World
|
||||||
|
|
||||||
|
class GenerationTaskSpigot(
|
||||||
|
private val plugin: Chunkmaster, override val world: World,
|
||||||
|
centerChunk: Chunk, private val startChunk: Chunk,
|
||||||
|
override val stopAfter: Int = -1
|
||||||
|
) : GenerationTask(plugin, centerChunk, startChunk) {
|
||||||
|
|
||||||
|
|
||||||
|
override var count = 0
|
||||||
|
private set
|
||||||
|
override var endReached: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the generation task. Every Iteration the next chunk will be generated if
|
||||||
|
* it hasn't been generated already.
|
||||||
|
* After 10 chunks have been generated, they will all be unloaded and saved.
|
||||||
|
*/
|
||||||
|
override fun run() {
|
||||||
|
if (plugin.mspt < msptThreshold) { // pause when tps < 2
|
||||||
|
if (loadedChunks.size > maxLoadedChunks) {
|
||||||
|
for (chunk in loadedChunks) {
|
||||||
|
if (chunk.isLoaded) {
|
||||||
|
chunk.unload(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadedChunks.clear()
|
||||||
|
} else {
|
||||||
|
if (borderReached()) {
|
||||||
|
endReached = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val chunk = nextChunkCoordinates
|
||||||
|
|
||||||
|
if (!world.isChunkGenerated(chunk.x, chunk.z)) {
|
||||||
|
val chunkInstance = world.getChunkAt(chunk.x, chunk.z)
|
||||||
|
chunkInstance.load(true)
|
||||||
|
loadedChunks.add(chunkInstance)
|
||||||
|
}
|
||||||
|
lastChunkCoords = chunk
|
||||||
|
count = spiral.count // set the count to the more accurate spiral count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the generation task.
|
||||||
|
* This unloads all chunks that were generated but not unloaded yet.
|
||||||
|
*/
|
||||||
|
override fun cancel() {
|
||||||
|
for (chunk in loadedChunks) {
|
||||||
|
if (chunk.isLoaded) {
|
||||||
|
chunk.unload(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package net.trivernis.chunkmaster.lib
|
package net.trivernis.chunkmaster.lib.generation
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitTask
|
import org.bukkit.scheduler.BukkitTask
|
||||||
|
|
||||||
data class TaskEntry(val id: Int, val task: BukkitTask, val generationTask: GenerationTask) {
|
data class TaskEntry(val id: Int, val task: BukkitTask, val generationTask: GenerationTask)
|
||||||
}
|
|
Loading…
Reference in New Issue