From 2d05620462df5f45b99e4fdcfbc345f927a467a2 Mon Sep 17 00:00:00 2001 From: Vankka Date: Sat, 30 Mar 2024 14:41:12 +0200 Subject: [PATCH] Interfaces for nickname, punishment sync. Change chat integration handling. EssentialsX integration. --- .../discordsrv/api/channel/GameChannel.java | 28 +++- .../api/module/{type => }/Module.java | 2 +- .../api/module/type/NicknameModule.java | 10 ++ ...ataProvider.java => PermissionModule.java} | 11 +- .../api/module/type/PunishmentModule.java | 47 ++++++ .../api/player/DiscordSRVPlayer.java | 7 + bukkit/build.gradle | 2 + .../integration/EssentialsXIntegration.java | 147 ++++++++++++++++++ .../bukkit/integration/VaultIntegration.java | 4 +- .../chat/ChattyChatIntegration.java | 26 ++-- .../integration/chat/LunaChatIntegration.java | 35 ++++- .../chat/McMMOChatIntegration.java | 20 ++- .../chat/TownyChatIntegration.java | 25 +-- .../chat/VentureChatIntegration.java | 58 ++++--- .../discordsrv/common/AbstractDiscordSRV.java | 2 +- .../com/discordsrv/common/DiscordSRV.java | 2 +- .../common/channel/GlobalChannel.java | 14 +- .../common/groupsync/GroupSyncModule.java | 38 ++--- .../integration/LuckPermsIntegration.java | 4 +- .../discord/DiscordChatMessageModule.java | 7 + .../common/module/ModuleManager.java | 2 +- .../common/module/type/AbstractModule.java | 2 +- .../common/module/type/ModuleDelegate.java | 2 +- .../permission/util/PermissionUtil.java | 8 +- .../com/discordsrv/common/player/IPlayer.java | 7 + settings.gradle | 1 + 26 files changed, 402 insertions(+), 109 deletions(-) rename api/src/main/java/com/discordsrv/api/module/{type => }/Module.java (99%) create mode 100644 api/src/main/java/com/discordsrv/api/module/type/NicknameModule.java rename api/src/main/java/com/discordsrv/api/module/type/{PermissionDataProvider.java => PermissionModule.java} (92%) create mode 100644 api/src/main/java/com/discordsrv/api/module/type/PunishmentModule.java create mode 100644 bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java diff --git a/api/src/main/java/com/discordsrv/api/channel/GameChannel.java b/api/src/main/java/com/discordsrv/api/channel/GameChannel.java index 4d72fb87..9e212aa3 100644 --- a/api/src/main/java/com/discordsrv/api/channel/GameChannel.java +++ b/api/src/main/java/com/discordsrv/api/channel/GameChannel.java @@ -24,8 +24,11 @@ package com.discordsrv.api.channel; import com.discordsrv.api.component.MinecraftComponent; +import com.discordsrv.api.player.DiscordSRVPlayer; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + /** * An in-game channel for sending Minecraft messages to. */ @@ -54,8 +57,27 @@ public interface GameChannel { boolean isChat(); /** - * Send a message to this {@link GameChannel}'s participants. - * @param component the message + * Players that will receive messages for this channel, these players must not be included in {@link #sendMessage(MinecraftComponent)}. + * @return the recipients for this channel + * @see #sendMessage(MinecraftComponent) */ - void sendMessage(@NotNull MinecraftComponent component); + @NotNull + Collection getRecipients(); + + /** + * Send a message to this {@link GameChannel}'s participants which are not included in {@link #getRecipients()}. + * @param component the message + * @see #getRecipients() + */ + default void sendMessage(@NotNull MinecraftComponent component) {} + + /** + * Sends the given message to the given player, used with {@link #getRecipients()}. May be used to apply personalized filters. + * @param player the player + * @param component the message + * @see #getRecipients() + */ + default void sendMessageToPlayer(@NotNull DiscordSRVPlayer player, @NotNull MinecraftComponent component) { + player.sendMessage(component); + } } diff --git a/api/src/main/java/com/discordsrv/api/module/type/Module.java b/api/src/main/java/com/discordsrv/api/module/Module.java similarity index 99% rename from api/src/main/java/com/discordsrv/api/module/type/Module.java rename to api/src/main/java/com/discordsrv/api/module/Module.java index 46c761ca..d261cb68 100644 --- a/api/src/main/java/com/discordsrv/api/module/type/Module.java +++ b/api/src/main/java/com/discordsrv/api/module/Module.java @@ -21,7 +21,7 @@ * SOFTWARE. */ -package com.discordsrv.api.module.type; +package com.discordsrv.api.module; import com.discordsrv.api.DiscordSRVApi; import com.discordsrv.api.discord.connection.details.DiscordCacheFlag; diff --git a/api/src/main/java/com/discordsrv/api/module/type/NicknameModule.java b/api/src/main/java/com/discordsrv/api/module/type/NicknameModule.java new file mode 100644 index 00000000..084880bf --- /dev/null +++ b/api/src/main/java/com/discordsrv/api/module/type/NicknameModule.java @@ -0,0 +1,10 @@ +package com.discordsrv.api.module.type; + +import java.util.UUID; + +public interface NicknameModule { + + String getNickname(UUID playerUUID); + void setNickname(UUID playerUUID, String nickname); + +} diff --git a/api/src/main/java/com/discordsrv/api/module/type/PermissionDataProvider.java b/api/src/main/java/com/discordsrv/api/module/type/PermissionModule.java similarity index 92% rename from api/src/main/java/com/discordsrv/api/module/type/PermissionDataProvider.java rename to api/src/main/java/com/discordsrv/api/module/type/PermissionModule.java index f5151140..ec6cc601 100644 --- a/api/src/main/java/com/discordsrv/api/module/type/PermissionDataProvider.java +++ b/api/src/main/java/com/discordsrv/api/module/type/PermissionModule.java @@ -23,6 +23,7 @@ package com.discordsrv.api.module.type; +import com.discordsrv.api.module.Module; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,30 +32,30 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public interface PermissionDataProvider extends Module { +public interface PermissionModule extends Module { boolean supportsOffline(); interface Basic extends Groups, Permissions, PrefixAndSuffix {} interface All extends Basic, Meta, GroupsContext {} - interface Groups extends PermissionDataProvider { + interface Groups extends PermissionModule { List getGroups(); CompletableFuture hasGroup(@NotNull UUID player, @NotNull String groupName, boolean includeInherited); CompletableFuture addGroup(@NotNull UUID player, @NotNull String groupName); CompletableFuture removeGroup(@NotNull UUID player, @NotNull String groupName); } - interface Permissions extends PermissionDataProvider { + interface Permissions extends PermissionModule { CompletableFuture hasPermission(@NotNull UUID player, @NotNull String permission); } - interface PrefixAndSuffix extends PermissionDataProvider { + interface PrefixAndSuffix extends PermissionModule { CompletableFuture getPrefix(@NotNull UUID player); CompletableFuture getSuffix(@NotNull UUID player); } - interface Meta extends PermissionDataProvider { + interface Meta extends PermissionModule { CompletableFuture getMeta(@NotNull UUID player, @NotNull String key); } diff --git a/api/src/main/java/com/discordsrv/api/module/type/PunishmentModule.java b/api/src/main/java/com/discordsrv/api/module/type/PunishmentModule.java new file mode 100644 index 00000000..ac624235 --- /dev/null +++ b/api/src/main/java/com/discordsrv/api/module/type/PunishmentModule.java @@ -0,0 +1,47 @@ +package com.discordsrv.api.module.type; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.time.Instant; +import java.util.UUID; + +public interface PunishmentModule { + + interface Bans extends PunishmentModule { + Punishment getBan(@NotNull UUID playerUUID); + void addBan(@NotNull UUID playerUUID, @Nullable Instant until, @Nullable String reason); + void removeBan(@NotNull UUID playerUUID); + } + + interface Mutes extends PunishmentModule { + Punishment getMute(@NotNull UUID playerUUID); + void addMute(@NotNull UUID playerUUID, @Nullable Instant until, @Nullable String reason); + void removeMute(@NotNull UUID playerUUID); + } + + class Punishment { + + private final boolean active; + private final Instant until; + private final String reason; + + public Punishment(boolean active, @Nullable Instant until, @Nullable String reason) { + this.active = active; + this.until = until; + this.reason = reason; + } + + public boolean active() { + return active; + } + + public Instant until() { + return until; + } + + public String reason() { + return reason; + } + } +} diff --git a/api/src/main/java/com/discordsrv/api/player/DiscordSRVPlayer.java b/api/src/main/java/com/discordsrv/api/player/DiscordSRVPlayer.java index 2e6b487c..98c83cfe 100644 --- a/api/src/main/java/com/discordsrv/api/player/DiscordSRVPlayer.java +++ b/api/src/main/java/com/discordsrv/api/player/DiscordSRVPlayer.java @@ -23,6 +23,7 @@ package com.discordsrv.api.player; +import com.discordsrv.api.component.MinecraftComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,4 +56,10 @@ public interface DiscordSRVPlayer { @Nullable Locale locale(); + /** + * Sends the provided message to the player. + * @param component the message + */ + void sendMessage(@NotNull MinecraftComponent component); + } diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 8c5d4ce7..f95e5694 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -30,6 +30,7 @@ allprojects { repositories { maven { url 'https://papermc.io/repo/repository/maven-public/' } maven { url 'https://nexus.scarsz.me/content/groups/public/' } + maven { url 'https://repo.essentialsx.net/releases/' } } } @@ -77,6 +78,7 @@ dependencies { compileOnly(libs.mcmmo) compileOnly(libs.townychat) compileOnly(libs.venturechat) + compileOnly(libs.essentialsx) } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java new file mode 100644 index 00000000..26132071 --- /dev/null +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/EssentialsXIntegration.java @@ -0,0 +1,147 @@ +package com.discordsrv.bukkit.integration; + +import com.discordsrv.api.channel.GameChannel; +import com.discordsrv.api.component.MinecraftComponent; +import com.discordsrv.api.event.bus.Subscribe; +import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; +import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.module.type.NicknameModule; +import com.discordsrv.api.module.type.PunishmentModule; +import com.discordsrv.api.player.DiscordSRVPlayer; +import com.discordsrv.bukkit.BukkitDiscordSRV; +import com.discordsrv.bukkit.player.BukkitPlayer; +import com.discordsrv.common.component.util.ComponentUtil; +import com.discordsrv.common.module.type.PluginIntegration; +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.User; +import net.essentialsx.api.v2.events.chat.GlobalChatEvent; +import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.time.Instant; +import java.util.Collection; +import java.util.UUID; + +public class EssentialsXIntegration + extends PluginIntegration + implements Listener, PunishmentModule.Mutes, NicknameModule { + + private final GlobalChannel channel = new GlobalChannel(); + + public EssentialsXIntegration(BukkitDiscordSRV discordSRV) { + super(discordSRV); + } + + @Override + public @NotNull String getIntegrationName() { + return "Essentials"; + } + + @Override + public boolean isEnabled() { + try { + Class.forName("net.essentialsx.api.v2.events.chat.GlobalChatEvent"); + } catch (ClassNotFoundException ignored) { + return false; + } + return super.isEnabled(); + } + + private Essentials get() { + return (Essentials) discordSRV.server().getPluginManager().getPlugin("Essentials"); + } + + private User getUser(UUID playerUUID) { + return get().getUsers().loadUncachedUser(playerUUID); + } + + @Override + public String getNickname(UUID playerUUID) { + User user = getUser(playerUUID); + return user.getNickname(); + } + + @Override + public void setNickname(UUID playerUUID, String nickname) { + User user = getUser(playerUUID); + user.setNickname(nickname); + } + + @Override + public Punishment getMute(@NotNull UUID playerUUID) { + User user = getUser(playerUUID); + if (!user.isMuted()) { + return new Punishment(false, null, null); + } + + return new Punishment(true, Instant.ofEpochMilli(user.getMuteTimeout()), user.getMuteReason()); + } + + @Override + public void addMute(@NotNull UUID playerUUID, @Nullable Instant until, @Nullable String reason) { + User user = getUser(playerUUID); + user.setMuted(true); + user.setMuteTimeout(until != null ? until.toEpochMilli() : 0); + user.setMuteReason(reason); + } + + @Override + public void removeMute(@NotNull UUID playerUUID) { + User user = getUser(playerUUID); + user.setMuted(false); + user.setMuteTimeout(0); + user.setMuteReason(null); + } + + @EventHandler(priority = org.bukkit.event.EventPriority.MONITOR) + public void onGlobalChat(GlobalChatEvent event) { + Player player = event.getPlayer(); + MinecraftComponent component = ComponentUtil.toAPI( + BukkitComponentSerializer.legacy().deserialize(event.getMessage()) + ); + + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); + boolean cancelled = event.isCancelled(); + discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( + new GameChatMessageReceiveEvent(event, srvPlayer, component, channel, cancelled) + )); + } + + @Subscribe + public void onGameChannelLookup(GameChannelLookupEvent event) { + if (checkProcessor(event) || !discordSRV.server().getPluginManager().isPluginEnabled("EssentialsChat")) { + return; + } + + if (event.isDefault()) { + event.process(channel); + } + } + + private class GlobalChannel implements GameChannel { + + @Override + public @NotNull String getOwnerName() { + return getIntegrationName(); + } + + @Override + public @NotNull String getChannelName() { + return GameChannel.DEFAULT_NAME; + } + + @Override + public boolean isChat() { + return true; + } + + @Override + public @NotNull Collection getRecipients() { + return discordSRV.playerProvider().allPlayers(); + } + } +} diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java index 675da48f..e0b63a49 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/VaultIntegration.java @@ -18,7 +18,7 @@ package com.discordsrv.bukkit.integration; -import com.discordsrv.api.module.type.PermissionDataProvider; +import com.discordsrv.api.module.type.PermissionModule; import com.discordsrv.bukkit.BukkitDiscordSRV; import com.discordsrv.common.exception.MessageException; import com.discordsrv.common.function.CheckedSupplier; @@ -38,7 +38,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class VaultIntegration extends PluginIntegration implements PermissionDataProvider.Basic { +public class VaultIntegration extends PluginIntegration implements PermissionModule.Basic { private Permission permission; private Chat chat; diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/ChattyChatIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/ChattyChatIntegration.java index 4782358e..bcf29f96 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/ChattyChatIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/ChattyChatIntegration.java @@ -23,12 +23,13 @@ import com.discordsrv.api.component.MinecraftComponent; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.bukkit.BukkitDiscordSRV; +import com.discordsrv.bukkit.player.BukkitPlayer; import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.logging.NamedLogger; import com.discordsrv.common.module.type.PluginIntegration; import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer; -import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; @@ -38,6 +39,10 @@ import ru.mrbrikster.chatty.api.ChattyApi; import ru.mrbrikster.chatty.api.chats.Chat; import ru.mrbrikster.chatty.api.events.ChattyMessageEvent; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + public class ChattyChatIntegration extends PluginIntegration implements Listener { public ChattyChatIntegration(BukkitDiscordSRV discordSRV) { @@ -78,14 +83,9 @@ public class ChattyChatIntegration extends PluginIntegration i BukkitComponentSerializer.legacy().deserialize(event.getMessage()) ); + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( - new GameChatMessageReceiveEvent( - event, - discordSRV.playerProvider().player(player), - component, - new ChattyChannel(chat), - false - ) + new GameChatMessageReceiveEvent(event, srvPlayer, component, new ChattyChannel(chat), false) )); } @@ -129,11 +129,13 @@ public class ChattyChatIntegration extends PluginIntegration i } @Override - public void sendMessage(@NotNull MinecraftComponent component) { - Component comp = ComponentUtil.fromAPI(component); - for (Player recipient : chat.getRecipients(null)) { - discordSRV.playerProvider().player(recipient).sendMessage(comp); + public @NotNull Set getRecipients() { + Collection players = chat.getRecipients(null); + Set srvPlayers = new HashSet<>(players.size()); + for (Player player : players) { + srvPlayers.add(discordSRV.playerProvider().player(player)); } + return srvPlayers; } } } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/LunaChatIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/LunaChatIntegration.java index 5bf5352f..0ab77393 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/LunaChatIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/LunaChatIntegration.java @@ -23,7 +23,9 @@ import com.discordsrv.api.component.MinecraftComponent; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.bukkit.BukkitDiscordSRV; +import com.discordsrv.bukkit.player.BukkitPlayer; import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.logging.NamedLogger; import com.discordsrv.common.module.type.PluginIntegration; @@ -42,6 +44,10 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + public class LunaChatIntegration extends PluginIntegration implements Listener { public LunaChatIntegration(BukkitDiscordSRV discordSRV) { @@ -87,14 +93,10 @@ public class LunaChatIntegration extends PluginIntegration imp BukkitComponentSerializer.legacy().deserialize(event.getNgMaskedMessage()) ); + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); + boolean cancelled = event.isCancelled(); discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( - new GameChatMessageReceiveEvent( - event, - discordSRV.playerProvider().player(player), - component, - new LunaChatChannel(channel), - event.isCancelled() - ) + new GameChatMessageReceiveEvent(event, srvPlayer, component, new LunaChatChannel(channel), cancelled) )); } @@ -145,10 +147,29 @@ public class LunaChatIntegration extends PluginIntegration imp return true; } + @Override + public @NotNull Set getRecipients() { + List members = channel.getMembers(); + Set players = new HashSet<>(members.size()); + for (ChannelMember member : members) { + if (!(member instanceof ChannelMemberPlayer)) { + continue; + } + + Player player = ((ChannelMemberPlayer) member).getPlayer(); + players.add(discordSRV.playerProvider().player(player)); + } + return players; + } + @Override public void sendMessage(@NotNull MinecraftComponent component) { BaseComponent[] baseComponent = BungeeComponentSerializer.get().serialize(ComponentUtil.fromAPI(component)); for (ChannelMember member : channel.getMembers()) { + if (member instanceof ChannelMemberPlayer) { + continue; + } + member.sendMessage(baseComponent); } } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/McMMOChatIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/McMMOChatIntegration.java index 96003bbe..3206c482 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/McMMOChatIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/McMMOChatIntegration.java @@ -6,7 +6,9 @@ import com.discordsrv.api.event.bus.EventPriority; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.bukkit.BukkitDiscordSRV; +import com.discordsrv.bukkit.player.BukkitPlayer; import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.logging.NamedLogger; import com.discordsrv.common.module.type.PluginIntegration; @@ -23,6 +25,9 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.Set; + public class McMMOChatIntegration extends PluginIntegration implements Listener { private final McMMOAdminChannel adminChannel = new McMMOAdminChannel(); @@ -85,14 +90,10 @@ public class McMMOChatIntegration extends PluginIntegration im BukkitComponentSerializer.gson().deserialize(json) ); + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); + boolean cancelled = event.isCancelled(); discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( - new GameChatMessageReceiveEvent( - event, - discordSRV.playerProvider().player(player), - component, - adminChannel, - event.isCancelled() - ) + new GameChatMessageReceiveEvent(event, srvPlayer, component, adminChannel, cancelled) )); } @@ -124,6 +125,11 @@ public class McMMOChatIntegration extends PluginIntegration im return true; } + @Override + public @NotNull Set getRecipients() { + return Collections.emptySet(); + } + @Override public void sendMessage(@NotNull MinecraftComponent component) { mcMMO mcMMO = (mcMMO) discordSRV.server().getPluginManager().getPlugin("mcMMO"); diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/TownyChatIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/TownyChatIntegration.java index a2d05f3f..5700b6ba 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/TownyChatIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/TownyChatIntegration.java @@ -23,6 +23,7 @@ import com.discordsrv.api.component.MinecraftComponent; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.bukkit.BukkitDiscordSRV; import com.discordsrv.bukkit.player.BukkitPlayer; import com.discordsrv.common.component.util.ComponentUtil; @@ -39,6 +40,10 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + public class TownyChatIntegration extends PluginIntegration implements Listener { public TownyChatIntegration(BukkitDiscordSRV discordSRV) { @@ -79,14 +84,10 @@ public class TownyChatIntegration extends PluginIntegration im BukkitComponentSerializer.legacy().deserialize(event.getMessage()) ); + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); + boolean cancelled = event.isCancelled(); discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( - new GameChatMessageReceiveEvent( - event, - discordSRV.playerProvider().player(player), - component, - new TownyChatChannel(channel), - event.isCancelled() - ) + new GameChatMessageReceiveEvent(event, srvPlayer, component, new TownyChatChannel(channel), cancelled) )); } @@ -138,8 +139,11 @@ public class TownyChatIntegration extends PluginIntegration im } @Override - public void sendMessage(@NotNull MinecraftComponent component) { - for (BukkitPlayer player : discordSRV.playerProvider().allPlayers()) { + public @NotNull Set getRecipients() { + Collection players = discordSRV.playerProvider().allPlayers(); + Set filteredPlayers = new HashSet<>(players.size()); + + for (BukkitPlayer player : players) { if (!channel.isPresent(player.username())) { continue; } @@ -149,8 +153,9 @@ public class TownyChatIntegration extends PluginIntegration im continue; } - player.sendMessage(ComponentUtil.fromAPI(component)); + filteredPlayers.add(player); } + return filteredPlayers; } } } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/VentureChatIntegration.java b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/VentureChatIntegration.java index 5b08bd3d..dde33d09 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/VentureChatIntegration.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/integration/chat/VentureChatIntegration.java @@ -23,7 +23,9 @@ import com.discordsrv.api.component.MinecraftComponent; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.channel.GameChannelLookupEvent; import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.bukkit.BukkitDiscordSRV; +import com.discordsrv.bukkit.player.BukkitPlayer; import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.logging.NamedLogger; import com.discordsrv.common.module.type.PluginIntegration; @@ -33,7 +35,6 @@ import mineverse.Aust1n46.chat.api.events.VentureChatEvent; import mineverse.Aust1n46.chat.channel.ChatChannel; import mineverse.Aust1n46.chat.utilities.Format; import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer; -import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextReplacementConfig; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -41,6 +42,9 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; public class VentureChatIntegration extends PluginIntegration implements Listener { @@ -90,14 +94,9 @@ public class VentureChatIntegration extends PluginIntegration BukkitComponentSerializer.legacy().deserialize(event.getChat()) ); + BukkitPlayer srvPlayer = discordSRV.playerProvider().player(player); discordSRV.scheduler().run(() -> discordSRV.eventBus().publish( - new GameChatMessageReceiveEvent( - event, - discordSRV.playerProvider().player(player), - component, - new VentureChatChannel(channel), - false - ) + new GameChatMessageReceiveEvent(event, srvPlayer, component, new VentureChatChannel(channel), false) )); } @@ -143,13 +142,16 @@ public class VentureChatIntegration extends PluginIntegration } @Override - public void sendMessage(@NotNull MinecraftComponent component) { - for (MineverseChatPlayer player : MineverseChatAPI.getMineverseChatPlayers()) { - if (!player.isListening(channel.getName())) { + public @NotNull Set getRecipients() { + Collection chatPlayers = MineverseChatAPI.getMineverseChatPlayers(); + Set players = new HashSet<>(chatPlayers.size()); + + for (MineverseChatPlayer chatPlayer : chatPlayers) { + if (!chatPlayer.isListening(channel.getName())) { continue; } - Player bukkitPlayer = player.getPlayer(); + Player bukkitPlayer = chatPlayer.getPlayer(); if (bukkitPlayer == null) { continue; } @@ -158,18 +160,28 @@ public class VentureChatIntegration extends PluginIntegration continue; } - Component comp = ComponentUtil.fromAPI(component); - if (player.hasFilter() && channel.isFiltered()) { - comp = comp.replaceText( - TextReplacementConfig.builder() - .match(Pattern.compile("[\\w\\W]+")) - .replacement(match -> match.content(Format.FilterChat(match.content()))) - .build() - ); - } - - discordSRV.playerProvider().player(bukkitPlayer).sendMessage(comp); + players.add(discordSRV.playerProvider().player(bukkitPlayer)); } + return players; + } + + @Override + public void sendMessageToPlayer(@NotNull DiscordSRVPlayer player, @NotNull MinecraftComponent component) { + MineverseChatPlayer chatPlayer = MineverseChatAPI.getMineverseChatPlayer(player.uniqueId()); + + if (chatPlayer.hasFilter() && channel.isFiltered()) { + component = ComponentUtil.toAPI( + ComponentUtil.fromAPI(component) + .replaceText( + TextReplacementConfig.builder() + .match(Pattern.compile("[\\w\\W]+")) + .replacement(match -> match.content(Format.FilterChat(match.content()))) + .build() + ) + ); + } + + player.sendMessage(component); } } } diff --git a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java index 6cce710f..3fd84894 100644 --- a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java @@ -22,7 +22,7 @@ import com.discordsrv.api.event.events.lifecycle.DiscordSRVConnectedEvent; import com.discordsrv.api.event.events.lifecycle.DiscordSRVReadyEvent; import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadedEvent; import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent; -import com.discordsrv.api.module.type.Module; +import com.discordsrv.api.module.Module; import com.discordsrv.common.api.util.ApiInstanceUtil; import com.discordsrv.common.bootstrap.IBootstrap; import com.discordsrv.common.channel.ChannelConfigHelper; diff --git a/common/src/main/java/com/discordsrv/common/DiscordSRV.java b/common/src/main/java/com/discordsrv/common/DiscordSRV.java index ec792408..7e7d3a76 100644 --- a/common/src/main/java/com/discordsrv/common/DiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/DiscordSRV.java @@ -19,7 +19,7 @@ package com.discordsrv.common; import com.discordsrv.api.DiscordSRVApi; -import com.discordsrv.api.module.type.Module; +import com.discordsrv.api.module.Module; import com.discordsrv.api.placeholder.PlainPlaceholderFormat; import com.discordsrv.common.bootstrap.IBootstrap; import com.discordsrv.common.channel.ChannelConfigHelper; diff --git a/common/src/main/java/com/discordsrv/common/channel/GlobalChannel.java b/common/src/main/java/com/discordsrv/common/channel/GlobalChannel.java index 999b2e02..1c78055f 100644 --- a/common/src/main/java/com/discordsrv/common/channel/GlobalChannel.java +++ b/common/src/main/java/com/discordsrv/common/channel/GlobalChannel.java @@ -19,13 +19,12 @@ package com.discordsrv.common.channel; import com.discordsrv.api.channel.GameChannel; -import com.discordsrv.api.component.MinecraftComponent; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.common.DiscordSRV; -import com.discordsrv.common.component.util.ComponentUtil; -import com.discordsrv.common.player.IPlayer; -import net.kyori.adventure.text.Component; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + public class GlobalChannel implements GameChannel { private final DiscordSRV discordSRV; @@ -50,10 +49,7 @@ public class GlobalChannel implements GameChannel { } @Override - public void sendMessage(@NotNull MinecraftComponent minecraftComponent) { - Component component = ComponentUtil.fromAPI(minecraftComponent); - for (IPlayer player : discordSRV.playerProvider().allPlayers()) { - player.sendMessage(component); - } + public @NotNull Collection getRecipients() { + return discordSRV.playerProvider().allPlayers(); } } diff --git a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java index 6efe775d..8eb33ee4 100644 --- a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java +++ b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java @@ -23,7 +23,7 @@ import com.discordsrv.api.discord.entity.guild.DiscordRole; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.discord.member.role.DiscordMemberRoleAddEvent; import com.discordsrv.api.event.events.discord.member.role.DiscordMemberRoleRemoveEvent; -import com.discordsrv.api.module.type.PermissionDataProvider; +import com.discordsrv.api.module.type.PermissionModule; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.config.main.GroupSyncConfig; import com.discordsrv.common.debug.DebugGenerateEvent; @@ -157,7 +157,7 @@ public class GroupSyncModule extends AbstractModule { } } - PermissionDataProvider.Groups groups = getPermissionProvider(); + PermissionModule.Groups groups = getPermissionProvider(); if (groups != null) { builder.append("\n\nAvailable groups (").append(groups.getClass().getName()).append("):"); @@ -205,13 +205,13 @@ public class GroupSyncModule extends AbstractModule { // Permission data helper methods - private PermissionDataProvider.Groups getPermissionProvider() { - PermissionDataProvider.GroupsContext groupsContext = discordSRV.getModule(PermissionDataProvider.GroupsContext.class); - return groupsContext == null ? discordSRV.getModule(PermissionDataProvider.Groups.class) : groupsContext; + private PermissionModule.Groups getPermissionProvider() { + PermissionModule.GroupsContext groupsContext = discordSRV.getModule(PermissionModule.GroupsContext.class); + return groupsContext == null ? discordSRV.getModule(PermissionModule.Groups.class) : groupsContext; } public boolean noPermissionProvider() { - PermissionDataProvider.Groups groups = getPermissionProvider(); + PermissionModule.Groups groups = getPermissionProvider(); return groups == null || !groups.isEnabled(); } @@ -224,9 +224,9 @@ public class GroupSyncModule extends AbstractModule { String groupName, @Nullable String serverContext ) { - PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); - if (permissionProvider instanceof PermissionDataProvider.GroupsContext) { - return ((PermissionDataProvider.GroupsContext) permissionProvider) + PermissionModule.Groups permissionProvider = getPermissionProvider(); + if (permissionProvider instanceof PermissionModule.GroupsContext) { + return ((PermissionModule.GroupsContext) permissionProvider) .hasGroup(player, groupName, false, serverContext != null ? Collections.singleton(serverContext) : null); } else { return permissionProvider.hasGroup(player, groupName, false); @@ -238,9 +238,9 @@ public class GroupSyncModule extends AbstractModule { String groupName, @Nullable String serverContext ) { - PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); - if (permissionProvider instanceof PermissionDataProvider.GroupsContext) { - return ((PermissionDataProvider.GroupsContext) permissionProvider) + PermissionModule.Groups permissionProvider = getPermissionProvider(); + if (permissionProvider instanceof PermissionModule.GroupsContext) { + return ((PermissionModule.GroupsContext) permissionProvider) .addGroup(player, groupName, Collections.singleton(serverContext)); } else { return permissionProvider.addGroup(player, groupName); @@ -252,9 +252,9 @@ public class GroupSyncModule extends AbstractModule { String groupName, @Nullable String serverContext ) { - PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); - if (permissionProvider instanceof PermissionDataProvider.GroupsContext) { - return ((PermissionDataProvider.GroupsContext) permissionProvider) + PermissionModule.Groups permissionProvider = getPermissionProvider(); + if (permissionProvider instanceof PermissionModule.GroupsContext) { + return ((PermissionModule.GroupsContext) permissionProvider) .removeGroup(player, groupName, Collections.singleton(serverContext)); } else { return permissionProvider.removeGroup(player, groupName); @@ -472,7 +472,7 @@ public class GroupSyncModule extends AbstractModule { return; } - PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); + PermissionModule.Groups permissionProvider = getPermissionProvider(); if (permissionProvider == null) { discordSRV.logger().warning("No supported permission plugin available to perform group sync"); return; @@ -547,7 +547,7 @@ public class GroupSyncModule extends AbstractModule { return; } - PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); + PermissionModule.Groups permissionProvider = getPermissionProvider(); Map> futures = new LinkedHashMap<>(); for (GroupSyncConfig.PairConfig pair : pairs) { GroupSyncDirection direction = pair.direction; @@ -559,10 +559,10 @@ public class GroupSyncModule extends AbstractModule { // Check if we're in the right context String context = pair.serverContext; - if (permissionProvider instanceof PermissionDataProvider.GroupsContext) { + if (permissionProvider instanceof PermissionModule.GroupsContext) { if (StringUtils.isEmpty(context)) { // Use the default server context of the server - Set defaultValues = ((PermissionDataProvider.GroupsContext) permissionProvider) + Set defaultValues = ((PermissionModule.GroupsContext) permissionProvider) .getDefaultServerContext(); if (!Objects.equals(serverContext, defaultValues)) { continue; diff --git a/common/src/main/java/com/discordsrv/common/integration/LuckPermsIntegration.java b/common/src/main/java/com/discordsrv/common/integration/LuckPermsIntegration.java index 68b5ebd5..794513a0 100644 --- a/common/src/main/java/com/discordsrv/common/integration/LuckPermsIntegration.java +++ b/common/src/main/java/com/discordsrv/common/integration/LuckPermsIntegration.java @@ -18,7 +18,7 @@ package com.discordsrv.common.integration; -import com.discordsrv.api.module.type.PermissionDataProvider; +import com.discordsrv.api.module.type.PermissionModule; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.exception.MessageException; import com.discordsrv.common.future.util.CompletableFutureUtil; @@ -56,7 +56,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.stream.Collectors; -public class LuckPermsIntegration extends PluginIntegration implements PermissionDataProvider.All { +public class LuckPermsIntegration extends PluginIntegration implements PermissionModule.All { private LuckPerms luckPerms; private final List> subscriptions = new ArrayList<>(); diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java index d943c57b..6061dd6c 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java @@ -35,6 +35,7 @@ import com.discordsrv.api.event.events.message.forward.discord.DiscordChatMessag import com.discordsrv.api.event.events.message.process.discord.DiscordChatMessageProcessEvent; import com.discordsrv.api.event.events.message.receive.discord.DiscordChatMessageReceiveEvent; import com.discordsrv.api.placeholder.util.Placeholders; +import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.component.renderer.DiscordSRVMinecraftRenderer; import com.discordsrv.common.component.util.ComponentUtil; @@ -226,6 +227,12 @@ public class DiscordChatMessageModule extends AbstractModule { } gameChannel.sendMessage(component); + + Collection players = gameChannel.getRecipients(); + for (DiscordSRVPlayer player : players) { + gameChannel.sendMessageToPlayer(player, component); + } + discordSRV.eventBus().publish(new DiscordChatMessageForwardedEvent(component, gameChannel)); } diff --git a/common/src/main/java/com/discordsrv/common/module/ModuleManager.java b/common/src/main/java/com/discordsrv/common/module/ModuleManager.java index db78dd86..66b19c2b 100644 --- a/common/src/main/java/com/discordsrv/common/module/ModuleManager.java +++ b/common/src/main/java/com/discordsrv/common/module/ModuleManager.java @@ -26,7 +26,7 @@ import com.discordsrv.api.event.bus.EventPriority; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.lifecycle.DiscordSRVReadyEvent; import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent; -import com.discordsrv.api.module.type.Module; +import com.discordsrv.api.module.Module; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.command.game.commands.subcommand.reload.ReloadResults; import com.discordsrv.common.debug.DebugGenerateEvent; diff --git a/common/src/main/java/com/discordsrv/common/module/type/AbstractModule.java b/common/src/main/java/com/discordsrv/common/module/type/AbstractModule.java index d8499d9c..6d0b7319 100644 --- a/common/src/main/java/com/discordsrv/common/module/type/AbstractModule.java +++ b/common/src/main/java/com/discordsrv/common/module/type/AbstractModule.java @@ -22,7 +22,7 @@ import com.discordsrv.api.discord.connection.details.DiscordCacheFlag; import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; import com.discordsrv.api.event.events.Cancellable; import com.discordsrv.api.event.events.Processable; -import com.discordsrv.api.module.type.Module; +import com.discordsrv.api.module.Module; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.event.util.EventUtil; import com.discordsrv.common.logging.Logger; diff --git a/common/src/main/java/com/discordsrv/common/module/type/ModuleDelegate.java b/common/src/main/java/com/discordsrv/common/module/type/ModuleDelegate.java index c35f7b3d..1a877260 100644 --- a/common/src/main/java/com/discordsrv/common/module/type/ModuleDelegate.java +++ b/common/src/main/java/com/discordsrv/common/module/type/ModuleDelegate.java @@ -22,7 +22,7 @@ import com.discordsrv.api.DiscordSRVApi; import com.discordsrv.api.discord.connection.details.DiscordCacheFlag; import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent; import com.discordsrv.api.discord.connection.details.DiscordMemberCachePolicy; -import com.discordsrv.api.module.type.Module; +import com.discordsrv.api.module.Module; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.logging.NamedLogger; import org.jetbrains.annotations.NotNull; diff --git a/common/src/main/java/com/discordsrv/common/permission/util/PermissionUtil.java b/common/src/main/java/com/discordsrv/common/permission/util/PermissionUtil.java index 5dec2ee7..65daea8d 100644 --- a/common/src/main/java/com/discordsrv/common/permission/util/PermissionUtil.java +++ b/common/src/main/java/com/discordsrv/common/permission/util/PermissionUtil.java @@ -18,7 +18,7 @@ package com.discordsrv.common.permission.util; -import com.discordsrv.api.module.type.PermissionDataProvider; +import com.discordsrv.api.module.type.PermissionModule; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.exception.MessageException; import net.kyori.adventure.text.Component; @@ -51,7 +51,7 @@ public final class PermissionUtil { } private static Component getMeta(DiscordSRV discordSRV, UUID uuid, String metaKey) { - PermissionDataProvider.Meta meta = discordSRV.getModule(PermissionDataProvider.Meta.class); + PermissionModule.Meta meta = discordSRV.getModule(PermissionModule.Meta.class); if (meta == null) { return null; } @@ -63,9 +63,9 @@ public final class PermissionUtil { private static Component getLegacy( DiscordSRV discordSRV, String what, - Function> legacy + Function> legacy ) { - PermissionDataProvider.PrefixAndSuffix permission = discordSRV.getModule(PermissionDataProvider.PrefixAndSuffix.class); + PermissionModule.PrefixAndSuffix permission = discordSRV.getModule(PermissionModule.PrefixAndSuffix.class); if (permission == null) { return null; } diff --git a/common/src/main/java/com/discordsrv/common/player/IPlayer.java b/common/src/main/java/com/discordsrv/common/player/IPlayer.java index 95bdb864..d377bc99 100644 --- a/common/src/main/java/com/discordsrv/common/player/IPlayer.java +++ b/common/src/main/java/com/discordsrv/common/player/IPlayer.java @@ -18,11 +18,13 @@ package com.discordsrv.common.player; +import com.discordsrv.api.component.MinecraftComponent; import com.discordsrv.api.placeholder.annotation.Placeholder; import com.discordsrv.api.placeholder.annotation.PlaceholderPrefix; import com.discordsrv.api.player.DiscordSRVPlayer; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.command.game.sender.ICommandSender; +import com.discordsrv.common.component.util.ComponentUtil; import com.discordsrv.common.config.main.AvatarProviderConfig; import com.discordsrv.common.permission.util.PermissionUtil; import com.discordsrv.common.profile.Profile; @@ -36,6 +38,11 @@ import java.util.UUID; @PlaceholderPrefix("player_") public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSender { + @Override + default void sendMessage(@NotNull MinecraftComponent component) { + sendMessage(ComponentUtil.fromAPI(component)); + } + @Override DiscordSRV discordSRV(); diff --git a/settings.gradle b/settings.gradle index bd280f3d..2501d061 100644 --- a/settings.gradle +++ b/settings.gradle @@ -111,6 +111,7 @@ dependencyResolutionManagement { library('bungeecord-chat', 'net.md-5', 'bungeecord-chat').version('1.12-SNAPSHOT') library('mcmmo', 'com.gmail.nossr50', 'mcmmo').version('2.1.220') library('griefprevention', 'me.ryanhamshire', 'GriefPrevention').version('16.18.1') + library('essentialsx', 'net.essentialsx', 'EssentialsX').version('2.20.1') // Logging library('slf4j-api', 'org.slf4j', 'slf4j-api').version('1.7.36')