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 {
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.Event;
import dev.architectury.event.EventFactory;
import dev.architectury.event.EventResult;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public interface ChatEvent {
/**
* @see Server#process(ServerPlayer, Component)
* @see Server#process(ServerPlayer, ChatComponent)
*/
Event<Server> SERVER = EventFactory.createEventResult();
@@ -39,9 +42,37 @@ public interface ChatEvent {
*
* @param player The player who has sent the message, or null.
* @param component The message as component.
* @return A {@link CompoundEventResult} determining the outcome of the event,
* if an outcome is set, the sent message is overridden.
* @return A {@link EventResult} determining the outcome of the event,
* 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;
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;
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 static final Component CANCELLING_COMPONENT = Component.literal("THIS SHOULDN'T BE DISPLAYED, ARCHITECTURY SPECIFIC STRING DO NOT IMITATE THIS");
private final ChatDecorator parent;
@@ -37,32 +41,46 @@ public class EventChatDecorator implements ChatDecorator {
}
@Override
public Component decorate(@Nullable ServerPlayer player, Component component) {
return processor.process(player, parent.decorate(player, component));
public CompletableFuture<Component> 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 PlayerChatMessage decorate(@Nullable ServerPlayer player, Component component, MessageSignature signature, boolean signedPreview) {
PlayerChatMessage message = parent.decorate(player, component, signature, signedPreview);
Component newContent = processor.process(player, component);
if (!newContent.equals(component)) {
return !signedPreview ? PlayerChatMessage.signed(component, signature).withUnsignedContent(newContent) : PlayerChatMessage.signed(newContent, signature);
}
return message;
public CompletableFuture<FilteredText<Component>> decorateFiltered(@Nullable ServerPlayer player, FilteredText<Component> message) {
return parent.decorateFiltered(player, message).thenApply(newMessage -> {
FilteredText<Component> newContent = processor.process(player, newMessage);
if (!newContent.equals(newMessage)) {
return newContent;
}
return newMessage;
}).exceptionally(throwable -> {
throwable.printStackTrace();
return message;
});
}
@Override
public PlayerChatMessage decorate(@Nullable ServerPlayer player, PlayerChatMessage message) {
PlayerChatMessage newMessage = parent.decorate(player, message.signedContent(), message.signature(), false);
Component newContent = processor.process(player, message.signedContent());
if (!newContent.equals(message.signedContent())) {
return PlayerChatMessage.signed(message.signedContent(), message.signature()).withUnsignedContent(newContent);
}
return message;
public CompletableFuture<FilteredText<PlayerChatMessage>> decorateChat(@Nullable ServerPlayer player, FilteredText<Component> component, MessageSignature signature, boolean signedPreview) {
return parent.decorateChat(player, component, signature, signedPreview).thenApply(message -> {
FilteredText<Component> newComponent = processor.process(player, message.map(PlayerChatMessage::signedContent));
FilteredText<PlayerChatMessage> 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 {
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;
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;
@@ -36,12 +39,13 @@ public class MixinMinecraftServer {
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);
ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component.raw(), component.filtered());
EventResult result = ChatEvent.SERVER.invoker().process(player, chatComponent);
if (result.isPresent()) {
if (result.isFalse()) {
return EventChatDecorator.CANCELLING_COMPONENT;
} else if (result.object() != null) {
return result.object();
return FilteredText.fullyFiltered(EventChatDecorator.CANCELLING_COMPONENT);
} else {
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.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.FilteredText;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.TextFilter;
import org.spongepowered.asm.mixin.Final;
@@ -48,11 +49,12 @@ public abstract class MixinServerGamePacketListenerImpl {
@Shadow
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",
target = "Lnet/minecraft/network/chat/PlayerChatMessage;verify(Lnet/minecraft/world/entity/player/ProfilePublicKey;)Z"),
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
private void handleChat(ServerboundChatPacket packet, TextFilter.FilteredText message, CallbackInfo ci, Component component, MessageSignature signature, PlayerChatMessage chatMessage) {
target = "Lnet/minecraft/network/chat/PlayerChatMessage;verify(Lnet/minecraft/server/level/ServerPlayer;)Z"),
cancellable = true)
private void handleChat(FilteredText<PlayerChatMessage> filteredText, CallbackInfo ci) {
PlayerChatMessage chatMessage = filteredText.raw();
if (chatMessage.serverContent().equals(EventChatDecorator.CANCELLING_COMPONENT)) {
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"
],
"mixins": [
"server.MixinDedicatedServer",
"BucketItemAccessor",
"ExplosionPreInvoker",
"HorseTameInvoker",

View File

@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx6G
org.gradle.daemon=false
forgeEnabled=false
platforms=fabric
minecraft_version=22w19a
supported_version=22w19a
minecraft_version=1.19-pre1
supported_version=1.19-pre1
cf_type=beta
@@ -14,7 +14,7 @@ base_version=5.4
maven_group=dev.architectury
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
forge_version=40.1.14

View File

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

View File

@@ -62,11 +62,12 @@ public class DebugEvents {
return EventResult.pass();
});
ChatEvent.SERVER.register((player, message) -> {
TestMod.SINK.accept("Server chat received: " + message);
if (message.getString().contains("shit")) {
return CompoundEventResult.interruptFalse(Component.empty());
TestMod.SINK.accept("Server chat received: " + message.getRaw());
if (message.getRaw().getString().contains("shit")) {
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 -> {
TestMod.SINK.accept("Server command performed: " + event.getResults().getReader().getString());