fix: support disabling Advanced.async on server
ci/woodpecker/push/jfmod Pipeline was successful
Details
ci/woodpecker/push/jfmod Pipeline was successful
Details
This commit is contained in:
parent
fa546b3f26
commit
e04cfaaf93
|
@ -4,7 +4,9 @@ import io.gitlab.jfronny.commons.cache.FixedSizeMap;
|
|||
import io.gitlab.jfronny.commons.log.Logger;
|
||||
import io.gitlab.jfronny.libjf.translate.api.Language;
|
||||
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.text.*;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -15,6 +17,7 @@ public class GoogleChat implements ModInitializer {
|
|||
public static final String MOD_ID = "google-chat";
|
||||
public static final Logger LOGGER = Logger.forName(MOD_ID);
|
||||
public static TranslateService<?> TRANSLATE_SERVICE;
|
||||
private static final boolean IS_SERVER = FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER;
|
||||
|
||||
private static final Map<Text, Text> s2ct = new FixedSizeMap<>(GoogleChatConfig.Advanced.cacheSize);
|
||||
private static final Map<Text, Text> c2st = new FixedSizeMap<>(GoogleChatConfig.Advanced.cacheSize);
|
||||
|
@ -146,7 +149,7 @@ public class GoogleChat implements ModInitializer {
|
|||
}
|
||||
|
||||
private static <K, V> V computeIfAbsent2(Map<K, V> map, K key, Function<K, V> compute) {
|
||||
if (!GoogleChatConfig.Advanced.async) return map.computeIfAbsent(key, compute);
|
||||
if (!GoogleChatConfig.Advanced.async && !IS_SERVER) return map.computeIfAbsent(key, compute);
|
||||
synchronized (map) {
|
||||
if (map.containsKey(key)) return map.get(key);
|
||||
V value = compute.apply(key);
|
||||
|
|
|
@ -1,44 +1,48 @@
|
|||
package io.gitlab.jfronny.googlechat.server;
|
||||
|
||||
import io.gitlab.jfronny.googlechat.*;
|
||||
import io.gitlab.jfronny.googlechat.GoogleChatConfig;
|
||||
import io.gitlab.jfronny.googlechat.TranslationDirection;
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
|
||||
import net.minecraft.network.message.MessageDecorator;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static io.gitlab.jfronny.libjf.LibJf.LOGGER;
|
||||
|
||||
public class GoogleChatServer implements DedicatedServerModInitializer {
|
||||
public class GoogleChatServer implements DedicatedServerModInitializer, MessageDecorator {
|
||||
@Override
|
||||
public void onInitializeServer() {
|
||||
// Default phase is executed between CONTENT and STYLING
|
||||
// Perform translation there instead of during CONTENT to better support other mods (such as chat-transform)
|
||||
// If this causes an incompatibility, I'll add my own phase
|
||||
ServerMessageDecoratorEvent.EVENT.register(Event.DEFAULT_PHASE, (sender, originalMessage) -> {
|
||||
CompletableFuture<Text> futureMessage = CompletableFuture.completedFuture(originalMessage);
|
||||
if (!GoogleChatConfig.General.enabled) return futureMessage; // fast fallthrough
|
||||
if (sender != null) { // Client messages should first be translated to the server language
|
||||
if (TranslationDirection.C2S.hasTarget()) {
|
||||
if (TranslationDirection.S2C.hasTarget()) {
|
||||
// Do not translate back and forth
|
||||
return futureMessage;
|
||||
}
|
||||
ServerMessageDecoratorEvent.EVENT.register(Event.DEFAULT_PHASE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Text> decorate(@Nullable ServerPlayerEntity sender, Text original) {
|
||||
final CompletableFuture<Text> future = CompletableFuture.completedFuture(original);
|
||||
if (!GoogleChatConfig.General.enabled) return future;
|
||||
return GoogleChatConfig.Advanced.async
|
||||
? decorate(sender, new TranslatableContainer.Async(future)).text()
|
||||
: CompletableFuture.completedFuture(decorate(sender, new TranslatableContainer.Sync(original)).text());
|
||||
}
|
||||
|
||||
private <K, T extends TranslatableContainer<K, T>> T decorate(@Nullable ServerPlayerEntity sender, T original) {
|
||||
T message = original;
|
||||
if (sender != null) { // Client messages should first be translated to the server language
|
||||
if (TranslationDirection.C2S.hasTarget()) {
|
||||
if (TranslationDirection.S2C.hasTarget()) {
|
||||
// Do not translate back and forth
|
||||
return message;
|
||||
}
|
||||
futureMessage = futureMessage.thenApplyAsync(msg -> {
|
||||
var translated = GoogleChat.translateIfNeeded(msg, TranslationDirection.C2S, true);
|
||||
if (GoogleChatConfig.Advanced.debugLogs) LOGGER.info("Applied C2S translation from " + msg + " to " + translated);
|
||||
return translated;
|
||||
});
|
||||
}
|
||||
// All messages should be translated to the client language before sending
|
||||
futureMessage = futureMessage.thenApplyAsync(msg -> {
|
||||
var translated = GoogleChat.translateIfNeeded(msg, TranslationDirection.S2C, true);
|
||||
if (GoogleChatConfig.Advanced.debugLogs) LOGGER.info("Applied S2C translation from " + msg + " to " + translated);
|
||||
return translated;
|
||||
});
|
||||
return futureMessage;
|
||||
});
|
||||
message = message.translate(TranslationDirection.C2S);
|
||||
}
|
||||
// All messages should be translated to the client language before sending
|
||||
message = message.translate(TranslationDirection.S2C);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package io.gitlab.jfronny.googlechat.server;
|
||||
|
||||
import io.gitlab.jfronny.googlechat.*;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static io.gitlab.jfronny.libjf.LibJf.LOGGER;
|
||||
|
||||
public sealed interface TranslatableContainer<T, S extends TranslatableContainer<T, S>> {
|
||||
S translate(TranslationDirection direction);
|
||||
|
||||
record Sync(Text text) implements TranslatableContainer<Text, Sync> {
|
||||
@Override
|
||||
public Sync translate(TranslationDirection direction) {
|
||||
return new Sync(translateAndLog(text, direction));
|
||||
}
|
||||
}
|
||||
|
||||
record Async(CompletableFuture<Text> text) implements TranslatableContainer<CompletableFuture<Text>, Async> {
|
||||
@Override
|
||||
public Async translate(TranslationDirection direction) {
|
||||
return new Async(text.thenApplyAsync(msg -> translateAndLog(msg, direction)));
|
||||
}
|
||||
}
|
||||
|
||||
static Text translateAndLog(final Text source, final TranslationDirection direction) {
|
||||
var translated = GoogleChat.translateIfNeeded(source, direction, true);
|
||||
if (GoogleChatConfig.Advanced.debugLogs) LOGGER.info("Applied C2S translation from " + source + " to " + translated);
|
||||
return translated;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue