diff options
4 files changed, 197 insertions, 195 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 326f5798f..93ccfe1fa 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -55,6 +55,7 @@ import at.hannibal2.skyhanni.features.chat.ChatFilter import at.hannibal2.skyhanni.features.chat.CompactBestiaryChatMessage import at.hannibal2.skyhanni.features.chat.CompactSplashPotionMessage import at.hannibal2.skyhanni.features.chat.PlayerDeathMessages +import at.hannibal2.skyhanni.features.chat.Translator import at.hannibal2.skyhanni.features.chat.WatchdogHider import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatFilter import at.hannibal2.skyhanni.features.chat.playerchat.PlayerChatModifier @@ -592,7 +593,7 @@ class SkyHanniMod { loadModule(WatchdogHider()) loadModule(AccountUpgradeReminder()) loadModule(PetExpTooltip()) -// loadModule(Translator()) + loadModule(Translator()) loadModule(GardenPlotBorders()) loadModule(CosmeticFollowingLine()) loadModule(SuperpairsClicksAlert()) 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 ea77de371..1e32ff718 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -7,6 +7,7 @@ import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.PartyAPI import at.hannibal2.skyhanni.features.bingo.BingoCardDisplay import at.hannibal2.skyhanni.features.bingo.BingoNextStepHelper +import at.hannibal2.skyhanni.features.chat.Translator import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostUtil import at.hannibal2.skyhanni.features.commands.PartyCommands import at.hannibal2.skyhanni.features.event.diana.BurrowWarpHelper @@ -162,13 +163,13 @@ object Commands { "shfarmingprofile", "Look up the farming profile from yourself or another player on elitebot.dev" ) { FarmingWeightDisplay.lookUpCommand(it) } -// registerCommand( -// "shcopytranslation", -// "<language code (2 letters)> <messsage to translate>\n" + -// "Requires the Chat > Translator feature to be enabled.\n" + -// "Copies the translation for a given message to your clipboard. " + -// "Language codes are at the end of the translation when you click on a message." -// ) { Translator.fromEnglish(it) } + registerCommand( + "shcopytranslation", + "<language code (2 letters)> <messsage to translate>\n" + + "Requires the Chat > Translator feature to be enabled.\n" + + "Copies the translation for a given message to your clipboard. " + + "Language codes are at the end of the translation when you click on a message." + ) { Translator.fromEnglish(it) } registerCommand( "shmouselock", "Lock/Unlock the mouse so it will no longer rotate the player (for farming)" @@ -297,10 +298,10 @@ object Commands { registerCommand("shsendcontests", "") { GardenNextJacobContest.shareContestConfirmed(it) } registerCommand("shwords", "Opens the config list for modifying visual words") { openVisualWords() } registerCommand("shstopaccountupgradereminder", "") { AccountUpgradeReminder.disable() } -// registerCommand( -// "shsendtranslation", -// "Respond with a translation of the message that the user clicks" -// ) { Translator.toEnglish(it) } + registerCommand( + "shsendtranslation", + "Respond with a translation of the message that the user clicks" + ) { Translator.toEnglish(it) } } private fun shortenedCommands() { diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java index d400c279f..309ce04a7 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/ChatConfig.java @@ -186,14 +186,14 @@ public class ChatConfig { @FeatureToggle public boolean hideSacksChange = false; -// @Expose -// @ConfigOption( -// name = "Translator", -// desc = "Click on a message to translate it into English. " + -// "Use §e/shcopytranslation§7 to get the translation from English. " + -// "§cTranslation is not guaranteed to be 100% accurate." -// ) -// @ConfigEditorBoolean -// @FeatureToggle -// public boolean translator = false; + @Expose + @ConfigOption( + name = "Translator", + desc = "Click on a message to translate it into English. " + + "Use §e/shcopytranslation§7 to get the translation from English. " + + "§cTranslation is not guaranteed to be 100% accurate." + ) + @ConfigEditorBoolean + @FeatureToggle + public boolean translator = false; } diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt index 8974a0cbc..6105d762a 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt @@ -1,173 +1,173 @@ -//package at.hannibal2.skyhanni.features.chat -// -//import at.hannibal2.skyhanni.SkyHanniMod -//import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope -//import at.hannibal2.skyhanni.events.LorenzChatEvent -//import at.hannibal2.skyhanni.utils.APIUtil -//import at.hannibal2.skyhanni.utils.LorenzUtils -//import at.hannibal2.skyhanni.utils.LorenzUtils.transformIf -//import at.hannibal2.skyhanni.utils.OSUtils -//import at.hannibal2.skyhanni.utils.StringUtils.getPlayerName -//import at.hannibal2.skyhanni.utils.StringUtils.removeColor -//import com.google.gson.JsonArray -//import kotlinx.coroutines.launch -//import net.minecraft.event.ClickEvent -//import net.minecraft.event.HoverEvent -//import net.minecraft.util.ChatComponentText -//import net.minecraft.util.ChatStyle -//import net.minecraftforge.fml.common.eventhandler.EventPriority -//import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -//import java.net.URLDecoder -//import java.net.URLEncoder -// -//class Translator { -// private val messageContentRegex = Regex(".*: (.*)") -// -// // Logic for listening for a user click on a chat message is from NotEnoughUpdates -// -// @SubscribeEvent(priority = EventPriority.LOWEST) -// fun onGuiChat(event: LorenzChatEvent) { -// if (!isEnabled()) return -// -// val message = event.message -// if (message.getPlayerName() == "-") return -// -// val editedComponent = event.chatComponent.transformIf({ siblings.isNotEmpty() }) { siblings.last() } -// -// val clickStyle = createClickStyle(message.removeColor(), editedComponent.chatStyle) -// editedComponent.setChatStyle(clickStyle) -// } -// -// private fun createClickStyle(message: String, style: ChatStyle): ChatStyle { -// style.setChatClickEvent( -// ClickEvent( -// ClickEvent.Action.RUN_COMMAND, -// "/shsendtranslation ${messageContentRegex.find(message.removeColor())!!.groupValues[1]}" -// ) -// ) -// style.setChatHoverEvent( -// HoverEvent( -// HoverEvent.Action.SHOW_TEXT, -// ChatComponentText("§bClick to translate!") -// ) -// ) -// return style -// } -// -// -// companion object { -// private val config get() = SkyHanniMod.feature.chat -// -// /* -// * Simplified version of the JSON response: -// * [ -// * [ -// * [ -// * 'translated sentence one with a space after the punctuation. ' -// * 'original sentence one without a space after the punctuation.' -// * ], -// * [ -// * 'translated sentence two without punctuation bc it's last' -// * 'original sentence two without punctuation' -// * ] -// * ], -// * null, -// * '"target language as a two-letter code following ISO 639-1"', -// * ] -// */ -// -// private fun getJSONResponse(urlString: String) = -// APIUtil.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" -// ) -// -// var messageToSend = "" -// val layer1 = getJSONResponse(url).asJsonArray -// if (layer1.size() <= 2) return "Error!" -// -// val language = layer1[2].toString() -// if (language == "\"en\"") return "Unable to translate!" -// if (language.length != 4) return "Error!" -// -// 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() -// val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1) -// messageToSend = "$messageToSend$sentenceWithoutQuotes" -// } -// messageToSend = "$messageToSend §7(Language: $language)" -// -// return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "") -// } -// -// 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("\\", "") -// } -// -// fun toEnglish(args: Array<String>) { -// if (!isEnabled()) return -// var message = "" -// for (i in args) { -// message = "$message$i " -// } -// -// coroutineScope.launch { -// val translation = getTranslationToEnglish(message) -// if (translation == "Unable to translate!") LorenzUtils.chat("§c[SkyHanni] Unable to translate message :( (is it in English?)") -// else LorenzUtils.chat("§e[SkyHanni] Found translation: §f$translation") -// } -// } -// -// fun fromEnglish(args: Array<String>) { -// if (!isEnabled()) return -// if (args.size < 2 || args[0].length != 2) { // args[0] is the language code -// LorenzUtils.chat("§cUsage: /shcopytranslation <two letter language code (at the end of a translation)> <message>") -// return -// } -// val language = args[0] -// var message = "" -// for (i in 1..<args.size) { -// message = "$message${args[i]} " -// } -// -// coroutineScope.launch { -// val translation = getTranslationFromEnglish(message, language) -// LorenzUtils.chat("§e[SkyHanni] Copied translation to clipboard: $translation") -// OSUtils.copyToClipboard(translation) -// } -// } -// -// fun isEnabled() = config.translator -// } -//}
\ No newline at end of file +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.APIUtil +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.transformIf +import at.hannibal2.skyhanni.utils.OSUtils +import at.hannibal2.skyhanni.utils.StringUtils.getPlayerNameFromChatMessage +import com.google.gson.JsonArray +import kotlinx.coroutines.launch +import net.minecraft.event.ClickEvent +import net.minecraft.event.HoverEvent +import net.minecraft.util.ChatComponentText +import net.minecraft.util.ChatStyle +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.net.URLDecoder +import java.net.URLEncoder + +class Translator { + private val messageContentRegex = Regex(".*: (.*)") + + // Logic for listening for a user click on a chat message is from NotEnoughUpdates + + @SubscribeEvent(priority = EventPriority.LOWEST) + fun onGuiChat(event: LorenzChatEvent) { + if (!isEnabled()) return + + val message = event.message + if (message.getPlayerNameFromChatMessage() == null) return + + val editedComponent = event.chatComponent.transformIf({ siblings.isNotEmpty() }) { siblings.last() } + if (editedComponent.chatStyle?.chatClickEvent?.action == ClickEvent.Action.OPEN_URL) return + + val clickStyle = createClickStyle(message, editedComponent.chatStyle) + editedComponent.setChatStyle(clickStyle) + } + + private fun createClickStyle(message: String, style: ChatStyle): ChatStyle { + style.setChatClickEvent( + ClickEvent( + ClickEvent.Action.RUN_COMMAND, + "/shsendtranslation ${messageContentRegex.find(message)!!.groupValues[1]}" + ) + ) + style.setChatHoverEvent( + HoverEvent( + HoverEvent.Action.SHOW_TEXT, + ChatComponentText("§bClick to translate!") + ) + ) + return style + } + + + companion object { + private val config get() = SkyHanniMod.feature.chat + + /* + * Simplified version of the JSON response: + * [ + * [ + * [ + * 'translated sentence one with a space after the punctuation. ' + * 'original sentence one without a space after the punctuation.' + * ], + * [ + * 'translated sentence two without punctuation bc it's last' + * 'original sentence two without punctuation' + * ] + * ], + * null, + * '"target language as a two-letter code following ISO 639-1"', + * ] + */ + + private fun getJSONResponse(urlString: String) = + APIUtil.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" + ) + + var messageToSend = "" + val layer1 = getJSONResponse(url).asJsonArray + if (layer1.size() <= 2) return "Error!" + + val language = layer1[2].toString() + if (language == "\"en\"") return "Unable to translate!" + if (language.length != 4) return "Error!" + + 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() + val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1) + messageToSend = "$messageToSend$sentenceWithoutQuotes" + } + messageToSend = "$messageToSend §7(Language: $language)" + + return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "") + } + + 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("\\", "") + } + + fun toEnglish(args: Array<String>) { + if (!isEnabled()) return + var message = "" + for (i in args) { + message = "$message$i " + } + + coroutineScope.launch { + val translation = getTranslationToEnglish(message) + if (translation == "Unable to translate!") LorenzUtils.chat("§c[SkyHanni] Unable to translate message :( (is it in English?)") + else LorenzUtils.chat("§e[SkyHanni] Found translation: §f$translation") + } + } + + fun fromEnglish(args: Array<String>) { + if (!isEnabled()) return + if (args.size < 2 || args[0].length != 2) { // args[0] is the language code + LorenzUtils.chat("§cUsage: /shcopytranslation <two letter language code (at the end of a translation)> <message>") + return + } + val language = args[0] + var message = "" + for (i in 1..<args.size) { + message = "$message${args[i]} " + } + + coroutineScope.launch { + val translation = getTranslationFromEnglish(message, language) + LorenzUtils.chat("§e[SkyHanni] Copied translation to clipboard: $translation") + OSUtils.copyToClipboard(translation) + } + } + + fun isEnabled() = config.translator + } +} |