mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
@@ -26,8 +26,8 @@ import net.minecraft.world.item.RecordItem;
|
|||||||
public class ArchitecturyRecordItem extends RecordItem {
|
public class ArchitecturyRecordItem extends RecordItem {
|
||||||
private final RegistrySupplier<SoundEvent> sound;
|
private final RegistrySupplier<SoundEvent> sound;
|
||||||
|
|
||||||
public ArchitecturyRecordItem(int analogOutput, RegistrySupplier<SoundEvent> sound, Properties properties, int lengthInSeconds) {
|
public ArchitecturyRecordItem(int analogOutput, RegistrySupplier<SoundEvent> sound, Properties properties) {
|
||||||
super(analogOutput, sound.orElse(null), properties, lengthInSeconds);
|
super(analogOutput, sound.orElse(null), properties);
|
||||||
this.sound = sound;
|
this.sound = sound;
|
||||||
|
|
||||||
if (!sound.isPresent()) {
|
if (!sound.isPresent()) {
|
||||||
|
|||||||
@@ -25,33 +25,49 @@ import dev.architectury.event.EventFactory;
|
|||||||
import dev.architectury.event.EventResult;
|
import dev.architectury.event.EventResult;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.chat.ClientChatPreview;
|
||||||
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
|
import net.minecraft.network.chat.ChatSender;
|
||||||
import net.minecraft.network.chat.ChatType;
|
import net.minecraft.network.chat.ChatType;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public interface ClientChatEvent {
|
public interface ClientChatEvent {
|
||||||
/**
|
/**
|
||||||
* @see Send#send(String, Component)
|
* @see Process#process(ChatProcessor)
|
||||||
*/
|
*/
|
||||||
Event<Send> SEND = EventFactory.createEventResult();
|
Event<Process> PROCESS = EventFactory.createEventResult();
|
||||||
/**
|
/**
|
||||||
* @see Received#process(ChatType.Bound, Component)
|
* @see Received#process(ChatType, Component, ChatSender)
|
||||||
*/
|
*/
|
||||||
Event<Received> RECEIVED = EventFactory.createCompoundEventResult();
|
Event<Received> RECEIVED = EventFactory.createCompoundEventResult();
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
interface Send {
|
interface Process {
|
||||||
/**
|
/**
|
||||||
* Event to cancel clients sending the chat message.
|
* Event to modify the chat message a clients sends.
|
||||||
* Equivalent to Forge's {@code ClientChatEvent} event.
|
* Equivalent to Forge's {@code ClientChatEvent} event.
|
||||||
*
|
*
|
||||||
* @param message The chat message.
|
* @param processor The chat message the client wants to send.
|
||||||
* @param component The chat component that was decorated, can be {@code null}.
|
|
||||||
* @return A {@link EventResult} determining the outcome of the event,
|
* @return A {@link EventResult} determining the outcome of the event,
|
||||||
* if an outcome is set, the message and component will be ignored.
|
* if an outcome is set, the sent message is overridden.
|
||||||
*/
|
*/
|
||||||
EventResult send(String message, @Nullable Component component);
|
EventResult process(ChatProcessor processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChatProcessor {
|
||||||
|
String getMessage();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
Component getComponent();
|
||||||
|
|
||||||
|
void setMessage(String message);
|
||||||
|
|
||||||
|
void setComponent(@Nullable Component component);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
@@ -63,9 +79,10 @@ public interface ClientChatEvent {
|
|||||||
*
|
*
|
||||||
* @param type Where was the message emitted from.
|
* @param type Where was the message emitted from.
|
||||||
* @param message The chat message.
|
* @param message The chat message.
|
||||||
|
* @param sender The packet sender. Can be {@code null}, but probably is the sending player UUID or null for system messages.
|
||||||
* @return A {@link CompoundEventResult} determining the outcome of the event,
|
* @return A {@link CompoundEventResult} determining the outcome of the event,
|
||||||
* if an outcome is set, the received message is overridden.
|
* if an outcome is set, the received message is overridden.
|
||||||
*/
|
*/
|
||||||
CompoundEventResult<Component> process(ChatType.Bound type, Component message);
|
CompoundEventResult<Component> process(ChatType type, Component message, @Nullable ChatSender sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package dev.architectury.event.events.common;
|
package dev.architectury.event.events.common;
|
||||||
|
|
||||||
|
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 dev.architectury.event.EventResult;
|
||||||
@@ -26,30 +27,15 @@ 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 Decorate#decorate(ServerPlayer, ChatComponent)
|
* @see Server#process(ServerPlayer, ChatComponent)
|
||||||
*/
|
*/
|
||||||
Event<Decorate> DECORATE = EventFactory.createLoop();
|
Event<Server> SERVER = EventFactory.createEventResult();
|
||||||
/**
|
|
||||||
* @see Received#received(ServerPlayer, Component)
|
|
||||||
*/
|
|
||||||
Event<Received> RECEIVED = EventFactory.createEventResult();
|
|
||||||
|
|
||||||
@FunctionalInterface
|
interface Server {
|
||||||
interface Decorate {
|
|
||||||
/**
|
|
||||||
* Invoked when the server receives a message from a client.
|
|
||||||
* Equivalent to Forge's {@code ServerChatEvent} event.
|
|
||||||
*
|
|
||||||
* @param player The player who has sent the message, or null.
|
|
||||||
* @param component The message as component.
|
|
||||||
*/
|
|
||||||
void decorate(@Nullable ServerPlayer player, ChatComponent component);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface Received {
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the server receives a message from a client.
|
* Invoked when the server receives a message from a client.
|
||||||
* Equivalent to Forge's {@code ServerChatEvent} event.
|
* Equivalent to Forge's {@code ServerChatEvent} event.
|
||||||
@@ -59,12 +45,34 @@ public interface ChatEvent {
|
|||||||
* @return A {@link EventResult} determining the outcome of the event,
|
* @return A {@link EventResult} determining the outcome of the event,
|
||||||
* the execution of the vanilla message may be cancelled by the result.
|
* the execution of the vanilla message may be cancelled by the result.
|
||||||
*/
|
*/
|
||||||
EventResult received(@Nullable ServerPlayer player, Component component);
|
EventResult process(@Nullable ServerPlayer player, ChatComponent component);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChatComponent {
|
interface ChatComponent {
|
||||||
Component get();
|
Component getRaw();
|
||||||
|
|
||||||
void set(Component component);
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,12 @@ package dev.architectury.event.events.common;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import dev.architectury.event.Event;
|
import dev.architectury.event.Event;
|
||||||
import dev.architectury.event.EventFactory;
|
import dev.architectury.event.EventFactory;
|
||||||
import net.minecraft.commands.CommandBuildContext;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.commands.Commands;
|
import net.minecraft.commands.Commands;
|
||||||
|
|
||||||
public interface CommandRegistrationEvent {
|
public interface CommandRegistrationEvent {
|
||||||
/**
|
/**
|
||||||
* @see CommandRegistrationEvent#register(CommandDispatcher, CommandBuildContext, Commands.CommandSelection)
|
* @see CommandRegistrationEvent#register(CommandDispatcher, Commands.CommandSelection)
|
||||||
*/
|
*/
|
||||||
Event<CommandRegistrationEvent> EVENT = EventFactory.createLoop();
|
Event<CommandRegistrationEvent> EVENT = EventFactory.createLoop();
|
||||||
|
|
||||||
@@ -37,8 +36,7 @@ public interface CommandRegistrationEvent {
|
|||||||
* Equivalent to Forge's {@code RegisterCommandsEvent} and Fabric's {@code CommandRegistrationCallback}.
|
* Equivalent to Forge's {@code RegisterCommandsEvent} and Fabric's {@code CommandRegistrationCallback}.
|
||||||
*
|
*
|
||||||
* @param dispatcher The command dispatcher to register commands to.
|
* @param dispatcher The command dispatcher to register commands to.
|
||||||
* @param registry The command registry for building arguments.
|
|
||||||
* @param selection The selection where the command can be executed.
|
* @param selection The selection where the command can be executed.
|
||||||
*/
|
*/
|
||||||
void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext registry, Commands.CommandSelection selection);
|
void register(CommandDispatcher<CommandSourceStack> dispatcher, Commands.CommandSelection selection);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import dev.architectury.event.events.client.ClientChatEvent;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public class ChatProcessorImpl implements ClientChatEvent.ChatProcessor {
|
||||||
|
private String message;
|
||||||
|
@Nullable
|
||||||
|
private Component component;
|
||||||
|
|
||||||
|
public ChatProcessorImpl(String message, @Nullable Component component) {
|
||||||
|
this.message = message;
|
||||||
|
this.component = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public Component getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = Objects.requireNonNull(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setComponent(@Nullable Component component) {
|
||||||
|
this.component = component;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -146,7 +146,7 @@ transitive-accessible method net/minecraft/world/item/AxeItem <init> (Lnet/minec
|
|||||||
transitive-accessible method net/minecraft/world/item/DiggerItem <init> (FFLnet/minecraft/world/item/Tier;Lnet/minecraft/tags/TagKey;Lnet/minecraft/world/item/Item$Properties;)V
|
transitive-accessible method net/minecraft/world/item/DiggerItem <init> (FFLnet/minecraft/world/item/Tier;Lnet/minecraft/tags/TagKey;Lnet/minecraft/world/item/Item$Properties;)V
|
||||||
transitive-accessible method net/minecraft/world/item/HoeItem <init> (Lnet/minecraft/world/item/Tier;IFLnet/minecraft/world/item/Item$Properties;)V
|
transitive-accessible method net/minecraft/world/item/HoeItem <init> (Lnet/minecraft/world/item/Tier;IFLnet/minecraft/world/item/Item$Properties;)V
|
||||||
transitive-accessible method net/minecraft/world/item/PickaxeItem <init> (Lnet/minecraft/world/item/Tier;IFLnet/minecraft/world/item/Item$Properties;)V
|
transitive-accessible method net/minecraft/world/item/PickaxeItem <init> (Lnet/minecraft/world/item/Tier;IFLnet/minecraft/world/item/Item$Properties;)V
|
||||||
transitive-accessible method net/minecraft/world/item/RecordItem <init> (ILnet/minecraft/sounds/SoundEvent;Lnet/minecraft/world/item/Item$Properties;I)V
|
transitive-accessible method net/minecraft/world/item/RecordItem <init> (ILnet/minecraft/sounds/SoundEvent;Lnet/minecraft/world/item/Item$Properties;)V
|
||||||
|
|
||||||
# Constructors of non-abstract block classes
|
# Constructors of non-abstract block classes
|
||||||
transitive-accessible method net/minecraft/world/level/block/AirBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
transitive-accessible method net/minecraft/world/level/block/AirBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ unifiedPublishing {
|
|||||||
displayName = "[Fabric $rootProject.supported_version] v$project.version"
|
displayName = "[Fabric $rootProject.supported_version] v$project.version"
|
||||||
releaseType = "$rootProject.artifact_type"
|
releaseType = "$rootProject.artifact_type"
|
||||||
changelog = releaseChangelog()
|
changelog = releaseChangelog()
|
||||||
gameVersions = ["1.19.1"]
|
gameVersions = ["1.19"]
|
||||||
gameLoaders = ["fabric", "quilt"]
|
gameLoaders = ["fabric", "quilt"]
|
||||||
mainPublication renameJarForPublication
|
mainPublication renameJarForPublication
|
||||||
relations {
|
relations {
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ import dev.architectury.event.events.client.ClientGuiEvent;
|
|||||||
import dev.architectury.event.events.client.ClientLifecycleEvent;
|
import dev.architectury.event.events.client.ClientLifecycleEvent;
|
||||||
import dev.architectury.event.events.client.ClientTickEvent;
|
import dev.architectury.event.events.client.ClientTickEvent;
|
||||||
import dev.architectury.event.events.client.ClientTooltipEvent;
|
import dev.architectury.event.events.client.ClientTooltipEvent;
|
||||||
import dev.architectury.event.events.common.*;
|
import dev.architectury.event.events.common.CommandRegistrationEvent;
|
||||||
import dev.architectury.impl.fabric.ChatComponentImpl;
|
import dev.architectury.event.events.common.InteractionEvent;
|
||||||
|
import dev.architectury.event.events.common.LifecycleEvent;
|
||||||
|
import dev.architectury.event.events.common.LootEvent;
|
||||||
|
import dev.architectury.event.events.common.TickEvent;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
@@ -39,11 +42,6 @@ import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
|||||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||||
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
||||||
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
|
|
||||||
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
|
|
||||||
import net.minecraft.network.chat.PlayerChatMessage;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class EventHandlerImpl {
|
public class EventHandlerImpl {
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
@@ -74,22 +72,13 @@ public class EventHandlerImpl {
|
|||||||
ServerWorldEvents.LOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act(world));
|
ServerWorldEvents.LOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_LOAD.invoker().act(world));
|
||||||
ServerWorldEvents.UNLOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act(world));
|
ServerWorldEvents.UNLOAD.register((server, world) -> LifecycleEvent.SERVER_LEVEL_UNLOAD.invoker().act(world));
|
||||||
|
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registry, selection) -> CommandRegistrationEvent.EVENT.invoker().register(dispatcher, registry, selection));
|
CommandRegistrationCallback.EVENT.register((dispatcher, registry, selection) -> CommandRegistrationEvent.EVENT.invoker().register(dispatcher, selection));
|
||||||
|
|
||||||
UseItemCallback.EVENT.register((player, world, hand) -> InteractionEvent.RIGHT_CLICK_ITEM.invoker().click(player, hand).asMinecraft());
|
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());
|
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());
|
AttackBlockCallback.EVENT.register((player, world, hand, pos, face) -> InteractionEvent.LEFT_CLICK_BLOCK.invoker().click(player, hand, pos, face).asMinecraft());
|
||||||
|
|
||||||
LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(lootManager, id, new LootTableModificationContextImpl(tableBuilder), source.isBuiltin()));
|
LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> LootEvent.MODIFY_LOOT_TABLE.invoker().modifyLootTable(lootManager, id, new LootTableModificationContextImpl(tableBuilder), source.isBuiltin()));
|
||||||
|
|
||||||
ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (player, component) -> {
|
|
||||||
ChatEvent.ChatComponent chatComponent = new ChatComponentImpl(component);
|
|
||||||
ChatEvent.DECORATE.invoker().decorate(player, chatComponent);
|
|
||||||
return CompletableFuture.completedFuture(chatComponent.get());
|
|
||||||
});
|
|
||||||
ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> {
|
|
||||||
return !ChatEvent.RECEIVED.invoker().received(sender, message.serverContent()).isFalse();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(EnvType.SERVER)
|
@Environment(EnvType.SERVER)
|
||||||
|
|||||||
@@ -26,18 +26,33 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public class ChatComponentImpl implements ChatEvent.ChatComponent {
|
public class ChatComponentImpl implements ChatEvent.ChatComponent {
|
||||||
private Component component;
|
private Component raw;
|
||||||
|
@Nullable
|
||||||
|
private Component filtered;
|
||||||
|
|
||||||
public ChatComponentImpl(Component component) {
|
public ChatComponentImpl(Component raw, @Nullable Component filtered) {
|
||||||
this.component = component;
|
this.raw = raw;
|
||||||
|
this.filtered = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component get() {
|
public Component getRaw() {
|
||||||
return component;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(Component component) {
|
@Override
|
||||||
this.component = component;
|
@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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.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;
|
||||||
|
private final ChatProcessor processor;
|
||||||
|
|
||||||
|
public EventChatDecorator(ChatDecorator parent, ChatProcessor processor) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.processor = processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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 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 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 {
|
||||||
|
FilteredText<Component> process(@Nullable ServerPlayer player, FilteredText<Component> text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ package dev.architectury.mixin.fabric;
|
|||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.ParseResults;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import dev.architectury.event.events.common.CommandPerformEvent;
|
import dev.architectury.event.events.common.CommandPerformEvent;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
@@ -33,9 +33,11 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
@Mixin(Commands.class)
|
@Mixin(Commands.class)
|
||||||
public class MixinCommands {
|
public class MixinCommands {
|
||||||
@Redirect(method = "performCommand",
|
@Redirect(method = "performCommand",
|
||||||
at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;execute(Lcom/mojang/brigadier/ParseResults;)I", remap = false))
|
at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;execute(Lcom/mojang/brigadier/StringReader;Ljava/lang/Object;)I", remap = false))
|
||||||
private int performCommand(CommandDispatcher<CommandSourceStack> dispatcher, ParseResults<CommandSourceStack> results) throws CommandSyntaxException {
|
private int performCommand(CommandDispatcher<CommandSourceStack> dispatcher, StringReader input, Object source) throws CommandSyntaxException {
|
||||||
var event = new CommandPerformEvent(results, null);
|
var stack = (CommandSourceStack) source;
|
||||||
|
var parse = dispatcher.parse(input, stack);
|
||||||
|
var event = new CommandPerformEvent(parse, null);
|
||||||
if (CommandPerformEvent.EVENT.invoker().act(event).isPresent()) {
|
if (CommandPerformEvent.EVENT.invoker().act(event).isPresent()) {
|
||||||
if (event.getThrowable() != null) {
|
if (event.getThrowable() != null) {
|
||||||
Throwables.throwIfUnchecked(event.getThrowable());
|
Throwables.throwIfUnchecked(event.getThrowable());
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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<ChatDecorator> 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;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.impl.fabric.EventChatDecorator;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.MessageSignature;
|
||||||
|
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;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
@Mixin(ServerGamePacketListenerImpl.class)
|
||||||
|
public abstract class MixinServerGamePacketListenerImpl {
|
||||||
|
@Shadow
|
||||||
|
public ServerPlayer player;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private MinecraftServer server;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract void detectRateSpam();
|
||||||
|
|
||||||
|
@Inject(method = "broadcastChatMessage",
|
||||||
|
at = @At(value = "INVOKE",
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,69 +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.client;
|
|
||||||
|
|
||||||
import dev.architectury.event.events.client.ClientChatEvent;
|
|
||||||
import net.minecraft.network.chat.ChatType;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArgs;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.client.multiplayer.chat.ChatListener$1")
|
|
||||||
public class MixinChatListener_1 {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
Component val$decoratedMessage;
|
|
||||||
@Unique
|
|
||||||
private ThreadLocal<Component> cancelNext = new ThreadLocal<>();
|
|
||||||
|
|
||||||
@ModifyArgs(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/chat/ChatListener;processPlayerChatMessage(Lnet/minecraft/network/chat/ChatType$Bound;Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/network/chat/Component;Lnet/minecraft/client/multiplayer/PlayerInfo;ZLjava/time/Instant;)Z"))
|
|
||||||
private void modifyMessage(Args args) {
|
|
||||||
cancelNext.remove();
|
|
||||||
ChatType.Bound boundChatType = args.get(0);
|
|
||||||
Component message = args.get(2);
|
|
||||||
var process = ClientChatEvent.RECEIVED.invoker().process(boundChatType, message);
|
|
||||||
if (process.isPresent()) {
|
|
||||||
if (process.isFalse()) {
|
|
||||||
cancelNext.set(message);
|
|
||||||
} else if (process.object() != null) {
|
|
||||||
args.set(2, process.object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/chat/ChatListener;processPlayerChatMessage(Lnet/minecraft/network/chat/ChatType$Bound;Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/network/chat/Component;Lnet/minecraft/client/multiplayer/PlayerInfo;ZLjava/time/Instant;)Z"),
|
|
||||||
cancellable = true)
|
|
||||||
private void handleChatPre(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (Objects.equals(cancelNext.get(), this.val$decoratedMessage)) {
|
|
||||||
cir.setReturnValue(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelNext.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +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.client;
|
|
||||||
|
|
||||||
import dev.architectury.event.events.client.ClientChatEvent;
|
|
||||||
import net.minecraft.network.chat.ChatType;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArgs;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.client.multiplayer.chat.ChatListener$2")
|
|
||||||
public class MixinChatListener_2 {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
Component val$decoratedMessage;
|
|
||||||
@Unique
|
|
||||||
private ThreadLocal<Component> cancelNext = new ThreadLocal<>();
|
|
||||||
|
|
||||||
@ModifyArgs(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/chat/ChatListener;processNonPlayerChatMessage(Lnet/minecraft/network/chat/ChatType$Bound;Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/network/chat/Component;)Z"))
|
|
||||||
private void modifyMessage(Args args) {
|
|
||||||
cancelNext.remove();
|
|
||||||
ChatType.Bound boundChatType = args.get(0);
|
|
||||||
Component message = args.get(2);
|
|
||||||
var process = ClientChatEvent.RECEIVED.invoker().process(boundChatType, message);
|
|
||||||
if (process.isPresent()) {
|
|
||||||
if (process.isFalse()) {
|
|
||||||
cancelNext.set(message);
|
|
||||||
} else if (process.object() != null) {
|
|
||||||
args.set(2, process.object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/chat/ChatListener;processNonPlayerChatMessage(Lnet/minecraft/network/chat/ChatType$Bound;Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/network/chat/Component;)Z"),
|
|
||||||
cancellable = true)
|
|
||||||
private void handleChatPre(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (Objects.equals(cancelNext.get(), this.val$decoratedMessage)) {
|
|
||||||
cir.setReturnValue(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelNext.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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.client;
|
||||||
|
|
||||||
|
import dev.architectury.event.events.client.ClientChatEvent;
|
||||||
|
import dev.architectury.impl.fabric.EventChatDecorator;
|
||||||
|
import net.minecraft.client.gui.Gui;
|
||||||
|
import net.minecraft.network.chat.ChatSender;
|
||||||
|
import net.minecraft.network.chat.ChatType;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(Gui.class)
|
||||||
|
public abstract class MixinGui {
|
||||||
|
@Unique
|
||||||
|
private ChatType chatType;
|
||||||
|
@Unique
|
||||||
|
private ChatSender chatSender;
|
||||||
|
|
||||||
|
@Inject(method = "handlePlayerChat", at = @At(value = "HEAD"))
|
||||||
|
private void handleChatPre(ChatType chatType, Component component, ChatSender chatSender, CallbackInfo ci) {
|
||||||
|
this.chatType = chatType;
|
||||||
|
this.chatSender = chatSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyVariable(method = "handlePlayerChat", at = @At("HEAD"), argsOnly = true, ordinal = 0)
|
||||||
|
private Component modifyMessage(Component message) {
|
||||||
|
if (chatType == null) {
|
||||||
|
chatType = null;
|
||||||
|
chatSender = null;
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, message, chatSender);
|
||||||
|
if (process.isPresent()) {
|
||||||
|
if (process.isFalse())
|
||||||
|
return EventChatDecorator.CANCELLING_COMPONENT;
|
||||||
|
if (process.object() != null)
|
||||||
|
return process.object();
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "handlePlayerChat", at = @At(value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/client/Minecraft;isBlocked(Ljava/util/UUID;)Z", ordinal = 0),
|
||||||
|
cancellable = true)
|
||||||
|
private void handleChat(ChatType chatType, Component component, ChatSender chatSender, CallbackInfo ci) {
|
||||||
|
if (EventChatDecorator.CANCELLING_COMPONENT.equals(component)) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "handleSystemChat", at = @At(value = "HEAD"))
|
||||||
|
private void handleSystemChatPre(ChatType chatType, Component component, CallbackInfo ci) {
|
||||||
|
this.chatType = chatType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyVariable(method = "handleSystemChat", at = @At("HEAD"), argsOnly = true, ordinal = 0)
|
||||||
|
private Component modifySystemMessage(Component message) {
|
||||||
|
if (chatType == null) {
|
||||||
|
chatType = null;
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, message, null);
|
||||||
|
if (process.isPresent()) {
|
||||||
|
if (process.isFalse())
|
||||||
|
return EventChatDecorator.CANCELLING_COMPONENT;
|
||||||
|
if (process.object() != null)
|
||||||
|
return process.object();
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "handleSystemChat", at = @At(value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/client/Options;hideMatchedNames()Lnet/minecraft/client/OptionInstance;"),
|
||||||
|
cancellable = true)
|
||||||
|
private void handleChat(ChatType chatType, Component component, CallbackInfo ci) {
|
||||||
|
if (EventChatDecorator.CANCELLING_COMPONENT.equals(component)) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,30 +20,53 @@
|
|||||||
package dev.architectury.mixin.fabric.client;
|
package dev.architectury.mixin.fabric.client;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import dev.architectury.event.CompoundEventResult;
|
||||||
import dev.architectury.event.EventResult;
|
import dev.architectury.event.EventResult;
|
||||||
import dev.architectury.event.events.client.ClientChatEvent;
|
import dev.architectury.event.events.client.ClientChatEvent;
|
||||||
|
import dev.architectury.impl.ChatProcessorImpl;
|
||||||
|
import dev.architectury.impl.fabric.EventChatDecorator;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.player.AbstractClientPlayer;
|
import net.minecraft.client.player.AbstractClientPlayer;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.MessageSigner;
|
||||||
import net.minecraft.world.entity.player.ProfilePublicKey;
|
import net.minecraft.world.entity.player.ProfilePublicKey;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
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;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Mixin(LocalPlayer.class)
|
@Mixin(LocalPlayer.class)
|
||||||
public abstract class MixinLocalPlayer extends AbstractClientPlayer {
|
public abstract class MixinLocalPlayer extends AbstractClientPlayer {
|
||||||
public MixinLocalPlayer(ClientLevel clientLevel, GameProfile gameProfile, @Nullable ProfilePublicKey profilePublicKey) {
|
public MixinLocalPlayer(ClientLevel clientLevel, GameProfile gameProfile, @Nullable ProfilePublicKey profilePublicKey) {
|
||||||
super(clientLevel, gameProfile, profilePublicKey);
|
super(clientLevel, gameProfile, profilePublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "sendChat(Ljava/lang/String;Lnet/minecraft/network/chat/Component;)V", at = @At(value = "HEAD"), cancellable = true)
|
@Shadow
|
||||||
private void chat(String string, Component component, CallbackInfo ci) {
|
protected abstract void sendChat(MessageSigner messageSigner, String string, @Nullable Component component);
|
||||||
EventResult process = ClientChatEvent.SEND.invoker().send(string, component);
|
|
||||||
if (process.isFalse()) {
|
@Inject(method = "chat(Ljava/lang/String;Lnet/minecraft/network/chat/Component;)V", at = @At(value = "HEAD"), cancellable = true)
|
||||||
ci.cancel();
|
private void chat(String message, Component component, CallbackInfo ci) {
|
||||||
|
ChatProcessorImpl processor = new ChatProcessorImpl(message, component);
|
||||||
|
EventResult process = ClientChatEvent.PROCESS.invoker().process(processor);
|
||||||
|
if (process.isPresent()) {
|
||||||
|
if (process.isFalse())
|
||||||
|
ci.cancel();
|
||||||
|
else {
|
||||||
|
String processorMessage = processor.getMessage();
|
||||||
|
Component processorComponent = processor.getComponent();
|
||||||
|
|
||||||
|
if (!Objects.equals(processorMessage, message) || !Objects.equals(processorComponent, component)) {
|
||||||
|
MessageSigner messageSigner = MessageSigner.create(this.getUUID());
|
||||||
|
this.sendChat(messageSigner, processorMessage, processorComponent);
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public abstract class MixinMinecraft {
|
|||||||
private ThreadLocal<Boolean> setScreenCancelled = new ThreadLocal<>();
|
private ThreadLocal<Boolean> setScreenCancelled = new ThreadLocal<>();
|
||||||
|
|
||||||
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V",
|
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/GameNarrator;clear()V"))
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/chat/NarratorChatListener;clear()V"))
|
||||||
private void handleLogin(Screen screen, CallbackInfo ci) {
|
private void handleLogin(Screen screen, CallbackInfo ci) {
|
||||||
ClientPlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(player);
|
ClientPlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(player);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,12 @@
|
|||||||
"client": [
|
"client": [
|
||||||
"client.ClientPlayerAttackInvoker",
|
"client.ClientPlayerAttackInvoker",
|
||||||
"client.MixinAbstractContainerScreen",
|
"client.MixinAbstractContainerScreen",
|
||||||
"client.MixinChatListener_1",
|
|
||||||
"client.MixinChatListener_2",
|
|
||||||
"client.MixinClientLevel",
|
"client.MixinClientLevel",
|
||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
"client.MixinDebugScreenOverlay",
|
||||||
"client.MixinEffectInstance",
|
"client.MixinEffectInstance",
|
||||||
"client.MixinGameRenderer",
|
"client.MixinGameRenderer",
|
||||||
|
"client.MixinGui",
|
||||||
"client.MixinIntegratedServer",
|
"client.MixinIntegratedServer",
|
||||||
"client.MixinKeyboardHandler",
|
"client.MixinKeyboardHandler",
|
||||||
"client.MixinLocalPlayer",
|
"client.MixinLocalPlayer",
|
||||||
@@ -45,6 +44,7 @@
|
|||||||
"MixinInventory",
|
"MixinInventory",
|
||||||
"MixinItemEntity",
|
"MixinItemEntity",
|
||||||
"MixinLivingEntity",
|
"MixinLivingEntity",
|
||||||
|
"MixinMinecraftServer",
|
||||||
"MixinNaturalSpawner",
|
"MixinNaturalSpawner",
|
||||||
"MixinOcelot",
|
"MixinOcelot",
|
||||||
"MixinPatrolSpawner",
|
"MixinPatrolSpawner",
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
"MixinPlayerAdvancements",
|
"MixinPlayerAdvancements",
|
||||||
"MixinPlayerList",
|
"MixinPlayerList",
|
||||||
"MixinResultSlot",
|
"MixinResultSlot",
|
||||||
|
"MixinServerGamePacketListenerImpl",
|
||||||
"MixinServerLevel",
|
"MixinServerLevel",
|
||||||
"MixinServerPlayer",
|
"MixinServerPlayer",
|
||||||
"MixinServerPlayerGameMode",
|
"MixinServerPlayerGameMode",
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ unifiedPublishing {
|
|||||||
displayName = "[Forge $rootProject.supported_version] v$project.version"
|
displayName = "[Forge $rootProject.supported_version] v$project.version"
|
||||||
releaseType = "$rootProject.artifact_type"
|
releaseType = "$rootProject.artifact_type"
|
||||||
changelog = releaseChangelog()
|
changelog = releaseChangelog()
|
||||||
gameVersions = ["1.19.1"]
|
gameVersions = ["1.19"]
|
||||||
gameLoaders = ["forge"]
|
gameLoaders = ["forge"]
|
||||||
mainPublication renameJarForPublication
|
mainPublication renameJarForPublication
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import dev.architectury.event.EventResult;
|
|||||||
import dev.architectury.event.events.client.ClientChatEvent;
|
import dev.architectury.event.events.client.ClientChatEvent;
|
||||||
import dev.architectury.event.events.client.*;
|
import dev.architectury.event.events.client.*;
|
||||||
import dev.architectury.event.events.common.InteractionEvent;
|
import dev.architectury.event.events.common.InteractionEvent;
|
||||||
|
import dev.architectury.impl.ChatProcessorImpl;
|
||||||
import dev.architectury.impl.ScreenAccessImpl;
|
import dev.architectury.impl.ScreenAccessImpl;
|
||||||
import dev.architectury.impl.TooltipEventColorContextImpl;
|
import dev.architectury.impl.TooltipEventColorContextImpl;
|
||||||
import dev.architectury.impl.TooltipEventPositionContextImpl;
|
import dev.architectury.impl.TooltipEventPositionContextImpl;
|
||||||
@@ -99,15 +100,24 @@ public class EventHandlerImplClient {
|
|||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||||
public static void event(net.minecraftforge.client.event.ClientChatEvent event) {
|
public static void event(net.minecraftforge.client.event.ClientChatEvent event) {
|
||||||
EventResult process = ClientChatEvent.SEND.invoker().send(event.getMessage(), null);
|
ChatProcessorImpl processor = new ChatProcessorImpl(event.getMessage(), null);
|
||||||
if (process.isFalse()) {
|
EventResult process = ClientChatEvent.PROCESS.invoker().process(processor);
|
||||||
event.setCanceled(true);
|
if (process.isPresent()) {
|
||||||
|
if (process.isFalse())
|
||||||
|
event.setCanceled(true);
|
||||||
|
else {
|
||||||
|
event.setMessage(processor.getMessage());
|
||||||
|
|
||||||
|
if (process.isTrue()) {
|
||||||
|
event.setCanceled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||||
public static void event(ClientChatReceivedEvent event) {
|
public static void event(ClientChatReceivedEvent event) {
|
||||||
CompoundEventResult<Component> process = ClientChatEvent.RECEIVED.invoker().process(event.getBoundChatType(), event.getMessage());
|
CompoundEventResult<Component> process = ClientChatEvent.RECEIVED.invoker().process(event.getType(), event.getMessage(), event.getChatSender());
|
||||||
if (process.isPresent()) {
|
if (process.isPresent()) {
|
||||||
if (process.isFalse())
|
if (process.isFalse())
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class EventHandlerImplCommon {
|
|||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||||
public static void event(RegisterCommandsEvent event) {
|
public static void event(RegisterCommandsEvent event) {
|
||||||
CommandRegistrationEvent.EVENT.invoker().register(event.getDispatcher(), event.getBuildContext(), event.getCommandSelection());
|
CommandRegistrationEvent.EVENT.invoker().register(event.getDispatcher(), event.getCommandSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||||
@@ -140,24 +140,30 @@ public class EventHandlerImplCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||||
public static void event(ServerChatEvent.Preview event) {
|
public static void event(ServerChatEvent event) {
|
||||||
class ChatComponentImpl implements ChatEvent.ChatComponent {
|
class ChatComponentImpl implements ChatEvent.ChatComponent {
|
||||||
@Override
|
@Override
|
||||||
public Component get() {
|
public Component getRaw() {
|
||||||
return event.getMessage();
|
return Component.literal(event.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(Component component) {
|
public Component getFiltered() {
|
||||||
event.setMessage(component);
|
return event.getComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRaw(Component raw) {
|
||||||
|
// NO-OP
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFiltered(Component filtered) {
|
||||||
|
event.setComponent(filtered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ChatEvent.DECORATE.invoker().decorate(event.getPlayer(), new ChatComponentImpl());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
EventResult process = ChatEvent.SERVER.invoker().process(event.getPlayer(), new ChatComponentImpl());
|
||||||
public static void event(ServerChatEvent.Submitted event) {
|
|
||||||
EventResult process = ChatEvent.RECEIVED.invoker().received(event.getPlayer(), event.getMessage());
|
|
||||||
if (process.isFalse())
|
if (process.isFalse())
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
modLoader = "javafml"
|
modLoader = "javafml"
|
||||||
loaderVersion = "[42,)"
|
loaderVersion = "[41,)"
|
||||||
issueTrackerURL = "https://github.com/shedaniel/architectury/issues"
|
issueTrackerURL = "https://github.com/shedaniel/architectury/issues"
|
||||||
license = "GNU LGPLv3"
|
license = "GNU LGPLv3"
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@ license = "LGPL-3"
|
|||||||
[[dependencies.architectury]]
|
[[dependencies.architectury]]
|
||||||
modId = "minecraft"
|
modId = "minecraft"
|
||||||
mandatory = true
|
mandatory = true
|
||||||
versionRange = "[1.19.1,)"
|
versionRange = "[1.19,)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
[[dependencies.architectury]]
|
[[dependencies.architectury]]
|
||||||
modId = "forge"
|
modId = "forge"
|
||||||
mandatory = true
|
mandatory = true
|
||||||
versionRange = "[42.0.0,)"
|
versionRange = "[41.0.94,)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ org.gradle.daemon=false
|
|||||||
|
|
||||||
platforms=fabric,forge
|
platforms=fabric,forge
|
||||||
|
|
||||||
minecraft_version=1.19.1
|
minecraft_version=1.19
|
||||||
supported_version=1.19.1
|
supported_version=1.19
|
||||||
|
|
||||||
artifact_type=release
|
artifact_type=release
|
||||||
|
|
||||||
archives_base_name=architectury
|
archives_base_name=architectury
|
||||||
archives_base_name_snapshot=architectury-snapshot
|
archives_base_name_snapshot=architectury-snapshot
|
||||||
base_version=6.0
|
base_version=5.10
|
||||||
maven_group=dev.architectury
|
maven_group=dev.architectury
|
||||||
|
|
||||||
fabric_loader_version=0.14.8
|
fabric_loader_version=0.14.6
|
||||||
fabric_api_version=0.58.5+1.19.1
|
fabric_api_version=0.55.1+1.19
|
||||||
mod_menu_version=3.1.0
|
mod_menu_version=3.1.0
|
||||||
|
|
||||||
forge_version=42.0.0
|
forge_version=41.0.94
|
||||||
|
|
||||||
curseforge_id=419699
|
curseforge_id=419699
|
||||||
modrinth_id=lhGA9TYQ
|
modrinth_id=lhGA9TYQ
|
||||||
|
|||||||
@@ -61,21 +61,19 @@ public class DebugEvents {
|
|||||||
TestMod.SINK.accept(Optional.ofNullable(placer).map(Entity::getScoreboardName).orElse("null") + " places block at " + toShortString(pos) + logSide(world));
|
TestMod.SINK.accept(Optional.ofNullable(placer).map(Entity::getScoreboardName).orElse("null") + " places block at " + toShortString(pos) + logSide(world));
|
||||||
return EventResult.pass();
|
return EventResult.pass();
|
||||||
});
|
});
|
||||||
ChatEvent.DECORATE.register((player, component) -> {
|
ChatEvent.SERVER.register((player, message) -> {
|
||||||
component.set(component.get().copy().withStyle(ChatFormatting.AQUA).append(" + new text"));
|
TestMod.SINK.accept("Server chat received: " + message.getRaw());
|
||||||
});
|
if (message.getRaw().getString().contains("shit")) {
|
||||||
ChatEvent.RECEIVED.register((player, message) -> {
|
|
||||||
TestMod.SINK.accept("Server chat received: " + message);
|
|
||||||
if (message.getString().contains("shit")) {
|
|
||||||
return EventResult.interruptFalse();
|
return EventResult.interruptFalse();
|
||||||
}
|
}
|
||||||
|
message.modifyBoth(component -> component.copy().withStyle(ChatFormatting.AQUA));
|
||||||
return EventResult.interruptTrue();
|
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());
|
||||||
return EventResult.pass();
|
return EventResult.pass();
|
||||||
});
|
});
|
||||||
CommandRegistrationEvent.EVENT.register((dispatcher, registry, selection) -> {
|
CommandRegistrationEvent.EVENT.register((dispatcher, selection) -> {
|
||||||
TestMod.SINK.accept("Server commands registers");
|
TestMod.SINK.accept("Server commands registers");
|
||||||
});
|
});
|
||||||
EntityEvent.LIVING_DEATH.register((entity, source) -> {
|
EntityEvent.LIVING_DEATH.register((entity, source) -> {
|
||||||
@@ -255,21 +253,12 @@ public class DebugEvents {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ClientChatEvent.SEND.register((message, component) -> {
|
ClientChatEvent.PROCESS.register((message) -> {
|
||||||
TestMod.SINK.accept("Client chat sent: " + message);
|
TestMod.SINK.accept("Client chat sent: " + message.getMessage());
|
||||||
if (message.contains("error")) {
|
|
||||||
return EventResult.interruptFalse();
|
|
||||||
}
|
|
||||||
return EventResult.pass();
|
return EventResult.pass();
|
||||||
});
|
});
|
||||||
ClientChatEvent.RECEIVED.register((type, message) -> {
|
ClientChatEvent.RECEIVED.register((type, message, sender) -> {
|
||||||
TestMod.SINK.accept("Client chat received: " + message.getString());
|
TestMod.SINK.accept("Client chat received: " + message.getString());
|
||||||
if (message.getString().contains("terraria")) {
|
|
||||||
return CompoundEventResult.interruptTrue(message.copy().append(" + terraria is a great game!"));
|
|
||||||
}
|
|
||||||
if (message.getString().contains("potato")) {
|
|
||||||
return CompoundEventResult.interruptFalse(Component.empty());
|
|
||||||
}
|
|
||||||
return CompoundEventResult.pass();
|
return CompoundEventResult.pass();
|
||||||
});
|
});
|
||||||
ClientLifecycleEvent.CLIENT_LEVEL_LOAD.register(world -> {
|
ClientLifecycleEvent.CLIENT_LEVEL_LOAD.register(world -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user