Rework impl, allow for regex filters (closes #1)
This commit is contained in:
parent
ec7cff19db
commit
258e9bbe1a
|
@ -11,4 +11,5 @@ dependencies {
|
|||
|
||||
// Compat fix
|
||||
include modImplementation(fabricApi.module("fabric-command-api-v1", "${project.fabric_version}"))
|
||||
include modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "${project.fabric_version}"))
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
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 net.minecraft.text.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GoogleChat {
|
||||
|
@ -16,4 +22,89 @@ public class GoogleChat {
|
|||
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) {
|
||||
LiteralText translatedText = new LiteralText(translateIfNeeded(sourceString, direction, true));
|
||||
if (GoogleChatConfig.translationTooltip)
|
||||
return source.copy().setStyle(addHover(Style.EMPTY, new LiteralText("Translated: ").append(translatedText)));
|
||||
else
|
||||
return translatedText.setStyle(addHover(Style.EMPTY, new LiteralText("Original: ").append(source)));
|
||||
}
|
||||
MutableText translated;
|
||||
if (source instanceof TranslatableText 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 = new TranslatableText(tx.getKey(), args);
|
||||
} else if (source instanceof LiteralText tx) {
|
||||
translated = new LiteralText(translateIfNeeded(tx.getRawString(), direction, false)).setStyle(tx.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 clientLang = svc.parseLang(GoogleChatConfig.clientLanguage);
|
||||
TLang serverLang = svc.parseLang(GoogleChatConfig.serverLanguage);
|
||||
try {
|
||||
return svc.translate(source,
|
||||
direction == Direction.C2S ? clientLang : serverLang,
|
||||
direction == Direction.C2S ? serverLang : clientLang);
|
||||
} 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,40 @@ 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;
|
||||
|
||||
public class GoogleChatConfig implements JfConfig {
|
||||
@Entry public static Boolean enabled = true;
|
||||
@Entry public static String serverLanguage = "auto";
|
||||
@Entry public static String clientLanguage = "en";
|
||||
@Entry public static Boolean translationTooltip = false;
|
||||
@Entry public static Boolean desugar = false;
|
||||
@Entry public static String receivingRegex = "";
|
||||
@Entry public static Boolean receivingRegexIsBlacklist = true;
|
||||
@Entry public static String sendingRegex = "";
|
||||
@Entry public static Boolean sendingRegexIsBlacklist = true;
|
||||
|
||||
@Preset
|
||||
public static void client() {
|
||||
enabled = true;
|
||||
if (!serverLanguage.equals("auto")) {
|
||||
serverLanguage = "auto";
|
||||
clientLanguage = "en";
|
||||
String tmp = receivingRegex;
|
||||
receivingRegex = sendingRegex;
|
||||
sendingRegex = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@Preset
|
||||
public static void server() {
|
||||
enabled = true;
|
||||
if (!clientLanguage.equals("auto")) {
|
||||
clientLanguage = "auto";
|
||||
serverLanguage = "en";
|
||||
String tmp = receivingRegex;
|
||||
receivingRegex = sendingRegex;
|
||||
sendingRegex = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
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 io.gitlab.jfronny.libjf.translate.api.TranslateException;
|
||||
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
||||
|
@ -33,15 +31,8 @@ public class ChatMessageC2SPacketMixin {
|
|||
}
|
||||
|
||||
private <T extends Language> void googlechat$translate(TranslateService<T> ts) {
|
||||
if (!GoogleChatConfig.enabled) return;
|
||||
T server = ts.parseLang(GoogleChatConfig.serverLanguage);
|
||||
if (server == ts.parseLang("auto") || chatMessage.startsWith("/")) return;
|
||||
try {
|
||||
chatMessage = ts.translate(chatMessage, ts.parseLang(GoogleChatConfig.clientLanguage), server);
|
||||
} catch (TranslateException e) {
|
||||
GoogleChat.LOGGER.error("Could not translate sent message", e);
|
||||
return;
|
||||
}
|
||||
if (chatMessage.startsWith("/")) return;
|
||||
chatMessage = GoogleChat.translateIfNeeded(chatMessage, GoogleChat.Direction.C2S, true);
|
||||
if (chatMessage.length() > 256) chatMessage = chatMessage.substring(0, 256);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,12 @@ 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 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.network.MessageType;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
|
||||
import net.minecraft.text.*;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
|
@ -19,7 +17,6 @@ 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.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Mixin(GameMessageS2CPacket.class)
|
||||
|
@ -29,42 +26,17 @@ public class GameMessageS2CPacketMixin {
|
|||
|
||||
@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(GoogleChat.TRANSLATE_SERVICE);
|
||||
googlechat$translate();
|
||||
}
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/network/PacketByteBuf;)V")
|
||||
private void init(PacketByteBuf buf, CallbackInfo ci) {
|
||||
googlechat$translate(GoogleChat.TRANSLATE_SERVICE);
|
||||
googlechat$translate();
|
||||
}
|
||||
|
||||
private <T extends Language> void googlechat$translate(TranslateService<T> ts) {
|
||||
private <T extends Language> void googlechat$translate() {
|
||||
if (!GoogleChatConfig.enabled) return;
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && GoogleChat.isSelf(sender)) {
|
||||
return;
|
||||
}
|
||||
T client = ts.parseLang(GoogleChatConfig.clientLanguage);
|
||||
if (client == ts.parseLang("auto")) return;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
message.asOrderedText().accept((index, style, codePoint) -> {
|
||||
sb.append((char)codePoint);
|
||||
return true;
|
||||
});
|
||||
try {
|
||||
LiteralText translatedText = new LiteralText(ts.translate(sb.toString(), ts.parseLang(GoogleChatConfig.serverLanguage), client));
|
||||
if (GoogleChatConfig.translationTooltip)
|
||||
message = googlechat$concat(message.getWithStyle(Style.EMPTY.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new LiteralText("Translated: ").append(translatedText)))));
|
||||
else
|
||||
message = translatedText.setStyle(Style.EMPTY.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new LiteralText("Original: ").append(message))));
|
||||
} catch (TranslateException e) {
|
||||
GoogleChat.LOGGER.error("Could not translate received message", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Text googlechat$concat(List<Text> texts) {
|
||||
MutableText res = null;
|
||||
for (Text text : texts) {
|
||||
res = res == null ? (MutableText) text : res.append(text);
|
||||
}
|
||||
return res;
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && GoogleChat.isSelf(sender)) return;
|
||||
message = GoogleChat.translateIfNeeded(message, GoogleChat.Direction.S2C, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,18 @@
|
|||
"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",
|
||||
"google-chat.jfconfig.translationTooltip": "Translation Tooltip",
|
||||
"google-chat.jfconfig.translationTooltip.tooltip": "Display translations as a tooltip (on hover) and keep the original message"
|
||||
"google-chat.jfconfig.translationTooltip.tooltip": "Display translations as a tooltip (on hover) and keep the original message. This will overwrite other tooltips",
|
||||
"google-chat.jfconfig.desugar": "Desugar",
|
||||
"google-chat.jfconfig.desugar.tooltip": "Translate all messages as plain strings. This will remove formatting but may be more accurate",
|
||||
"google-chat.jfconfig.receivingRegex": "Receiving Regex",
|
||||
"google-chat.jfconfig.receivingRegex.tooltip": "A Regex pattern to check whether a received message should be translated",
|
||||
"google-chat.jfconfig.receivingRegexIsBlacklist": "Receiving Regex Is Blacklist",
|
||||
"google-chat.jfconfig.receivingRegexIsBlacklist.tooltip": "Whether the relevant regex should blacklist messages from translation instead of whitelisting",
|
||||
"google-chat.jfconfig.sendingRegex": "Sending Regex",
|
||||
"google-chat.jfconfig.sendingRegex.tooltip": "A Regex pattern to check whether a sent message should be translated",
|
||||
"google-chat.jfconfig.sendingRegexIsBlacklist": "Sending Regex Is Blacklist",
|
||||
"google-chat.jfconfig.sendingRegexIsBlacklist.tooltip": "Whether the relevant regex should blacklist messages from translation instead of whitelisting",
|
||||
|
||||
"google-chat.jfconfig.client": "Client",
|
||||
"google-chat.jfconfig.server": "Server"
|
||||
}
|
|
@ -20,5 +20,10 @@
|
|||
"depends": {
|
||||
"fabricloader": ">=0.12.12",
|
||||
"minecraft": "*"
|
||||
},
|
||||
"custom": {
|
||||
"libjf:config": {
|
||||
"referencedConfigs": ["libjf-translate-v1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue