GoogleChat/src/client/java/io/gitlab/jfronny/googlechat/client/mixin/MessageHandlerMixin.java

101 lines
7.0 KiB
Java

package io.gitlab.jfronny.googlechat.client.mixin;
import com.mojang.authlib.GameProfile;
import io.gitlab.jfronny.googlechat.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.*;
import net.minecraft.client.network.message.MessageHandler;
import net.minecraft.client.util.NarratorManager;
import net.minecraft.network.message.*;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
@Mixin(MessageHandler.class)
public abstract class MessageHandlerMixin {
@Shadow @Final private MinecraftClient client;
@Shadow protected abstract void narrate(MessageType.Parameters params, Text message);
@Unique CompletableFuture<Void> googlechat$currentFuture = CompletableFuture.completedFuture(null);
@Unique ThreadLocal<GameProfile> sender = new ThreadLocal<>();
@Redirect(method = "onGameMessage(Lnet/minecraft/text/Text;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;setOverlayMessage(Lnet/minecraft/text/Text;Z)V"))
private void googlechat$onGameMessage$setOverlayMessage(InGameHud instance, Text message, boolean tinted) {
if (googlechat$shouldTranslate()) googlechat$schedule(() -> instance.setOverlayMessage(googlechat$s2c(message), tinted));
else instance.setOverlayMessage(message, tinted);
}
@Redirect(method = "onGameMessage(Lnet/minecraft/text/Text;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;addMessage(Lnet/minecraft/text/Text;)V"))
private void googlechat$onGameMessage$addMessage(ChatHud instance, Text text) {
if (googlechat$shouldTranslate()) googlechat$schedule(() -> instance.addMessage(googlechat$s2c(text)));
else instance.addMessage(text);
}
@Redirect(method = "onGameMessage(Lnet/minecraft/text/Text;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/NarratorManager;narrateSystemMessage(Lnet/minecraft/text/Text;)V"))
private void googlechat$onGameMessage$narrateSystemMessage(NarratorManager instance, Text text) {
if (googlechat$shouldTranslate()) googlechat$schedule(() -> instance.narrateSystemMessage(googlechat$s2c(text)));
else instance.narrateSystemMessage(text);
}
@Redirect(method = "method_45745(Lnet/minecraft/network/message/MessageType$Parameters;Lnet/minecraft/text/Text;Ljava/time/Instant;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;addMessage(Lnet/minecraft/text/Text;)V"))
private void googlechat$onProfilelessMessage$addMessage(ChatHud instance, Text text) {
if (googlechat$shouldTranslate()) googlechat$schedule(() -> instance.addMessage(googlechat$s2c(text)));
else instance.addMessage(text);
}
@Redirect(method = "method_45745(Lnet/minecraft/network/message/MessageType$Parameters;Lnet/minecraft/text/Text;Ljava/time/Instant;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/message/MessageHandler;narrate(Lnet/minecraft/network/message/MessageType$Parameters;Lnet/minecraft/text/Text;)V"))
private void googlechat$onProfilelessMessage$narrate(MessageHandler instance, MessageType.Parameters params, Text message) {
if (instance != (Object) this) GoogleChat.LOGGER.warn("Mismatched message handler in onGameMessage");
if (googlechat$shouldTranslate()) googlechat$schedule(() -> narrate(params, googlechat$s2c(message)));
else narrate(params, message);
}
@Inject(method = "onChatMessage(Lnet/minecraft/network/message/SignedMessage;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/message/MessageType$Parameters;)V", at = @At("HEAD"))
private void googlechat$onChatMessage$extractSender(SignedMessage message, GameProfile sender, MessageType.Parameters params, CallbackInfo ci) {
this.sender.set(sender);
}
@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/client/gui/hud/ChatHud;addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V"))
private void googlechat$processChatMessageInternal$addMessage(ChatHud instance, Text message, MessageSignatureData signature, MessageIndicator indicator) {
if (googlechat$shouldTranslate()) googlechat$schedule(() -> instance.addMessage(googlechat$s2c(message), signature, indicator));
else instance.addMessage(message, signature, indicator);
}
@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/client/network/message/MessageHandler;narrate(Lnet/minecraft/network/message/MessageType$Parameters;Lnet/minecraft/text/Text;)V"))
private void googlechat$processChatMessageInternal$narrate(MessageHandler instance, MessageType.Parameters params, Text message) {
if (instance != (Object) this) GoogleChat.LOGGER.warn("Mismatched message handler in onGameMessage");
if (googlechat$shouldTranslate()) googlechat$schedule(() -> narrate(params, googlechat$s2c(message)));
else narrate(params, message);
}
@Inject(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("RETURN"))
private void googlechat$processChatMessageInternal$clearSender(MessageType.Parameters params, SignedMessage message, Text decorated, GameProfile sender, boolean onlyShowSecureChat, Instant receptionTimestamp, CallbackInfoReturnable<Boolean> cir) {
this.sender.remove();
}
private Text googlechat$s2c(Text message) {
return GoogleChat.translateIfNeeded(message, TranslationDirection.S2C, true);
}
private void googlechat$schedule(Runnable runnable) {
if (!GoogleChatConfig.Advanced.async) runnable.run();
else googlechat$currentFuture.whenCompleteAsync((_1, _2) -> runnable.run()).exceptionally(throwable -> {
GoogleChat.LOGGER.error("Something went wrong while processing a message", throwable);
return null;
});
}
private boolean googlechat$shouldTranslate() {
if (!GoogleChatConfig.General.enabled) return false;
if (client == null || client.player == null) return false;
var sender = this.sender.get();
if (sender == null) return true;
return !sender.getId().equals(client.player.getUuid());
}
}