From cf97a7f5eedd86276786f431c11b4675c15f89d3 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 16 Jul 2022 17:02:23 +0800 Subject: [PATCH 1/2] Switch to Fabric events for processing chat --- .../event/fabric/EventHandlerImpl.java | 25 ++++++-- .../impl/fabric/EventChatDecorator.java | 62 +------------------ .../mixin/fabric/MixinMinecraftServer.java | 55 ---------------- .../main/resources/architectury.mixins.json | 1 - .../architectury/test/events/DebugEvents.java | 6 +- 5 files changed, 27 insertions(+), 122 deletions(-) delete mode 100644 fabric/src/main/java/dev/architectury/mixin/fabric/MixinMinecraftServer.java diff --git a/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java b/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java index 4ed7d0a7c..a279f26a8 100644 --- a/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java +++ b/fabric/src/main/java/dev/architectury/event/fabric/EventHandlerImpl.java @@ -19,14 +19,14 @@ package dev.architectury.event.fabric; +import dev.architectury.event.EventResult; import dev.architectury.event.events.client.ClientGuiEvent; import dev.architectury.event.events.client.ClientLifecycleEvent; import dev.architectury.event.events.client.ClientTickEvent; import dev.architectury.event.events.client.ClientTooltipEvent; -import dev.architectury.event.events.common.CommandRegistrationEvent; -import dev.architectury.event.events.common.InteractionEvent; -import dev.architectury.event.events.common.LifecycleEvent; -import dev.architectury.event.events.common.TickEvent; +import dev.architectury.event.events.common.*; +import dev.architectury.impl.fabric.ChatComponentImpl; +import dev.architectury.impl.fabric.EventChatDecorator; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; @@ -40,6 +40,9 @@ import net.fabricmc.fabric.api.event.player.AttackBlockCallback; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.player.UseItemCallback; +import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent; + +import java.util.concurrent.CompletableFuture; public class EventHandlerImpl { @Environment(EnvType.CLIENT) @@ -75,6 +78,20 @@ public static void registerCommon() { UseItemCallback.EVENT.register((player, world, hand) -> InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(player, hand).asMinecraft()); UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> InteractionEvent.RIGHT_CLICK_BLOCK.invoker().click(player, hand, hitResult.getBlockPos(), hitResult.getDirection()).asMinecraft()); AttackBlockCallback.EVENT.register((player, world, hand, pos, face) -> InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(player, hand, pos, face).asMinecraft()); + + ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (player, component) -> { + ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component, component); + EventResult result = ChatEvent.SERVER.invoker().process(player, chatComponent); + if (result.isPresent()) { + if (result.isFalse()) { + return CompletableFuture.completedFuture(EventChatDecorator.CANCELLING_COMPONENT); + } else { + return CompletableFuture.completedFuture(chatComponent.getFiltered()); + } + } + + return CompletableFuture.completedFuture(component); + }); } @Environment(EnvType.SERVER) diff --git a/fabric/src/main/java/dev/architectury/impl/fabric/EventChatDecorator.java b/fabric/src/main/java/dev/architectury/impl/fabric/EventChatDecorator.java index 00ae7d107..a1fddbb92 100644 --- a/fabric/src/main/java/dev/architectury/impl/fabric/EventChatDecorator.java +++ b/fabric/src/main/java/dev/architectury/impl/fabric/EventChatDecorator.java @@ -19,68 +19,8 @@ package dev.architectury.impl.fabric; -import dev.architectury.event.events.common.ChatEvent; -import net.minecraft.network.chat.ChatDecorator; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MessageSignature; -import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.FilteredText; -import org.jetbrains.annotations.Nullable; -import java.util.concurrent.CompletableFuture; - -public class EventChatDecorator implements ChatDecorator { +public class EventChatDecorator { public static final Component CANCELLING_COMPONENT = Component.literal("THIS SHOULDN'T BE DISPLAYED, ARCHITECTURY SPECIFIC STRING DO NOT IMITATE THIS"); - private final ChatDecorator parent; - private final ChatProcessor processor; - - public EventChatDecorator(ChatDecorator parent, ChatProcessor processor) { - this.parent = parent; - this.processor = processor; - } - - @Override - public CompletableFuture decorate(@Nullable ServerPlayer player, Component component) { - return parent.decorate(player, component).thenApply(c -> { - return processor.process(player, FilteredText.fullyFiltered(c)).raw(); - }).exceptionally(throwable -> { - throwable.printStackTrace(); - return component; - }); - } - - @Override - public CompletableFuture> decorateFiltered(@Nullable ServerPlayer player, FilteredText message) { - return parent.decorateFiltered(player, message).thenApply(newMessage -> { - FilteredText newContent = processor.process(player, newMessage); - if (!newContent.equals(newMessage)) { - return newContent; - } - return newMessage; - }).exceptionally(throwable -> { - throwable.printStackTrace(); - return message; - }); - } - - @Override - public CompletableFuture> decorateChat(@Nullable ServerPlayer player, FilteredText component, MessageSignature signature, boolean signedPreview) { - return parent.decorateChat(player, component, signature, signedPreview).thenApply(message -> { - FilteredText newComponent = processor.process(player, message.map(PlayerChatMessage::signedContent)); - FilteredText newMessage = PlayerChatMessage.filteredSigned(component, newComponent, signature, signedPreview); - if (!newMessage.equals(message)) { - return newMessage; - } - return message; - }).exceptionally(throwable -> { - throwable.printStackTrace(); - return PlayerChatMessage.filteredSigned(component, component, signature, signedPreview); - }); - } - - @FunctionalInterface - public interface ChatProcessor { - FilteredText process(@Nullable ServerPlayer player, FilteredText text); - } } diff --git a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinMinecraftServer.java b/fabric/src/main/java/dev/architectury/mixin/fabric/MixinMinecraftServer.java deleted file mode 100644 index d7d180932..000000000 --- a/fabric/src/main/java/dev/architectury/mixin/fabric/MixinMinecraftServer.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of architectury. - * Copyright (C) 2020, 2021, 2022 architectury - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package dev.architectury.mixin.fabric; - -import dev.architectury.event.CompoundEventResult; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.common.ChatEvent; -import dev.architectury.impl.fabric.ChatComponentImpl; -import dev.architectury.impl.fabric.EventChatDecorator; -import net.minecraft.network.chat.ChatDecorator; -import net.minecraft.network.chat.Component; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.FilteredText; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(MinecraftServer.class) -public class MixinMinecraftServer { - @Inject(method = "getChatDecorator", at = @At("RETURN"), cancellable = true) - private void getChatDecorator(CallbackInfoReturnable cir) { - ChatDecorator parent = cir.getReturnValue(); - cir.setReturnValue(new EventChatDecorator(parent, (player, component) -> { - ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component.raw(), component.filtered()); - EventResult result = ChatEvent.SERVER.invoker().process(player, chatComponent); - if (result.isPresent()) { - if (result.isFalse()) { - return FilteredText.fullyFiltered(EventChatDecorator.CANCELLING_COMPONENT); - } else { - return new FilteredText<>(chatComponent.getRaw(), chatComponent.getFiltered()); - } - } - - return component; - })); - } -} diff --git a/fabric/src/main/resources/architectury.mixins.json b/fabric/src/main/resources/architectury.mixins.json index aecc7fade..70f92bb9c 100644 --- a/fabric/src/main/resources/architectury.mixins.json +++ b/fabric/src/main/resources/architectury.mixins.json @@ -44,7 +44,6 @@ "MixinInventory", "MixinItemEntity", "MixinLivingEntity", - "MixinMinecraftServer", "MixinNaturalSpawner", "MixinOcelot", "MixinPatrolSpawner", diff --git a/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java b/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java index edc171c4c..1700e8ed4 100644 --- a/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java +++ b/testmod-common/src/main/java/dev/architectury/test/events/DebugEvents.java @@ -66,7 +66,7 @@ public static void debugEvents() { if (message.getRaw().getString().contains("shit")) { return EventResult.interruptFalse(); } - message.modifyBoth(component -> component.copy().withStyle(ChatFormatting.AQUA)); + message.modifyBoth(component -> component.copy().withStyle(ChatFormatting.AQUA).append(" + new text")); return EventResult.interruptTrue(); }); CommandPerformEvent.EVENT.register(event -> { @@ -255,6 +255,10 @@ public static void debugEventsClient() { }); ClientChatEvent.PROCESS.register((message) -> { TestMod.SINK.accept("Client chat sent: " + message.getMessage()); + if (message.getMessage().contains("error")) { + message.setMessage("Error: " + message.getMessage()); + return EventResult.interruptTrue(); + } return EventResult.pass(); }); ClientChatEvent.RECEIVED.register((type, message, sender) -> { From 95bc9b6ec6e07f46675f766c2b8b594898d0de3c Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 16 Jul 2022 17:02:36 +0800 Subject: [PATCH 2/2] Fix Forge cancelling client message processing --- .../dev/architectury/event/forge/EventHandlerImplClient.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java index f97cce927..eea7b2865 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java @@ -107,10 +107,6 @@ public static void event(net.minecraftforge.client.event.ClientChatEvent event) event.setCanceled(true); else { event.setMessage(processor.getMessage()); - - if (process.isTrue()) { - event.setCanceled(true); - } } } }