Simple caching system

This commit is contained in:
Johannes Frohnmeyer 2023-03-12 10:19:20 +01:00
parent 60e3c5c125
commit c24ed99fae
Signed by: Johannes
GPG Key ID: E76429612C2929F4
8 changed files with 83 additions and 28 deletions

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.googlechat.client.mixin;
import io.gitlab.jfronny.googlechat.GoogleChat;
import io.gitlab.jfronny.googlechat.GoogleChatCache;
import net.minecraft.client.gui.screen.ChatScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -11,6 +11,6 @@ public class ChatScreenMixin {
@ModifyVariable(method = "sendMessage(Ljava/lang/String;Z)Z", at = @At(value = "HEAD"), argsOnly = true, ordinal = 0)
String googlechat$translateChatText(String chatText) {
if (chatText.startsWith("/")) return chatText; // Bypass for client-side commands (Carpet, ...)
return GoogleChat.translateIfNeeded(chatText, GoogleChat.Direction.C2S, true);
return GoogleChatCache.c2s(chatText);
}
}

View File

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

View File

@ -1,43 +1,40 @@
package io.gitlab.jfronny.googlechat.client.mixin;
import com.mojang.authlib.GameProfile;
import io.gitlab.jfronny.googlechat.GoogleChat;
import io.gitlab.jfronny.googlechat.GoogleChatCache;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.message.MessageHandler;
import net.minecraft.network.message.MessageType;
import net.minecraft.network.message.SignedMessage;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
@Mixin(MessageHandler.class)
public class MessageHandlerMixin {
@Shadow @Final private MinecraftClient client;
@Redirect(method = "onChatMessage(Lnet/minecraft/network/message/SignedMessage;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/message/MessageType$Parameters;applyChatDecoration(Lnet/minecraft/text/Text;)Lnet/minecraft/text/Text;"))
Text googlechat$applyDecoration(MessageType.Parameters instance, Text content, SignedMessage args$signed, GameProfile args$sender) {
return instance.applyChatDecoration(googlechat$shouldTranslate(args$sender) ? googlechat$translate(content) : content);
return instance.applyChatDecoration(googlechat$shouldTranslate(args$sender) ? GoogleChatCache.s2c(content) : content);
}
@Redirect(method = "processChatMessageInternal(Lnet/minecraft/network/message/MessageType$Parameters;Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/text/Text;Lcom/mojang/authlib/GameProfile;ZLjava/time/Instant;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/message/MessageType$Parameters;applyChatDecoration(Lnet/minecraft/text/Text;)Lnet/minecraft/text/Text;"))
Text googlechat$applyDecoration2(MessageType.Parameters instance, Text content, MessageType.Parameters args$params, SignedMessage args$message, Text args$decorated, GameProfile args$sender) {
return instance.applyChatDecoration(googlechat$shouldTranslate(args$sender) ? googlechat$translate(content) : content);
return instance.applyChatDecoration(googlechat$shouldTranslate(args$sender) ? GoogleChatCache.s2c(content) : content);
}
@ModifyVariable(method = "onProfilelessMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At(value = "HEAD"), argsOnly = true, ordinal = 0)
Text googlechat$applyTranslation(Text origin) {
return googlechat$translate(origin);
return GoogleChatCache.s2c(origin);
}
@ModifyVariable(method = "onGameMessage(Lnet/minecraft/text/Text;Z)V", at = @At(value = "HEAD"), argsOnly = true, ordinal = 0)
Text googlechat$applyTranslation2(Text origin) {
return googlechat$translate(origin);
}
private Text googlechat$translate(Text message) {
return GoogleChat.translateIfNeeded(message, GoogleChat.Direction.S2C, true);
return GoogleChatCache.s2c(origin);
}
private boolean googlechat$shouldTranslate(GameProfile sender) {
MinecraftClient mc = MinecraftClient.getInstance();
return mc != null && mc.player != null && sender != null && !sender.getId().equals(mc.player.getUuid());
return client != null && client.player != null && sender != null && !sender.getId().equals(client.player.getUuid());
}
}

View File

@ -89,8 +89,8 @@ public class GoogleChat {
if (respectRegex && failsRegex(source, direction)) return source;
// Ignore generics since this is apparently not something java supports
@SuppressWarnings("rawtypes") TranslateService svc = GoogleChat.TRANSLATE_SERVICE;
Language sourceLang = svc.parseLang(direction == Direction.C2S ? GoogleChatConfig.clientLanguage : GoogleChatConfig.serverLanguage);
Language targetLang = svc.parseLang(direction == Direction.C2S ? GoogleChatConfig.serverLanguage : GoogleChatConfig.clientLanguage);
Language sourceLang = svc.parseLang(direction.source());
Language targetLang = svc.parseLang(direction.target());
try {
//noinspection unchecked
return svc.translate(source, sourceLang, targetLang);
@ -111,14 +111,25 @@ public class GoogleChat {
}
public static boolean hasTarget(Direction direction) {
return !TRANSLATE_SERVICE.parseLang(switch (direction) {
case C2S -> GoogleChatConfig.serverLanguage;
case S2C -> GoogleChatConfig.clientLanguage;
}).getIdentifier().equals("auto");
return direction.target().equals("auto");
}
public enum Direction {
C2S,
S2C
S2C;
public String source() {
return switch (this) {
case C2S -> GoogleChatConfig.clientLanguage;
case S2C -> GoogleChatConfig.serverLanguage;
};
}
public String target() {
return switch (this) {
case C2S -> GoogleChatConfig.serverLanguage;
case S2C -> GoogleChatConfig.clientLanguage;
};
}
}
}

View File

@ -0,0 +1,41 @@
package io.gitlab.jfronny.googlechat;
import io.gitlab.jfronny.commons.cache.FixedSizeMap;
import net.minecraft.text.Text;
import java.util.Map;
public class GoogleChatCache {
private static Map<Text, Text> s2ct = new FixedSizeMap<>(GoogleChatConfig.cacheSize);
private static Map<Text, Text> c2st = new FixedSizeMap<>(GoogleChatConfig.cacheSize);
private static Map<String, String> s2cs = new FixedSizeMap<>(GoogleChatConfig.cacheSize);
private static Map<String, String> c2ss = new FixedSizeMap<>(GoogleChatConfig.cacheSize);
public static void clear() {
s2ct.clear();
c2st.clear();
s2cs.clear();
c2ss.clear();
}
public static void onConfigChange() {
GoogleChat.LOGGER.info("Config Change");
clear();
}
public static Text s2c(Text msg) {
return s2ct.computeIfAbsent(msg, m -> GoogleChat.translateIfNeeded(m, GoogleChat.Direction.S2C, true));
}
public static Text c2s(Text msg) {
return c2st.computeIfAbsent(msg, m -> GoogleChat.translateIfNeeded(m, GoogleChat.Direction.C2S, true));
}
public static String s2c(String msg) {
return s2cs.computeIfAbsent(msg, m -> GoogleChat.translateIfNeeded(m, GoogleChat.Direction.S2C, true));
}
public static String c2s(String msg) {
return c2ss.computeIfAbsent(msg, m -> GoogleChat.translateIfNeeded(m, GoogleChat.Direction.C2S, true));
}
}

View File

@ -15,6 +15,7 @@ public class GoogleChatConfig {
@Entry public static boolean receivingRegexIsBlacklist = true;
@Entry public static String sendingRegex = "";
@Entry public static boolean sendingRegexIsBlacklist = true;
@Entry(min = 1, max = 1024) public static int cacheSize = 256;
@Entry public static boolean debugLogs = FabricLoader.getInstance().isDevelopmentEnvironment();
@Preset
@ -48,6 +49,7 @@ public class GoogleChatConfig {
Your client language is not set to "auto" and you are using a server.
This setup is not recommended! Please set up GoogleChat according to its documentation!""");
}
GoogleChatCache.onConfigChange();
}
static {

View File

@ -1,7 +1,6 @@
package io.gitlab.jfronny.googlechat.server;
import io.gitlab.jfronny.googlechat.GoogleChat;
import io.gitlab.jfronny.googlechat.GoogleChatConfig;
import io.gitlab.jfronny.googlechat.*;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
import net.minecraft.text.Text;
@ -9,7 +8,6 @@ import net.minecraft.text.Text;
import java.util.concurrent.CompletableFuture;
import static io.gitlab.jfronny.googlechat.GoogleChat.hasTarget;
import static io.gitlab.jfronny.googlechat.GoogleChat.translateIfNeeded;
import static io.gitlab.jfronny.libjf.LibJf.LOGGER;
public class GoogleChatServer implements DedicatedServerModInitializer {
@ -17,16 +15,20 @@ public class GoogleChatServer implements DedicatedServerModInitializer {
public void onInitializeServer() {
ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (sender, message) -> {
Text original;
if (sender != null && hasTarget(GoogleChat.Direction.C2S)) {
if (hasTarget(GoogleChat.Direction.S2C)) return CompletableFuture.completedFuture(message); // Do not translate back and forth
}
if (sender != null) { // Client messages should first be translated to the server language
if (hasTarget(GoogleChat.Direction.C2S) && hasTarget(GoogleChat.Direction.S2C)) // Do not translate back and forth
return CompletableFuture.completedFuture(message);
original = message;
message = translateIfNeeded(message, GoogleChat.Direction.C2S, true);
message = GoogleChatCache.c2s(message);
if (GoogleChatConfig.debugLogs) LOGGER.info("Applied C2S translation from " + original + " to " + message);
}
// All messages should be translated to the client language before sending
original = message;
message = translateIfNeeded(message, GoogleChat.Direction.S2C, true);
message = GoogleChatCache.s2c(message);
if (GoogleChatConfig.debugLogs) LOGGER.info("Applied S2C translation from " + original + " to " + message);
return CompletableFuture.completedFuture(message);
});

View File

@ -18,6 +18,8 @@
"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.cacheSize": "Cache Size",
"google-chat.jfconfig.cacheSize.tooltips": "The size of each message cache. Since there are four caches, the actual size will be four times this.",
"google-chat.jfconfig.debugLogs": "Debug Logs",
"google-chat.jfconfig.debugLogs.tooltips": "Log additional information about message processing. Useful for debugging",