Fixes and speed improvement

- added config parameter to define the number of chunks that should be generated per step
- probably fixed #3 by processing or canceling pending chunks before the world is saved
release/0.12-beta
Trivernis 5 years ago
parent c6bc75c7fe
commit 8134ccde9c

@ -39,13 +39,18 @@ generation:
# The value should be a positive integer. # The value should be a positive integer.
period: 2 period: 2
# The max amount of chunks that should be generated per step.
# Higher values mean higher generation speed but higher performance impact.
# The value should be a positive integer.
chunks-per-step: 4
# Paper Only # Paper Only
# The number of already generated chunks that will be skipped for each step. # The number of already generated chunks that will be skipped for each step.
# Notice that these still have a performance impact because the server needs to check # Notice that these still have a performance impact because the server needs to check
# if the chunk is generated. # if the chunk is generated.
# Higher values mean faster generation but greater performance impact. # Higher values mean faster generation but greater performance impact.
# The value should be a positive integer. # The value should be a positive integer.
chunks-skips-per-step: 5 chunk-skips-per-step: 100
# The maximum milliseconds per tick the server is allowed to have # The maximum milliseconds per tick the server is allowed to have
# during the cunk generation process. # during the cunk generation process.

@ -22,7 +22,7 @@ idea {
} }
group "net.trivernis" group "net.trivernis"
version "0.11-beta" version "0.12-beta"
sourceCompatibility = 1.8 sourceCompatibility = 1.8

@ -32,8 +32,8 @@ class Chunkmaster: JavaPlugin() {
generationManager = GenerationManager(this, server) generationManager = GenerationManager(this, server)
generationManager.init() generationManager.init()
getCommand("chunkmaster")?.setExecutor(CommandChunkmaster(this, server))
getCommand("chunkmaster")?.aliases = mutableListOf("chm", "chunkm", "cmaster") getCommand("chunkmaster")?.aliases = mutableListOf("chm", "chunkm", "cmaster")
getCommand("chunkmaster")?.setExecutor(CommandChunkmaster(this, server))
server.pluginManager.registerEvents(ChunkmasterEvents(this, server), this) server.pluginManager.registerEvents(ChunkmasterEvents(this, server), this)
@ -60,7 +60,8 @@ class Chunkmaster: JavaPlugin() {
private fun configure() { private fun configure() {
dataFolder.mkdir() dataFolder.mkdir()
config.addDefault("generation.period", 2L) config.addDefault("generation.period", 2L)
config.addDefault("generation.chunks-skips-per-step", 10) config.addDefault("generation.chunks-per-step", 4)
config.addDefault("generation.chunk-skips-per-step", 100)
config.addDefault("generation.mspt-pause-threshold", 500L) config.addDefault("generation.mspt-pause-threshold", 500L)
config.addDefault("generation.pause-on-join", true) config.addDefault("generation.pause-on-join", true)
config.addDefault("generation.max-pending-chunks", 10) config.addDefault("generation.max-pending-chunks", 10)

@ -1,10 +1,12 @@
package net.trivernis.chunkmaster package net.trivernis.chunkmaster
import net.trivernis.chunkmaster.lib.generation.GenerationTaskPaper
import org.bukkit.Server import org.bukkit.Server
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.event.world.WorldSaveEvent
class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server: Server) : Listener { class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server: Server) : Listener {
@ -21,8 +23,8 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server
server.onlinePlayers.isEmpty() server.onlinePlayers.isEmpty()
) { ) {
if (!playerPaused) { if (!playerPaused) {
chunkmaster.generationManager.resumeAll()
chunkmaster.logger.info("Server is empty. Resuming chunk generation tasks.") chunkmaster.logger.info("Server is empty. Resuming chunk generation tasks.")
chunkmaster.generationManager.resumeAll()
} else if (chunkmaster.generationManager.paused){ } else if (chunkmaster.generationManager.paused){
chunkmaster.logger.info("Generation was manually paused. Not resuming automatically.") chunkmaster.logger.info("Generation was manually paused. Not resuming automatically.")
playerPaused = chunkmaster.generationManager.paused playerPaused = chunkmaster.generationManager.paused
@ -40,9 +42,22 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server
fun onPlayerJoin(event: PlayerJoinEvent) { fun onPlayerJoin(event: PlayerJoinEvent) {
if (pauseOnJoin) { if (pauseOnJoin) {
if (server.onlinePlayers.size == 1 || server.onlinePlayers.isEmpty()) { if (server.onlinePlayers.size == 1 || server.onlinePlayers.isEmpty()) {
chunkmaster.logger.info("Pausing generation tasks because of player join.")
playerPaused = chunkmaster.generationManager.paused playerPaused = chunkmaster.generationManager.paused
chunkmaster.generationManager.pauseAll() chunkmaster.generationManager.pauseAll()
chunkmaster.logger.info("Pausing generation tasks because of player join.") }
}
}
/**
* Unload all chunks before a save.
*/
@EventHandler
fun onWorldSave(event: WorldSaveEvent) {
val task = chunkmaster.generationManager.tasks.find { it.generationTask.world == event.world }
if (task != null) {
if (task.generationTask is GenerationTaskPaper) {
task.generationTask.unloadAllChunks()
} }
} }
} }

@ -22,6 +22,7 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChun
protected val chunkSkips = plugin.config.getInt("generation.chunks-skips-per-step") protected val chunkSkips = plugin.config.getInt("generation.chunks-skips-per-step")
protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold") protected val msptThreshold = plugin.config.getLong("generation.mspt-pause-threshold")
protected val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks") protected val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks")
protected val chunksPerStep = plugin.config.getInt("generation.chunks-per-step")
protected var endReachedCallback: (() -> Unit)? = null protected var endReachedCallback: (() -> Unit)? = null
private set private set

@ -52,7 +52,12 @@ class GenerationTaskPaper(
} }
if (!PaperLib.isChunkGenerated(world, chunk.x, chunk.z)) { if (!PaperLib.isChunkGenerated(world, chunk.x, chunk.z)) {
pendingChunks.add(PaperLib.getChunkAtAsync(world, chunk.x, chunk.z, true)) for (i in 0 until chunksPerStep) {
if (!PaperLib.isChunkGenerated(world, chunk.x, chunk.z)) {
pendingChunks.add(PaperLib.getChunkAtAsync(world, chunk.x, chunk.z, true))
}
chunk = nextChunkCoordinates
}
} }
lastChunkCoords = chunk lastChunkCoords = chunk
count = spiral.count // set the count to the more accurate spiral count count = spiral.count // set the count to the more accurate spiral count
@ -66,6 +71,13 @@ class GenerationTaskPaper(
* This unloads all chunks that were generated but not unloaded yet. * This unloads all chunks that were generated but not unloaded yet.
*/ */
override fun cancel() { override fun cancel() {
unloadAllChunks()
}
/**
* Cancels all pending chunks and unloads all loaded chunks.
*/
fun unloadAllChunks() {
for (pendingChunk in pendingChunks) { for (pendingChunk in pendingChunks) {
if (pendingChunk.isDone) { if (pendingChunk.isDone) {
loadedChunks.add(pendingChunk.get()) loadedChunks.add(pendingChunk.get())

@ -37,12 +37,15 @@ class GenerationTaskSpigot(
return return
} }
val chunk = nextChunkCoordinates var chunk = nextChunkCoordinates
if (!world.isChunkGenerated(chunk.x, chunk.z)) { if (!world.isChunkGenerated(chunk.x, chunk.z)) {
val chunkInstance = world.getChunkAt(chunk.x, chunk.z) for (i in 0 until chunksPerStep) {
chunkInstance.load(true) val chunkInstance = world.getChunkAt(chunk.x, chunk.z)
loadedChunks.add(chunkInstance) chunkInstance.load(true)
loadedChunks.add(chunkInstance)
chunk = nextChunkCoordinates
}
} }
lastChunkCoords = chunk lastChunkCoords = chunk
count = spiral.count // set the count to the more accurate spiral count count = spiral.count // set the count to the more accurate spiral count

@ -1,6 +1,6 @@
main: net.trivernis.chunkmaster.Chunkmaster main: net.trivernis.chunkmaster.Chunkmaster
name: Chunkmaster name: Chunkmaster
version: '0.11-beta' version: '0.12-beta'
description: Chunk commands plugin. description: Chunk commands plugin.
author: Trivernis author: Trivernis
website: trivernis.net website: trivernis.net

Loading…
Cancel
Save