Update for 1.19

This commit is contained in:
Johannes Frohnmeyer 2022-06-07 21:34:26 +02:00
parent a4b4d49072
commit 6cc30ede87
Signed by: Johannes
GPG Key ID: E76429612C2929F4
14 changed files with 139 additions and 128 deletions

View File

@ -9,4 +9,6 @@ If you want to use GoogleChat serverside (which is supported btw), a config like
"serverLanguage": "en",
"clientLanguage": "auto"
}
```
```
You should also enable previews-chat in your server.properties to allow signed message translations

View File

@ -1,16 +1,15 @@
apply from: "https://jfmods.gitlab.io/scripts/jfmod.gradle"
dependencies {
include modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}")
include modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1:${project.jfapi_version}")
include("io.gitlab.jfronny.libjf:libjf-unsafe-v0:${project.jfapi_version}")
include("io.gitlab.jfronny.libjf:libjf-base:${project.jfapi_version}")
modRuntimeOnly("io.gitlab.jfronny.libjf:libjf-devutil-v0:${project.jfapi_version}")
modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}")
modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1:${project.jfapi_version}")
modImplementation "com.terraformersmc:modmenu:3.1.0"
//modRuntimeOnly("io.gitlab.jfronny.libjf:libjf-devutil-v0:${project.jfapi_version}")
modImplementation "com.terraformersmc:modmenu:4.0.0-beta.4"
// Compat fix
include modImplementation(fabricApi.module("fabric-command-api-v1", "${project.fabric_version}"))
include modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "${project.fabric_version}"))
include modRuntimeOnly('io.gitlab.jfronny:gson:2.9.0.2022.4.2.19.45.43') // Dependency of LibJF 2.7.0
include modImplementation(fabricApi.module("fabric-command-api-v2", project.fabric_version))
include modImplementation(fabricApi.module("fabric-lifecycle-events-v1", project.fabric_version))
include modImplementation(fabricApi.module("fabric-message-api-v1", project.fabric_version))
}

View File

@ -1,14 +1,16 @@
# https://fabricmc.net/develop/
minecraft_version=1.18.2
yarn_mappings=build.2
loader_version=0.13.3
minecraft_version=1.19
yarn_mappings=build.1
loader_version=0.14.6
maven_group=io.gitlab.jfronny
archives_base_name=GoogleChat
jfapi_version=2.7.0
fabric_version=0.48.0+1.18.2
jfapi_version=2.9.0
fabric_version=0.55.1+1.19
modrinth_id=Hd7ZLKRk
modrinth_required_dependencies=WKwQAwke
modrinth_optional_dependencies=mOgUt4GM
curseforge_id=574331
curseforge_required_dependencies=libjf
curseforge_optional_dependencies=modmenu

View File

@ -0,0 +1,4 @@
package io.gitlab.jfronny.googlechat;
public record CacheKey(String sourceText, String sourceLangId, String targetLangId) {
}

View File

@ -0,0 +1,17 @@
package io.gitlab.jfronny.googlechat;
import java.util.*;
public class FixedSizeCache<K, V> extends LinkedHashMap<K, V> {
private final int maxSize;
public FixedSizeCache(int size) {
super(size + 2, 1F);
this.maxSize = size;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxSize;
}
}

View File

@ -1,22 +1,32 @@
package io.gitlab.jfronny.googlechat;
import io.gitlab.jfronny.libjf.translate.api.Language;
import io.gitlab.jfronny.libjf.translate.api.TranslateException;
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import io.gitlab.jfronny.commons.log.*;
import io.gitlab.jfronny.libjf.translate.api.*;
import net.fabricmc.api.*;
import net.fabricmc.fabric.api.message.v1.*;
import net.fabricmc.loader.api.*;
import net.minecraft.client.*;
import net.minecraft.text.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.*;
public class GoogleChat {
public class GoogleChat implements ModInitializer {
public static final String MOD_ID = "google-chat";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
public static final Logger LOGGER = Logger.forName(MOD_ID);
public static final TranslateService<?> TRANSLATE_SERVICE = TranslateService.getConfigured();
private static final FixedSizeCache<CacheKey, String> TRANSLATION_CACHE = new FixedSizeCache<>(126);
@Override
public void onInitialize() {
ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (sender, message) -> {
if (sender != null) // Client messages should first be translated to the server language
message = translateIfNeeded(message, Direction.C2S, true);
// All messages should be translated to the client language before sending
message = translateIfNeeded(message, Direction.S2C, true);
return CompletableFuture.completedFuture(message);
});
}
public static boolean isSelf(UUID sender) {
MinecraftClient mc = MinecraftClient.getInstance();
@ -29,14 +39,14 @@ public class GoogleChat {
if (respectRegex && failsRegex(sourceString, direction))
return source;
if (GoogleChatConfig.desugar) {
LiteralText translatedText = new LiteralText(translateIfNeeded(sourceString, direction, true));
MutableText translatedText = Text.literal(translateIfNeeded(sourceString, direction, true));
if (GoogleChatConfig.translationTooltip)
return source.copy().setStyle(addHover(Style.EMPTY, new LiteralText("Translated: ").append(translatedText)));
return source.copy().setStyle(addHover(Style.EMPTY, Text.literal("Translated: ").append(translatedText)));
else
return translatedText.setStyle(addHover(Style.EMPTY, new LiteralText("Original: ").append(source)));
return translatedText.setStyle(addHover(Style.EMPTY, Text.literal("Original: ").append(source)));
}
MutableText translated;
if (source instanceof TranslatableText tx) {
if (source.getContent() instanceof TranslatableTextContent tx) {
Object[] args = tx.getArgs();
args = Arrays.copyOf(args, args.length);
// We're not translating TranslatableText but want potential keys
@ -45,9 +55,9 @@ public class GoogleChat {
: args[i] instanceof String tx1 ? translateIfNeeded(tx1, direction, false)
: args[i];
}
translated = new TranslatableText(tx.getKey(), args);
} else if (source instanceof LiteralText tx) {
translated = new LiteralText(translateIfNeeded(tx.getRawString(), direction, false)).setStyle(tx.getStyle());
translated = Text.translatable(tx.getKey(), args);
} else if (source.getContent() instanceof LiteralTextContent tx) {
translated = Text.literal(translateIfNeeded(tx.string(), direction, false)).setStyle(source.getStyle());
} else {
//LOGGER.info("Unhandled text type: " + source.getClass() + " (" + source + ")");
translated = source.copy();
@ -76,12 +86,14 @@ public class GoogleChat {
if (respectRegex && failsRegex(source, direction))
return source;
TranslateService<TLang> svc = (TranslateService<TLang>) GoogleChat.TRANSLATE_SERVICE; // Generics bypass
TLang clientLang = svc.parseLang(GoogleChatConfig.clientLanguage);
TLang serverLang = svc.parseLang(GoogleChatConfig.serverLanguage);
TLang sourceLang = svc.parseLang(direction == Direction.C2S ? GoogleChatConfig.clientLanguage : GoogleChatConfig.serverLanguage);
TLang targetLang = svc.parseLang(direction == Direction.C2S ? GoogleChatConfig.serverLanguage : GoogleChatConfig.clientLanguage);
CacheKey key = new CacheKey(source, sourceLang.getIdentifier(), targetLang.getIdentifier());
if (TRANSLATION_CACHE.containsKey(key)) return TRANSLATION_CACHE.get(key);
try {
return svc.translate(source,
direction == Direction.C2S ? clientLang : serverLang,
direction == Direction.C2S ? serverLang : clientLang);
String translated = svc.translate(source, sourceLang, targetLang);
TRANSLATION_CACHE.put(key, translated);
return translated;
} catch (TranslateException e) {
LOGGER.error("Could not translate text: " + source, e);
return source;

View File

@ -1,8 +1,8 @@
package io.gitlab.jfronny.googlechat;
import io.gitlab.jfronny.libjf.config.api.Entry;
import io.gitlab.jfronny.libjf.config.api.JfConfig;
import io.gitlab.jfronny.libjf.config.api.Preset;
import io.gitlab.jfronny.libjf.config.api.*;
import net.fabricmc.api.*;
import net.fabricmc.loader.api.*;
public class GoogleChatConfig implements JfConfig {
@Entry public static Boolean enabled = true;
@ -38,4 +38,12 @@ public class GoogleChatConfig implements JfConfig {
sendingRegex = tmp;
}
}
@Verifier
public static void verify() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER && !clientLanguage.equals("auto")) {
System.err.println("Your client language is not set to \"auto\" and you are using a server.\n"
+ "This setup is not recommended! Please set up GoogleChat according to its documentation!");
}
}
}

View File

@ -1,38 +0,0 @@
package io.gitlab.jfronny.googlechat.mixin;
import io.gitlab.jfronny.googlechat.GoogleChat;
import io.gitlab.jfronny.libjf.translate.api.Language;
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ChatMessageC2SPacket.class)
public class ChatMessageC2SPacketMixin {
@Mutable
@Final
@Shadow
private String chatMessage;
@Inject(at = @At("RETURN"), method = "<init>(Ljava/lang/String;)V")
public void init(String chatMessage, CallbackInfo info) {
googlechat$translate(GoogleChat.TRANSLATE_SERVICE);
}
@Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/network/PacketByteBuf;)V")
public void init(PacketByteBuf buf, CallbackInfo ci) {
googlechat$translate(GoogleChat.TRANSLATE_SERVICE);
}
private <T extends Language> void googlechat$translate(TranslateService<T> ts) {
if (chatMessage.startsWith("/")) return;
chatMessage = GoogleChat.translateIfNeeded(chatMessage, GoogleChat.Direction.C2S, true);
if (chatMessage.length() > 256) chatMessage = chatMessage.substring(0, 256);
}
}

View File

@ -0,0 +1,14 @@
package io.gitlab.jfronny.googlechat.mixin;
import io.gitlab.jfronny.googlechat.*;
import net.minecraft.client.gui.screen.*;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
@Mixin(ChatScreen.class)
public class ChatScreenMixin {
@ModifyVariable(method = "tryRequestChatPreview(Ljava/lang/String;)V", at = @At(value = "HEAD"), argsOnly = true, ordinal = 0)
String googlechat$translateChatText(String source) {
return GoogleChat.translateIfNeeded(source, GoogleChat.Direction.C2S, true);
}
}

View File

@ -0,0 +1,19 @@
package io.gitlab.jfronny.googlechat.mixin;
import io.gitlab.jfronny.googlechat.*;
import net.minecraft.client.gui.hud.*;
import net.minecraft.client.network.*;
import net.minecraft.network.message.*;
import net.minecraft.text.*;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
@Redirect(method = "handleMessage(Lnet/minecraft/network/message/MessageType;Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/network/message/MessageSender;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;onChatMessage(Lnet/minecraft/network/message/MessageType;Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSender;)V"))
private void googlechat$interceptChatMessage(InGameHud hud, MessageType type, Text message, MessageSender sender) {
if (!GoogleChat.isSelf(sender.uuid()))
message = GoogleChat.translateIfNeeded(message, GoogleChat.Direction.S2C, true);
hud.onChatMessage(type, message, sender);
}
}

View File

@ -0,0 +1,14 @@
package io.gitlab.jfronny.googlechat.mixin;
import io.gitlab.jfronny.googlechat.*;
import net.minecraft.client.network.*;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
@Mixin(ClientPlayerEntity.class)
public class ClientPlayerEntityMixin {
@ModifyVariable(method = "sendChatMessage(Ljava/lang/String;Lnet/minecraft/text/Text;)V", at = @At("HEAD"), argsOnly = true, ordinal = 0)
String googlechat$translateMessage(String source) {
return GoogleChat.translateIfNeeded(source, GoogleChat.Direction.C2S, true);
}
}

View File

@ -1,42 +0,0 @@
package io.gitlab.jfronny.googlechat.mixin;
import io.gitlab.jfronny.googlechat.GoogleChat;
import io.gitlab.jfronny.googlechat.GoogleChatConfig;
import io.gitlab.jfronny.libjf.translate.api.Language;
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.Text;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.UUID;
@Mixin(GameMessageS2CPacket.class)
public class GameMessageS2CPacketMixin {
@Shadow @Final @Mutable private Text message;
@Shadow @Final private UUID sender;
@Inject(at = @At("RETURN"), method = "<init>(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 = "<init>(Lnet/minecraft/network/PacketByteBuf;)V")
private void init(PacketByteBuf buf, CallbackInfo ci) {
googlechat$translate();
}
private <T extends Language> void googlechat$translate() {
if (!GoogleChatConfig.enabled) return;
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && GoogleChat.isSelf(sender)) return;
message = GoogleChat.translateIfNeeded(message, GoogleChat.Direction.S2C, true);
}
}

View File

@ -3,9 +3,10 @@
"minVersion": "0.8",
"package": "io.gitlab.jfronny.googlechat.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"ChatMessageC2SPacketMixin",
"GameMessageS2CPacketMixin"
"client": [
"ChatScreenMixin",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin"
],
"injectors": {
"defaultRequire": 1

View File

@ -10,9 +10,8 @@
"icon": "assets/google-chat/icon.png",
"environment": "*",
"entrypoints": {
"libjf:config": [
"io.gitlab.jfronny.googlechat.GoogleChatConfig"
]
"libjf:config": ["io.gitlab.jfronny.googlechat.GoogleChatConfig"],
"main": ["io.gitlab.jfronny.googlechat.GoogleChat"]
},
"mixins": [
"GoogleChat.mixins.json"