Update for 1.19
This commit is contained in:
parent
a4b4d49072
commit
6cc30ede87
|
@ -10,3 +10,5 @@ If you want to use GoogleChat serverside (which is supported btw), a config like
|
||||||
"clientLanguage": "auto"
|
"clientLanguage": "auto"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You should also enable previews-chat in your server.properties to allow signed message translations
|
17
build.gradle
17
build.gradle
|
@ -1,16 +1,15 @@
|
||||||
apply from: "https://jfmods.gitlab.io/scripts/jfmod.gradle"
|
apply from: "https://jfmods.gitlab.io/scripts/jfmod.gradle"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
include modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}")
|
modImplementation("io.gitlab.jfronny.libjf:libjf-config-v0:${project.jfapi_version}")
|
||||||
include modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1:${project.jfapi_version}")
|
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 "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
|
// Compat fix
|
||||||
include modImplementation(fabricApi.module("fabric-command-api-v1", "${project.fabric_version}"))
|
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-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-message-api-v1", project.fabric_version))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
# https://fabricmc.net/develop/
|
# https://fabricmc.net/develop/
|
||||||
minecraft_version=1.18.2
|
minecraft_version=1.19
|
||||||
yarn_mappings=build.2
|
yarn_mappings=build.1
|
||||||
loader_version=0.13.3
|
loader_version=0.14.6
|
||||||
maven_group=io.gitlab.jfronny
|
maven_group=io.gitlab.jfronny
|
||||||
archives_base_name=GoogleChat
|
archives_base_name=GoogleChat
|
||||||
|
|
||||||
jfapi_version=2.7.0
|
jfapi_version=2.9.0
|
||||||
fabric_version=0.48.0+1.18.2
|
fabric_version=0.55.1+1.19
|
||||||
|
|
||||||
modrinth_id=Hd7ZLKRk
|
modrinth_id=Hd7ZLKRk
|
||||||
|
modrinth_required_dependencies=WKwQAwke
|
||||||
modrinth_optional_dependencies=mOgUt4GM
|
modrinth_optional_dependencies=mOgUt4GM
|
||||||
curseforge_id=574331
|
curseforge_id=574331
|
||||||
|
curseforge_required_dependencies=libjf
|
||||||
curseforge_optional_dependencies=modmenu
|
curseforge_optional_dependencies=modmenu
|
|
@ -0,0 +1,4 @@
|
||||||
|
package io.gitlab.jfronny.googlechat;
|
||||||
|
|
||||||
|
public record CacheKey(String sourceText, String sourceLangId, String targetLangId) {
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,32 @@
|
||||||
package io.gitlab.jfronny.googlechat;
|
package io.gitlab.jfronny.googlechat;
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.translate.api.Language;
|
import io.gitlab.jfronny.commons.log.*;
|
||||||
import io.gitlab.jfronny.libjf.translate.api.TranslateException;
|
import io.gitlab.jfronny.libjf.translate.api.*;
|
||||||
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
import net.fabricmc.api.*;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.fabric.api.message.v1.*;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.*;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.*;
|
||||||
import net.minecraft.text.*;
|
import net.minecraft.text.*;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.UUID;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class GoogleChat {
|
public class GoogleChat implements ModInitializer {
|
||||||
public static final String MOD_ID = "google-chat";
|
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();
|
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) {
|
public static boolean isSelf(UUID sender) {
|
||||||
MinecraftClient mc = MinecraftClient.getInstance();
|
MinecraftClient mc = MinecraftClient.getInstance();
|
||||||
|
@ -29,14 +39,14 @@ public class GoogleChat {
|
||||||
if (respectRegex && failsRegex(sourceString, direction))
|
if (respectRegex && failsRegex(sourceString, direction))
|
||||||
return source;
|
return source;
|
||||||
if (GoogleChatConfig.desugar) {
|
if (GoogleChatConfig.desugar) {
|
||||||
LiteralText translatedText = new LiteralText(translateIfNeeded(sourceString, direction, true));
|
MutableText translatedText = Text.literal(translateIfNeeded(sourceString, direction, true));
|
||||||
if (GoogleChatConfig.translationTooltip)
|
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
|
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;
|
MutableText translated;
|
||||||
if (source instanceof TranslatableText tx) {
|
if (source.getContent() instanceof TranslatableTextContent tx) {
|
||||||
Object[] args = tx.getArgs();
|
Object[] args = tx.getArgs();
|
||||||
args = Arrays.copyOf(args, args.length);
|
args = Arrays.copyOf(args, args.length);
|
||||||
// We're not translating TranslatableText but want potential keys
|
// 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] instanceof String tx1 ? translateIfNeeded(tx1, direction, false)
|
||||||
: args[i];
|
: args[i];
|
||||||
}
|
}
|
||||||
translated = new TranslatableText(tx.getKey(), args);
|
translated = Text.translatable(tx.getKey(), args);
|
||||||
} else if (source instanceof LiteralText tx) {
|
} else if (source.getContent() instanceof LiteralTextContent tx) {
|
||||||
translated = new LiteralText(translateIfNeeded(tx.getRawString(), direction, false)).setStyle(tx.getStyle());
|
translated = Text.literal(translateIfNeeded(tx.string(), direction, false)).setStyle(source.getStyle());
|
||||||
} else {
|
} else {
|
||||||
//LOGGER.info("Unhandled text type: " + source.getClass() + " (" + source + ")");
|
//LOGGER.info("Unhandled text type: " + source.getClass() + " (" + source + ")");
|
||||||
translated = source.copy();
|
translated = source.copy();
|
||||||
|
@ -76,12 +86,14 @@ public class GoogleChat {
|
||||||
if (respectRegex && failsRegex(source, direction))
|
if (respectRegex && failsRegex(source, direction))
|
||||||
return source;
|
return source;
|
||||||
TranslateService<TLang> svc = (TranslateService<TLang>) GoogleChat.TRANSLATE_SERVICE; // Generics bypass
|
TranslateService<TLang> svc = (TranslateService<TLang>) GoogleChat.TRANSLATE_SERVICE; // Generics bypass
|
||||||
TLang clientLang = svc.parseLang(GoogleChatConfig.clientLanguage);
|
TLang sourceLang = svc.parseLang(direction == Direction.C2S ? GoogleChatConfig.clientLanguage : GoogleChatConfig.serverLanguage);
|
||||||
TLang serverLang = svc.parseLang(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 {
|
try {
|
||||||
return svc.translate(source,
|
String translated = svc.translate(source, sourceLang, targetLang);
|
||||||
direction == Direction.C2S ? clientLang : serverLang,
|
TRANSLATION_CACHE.put(key, translated);
|
||||||
direction == Direction.C2S ? serverLang : clientLang);
|
return translated;
|
||||||
} catch (TranslateException e) {
|
} catch (TranslateException e) {
|
||||||
LOGGER.error("Could not translate text: " + source, e);
|
LOGGER.error("Could not translate text: " + source, e);
|
||||||
return source;
|
return source;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package io.gitlab.jfronny.googlechat;
|
package io.gitlab.jfronny.googlechat;
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.config.api.Entry;
|
import io.gitlab.jfronny.libjf.config.api.*;
|
||||||
import io.gitlab.jfronny.libjf.config.api.JfConfig;
|
import net.fabricmc.api.*;
|
||||||
import io.gitlab.jfronny.libjf.config.api.Preset;
|
import net.fabricmc.loader.api.*;
|
||||||
|
|
||||||
public class GoogleChatConfig implements JfConfig {
|
public class GoogleChatConfig implements JfConfig {
|
||||||
@Entry public static Boolean enabled = true;
|
@Entry public static Boolean enabled = true;
|
||||||
|
@ -38,4 +38,12 @@ public class GoogleChatConfig implements JfConfig {
|
||||||
sendingRegex = tmp;
|
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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,9 +3,10 @@
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "io.gitlab.jfronny.googlechat.mixin",
|
"package": "io.gitlab.jfronny.googlechat.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"client": [
|
||||||
"ChatMessageC2SPacketMixin",
|
"ChatScreenMixin",
|
||||||
"GameMessageS2CPacketMixin"
|
"ClientPlayerEntityMixin",
|
||||||
|
"ClientPlayNetworkHandlerMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
@ -10,9 +10,8 @@
|
||||||
"icon": "assets/google-chat/icon.png",
|
"icon": "assets/google-chat/icon.png",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"libjf:config": [
|
"libjf:config": ["io.gitlab.jfronny.googlechat.GoogleChatConfig"],
|
||||||
"io.gitlab.jfronny.googlechat.GoogleChatConfig"
|
"main": ["io.gitlab.jfronny.googlechat.GoogleChat"]
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"GoogleChat.mixins.json"
|
"GoogleChat.mixins.json"
|
||||||
|
|
Loading…
Reference in New Issue