123 lines
5.9 KiB
Java
123 lines
5.9 KiB
Java
package io.gitlab.jfronny.googlechat;
|
|
|
|
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 java.util.*;
|
|
import java.util.concurrent.*;
|
|
|
|
public class GoogleChat implements ModInitializer {
|
|
public static final String MOD_ID = "google-chat";
|
|
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();
|
|
return mc == null || mc.player == null || sender.equals(mc.player.getUuid());
|
|
}
|
|
|
|
public static Text translateIfNeeded(Text source, Direction direction, boolean respectRegex) {
|
|
if (shouldSkipOutright(direction)) return source;
|
|
String sourceString = toString(source);
|
|
if (respectRegex && failsRegex(sourceString, direction))
|
|
return source;
|
|
if (GoogleChatConfig.desugar) {
|
|
MutableText translatedText = Text.literal(translateIfNeeded(sourceString, direction, true));
|
|
if (GoogleChatConfig.translationTooltip)
|
|
return source.copy().setStyle(addHover(Style.EMPTY, Text.literal("Translated: ").append(translatedText)));
|
|
else
|
|
return translatedText.setStyle(addHover(Style.EMPTY, Text.literal("Original: ").append(source)));
|
|
}
|
|
MutableText translated;
|
|
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
|
|
for (int i = 0; i < args.length; i++) {
|
|
args[i] = args[i] instanceof Text tx1 ? translateIfNeeded(tx1, direction, false)
|
|
: args[i] instanceof String tx1 ? translateIfNeeded(tx1, direction, false)
|
|
: args[i];
|
|
}
|
|
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();
|
|
}
|
|
if (GoogleChatConfig.translationTooltip)
|
|
return source.copy().styled(style -> addHover(style, translated));
|
|
else
|
|
return translated;
|
|
}
|
|
|
|
private static String toString(Text text) {
|
|
StringBuilder sb = new StringBuilder();
|
|
text.asOrderedText().accept((index, style, codePoint) -> {
|
|
sb.append((char)codePoint);
|
|
return true;
|
|
});
|
|
return sb.toString();
|
|
}
|
|
|
|
private static Style addHover(Style style, Text hoverText) {
|
|
return style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverText));
|
|
}
|
|
|
|
public static <TLang extends Language> String translateIfNeeded(String source, Direction direction, boolean respectRegex) {
|
|
if (shouldSkipOutright(direction)) return source;
|
|
if (respectRegex && failsRegex(source, direction))
|
|
return source;
|
|
TranslateService<TLang> svc = (TranslateService<TLang>) GoogleChat.TRANSLATE_SERVICE; // Generics bypass
|
|
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 {
|
|
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;
|
|
}
|
|
}
|
|
|
|
private static boolean failsRegex(String text, Direction direction) {
|
|
boolean isSender = (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) == (direction == Direction.C2S);
|
|
if (isSender) return text.matches(GoogleChatConfig.sendingRegex) == GoogleChatConfig.sendingRegexIsBlacklist;
|
|
else return text.matches(GoogleChatConfig.receivingRegex) == GoogleChatConfig.receivingRegexIsBlacklist;
|
|
}
|
|
|
|
private static boolean shouldSkipOutright(Direction direction) {
|
|
if (!GoogleChatConfig.enabled) return true;
|
|
Language clientLang = TRANSLATE_SERVICE.parseLang(GoogleChatConfig.clientLanguage);
|
|
Language serverLang = TRANSLATE_SERVICE.parseLang(GoogleChatConfig.serverLanguage);
|
|
if (direction == Direction.S2C && clientLang.getIdentifier().equals("auto")) return true;
|
|
if (direction == Direction.C2S && serverLang.getIdentifier().equals("auto")) return true;
|
|
return false;
|
|
}
|
|
|
|
public enum Direction {
|
|
C2S,
|
|
S2C
|
|
}
|
|
}
|