text: json fallback translation key

This commit is contained in:
Bixilon 2023-03-18 13:34:50 +01:00
parent c8318fceaf
commit 660aae38d4
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
16 changed files with 48 additions and 78 deletions

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -14,7 +14,6 @@
package de.bixilon.minosoft.data.chat.message
import de.bixilon.minosoft.data.chat.ChatUtil
import de.bixilon.minosoft.data.language.lang.Language
import de.bixilon.minosoft.data.registries.chat.ChatMessageType
import de.bixilon.minosoft.data.registries.chat.ChatParameter
import de.bixilon.minosoft.data.text.ChatComponent
@ -32,11 +31,7 @@ FormattedChatMessage(
init {
// ToDo: parent (formatting)
val data = type.chat.formatParameters(parameters)
text = if (connection.language.canTranslate(type.chat.translationKey.toResourceLocation())) {
connection.language.translate(type.chat.translationKey.toResourceLocation(), restrictedMode = true, data = data)
} else {
Language.translate(type.chat.translationKey, restrictedMode = true, data = data)
}
text = connection.language.forceTranslate(type.chat.translationKey.toResourceLocation(), restrictedMode = true, fallback = type.chat.translationKey, data = data)
text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR)
}
}

View File

@ -99,10 +99,7 @@ class ItemStack {
if (item._count <= 0) {
return false
}
if (_durability?._valid == false) {
return false
}
return true
return _durability?._valid != false
}
val rarity: Rarities
@ -128,7 +125,7 @@ class ItemStack {
_display?.customDisplayName?.let { return it }
item.item.translationKey.let {
val language = holder?.connection?.language ?: return@let
val translated = language.translate(it)
val translated = language.forceTranslate(it)
rarity.color.let { color -> translated.setFallbackColor(color) }
return translated
}

View File

@ -12,7 +12,6 @@
*/
package de.bixilon.minosoft.data.language.lang
import de.bixilon.minosoft.data.language.LanguageUtil
import de.bixilon.minosoft.data.language.translate.Translator
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.BaseComponent
@ -24,12 +23,8 @@ class Language(
private val data: LanguageData,
) : Translator {
override fun canTranslate(key: ResourceLocation?): Boolean {
return data.containsKey(key?.path)
}
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent {
val placeholder = this.data[key?.path] ?: return LanguageUtil.getFallbackTranslation(key, parent, restrictedMode, *data)
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent? {
val placeholder = this.data[key?.path] ?: return null
return Companion.translate(placeholder, parent, this, restrictedMode, *data)
}

View File

@ -13,7 +13,6 @@
package de.bixilon.minosoft.data.language.lang
import de.bixilon.minosoft.data.language.LanguageUtil
import de.bixilon.minosoft.data.language.translate.Translator
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
@ -23,21 +22,10 @@ class LanguageList(
private val list: MutableList<Language>,
) : Translator {
override fun canTranslate(key: ResourceLocation?): Boolean {
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent? {
for (language in list) {
if (language.canTranslate(key)) {
return true
}
return language.translate(key, parent, restrictedMode, data) ?: continue
}
return false
}
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent {
for (language in list) {
if (language.canTranslate(key)) {
return language.translate(key, parent, restrictedMode, data)
}
}
return LanguageUtil.getFallbackTranslation(key, parent, restrictedMode, data)
return null
}
}

View File

@ -14,7 +14,6 @@
package de.bixilon.minosoft.data.language.manager
import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
import de.bixilon.minosoft.data.language.LanguageUtil
import de.bixilon.minosoft.data.language.translate.Translator
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
@ -24,22 +23,11 @@ class LanguageManager(
private val languages: MutableList<Translator> = synchronizedListOf(),
) : Translator {
override fun canTranslate(key: ResourceLocation?): Boolean {
for (language in languages) {
if (language.canTranslate(key)) {
return true
}
}
return false
}
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent {
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent? {
for (language in languages) {
if (!language.canTranslate(key)) {
continue
}
return language.translate(key, parent, restrictedMode, *data)
return language.translate(key, parent, restrictedMode, *data) ?: continue
}
return LanguageUtil.getFallbackTranslation(key, parent, restrictedMode, data)
return null
}
}

View File

@ -22,14 +22,9 @@ class MultiLanguageManager(
val translators: MutableMap<String, Translator> = mutableMapOf(),
) : Translator {
override fun canTranslate(key: ResourceLocation?): Boolean {
key ?: return false
return translators[key.namespace]?.canTranslate(key) == true
}
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent? {
if (key == null) return null
override fun translate(key: ResourceLocation?, parent: TextComponent?, restrictedMode: Boolean, vararg data: Any?): ChatComponent {
key ?: return ChatComponent.of("null: ${data.contentToString()}", restrictedMode = restrictedMode)
return translators[key.namespace]?.translate(key, parent, restrictedMode, *data) ?: ChatComponent.of("$key: ${data.contentToString()}", restrictedMode = restrictedMode)
return translators[key.namespace]?.translate(key, parent, restrictedMode, *data)
}
}

View File

@ -13,22 +13,34 @@
package de.bixilon.minosoft.data.language.translate
import de.bixilon.minosoft.data.language.LanguageUtil
import de.bixilon.minosoft.data.language.lang.Language
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
interface Translator {
fun canTranslate(key: ResourceLocation?): Boolean
fun forceTranslate(key: ResourceLocation?, vararg data: Any?): ChatComponent {
return forceTranslate(key, null, false, null, *data)
}
fun translate(key: ResourceLocation?, parent: TextComponent? = null, vararg data: Any?): ChatComponent = translate(key, parent, false, *data)
fun translate(key: ResourceLocation?, parent: TextComponent? = null, restrictedMode: Boolean = false, vararg data: Any?): ChatComponent
fun forceTranslate(key: ResourceLocation?, parent: TextComponent? = null, restrictedMode: Boolean = false, fallback: String? = null, vararg data: Any?): ChatComponent {
translate(key, parent, restrictedMode, *data)?.let { return it }
if (fallback != null) {
return Language.translate(fallback, parent, null, restrictedMode)
}
return LanguageUtil.getFallbackTranslation(key, parent, restrictedMode, data)
}
fun translate(key: ResourceLocation?, parent: TextComponent? = null, vararg data: Any?): ChatComponent? = translate(key, parent, false, *data)
fun translate(key: ResourceLocation?, parent: TextComponent? = null, restrictedMode: Boolean = false, vararg data: Any?): ChatComponent?
fun translate(translatable: Any?): ChatComponent {
return when (translatable) {
is ChatComponent -> translatable
is Translatable -> translate(translatable.translationKey)
is Translatable -> forceTranslate(translatable.translationKey)
else -> ChatComponent.of(translatable)
}
}

View File

@ -96,8 +96,8 @@ class BaseComponent : ChatComponent {
with.add(part ?: continue)
}
}
// TODO: 1.19.4 added a "fallback" field
this += translator?.translate(it.toResourceLocation(), component, restrictedMode, *with.toTypedArray()) ?: ChatComponent.of(json["with"], translator, component, restrictedMode)
val fallback = json["fallback"]?.toString()
this += translator?.forceTranslate(it.toResourceLocation(), component, restrictedMode, fallback, *with.toTypedArray()) ?: ChatComponent.of(json["with"], translator, component, restrictedMode)
}
}
@ -247,7 +247,7 @@ class BaseComponent : ChatComponent {
}
pointer -= length
}
throw IllegalArgumentException("Pointer ot of bounds!")
throw IllegalArgumentException("Pointer out of bounds!")
}
override fun trim(): ChatComponent? {

View File

@ -101,7 +101,7 @@ interface ChatComponent {
return raw
}
if (raw is Translatable && raw !is ResourceLocation) {
return (translator ?: Minosoft.LANGUAGE_MANAGER).translate(raw.translationKey, parent, restrictedMode = restrictedMode)
return (translator ?: Minosoft.LANGUAGE_MANAGER).forceTranslate(raw.translationKey, parent, restrictedMode = restrictedMode)
}
when (raw) {

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -27,8 +27,8 @@ object TranslatableComponents {
val GENERAL_EXIT = "minosoft:general.exit".toResourceLocation()
val GENERAL_REFRESH = "minosoft:general.refresh".toResourceLocation()
val EROS_DELETE_SERVER_CONFIRM_DESCRIPTION = { name: ChatComponent, address: String -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:server_info.delete.dialog.description".toResourceLocation(), null, name, address) }
val ACCOUNT_CARD_CONNECTION_COUNT = { count: Int -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:main.account.card.connection_count".toResourceLocation(), null, count) }
val CONNECTION_KICK_DESCRIPTION = { server: AbstractServer, account: Account -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:connection.kick.description".toResourceLocation(), null, server.name, account.username) }
val CONNECTION_LOGIN_KICK_DESCRIPTION = { server: AbstractServer, account: Account -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:connection.login_kick.description".toResourceLocation(), null, server.name, account.username) }
val EROS_DELETE_SERVER_CONFIRM_DESCRIPTION = { name: ChatComponent, address: String -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:server_info.delete.dialog.description".toResourceLocation(), null, null, name, address) }
val ACCOUNT_CARD_CONNECTION_COUNT = { count: Int -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:main.account.card.connection_count".toResourceLocation(), null, null, count) }
val CONNECTION_KICK_DESCRIPTION = { server: AbstractServer, account: Account -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:connection.kick.description".toResourceLocation(), null, null, server.name, account.username) }
val CONNECTION_LOGIN_KICK_DESCRIPTION = { server: AbstractServer, account: Account -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:connection.login_kick.description".toResourceLocation(), null, null, server.name, account.username) }
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -66,7 +66,7 @@ class ErosErrorReport : DialogController() {
companion object {
private val LAYOUT = "minosoft:eros/dialog/error.fxml".toResourceLocation()
private val TITLE = { exception: Throwable? -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:error.title".toResourceLocation(), null, exception?.let { it::class.java.realName }) }
private val TITLE = { exception: Throwable? -> Minosoft.LANGUAGE_MANAGER.forceTranslate("minosoft:error.title".toResourceLocation(), null, false, exception?.let { it::class.java.realName }) }
private val HEADER = "minosoft:error.header".toResourceLocation()
private val DESCRIPTION = "minosoft:error.description".toResourceLocation()
private val FATAL_CRASH = "minosoft:error.fatal_crash".toResourceLocation()

View File

@ -139,7 +139,7 @@ class ServerModifyDialog(
version ?: return
text = if (version == Versions.AUTOMATIC) {
Minosoft.LANGUAGE_MANAGER.translate(VERSION_AUTOMATIC).message
Minosoft.LANGUAGE_MANAGER.forceTranslate(VERSION_AUTOMATIC).message
} else {
"${version.name} (${version.type.name.lowercase()})"
}

View File

@ -41,7 +41,7 @@ class InfoPane<T>(vararg children: Node) : AnchorPane(*children) {
for ((key, property) in properties) {
val propertyValue = property(item) ?: continue
propertiesPane.add(Minosoft.LANGUAGE_MANAGER.translate(key).textFlow, 0, row)
propertiesPane.add(Minosoft.LANGUAGE_MANAGER.forceTranslate(key).textFlow, 0, row)
propertiesPane.add(propertyValue.format().textFlow, 1, row++)
}
}

View File

@ -183,7 +183,7 @@ class AccountController : EmbeddedJavaFXController<Pane>() {
for ((key, property) in ACCOUNT_INFO_PROPERTIES.extend(accountTypeListViewFX.selectionModel.selectedItem.additionalDetails)) { // ToDo
val propertyValue = property(account) ?: continue
it.add(Minosoft.LANGUAGE_MANAGER.translate(key).textFlow, 0, row)
it.add(Minosoft.LANGUAGE_MANAGER.forceTranslate(key).textFlow, 0, row)
it.add(ChatComponent.of(propertyValue).textFlow, 1, row++)
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -108,7 +108,7 @@ class MicrosoftAddController(
companion object {
private val LAYOUT = "minosoft:eros/main/account/add/microsoft.fxml".toResourceLocation()
private val TITLE = "minosoft:main.account.add.microsoft.title".toResourceLocation()
private val HEADER = { link: URL -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:main.account.add.microsoft.header".toResourceLocation(), null, link) }
private val HEADER = { link: URL -> Minosoft.LANGUAGE_MANAGER.translate("minosoft:main.account.add.microsoft.header".toResourceLocation(), null, null, link) }
private val CANCEL = "minosoft:main.account.add.microsoft.cancel".toResourceLocation()
}
}

View File

@ -52,7 +52,7 @@ abstract class WawlaElement(protected val wawla: WawlaHUDElement) : Element(wawl
}
protected fun createNameElement(translationKey: ResourceLocation?): TextElement {
val name = wawla.context.connection.language.translate(translationKey)
val name = wawla.context.connection.language.forceTranslate(translationKey)
name.setFallbackColor(ChatColors.WHITE)
return TextElement(guiRenderer, name, background = false, scale = 1.2f)
}