From f88100be5ff34d292eb1b1a1219f5b5e91c99384 Mon Sep 17 00:00:00 2001 From: trivernis Date: Thu, 30 Jan 2020 20:31:19 +0100 Subject: [PATCH 1/6] Fix chunk center coordinate being calculated the wrong way Fixes #19 --- .../trivernis/chunkmaster/lib/generation/ChunkCoordinates.kt | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/ChunkCoordinates.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/ChunkCoordinates.kt index 1376d53..cbb4441 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/ChunkCoordinates.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/ChunkCoordinates.kt @@ -5,6 +5,6 @@ import org.bukkit.World class ChunkCoordinates(val x: Int, val z: Int) { fun getCenterLocation(world: World): Location { - return Location(world, ((x*16) + 8).toDouble(), 1.0, ((x*16) + 8).toDouble()) + return Location(world, ((x*16) + 8).toDouble(), 1.0, ((z*16) + 8).toDouble()) } } \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c63905a..dee18cb 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.13-beta' +version: '0.14-beta' description: Chunk commands plugin. author: Trivernis website: trivernis.net From 900600714ea56d588a8d619d8603a9c0a0ff24dd Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Feb 2020 10:46:46 +0100 Subject: [PATCH 2/6] Add i18n structure --- .../net/trivernis/chunkmaster/Chunkmaster.kt | 5 +++ .../trivernis/chunkmaster/commands/CmdList.kt | 4 +- .../chunkmaster/lib/LanguageManager.kt | 45 +++++++++++++++++++ .../lib/generation/GenerationManager.kt | 18 +++----- src/main/resources/DEFAULT.i18n.properties | 0 5 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt create mode 100644 src/main/resources/DEFAULT.i18n.properties diff --git a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt index f24c79e..55459bf 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt @@ -2,6 +2,7 @@ package net.trivernis.chunkmaster import io.papermc.lib.PaperLib import net.trivernis.chunkmaster.commands.* +import net.trivernis.chunkmaster.lib.LanguageManager import net.trivernis.chunkmaster.lib.generation.GenerationManager import net.trivernis.chunkmaster.lib.SqliteManager import org.bstats.bukkit.Metrics @@ -12,6 +13,7 @@ import java.lang.Exception class Chunkmaster: JavaPlugin() { lateinit var sqliteManager: SqliteManager lateinit var generationManager: GenerationManager + lateinit var langManager: LanguageManager private lateinit var tpsTask: BukkitTask var mspt = 20 // keep track of the milliseconds per tick private set @@ -25,6 +27,8 @@ class Chunkmaster: JavaPlugin() { val metrics = Metrics(this) + langManager = LanguageManager(this) + langManager.loadProperties() initDatabase() generationManager = GenerationManager(this, server) generationManager.init() @@ -70,6 +74,7 @@ class Chunkmaster: JavaPlugin() { config.addDefault("generation.max-loaded-chunks", 10) config.addDefault("generation.ignore-worldborder", false) config.addDefault("database.filename", "chunkmaster.db") + config.addDefault("language", "EN") config.options().copyDefaults(true) saveConfig() } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt index b98a6f4..4d1998b 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt @@ -50,7 +50,9 @@ class CmdList(private val chunkmaster: Chunkmaster): Subcommand { 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) + .append("${"%.1f".format(genTask.count)} chunks").color(ChatColor.BLUE) + .append(", ETA: ").color(ChatColor.WHITE) + .append("") if (genTask.stopAfter > 0) { response.append(" (${(genTask.count.toDouble()/genTask.stopAfter.toDouble())*100}%).") diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt new file mode 100644 index 0000000..2e4923e --- /dev/null +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt @@ -0,0 +1,45 @@ +package net.trivernis.chunkmaster.lib +import net.trivernis.chunkmaster.Chunkmaster +import java.io.File +import java.lang.Exception +import java.util.Properties +import java.util.logging.Level + +class LanguageManager(private val plugin: Chunkmaster) { + private val langProps = Properties() + private val languageFolder = "${plugin.dataFolder.absolutePath}/i18n" + private var langFileLoaded = false + + fun loadProperties() { + val language = plugin.config.getString("language") + val langFile = "$languageFolder/$language.i18n.properties" + val file = File(langFile) + val loader = Thread.currentThread().contextClassLoader + val defaultStream = this.javaClass.getResourceAsStream("/DEFAULT.i18n.properties") + if (defaultStream != null) { + langProps.load(defaultStream) + defaultStream.close() + } else { + plugin.logger.severe("Couldn't load default language properties.") + } + if (file.exists()) { + try { + val inputStream = loader.getResourceAsStream(langFile) + if (inputStream != null) { + langProps.load(inputStream) + langFileLoaded = true + inputStream.close() + } + } catch (e: Exception) { + plugin.logger.warning("Language file $langFile could not be loaded!") + plugin.logger.fine(e.toString()) + } + } else { + plugin.logger.warning("Language File $langFile could not be found!") + } + } + + fun getLocalized(key: String) { + langProps.getProperty(key) + } +} \ No newline at end of file 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 6a08d76..ee5fa6d 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt @@ -47,12 +47,9 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server ) var id = 0 - chunkmaster.sqliteManager.executeStatement( - """ - SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1 - """.trimIndent(), - HashMap() - ) { + chunkmaster.sqliteManager.executeStatement(""" + SELECT id FROM generation_tasks ORDER BY id DESC LIMIT 1 + """.trimIndent(), HashMap()) { it.next() id = it.getInt("id") } @@ -114,11 +111,9 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server } if (taskEntry != null) { taskEntry.cancel() - chunkmaster.sqliteManager.executeStatement( - """ + chunkmaster.sqliteManager.executeStatement(""" DELETE FROM generation_tasks WHERE id = ?; - """.trimIndent(), - HashMap(mapOf(1 to taskEntry.id)), + """.trimIndent(), HashMap(mapOf(1 to taskEntry.id)), null ) @@ -171,8 +166,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server * Starts all generation tasks. */ fun startAll() { - chunkmaster.sqliteManager.executeStatement("SELECT * FROM generation_tasks", HashMap()) { - val res = it + chunkmaster.sqliteManager.executeStatement("SELECT * FROM generation_tasks", HashMap()) { res -> while (res.next()) { try { val id = res.getInt("id") diff --git a/src/main/resources/DEFAULT.i18n.properties b/src/main/resources/DEFAULT.i18n.properties new file mode 100644 index 0000000..e69de29 From bd731c85f0635a1d080e68c6ef4439fcf578da74 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Feb 2020 11:58:40 +0100 Subject: [PATCH 3/6] Add i18n to generation manager --- .../net/trivernis/chunkmaster/Chunkmaster.kt | 2 +- .../chunkmaster/commands/CmdGenerate.kt | 5 +-- .../chunkmaster/lib/LanguageManager.kt | 25 +++++++++--- .../lib/generation/GenerationManager.kt | 38 ++++++++++--------- .../lib/generation/GenerationTask.kt | 2 - src/main/resources/DEFAULT.i18n.properties | 0 .../resources/i18n/DEFAULT.i18n.properties | 11 ++++++ src/main/resources/i18n/de.i18n.properties | 11 ++++++ src/main/resources/i18n/en.i18n.properties | 11 ++++++ 9 files changed, 76 insertions(+), 29 deletions(-) delete mode 100644 src/main/resources/DEFAULT.i18n.properties create mode 100644 src/main/resources/i18n/DEFAULT.i18n.properties create mode 100644 src/main/resources/i18n/de.i18n.properties create mode 100644 src/main/resources/i18n/en.i18n.properties diff --git a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt index 55459bf..91bf6e7 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt @@ -74,7 +74,7 @@ class Chunkmaster: JavaPlugin() { config.addDefault("generation.max-loaded-chunks", 10) config.addDefault("generation.ignore-worldborder", false) config.addDefault("database.filename", "chunkmaster.db") - config.addDefault("language", "EN") + config.addDefault("language", "en") config.options().copyDefaults(true) saveConfig() } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt index 9ea4dde..8d07447 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt @@ -79,8 +79,7 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand { stopAfter = getStopAfter(stopAfter, args[2]) } } else { - sender.spigot().sendMessage( - *ComponentBuilder("You need to provide a world name").color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("WORLD_NAME_REQUIRED")) return false } } @@ -126,7 +125,7 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand { .append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create()) false } else { - sender.spigot().sendMessage(*ComponentBuilder("Task already exists!").color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_ALREADY_EXISTS", worldName)) return false } } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt index 2e4923e..e72d2e5 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt @@ -3,19 +3,23 @@ import net.trivernis.chunkmaster.Chunkmaster import java.io.File import java.lang.Exception import java.util.Properties -import java.util.logging.Level class LanguageManager(private val plugin: Chunkmaster) { private val langProps = Properties() private val languageFolder = "${plugin.dataFolder.absolutePath}/i18n" private var langFileLoaded = false + /** + * Loads the default properties file and then the language specific ones. + * If no lang-specific file is found in the plugins directory under i18n an attempt is made to + * load the file from inside the jar in i18n. + */ fun loadProperties() { val language = plugin.config.getString("language") val langFile = "$languageFolder/$language.i18n.properties" val file = File(langFile) val loader = Thread.currentThread().contextClassLoader - val defaultStream = this.javaClass.getResourceAsStream("/DEFAULT.i18n.properties") + val defaultStream = this.javaClass.getResourceAsStream("/i18n/DEFAULT.i18n.properties") if (defaultStream != null) { langProps.load(defaultStream) defaultStream.close() @@ -35,11 +39,22 @@ class LanguageManager(private val plugin: Chunkmaster) { plugin.logger.fine(e.toString()) } } else { - plugin.logger.warning("Language File $langFile could not be found!") + val inputStream = this.javaClass.getResourceAsStream("/i18n/$language.i18n.properties") + if (inputStream != null) { + langProps.load(inputStream) + langFileLoaded = true + inputStream.close() + } else { + plugin.logger.warning("Language File $langFile could not be found!") + } } } - fun getLocalized(key: String) { - langProps.getProperty(key) + /** + * Returns a localized message with replacements + */ + fun getLocalized(key: String, vararg replacements: Any): String { + val localizedString = langProps.getProperty(key) + return String.format(localizedString, *replacements) } } \ No newline at end of file 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 ee5fa6d..81b69ab 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt @@ -55,7 +55,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server } generationTask.onEndReached { - chunkmaster.logger.info("Task #${id} finished after ${it.count} chunks.") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("TASK_FINISHED", id, it.count)) removeTask(id) } @@ -86,7 +86,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server stopAfter: Int = -1 ) { if (!paused) { - chunkmaster.logger.info("Resuming chunk generation task for world \"${world.name}\"") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("RESUME_FOR_WORLD", world.name)) val generationTask = createGenerationTask(world, center, last, stopAfter) val task = server.scheduler.runTaskTimer( chunkmaster, generationTask, 200, // 10 sec delay @@ -94,7 +94,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server ) tasks.add(RunningTaskEntry(id, task, generationTask)) generationTask.onEndReached { - chunkmaster.logger.info("Task #${id} finished after ${generationTask.count} chunks.") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("TASK_FINISHED", id, generationTask.count)) removeTask(id) } } @@ -134,7 +134,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server * Loads tasks from the database and resumes them */ fun init() { - chunkmaster.logger.info("Creating task to load chunk generation Tasks later...") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("CREATE_DELAYED_LOAD")) server.scheduler.runTaskTimer(chunkmaster, Runnable { saveProgress() // save progress every 30 seconds }, 600, 600) @@ -157,7 +157,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server if (task.task.isCancelled) { removalSet.add(task) } - chunkmaster.logger.info("Canceled task #${task.id}") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("TASK_CANCELED", task.id)) } tasks.removeAll(removalSet) } @@ -178,13 +178,13 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server resumeTask(world!!, center, last, id, stopAfter) } } catch (error: NullPointerException) { - chunkmaster.logger.severe("Failed to load Task ${res.getInt("id")}.") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TASK_LOAD_FAILED", res.getInt("id"))) } } } if (tasks.isNotEmpty()) { - chunkmaster.logger.info("${tasks.size} saved tasks loaded.") + chunkmaster.logger.info(chunkmaster.langManager.getLocalized("TASK_LOAD_SUCCESS", tasks.size)) } } @@ -215,16 +215,18 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server for (task in tasks) { try { val genTask = task.generationTask - chunkmaster.logger.info( - """Task #${task.id} running for "${genTask.world.name}". - |Progress ${task.generationTask.count} chunks - |${if (task.generationTask.stopAfter > 0) "(${"%.2f".format( - (task.generationTask.count.toDouble() / - task.generationTask.stopAfter.toDouble()) * 100 - )}%)" else ""}. - | Speed: ${"%.1f".format(task.generationSpeed)} chunks/sec, - |Last Chunk: ${genTask.lastChunk.x}, ${genTask.lastChunk.z}""".trimMargin("|").replace('\n', ' ') - ) + val percentage = if (genTask.stopAfter > 0) "(${"%.2f".format( + (genTask.count.toDouble() / genTask.stopAfter.toDouble()) * 100 + )}%)" else "" + chunkmaster.logger.info(chunkmaster.langManager.getLocalized( + "TASK_PERIODIC_REPORT", + task.id, + genTask.world.name, + genTask.count, + percentage, + task.generationSpeed!!, + genTask.lastChunk.x, + genTask.lastChunk.z)) chunkmaster.sqliteManager.executeStatement( """ UPDATE generation_tasks SET last_x = ?, last_z = ? @@ -234,7 +236,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server null ) } catch (error: Exception) { - chunkmaster.logger.warning("Exception when saving task progress ${error.message}") + chunkmaster.logger.warning(chunkmaster.langManager.getLocalized("TASK_SAVE_FAILED", error.toString())) } } } 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 d089772..92f3ea5 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationTask.kt @@ -4,13 +4,11 @@ import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.lib.Spiral import org.bukkit.Chunk import org.bukkit.World - /** * Interface for generation tasks. */ abstract class GenerationTask(plugin: Chunkmaster, centerChunk: ChunkCoordinates, startChunk: ChunkCoordinates) : Runnable { - abstract val stopAfter: Int abstract val world: World abstract val count: Int diff --git a/src/main/resources/DEFAULT.i18n.properties b/src/main/resources/DEFAULT.i18n.properties deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/i18n/DEFAULT.i18n.properties b/src/main/resources/i18n/DEFAULT.i18n.properties new file mode 100644 index 0000000..0376e0b --- /dev/null +++ b/src/main/resources/i18n/DEFAULT.i18n.properties @@ -0,0 +1,11 @@ +RESUME_FOR_WORLD = Resuming chunk generation task for world '%s'... +TASK_FINISHED = Task #%d finished after %d chunks. +TASK_CANCELED = Canceled task #%d. +TASK_LOAD_FAILED = Failed to load task #%d. +TASK_LOAD_SUCCESS = %d saved tasks loaded. +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_SAVE_FAILED = Exception when saving tasks: %s +CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... + +WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name! +TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! \ No newline at end of file diff --git a/src/main/resources/i18n/de.i18n.properties b/src/main/resources/i18n/de.i18n.properties new file mode 100644 index 0000000..4d55794 --- /dev/null +++ b/src/main/resources/i18n/de.i18n.properties @@ -0,0 +1,11 @@ +RESUME_FOR_WORLD = Setze das Chunk-Generieren für Welt '%s' fort... +TASK_FINISHED = Aufgabe #%d wurde nach %d chunks beendet. +TASK_CANCELED = Aufgabe #%d wurde abgebrochen. +TASK_LOAD_FAILED = Aufgabe #%d konnte nicht geladen werden. +TASK_LOAD_SUCCESS = %d gespeicherte Aufgaben wurden geladen. +CREATE_DELAYED_LOAD = Erstelle einen Bukkit-Task zum verzögerten Laden von Aufgaben... +TASK_PERIODIC_REPORT = Aufgabe #%d für Welt '%s'. Fortschritt: %d chunks %s, Geschwindigkeit: %.1f ch/s, Letzer Chunk: %d, %d +TASK_SAVE_FAILED = Exception beim Speichern der Aufgaben: %s + +WORLD_NAME_REQUIRED = \u00A7cDu musst einen Weltennamen angeben! +TASK_ALREADY_EXISTS = \u00A7cEs existiert bereits eine Aufgabe für '%s'! \ No newline at end of file diff --git a/src/main/resources/i18n/en.i18n.properties b/src/main/resources/i18n/en.i18n.properties new file mode 100644 index 0000000..0376e0b --- /dev/null +++ b/src/main/resources/i18n/en.i18n.properties @@ -0,0 +1,11 @@ +RESUME_FOR_WORLD = Resuming chunk generation task for world '%s'... +TASK_FINISHED = Task #%d finished after %d chunks. +TASK_CANCELED = Canceled task #%d. +TASK_LOAD_FAILED = Failed to load task #%d. +TASK_LOAD_SUCCESS = %d saved tasks loaded. +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_SAVE_FAILED = Exception when saving tasks: %s +CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... + +WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name! +TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! \ No newline at end of file From 965598de2becb39778b19cd6aab40db68358453e Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 5 Feb 2020 16:34:13 +0100 Subject: [PATCH 4/6] Add i18n to every output Closes #16 --- .../net/trivernis/chunkmaster/Chunkmaster.kt | 8 +-- .../chunkmaster/commands/CmdCancel.kt | 8 ++- .../chunkmaster/commands/CmdGenerate.kt | 11 ++-- .../trivernis/chunkmaster/commands/CmdList.kt | 47 ++++++++--------- .../chunkmaster/commands/CmdPause.kt | 9 +--- .../chunkmaster/commands/CmdReload.kt | 5 +- .../chunkmaster/commands/CmdResume.kt | 6 +-- .../chunkmaster/commands/CmdTpChunk.kt | 9 ++-- .../commands/CommandChunkmaster.kt | 12 ++--- .../chunkmaster/lib/LanguageManager.kt | 1 + .../chunkmaster/lib/SqliteManager.kt | 14 ++--- .../resources/i18n/DEFAULT.i18n.properties | 47 +++++++++++++++-- src/main/resources/i18n/de.i18n.properties | 51 ++++++++++++++++--- src/main/resources/i18n/en.i18n.properties | 16 ++++-- 14 files changed, 150 insertions(+), 94 deletions(-) diff --git a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt index 91bf6e7..efc8916 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/Chunkmaster.kt @@ -56,7 +56,7 @@ class Chunkmaster: JavaPlugin() { * Stop all tasks and close database connection on disable */ override fun onDisable() { - logger.info("Stopping all generation tasks...") + logger.info(langManager.getLocalized("STOPPING_ALL_TASKS")) generationManager.stopAll() } @@ -83,13 +83,13 @@ class Chunkmaster: JavaPlugin() { * Initializes the database */ private fun initDatabase() { - logger.info("Initializing Database...") + logger.info(langManager.getLocalized("DB_INIT")) try { this.sqliteManager = SqliteManager( this) sqliteManager.init() - logger.info("Database fully initialized.") + logger.info(langManager.getLocalized("DB_INIT_FINISHED")) } catch(e: Exception) { - logger.warning("Failed to init database: ${e.message}") + logger.warning(langManager.getLocalized("DB_INIT_EROR", e.message!!)) } } } \ 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 b1fa084..0c662c5 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdCancel.kt @@ -32,16 +32,14 @@ class CmdCancel(private val chunkmaster: Chunkmaster): Subcommand { 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("Task ${args[0]} canceled.") + sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_CANCELED", args[0])) true } else { - sender.spigot().sendMessage(*ComponentBuilder("Task ${args[0]} not found!") - .color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_NOT_FOUND", args[0])) false } } else { - sender.spigot().sendMessage(*ComponentBuilder("You need to provide a task id to cancel.") - .color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_ID_REQUIRED")); false } } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt index 8d07447..deaa7c3 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdGenerate.kt @@ -1,7 +1,5 @@ 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.lib.Subcommand import org.bukkit.command.Command @@ -115,14 +113,11 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand { val allTasks = chunkmaster.generationManager.allTasks return if (world != null && (allTasks.find { it.generationTask.world == world }) == null) { chunkmaster.generationManager.addTask(world, stopAfter) - sender.spigot().sendMessage(*ComponentBuilder("Generation task for world ").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(" successfully created").color(ChatColor.BLUE).create()) + sender.sendMessage(chunkmaster.langManager + .getLocalized("TASK_CREATION_SUCCESS", worldName, if (stopAfter > 0) "$stopAfter chunks" else "WorldBorder")) true } else if (world == null){ - sender.spigot().sendMessage(*ComponentBuilder("World ").color(ChatColor.RED) - .append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("WORLD_NOT_FOUND", worldName)); false } else { sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_ALREADY_EXISTS", worldName)) diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt index 4d1998b..86f98c3 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdList.kt @@ -4,6 +4,7 @@ import net.md_5.bungee.api.ChatColor import net.md_5.bungee.api.chat.ComponentBuilder import net.trivernis.chunkmaster.Chunkmaster import net.trivernis.chunkmaster.lib.Subcommand +import net.trivernis.chunkmaster.lib.generation.TaskEntry import org.bukkit.command.Command import org.bukkit.command.CommandSender @@ -27,39 +28,33 @@ class CmdList(private val chunkmaster: Chunkmaster): Subcommand { val pausedTasks = chunkmaster.generationManager.pausedTasks if (runningTasks.isEmpty() && pausedTasks.isEmpty()) { - sender.spigot().sendMessage(*ComponentBuilder("There are no generation tasks.") - .color(ChatColor.BLUE).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("NO_GENERATION_TASKS")) } else if (runningTasks.isEmpty()) { - val response = ComponentBuilder("Currently paused generation tasks:").color(ChatColor.WHITE).bold(true) + var response = chunkmaster.langManager.getLocalized("PAUSED_TASKS_HEADER") 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}%).") - } + response += getGenerationEntry(taskEntry) } - sender.spigot().sendMessage(*response.create()) + sender.sendMessage(response) } else { - val response = ComponentBuilder("Currently running generation tasks:").color(ChatColor.WHITE).bold(true) + var response = chunkmaster.langManager.getLocalized("RUNNING_TASKS_HEADER") for (task in runningTasks) { - val genTask = task.generationTask - 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("${"%.1f".format(genTask.count)} chunks").color(ChatColor.BLUE) - .append(", ETA: ").color(ChatColor.WHITE) - .append("") - - if (genTask.stopAfter > 0) { - response.append(" (${(genTask.count.toDouble()/genTask.stopAfter.toDouble())*100}%).") - } + response += getGenerationEntry(task) } - sender.spigot().sendMessage(*response.create()) + sender.sendMessage(response) } return true } + + /** + * Returns the report string for one generation task + */ + private fun getGenerationEntry(task: TaskEntry): String { + val genTask = task.generationTask + val percentage = if (genTask.stopAfter > 0) + " (%.1f".format((genTask.count.toDouble()/genTask.stopAfter.toDouble())*100) + "%)." + else + "" + return "\n" + chunkmaster.langManager.getLocalized("TASKS_ENTRY", + task.id, genTask.world.name, genTask.count, percentage) + } } \ No newline at end of file diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdPause.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdPause.kt index 6e1d46c..c49cddc 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdPause.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdPause.kt @@ -22,15 +22,10 @@ class CmdPause(private val chunkmaster: Chunkmaster) : Subcommand { override fun execute(sender: CommandSender, args: List): Boolean { return if (!chunkmaster.generationManager.paused) { chunkmaster.generationManager.pauseAll() - sender.spigot().sendMessage( - *ComponentBuilder("Paused all generation tasks.") - .color(ChatColor.BLUE).create() - ) + sender.sendMessage(chunkmaster.langManager.getLocalized("PAUSE_SUCCESS")) true } else { - sender.spigot().sendMessage( - *ComponentBuilder("The generation process is already paused.").color(ChatColor.RED).create() - ) + sender.sendMessage(chunkmaster.langManager.getLocalized("ALREADY_PAUSED")) false } } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdReload.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdReload.kt index 91b6c81..4a38fa6 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdReload.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdReload.kt @@ -23,12 +23,11 @@ class CmdReload(private val chunkmaster: Chunkmaster): Subcommand { * Reload command to reload the config and restart the tasks. */ override fun execute(sender: CommandSender, args: List): Boolean { - sender.spigot().sendMessage(*ComponentBuilder("Reloading config and restarting tasks...") - .color(ChatColor.YELLOW).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("CONFIG_RELOADING")) chunkmaster.generationManager.stopAll() chunkmaster.reloadConfig() chunkmaster.generationManager.startAll() - sender.spigot().sendMessage(*ComponentBuilder("Config reload complete!").color(ChatColor.GREEN).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("CONFIG_RELOADED")) return true } } \ No newline at end of file diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdResume.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdResume.kt index c5beb9c..2d143f0 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdResume.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdResume.kt @@ -22,12 +22,10 @@ class CmdResume(private val chunkmaster: Chunkmaster): Subcommand { override fun execute(sender: CommandSender, args: List): Boolean { return if (chunkmaster.generationManager.paused) { chunkmaster.generationManager.resumeAll() - sender.spigot().sendMessage( - *ComponentBuilder("Resumed all generation tasks.").color(ChatColor.BLUE).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("RESUME_SUCCESS")) true } else { - sender.spigot().sendMessage( - *ComponentBuilder("There are no paused generation tasks.").color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("NOT_PAUSED")) false } } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdTpChunk.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdTpChunk.kt index 20d6c4d..8ffcb6d 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdTpChunk.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CmdTpChunk.kt @@ -3,13 +3,14 @@ package net.trivernis.chunkmaster.commands 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.lib.Subcommand import org.bukkit.Material import org.bukkit.command.Command import org.bukkit.command.CommandSender import org.bukkit.entity.Player -class CmdTpChunk: Subcommand { +class CmdTpChunk(private val chunkmaster: Chunkmaster): Subcommand { override val name = "tpchunk" override fun onTabComplete( @@ -37,15 +38,13 @@ class CmdTpChunk: Subcommand { } else { sender.teleport(location) } - sender.spigot().sendMessage(*ComponentBuilder("You have been teleportet to chunk") - .color(ChatColor.YELLOW).append("${args[0]}, ${args[1]}").color(ChatColor.BLUE).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("TELEPORTED", args[0], args[1])) return true } else { return false } } else { - sender.spigot().sendMessage(*ComponentBuilder("This command can only be executed by a player!") - .color(ChatColor.RED).create()) + sender.sendMessage(chunkmaster.langManager.getLocalized("TP_ONLY_PLAYER")) return false } } diff --git a/src/main/kotlin/net/trivernis/chunkmaster/commands/CommandChunkmaster.kt b/src/main/kotlin/net/trivernis/chunkmaster/commands/CommandChunkmaster.kt index a3072cc..bf05ce2 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/commands/CommandChunkmaster.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/commands/CommandChunkmaster.kt @@ -44,17 +44,11 @@ class CommandChunkmaster(private val chunkmaster: Chunkmaster, private val serve return if (commands.containsKey(args[0])) { commands[args[0]]!!.execute(sender, args.slice(1 until args.size)) } else { - sender.spigot().sendMessage( - *ComponentBuilder("Subcommand ").color(ChatColor.RED) - .append(args[0]).color(ChatColor.GREEN).append(" not found").color(ChatColor.RED).create() - ) + sender.sendMessage(chunkmaster.langManager.getLocalized("SUBCOMMAND_NOT_FOUND", args[0])) false } } else { - sender.spigot().sendMessage( - *ComponentBuilder("You do not have permission!") - .color(ChatColor.RED).create() - ) + sender.sendMessage(chunkmaster.langManager.getLocalized("NO_PERMISSION")) } return true } else { @@ -84,7 +78,7 @@ class CommandChunkmaster(private val chunkmaster: Chunkmaster, private val serve val cmdReload = CmdReload(chunkmaster) commands[cmdReload.name] = cmdReload - val cmdTpChunk = CmdTpChunk() + val cmdTpChunk = CmdTpChunk(chunkmaster) commands[cmdTpChunk.name] = cmdTpChunk } } \ No newline at end of file diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt index e72d2e5..da48546 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/LanguageManager.kt @@ -1,5 +1,6 @@ package net.trivernis.chunkmaster.lib import net.trivernis.chunkmaster.Chunkmaster +import java.io.BufferedReader import java.io.File import java.lang.Exception import java.util.Properties diff --git a/src/main/kotlin/net/trivernis/chunkmaster/lib/SqliteManager.kt b/src/main/kotlin/net/trivernis/chunkmaster/lib/SqliteManager.kt index d28db0b..507f97d 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/SqliteManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/SqliteManager.kt @@ -36,7 +36,7 @@ class SqliteManager(private val chunkmaster: Chunkmaster) { return DriverManager.getConnection("jdbc:sqlite:${chunkmaster.dataFolder.absolutePath}/" + "${chunkmaster.config.getString("database.filename")}") } catch (e: Exception) { - chunkmaster.logger.severe("Could not get database connection.") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("DATABASE_CONNECTION_ERROR")) chunkmaster.logger.severe(e.message) } return null @@ -92,13 +92,13 @@ class SqliteManager(private val chunkmaster: Chunkmaster) { } statement.close() } catch (e: Exception) { - chunkmaster.logger.severe("An error occured on sql $sql. ${e.message}") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("SQL_ERROR", e.message!!)) chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) } finally { connection.close() } } else { - chunkmaster.logger.severe("Could not execute sql $sql. No database connection established.") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("NO_DATABASE_CONNECTION")) } } @@ -114,10 +114,10 @@ class SqliteManager(private val chunkmaster: Chunkmaster) { tableDef += "${column.first} ${column.second}," } tableDef = tableDef.substringBeforeLast(",") + ");" - chunkmaster.logger.info("Creating table $table with definition $tableDef") + chunkmaster.logger.finest(chunkmaster.langManager.getLocalized("CREATE_TABLE_DEFINITION", table, tableDef)) executeStatement(tableDef, HashMap(), null) } catch (e: Exception) { - chunkmaster.logger.severe("Error creating table $table.") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("TABLE_CREATE_ERROR", table)) chunkmaster.logger.severe(e.message) chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) } @@ -126,9 +126,9 @@ class SqliteManager(private val chunkmaster: Chunkmaster) { val updateSql = "ALTER TABLE ${table.first} ADD COLUMN ${table.second.first} ${table.second.second}" try { executeStatement(updateSql, HashMap(), null) - chunkmaster.logger.info("Updated table ${table.first} with sql $updateSql") + chunkmaster.logger.finest(chunkmaster.langManager.getLocalized("UPDATE_TABLE_DEFINITION", table.first, updateSql)) } catch (e: Exception) { - chunkmaster.logger.severe("Failed to update table ${table.first} with sql $updateSql") + chunkmaster.logger.severe(chunkmaster.langManager.getLocalized("UPDATE_TABLE_FAILED", table.first, updateSql)) chunkmaster.logger.severe(e.message) chunkmaster.logger.info(ExceptionUtils.getStackTrace(e)) } diff --git a/src/main/resources/i18n/DEFAULT.i18n.properties b/src/main/resources/i18n/DEFAULT.i18n.properties index 0376e0b..f79da32 100644 --- a/src/main/resources/i18n/DEFAULT.i18n.properties +++ b/src/main/resources/i18n/DEFAULT.i18n.properties @@ -1,11 +1,48 @@ RESUME_FOR_WORLD = Resuming chunk generation task for world '%s'... TASK_FINISHED = Task #%d finished after %d chunks. -TASK_CANCELED = Canceled task #%d. -TASK_LOAD_FAILED = Failed to load task #%d. +TASK_CANCELED = Canceled task #%s. +TASK_LOAD_FAILED = \u00A7cFailed to load task #%d. TASK_LOAD_SUCCESS = %d saved tasks loaded. -TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d -TASK_SAVE_FAILED = Exception when saving tasks: %s +TASK_NOT_FOUND = \u00A7cTask %s not found! CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_SAVE_FAILED = \u00A7cException when saving tasks: %s WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name! -TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! \ No newline at end of file +WORLD_NOT_FOUND = \u00A7cWorld \u00A72%s \u00A7cnot found! +TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! +TASK_CREATION_SUCCESS = \u00A79Generation Task for world \u00A72%s \u00A79 until \u00A72%s \u00A79successfully created! +TASK_ID_REQUIRED = \u00A7cYou need to provide a task id! + +PAUSED_TASKS_HEADER = Currently Paused Generation Tasks +TASKS_ENTRY = - \u00A79#%d\u00A7r - \u00A72%s\u00A7r - \u00A72%d chunks %s\u00A7r +RUNNING_TASKS_HEADER = Currently Running Generation Tasks +NO_GENERATION_TASKS = There are no generation tasks. + +PAUSE_SUCCESS = \u00A79Paused all generation tasks. +ALREADY_PAUSED = \u00A7cThe generation process is already paused! + +RESUME_SUCCESS = \u00A79Resumed all generation Tasks. +NOT_PAUSED = \u00A7cThe generation process is not paused! + +CONFIG_RELOADING = Reloading the config file... +CONFIG_RELOADED = \u00A72The config file has been reloaded! + +TELEPORTED = \u00A79You have been teleported to chunk \u00A72%s, %s +TP_ONLY_PLAYER = \u00A7cThis command can only be executed by a player! + +NO_PERMISSION = \u00A7cYou do not have the permission for this command! +SUBCOMMAND_NOT_FOUND = \u00A7cSubcommand \u00A72%s \u00A7cnot found! + +STOPPING_ALL_TASKS = Stopping all generation tasks... +DB_INIT = Initializing database... +DB_INIT_FINISHED = Database fully initialized. +DB_INIT_EROR = Failed to init database: %s. + +DATABASE_CONNECTION_ERROR = \u00A7cCould not get the database connection! +SQL_ERROR = \u00A7cAn eror occured on sql %s! +NO_DATABASE_CONNECTION = \u00A7cCould not execute sql: No database connection. +CREATE_TABLE_DEFINITION = Created table %s with definition %s. +TABLE_CREATE_ERROR = \u00A7cError when creation table %s. +UPDATE_TABLE_DEFINITION = Updated table %s with sql %s. +UPDATE_TABLE_FAILED = Failed to update table %s with sql %s. \ 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 4d55794..14aa4d3 100644 --- a/src/main/resources/i18n/de.i18n.properties +++ b/src/main/resources/i18n/de.i18n.properties @@ -1,11 +1,48 @@ -RESUME_FOR_WORLD = Setze das Chunk-Generieren für Welt '%s' fort... +RESUME_FOR_WORLD = Setze das Chunk-Generieren f\u00fcr Welt '%s' fort... TASK_FINISHED = Aufgabe #%d wurde nach %d chunks beendet. -TASK_CANCELED = Aufgabe #%d wurde abgebrochen. -TASK_LOAD_FAILED = Aufgabe #%d konnte nicht geladen werden. +TASK_CANCELED = Aufgabe #%s wurde abgebrochen. +TASK_LOAD_FAILED = \u00A7cAufgabe #%d konnte nicht geladen werden. TASK_LOAD_SUCCESS = %d gespeicherte Aufgaben wurden geladen. -CREATE_DELAYED_LOAD = Erstelle einen Bukkit-Task zum verzögerten Laden von Aufgaben... -TASK_PERIODIC_REPORT = Aufgabe #%d für Welt '%s'. Fortschritt: %d chunks %s, Geschwindigkeit: %.1f ch/s, Letzer Chunk: %d, %d -TASK_SAVE_FAILED = Exception beim Speichern der Aufgaben: %s +TASK_NOT_FOUND = \u00A7cAufgabe %s konnte nicht gefunden werden! +CREATE_DELAYED_LOAD = Erstelle einen Bukkit-Task zum verz\u00f6gerten Laden von Aufgaben... +TASK_PERIODIC_REPORT = Aufgabe #%d f\u00fcr Welt '%s'. Fortschritt: %d chunks %s, Geschwindigkeit: %.1f ch/s, Letzer Chunk: %d, %d +TASK_SAVE_FAILED = \u00A7cFehler beim Speichern der Aufgaben: %s WORLD_NAME_REQUIRED = \u00A7cDu musst einen Weltennamen angeben! -TASK_ALREADY_EXISTS = \u00A7cEs existiert bereits eine Aufgabe für '%s'! \ No newline at end of file +WORLD_NOT_FOUND = \u00A7c Die Welt \u00A72%s \u00A7cwurde nicht gefunden! +TASK_ALREADY_EXISTS = \u00A7cEs existiert bereits eine Aufgabe f\u00fcr \u00A72%s\u00A7c! +TASK_CREATION_SUCCESS = \u00A79Generierungs-Aufgabe \u00A72%s \u00A79 bis \u00A72%s \u00A79wurde erfolgreich erstellt! +TASK_ID_REQUIRED = \u00A7cDu musst eine Aufgaben-Id angeben! + +PAUSED_TASKS_HEADER = \u00A7lPausierte Generierungsaufgaben\u00A7r + +RUNNING_TASKS_HEADER = \u00A7lLaufende Generierungsaufgaben\u00A7r +NO_GENERATION_TASKS = Es gibt keine Aufgaben. + +PAUSE_SUCCESS = \u00A79Alle Aufgaben wurden pausiert. +ALREADY_PAUSED = \u00A7cDas Generieren ist bereits pausiert. + +RESUME_SUCCESS = \u00A79Alle Aufgaben wurden fortgesetzt. +NOT_PAUSED = \u00A7cEs gibt keine pausierten Aufgaben! + +CONFIG_RELOADING = Die Konfigurationsdatei wird neu eingelesen... +CONFIG_RELOADED = \u00A72Die Konfigurationsdatei wurde neu geladen! + +TELEPORTED = \u00A79Du wurdest zum Chunk \u00A72%s, %s \u00A79teleportiert +TP_ONLY_PLAYER = \u00A7cDieser Befehl kann nur von einem Spieler ausgef\u00fchrt werden. + +NO_PERMISSION = \u00A7cDu hast nicht die Rechte für diesen Befehl! +SUBCOMMAND_NOT_FOUND = \u00A7cUnteraktion \u00A72%s \u00A7cwurde nicht gefunden! + +STOPPING_ALL_TASKS = Stoppt alle Aufgaben... +DB_INIT = Initialisiere Datenbank... +DB_INIT_FINISHED = Die Datenbank wurde initialisiert. +DB_INIT_EROR = Fehler beim Initalisieren der Datenbank: %s. + +DATABASE_CONNECTION_ERROR = \u00A7cDie Datenbankverbindung konnte nicht erzeugt werden. +SQL_ERROR = \u00A7cEin Fehler trat mit sql %s auf! +NO_DATABASE_CONNECTION = \u00A7cSql konnte nicht ausgef\u00fchrt werden: Keine Datenbankverbindung. +CREATE_TABLE_DEFINITION = Tabelle %s mit Definition %s wurde erstellt. +TABLE_CREATE_ERROR = \u00A7cFehler 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. \ 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 0376e0b..c13d3b1 100644 --- a/src/main/resources/i18n/en.i18n.properties +++ b/src/main/resources/i18n/en.i18n.properties @@ -1,11 +1,19 @@ RESUME_FOR_WORLD = Resuming chunk generation task for world '%s'... TASK_FINISHED = Task #%d finished after %d chunks. TASK_CANCELED = Canceled task #%d. -TASK_LOAD_FAILED = Failed to load task #%d. +TASK_LOAD_FAILED = \u00A7cFailed to load task #%d. TASK_LOAD_SUCCESS = %d saved tasks loaded. -TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d -TASK_SAVE_FAILED = Exception when saving tasks: %s +TASK_NOT_FOUND = \u00A7cTask %d not found! CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_SAVE_FAILED = \u00A7cException when saving tasks: %s WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name! -TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! \ No newline at end of file +WORLD_NOT_FOUND = \u00A7cWorld \u00A72%s \u00A7cnot found! +TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! +TASK_CREATION_SUCCESS = \u00A79Generation Task for world \u00A72%s \u00A79 until \u00A72%s \u00A79successfully created! +TASK_ID_REQUIRED = \u00A7cYou need to provide a task id! +PAUSED_TASKS_HEADER = Currently Paused Generation Tasks +TASKS_ENTRY = - \u00A79#%d\u00A7r - \u00A72%s\u00A7r - \u00A72%d chunks %s\u00A7r +RUNNING_TASKS_HEADER = Currently Running Generation Tasks +NO_GENERATION_TASKS = There are no generation tasks. \ No newline at end of file From 3d8c47aee26d6ba3c264c6ad03f1ee63affbdcba Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 5 Feb 2020 16:34:35 +0100 Subject: [PATCH 5/6] Update english i18n --- src/main/resources/i18n/en.i18n.properties | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/main/resources/i18n/en.i18n.properties b/src/main/resources/i18n/en.i18n.properties index c13d3b1..f79da32 100644 --- a/src/main/resources/i18n/en.i18n.properties +++ b/src/main/resources/i18n/en.i18n.properties @@ -1,9 +1,9 @@ RESUME_FOR_WORLD = Resuming chunk generation task for world '%s'... TASK_FINISHED = Task #%d finished after %d chunks. -TASK_CANCELED = Canceled task #%d. +TASK_CANCELED = Canceled task #%s. TASK_LOAD_FAILED = \u00A7cFailed to load task #%d. TASK_LOAD_SUCCESS = %d saved tasks loaded. -TASK_NOT_FOUND = \u00A7cTask %d not found! +TASK_NOT_FOUND = \u00A7cTask %s not found! CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d TASK_SAVE_FAILED = \u00A7cException when saving tasks: %s @@ -13,7 +13,36 @@ WORLD_NOT_FOUND = \u00A7cWorld \u00A72%s \u00A7cnot found! TASK_ALREADY_EXISTS = \u00A7cA task for '%s' already exists! TASK_CREATION_SUCCESS = \u00A79Generation Task for world \u00A72%s \u00A79 until \u00A72%s \u00A79successfully created! TASK_ID_REQUIRED = \u00A7cYou need to provide a task id! + PAUSED_TASKS_HEADER = Currently Paused Generation Tasks TASKS_ENTRY = - \u00A79#%d\u00A7r - \u00A72%s\u00A7r - \u00A72%d chunks %s\u00A7r RUNNING_TASKS_HEADER = Currently Running Generation Tasks -NO_GENERATION_TASKS = There are no generation tasks. \ No newline at end of file +NO_GENERATION_TASKS = There are no generation tasks. + +PAUSE_SUCCESS = \u00A79Paused all generation tasks. +ALREADY_PAUSED = \u00A7cThe generation process is already paused! + +RESUME_SUCCESS = \u00A79Resumed all generation Tasks. +NOT_PAUSED = \u00A7cThe generation process is not paused! + +CONFIG_RELOADING = Reloading the config file... +CONFIG_RELOADED = \u00A72The config file has been reloaded! + +TELEPORTED = \u00A79You have been teleported to chunk \u00A72%s, %s +TP_ONLY_PLAYER = \u00A7cThis command can only be executed by a player! + +NO_PERMISSION = \u00A7cYou do not have the permission for this command! +SUBCOMMAND_NOT_FOUND = \u00A7cSubcommand \u00A72%s \u00A7cnot found! + +STOPPING_ALL_TASKS = Stopping all generation tasks... +DB_INIT = Initializing database... +DB_INIT_FINISHED = Database fully initialized. +DB_INIT_EROR = Failed to init database: %s. + +DATABASE_CONNECTION_ERROR = \u00A7cCould not get the database connection! +SQL_ERROR = \u00A7cAn eror occured on sql %s! +NO_DATABASE_CONNECTION = \u00A7cCould not execute sql: No database connection. +CREATE_TABLE_DEFINITION = Created table %s with definition %s. +TABLE_CREATE_ERROR = \u00A7cError when creation table %s. +UPDATE_TABLE_DEFINITION = Updated table %s with sql %s. +UPDATE_TABLE_FAILED = Failed to update table %s with sql %s. \ No newline at end of file From a4115ebdf76e342fbe5a24c1739f71c57a95ee3e Mon Sep 17 00:00:00 2001 From: Trivernis Date: Wed, 5 Feb 2020 17:31:33 +0100 Subject: [PATCH 6/6] Add ETA to periodic reports Closes #17 --- .../lib/generation/GenerationManager.kt | 14 +++++++++++++- src/main/resources/i18n/DEFAULT.i18n.properties | 2 +- src/main/resources/i18n/de.i18n.properties | 2 +- src/main/resources/i18n/en.i18n.properties | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) 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 81b69ab..b9e0bfb 100644 --- a/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt +++ b/src/main/kotlin/net/trivernis/chunkmaster/lib/generation/GenerationManager.kt @@ -215,16 +215,28 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server for (task in tasks) { try { val genTask = task.generationTask + val speed = task.generationSpeed!! val percentage = if (genTask.stopAfter > 0) "(${"%.2f".format( (genTask.count.toDouble() / genTask.stopAfter.toDouble()) * 100 )}%)" else "" + val eta = if (genTask.stopAfter > 0 && speed > 0) { + val etaSeconds = (genTask.stopAfter - genTask.count).toDouble()/speed + chunkmaster.logger.info(""+etaSeconds) + val hours: Int = (etaSeconds/3600).toInt() + val minutes: Int = ((etaSeconds % 3600) / 60).toInt() + val seconds: Int = (etaSeconds % 60).toInt() + ", ETA: %d:%02d:%02d".format(hours, minutes, seconds) + } else { + "" + } chunkmaster.logger.info(chunkmaster.langManager.getLocalized( "TASK_PERIODIC_REPORT", task.id, genTask.world.name, genTask.count, percentage, - task.generationSpeed!!, + eta, + speed, genTask.lastChunk.x, genTask.lastChunk.z)) chunkmaster.sqliteManager.executeStatement( diff --git a/src/main/resources/i18n/DEFAULT.i18n.properties b/src/main/resources/i18n/DEFAULT.i18n.properties index f79da32..e0771de 100644 --- a/src/main/resources/i18n/DEFAULT.i18n.properties +++ b/src/main/resources/i18n/DEFAULT.i18n.properties @@ -5,7 +5,7 @@ TASK_LOAD_FAILED = \u00A7cFailed to load task #%d. TASK_LOAD_SUCCESS = %d saved tasks loaded. TASK_NOT_FOUND = \u00A7cTask %s not found! CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... -TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s %s, Speed: %.1f ch/s, Last Chunk: %d, %d TASK_SAVE_FAILED = \u00A7cException when saving tasks: %s WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name! diff --git a/src/main/resources/i18n/de.i18n.properties b/src/main/resources/i18n/de.i18n.properties index 14aa4d3..e1ee078 100644 --- a/src/main/resources/i18n/de.i18n.properties +++ b/src/main/resources/i18n/de.i18n.properties @@ -5,7 +5,7 @@ TASK_LOAD_FAILED = \u00A7cAufgabe #%d konnte nicht geladen werden. TASK_LOAD_SUCCESS = %d gespeicherte Aufgaben wurden geladen. TASK_NOT_FOUND = \u00A7cAufgabe %s konnte nicht gefunden werden! CREATE_DELAYED_LOAD = Erstelle einen Bukkit-Task zum verz\u00f6gerten Laden von Aufgaben... -TASK_PERIODIC_REPORT = Aufgabe #%d f\u00fcr Welt '%s'. Fortschritt: %d chunks %s, Geschwindigkeit: %.1f ch/s, Letzer Chunk: %d, %d +TASK_PERIODIC_REPORT = Aufgabe #%d f\u00fcr Welt '%s'. Fortschritt: %d chunks %s %s, Geschwindigkeit: %.1f ch/s, Letzer Chunk: %d, %d TASK_SAVE_FAILED = \u00A7cFehler beim Speichern der Aufgaben: %s WORLD_NAME_REQUIRED = \u00A7cDu musst einen Weltennamen angeben! diff --git a/src/main/resources/i18n/en.i18n.properties b/src/main/resources/i18n/en.i18n.properties index f79da32..e0771de 100644 --- a/src/main/resources/i18n/en.i18n.properties +++ b/src/main/resources/i18n/en.i18n.properties @@ -5,7 +5,7 @@ TASK_LOAD_FAILED = \u00A7cFailed to load task #%d. TASK_LOAD_SUCCESS = %d saved tasks loaded. TASK_NOT_FOUND = \u00A7cTask %s not found! CREATE_DELAYED_LOAD = Creating task to load chunk generation Tasks later... -TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s, Speed: %.1f ch/s, Last Chunk: %d, %d +TASK_PERIODIC_REPORT = Task #%d running for '%s'. Progress: %d chunks %s %s, Speed: %.1f ch/s, Last Chunk: %d, %d TASK_SAVE_FAILED = \u00A7cException when saving tasks: %s WORLD_NAME_REQUIRED = \u00A7cYou need to provide a world name!