Merge develop into master

* Update Translation to 1.3.0 (#86)

* Update Translation to 1.3.0

* Tweak SQL_ERROR word order

Co-authored-by: NPBeta <shanhang007@gmail.com>

* Update version to 1.3.1

* Remove empty body of PausedTaskEntry

Co-authored-by: NPBeta <shanhang007@gmail.com>
pull/105/head v1.3.1
Trivernis 4 years ago committed by GitHub
parent 4d4107aaf3
commit 82662bc4d3
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 "1.3.0" version "1.3.1"
sourceCompatibility = 1.8 sourceCompatibility = 1.8

@ -10,7 +10,7 @@ import org.bukkit.plugin.java.JavaPlugin
import org.bukkit.scheduler.BukkitTask import org.bukkit.scheduler.BukkitTask
import org.dynmap.DynmapAPI import org.dynmap.DynmapAPI
class Chunkmaster: JavaPlugin() { class Chunkmaster : JavaPlugin() {
lateinit var sqliteManager: SqliteManager lateinit var sqliteManager: SqliteManager
lateinit var generationManager: GenerationManager lateinit var generationManager: GenerationManager
lateinit var langManager: LanguageManager lateinit var langManager: LanguageManager
@ -48,7 +48,7 @@ class Chunkmaster: JavaPlugin() {
if (PaperLib.isPaper() && PaperLib.getMinecraftPatchVersion() >= 225) { if (PaperLib.isPaper() && PaperLib.getMinecraftPatchVersion() >= 225) {
tpsTask = server.scheduler.runTaskTimer(this, Runnable { tpsTask = server.scheduler.runTaskTimer(this, Runnable {
mspt = 1000/server.currentTick // use papers exposed tick rather than calculating it mspt = 1000 / server.currentTick // use papers exposed tick rather than calculating it
}, 1, 300) }, 1, 300)
} else { } else {
tpsTask = server.scheduler.runTaskTimer(this, Runnable { tpsTask = server.scheduler.runTaskTimer(this, Runnable {
@ -97,7 +97,7 @@ class Chunkmaster: JavaPlugin() {
this.sqliteManager = SqliteManager(this) this.sqliteManager = SqliteManager(this)
sqliteManager.init() sqliteManager.init()
logger.info(langManager.getLocalized("DB_INIT_FINISHED")) logger.info(langManager.getLocalized("DB_INIT_FINISHED"))
} catch(e: Exception) { } catch (e: Exception) {
logger.warning(langManager.getLocalized("DB_INIT_EROR", e.message!!)) logger.warning(langManager.getLocalized("DB_INIT_EROR", e.message!!))
} }
} }

@ -9,7 +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 pauseOnPlayerCount: Int private val pauseOnPlayerCount: Int
get () { get() {
return chunkmaster.config.getInt("generation.pause-on-player-count") return chunkmaster.config.getInt("generation.pause-on-player-count")
} }
private var playerPaused = false private var playerPaused = false
@ -25,7 +25,7 @@ class ChunkmasterEvents(private val chunkmaster: Chunkmaster, private val server
chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_PLAYER_LEAVE")) chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_PLAYER_LEAVE"))
} }
chunkmaster.generationManager.resumeAll() chunkmaster.generationManager.resumeAll()
} else if (chunkmaster.generationManager.paused){ } else if (chunkmaster.generationManager.paused) {
chunkmaster.logger.info(chunkmaster.langManager.getLocalized("PAUSE_MANUALLY")) chunkmaster.logger.info(chunkmaster.langManager.getLocalized("PAUSE_MANUALLY"))
playerPaused = chunkmaster.generationManager.paused playerPaused = chunkmaster.generationManager.paused
} }

@ -5,7 +5,7 @@ import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.command.Command 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"
/** /**
@ -19,7 +19,7 @@ class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand {
): MutableList<String> { ): MutableList<String> {
val genManager = chunkmaster.generationManager val genManager = chunkmaster.generationManager
val allTasks = genManager.allTasks val allTasks = genManager.allTasks
return allTasks.filter {it.id.toString().indexOf(args[0]) == 0} return allTasks.filter { it.id.toString().indexOf(args[0]) == 0 }
.map { it.id.toString() }.toMutableList() .map { it.id.toString() }.toMutableList()
} }

@ -6,7 +6,7 @@ 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"
/** /**
@ -20,14 +20,14 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
): MutableList<String> { ): MutableList<String> {
if (args.size == 1) { if (args.size == 1) {
return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 } return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 }
.map {it.name}.toMutableList() .map { it.name }.toMutableList()
} else if (args.size == 2) { } else if (args.size == 2) {
if (args[0].toIntOrNull() != null) { if (args[0].toIntOrNull() != null) {
return shapes.filter {it.indexOf(args[1]) == 0}.toMutableList() return shapes.filter { it.indexOf(args[1]) == 0 }.toMutableList()
} }
} else if (args.size > 2) { } else if (args.size > 2) {
if (args[1].toIntOrNull() != null) { if (args[1].toIntOrNull() != null) {
return shapes.filter {it.indexOf(args[2]) == 0}.toMutableList() return shapes.filter { it.indexOf(args[2]) == 0 }.toMutableList()
} }
} }
return emptyList<String>().toMutableList() return emptyList<String>().toMutableList()
@ -97,19 +97,22 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
val world = chunkmaster.server.getWorld(worldName) val world = chunkmaster.server.getWorld(worldName)
val allTasks = chunkmaster.generationManager.allTasks val allTasks = chunkmaster.generationManager.allTasks
return if (world != null && (allTasks.find { it.generationTask.world == world }) == null) { return if (world != null && (allTasks.find { it.generationTask.world == world }) == null) {
chunkmaster.generationManager.addTask(world, if (blockRadius > 0) blockRadius/16 else -1 , shape) chunkmaster.generationManager.addTask(world, if (blockRadius > 0) blockRadius / 16 else -1, shape)
sender.sendMessage(chunkmaster.langManager sender.sendMessage(
.getLocalized("TASK_CREATION_SUCCESS", chunkmaster.langManager
worldName, .getLocalized(
if (blockRadius > 0) { "TASK_CREATION_SUCCESS",
chunkmaster.langManager.getLocalized("TASK_UNIT_RADIUS", blockRadius) worldName,
} else{ if (blockRadius > 0) {
chunkmaster.langManager.getLocalized("TASK_UNIT_WORLDBORDER") chunkmaster.langManager.getLocalized("TASK_UNIT_RADIUS", blockRadius)
}, } else {
shape chunkmaster.langManager.getLocalized("TASK_UNIT_WORLDBORDER")
)) },
shape
)
)
true true
} else if (world == null){ } else if (world == null) {
sender.sendMessage(chunkmaster.langManager.getLocalized("WORLD_NOT_FOUND", worldName)); sender.sendMessage(chunkmaster.langManager.getLocalized("WORLD_NOT_FOUND", worldName));
false false
} else { } else {

@ -6,7 +6,7 @@ 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 CmdGetCenter(private val chunkmaster: Chunkmaster): Subcommand { class CmdGetCenter(private val chunkmaster: Chunkmaster) : Subcommand {
override val name = "getCenter"; override val name = "getCenter";
override fun onTabComplete( override fun onTabComplete(
@ -17,7 +17,7 @@ class CmdGetCenter(private val chunkmaster: Chunkmaster): Subcommand {
): MutableList<String> { ): MutableList<String> {
if (args.size == 1) { if (args.size == 1) {
return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 } return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 }
.map {it.name}.toMutableList() .map { it.name }.toMutableList()
} }
return emptyList<String>().toMutableList() return emptyList<String>().toMutableList()
} }
@ -55,7 +55,14 @@ class CmdGetCenter(private val chunkmaster: Chunkmaster): Subcommand {
} }
center = Pair(world.spawnLocation.chunk.x, world.spawnLocation.chunk.z) center = Pair(world.spawnLocation.chunk.x, world.spawnLocation.chunk.z)
} }
sender.sendMessage(chunkmaster.langManager.getLocalized("CENTER_INFO", worldName, center.first, center.second)) sender.sendMessage(
chunkmaster.langManager.getLocalized(
"CENTER_INFO",
worldName,
center.first,
center.second
)
)
} }
} }
} }

@ -7,7 +7,7 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import kotlin.math.ceil import kotlin.math.ceil
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( override fun onTabComplete(
@ -50,7 +50,7 @@ class CmdList(private val chunkmaster: Chunkmaster): Subcommand {
private fun getGenerationEntry(task: TaskEntry): String { private fun getGenerationEntry(task: TaskEntry): String {
val genTask = task.generationTask val genTask = task.generationTask
val percentage = if (genTask.radius > 0) val percentage = if (genTask.radius > 0)
" (%.1f".format(genTask.shape.progress()*100) + "%)." " (%.1f".format(genTask.shape.progress() * 100) + "%)."
else else
"" ""
val count = if (genTask.radius > 0) { val count = if (genTask.radius > 0) {
@ -58,7 +58,9 @@ class CmdList(private val chunkmaster: Chunkmaster): Subcommand {
} else { } else {
genTask.count.toString() genTask.count.toString()
} }
return "\n" + chunkmaster.langManager.getLocalized("TASKS_ENTRY", return "\n" + chunkmaster.langManager.getLocalized(
task.id, genTask.world.name, genTask.state.toString(), count, percentage) "TASKS_ENTRY",
task.id, genTask.world.name, genTask.state.toString(), count, percentage
)
} }
} }

@ -1,7 +1,5 @@
package net.trivernis.chunkmaster.commands package net.trivernis.chunkmaster.commands
import net.md_5.bungee.api.ChatColor
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.Command

@ -1,13 +1,11 @@
package net.trivernis.chunkmaster.commands package net.trivernis.chunkmaster.commands
import net.md_5.bungee.api.ChatColor
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.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
class CmdReload(private val chunkmaster: Chunkmaster): Subcommand { class CmdReload(private val chunkmaster: Chunkmaster) : Subcommand {
override val name = "reload" override val name = "reload"
override fun onTabComplete( override fun onTabComplete(

@ -1,13 +1,11 @@
package net.trivernis.chunkmaster.commands package net.trivernis.chunkmaster.commands
import net.md_5.bungee.api.ChatColor
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.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( override fun onTabComplete(

@ -6,7 +6,7 @@ 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 CmdSetCenter(private val chunkmaster: Chunkmaster): Subcommand { class CmdSetCenter(private val chunkmaster: Chunkmaster) : Subcommand {
override val name = "setCenter"; override val name = "setCenter";
override fun onTabComplete( override fun onTabComplete(
@ -18,7 +18,7 @@ class CmdSetCenter(private val chunkmaster: Chunkmaster): Subcommand {
if (args.size == 1) { if (args.size == 1) {
if (args[0].toIntOrNull() == null) { if (args[0].toIntOrNull() == null) {
return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 } return sender.server.worlds.filter { it.name.indexOf(args[0]) == 0 }
.map {it.name}.toMutableList() .map { it.name }.toMutableList()
} }
} }
return emptyList<String>().toMutableList(); return emptyList<String>().toMutableList();

@ -5,9 +5,8 @@ import net.trivernis.chunkmaster.lib.Subcommand
import org.bukkit.World import org.bukkit.World
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
class CmdStats(private val chunkmaster: Chunkmaster): Subcommand { class CmdStats(private val chunkmaster: Chunkmaster) : Subcommand {
override val name = "stats" override val name = "stats"
override fun onTabComplete( override fun onTabComplete(
@ -23,8 +22,10 @@ class CmdStats(private val chunkmaster: Chunkmaster): Subcommand {
if (args.isNotEmpty()) { if (args.isNotEmpty()) {
val world = sender.server.getWorld(args[0]) val world = sender.server.getWorld(args[0])
if (world == null) { if (world == null) {
sender.sendMessage(chunkmaster.langManager.getLocalized("STATS_HEADER") + "\n" + sender.sendMessage(
chunkmaster.langManager.getLocalized("WORLD_NOT_FOUND", args[0])) chunkmaster.langManager.getLocalized("STATS_HEADER") + "\n" +
chunkmaster.langManager.getLocalized("WORLD_NOT_FOUND", args[0])
)
return false return false
} }
sender.sendMessage(getWorldStatsMessage(sender, world)) sender.sendMessage(getWorldStatsMessage(sender, world))
@ -53,7 +54,12 @@ class CmdStats(private val chunkmaster: Chunkmaster): Subcommand {
${chunkmaster.langManager.getLocalized("STATS_SERVER")} ${chunkmaster.langManager.getLocalized("STATS_SERVER")}
${chunkmaster.langManager.getLocalized("STATS_SERVER_VERSION", sender.server.version)} ${chunkmaster.langManager.getLocalized("STATS_SERVER_VERSION", sender.server.version)}
${chunkmaster.langManager.getLocalized("STATS_PLUGIN_VERSION", chunkmaster.description.version)} ${chunkmaster.langManager.getLocalized("STATS_PLUGIN_VERSION", chunkmaster.description.version)}
${chunkmaster.langManager.getLocalized("STATS_MEMORY", memUsed/1000000, runtime.maxMemory()/1000000, (memUsed.toFloat()/runtime.maxMemory().toFloat()) * 100)} ${chunkmaster.langManager.getLocalized(
"STATS_MEMORY",
memUsed / 1000000,
runtime.maxMemory() / 1000000,
(memUsed.toFloat() / runtime.maxMemory().toFloat()) * 100
)}
${chunkmaster.langManager.getLocalized("STATS_CORES", runtime.availableProcessors())} ${chunkmaster.langManager.getLocalized("STATS_CORES", runtime.availableProcessors())}
${chunkmaster.langManager.getLocalized("STATS_PLUGIN_LOADED_CHUNKS", chunkmaster.generationManager.loadedChunkCount)} ${chunkmaster.langManager.getLocalized("STATS_PLUGIN_LOADED_CHUNKS", chunkmaster.generationManager.loadedChunkCount)}

@ -1,8 +1,6 @@
package net.trivernis.chunkmaster.commands package net.trivernis.chunkmaster.commands
import io.papermc.lib.PaperLib import io.papermc.lib.PaperLib
import net.md_5.bungee.api.ChatColor
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.Material import org.bukkit.Material
@ -10,7 +8,7 @@ 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 CmdTpChunk(private val chunkmaster: Chunkmaster): Subcommand { class CmdTpChunk(private val chunkmaster: Chunkmaster) : Subcommand {
override val name = "tpchunk" override val name = "tpchunk"
override fun onTabComplete( override fun onTabComplete(

@ -1,7 +1,5 @@
package net.trivernis.chunkmaster.commands package net.trivernis.chunkmaster.commands
import net.md_5.bungee.api.ChatColor
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.Server import org.bukkit.Server

@ -1,8 +1,8 @@
package net.trivernis.chunkmaster.lib package net.trivernis.chunkmaster.lib
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import java.lang.Exception
import java.util.Properties
import java.io.* import java.io.*
import java.util.*
class LanguageManager(private val plugin: Chunkmaster) { class LanguageManager(private val plugin: Chunkmaster) {
private val langProps = Properties() private val langProps = Properties()
@ -20,12 +20,14 @@ class LanguageManager(private val plugin: Chunkmaster) {
val file = File(langFile) val file = File(langFile)
val loader = Thread.currentThread().contextClassLoader val loader = Thread.currentThread().contextClassLoader
val defaultStream = this.javaClass.getResourceAsStream("/i18n/DEFAULT.i18n.properties") val defaultStream = this.javaClass.getResourceAsStream("/i18n/DEFAULT.i18n.properties")
if (defaultStream != null) { if (defaultStream != null) {
langProps.load(getReaderForProperties(defaultStream)) langProps.load(getReaderForProperties(defaultStream))
defaultStream.close() defaultStream.close()
} else { } else {
plugin.logger.severe("Couldn't load default language properties.") plugin.logger.severe("Couldn't load default language properties.")
} }
if (file.exists()) { if (file.exists()) {
try { try {
val inputStream = loader.getResourceAsStream(langFile) val inputStream = loader.getResourceAsStream(langFile)
@ -34,7 +36,7 @@ class LanguageManager(private val plugin: Chunkmaster) {
langFileLoaded = true langFileLoaded = true
inputStream.close() inputStream.close()
} }
} catch (e: Exception) { } catch (e: Exception) {
plugin.logger.warning("Language file $langFile could not be loaded!") plugin.logger.warning("Language file $langFile could not be loaded!")
plugin.logger.fine(e.toString()) plugin.logger.fine(e.toString())
} }

@ -37,7 +37,8 @@ class GenerationTasks(private val sqliteManager: SqliteManager) {
*/ */
fun addGenerationTask(world: String, center: ChunkCoordinates, radius: Int, shape: String): CompletableFuture<Int> { fun addGenerationTask(world: String, center: ChunkCoordinates, radius: Int, shape: String): CompletableFuture<Int> {
val completableFuture = CompletableFuture<Int>() val completableFuture = CompletableFuture<Int>()
sqliteManager.executeStatement(""" sqliteManager.executeStatement(
"""
INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, radius, shape) INSERT INTO generation_tasks (center_x, center_z, last_x, last_z, world, radius, shape)
values (?, ?, ?, ?, ?, ?, ?)""", values (?, ?, ?, ?, ?, ?, ?)""",
hashMapOf( hashMapOf(

@ -1,170 +1,189 @@
package net.trivernis.chunkmaster.lib.database package net.trivernis.chunkmaster.lib.database
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import org.apache.commons.lang.exception.ExceptionUtils import org.apache.commons.lang.exception.ExceptionUtils
import java.lang.Exception import java.sql.Connection
import java.sql.Connection import java.sql.DriverManager
import java.sql.DriverManager import java.sql.ResultSet
import java.sql.ResultSet
class SqliteManager(private val chunkmaster: Chunkmaster) {
class SqliteManager(private val chunkmaster: Chunkmaster) { private val tables = listOf(
private val tables = listOf( Pair(
Pair( "generation_tasks",
"generation_tasks", listOf(
listOf( Pair("id", "integer PRIMARY KEY AUTOINCREMENT"),
Pair("id", "integer PRIMARY KEY AUTOINCREMENT"), Pair("center_x", "integer NOT NULL DEFAULT 0"),
Pair("center_x", "integer NOT NULL DEFAULT 0"), Pair("center_z", "integer NOT NULL DEFAULT 0"),
Pair("center_z", "integer NOT NULL DEFAULT 0"), Pair("last_x", "integer NOT NULL DEFAULT 0"),
Pair("last_x", "integer NOT NULL DEFAULT 0"), Pair("last_z", "integer NOT NULL DEFAULT 0"),
Pair("last_z", "integer NOT NULL DEFAULT 0"), Pair("world", "text UNIQUE NOT NULL DEFAULT 'world'"),
Pair("world", "text UNIQUE NOT NULL DEFAULT 'world'"), Pair("radius", "integer DEFAULT -1"),
Pair("radius", "integer DEFAULT -1"), Pair("shape", "text NOT NULL DEFAULT 'square'"),
Pair("shape", "text NOT NULL DEFAULT 'square'"), Pair("state", "text NOT NULL DEFAULT 'GENERATING'")
Pair("state", "text NOT NULL DEFAULT 'GENERATING'") )
) ),
), Pair(
Pair( "world_properties",
"world_properties", listOf(
listOf( Pair("name", "text PRIMARY KEY"),
Pair("name", "text PRIMARY KEY"), Pair("center_x", "integer NOT NULL DEFAULT 0"),
Pair("center_x", "integer NOT NULL DEFAULT 0"), Pair("center_z", "integer NOT NULL DEFAULT 0")
Pair("center_z", "integer NOT NULL DEFAULT 0") )
) ),
), Pair(
Pair( "pending_chunks",
"pending_chunks", listOf(
listOf( Pair("id", "integer PRIMARY KEY AUTOINCREMENT"),
Pair("id", "integer PRIMARY KEY AUTOINCREMENT"), Pair("task_id", "integer NOT NULL"),
Pair("task_id", "integer NOT NULL"), Pair("chunk_x", "integer NOT NULL"),
Pair("chunk_x", "integer NOT NULL"), Pair("chunk_z", "integer NOT NULL")
Pair("chunk_z", "integer NOT NULL") )
) )
) )
) private val needUpdate = HashSet<Pair<String, Pair<String, String>>>()
private val needUpdate = HashSet<Pair<String, Pair<String, String>>>() private val needCreation = HashSet<String>()
private val needCreation = HashSet<String>() private var connection: Connection? = null
private var connection: Connection? = null private var activeTasks = 0
private var activeTasks = 0
val worldProperties = WorldProperties(this)
val worldProperties = WorldProperties(this) val pendingChunks = PendingChunks(this)
val pendingChunks = PendingChunks(this) val generationTasks = GenerationTasks(this)
val generationTasks = GenerationTasks(this)
/**
/** * Returns the connection to the database
* Returns the connection to the database */
*/ fun getConnection(): Connection? {
fun getConnection(): Connection? { if (this.connection != null) {
if (this.connection != null) { return this.connection
return this.connection }
} try {
try { Class.forName("org.sqlite.JDBC")
Class.forName("org.sqlite.JDBC") this.connection = DriverManager.getConnection(
this.connection = DriverManager.getConnection("jdbc:sqlite:${chunkmaster.dataFolder.absolutePath}/" + "jdbc:sqlite:${chunkmaster.dataFolder.absolutePath}/" +
"${chunkmaster.config.getString("database.filename")}") "${chunkmaster.config.getString("database.filename")}"
return this.connection )
} catch (e: Exception) { return this.connection
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("DATABASE_CONNECTION_ERROR")) } catch (e: Exception) {
chunkmaster.logger.severe(e.message) chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("DATABASE_CONNECTION_ERROR"))
} chunkmaster.logger.severe(e.message)
return null }
} return null
}
/**
* Checks for and performs an update /**
*/ * Checks for and performs an update
fun init() { */
this.checkUpdate() fun init() {
this.performUpdate() this.checkUpdate()
} this.performUpdate()
}
/**
* Checks which tables need an update or creation. /**
*/ * Checks which tables need an update or creation.
private fun checkUpdate() { */
val meta = getConnection()!!.metaData private fun checkUpdate() {
val meta = getConnection()!!.metaData
for (table in tables) {
val resTables = meta.getTables(null, null, table.first, null) for (table in tables) {
val resTables = meta.getTables(null, null, table.first, null)
if (resTables.next()) { // table exists
for (column in table.second) { if (resTables.next()) { // table exists
val resColumn = meta.getColumns(null, null, table.first, column.first) for (column in table.second) {
if (!resColumn.next()) { val resColumn = meta.getColumns(null, null, table.first, column.first)
needUpdate.add(Pair(table.first, column)) if (!resColumn.next()) {
} needUpdate.add(Pair(table.first, column))
resColumn.close() }
} resColumn.close()
} else { }
needCreation.add(table.first) } else {
} needCreation.add(table.first)
resTables.close() }
} resTables.close()
} }
}
/**
* Executes a sql statement on the database. /**
*/ * Executes a sql statement on the database.
fun executeStatement(sql: String, values: HashMap<Int, Any>, callback: ((ResultSet?) -> Unit)?) { */
val connection = getConnection() fun executeStatement(sql: String, values: HashMap<Int, Any>, callback: ((ResultSet?) -> Unit)?) {
activeTasks++ val connection = getConnection()
if (connection != null) { activeTasks++
try { if (connection != null) {
//println("'$sql' with values $values") try {
val statement = connection.prepareStatement(sql) //println("'$sql' with values $values")
for (parameterValue in values) { val statement = connection.prepareStatement(sql)
statement.setObject(parameterValue.key, parameterValue.value) for (parameterValue in values) {
} statement.setObject(parameterValue.key, parameterValue.value)
statement.execute() }
val res: ResultSet? = statement.resultSet statement.execute()
if (callback != null) { val res: ResultSet? = statement.resultSet
callback(res) if (callback != null) {
} callback(res)
statement.close() }
} catch (e: Exception) { statement.close()
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("SQL_ERROR", e.toString())) } catch (e: Exception) {
chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("SQL_ERROR", e.toString()))
} finally { chunkmaster.logger.info(ExceptionUtils.getStackTrace(e))
activeTasks-- } finally {
if (activeTasks == 0) { activeTasks--
connection.close() if (activeTasks == 0) {
this.connection = null connection.close()
} this.connection = null
} }
} else { }
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("NO_DATABASE_CONNECTION")) } else {
} chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("NO_DATABASE_CONNECTION"))
} }
}
/**
* Creates or updates tables that needed an update. /**
*/ * Creates or updates tables that needed an update.
private fun performUpdate() { */
for (table in needCreation) { private fun performUpdate() {
try { for (table in needCreation) {
var tableDef = "CREATE TABLE IF NOT EXISTS $table (" try {
var tableDef = "CREATE TABLE IF NOT EXISTS $table ("
for (column in tables.find{it.first == table}!!.second) {
tableDef += "${column.first} ${column.second}," for (column in tables.find { it.first == table }!!.second) {
} tableDef += "${column.first} ${column.second},"
tableDef = tableDef.substringBeforeLast(",") + ");" }
chunkmaster.logger.finest(chunkmaster.langManager.getLocalized("CREATE_TABLE_DEFINITION", table, tableDef)) tableDef = tableDef.substringBeforeLast(",") + ");"
executeStatement(tableDef, HashMap(), null) chunkmaster.logger.finest(
} catch (e: Exception) { chunkmaster.langManager.getLocalized(
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TABLE_CREATE_ERROR", table)) "CREATE_TABLE_DEFINITION",
chunkmaster.logger.severe(e.message) table,
chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) tableDef
} )
} )
for (table in needUpdate) { executeStatement(tableDef, HashMap(), null)
val updateSql = "ALTER TABLE ${table.first} ADD COLUMN ${table.second.first} ${table.second.second}" } catch (e: Exception) {
try { chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TABLE_CREATE_ERROR", table))
executeStatement(updateSql, HashMap(), null) chunkmaster.logger.severe(e.message)
chunkmaster.logger.finest(chunkmaster.langManager.getLocalized("UPDATE_TABLE_DEFINITION", table.first, updateSql)) chunkmaster.logger.info(ExceptionUtils.getStackTrace(e))
} catch (e: Exception) { }
chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("UPDATE_TABLE_FAILED", table.first, updateSql)) }
chunkmaster.logger.severe(e.message) for (table in needUpdate) {
chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) val updateSql = "ALTER TABLE ${table.first} ADD COLUMN ${table.second.first} ${table.second.second}"
} try {
} executeStatement(updateSql, HashMap(), null)
} chunkmaster.logger.finest(
chunkmaster.langManager.getLocalized(
"UPDATE_TABLE_DEFINITION",
table.first,
updateSql
)
)
} catch (e: Exception) {
chunkmaster.logger.severe(
chunkmaster.langManager.getLocalized(
"UPDATE_TABLE_FAILED",
table.first,
updateSql
)
)
chunkmaster.logger.severe(e.message)
chunkmaster.logger.info(ExceptionUtils.getStackTrace(e))
}
}
}
} }

@ -1,6 +1,5 @@
package net.trivernis.chunkmaster.lib.database package net.trivernis.chunkmaster.lib.database
import net.trivernis.chunkmaster.lib.generation.ChunkCoordinates
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture
class WorldProperties(private val sqliteManager: SqliteManager) { class WorldProperties(private val sqliteManager: SqliteManager) {
@ -36,7 +35,7 @@ class WorldProperties(private val sqliteManager: SqliteManager) {
getWorldCenter(worldName).thenAccept { getWorldCenter(worldName).thenAccept {
if (it != null) { if (it != null) {
updateWorldProperties(worldName, center).thenAccept {completableFuture.complete(null) } updateWorldProperties(worldName, center).thenAccept { completableFuture.complete(null) }
} else { } else {
insertWorldProperties(worldName, center).thenAccept { completableFuture.complete(null) } insertWorldProperties(worldName, center).thenAccept { completableFuture.complete(null) }
} }
@ -49,7 +48,8 @@ class WorldProperties(private val sqliteManager: SqliteManager) {
*/ */
private fun updateWorldProperties(worldName: String, center: Pair<Int, Int>): CompletableFuture<Void> { private fun updateWorldProperties(worldName: String, center: Pair<Int, Int>): CompletableFuture<Void> {
val completableFuture = CompletableFuture<Void>() val completableFuture = CompletableFuture<Void>()
sqliteManager.executeStatement("UPDATE world_properties SET center_x = ?, center_z = ? WHERE name = ?", sqliteManager.executeStatement(
"UPDATE world_properties SET center_x = ?, center_z = ? WHERE name = ?",
hashMapOf( hashMapOf(
1 to center.first, 1 to center.first,
2 to center.second, 2 to center.second,
@ -67,7 +67,8 @@ class WorldProperties(private val sqliteManager: SqliteManager) {
*/ */
private fun insertWorldProperties(worldName: String, center: Pair<Int, Int>): CompletableFuture<Void> { private fun insertWorldProperties(worldName: String, center: Pair<Int, Int>): CompletableFuture<Void> {
val completableFuture = CompletableFuture<Void>() val completableFuture = CompletableFuture<Void>()
sqliteManager.executeStatement("INSERT INTO world_properties (name, center_x, center_z) VALUES (?, ?, ?)", sqliteManager.executeStatement(
"INSERT INTO world_properties (name, center_x, center_z) VALUES (?, ?, ?)",
hashMapOf( hashMapOf(
1 to worldName, 1 to worldName,
2 to center.first, 2 to center.first,

@ -2,7 +2,6 @@ package net.trivernis.chunkmaster.lib.dynmap
import org.bukkit.Location import org.bukkit.Location
import org.dynmap.markers.AreaMarker import org.dynmap.markers.AreaMarker
import org.dynmap.markers.Marker
import org.dynmap.markers.MarkerSet import org.dynmap.markers.MarkerSet
import org.dynmap.markers.PolyLineMarker import org.dynmap.markers.PolyLineMarker
@ -46,7 +45,12 @@ class ExtendedMarkerSet(private val markerSet: MarkerSet) {
} }
fun creUpdatePolyLineMarker(id: String, label: String, edges: List<Location>, style: MarkerStyle?): PolyLineMarker? { fun creUpdatePolyLineMarker(
id: String,
label: String,
edges: List<Location>,
style: MarkerStyle?
): PolyLineMarker? {
var marker = markerSet.findPolyLineMarker(id) var marker = markerSet.findPolyLineMarker(id)
val xList = edges.map { it.x } val xList = edges.map { it.x }
val yList = edges.map { it.y } val yList = edges.map { it.y }
@ -54,7 +58,16 @@ class ExtendedMarkerSet(private val markerSet: MarkerSet) {
if (marker != null) { if (marker != null) {
marker.setCornerLocations(xList.toDoubleArray(), yList.toDoubleArray(), zList.toDoubleArray()) marker.setCornerLocations(xList.toDoubleArray(), yList.toDoubleArray(), zList.toDoubleArray())
} else { } else {
marker = markerSet.createPolyLineMarker(id, label, false, edges.first().world.name, xList.toDoubleArray(), yList.toDoubleArray(), zList.toDoubleArray(), true) marker = markerSet.createPolyLineMarker(
id,
label,
false,
edges.first().world.name,
xList.toDoubleArray(),
yList.toDoubleArray(),
zList.toDoubleArray(),
true
)
} }
if (style != null) { if (style != null) {
if (style.lineStyle != null) { if (style.lineStyle != null) {

@ -2,4 +2,9 @@ package net.trivernis.chunkmaster.lib.dynmap
import org.dynmap.markers.MarkerIcon import org.dynmap.markers.MarkerIcon
data class MarkerStyle(val icon: MarkerIcon?, val lineStyle: LineStyle?, val fillStyle: FillStyle?, val boostFlag: Boolean = false) data class MarkerStyle(
val icon: MarkerIcon?,
val lineStyle: LineStyle?,
val fillStyle: FillStyle?,
val boostFlag: Boolean = false
)

@ -5,7 +5,7 @@ import org.bukkit.World
class ChunkCoordinates(val x: Int, val z: Int) { class ChunkCoordinates(val x: Int, val z: Int) {
fun getCenterLocation(world: World): Location { fun getCenterLocation(world: World): Location {
return Location(world, ((x*16) + 8).toDouble(), 1.0, ((z*16) + 8).toDouble()) return Location(world, ((x * 16) + 8).toDouble(), 1.0, ((z * 16) + 8).toDouble())
} }
override fun toString(): String { override fun toString(): String {

@ -2,13 +2,10 @@ package net.trivernis.chunkmaster.lib.generation
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import org.bukkit.Chunk import org.bukkit.Chunk
import java.lang.Exception
import java.util.* import java.util.*
import java.util.concurrent.*
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.collections.HashSet
class ChunkUnloader(private val plugin: Chunkmaster): Runnable { class ChunkUnloader(private val plugin: Chunkmaster) : Runnable {
private val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks") private val maxLoadedChunks = plugin.config.getInt("generation.max-loaded-chunks")
private val lock = ReentrantReadWriteLock() private val lock = ReentrantReadWriteLock()
private var unloadingQueue = Vector<Chunk>(maxLoadedChunks) private var unloadingQueue = Vector<Chunk>(maxLoadedChunks)

@ -4,7 +4,7 @@ import io.papermc.lib.PaperLib
import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.shapes.Shape import net.trivernis.chunkmaster.lib.shapes.Shape
import org.bukkit.World import org.bukkit.World
import java.util.concurrent.* import java.util.concurrent.ArrayBlockingQueue
class DefaultGenerationTask( class DefaultGenerationTask(
private val plugin: Chunkmaster, private val plugin: Chunkmaster,

@ -22,11 +22,11 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
return chunkmaster.config.getLong("generation.unloading-period") return chunkmaster.config.getLong("generation.unloading-period")
} }
private val pauseOnPlayerCount: Int private val pauseOnPlayerCount: Int
get () { get() {
return chunkmaster.config.getInt("generation.pause-on-player-count") return chunkmaster.config.getInt("generation.pause-on-player-count")
} }
private val autostart: Boolean private val autostart: Boolean
get () { get() {
return chunkmaster.config.getBoolean("generation.autostart") return chunkmaster.config.getBoolean("generation.autostart")
} }

@ -4,7 +4,6 @@ import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.dynmap.* import net.trivernis.chunkmaster.lib.dynmap.*
import net.trivernis.chunkmaster.lib.shapes.Shape import net.trivernis.chunkmaster.lib.shapes.Shape
import org.bukkit.World import org.bukkit.World
import java.util.concurrent.Semaphore
import kotlin.math.ceil import kotlin.math.ceil
/** /**
@ -75,12 +74,14 @@ abstract class GenerationTask(
TaskState.CORRECTING -> { TaskState.CORRECTING -> {
this.generateMissing() this.generateMissing()
} }
else -> { } else -> {
}
} }
if (!cancelRun && this.borderReached()) { if (!cancelRun && this.borderReached()) {
this.setEndReached() this.setEndReached()
} }
} catch (e: InterruptedException){} } catch (e: InterruptedException) {
}
isRunning = false isRunning = false
} }
@ -108,7 +109,8 @@ abstract class GenerationTask(
markerSet?.creUpdatePolyLineMarker( markerSet?.creUpdatePolyLineMarker(
markerAreaId, markerAreaId,
markerAreaName, markerAreaName,
this.shape.getShapeEdgeLocations().map { ChunkCoordinates(it.first, it.second).getCenterLocation(this.world) }, this.shape.getShapeEdgeLocations()
.map { ChunkCoordinates(it.first, it.second).getCenterLocation(this.world) },
markerAreaStyle markerAreaStyle
) )
} }

@ -1,6 +1,5 @@
package net.trivernis.chunkmaster.lib.generation package net.trivernis.chunkmaster.lib.generation
import net.trivernis.chunkmaster.lib.generation.ChunkCoordinates
import org.bukkit.Chunk import org.bukkit.Chunk
import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture

@ -5,5 +5,4 @@ import net.trivernis.chunkmaster.lib.generation.GenerationTask
class PausedTaskEntry( class PausedTaskEntry(
override val id: Int, override val id: Int,
override val generationTask: GenerationTask override val generationTask: GenerationTask
) : TaskEntry { ) : TaskEntry
}

@ -1,70 +1,69 @@
package net.trivernis.chunkmaster.lib.generation.taskentry package net.trivernis.chunkmaster.lib.generation.taskentry
import io.papermc.lib.PaperLib import net.trivernis.chunkmaster.lib.generation.GenerationTask
import net.trivernis.chunkmaster.lib.generation.GenerationTask
class RunningTaskEntry(
class RunningTaskEntry( override val id: Int,
override val id: Int, override val generationTask: GenerationTask
override val generationTask: GenerationTask ) : TaskEntry {
) : TaskEntry {
private var lastProgress: Pair<Long, Double>? = null
private var lastProgress: Pair<Long, Double>? = null private var lastChunkCount: Pair<Long, Int>? = null
private var lastChunkCount: Pair<Long, Int>? = null private var thread = Thread(generationTask)
private var thread = Thread(generationTask)
/**
/** * Returns the generation Speed
* Returns the generation Speed */
*/ val generationSpeed: Pair<Double?, Double?>
val generationSpeed: Pair<Double?, Double?> get() {
get() { var generationSpeed: Double? = null
var generationSpeed: Double? = null var chunkGenerationSpeed: Double? = null
var chunkGenerationSpeed: Double? = null if (lastProgress != null) {
if (lastProgress != null) { val progressDiff = generationTask.shape.progress() - lastProgress!!.second
val progressDiff = generationTask.shape.progress() - lastProgress!!.second val timeDiff = (System.currentTimeMillis() - lastProgress!!.first).toDouble() / 1000
val timeDiff = (System.currentTimeMillis() - lastProgress!!.first).toDouble() / 1000 generationSpeed = progressDiff / timeDiff
generationSpeed = progressDiff / timeDiff }
} if (lastChunkCount != null) {
if (lastChunkCount != null) { val chunkDiff = generationTask.count - lastChunkCount!!.second
val chunkDiff = generationTask.count - lastChunkCount!!.second val timeDiff = (System.currentTimeMillis() - lastChunkCount!!.first).toDouble() / 1000
val timeDiff = (System.currentTimeMillis() - lastChunkCount!!.first).toDouble() / 1000 chunkGenerationSpeed = chunkDiff / timeDiff
chunkGenerationSpeed = chunkDiff / timeDiff }
} lastProgress = Pair(System.currentTimeMillis(), generationTask.shape.progress())
lastProgress = Pair(System.currentTimeMillis(), generationTask.shape.progress()) lastChunkCount = Pair(System.currentTimeMillis(), generationTask.count)
lastChunkCount = Pair(System.currentTimeMillis(), generationTask.count) return Pair(generationSpeed, chunkGenerationSpeed)
return Pair(generationSpeed, chunkGenerationSpeed) }
}
init {
init { lastProgress = Pair(System.currentTimeMillis(), generationTask.shape.progress())
lastProgress = Pair(System.currentTimeMillis(), generationTask.shape.progress()) lastChunkCount = Pair(System.currentTimeMillis(), generationTask.count)
lastChunkCount = Pair(System.currentTimeMillis(), generationTask.count) }
}
fun start() {
fun start() { thread.start()
thread.start() }
}
fun cancel(timeout: Long): Boolean {
fun cancel(timeout: Long): Boolean { if (generationTask.isRunning) {
if (generationTask.isRunning) { generationTask.cancel()
generationTask.cancel() thread.interrupt()
thread.interrupt() }
} return try {
return try { joinThread(timeout)
joinThread(timeout) } catch (e: InterruptedException) {
} catch (e: InterruptedException) { true
true }
} }
}
private fun joinThread(timeout: Long): Boolean {
private fun joinThread(timeout: Long): Boolean { var threadStopped = false
var threadStopped = false
for (i in 0..100) {
for (i in 0..100) { if (!thread.isAlive || !generationTask.isRunning) {
if (!thread.isAlive || !generationTask.isRunning) { threadStopped = true
threadStopped = true break
break }
} Thread.sleep(timeout / 100)
Thread.sleep(timeout / 100) }
} return threadStopped
return threadStopped }
}
} }

@ -1,14 +1,10 @@
package net.trivernis.chunkmaster.lib.shapes package net.trivernis.chunkmaster.lib.shapes
import net.trivernis.chunkmaster.lib.dynmap.ExtendedMarkerSet
import net.trivernis.chunkmaster.lib.dynmap.MarkerStyle
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashSet import kotlin.collections.HashSet
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.sqrt
import kotlin.system.exitProcess
class Circle(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape(center, start, radius) { class Circle(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape(center, start, radius) {
private var r = 0 private var r = 0
@ -21,7 +17,7 @@ class Circle(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape
} }
override fun total(): Double { override fun total(): Double {
return (PI * radius.toFloat().pow(2)) return (PI * radius.toFloat().pow(2))
} }
override fun progress(): Double { override fun progress(): Double {
@ -50,16 +46,19 @@ class Circle(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape
if (endReached()) { if (endReached()) {
return currentPos return currentPos
} }
if (count == 0 && currentPos != center) { if (count == 0 && currentPos != center) {
val tmpCircle = Circle(center, center, radius) val tmpCircle = Circle(center, center, radius)
while (tmpCircle.next() != currentPos && !tmpCircle.endReached()); while (tmpCircle.next() != currentPos && !tmpCircle.endReached());
this.count = tmpCircle.count this.count = tmpCircle.count
this.r = tmpCircle.r this.r = tmpCircle.r
} }
if (count == 0) { if (count == 0) {
count++ count++
return center return center
} }
if (coords.isEmpty()) { if (coords.isEmpty()) {
r++ r++
val tmpCoords = HashSet<Pair<Int, Int>>() val tmpCoords = HashSet<Pair<Int, Int>>()
@ -70,6 +69,7 @@ class Circle(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape
coords.addAll(tmpCoords) coords.addAll(tmpCoords)
previousCoords.addAll(tmpCoords) previousCoords.addAll(tmpCoords)
} }
count++ count++
val coord = coords.pop() val coord = coords.pop()
currentPos = Pair(coord.first + center.first, coord.second + center.second) currentPos = Pair(coord.first + center.first, coord.second + center.second)

@ -1,9 +1,5 @@
package net.trivernis.chunkmaster.lib.shapes package net.trivernis.chunkmaster.lib.shapes
import net.trivernis.chunkmaster.lib.dynmap.ExtendedMarkerSet
import net.trivernis.chunkmaster.lib.dynmap.MarkerStyle
import javax.xml.stream.Location
abstract class Shape(protected val center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) { abstract class Shape(protected val center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) {
protected var currentPos = start protected var currentPos = start
protected var radius = radius protected var radius = radius

@ -1,11 +1,9 @@
package net.trivernis.chunkmaster.lib.shapes package net.trivernis.chunkmaster.lib.shapes
import kotlin.math.PI
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.sqrt
class Spiral(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int): Shape(center, start, radius) { class Spiral(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape(center, start, radius) {
private var direction = 0 private var direction = 0
override fun endReached(): Boolean { override fun endReached(): Boolean {
@ -44,20 +42,20 @@ class Spiral(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int): Shape(
count = simSpiral.count count = simSpiral.count
} }
if (count == 1) { // because of the center behaviour if (count == 1) { // because of the center behaviour
count ++ count++
return currentPos return currentPos
} }
if (currentPos == center) { // the center has to be handled exclusively if (currentPos == center) { // the center has to be handled exclusively
currentPos = Pair(center.first, center.second + 1) currentPos = Pair(center.first, center.second + 1)
count ++ count++
return center return center
} else { } else {
val distances = getDistances(center, currentPos) val distances = getDistances(center, currentPos)
if (abs(distances.first) == abs(distances.second)) { if (abs(distances.first) == abs(distances.second)) {
direction = (direction + 1)%5 direction = (direction + 1) % 5
}
} }
when(direction) { }
when (direction) {
0 -> { 0 -> {
currentPos = Pair(currentPos.first + 1, currentPos.second) currentPos = Pair(currentPos.first + 1, currentPos.second)
} }
@ -75,7 +73,7 @@ class Spiral(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int): Shape(
direction = 0 direction = 0
} }
} }
count ++ count++
return currentPos return currentPos
} }

@ -1,11 +1,12 @@
RESUME_FOR_WORLD = 正在恢复执行 '%s' 世界的区块生成任务... RESUME_FOR_WORLD = 正在恢复执行 '%s' 世界的区块生成任务...
TASK_FINISHED = 任务 #%d 在生成 %d 个区块后完成. TASK_FINISHED = 任务 #%d 在生成 %d 个区块后完成.
TASK_CANCELED = 已取消任务 #%s. TASK_CANCELLED = 已取消任务 #%s.
TASK_LOAD_FAILED = §c加载任务 #%d 失败. TASK_LOAD_FAILED = §c加载任务 #%d 失败.
TASK_LOAD_SUCCESS = %d 个已保存的任务加载完成. TASK_LOAD_SUCCESS = %d 个已保存的任务加载完成.
TASK_NOT_FOUND = §c任务 %s 未找到! TASK_NOT_FOUND = §c任务 %s 未找到!
CREATE_DELAYED_LOAD = 正在创建延迟执行的区块生成任务... CREATE_DELAYED_LOAD = 正在创建延迟执行的区块生成任务...
TASK_PERIODIC_REPORT = 任务 #%d 正在 '%s' 世界执行. 进度: %d 区块 %s %s, 速度: %.1f 区块 / 秒, 最新生成的区块: %d, %d TASK_PERIODIC_REPORT = 任务 #%d 正在 '%s' 世界执行. 状态: %s. 进度: %d 区块 %s %s, 速度: %.1f 区块 / 秒, 最新生成的区块: %d, %d
TASK_PERIODIC_REPORT_CORRECTING = 任务 #%d 正在为世界 '%s' 生成缺失的区块. 进度: %d 区块 %s
TASK_SAVE_FAILED = §c保存任务时发生错误: %s TASK_SAVE_FAILED = §c保存任务时发生错误: %s
WORLD_NAME_REQUIRED = §c你需要提供世界名称! WORLD_NAME_REQUIRED = §c你需要提供世界名称!
@ -18,7 +19,7 @@ TASK_ID_REQUIRED = §c你需要提供任务 ID!
INVALID_ARGUMENT = §c在 %s: %s 存在无效的变量! INVALID_ARGUMENT = §c在 %s: %s 存在无效的变量!
PAUSED_TASKS_HEADER = 当前暂停的区块生成任务 PAUSED_TASKS_HEADER = 当前暂停的区块生成任务
TASKS_ENTRY = - §9#%d§r - §2%s§r - §2%d 区块 %s§r TASKS_ENTRY = - §9#%d§r - §2%s§r - §2%s§r - §2%s 区块 %s§r
RUNNING_TASKS_HEADER = 当前运行的区块生成任务 RUNNING_TASKS_HEADER = 当前运行的区块生成任务
NO_GENERATION_TASKS = 无区块生成任务. NO_GENERATION_TASKS = 无区块生成任务.
@ -44,7 +45,7 @@ DB_INIT_FINISHED = 数据库初始化完成.
DB_INIT_EROR = 初始化数据库时发生错误: %s. DB_INIT_EROR = 初始化数据库时发生错误: %s.
DATABASE_CONNECTION_ERROR = §c连接数据库失败! DATABASE_CONNECTION_ERROR = §c连接数据库失败!
SQL_ERROR = §cSQL %s 发生错误! SQL_ERROR = §cSQL 发生错误: %s !
NO_DATABASE_CONNECTION = §c无法执行 SQL 语句: 无数据库连接. NO_DATABASE_CONNECTION = §c无法执行 SQL 语句: 无数据库连接.
CREATE_TABLE_DEFINITION = 已创建表 %s ,定义 %s. CREATE_TABLE_DEFINITION = 已创建表 %s ,定义 %s.
TABLE_CREATE_ERROR = §c创建表 %s 失败. TABLE_CREATE_ERROR = §c创建表 %s 失败.
@ -73,3 +74,7 @@ STATS_WORLD_NAME = §l%s§r
STATS_ENTITY_COUNT = - §2%d§r 实体 STATS_ENTITY_COUNT = - §2%d§r 实体
STATS_LOADED_CHUNKS = - §2%d§r 已载入区块 STATS_LOADED_CHUNKS = - §2%d§r 已载入区块
STATS_PLUGIN_LOADED_CHUNKS = - §2%d§r 被 Chunk Master 载入的区块 STATS_PLUGIN_LOADED_CHUNKS = - §2%d§r 被 Chunk Master 载入的区块
SAVING_CHUNKS = 正在保存 %d 已载入的区块...
CANCEL_FAIL = 取消任务 #%d 操作超时!
NO_AUTOSTART = 自动启动被设置为 §2关闭§r. 正在暂停...

@ -1,6 +1,6 @@
main: net.trivernis.chunkmaster.Chunkmaster main: net.trivernis.chunkmaster.Chunkmaster
name: Chunkmaster name: Chunkmaster
version: '1.3.0' version: '1.3.1'
description: Automated world pregeneration. description: Automated world pregeneration.
author: Trivernis author: Trivernis
website: trivernis.net website: trivernis.net

Loading…
Cancel
Save