Merge pull request #2 from Trivernis/release/0.11-beta

Release/0.11 beta
pull/4/head^2 v0.11-beta
Trivernis 5 years ago committed by GitHub
commit 3f8476ecc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,7 +22,7 @@ idea {
} }
group "net.trivernis" group "net.trivernis"
version "0.10-beta" version "0.11-beta"
sourceCompatibility = 1.8 sourceCompatibility = 1.8
@ -31,9 +31,6 @@ repositories {
maven { maven {
url "https://hub.spigotmc.org/nexus/content/repositories/snapshots" url "https://hub.spigotmc.org/nexus/content/repositories/snapshots"
} }
maven {
url 'https://papermc.io/repo/repository/maven-public/'
}
maven { maven {
url 'https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc' url 'https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc'
} }
@ -41,6 +38,10 @@ repositories {
name 'papermc' name 'papermc'
url 'https://papermc.io/repo/repository/maven-public/' url 'https://papermc.io/repo/repository/maven-public/'
} }
maven {
name 'CodeMc'
url 'https://repo.codemc.org/repository/maven-public'
}
} }
dependencies { dependencies {
@ -50,11 +51,15 @@ dependencies {
compileOnly "org.spigotmc:spigot-api:1.14.4-R0.1-SNAPSHOT" compileOnly "org.spigotmc:spigot-api:1.14.4-R0.1-SNAPSHOT"
compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.28.0' compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.28.0'
compile "io.papermc:paperlib:1.0.2" compile "io.papermc:paperlib:1.0.2"
compile "org.bstats:bstats-bukkit:1.5"
} }
apply plugin: "com.github.johnrengelman.shadow" apply plugin: "com.github.johnrengelman.shadow"
apply plugin: 'java'
shadowJar { shadowJar {
relocate 'io.papermc.lib', 'net.trivernis.chunkmaster.paperlib' relocate 'io.papermc.lib', 'net.trivernis.chunkmaster.paperlib'
relocate 'org.bstats', 'net.trivernis.chunkmaster.bstats'
} }
jar { jar {

@ -4,6 +4,7 @@ import io.papermc.lib.PaperLib
import net.trivernis.chunkmaster.commands.* import net.trivernis.chunkmaster.commands.*
import net.trivernis.chunkmaster.lib.generation.GenerationManager import net.trivernis.chunkmaster.lib.generation.GenerationManager
import net.trivernis.chunkmaster.lib.SqlUpdateManager import net.trivernis.chunkmaster.lib.SqlUpdateManager
import org.bstats.bukkit.Metrics
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
import org.bukkit.scheduler.BukkitTask import org.bukkit.scheduler.BukkitTask
import java.lang.Exception import java.lang.Exception
@ -24,6 +25,9 @@ class Chunkmaster: JavaPlugin() {
override fun onEnable() { override fun onEnable() {
PaperLib.suggestPaper(this) PaperLib.suggestPaper(this)
configure() configure()
val metrics = Metrics(this)
initDatabase() initDatabase()
generationManager = GenerationManager(this, server) generationManager = GenerationManager(this, server)
generationManager.init() generationManager.init()

@ -9,6 +9,7 @@ import org.bukkit.event.player.PlayerQuitEvent
class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server: Server) : Listener { class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server: Server) : Listener {
private val pauseOnJoin = chunkmaster.config.getBoolean("generation.pause-on-join") private val pauseOnJoin = chunkmaster.config.getBoolean("generation.pause-on-join")
private var playerPaused = false
/** /**
* Autostart generation tasks * Autostart generation tasks
@ -19,9 +20,14 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server
if (server.onlinePlayers.size == 1 && server.onlinePlayers.contains(event.player) || if (server.onlinePlayers.size == 1 && server.onlinePlayers.contains(event.player) ||
server.onlinePlayers.isEmpty() server.onlinePlayers.isEmpty()
) { ) {
if (!chunkmaster.generationManager.paused) { if (!playerPaused) {
chunkmaster.generationManager.startAll() chunkmaster.generationManager.resumeAll()
chunkmaster.logger.info("Server is empty. Starting chunk generation tasks.") chunkmaster.logger.info("Server is empty. Resuming chunk generation tasks.")
} 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.")
} }
} }
} }
@ -34,8 +40,9 @@ 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.generationManager.stopAll() playerPaused = chunkmaster.generationManager.paused
chunkmaster.logger.info("Stopping generation tasks because of player join.") chunkmaster.generationManager.pauseAll()
chunkmaster.logger.info("Pausing generation tasks because of player join.")
} }
} }
} }

@ -4,11 +4,31 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ComponentBuilder import net.md_5.bungee.api.chat.ComponentBuilder
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Subcommand import net.trivernis.chunkmaster.lib.Subcommand
import net.trivernis.chunkmaster.lib.generation.TaskEntry
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand { class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand {
override val name = "cancel" override val name = "cancel"
/**
* TabComplete for subcommand cancel.
*/
override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: List<String>
): MutableList<String> {
val genManager = chunkmaster.generationManager
val allTasks = genManager.allTasks
return allTasks.filter {it.id.toString().indexOf(args[0]) == 0}
.map { it.id.toString() }.toMutableList()
}
/**
* Cancels the generation task if it exists.
*/
override fun execute(sender: CommandSender, args: List<String>): Boolean { override fun execute(sender: CommandSender, args: List<String>): Boolean {
return if (args.isNotEmpty() && args[0].toIntOrNull() != null) { return if (args.isNotEmpty() && args[0].toIntOrNull() != null) {
if (chunkmaster.generationManager.removeTask(args[0].toInt())) { if (chunkmaster.generationManager.removeTask(args[0].toInt())) {

@ -4,12 +4,32 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ComponentBuilder import net.md_5.bungee.api.chat.ComponentBuilder
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Subcommand import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Player import org.bukkit.entity.Player
class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand { class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
override val name = "generate" override val name = "generate"
/**
* TabComplete for generate command.
*/
override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: List<String>
): MutableList<String> {
if (args.size == 1) {
return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 }
.map {it.name}.toMutableList()
}
return emptyList<String>().toMutableList()
}
/**
* Creates a new generation task for the world and chunk count.
*/
override fun execute(sender: CommandSender, args: List<String>): Boolean { override fun execute(sender: CommandSender, args: List<String>): Boolean {
var worldName = "" var worldName = ""
var stopAfter = -1 var stopAfter = -1
@ -39,17 +59,21 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
} }
} }
val world = chunkmaster.server.getWorld(worldName) val world = chunkmaster.server.getWorld(worldName)
return if (world != null) { val allTasks = chunkmaster.generationManager.allTasks
return if (world != null && (allTasks.find { it.generationTask.world == world }) == null) {
chunkmaster.generationManager.addTask(world, stopAfter) chunkmaster.generationManager.addTask(world, stopAfter)
sender.spigot().sendMessage(*ComponentBuilder("Generation task for world ").color(ChatColor.BLUE) sender.spigot().sendMessage(*ComponentBuilder("Generation task for world ").color(ChatColor.BLUE)
.append(worldName).color(ChatColor.GREEN).append(" until ").color(ChatColor.BLUE) .append(worldName).color(ChatColor.GREEN).append(" until ").color(ChatColor.BLUE)
.append(if (stopAfter > 0) "$stopAfter chunks" else "WorldBorder").color(ChatColor.GREEN) .append(if (stopAfter > 0) "$stopAfter chunks" else "WorldBorder").color(ChatColor.GREEN)
.append(" successfully created").color(ChatColor.BLUE).create()) .append(" successfully created").color(ChatColor.BLUE).create())
true true
} else { } else if (world == null){
sender.spigot().sendMessage(*ComponentBuilder("World ").color(ChatColor.RED) sender.spigot().sendMessage(*ComponentBuilder("World ").color(ChatColor.RED)
.append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create()) .append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create())
false false
} else {
sender.spigot().sendMessage(*ComponentBuilder("Task already exists!").color(ChatColor.RED).create())
return false
} }
} }
} }

@ -4,21 +4,57 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ComponentBuilder import net.md_5.bungee.api.chat.ComponentBuilder
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Subcommand import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class CmdList(private val chunkmaster: Chunkmaster): Subcommand { class CmdList(private val chunkmaster: Chunkmaster): Subcommand {
override val name = "list" override val name = "list"
override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: List<String>
): MutableList<String> {
return emptyList<String>().toMutableList()
}
/**
* Lists all running or paused generation tasks.
*/
override fun execute(sender: CommandSender, args: List<String>): Boolean { override fun execute(sender: CommandSender, args: List<String>): Boolean {
val runningTasks = chunkmaster.generationManager.tasks val runningTasks = chunkmaster.generationManager.tasks
if (runningTasks.isEmpty()) { val pausedTasks = chunkmaster.generationManager.pausedTasks
sender.spigot().sendMessage(*ComponentBuilder("There are no running generation tasks.")
if (runningTasks.isEmpty() && pausedTasks.isEmpty()) {
sender.spigot().sendMessage(*ComponentBuilder("There are no generation tasks.")
.color(ChatColor.BLUE).create()) .color(ChatColor.BLUE).create())
} else if (runningTasks.isEmpty()) {
val response = ComponentBuilder("Currently paused generation tasks:").color(ChatColor.WHITE).bold(true)
for (taskEntry in pausedTasks) {
val genTask = taskEntry.generationTask
response.append("\n - ").color(ChatColor.WHITE).bold(false)
response.append("#${taskEntry.id}").color(ChatColor.BLUE).append(" - ").color(ChatColor.WHITE)
response.append(genTask.world.name).color(ChatColor.GREEN).append(" - Progress: ").color(ChatColor.WHITE)
response.append("${genTask.count} chunks").color(ChatColor.BLUE)
if (genTask.stopAfter > 0) {
response.append(" (${(genTask.count.toDouble()/genTask.stopAfter.toDouble())*100}%).")
}
}
sender.spigot().sendMessage(*response.create())
} else { } else {
val response = ComponentBuilder("Currently running generation tasks:").color(ChatColor.WHITE) val response = ComponentBuilder("Currently running generation tasks:").color(ChatColor.WHITE).bold(true)
for (task in runningTasks) { for (task in runningTasks) {
response.append("\n - #${task.id}: ${task.generationTask.world.name}, Progress ${task.generationTask.count}") val genTask = task.generationTask
.color(ChatColor.BLUE) response.append("\n - ").color(ChatColor.WHITE).bold(false)
.append("#${task.id}").color(ChatColor.BLUE).append(" - ").color(ChatColor.WHITE)
.append(genTask.world.name).color(ChatColor.GREEN).append(" - Progress: ").color(ChatColor.WHITE)
.append("${genTask.count} chunks").color(ChatColor.BLUE)
if (genTask.stopAfter > 0) {
response.append(" (${(genTask.count.toDouble()/genTask.stopAfter.toDouble())*100}%).")
}
} }
sender.spigot().sendMessage(*response.create()) sender.spigot().sendMessage(*response.create())
} }

@ -4,11 +4,21 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ComponentBuilder import net.md_5.bungee.api.chat.ComponentBuilder
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Subcommand import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class CmdPause(private val chunkmaster: Chunkmaster) : Subcommand { class CmdPause(private val chunkmaster: Chunkmaster) : Subcommand {
override val name: String = "pause" override val name: String = "pause"
override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: List<String>
): MutableList<String> {
return emptyList<String>().toMutableList()
}
override fun execute(sender: CommandSender, args: List<String>): Boolean { override fun execute(sender: CommandSender, args: List<String>): Boolean {
return if (!chunkmaster.generationManager.paused) { return if (!chunkmaster.generationManager.paused) {
chunkmaster.generationManager.pauseAll() chunkmaster.generationManager.pauseAll()

@ -4,11 +4,21 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ComponentBuilder import net.md_5.bungee.api.chat.ComponentBuilder
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Subcommand import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class CmdResume(private val chunkmaster: Chunkmaster): Subcommand { class CmdResume(private val chunkmaster: Chunkmaster): Subcommand {
override val name = "resume" override val name = "resume"
override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: List<String>
): MutableList<String> {
return emptyList<String>().toMutableList()
}
override fun execute(sender: CommandSender, args: List<String>): Boolean { override fun execute(sender: CommandSender, args: List<String>): Boolean {
return if (chunkmaster.generationManager.paused) { return if (chunkmaster.generationManager.paused) {
chunkmaster.generationManager.resumeAll() chunkmaster.generationManager.resumeAll()

@ -23,7 +23,16 @@ class CommandChunkmaster(private val chunkmaster: Chunkmaster, private val serve
*/ */
override fun onTabComplete(sender: CommandSender, command: Command, alias: String, args: Array<out String>): override fun onTabComplete(sender: CommandSender, command: Command, alias: String, args: Array<out String>):
MutableList<String> { MutableList<String> {
return commands.keys.filter { it.indexOf(args[0]) == 0 }.toMutableList() if (args.size == 1) {
return commands.keys.filter { it.indexOf(args[0]) == 0 }.toMutableList()
} else if (args.isNotEmpty()){
if (commands.containsKey(args[0])) {
val commandEntry = commands[args[0]]
return commandEntry!!.onTabComplete(sender, command, alias, args.slice(1 until args.size))
}
}
return emptyList<String>().toMutableList()
} }
/** /**

@ -1,8 +1,10 @@
package net.trivernis.chunkmaster.lib package net.trivernis.chunkmaster.lib
import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
interface Subcommand { interface Subcommand {
val name: String val name: String
fun execute(sender: CommandSender, args: List<String>): Boolean fun execute(sender: CommandSender, args: List<String>): Boolean
fun onTabComplete(sender: CommandSender, command: Command, alias: String, args: List<String>): MutableList<String>
} }

@ -10,7 +10,15 @@ import java.lang.NullPointerException
class GenerationManager(private val chunkmaster: Chunkmaster, private val server: Server) { class GenerationManager(private val chunkmaster: Chunkmaster, private val server: Server) {
val tasks: HashSet<TaskEntry> = HashSet() val tasks: HashSet<RunningTaskEntry> = HashSet()
val pausedTasks: HashSet<PausedTaskEntry> = HashSet()
val allTasks: HashSet<TaskEntry>
get() {
val all = HashSet<TaskEntry>()
all.addAll(pausedTasks)
all.addAll(tasks)
return all
}
var paused = false var paused = false
private set private set
@ -18,39 +26,51 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
* Adds a generation task * Adds a generation task
*/ */
fun addTask(world: World, stopAfter: Int = -1): Int { fun addTask(world: World, stopAfter: Int = -1): Int {
val centerChunk = world.getChunkAt(world.spawnLocation) val foundTask = allTasks.find { it.generationTask.world == world }
val generationTask = createGenerationTask(world, centerChunk, centerChunk, stopAfter) if (foundTask == null) {
val centerChunk = world.getChunkAt(world.spawnLocation)
val generationTask = createGenerationTask(world, centerChunk, centerChunk, stopAfter)
val insertStatement = chunkmaster.sqliteConnection.prepareStatement(""" val insertStatement = chunkmaster.sqliteConnection.prepareStatement("""
INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, stop_after) INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, stop_after)
values (?, ?, ?, ?, ?, ?) values (?, ?, ?, ?, ?, ?)
""") """)
insertStatement.setInt(1, centerChunk.x) insertStatement.setInt(1, centerChunk.x)
insertStatement.setInt(2, centerChunk.z) insertStatement.setInt(2, centerChunk.z)
insertStatement.setInt(3, centerChunk.x) insertStatement.setInt(3, centerChunk.x)
insertStatement.setInt(4, centerChunk.z) insertStatement.setInt(4, centerChunk.z)
insertStatement.setString(5, world.name) insertStatement.setString(5, world.name)
insertStatement.setInt(6, stopAfter) insertStatement.setInt(6, stopAfter)
insertStatement.execute() insertStatement.execute()
val getIdStatement = chunkmaster.sqliteConnection.prepareStatement(""" val getIdStatement = chunkmaster.sqliteConnection.prepareStatement("""
SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1 SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1
""".trimIndent()) """.trimIndent())
getIdStatement.execute() getIdStatement.execute()
val result = getIdStatement.resultSet val result = getIdStatement.resultSet
result.next() result.next()
val id: Int = result.getInt("id") val id: Int = result.getInt("id")
insertStatement.close() insertStatement.close()
getIdStatement.close() getIdStatement.close()
if (!paused) { generationTask.onEndReached {
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10, server.consoleSender.sendMessage("Task #${id} finished after ${generationTask.count} chunks.")
chunkmaster.config.getLong("generation.period")) removeTask(id)
tasks.add(TaskEntry(id, task, generationTask)) }
}
if (!paused) {
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10,
chunkmaster.config.getLong("generation.period"))
tasks.add(RunningTaskEntry(id, task, generationTask))
} else {
pausedTasks.add(PausedTaskEntry(id, generationTask))
}
return id return id
} else {
return foundTask.id
}
} }
/** /**
@ -62,7 +82,11 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
val generationTask = createGenerationTask(world, center, last, stopAfter) val generationTask = createGenerationTask(world, center, last, stopAfter)
val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10, val task = server.scheduler.runTaskTimer(chunkmaster, generationTask, 10,
chunkmaster.config.getLong("generation.period")) chunkmaster.config.getLong("generation.period"))
tasks.add(TaskEntry(id, task, generationTask)) tasks.add(RunningTaskEntry(id, task, generationTask))
generationTask.onEndReached {
server.consoleSender.sendMessage("Task #${id} finished after ${generationTask.count} chunks.")
removeTask(id)
}
} }
} }
@ -70,18 +94,26 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
* Stops a running generation task. * Stops a running generation task.
*/ */
fun removeTask(id: Int): Boolean { fun removeTask(id: Int): Boolean {
val taskEntry = this.tasks.find {it.id == id} val taskEntry: TaskEntry? = if (this.paused) {
this.pausedTasks.find {it.id == id}
} else {
this.tasks.find {it.id == id}
}
if (taskEntry != null) { if (taskEntry != null) {
taskEntry.generationTask.cancel() taskEntry.cancel()
taskEntry.task.cancel()
val deleteTask = chunkmaster.sqliteConnection.prepareStatement(""" val deleteTask = chunkmaster.sqliteConnection.prepareStatement("""
DELETE FROM generation_tasks WHERE id = ?; DELETE FROM generation_tasks WHERE id = ?;
""".trimIndent()) """.trimIndent())
deleteTask.setInt(1, taskEntry.id) deleteTask.setInt(1, taskEntry.id)
deleteTask.execute() deleteTask.execute()
deleteTask.close() deleteTask.close()
if (taskEntry.task.isCancelled) {
tasks.remove(taskEntry) if (taskEntry is RunningTaskEntry) {
if (taskEntry.task.isCancelled) {
tasks.remove(taskEntry)
}
} else if (taskEntry is PausedTaskEntry) {
pausedTasks.remove(taskEntry)
} }
return true return true
} }
@ -109,7 +141,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
*/ */
fun stopAll() { fun stopAll() {
saveProgress() saveProgress()
val removalSet = HashSet<TaskEntry>() val removalSet = HashSet<RunningTaskEntry>()
for (task in tasks) { for (task in tasks) {
task.generationTask.cancel() task.generationTask.cancel()
task.task.cancel() task.task.cancel()
@ -154,6 +186,9 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
*/ */
fun pauseAll() { fun pauseAll() {
paused = true paused = true
for (task in tasks) {
pausedTasks.add(PausedTaskEntry(task.id, task.generationTask))
}
stopAll() stopAll()
} }
@ -162,6 +197,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
*/ */
fun resumeAll() { fun resumeAll() {
paused = false paused = false
pausedTasks.clear()
startAll() startAll()
} }
@ -174,7 +210,8 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
val genTask = task.generationTask val genTask = task.generationTask
server.consoleSender.sendMessage("""Task #${task.id} running for "${genTask.world.name}". server.consoleSender.sendMessage("""Task #${task.id} running for "${genTask.world.name}".
|Progress ${task.generationTask.count} chunks |Progress ${task.generationTask.count} chunks
|${if (task.generationTask.stopAfter > 0)"(${(task.generationTask.count.toDouble()/task.generationTask.stopAfter.toDouble())*100}%)" else ""}. |${if (task.generationTask.stopAfter > 0)"(${(task.generationTask.count.toDouble()/
task.generationTask.stopAfter.toDouble())*100}%)" else ""}.
|Last Chunk: ${genTask.lastChunk.x}, ${genTask.lastChunk.z}""".trimMargin("|").replace('\n', ' ')) |Last Chunk: ${genTask.lastChunk.x}, ${genTask.lastChunk.z}""".trimMargin("|").replace('\n', ' '))
val updateStatement = chunkmaster.sqliteConnection.prepareStatement(""" val updateStatement = chunkmaster.sqliteConnection.prepareStatement("""
UPDATE generation_tasks SET last_x = ?, last_z = ? UPDATE generation_tasks SET last_x = ?, last_z = ?
@ -185,11 +222,6 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
updateStatement.setInt(3, task.id) updateStatement.setInt(3, task.id)
updateStatement.execute() updateStatement.execute()
updateStatement.close() updateStatement.close()
if (genTask.endReached) { // remove the task if it is finished after the progress has been saved
server.consoleSender.sendMessage("Task #${task.id} finished after ${genTask.count} chunks.")
removeTask(task.id)
}
} catch (error: Exception) { } catch (error: Exception) {
server.consoleSender.sendMessage("Exception when saving task progress ${error.message}") server.consoleSender.sendMessage("Exception when saving task progress ${error.message}")
} }

@ -23,6 +23,9 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChun
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 var endReachedCallback: (() -> Unit)? = null
private set
abstract override fun run() abstract override fun run()
abstract fun cancel() abstract fun cancel()
@ -48,4 +51,11 @@ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: Chunk, startChun
protected fun borderReached(): Boolean { protected fun borderReached(): Boolean {
return !world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) || (stopAfter in 1..count) return !world.worldBorder.isInside(lastChunkCoords.getCenterLocation(world)) || (stopAfter in 1..count)
} }
/**
* Registers end reached callback
*/
fun onEndReached(cb: () -> Unit) {
endReachedCallback = cb
}
} }

@ -38,6 +38,7 @@ class GenerationTaskPaper(
} else if (pendingChunks.size < maxPendingChunks) { // if more than 10 chunks are pending, wait. } else if (pendingChunks.size < maxPendingChunks) { // if more than 10 chunks are pending, wait.
if (borderReached()) { if (borderReached()) {
endReached = true endReached = true
endReachedCallback?.invoke()
return return
} }
@ -73,6 +74,9 @@ class GenerationTaskPaper(
} }
} }
pendingChunks.clear() pendingChunks.clear()
if (loadedChunks.isNotEmpty()) {
lastChunkCoords = ChunkCoordinates(loadedChunks.last().x, loadedChunks.last().z)
}
for (chunk in loadedChunks) { for (chunk in loadedChunks) {
if (chunk.isLoaded) { if (chunk.isLoaded) {
chunk.unload(true) chunk.unload(true)

@ -33,6 +33,7 @@ class GenerationTaskSpigot(
} else { } else {
if (borderReached()) { if (borderReached()) {
endReached = true endReached = true
endReachedCallback?.invoke()
return return
} }

@ -0,0 +1,10 @@
package net.trivernis.chunkmaster.lib.generation
class PausedTaskEntry(
override val id: Int,
override val generationTask: GenerationTask
) : TaskEntry {
override fun cancel() {
generationTask.cancel()
}
}

@ -0,0 +1,14 @@
package net.trivernis.chunkmaster.lib.generation
import org.bukkit.scheduler.BukkitTask
class RunningTaskEntry(
override val id: Int,
val task: BukkitTask,
override val generationTask: GenerationTask
) : TaskEntry {
override fun cancel() {
task.cancel()
generationTask.cancel()
}
}

@ -2,4 +2,12 @@ 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) /**
* Generic task entry
*/
interface TaskEntry {
val id: Int
val generationTask: GenerationTask
fun cancel()
}

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

Loading…
Cancel
Save