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 * 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. * 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 package de.bixilon.minosoft.data.chat.message
import de.bixilon.minosoft.data.chat.ChatUtil 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.ChatMessageType
import de.bixilon.minosoft.data.registries.chat.ChatParameter import de.bixilon.minosoft.data.registries.chat.ChatParameter
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
@ -32,11 +31,7 @@ FormattedChatMessage(
init { init {
// ToDo: parent (formatting) // ToDo: parent (formatting)
val data = type.chat.formatParameters(parameters) val data = type.chat.formatParameters(parameters)
text = if (connection.language.canTranslate(type.chat.translationKey.toResourceLocation())) { text = connection.language.forceTranslate(type.chat.translationKey.toResourceLocation(), restrictedMode = true, fallback = type.chat.translationKey, data = data)
connection.language.translate(type.chat.translationKey.toResourceLocation(), restrictedMode = true, data = data)
} else {
Language.translate(type.chat.translationKey, restrictedMode = true, data = data)
}
text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR)
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,22 +13,34 @@
package de.bixilon.minosoft.data.language.translate 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.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.data.text.TextComponent
interface Translator { 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 forceTranslate(key: ResourceLocation?, parent: TextComponent? = null, restrictedMode: Boolean = false, fallback: String? = null, vararg data: Any?): ChatComponent {
fun translate(key: ResourceLocation?, parent: TextComponent? = null, restrictedMode: Boolean = false, 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 { fun translate(translatable: Any?): ChatComponent {
return when (translatable) { return when (translatable) {
is ChatComponent -> translatable is ChatComponent -> translatable
is Translatable -> translate(translatable.translationKey) is Translatable -> forceTranslate(translatable.translationKey)
else -> ChatComponent.of(translatable) else -> ChatComponent.of(translatable)
} }
} }

View File

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

View File

@ -101,7 +101,7 @@ interface ChatComponent {
return raw return raw
} }
if (raw is Translatable && raw !is ResourceLocation) { 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) { when (raw) {

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * 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. * 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_EXIT = "minosoft:general.exit".toResourceLocation()
val GENERAL_REFRESH = "minosoft:general.refresh".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 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, count) } 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, server.name, account.username) } 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, 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 * 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. * 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 { companion object {
private val LAYOUT = "minosoft:eros/dialog/error.fxml".toResourceLocation() 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 HEADER = "minosoft:error.header".toResourceLocation()
private val DESCRIPTION = "minosoft:error.description".toResourceLocation() private val DESCRIPTION = "minosoft:error.description".toResourceLocation()
private val FATAL_CRASH = "minosoft:error.fatal_crash".toResourceLocation() private val FATAL_CRASH = "minosoft:error.fatal_crash".toResourceLocation()

View File

@ -139,7 +139,7 @@ class ServerModifyDialog(
version ?: return version ?: return
text = if (version == Versions.AUTOMATIC) { text = if (version == Versions.AUTOMATIC) {
Minosoft.LANGUAGE_MANAGER.translate(VERSION_AUTOMATIC).message Minosoft.LANGUAGE_MANAGER.forceTranslate(VERSION_AUTOMATIC).message
} else { } else {
"${version.name} (${version.type.name.lowercase()})" "${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) { for ((key, property) in properties) {
val propertyValue = property(item) ?: continue 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++) 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 for ((key, property) in ACCOUNT_INFO_PROPERTIES.extend(accountTypeListViewFX.selectionModel.selectedItem.additionalDetails)) { // ToDo
val propertyValue = property(account) ?: continue 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++) it.add(ChatComponent.of(propertyValue).textFlow, 1, row++)
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * 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. * 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 { companion object {
private val LAYOUT = "minosoft:eros/main/account/add/microsoft.fxml".toResourceLocation() private val LAYOUT = "minosoft:eros/main/account/add/microsoft.fxml".toResourceLocation()
private val TITLE = "minosoft:main.account.add.microsoft.title".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() 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 { 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) name.setFallbackColor(ChatColors.WHITE)
return TextElement(guiRenderer, name, background = false, scale = 1.2f) return TextElement(guiRenderer, name, background = false, scale = 1.2f)
} }