diff --git a/paper/src/main/java/net/draycia/carbon/paper/listeners/PaperChatListener.java b/paper/src/main/java/net/draycia/carbon/paper/listeners/PaperChatListener.java index 25eea514c..77e9c296e 100644 --- a/paper/src/main/java/net/draycia/carbon/paper/listeners/PaperChatListener.java +++ b/paper/src/main/java/net/draycia/carbon/paper/listeners/PaperChatListener.java @@ -41,7 +41,6 @@ public final class PaperChatListener extends ChatListenerInternal implements Listener { private final CarbonChat carbonChat; - final ConfigManager configManager; @Inject public PaperChatListener( @@ -51,7 +50,6 @@ public PaperChatListener( ) { super(carbonChat.eventHandler(), carbonMessages, configManager); this.carbonChat = carbonChat; - this.configManager = configManager; } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) diff --git a/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeChatListener.java b/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeChatListener.java index 35d14fd22..01413536a 100644 --- a/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeChatListener.java +++ b/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeChatListener.java @@ -20,25 +20,19 @@ package net.draycia.carbon.sponge.listeners; import com.google.inject.Inject; -import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.regex.Pattern; +import java.util.UUID; import net.draycia.carbon.api.CarbonChat; -import net.draycia.carbon.api.channels.ChannelRegistry; -import net.draycia.carbon.api.events.CarbonChatEvent; import net.draycia.carbon.api.users.CarbonPlayer; -import net.draycia.carbon.api.users.ComponentPlayerResult; -import net.draycia.carbon.api.util.KeyedRenderer; -import net.draycia.carbon.api.util.Component; +import net.draycia.carbon.common.config.ConfigManager; +import net.draycia.carbon.common.event.events.CarbonChatEventImpl; +import net.draycia.carbon.common.listeners.ChatListenerInternal; +import net.draycia.carbon.common.messages.CarbonMessages; import net.draycia.carbon.sponge.CarbonChatSponge; import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.audience.ForwardingAudience; -import net.kyori.adventure.audience.MessageType; +import net.kyori.adventure.chat.SignedMessage; import net.kyori.adventure.identity.Identity; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -51,160 +45,60 @@ import org.spongepowered.api.event.message.PlayerChatEvent; import org.spongepowered.api.util.Tristate; -import static java.util.Objects.requireNonNullElse; -import static net.draycia.carbon.api.util.KeyedRenderer.keyedRenderer; -import static net.kyori.adventure.key.Key.key; -import static net.kyori.adventure.text.Component.empty; -import static net.kyori.adventure.text.Component.text; - @DefaultQualifier(NonNull.class) -public final class SpongeChatListener { +public final class SpongeChatListener extends ChatListenerInternal { private final CarbonChatSponge carbonChat; - private final ChannelRegistry registry; - private final CarbonMessages carbonMessages; - - private static final Pattern DEFAULT_URL_PATTERN = Pattern.compile("(?:(https?)://)?([-\\w_.]+\\.\\w{2,})(/\\S*)?"); @Inject private SpongeChatListener( final CarbonChat carbonChat, - final ChannelRegistry registry, - final CarbonMessages carbonMessages + final CarbonMessages carbonMessages, + final ConfigManager configManager ) { + super(carbonChat.eventHandler(), carbonMessages, configManager); this.carbonChat = (CarbonChatSponge) carbonChat; - this.registry = registry; - this.carbonMessages = carbonMessages; } @Listener @IsCancelled(Tristate.FALSE) - public void onPlayerChat(final PlayerChatEvent event, final @First Player source) { - final var playerResult = this.carbonChat.server().userManager().carbonPlayer(source.uniqueId()).join(); - final @Nullable CarbonPlayer sender = playerResult.player(); + public void onPlayerChat(final PlayerChatEvent.Submit event, final @First Player source, final @First SignedMessage signedMessage) { + final Optional optionalPlayer = event.player(); - if (sender == null) { + if (optionalPlayer.isEmpty()) { return; } - var channel = requireNonNullElse(sender.selectedChannel(), this.registry.defaultValue()); - - final var messageContents = PlainTextComponentSerializer.plainText().serialize(event.originalMessage()); - var eventMessage = event.message(); - - final CarbonPlayer.ChannelMessage channelMessage = sender.channelForMessage(eventMessage); - - if (channelMessage.channel() != null) { - channel = channelMessage.channel(); - } - - eventMessage = channelMessage.message(); + final @Nullable CarbonPlayer sender = this.carbonChat.userManager().user(optionalPlayer.get().uniqueId()).join(); - if (sender.leftChannels().contains(channel.key())) { - sender.joinChannel(channel); - this.carbonMessages.channelJoined(sender); - } - for (final var chatChannel : this.registry) { - if (chatChannel.quickPrefix() == null) { - continue; - } + final String content = PlainTextComponentSerializer.plainText().serialize(event.message()); + final @Nullable CarbonChatEventImpl chatEvent = this.prepareAndEmitChatEvent(sender, content, signedMessage); - if (messageContents.startsWith(chatChannel.quickPrefix()) && chatChannel.speechPermitted(sender).permitted()) { - channel = chatChannel; - eventMessage = eventMessage.replaceText(TextReplacementConfig.builder() - .once() - .matchLiteral(channel.quickPrefix()) - .replacement(text()) - .build()); - break; - } + if (chatEvent == null || chatEvent.cancelled()) { + event.setCancelled(true); + return; } - final List recipients; + final List recipientIDs = chatEvent.recipients().stream().map(audience -> + audience.get(Identity.UUID).orElse(new UUID(0,0))).toList(); - if (event.audience().isPresent()) { - final var audience = event.audience().get(); + event.setFilter(serverPlayer -> recipientIDs.contains(serverPlayer.uniqueId())); - if (audience instanceof ForwardingAudience forwardingAudience) { - recipients = new ArrayList<>(); + // No way to render per player, or get the message signature? + // Why do things keep vanishing with no easily findable alternative? :( + event.renderer(($, $$, $$$, recipient) -> { + final var recipientUUID = recipient.get(Identity.UUID); + final Audience recipientViewer; - forwardingAudience.forEachAudience(recipients::add); + if (recipientUUID.isPresent()) { + recipientViewer = this.carbonChat.userManager().user(recipientUUID.get()).join(); } else { - recipients = channel.recipients(sender); - } - } else { - recipients = channel.recipients(sender); - } - - final var renderers = new ArrayList(); - renderers.add(keyedRenderer(Key.key("carbon", "default"), channel)); - - final var chatEvent = new CarbonChatEvent(sender, eventMessage, recipients, renderers, channel, false); - final var result = this.carbonChat.eventHandler().emit(chatEvent); - - if (!result.wasSuccessful() || chatEvent.result().cancelled()) { - if (!result.exceptions().isEmpty()) { - for (var entry : result.exceptions().entrySet()) { - this.carbonChat.logger().error("Exception in event handler: " + entry.getKey().getClass().getName()); - entry.getValue().printStackTrace(); - } - } - - final var failure = chatEvent.result().reason(); - - if (!failure.equals(empty())) { - sender.sendMessage(failure); + recipientViewer = recipient; } - } - - try { - event.setAudience(Audience.audience(chatEvent.recipients())); - } catch (final UnsupportedOperationException exception) { - exception.printStackTrace(); - // Do we log something here? Would get spammy fast. - } - if (sender.hasPermission("carbon.hideidentity")) { - for (final var recipient : chatEvent.recipients()) { - var renderedMessage = new Component(chatEvent.message(), MessageType.CHAT); - - for (final var renderer : chatEvent.renderers()) { - try { - if (recipient instanceof Player player) { - final ComponentPlayerResult targetPlayer = this.carbonChat.server().userManager().carbonPlayer(player.uniqueId()).join(); - - renderedMessage = renderer.render(sender, targetPlayer.player(), renderedMessage, chatEvent.message()); - } else { - renderedMessage = renderer.render(sender, recipient, renderedMessage, chatEvent.message()); - } - } catch (final Exception e) { - e.printStackTrace(); - } - } - - recipient.sendMessage(Identity.nil(), renderedMessage); - } - } else { - event.setChatFormatter((player, target, msg, originalMessage) -> { - Component component = msg; - - for (final var renderer : chatEvent.renderers()) { - if (target instanceof ServerPlayer serverPlayer) { - final ComponentPlayerResult targetPlayer = this.carbonChat.server().userManager().carbonPlayer(serverPlayer.uniqueId()).join(); - component = renderer.render(playerResult.player(), targetPlayer.player(), component, msg); - } else { - component = renderer.render(playerResult.player(), target, component, msg); - } - } - - if (component == Component.empty()) { - return Optional.empty(); - } - - return Optional.ofNullable(component); - }); - } + return chatEvent.renderFor(recipientViewer); + }); } } diff --git a/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeReloadListener.java b/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeReloadListener.java index 969cc16cf..1e0ab8dc3 100644 --- a/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeReloadListener.java +++ b/sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeReloadListener.java @@ -22,25 +22,25 @@ import com.google.inject.Inject; import net.draycia.carbon.api.CarbonChat; import net.draycia.carbon.common.channels.CarbonChannelRegistry; -import net.draycia.carbon.common.config.ConfigFactory; -import net.draycia.carbon.common.event.CarbonReloadEvent; +import net.draycia.carbon.common.config.ConfigManager; +import net.draycia.carbon.common.event.events.CarbonReloadEvent; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.lifecycle.RefreshGameEvent; public class SpongeReloadListener { final CarbonChat carbonChat; - final ConfigFactory configFactory; + final ConfigManager configManager; final CarbonChannelRegistry channelRegistry; @Inject public SpongeReloadListener( final CarbonChat carbonChat, - final ConfigFactory configFactory, + final ConfigManager configManager, final CarbonChannelRegistry channelRegistry ) { this.carbonChat = carbonChat; - this.configFactory = configFactory; + this.configManager = configManager; this.channelRegistry = channelRegistry; } diff --git a/sponge/src/main/java/net/draycia/carbon/sponge/users/CarbonPlayerSponge.java b/sponge/src/main/java/net/draycia/carbon/sponge/users/CarbonPlayerSponge.java index 63840f0b1..c51e207b2 100644 --- a/sponge/src/main/java/net/draycia/carbon/sponge/users/CarbonPlayerSponge.java +++ b/sponge/src/main/java/net/draycia/carbon/sponge/users/CarbonPlayerSponge.java @@ -47,10 +47,8 @@ @DefaultQualifier(NonNull.class) public final class CarbonPlayerSponge extends WrappedCarbonPlayer implements ForwardingAudience.Single { - private final CarbonPlayerCommon carbonPlayerCommon; - public CarbonPlayerSponge(final CarbonPlayerCommon carbonPlayerCommon) { - this.carbonPlayerCommon = carbonPlayerCommon; + super(carbonPlayerCommon); } @Override @@ -61,8 +59,12 @@ public CarbonPlayerSponge(final CarbonPlayerCommon carbonPlayerCommon) { } @Override - public CarbonPlayerCommon carbonPlayerCommon() { - return this.carbonPlayerCommon; + protected Optional platformDisplayName() { + if (this.player().isEmpty()) { + return Optional.empty(); + } + + return this.player().get().get(Keys.CUSTOM_NAME); } private Optional player() { @@ -120,11 +122,6 @@ public boolean sameWorldAs(final CarbonPlayer other) { return player.get().world().equals(otherPlayer.get().world()); } - @Override - public void displayName(final @Nullable Component displayName) { - this.carbonPlayerCommon.displayName(displayName); - } - @Override public @Nullable Component createItemHoverComponent(final InventorySlot slot) { final Optional optionalPlayer = this.player(); // This is temporary (it's not) diff --git a/sponge/src/main/java/net/draycia/carbon/sponge/users/SpongeProfileResolver.java b/sponge/src/main/java/net/draycia/carbon/sponge/users/SpongeProfileResolver.java index 9935c319a..ae51a6052 100644 --- a/sponge/src/main/java/net/draycia/carbon/sponge/users/SpongeProfileResolver.java +++ b/sponge/src/main/java/net/draycia/carbon/sponge/users/SpongeProfileResolver.java @@ -25,16 +25,14 @@ private SpongeProfileResolver(final MojangProfileResolver mojang) { @Override public CompletableFuture<@Nullable UUID> resolveUUID(final String username, final boolean cacheOnly) { - // TODO: handle profile lookup failure - // TODO: do we need the mojang profile resolver here? Sponge's profile manager automatically caches and uses its own version - return Sponge.server().gameProfileManager().basicProfile(username).thenApply(GameProfile::uuid); + return Sponge.server().gameProfileManager().basicProfile(username).thenApply(GameProfile::uuid).exceptionallyCompose(throwable -> + this.mojang.resolveUUID(username, cacheOnly)); } @Override public CompletableFuture<@Nullable String> resolveName(final UUID uuid, final boolean cacheOnly) { - // TODO: handle profile lookup failure - // TODO: do we need the mojang profile resolver here? Sponge's profile manager automatically caches and uses its own version - return Sponge.server().gameProfileManager().basicProfile(uuid).thenApply(profile -> profile.name().orElse(null)); + return Sponge.server().gameProfileManager().basicProfile(uuid).thenApply(profile -> profile.name().orElseThrow()).exceptionallyCompose(throwable -> + this.mojang.resolveName(uuid, cacheOnly)); } @Override diff --git a/velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityChatListener.java b/velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityChatListener.java index b5319257c..0f68e99fb 100644 --- a/velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityChatListener.java +++ b/velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityChatListener.java @@ -51,7 +51,6 @@ public final class VelocityChatListener extends ChatListenerInternal implements private final Logger logger; private final AtomicInteger timesWarned = new AtomicInteger(0); private final Supplier signedSupplier; - final ConfigManager configManager; @Inject private VelocityChatListener( @@ -65,7 +64,6 @@ private VelocityChatListener( super(carbonChat.eventHandler(), carbonMessages, configManager); this.userManager = userManager; this.logger = logger; - this.configManager = configManager; this.signedSupplier = Suppliers.memoize( () -> pluginManager.isLoaded("unsignedvelocity") || pluginManager.isLoaded("signedvelocity")