Add i18n to generation manager

pull/20/head
trivernis 5 years ago
parent 900600714e
commit bd731c85f0

@ -74,7 +74,7 @@ class Chunkmaster: JavaPlugin() {
config.addDefault("generation.max-loaded-chunks", 10) config.addDefault("generation.max-loaded-chunks", 10)
config.addDefault("generation.ignore-worldborder", false) config.addDefault("generation.ignore-worldborder", false)
config.addDefault("database.filename", "chunkmaster.db") config.addDefault("database.filename", "chunkmaster.db")
config.addDefault("language", "EN") config.addDefault("language", "en")
config.options().copyDefaults(true) config.options().copyDefaults(true)
saveConfig() saveConfig()
} }

@ -79,8 +79,7 @@ class CmdGenerate(private val chunkmaster: Chunkmaster): Subcommand {
stopAfter = getStopAfter(stopAfter, args[2]) stopAfter = getStopAfter(stopAfter, args[2])
} }
} else { } else {
sender.spigot().sendMessage( sender.sendMessage(chunkmaster.langManager.getLocalized("WORLD_NAME_REQUIRED"))
*ComponentBuilder("You need to provide a world name").color(ChatColor.RED).create())
return false 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()) .append(worldName).color(ChatColor.GREEN).append(" not found!").color(ChatColor.RED).create())
false false
} else { } else {
sender.spigot().sendMessage(*ComponentBuilder("Task already exists!").color(ChatColor.RED).create()) sender.sendMessage(chunkmaster.langManager.getLocalized("TASK_ALREADY_EXISTS", worldName))
return false return false
} }
} }

@ -3,19 +3,23 @@ import net.trivernis.chunkmaster.Chunkmaster
import java.io.File import java.io.File
import java.lang.Exception import java.lang.Exception
import java.util.Properties import java.util.Properties
import java.util.logging.Level
class LanguageManager(private val plugin: Chunkmaster) { class LanguageManager(private val plugin: Chunkmaster) {
private val langProps = Properties() private val langProps = Properties()
private val languageFolder = "${plugin.dataFolder.absolutePath}/i18n" private val languageFolder = "${plugin.dataFolder.absolutePath}/i18n"
private var langFileLoaded = false 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() { fun loadProperties() {
val language = plugin.config.getString("language") val language = plugin.config.getString("language")
val langFile = "$languageFolder/$language.i18n.properties" val langFile = "$languageFolder/$language.i18n.properties"
val file = File(langFile) val file = File(langFile)
val loader = Thread.currentThread().contextClassLoader 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) { if (defaultStream != null) {
langProps.load(defaultStream) langProps.load(defaultStream)
defaultStream.close() defaultStream.close()
@ -34,12 +38,23 @@ class LanguageManager(private val plugin: Chunkmaster) {
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())
} }
} else {
val inputStream = this.javaClass.getResourceAsStream("/i18n/$language.i18n.properties")
if (inputStream != null) {
langProps.load(inputStream)
langFileLoaded = true
inputStream.close()
} else { } else {
plugin.logger.warning("Language File $langFile could not be found!") 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)
} }
} }

@ -55,7 +55,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
} }
generationTask.onEndReached { 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) removeTask(id)
} }
@ -86,7 +86,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
stopAfter: Int = -1 stopAfter: Int = -1
) { ) {
if (!paused) { 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 generationTask = createGenerationTask(world, center, last, stopAfter)
val task = server.scheduler.runTaskTimer( val task = server.scheduler.runTaskTimer(
chunkmaster, generationTask, 200, // 10 sec delay 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)) tasks.add(RunningTaskEntry(id, task, generationTask))
generationTask.onEndReached { 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) removeTask(id)
} }
} }
@ -134,7 +134,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
* Loads tasks from the database and resumes them * Loads tasks from the database and resumes them
*/ */
fun init() { 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 { server.scheduler.runTaskTimer(chunkmaster, Runnable {
saveProgress() // save progress every 30 seconds saveProgress() // save progress every 30 seconds
}, 600, 600) }, 600, 600)
@ -157,7 +157,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
if (task.task.isCancelled) { if (task.task.isCancelled) {
removalSet.add(task) removalSet.add(task)
} }
chunkmaster.logger.info("Canceled task #${task.id}") chunkmaster.logger.info(chunkmaster.langManager.getLocalized("TASK_CANCELED", task.id))
} }
tasks.removeAll(removalSet) tasks.removeAll(removalSet)
} }
@ -178,13 +178,13 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
resumeTask(world!!, center, last, id, stopAfter) resumeTask(world!!, center, last, id, stopAfter)
} }
} catch (error: NullPointerException) { } 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()) { 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) { for (task in tasks) {
try { try {
val genTask = task.generationTask val genTask = task.generationTask
chunkmaster.logger.info( val percentage = if (genTask.stopAfter > 0) "(${"%.2f".format(
"""Task #${task.id} running for "${genTask.world.name}". (genTask.count.toDouble() / genTask.stopAfter.toDouble()) * 100
|Progress ${task.generationTask.count} chunks )}%)" else ""
|${if (task.generationTask.stopAfter > 0) "(${"%.2f".format( chunkmaster.logger.info(chunkmaster.langManager.getLocalized(
(task.generationTask.count.toDouble() / "TASK_PERIODIC_REPORT",
task.generationTask.stopAfter.toDouble()) * 100 task.id,
)}%)" else ""}. genTask.world.name,
| Speed: ${"%.1f".format(task.generationSpeed)} chunks/sec, genTask.count,
|Last Chunk: ${genTask.lastChunk.x}, ${genTask.lastChunk.z}""".trimMargin("|").replace('\n', ' ') percentage,
) task.generationSpeed!!,
genTask.lastChunk.x,
genTask.lastChunk.z))
chunkmaster.sqliteManager.executeStatement( chunkmaster.sqliteManager.executeStatement(
""" """
UPDATE generation_tasks SET last_x = ?, last_z = ? UPDATE generation_tasks SET last_x = ?, last_z = ?
@ -234,7 +236,7 @@ class GenerationManager(private val chunkmaster: Chunkmaster, private val server
null null
) )
} catch (error: Exception) { } catch (error: Exception) {
chunkmaster.logger.warning("Exception when saving task progress ${error.message}") chunkmaster.logger.warning(chunkmaster.langManager.getLocalized("TASK_SAVE_FAILED", error.toString()))
} }
} }
} }

@ -4,13 +4,11 @@ import net.trivernis.chunkmaster.Chunkmaster
import net.trivernis.chunkmaster.lib.Spiral import net.trivernis.chunkmaster.lib.Spiral
import org.bukkit.Chunk import org.bukkit.Chunk
import org.bukkit.World import org.bukkit.World
/** /**
* Interface for generation tasks. * Interface for generation tasks.
*/ */
abstract class GenerationTask(plugin: Chunkmaster, centerChunk: ChunkCoordinates, startChunk: ChunkCoordinates) : abstract class GenerationTask(plugin: Chunkmaster, centerChunk: ChunkCoordinates, startChunk: ChunkCoordinates) :
Runnable { Runnable {
abstract val stopAfter: Int abstract val stopAfter: Int
abstract val world: World abstract val world: World
abstract val count: Int abstract val count: Int

@ -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!

@ -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'!

@ -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!
Loading…
Cancel
Save