Update to 1.19-pre1

This commit is contained in:
shedaniel
2022-05-19 20:19:08 +08:00
parent 0adf9a2e6d
commit 258d23c62e
12 changed files with 172 additions and 91 deletions

View File

@@ -9,7 +9,7 @@ dependencies {
} }
architectury { architectury {
common(rootProject.forgeEnabled.toBoolean()) common(rootProject.platforms.split(","))
} }
/** /**

View File

@@ -22,13 +22,16 @@ package dev.architectury.event.events.common;
import dev.architectury.event.CompoundEventResult; import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.Event; import dev.architectury.event.Event;
import dev.architectury.event.EventFactory; import dev.architectury.event.EventFactory;
import dev.architectury.event.EventResult;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public interface ChatEvent { public interface ChatEvent {
/** /**
* @see Server#process(ServerPlayer, Component) * @see Server#process(ServerPlayer, ChatComponent)
*/ */
Event<Server> SERVER = EventFactory.createEventResult(); Event<Server> SERVER = EventFactory.createEventResult();
@@ -39,9 +42,37 @@ public interface ChatEvent {
* *
* @param player The player who has sent the message, or null. * @param player The player who has sent the message, or null.
* @param component The message as component. * @param component The message as component.
* @return A {@link CompoundEventResult} determining the outcome of the event, * @return A {@link EventResult} determining the outcome of the event,
* if an outcome is set, the sent message is overridden. * the execution of the vanilla message may be cancelled by the result.
*/ */
CompoundEventResult<Component> process(@Nullable ServerPlayer player, Component component); EventResult process(@Nullable ServerPlayer player, ChatComponent component);
}
interface ChatComponent {
Component getRaw();
@Nullable
Component getFiltered();
void setRaw(Component raw);
void setFiltered(@Nullable Component filtered);
default void modifyRaw(Function<Component, Component> function) {
setRaw(function.apply(getRaw()));
}
default void modifyFiltered(Function<Component, Component> function) {
Component filtered = getFiltered();
if (filtered != null) {
setFiltered(function.apply(filtered));
}
}
default void modifyBoth(Function<Component, Component> function) {
modifyRaw(function);
modifyFiltered(function);
}
} }
} }

View File

@@ -1,3 +1,22 @@
/*
* 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.hooks.item.tool.fabric; package dev.architectury.hooks.item.tool.fabric;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;

View File

@@ -0,0 +1,58 @@
/*
* 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.impl.fabric;
import dev.architectury.event.events.common.ChatEvent;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@ApiStatus.Internal
public class ChatComponentImpl implements ChatEvent.ChatComponent {
private Component raw;
@Nullable
private Component filtered;
public ChatComponentImpl(Component raw, @Nullable Component filtered) {
this.raw = raw;
this.filtered = filtered;
}
@Override
public Component getRaw() {
return raw;
}
@Override
@Nullable
public Component getFiltered() {
return filtered;
}
@Override
public void setRaw(Component raw) {
this.raw = raw;
}
@Override
public void setFiltered(@Nullable Component filtered) {
this.filtered = filtered;
}
}

View File

@@ -19,13 +19,17 @@
package dev.architectury.impl.fabric; package dev.architectury.impl.fabric;
import dev.architectury.event.events.common.ChatEvent;
import net.minecraft.network.chat.ChatDecorator; import net.minecraft.network.chat.ChatDecorator;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MessageSignature; import net.minecraft.network.chat.MessageSignature;
import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.FilteredText;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public class EventChatDecorator implements ChatDecorator { public class EventChatDecorator implements ChatDecorator {
public static final Component CANCELLING_COMPONENT = Component.literal("THIS SHOULDN'T BE DISPLAYED, ARCHITECTURY SPECIFIC STRING DO NOT IMITATE THIS"); 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 ChatDecorator parent;
@@ -37,32 +41,46 @@ public class EventChatDecorator implements ChatDecorator {
} }
@Override @Override
public Component decorate(@Nullable ServerPlayer player, Component component) { public CompletableFuture<Component> decorate(@Nullable ServerPlayer player, Component component) {
return processor.process(player, parent.decorate(player, component)); return parent.decorate(player, component).thenApply(c -> {
return processor.process(player, FilteredText.fullyFiltered(c)).raw();
}).exceptionally(throwable -> {
throwable.printStackTrace();
return component;
});
} }
@Override @Override
public PlayerChatMessage decorate(@Nullable ServerPlayer player, Component component, MessageSignature signature, boolean signedPreview) { public CompletableFuture<FilteredText<Component>> decorateFiltered(@Nullable ServerPlayer player, FilteredText<Component> message) {
PlayerChatMessage message = parent.decorate(player, component, signature, signedPreview); return parent.decorateFiltered(player, message).thenApply(newMessage -> {
Component newContent = processor.process(player, component); FilteredText<Component> newContent = processor.process(player, newMessage);
if (!newContent.equals(component)) { if (!newContent.equals(newMessage)) {
return !signedPreview ? PlayerChatMessage.signed(component, signature).withUnsignedContent(newContent) : PlayerChatMessage.signed(newContent, signature); return newContent;
} }
return newMessage;
}).exceptionally(throwable -> {
throwable.printStackTrace();
return message; return message;
});
} }
@Override @Override
public PlayerChatMessage decorate(@Nullable ServerPlayer player, PlayerChatMessage message) { public CompletableFuture<FilteredText<PlayerChatMessage>> decorateChat(@Nullable ServerPlayer player, FilteredText<Component> component, MessageSignature signature, boolean signedPreview) {
PlayerChatMessage newMessage = parent.decorate(player, message.signedContent(), message.signature(), false); return parent.decorateChat(player, component, signature, signedPreview).thenApply(message -> {
Component newContent = processor.process(player, message.signedContent()); FilteredText<Component> newComponent = processor.process(player, message.map(PlayerChatMessage::signedContent));
if (!newContent.equals(message.signedContent())) { FilteredText<PlayerChatMessage> newMessage = PlayerChatMessage.filteredSigned(component, newComponent, signature, signedPreview);
return PlayerChatMessage.signed(message.signedContent(), message.signature()).withUnsignedContent(newContent); if (!newMessage.equals(message)) {
return newMessage;
} }
return message; return message;
}).exceptionally(throwable -> {
throwable.printStackTrace();
return PlayerChatMessage.filteredSigned(component, component, signature, signedPreview);
});
} }
@FunctionalInterface @FunctionalInterface
public interface ChatProcessor { public interface ChatProcessor {
Component process(@Nullable ServerPlayer player, Component component); FilteredText<Component> process(@Nullable ServerPlayer player, FilteredText<Component> text);
} }
} }

View File

@@ -20,11 +20,14 @@
package dev.architectury.mixin.fabric; package dev.architectury.mixin.fabric;
import dev.architectury.event.CompoundEventResult; import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.common.ChatEvent; import dev.architectury.event.events.common.ChatEvent;
import dev.architectury.impl.fabric.ChatComponentImpl;
import dev.architectury.impl.fabric.EventChatDecorator; import dev.architectury.impl.fabric.EventChatDecorator;
import net.minecraft.network.chat.ChatDecorator; import net.minecraft.network.chat.ChatDecorator;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.FilteredText;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -36,12 +39,13 @@ public class MixinMinecraftServer {
private void getChatDecorator(CallbackInfoReturnable<ChatDecorator> cir) { private void getChatDecorator(CallbackInfoReturnable<ChatDecorator> cir) {
ChatDecorator parent = cir.getReturnValue(); ChatDecorator parent = cir.getReturnValue();
cir.setReturnValue(new EventChatDecorator(parent, (player, component) -> { cir.setReturnValue(new EventChatDecorator(parent, (player, component) -> {
CompoundEventResult<Component> result = ChatEvent.SERVER.invoker().process(player, component); ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component.raw(), component.filtered());
EventResult result = ChatEvent.SERVER.invoker().process(player, chatComponent);
if (result.isPresent()) { if (result.isPresent()) {
if (result.isFalse()) { if (result.isFalse()) {
return EventChatDecorator.CANCELLING_COMPONENT; return FilteredText.fullyFiltered(EventChatDecorator.CANCELLING_COMPONENT);
} else if (result.object() != null) { } else {
return result.object(); return new FilteredText<>(chatComponent.getRaw(), chatComponent.getFiltered());
} }
} }

View File

@@ -26,6 +26,7 @@ import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.network.protocol.game.ServerboundChatPacket; import net.minecraft.network.protocol.game.ServerboundChatPacket;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.FilteredText;
import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.TextFilter; import net.minecraft.server.network.TextFilter;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@@ -48,11 +49,12 @@ public abstract class MixinServerGamePacketListenerImpl {
@Shadow @Shadow
protected abstract void detectRateSpam(); protected abstract void detectRateSpam();
@Inject(method = "handleChat(Lnet/minecraft/network/protocol/game/ServerboundChatPacket;Lnet/minecraft/server/network/TextFilter$FilteredText;)V", @Inject(method = "broadcastChatMessage",
at = @At(value = "INVOKE", at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/chat/PlayerChatMessage;verify(Lnet/minecraft/world/entity/player/ProfilePublicKey;)Z"), target = "Lnet/minecraft/network/chat/PlayerChatMessage;verify(Lnet/minecraft/server/level/ServerPlayer;)Z"),
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) cancellable = true)
private void handleChat(ServerboundChatPacket packet, TextFilter.FilteredText message, CallbackInfo ci, Component component, MessageSignature signature, PlayerChatMessage chatMessage) { private void handleChat(FilteredText<PlayerChatMessage> filteredText, CallbackInfo ci) {
PlayerChatMessage chatMessage = filteredText.raw();
if (chatMessage.serverContent().equals(EventChatDecorator.CANCELLING_COMPONENT)) { if (chatMessage.serverContent().equals(EventChatDecorator.CANCELLING_COMPONENT)) {
ci.cancel(); ci.cancel();
} }

View File

@@ -1,51 +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.server;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.events.common.ChatEvent;
import dev.architectury.impl.fabric.EventChatDecorator;
import net.minecraft.network.chat.ChatDecorator;
import net.minecraft.network.chat.Component;
import net.minecraft.server.dedicated.DedicatedServer;
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(DedicatedServer.class)
public class MixinDedicatedServer {
@Inject(method = "getChatDecorator", at = @At("RETURN"), cancellable = true)
private void getChatDecorator(CallbackInfoReturnable<ChatDecorator> cir) {
ChatDecorator parent = cir.getReturnValue();
cir.setReturnValue(new EventChatDecorator(parent, (player, component) -> {
CompoundEventResult<Component> result = ChatEvent.SERVER.invoker().process(player, component);
if (result.isPresent()) {
if (result.isFalse()) {
return EventChatDecorator.CANCELLING_COMPONENT;
} else if (result.object() != null) {
return result.object();
}
}
return component;
}));
}
}

View File

@@ -22,7 +22,6 @@
"client.MixinTextureAtlas" "client.MixinTextureAtlas"
], ],
"mixins": [ "mixins": [
"server.MixinDedicatedServer",
"BucketItemAccessor", "BucketItemAccessor",
"ExplosionPreInvoker", "ExplosionPreInvoker",
"HorseTameInvoker", "HorseTameInvoker",

View File

@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx6G org.gradle.jvmargs=-Xmx6G
org.gradle.daemon=false org.gradle.daemon=false
forgeEnabled=false platforms=fabric
minecraft_version=22w19a minecraft_version=1.19-pre1
supported_version=22w19a supported_version=1.19-pre1
cf_type=beta cf_type=beta
@@ -14,7 +14,7 @@ base_version=5.4
maven_group=dev.architectury maven_group=dev.architectury
fabric_loader_version=0.14.5 fabric_loader_version=0.14.5
fabric_api_version=0.52.2+1.19 fabric_api_version=0.52.4+1.19
mod_menu_version=3.1.0 mod_menu_version=3.1.0
forge_version=40.1.14 forge_version=40.1.14

View File

@@ -6,5 +6,5 @@ dependencies {
} }
architectury { architectury {
common(rootProject.forgeEnabled.toBoolean()) common(rootProject.platforms.split(","))
} }

View File

@@ -62,11 +62,12 @@ public class DebugEvents {
return EventResult.pass(); return EventResult.pass();
}); });
ChatEvent.SERVER.register((player, message) -> { ChatEvent.SERVER.register((player, message) -> {
TestMod.SINK.accept("Server chat received: " + message); TestMod.SINK.accept("Server chat received: " + message.getRaw());
if (message.getString().contains("shit")) { if (message.getRaw().getString().contains("shit")) {
return CompoundEventResult.interruptFalse(Component.empty()); return EventResult.interruptFalse();
} }
return CompoundEventResult.interruptTrue(message.copy().withStyle(ChatFormatting.AQUA)); message.modifyBoth(component -> component.copy().withStyle(ChatFormatting.AQUA));
return EventResult.interruptTrue();
}); });
CommandPerformEvent.EVENT.register(event -> { CommandPerformEvent.EVENT.register(event -> {
TestMod.SINK.accept("Server command performed: " + event.getResults().getReader().getString()); TestMod.SINK.accept("Server command performed: " + event.getResults().getReader().getString());