diff --git a/README.md b/README.md index 504584f..ed276a3 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,12 @@ All features can be accessed with the command `/chunkmaster` or the aliases `/ch - `/chunkmaster generate [world] [radius] []` Starts the generation until the specified chunk count or the world border is reached. - `/chunkmaster list` Lists all running generation tasks -- `/chunkmaster cancel ` Cancels the generation task with the specified id (if it is running). +- `/chunkmaster cancel ` Cancels the generation task with the specified id (if it is running). - `/chunkmaster pause` Pauses all generation tasks until the resume command is executed. - `/chunkmaster resume` Resumes all paused generation tasks. - `/chunkmaster reload` Reloads the configuration file. - `/chunkmaster tpchunk ` Teleports you to the specified chunk coordinates. -- `/ setCenter [] ` - sets the center chunk of the world +- `/ setCenter [[] ]]` - sets the center chunk of the world - `/ getCenter []` - returns the center chunk of the world #### Examples @@ -114,13 +114,12 @@ generation: # The value should be a positive integer greater than 50. mspt-pause-threshold: 500 - # If the chunk generation process should pause on player join. + # Pauses the generation if the number of players on the server is larger or equal + # to the configured value # Notice that playing on a server that constantly generates chunks can be # very laggy and can cause it to crash. - # You could configure the values above so that the performance impact of the generation - # process is minimal. - # The value should be a boolean - pause-on-join: true + # The value should be a posivitve integer > 1. + pause-on-player-count: 1 ``` ### Spigot and Paper diff --git a/build.gradle b/build.gradle index 2887247..0cb7bbe 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ idea { } group "net.trivernis" -version "0.16-beta" +version "1.0" sourceCompatibility = 1.8 diff --git a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt index 285b8d9..9c709a4 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt @@ -75,7 +75,7 @@ class Chunkmaster: JavaPlugin() { config.addDefault("generation.chunks-per-step", 2) config.addDefault("generation.chunk-skips-per-step", 100) config.addDefault("generation.mspt-pause-threshold", 500L) - config.addDefault("generation.pause-on-join", true) + config.addDefault("generation.pause-on-player-count", 1) config.addDefault("generation.max-pending-chunks", 10) config.addDefault("generation.max-loaded-chunks", 10) config.addDefault("generation.ignore-worldborder", false) diff --git a/src/main/kotlin/net/trivernis/chunkmaster/ChunkmasterEvents.kt b/src/main/kotlin/net/trivernis/chunkmaster/ChunkmasterEvents.kt index 7c57428..650f65c 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/ChunkmasterEvents.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/ChunkmasterEvents.kt @@ -1,16 +1,17 @@ package net.trivernis.chunkmaster -import net.trivernis.chunkmaster.lib.generation.GenerationTaskPaper import org.bukkit.Server import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerQuitEvent -import org.bukkit.event.world.WorldSaveEvent class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server: Server) : Listener { - private val pauseOnJoin = chunkmaster.config.getBoolean("generation.pause-on-join") + private val pauseOnPlayerCount: Int + get () { + return chunkmaster.config.getInt("generation.pause-on-player-count") + } private var playerPaused = false /** @@ -18,21 +19,15 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server */ @EventHandler fun onPlayerQuit(event: PlayerQuitEvent) { - if (pauseOnJoin) { - if (server.onlinePlayers.size == 1 && server.onlinePlayers.contains(event.player) || - server.onlinePlayers.isEmpty() - ) { - if (!playerPaused) { - if (chunkmaster.generationManager.pausedTasks.isNotEmpty()) { - chunkmaster.logger.info("Server is empty. Resuming chunk generation tasks.") - } - chunkmaster.generationManager.resumeAll() - } else if (chunkmaster.generationManager.paused){ - chunkmaster.logger.info("Generation was manually paused. Not resuming automatically.") - playerPaused = chunkmaster.generationManager.paused - } else { - chunkmaster.logger.info("Generation tasks are already running.") + if (server.onlinePlayers.size == pauseOnPlayerCount) { + if (!playerPaused) { + if (chunkmaster.generationManager.pausedTasks.isNotEmpty()) { + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_PLAYER_LEAVE")) } + chunkmaster.generationManager.resumeAll() + } else if (chunkmaster.generationManager.paused){ + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("PAUSE_MANUALLY")) + playerPaused = chunkmaster.generationManager.paused } } } @@ -42,14 +37,12 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server */ @EventHandler fun onPlayerJoin(event: PlayerJoinEvent) { - if (pauseOnJoin) { - if (server.onlinePlayers.size == 1 || server.onlinePlayers.isEmpty()) { - if (chunkmaster.generationManager.tasks.isNotEmpty()) { - chunkmaster.logger.info("Pausing generation tasks because of player join.") - } - playerPaused = chunkmaster.generationManager.paused - chunkmaster.generationManager.pauseAll() + if (server.onlinePlayers.size >= pauseOnPlayerCount) { + if (chunkmaster.generationManager.tasks.isNotEmpty()) { + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("PAUSE_PLAYER_JOIN")) } + playerPaused = chunkmaster.generationManager.paused + chunkmaster.generationManager.pauseAll() } } } \ No newline at end of file diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt index 0c662c5..0bc262f 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt @@ -30,14 +30,21 @@ class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand { * Cancels the generation task if it exists. */ override fun execute(sender: CommandSender, args: List): Boolean { - return if (args.isNotEmpty() && args[0].toIntOrNull() != null) { - if (chunkmaster.generationManager.removeTask(args[0].toInt())) { - sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_CANCELED", args[0])) + return if (args.isNotEmpty()) { + val index = if (args[0].toIntOrNull() != null) { + args[0].toInt() + } else { + chunkmaster.generationManager.tasks.find { it.generationTask.world.name == args[0] }?.id + } + + if (index != null && chunkmaster.generationManager.removeTask(index)) { + sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_CANCELED", index)) true } else { sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_NOT_FOUND", args[0])) false } + } else { sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_ID_REQUIRED")); false diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdSetCenter.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdSetCenter.kt index eb09826..8714303 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdSetCenter.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdSetCenter.kt @@ -29,26 +29,30 @@ class CmdSetCenter(private val chunkmaster: Chunkmaster): Subcommand { val centerX: Int val centerZ: Int - if (args.size < 2) { - sender.sendMessage(chunkmaster.langManager.getLocalized("TOO_FEW_ARGUMENTS")) - return false - } if (sender is Player) { - if (args.size == 2) { - world = sender.world.name - if (args[0].toIntOrNull() == null || args[1].toIntOrNull() == null) { - sender.sendMessage(chunkmaster.langManager.getLocalized("COORD_INVALID", args[0], args[1])) - return false + when { + args.isEmpty() -> { + world = sender.world.name + centerX = sender.location.chunk.x + centerZ = sender.location.chunk.z } - centerX = args[0].toInt() - centerZ = args[1].toInt() - } else { - if (!validateThreeArgs(sender, args)) { - return false + args.size == 2 -> { + world = sender.world.name + if (args[0].toIntOrNull() == null || args[1].toIntOrNull() == null) { + sender.sendMessage(chunkmaster.langManager.getLocalized("COORD_INVALID", args[0], args[1])) + return false + } + centerX = args[0].toInt() + centerZ = args[1].toInt() + } + else -> { + if (!validateThreeArgs(sender, args)) { + return false + } + world = args[0] + centerX = args[1].toInt() + centerZ = args[2].toInt() } - world = args[0] - centerX = args[1].toInt() - centerZ = args[2].toInt() } } else { if (args.size < 3) { diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt index 509d910..989fe04 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt @@ -19,7 +19,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server this.loadWorldCenters() } this.startAll() - if (!server.onlinePlayers.isEmpty()) { + if (server.onlinePlayers.size >= chunkmaster.config.getInt("generation.pause-on-player-count")) { this.pauseAll() } } @@ -239,7 +239,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server /** * Overload that doesn't need an argument */ - fun loadWorldCenters() { + private fun loadWorldCenters() { loadWorldCenters(null) } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt index 539a8da..28df798 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt @@ -5,12 +5,13 @@ import net.trivernis.chunkmaster.lib.dynmap.* import net.trivernis.chunkmaster.lib.shapes.Shape import org.bukkit.Chunk import org.bukkit.World +import java.lang.Exception /** * Interface for generation tasks. */ abstract class GenerationTask( - plugin: Chunkmaster, + private val plugin: Chunkmaster, startChunk: ChunkCoordinates, val shape: Shape ) : @@ -69,7 +70,11 @@ abstract class GenerationTask( protected fun unloadLoadedChunks() { for (chunk in loadedChunks) { if (chunk.isLoaded) { - chunk.unload(true) + try { + chunk.unload(true) + } catch (e: Exception) { + plugin.logger.severe(e.toString()) + } } if (dynmapIntegration) { dynmap?.triggerRenderOfVolume(chunk.getBlock(0, 0, 0).location, chunk.getBlock(15, 255, 15).location) diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTaskPaper.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTaskPaper.kt index 5e8d92f..e68f869 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTaskPaper.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTaskPaper.kt @@ -4,6 +4,7 @@ import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.lib.shapes.Shape import org.bukkit.Chunk import org.bukkit.World +import java.lang.Exception import java.util.concurrent.CompletableFuture class GenerationTaskPaper( @@ -92,7 +93,11 @@ class GenerationTaskPaper( } for (chunk in loadedChunks) { if (chunk.isLoaded) { - chunk.unload(true) + try { + chunk.unload(true); + } catch (e: Exception){ + plugin.logger.severe(e.toString()) + } } } } diff --git a/src/main/resources/i18n/DEFAULT.i18n.properties b/src/main/resources/i18n/DEFAULT.i18n.properties index 3b9bb3c..6e9ec32 100644 --- a/src/main/resources/i18n/DEFAULT.i18n.properties +++ b/src/main/resources/i18n/DEFAULT.i18n.properties @@ -56,4 +56,8 @@ COORD_INVALID = §cThe provided coordinate ('%s', '%s') is invalid! CENTER_UPDATED = §9The center for world §2%s §9has been set to §2(%s, %s)§9. CENTER_INFO = §9The center for world §2%s §9is §2(%s, %s)§9. -PLUGIN_DETECTED = Detected %s version %s \ No newline at end of file +PLUGIN_DETECTED = Detected %s version %s + +RESUME_PLAYER_LEAVE = The player count is smaller than the configured pause value. Resuming generation... +PAUSE_PLAYER_JOIN = The player count has reached the pause value. Pausing generation... +PAUSE_MANUALLY = Generation was manually paused. Not resuming automatically. \ No newline at end of file diff --git a/src/main/resources/i18n/de.i18n.properties b/src/main/resources/i18n/de.i18n.properties index e30787d..33f7a10 100644 --- a/src/main/resources/i18n/de.i18n.properties +++ b/src/main/resources/i18n/de.i18n.properties @@ -51,9 +51,13 @@ TABLE_CREATE_ERROR = §cFehler beim erstellen der Tabelle %s. UPDATE_TABLE_DEFINITION = Tabelle %s wurde mit sql %s geupdated. UPDATE_TABLE_FAILED = Fehler beim Updaten der Tabelle %s mit sql %s. -TOO_FEW_ARGUMENTS = §cDu hast nicht genug arguments angegeben. +TOO_FEW_ARGUMENTS = §cDu hast nicht genug Parameter angegeben. COORD_INVALID = §cDie Koordinate ('%s', '%s') ist ungültig! CENTER_UPDATED = §9Die Mitte der Welt §2%s §9wurde auf §2(%s, %s)§9 gesetzt. CENTER_INFO = §9Die Mitte der Welt §2%s §9ist §2(%s, %s)§9. -PLUGIN_DETECTED = Plugin %s in der Version %s gefunden! \ No newline at end of file +PLUGIN_DETECTED = Plugin %s in der Version %s gefunden! + +RESUME_PLAYER_LEAVE = Die Anzahl der Spieler hat den festgelegen Wert zum Pausieren unterschritten. Setze Generieren fort... +PAUSE_PLAYER_JOIN = Die Anzahl der Spieler hat den festgelegten Wert zum Pausieren erreicht. Pausiere... +PAUSE_MANUALLY = Das Generieren wurde manuell pausiert und wird deswegen nicht automatisch fortgesetzt. \ No newline at end of file diff --git a/src/main/resources/i18n/en.i18n.properties b/src/main/resources/i18n/en.i18n.properties index 3b9bb3c..6e9ec32 100644 --- a/src/main/resources/i18n/en.i18n.properties +++ b/src/main/resources/i18n/en.i18n.properties @@ -56,4 +56,8 @@ COORD_INVALID = §cThe provided coordinate ('%s', '%s') is invalid! CENTER_UPDATED = §9The center for world §2%s §9has been set to §2(%s, %s)§9. CENTER_INFO = §9The center for world §2%s §9is §2(%s, %s)§9. -PLUGIN_DETECTED = Detected %s version %s \ No newline at end of file +PLUGIN_DETECTED = Detected %s version %s + +RESUME_PLAYER_LEAVE = The player count is smaller than the configured pause value. Resuming generation... +PAUSE_PLAYER_JOIN = The player count has reached the pause value. Pausing generation... +PAUSE_MANUALLY = Generation was manually paused. Not resuming automatically. \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 15dbfb0..6f73c45 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: net.trivernis.chunkmaster.Chunkmaster name: Chunkmaster -version: '0.16-beta' +version: '1.0' description: Chunk commands plugin. author: Trivernis website: trivernis.net @@ -14,13 +14,13 @@ commands: permission: chunkmaster.chunkmaster usage: | / generate [] [] - generates chunks starting from the spawn until the chunk-count is reached - / cancel - cancels the generation task with the task-id + / cancel - cancels the generation task with the task-id / list - lists all running and paused generation tasks / pause - pauses all generation tasks / resume - resumes all generation tasks / reload - reloads the configuration and restarts all tasks / tpchunk - teleports you to the chunk with the given chunk coordinates - / setCenter [] - sets the center chunk of the world + / setCenter [[] ]] - sets the center chunk of the world / getCenter [] - returns the center chunk of the world aliases: - chm