diff --git a/build.gradle b/build.gradle index e9c368d..276196a 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,10 @@ repositories { dependencies { include modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}") + include modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v0:${project.jfapi_version}") include("io.gitlab.jfronny.libjf:libjf-unsafe-v0:${project.jfapi_version}") include("io.gitlab.jfronny.libjf:libjf-base:${project.jfapi_version}") - runtimeOnly("io.gitlab.jfronny.libjf:libjf-devutil-v0:${project.jfapi_version}") + //runtimeOnly("io.gitlab.jfronny.libjf:libjf-devutil-v0:${project.jfapi_version}") // https://maven.terraformersmc.com/releases/com/terraformersmc/modmenu modImplementation "com.terraformersmc:modmenu:3.0.1" diff --git a/gradle.properties b/gradle.properties index 41347a5..a36ee5d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,3 @@ -org.gradle.jvmargs=-Xmx1G # https://fabricmc.net/versions.html minecraft_version=1.18.1 yarn_mappings=build.12 @@ -6,10 +5,10 @@ loader_version=0.12.12 maven_group=io.gitlab.jfronny archives_base_name=GoogleChat -jfapi_version=2.2.1 -modrinth_io= +jfapi_version=2.4.0 +modrinth_id=Hd7ZLKRk # modrinth_required_dependencies= # modrinth_optional_dependencies= -curseforge_id=none +curseforge_id=574331 # curseforge_required_dependencies= # curseforge_optional_dependencies= \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/googlechat/GoogleChat.java b/src/main/java/io/gitlab/jfronny/googlechat/GoogleChat.java index fa42fad..8859b7b 100644 --- a/src/main/java/io/gitlab/jfronny/googlechat/GoogleChat.java +++ b/src/main/java/io/gitlab/jfronny/googlechat/GoogleChat.java @@ -1,17 +1,17 @@ package io.gitlab.jfronny.googlechat; -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import net.minecraft.client.MinecraftClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -@Environment(EnvType.CLIENT) -public class GoogleChat implements ClientModInitializer { +import java.util.UUID; + +public class GoogleChat { public static final String MOD_ID = "google-chat"; - public static final Logger LOGGER = LogManager.getFormatterLogger(MOD_ID); - @Override - public void onInitializeClient() { + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static boolean isSelf(UUID sender) { + MinecraftClient mc = MinecraftClient.getInstance(); + return mc == null || mc.player == null || sender.equals(mc.player.getUuid()); } } diff --git a/src/main/java/io/gitlab/jfronny/googlechat/api/GoogleService.java b/src/main/java/io/gitlab/jfronny/googlechat/api/GoogleService.java deleted file mode 100644 index 9bce2eb..0000000 --- a/src/main/java/io/gitlab/jfronny/googlechat/api/GoogleService.java +++ /dev/null @@ -1,79 +0,0 @@ -package io.gitlab.jfronny.googlechat.api; - -import io.gitlab.jfronny.googlechat.GoogleChat; -import org.apache.commons.lang3.StringEscapeUtils; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class GoogleService { - private static final Pattern TRANSLATION_RESULT = Pattern.compile("class=\"result-container\">([^<]*)", Pattern.MULTILINE); - - public static String translate(String textToTranslate, Language translateFrom, Language translateTo) { - if (textToTranslate == null) - return null; - String pageSource = ""; - try { - pageSource = getPageSource(textToTranslate, translateFrom.value, translateTo.value); - Matcher matcher = TRANSLATION_RESULT.matcher(pageSource); - if (matcher.find()) { - String match = matcher.group(1); - if (match != null && !match.isEmpty()) { - return StringEscapeUtils.unescapeHtml4(match); - } - } - GoogleChat.LOGGER.error("Could not translate \"" + textToTranslate + "\": result page couldn't be parsed"); - return null; - } catch (Exception e) { - try { - Path p = Files.createTempFile("translater-pagedump-", ".html").toAbsolutePath(); - Files.writeString(p, pageSource); - GoogleChat.LOGGER.error("Could not translate string, see dumped page at " + p, e); - } catch (IOException ioe) { - GoogleChat.LOGGER.error("Could not translate string and the page could not be dumped", ioe); - } - return null; - } - } - - private static String getPageSource(String textToTranslate, String translateFrom, String translateTo) - throws Exception { - if (textToTranslate == null) - return null; - String pageUrl = String.format("https://translate.google.com/m?hl=en&sl=%s&tl=%s&ie=UTF-8&prev=_m&q=%s", - translateFrom, translateTo, URLEncoder.encode(textToTranslate.trim(), StandardCharsets.UTF_8)); - URL url = new URL(pageUrl); - HttpURLConnection connection = null; - BufferedReader bufferedReader = null; - StringBuilder pageSource = new StringBuilder(); - try { - connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(5000); - connection.setRequestProperty("User-Agent", - "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"); - bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); - String line; - while ((line = bufferedReader.readLine()) != null) { - pageSource.append(line).append('\n'); - } - return pageSource.toString(); - } catch (Exception e) { - GoogleChat.LOGGER.error("Could not load translation from google", e); - return null; - } finally { - if (connection != null) - connection.disconnect(); - if (bufferedReader != null) - bufferedReader.close(); - } - } -} diff --git a/src/main/java/io/gitlab/jfronny/googlechat/api/Language.java b/src/main/java/io/gitlab/jfronny/googlechat/api/Language.java deleted file mode 100644 index 5bc378c..0000000 --- a/src/main/java/io/gitlab/jfronny/googlechat/api/Language.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.gitlab.jfronny.googlechat.api; - -import java.util.HashMap; -import java.util.Map; - -public enum Language { - AUTO_DETECT("AUTO_DETECT", "auto"), ARABIC("ARABIC", "ar"), CHINESE_SIMPLIFIED("CHINESE_SIMPLIFIED", "zh-CN"), - CHINESE_TRADITIONAL("CHINESE_TRADITIONAL", "zh-TW"), ENGLISH("ENGLISH", "en"), FILIPINO("FILIPINO", "tl"), - FRENCH("FRENCH", "fr"), GERMAN("GERMAN", "de"), GREEK("GREEK", "el"), INDONESIAN("INDONESIAN", "id"), - IRISH("IRISH", "ga"), ITALIAN("ITALIAN", "it"), JAPANESE("JAPANESE", "ja"), JAVANESE("JAVANESE", "jw"), - KOREAN("KOREAN", "ko"), LATIN("LATIN", "la"), POLISH("POLISH", "pl"), PORTUGUESE("PORTUGUESE", "pt"), - RUSSIAN("RUSSIAN", "ru"), SPANISH("SPANISH", "es"), SWEDISH("SWEDISH", "sv"), THAI("THAI", "th"), - VIETNAMESE("VIETNAMESE", "vi"); - - private static final Map LANGUAGE_BY_VALUE = new HashMap<>(); - - static { - for (Language language : Language.values()) { - LANGUAGE_BY_VALUE.put(language.value, language); - } - } - - public static Language byValue(String value) { - return LANGUAGE_BY_VALUE.getOrDefault(value, AUTO_DETECT); - } - - public final String name; - public final String value; - - Language(String name, String value) { - this.name = name; - this.value = value; - } - - @Override - public String toString() { - return name; - } -} diff --git a/src/main/java/io/gitlab/jfronny/googlechat/mixin/ChatMessageC2SPacketMixin.java b/src/main/java/io/gitlab/jfronny/googlechat/mixin/ChatMessageC2SPacketMixin.java index 9fdd145..fa3e96c 100644 --- a/src/main/java/io/gitlab/jfronny/googlechat/mixin/ChatMessageC2SPacketMixin.java +++ b/src/main/java/io/gitlab/jfronny/googlechat/mixin/ChatMessageC2SPacketMixin.java @@ -1,9 +1,15 @@ package io.gitlab.jfronny.googlechat.mixin; +import io.gitlab.jfronny.googlechat.GoogleChat; import io.gitlab.jfronny.googlechat.GoogleChatConfig; -import io.gitlab.jfronny.googlechat.api.GoogleService; -import io.gitlab.jfronny.googlechat.api.Language; +import io.gitlab.jfronny.libjf.translate.Language; +import io.gitlab.jfronny.libjf.translate.TranslateException; +import io.gitlab.jfronny.libjf.translate.TranslateService; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; +import net.minecraft.util.Util; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -21,11 +27,24 @@ public class ChatMessageC2SPacketMixin { @Inject(at = @At("RETURN"), method = "(Ljava/lang/String;)V") public void init(String chatMessage, CallbackInfo info) { + googlechat$translate(); + } + + @Inject(at = @At("RETURN"), method = "(Lnet/minecraft/network/PacketByteBuf;)V") + public void init(PacketByteBuf buf, CallbackInfo ci) { + googlechat$translate(); + } + + private void googlechat$translate() { if (!GoogleChatConfig.enabled) return; - Language server = Language.byValue(GoogleChatConfig.serverLanguage); + Language server = Language.byId(GoogleChatConfig.serverLanguage); if (server == Language.AUTO_DETECT || chatMessage.startsWith("/")) return; - chatMessage = GoogleService.translate(chatMessage, Language.byValue(GoogleChatConfig.clientLanguage), server); + try { + chatMessage = TranslateService.translate(chatMessage, Language.byId(GoogleChatConfig.clientLanguage), server); + } catch (TranslateException e) { + GoogleChat.LOGGER.error("Could not translate sent message", e); + return; + } if (chatMessage.length() > 256) chatMessage = chatMessage.substring(0, 256); - this.chatMessage = chatMessage; } } diff --git a/src/main/java/io/gitlab/jfronny/googlechat/mixin/GameMessageS2CPacketMixin.java b/src/main/java/io/gitlab/jfronny/googlechat/mixin/GameMessageS2CPacketMixin.java index 64ed50c..e689da9 100644 --- a/src/main/java/io/gitlab/jfronny/googlechat/mixin/GameMessageS2CPacketMixin.java +++ b/src/main/java/io/gitlab/jfronny/googlechat/mixin/GameMessageS2CPacketMixin.java @@ -1,14 +1,18 @@ package io.gitlab.jfronny.googlechat.mixin; +import io.gitlab.jfronny.googlechat.GoogleChat; import io.gitlab.jfronny.googlechat.GoogleChatConfig; -import io.gitlab.jfronny.googlechat.api.GoogleService; -import io.gitlab.jfronny.googlechat.api.Language; -import net.minecraft.client.MinecraftClient; +import io.gitlab.jfronny.libjf.translate.Language; +import io.gitlab.jfronny.libjf.translate.TranslateException; +import io.gitlab.jfronny.libjf.translate.TranslateService; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.network.MessageType; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import net.minecraft.util.Util; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -24,18 +28,32 @@ public class GameMessageS2CPacketMixin { @Shadow @Final @Mutable private Text message; @Shadow @Final private UUID sender; + @Inject(at = @At("RETURN"), method = "(Lnet/minecraft/text/Text;Lnet/minecraft/network/MessageType;Ljava/util/UUID;)V") + private void init(Text message, MessageType type, UUID sender, CallbackInfo ci) { + googlechat$translate(); + } + @Inject(at = @At("RETURN"), method = "(Lnet/minecraft/network/PacketByteBuf;)V") private void init(PacketByteBuf buf, CallbackInfo ci) { + googlechat$translate(); + } + + private void googlechat$translate() { if (!GoogleChatConfig.enabled) return; - MinecraftClient mc = MinecraftClient.getInstance(); - if (mc == null || mc.player == null || sender.equals(mc.player.getUuid())) return; - Language client = Language.byValue(GoogleChatConfig.clientLanguage); + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && GoogleChat.isSelf(sender)) { + return; + } + Language client = Language.byId(GoogleChatConfig.clientLanguage); if (client == Language.AUTO_DETECT) return; StringBuilder sb = new StringBuilder(); message.asOrderedText().accept((index, style, codePoint) -> { sb.append((char)codePoint); return true; }); - message = new LiteralText(GoogleService.translate(sb.toString(), Language.byValue(GoogleChatConfig.serverLanguage), client)); + try { + message = new LiteralText(TranslateService.translate(sb.toString(), Language.byId(GoogleChatConfig.serverLanguage), client)); + } catch (TranslateException e) { + GoogleChat.LOGGER.error("Could not translate received message", e); + } } } diff --git a/src/main/resources/GoogleChat.mixins.json b/src/main/resources/GoogleChat.mixins.json index 62f2cf0..76aa120 100644 --- a/src/main/resources/GoogleChat.mixins.json +++ b/src/main/resources/GoogleChat.mixins.json @@ -4,8 +4,6 @@ "package": "io.gitlab.jfronny.googlechat.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - ], - "client": [ "ChatMessageC2SPacketMixin", "GameMessageS2CPacketMixin" ], diff --git a/src/main/resources/assets/google-chat/icon.png b/src/main/resources/assets/google-chat/icon.png new file mode 100644 index 0000000..c4dfead Binary files /dev/null and b/src/main/resources/assets/google-chat/icon.png differ diff --git a/src/main/resources/assets/google-chat/lang/en_us.json b/src/main/resources/assets/google-chat/lang/en_us.json new file mode 100644 index 0000000..0888000 --- /dev/null +++ b/src/main/resources/assets/google-chat/lang/en_us.json @@ -0,0 +1,9 @@ +{ + "google-chat.jfconfig.title": "GoogleChat", + "google-chat.jfconfig.enabled": "Enabled", + "google-chat.jfconfig.enabled.tooltip": "Whether translations should be applied", + "google-chat.jfconfig.serverLanguage": "Server Language", + "google-chat.jfconfig.serverLanguage.tooltip": "The language of the server used in translations. \"auto\" will disable translating your own messages", + "google-chat.jfconfig.clientLanguage": "Client Language", + "google-chat.jfconfig.clientLanguage.tooltip": "Your own language used in translations. \"auto\" will disable translating messages by other server members" +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 65e08c2..3287425 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -7,12 +7,9 @@ "authors": [], "contact": {}, "license": "MIT", - "icon": "assets/GoogleChat/icon.png", - "environment": "client", + "icon": "assets/google-chat/icon.png", + "environment": "*", "entrypoints": { - "client": [ - "io.gitlab.jfronny.googlechat.GoogleChat" - ], "libjf:config": [ "io.gitlab.jfronny.googlechat.GoogleChatConfig" ]