From c4b878f6b4c718aa07642ca2f803431aeeefff28 Mon Sep 17 00:00:00 2001 From: Pugzy Date: Sun, 24 Nov 2024 15:21:02 +0000 Subject: [PATCH] Add party chat and admin list command --- .../java/dev/pgm/community/Community.java | 7 ++ .../pgm/community/CommunityPermissions.java | 1 + .../chat/network/NetworkChatFeature.java | 16 ++-- .../chat/network/NetworkChatMessage.java | 10 +-- .../commands/graph/CommunityCommandGraph.java | 5 ++ .../pgm/community/squads/SquadChannel.java | 80 +++++++++++++++++++ .../pgm/community/squads/SquadCommands.java | 51 +++++++++++- .../pgm/community/squads/SquadFeature.java | 5 ++ core/src/main/resources/strings.properties | 1 + 9 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 core/src/main/java/dev/pgm/community/squads/SquadChannel.java diff --git a/core/src/main/java/dev/pgm/community/Community.java b/core/src/main/java/dev/pgm/community/Community.java index 74edb9ea..99c10d92 100644 --- a/core/src/main/java/dev/pgm/community/Community.java +++ b/core/src/main/java/dev/pgm/community/Community.java @@ -4,6 +4,7 @@ import dev.pgm.community.database.DatabaseConnection; import dev.pgm.community.events.CommunityEvent; import dev.pgm.community.feature.FeatureManager; +import dev.pgm.community.squads.SquadChannel; import dev.pgm.community.text.TextTranslations; import dev.pgm.community.utils.PGMUtils; import fr.minuskube.inv.InventoryManager; @@ -12,6 +13,7 @@ import org.bukkit.Bukkit; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; +import tc.oc.pgm.api.integration.Integration; import tc.oc.pgm.util.bukkit.BukkitUtils; public class Community extends JavaPlugin { @@ -29,6 +31,11 @@ public class Community extends JavaPlugin { private Random random; + @Override + public void onLoad() { + Integration.registerChannel(SquadChannel.INSTANCE); + } + @Override public void onEnable() { plugin = this; diff --git a/core/src/main/java/dev/pgm/community/CommunityPermissions.java b/core/src/main/java/dev/pgm/community/CommunityPermissions.java index 9fa92236..30b77bfb 100644 --- a/core/src/main/java/dev/pgm/community/CommunityPermissions.java +++ b/core/src/main/java/dev/pgm/community/CommunityPermissions.java @@ -115,6 +115,7 @@ public interface CommunityPermissions { // Squads String SQUAD = ROOT + ".squad"; // Access to squad commands String SQUAD_CREATE = SQUAD + ".create"; // Can create a squad + String SQUAD_ADMIN = SQUAD + ".admin"; // Administrative squad permission // General Commands String FLIGHT = ROOT + ".fly"; diff --git a/core/src/main/java/dev/pgm/community/chat/network/NetworkChatFeature.java b/core/src/main/java/dev/pgm/community/chat/network/NetworkChatFeature.java index f81c3270..b7a9bbd9 100644 --- a/core/src/main/java/dev/pgm/community/chat/network/NetworkChatFeature.java +++ b/core/src/main/java/dev/pgm/community/chat/network/NetworkChatFeature.java @@ -16,8 +16,8 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.configuration.Configuration; import org.bukkit.event.EventHandler; -import tc.oc.pgm.util.channels.Channel; -import tc.oc.pgm.util.event.ChannelMessageEvent; +import tc.oc.pgm.api.event.ChannelMessageEvent; +import tc.oc.pgm.channels.AdminChannel; public class NetworkChatFeature extends FeatureBase { @@ -34,14 +34,14 @@ public NetworkChatFeature(Configuration config, Logger logger, NetworkFeature ne } @EventHandler - public void onMatchPlayerChat(ChannelMessageEvent event) { - if (event.getChannel() == Channel.ADMIN) { + public void onMatchPlayerChat(ChannelMessageEvent event) { + if (event.getChannel() instanceof AdminChannel) { network.sendUpdate(new ChatUpdate(new NetworkChatMessage(event, getServer()))); } // TODO: maybe more cross server message types? } public void recieveUpdate(NetworkChatMessage message) { - if (message.getChannel() == Channel.ADMIN) { + if (message.getChannel() instanceof AdminChannel) { Component formatted = formatMessage(message.getSender(), message.getMessage()); BroadcastUtils.sendAdminChatMessage( formatted, @@ -52,6 +52,10 @@ public void recieveUpdate(NetworkChatMessage message) { } private Component formatMessage(Component sender, Component message) { - return text().append(sender).append(text(": ", NamedTextColor.WHITE)).append(message).build(); + return text() + .append(sender) + .append(text(": ", NamedTextColor.WHITE)) + .append(message) + .build(); } } diff --git a/core/src/main/java/dev/pgm/community/chat/network/NetworkChatMessage.java b/core/src/main/java/dev/pgm/community/chat/network/NetworkChatMessage.java index 8e9aa78e..b7a845dd 100644 --- a/core/src/main/java/dev/pgm/community/chat/network/NetworkChatMessage.java +++ b/core/src/main/java/dev/pgm/community/chat/network/NetworkChatMessage.java @@ -5,9 +5,9 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import tc.oc.pgm.api.channels.Channel; +import tc.oc.pgm.api.event.ChannelMessageEvent; import tc.oc.pgm.util.Audience; -import tc.oc.pgm.util.channels.Channel; -import tc.oc.pgm.util.event.ChannelMessageEvent; import tc.oc.pgm.util.named.NameStyle; import tc.oc.pgm.util.text.TextTranslations; @@ -16,9 +16,9 @@ public class NetworkChatMessage { private String message; private String sender; private String server; - private Channel channel; + private Channel channel; - public NetworkChatMessage(ChannelMessageEvent event, String server) { + public NetworkChatMessage(ChannelMessageEvent event, String server) { this.message = toMinecraftGson(text(event.getMessage())); this.sender = toMinecraftGson(player(event.getSender(), NameStyle.FANCY)); this.channel = event.getChannel(); @@ -37,7 +37,7 @@ public String getServer() { return server; } - public Channel getChannel() { + public Channel getChannel() { return channel; } diff --git a/core/src/main/java/dev/pgm/community/commands/graph/CommunityCommandGraph.java b/core/src/main/java/dev/pgm/community/commands/graph/CommunityCommandGraph.java index 514cce43..8c17c93f 100644 --- a/core/src/main/java/dev/pgm/community/commands/graph/CommunityCommandGraph.java +++ b/core/src/main/java/dev/pgm/community/commands/graph/CommunityCommandGraph.java @@ -65,7 +65,9 @@ import tc.oc.pgm.command.util.CommandGraph; import tc.oc.pgm.lib.org.incendo.cloud.minecraft.extras.MinecraftHelp; import tc.oc.pgm.lib.org.incendo.cloud.parser.standard.StringParser; +import tc.oc.pgm.lib.org.incendo.cloud.suggestion.SuggestionProvider; import tc.oc.pgm.util.Audience; +import tc.oc.pgm.util.Players; public class CommunityCommandGraph extends CommandGraph { @@ -99,6 +101,9 @@ protected void setupParsers() { registerParser(GameMode.class, new GameModeParser()); registerParser(OfflinePlayer.class, new OfflinePlayerParser()); registerParser(MatchPlayer.class, new MatchPlayerParser()); + + parsers.registerSuggestionProvider( + "players", SuggestionProvider.blockingStrings(Players::suggestPlayers)); } @Override diff --git a/core/src/main/java/dev/pgm/community/squads/SquadChannel.java b/core/src/main/java/dev/pgm/community/squads/SquadChannel.java new file mode 100644 index 00000000..7dcf8397 --- /dev/null +++ b/core/src/main/java/dev/pgm/community/squads/SquadChannel.java @@ -0,0 +1,80 @@ +package dev.pgm.community.squads; + +import static net.kyori.adventure.text.Component.empty; +import static net.kyori.adventure.text.Component.text; +import static tc.oc.pgm.util.text.TextException.exception; + +import java.util.Collection; +import java.util.List; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.Nullable; +import tc.oc.pgm.api.PGM; +import tc.oc.pgm.api.channels.Channel; +import tc.oc.pgm.api.match.MatchManager; +import tc.oc.pgm.api.player.MatchPlayer; +import tc.oc.pgm.lib.org.incendo.cloud.context.CommandContext; +import tc.oc.pgm.util.named.NameStyle; + +public class SquadChannel implements Channel { + + public static final SquadChannel INSTANCE = new SquadChannel(); + + private static final List ALIASES = List.of("sc", "pc"); + + public static final TextComponent PREFIX = + text().append(text("(Party) ", NamedTextColor.YELLOW)).build(); + + private SquadFeature squads; + private MatchManager matchManager; + + public void init(SquadFeature squadFeature) { + this.squads = squadFeature; + this.matchManager = PGM.get().getMatchManager(); + } + + @Override + public String getDisplayName() { + return "squad"; + } + + @Override + public List getAliases() { + return ALIASES; + } + + @Override + public String getLoggerFormat(Squad target) { + return "(Party) %s: %s"; + } + + @Override + public Squad getTarget(MatchPlayer matchPlayer, CommandContext commandContext) { + Squad squad = squads.getSquadByPlayer(matchPlayer); + if (squad == null) throw exception("squad.err.memberOnly"); + + return squad; + } + + @Override + public Collection getViewers(Squad squad) { + return squad.getPlayers().stream().map(uuid -> matchManager.getPlayer(uuid)).toList(); + } + + @Override + public Component formatMessage(Squad squad, @Nullable MatchPlayer sender, Component message) { + return text() + .append(PREFIX) + .append( + sender != null + ? text() + .append(sender.getName(NameStyle.VERBOSE)) + .append(text(": ", NamedTextColor.WHITE)) + .build() + : empty()) + .append(message) + .build(); + } +} diff --git a/core/src/main/java/dev/pgm/community/squads/SquadCommands.java b/core/src/main/java/dev/pgm/community/squads/SquadCommands.java index 9dafbe71..72ab9ca7 100644 --- a/core/src/main/java/dev/pgm/community/squads/SquadCommands.java +++ b/core/src/main/java/dev/pgm/community/squads/SquadCommands.java @@ -6,6 +6,7 @@ import static net.kyori.adventure.text.event.HoverEvent.showText; import static tc.oc.pgm.util.player.PlayerComponent.player; import static tc.oc.pgm.util.text.TextException.exception; +import static tc.oc.pgm.util.text.TextFormatter.horizontalLineHeading; import co.aikar.commands.annotation.CommandPermission; import com.google.common.collect.ImmutableList; @@ -19,11 +20,14 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; import tc.oc.pgm.api.PGM; import tc.oc.pgm.api.player.MatchPlayer; import tc.oc.pgm.lib.org.incendo.cloud.annotations.Argument; import tc.oc.pgm.lib.org.incendo.cloud.annotations.Command; import tc.oc.pgm.lib.org.incendo.cloud.annotations.CommandDescription; +import tc.oc.pgm.lib.org.incendo.cloud.annotations.Flag; +import tc.oc.pgm.lib.org.incendo.cloud.context.CommandContext; import tc.oc.pgm.util.Players; import tc.oc.pgm.util.PrettyPaginatedComponentResults; import tc.oc.pgm.util.named.NameStyle; @@ -43,7 +47,7 @@ public SquadCommands() { @CommandPermission(CommunityPermissions.SQUAD) public void listDefault(MatchPlayer sender) { checkEnabled(); - list(sender); + list(sender, false); } @Command("") @@ -123,14 +127,40 @@ public void leave(MatchPlayer sender) { @Command("list") @CommandDescription("List party members") @CommandPermission(CommunityPermissions.SQUAD) - public void list(MatchPlayer sender) { + public void list(MatchPlayer sender, @Flag(value = "all", aliases = "a") boolean all) { checkEnabled(); + + if (all && sender.getBukkit().hasPermission(CommunityPermissions.SQUAD_ADMIN)) { + Component header = horizontalLineHeading( + sender.getBukkit(), translatable("squad.list.all"), NamedTextColor.BLUE); + + new PrettyPaginatedComponentResults(header, manager.getSquads().size()) { + @Override + public Component format(Squad squad, int index) { + return text() + .append(text(index + 1)) + .append(text(". ")) + .append(player(squad.getLeader(), NameStyle.VERBOSE)) + .append(text(": ")) + .append(TextFormatter.list( + squad.getPlayers().stream() + .skip(1) + .map(uuid -> player(uuid, NameStyle.VERBOSE)) + .toList(), + NamedTextColor.GRAY)) + .build(); + } + }.display(sender, ImmutableList.copyOf(manager.getSquads()), 1); + + return; + } + Squad squad = manager.getSquadByPlayer(sender); if (squad == null) throw exception("squad.err.memberOnly"); boolean isLeader = Objects.equals(sender.getId(), squad.getLeader()); - Component header = TextFormatter.horizontalLineHeading( + Component header = horizontalLineHeading( sender.getBukkit(), translatable("squad.list.header", player(squad.getLeader(), NameStyle.VERBOSE)), NamedTextColor.BLUE); @@ -168,6 +198,21 @@ public Component format(UUID player, int index) { }.display(sender, ImmutableList.copyOf(squad.getAllPlayers()), 1); } + @Command("chat [message]") + @CommandDescription("Sends a message to your party") + @CommandPermission(CommunityPermissions.SQUAD) + public void chat( + CommandContext context, + MatchPlayer sender, + @Argument(value = "message", suggestions = "players") String message) { + checkEnabled(); + if (message == null) { + PGM.get().getChatManager().setChannel(sender, SquadChannel.INSTANCE); + } else { + PGM.get().getChatManager().process(SquadChannel.INSTANCE, sender, context); + } + } + @Command("kick ") @CommandDescription("Kick a player from your party") @CommandPermission(CommunityPermissions.SQUAD) diff --git a/core/src/main/java/dev/pgm/community/squads/SquadFeature.java b/core/src/main/java/dev/pgm/community/squads/SquadFeature.java index 49087989..54cbcfd4 100644 --- a/core/src/main/java/dev/pgm/community/squads/SquadFeature.java +++ b/core/src/main/java/dev/pgm/community/squads/SquadFeature.java @@ -58,9 +58,14 @@ public SquadFeature(Configuration config, Logger logger) { if (getConfig().isEnabled() && isPGMEnabled()) { enable(); Integration.setSquadIntegration(this); + SquadChannel.INSTANCE.init(this); } } + public List getSquads() { + return squads; + } + @Override public boolean areInSquad(Player a, Player b) { Squad squad = getSquadByPlayer(a.getUniqueId()); diff --git a/core/src/main/resources/strings.properties b/core/src/main/resources/strings.properties index 4c428c6a..9fb43fe3 100644 --- a/core/src/main/resources/strings.properties +++ b/core/src/main/resources/strings.properties @@ -13,6 +13,7 @@ squad.deny.leader = {0} has denied your invitation squad.leave.success = Successfully left the party +squad.list.all = Parties squad.list.header = {0}'s Party squad.list.leader = (leader) squad.list.pending = (pending)