aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorObsidian <108832807+Obsidianninja11@users.noreply.github.com>2024-10-11 10:23:27 -0800
committerGitHub <noreply@github.com>2024-10-11 20:23:27 +0200
commit92291e61cbbdc05736288aef1743ee1c667da6fa (patch)
tree2184e58377869d4e76389c8b285fba9cc7caaf99
parent8a0105f4ad3964d1c8977fa8b09c75df33a74c74 (diff)
downloadskyhanni-92291e61cbbdc05736288aef1743ee1c667da6fa.tar.gz
skyhanni-92291e61cbbdc05736288aef1743ee1c667da6fa.tar.bz2
skyhanni-92291e61cbbdc05736288aef1743ee1c667da6fa.zip
Fix/Improvement: Translator feature (#2693)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/chat/TranslatorConfig.java20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/translation/TranslatableLanguage.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/translation/Translator.kt133
4 files changed, 95 insertions, 74 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
index 44565aa95..bd94a1658 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -252,12 +252,12 @@ object Commands {
) { FarmingWeightDisplay.lookUpCommand(it) }
registerCommand(
"shcopytranslation",
- "Copy the English translation of a message in another language to the clipboard.\n" + "Uses a 2 letter language code that can be found at the end of a translation message.",
- ) { Translator.fromEnglish(it) }
+ "Copy the translation of a message in another language to your clipboard.\n" + "Uses a language code that can be found at the end of a translation message.",
+ ) { Translator.fromNativeLanguage(it) }
registerCommand(
"shtranslate",
- "Translate a message in another language to English.",
- ) { Translator.toEnglish(it) }
+ "Translate a message in another language to your language.",
+ ) { Translator.toNativeLanguage(it) }
registerCommand(
"shmouselock",
"Lock/Unlock the mouse so it will no longer rotate the player (for farming)",
@@ -619,6 +619,10 @@ object Commands {
"shresetmineshaftpitystats",
"Resets the mineshaft pity display stats",
) { MineshaftPityDisplay.fullResetCounter() }
+ registerCommand(
+ "shtranslateadvanced",
+ "Translates a message in an inputted language to another inputted language.",
+ ) { Translator.translateAdvancedCommand(it) }
}
private fun internalCommands() {
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/chat/TranslatorConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/chat/TranslatorConfig.java
index 648afbd87..fdd678d0b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/chat/TranslatorConfig.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/chat/TranslatorConfig.java
@@ -2,8 +2,10 @@ package at.hannibal2.skyhanni.config.features.chat;
import at.hannibal2.skyhanni.config.FeatureToggle;
import at.hannibal2.skyhanni.features.chat.translation.TranslatableLanguage;
+import at.hannibal2.skyhanni.utils.OSUtils;
import com.google.gson.annotations.Expose;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorButton;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorDropdown;
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorText;
import io.github.notenoughupdates.moulconfig.annotations.ConfigOption;
@@ -14,7 +16,7 @@ public class TranslatorConfig {
@Expose
@ConfigOption(
name = "Translate On Click",
- desc = "Click on a message to translate it to English.\n" +
+ desc = "Click on a message to translate it to your language.\n" +
"Use §e/shcopytranslation§7 to translate from English.\n" +
"§cTranslation is not guaranteed to be 100% accurate."
)
@@ -22,7 +24,7 @@ public class TranslatorConfig {
@FeatureToggle
public boolean translateOnClick = false;
- @ConfigOption(name = "Language Name", desc = "The name of the language selected below. Note that languages marked as unknown might still be supported.")
+ @ConfigOption(name = "Your Language", desc = "The language that messages should be translated to.")
@Expose
@ConfigEditorDropdown
public Property<TranslatableLanguage> languageName = Property.of(TranslatableLanguage.ENGLISH);
@@ -30,8 +32,18 @@ public class TranslatorConfig {
@Expose
@ConfigOption(
name = "Language Code",
- desc = "Enter a language code here to translate on chat click into another language. " +
- "E.g. `es` for spanish or 'de' for german. Empty for english.")
+ desc = "If your language doesn't show in the dropdown, enter your language code here. " +
+ "E.g. 'es' for Spanish or 'de' for German. Empty will use English."
+ )
@ConfigEditorText
public Property<String> languageCode = Property.of("en");
+
+ @ConfigOption(
+ name = "List of Language Codes",
+ desc = "A list of Google Translate's suppored language codes."
+ )
+ @ConfigEditorButton(buttonText = "Open")
+ public Runnable langCodesURL = () -> OSUtils.openBrowser(
+ "https://cloud.google.com/translate/docs/languages#try-it-for-yourself"
+ );
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/translation/TranslatableLanguage.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/translation/TranslatableLanguage.kt
index 13a19a1dc..7f5db80d1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/translation/TranslatableLanguage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/translation/TranslatableLanguage.kt
@@ -34,8 +34,8 @@ enum class TranslatableLanguage(private val englishName: String, private val nat
TAGALOG("Tagalog", "Tagalog", "tl"), // Major language in the Philippines
PUNJABI("Punjabi", "ਪੰਜਾਬੀ", "pa"), // Significant in India and Pakistan
- // 5. need better name
- UNKNOWN("Unknown Language", "", ""),
+ // 5. Other Language
+ UNKNOWN("Other", "", ""),
;
// Limit to 20 characters so that the text is not too small in the config
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/translation/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/translation/Translator.kt
index 24809faac..ca827432f 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/translation/Translator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/translation/Translator.kt
@@ -66,7 +66,7 @@ object Translator {
if (text.isEmpty()) {
config.languageName.set(TranslatableLanguage.ENGLISH)
} else {
- for (language in TranslatableLanguage.values()) {
+ for (language in TranslatableLanguage.entries) {
if (language.languageCode.equals(text, ignoreCase = true)) {
config.languageName.set(language)
return@onToggle
@@ -107,102 +107,107 @@ object Translator {
* ]
* ],
* null,
- * '"target language as a two-letter code following ISO 639-1"',
+ * '"target language as a (usually) two-letter code following ISO 639-1"',
* ]
*/
- private fun getJSONResponse(urlString: String) =
- APIUtils.getJSONResponseAsElement(urlString, false, "Google Translate API")
+ private fun getJSONResponse(urlString: String) = APIUtils.getJSONResponseAsElement(urlString, false, "Google Translate API")
- private fun getTranslationToEnglish(message: String): String {
- val url =
- "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t&q=" +
- URLEncoder.encode(message, "UTF-8")
+ fun getTranslation(
+ message: String,
+ targetLanguage: String,
+ sourceLanguage: String = "auto",
+ ): Array<String>? {
+ // TODO add &dj=1 to use named json
+ val url = "https://translate.googleapis.com/translate_a/single?client=gtx&dt=t&sl=$sourceLanguage&tl=$targetLanguage&q=" +
+ URLEncoder.encode(message, "UTF-8")
var messageToSend = ""
- val layer1 = getJSONResponse(url).asJsonArray
- if (layer1.size() <= 2) return "Error!"
+ val fullResponse = getJSONResponse(url).asJsonArray
+ if (fullResponse.size() < 3) return null
- val language = layer1[2].toString()
- if (language == "\"en\"") return "Unable to translate!"
- if (language.length != 4) return "Error!"
+ val language = fullResponse[2].toString() // the detected language the message is in
+ val sentences = fullResponse[0] as? JsonArray ?: return null
- val layer2 = try {
- layer1[0] as JsonArray
- } catch (_: Exception) {
- return "Error!"
- }
-
- for (layer3 in layer2) {
- val arrayLayer3 = layer3 as? JsonArray ?: continue
- val sentence = arrayLayer3[0].toString()
+ for (rawSentence in sentences) {
+ val arrayPhrase = rawSentence as? JsonArray ?: continue
+ val sentence = arrayPhrase[0].toString()
val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1)
messageToSend = "$messageToSend$sentenceWithoutQuotes"
}
- messageToSend = "$messageToSend §7(Language: $language)"
+ messageToSend = URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "") // Not sure if this is actually needed
+ return arrayOf(messageToSend, language)
+ }
- return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
+ @Deprecated("Use toNativeLanguage() instead", ReplaceWith("Translator.toNativeLanguage(args)"))
+ fun toEnglish(args: Array<String>) {
+ toNativeLanguage(args)
}
- private fun getTranslationFromEnglish(message: String, lang: String): String {
- val url =
- "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=$lang&dt=t&q=" +
- URLEncoder.encode(message, "UTF-8")
-
- val layer1 = getJSONResponse(url).asJsonArray
- if (layer1.size() < 1) return "Error!"
- val layer2 = layer1[0] as? JsonArray
-
- val firstSentence = (layer2?.get(0) as? JsonArray)?.get(0).toString()
- var messageToSend = firstSentence.substring(0, firstSentence.length - 1)
- if (layer2 != null) {
- for (sentenceIndex in 1..<layer2.size()) {
- val sentence = (layer2.get(sentenceIndex) as JsonArray).get(0).toString()
- val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1)
- messageToSend = "$messageToSend$sentenceWithoutQuotes"
- }
- } // The first translated sentence only has 1 extra char at the end, but sentences after it need 1 at the front and 1 at the end removed in the substring
- messageToSend = messageToSend.substring(1, messageToSend.length)
- return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
+ @Deprecated("Use fromNativeLanguage() instead", ReplaceWith("Translator.fromNativeLanguage(args)"))
+ fun fromEnglish(args: Array<String>) {
+ fromNativeLanguage(args)
}
- fun toEnglish(args: Array<String>) {
+ fun toNativeLanguage(args: Array<String>) {
val message = args.joinToString(" ").removeColor()
coroutineScope.launch {
- var lang = config.languageCode.get()
- val translation = if (lang.isEmpty()) {
- getTranslationToEnglish(message)
- } else {
- getTranslationFromEnglish(message, lang)
- }
- if (message == translation) {
- ChatUtils.userError("Translation is the same as the original message!")
- return@launch
- }
+ val translation = getTranslation(message, nativeLanguage())
+ val translatedMessage = translation?.get(0) ?: "Error!"
+ val detectedLanguage = translation?.get(1) ?: "Error!"
- if (translation == "Unable to translate!") {
- ChatUtils.userError("Unable to translate message :( (is it in English?)")
+ if (message == translatedMessage) {
+ ChatUtils.userError("Translation is the same as the original message!")
return@launch
}
- ChatUtils.chat("Found translation: §f$translation")
+ ChatUtils.clickableChat(
+ "Found translation: §f$translatedMessage",
+ onClick = { OSUtils.copyToClipboard(translatedMessage) },
+ "§eClick to copy!\n§eOriginal message: §f$message §7(Language: $detectedLanguage)",
+ )
}
}
- fun fromEnglish(args: Array<String>) {
- if (args.size < 2 || args[0].length != 2) { // args[0] is the language code
- ChatUtils.userError("Usage: /shcopytranslation <two letter language code (at the end of a translation)> <message>")
+ fun fromNativeLanguage(args: Array<String>) {
+ if (args.size < 2) {
+ ChatUtils.userError("Usage: /shcopytranslation <language code (found at the end of a translation)> <message>")
return
}
val language = args[0]
val message = args.drop(1).joinToString(" ")
coroutineScope.launch {
- val translation = getTranslationFromEnglish(message, language)
- ChatUtils.chat("Copied translation to clipboard: §f$translation")
- OSUtils.copyToClipboard(translation)
+ val translation = getTranslation(message, language, nativeLanguage())?.get(0) ?: "Error!"
+ ChatUtils.clickableChat(
+ "Copied §f$language §etranslation to clipboard: §f$translation",
+ onClick = { OSUtils.copyToClipboard(translation) },
+ "§eClick to copy!\n§eOriginal message: §f$message",
+ )
}
}
+ fun translateAdvancedCommand(args: Array<String>) {
+ if (args.size < 3) {
+ ChatUtils.userError("Usage: /shtranslateadvanced <source lang code> <target lang code> <message>")
+ return
+ }
+ val sourceLanguage = args[0]
+ val targetLanguage = args[1]
+ val message = args.drop(2).joinToString(" ")
+
+ val translation = getTranslation(message, sourceLanguage, targetLanguage)
+ val translatedMessage = translation?.get(0) ?: "Error!"
+ val detectedLanguage = if (sourceLanguage == "auto") " ${translation?.get(1) ?: "Error!"}" else ""
+
+ ChatUtils.clickableChat(
+ "Found translation from sl: $sourceLanguage: §f$translatedMessage §7(tl: $targetLanguage)",
+ onClick = { OSUtils.copyToClipboard(translatedMessage) },
+ "§eClick to copy!\n§eOriginal message: §f$message §7(sl: $sourceLanguage$detectedLanguage)",
+ )
+ }
+
+ fun nativeLanguage(): String = config.languageCode.get().ifEmpty { "en" }
+
fun isEnabled() = config.translateOnClick
}