diff --git a/src/main/java/dev/plex/Guilds.java b/src/main/java/dev/plex/Guilds.java index b8dd051..784d805 100644 --- a/src/main/java/dev/plex/Guilds.java +++ b/src/main/java/dev/plex/Guilds.java @@ -5,9 +5,11 @@ import dev.plex.data.SQLGuildManager; import dev.plex.data.SQLManager; import dev.plex.guild.Guild; import dev.plex.guild.GuildHolder; +import dev.plex.listener.impl.ChatListener; import dev.plex.module.PlexModule; import dev.plex.storage.StorageType; import dev.plex.util.PlexLog; +import io.papermc.paper.event.player.AsyncChatEvent; import lombok.Getter; import java.util.Arrays; @@ -18,7 +20,7 @@ import java.util.Arrays; public class Guilds extends PlexModule { private static Guilds module; - private GuildHolder guildHolder = new GuildHolder(); + private final GuildHolder guildHolder = new GuildHolder(); private SQLGuildManager sqlGuildManager; @@ -31,7 +33,6 @@ public class Guilds extends PlexModule @Override public void enable() { - if (getPlex().getStorageType() == StorageType.MONGODB) { getPlex().getMongoConnection().getDatastore().getMapper().map(Guild.class); diff --git a/src/main/java/dev/plex/data/SQLGuildManager.java b/src/main/java/dev/plex/data/SQLGuildManager.java index 7925917..d98179a 100644 --- a/src/main/java/dev/plex/data/SQLGuildManager.java +++ b/src/main/java/dev/plex/data/SQLGuildManager.java @@ -28,7 +28,7 @@ public class SQLGuildManager private static final String SELECT_GUILD = "SELECT * FROM `guilds`"; private static final String SELECT_GUILD_OWNER = "SELECT * FROM `guilds` WHERE owner=?"; private static final String SELECT_GUILD_MEMBER_MYSQL = "SELECT * FROM `guilds` WHERE json_search(members, ?, ?) IS NOT NULL LIMIT 1"; - private static final String INSERT_GUILD = "INSERT INTO `guilds` (`name`, `owner`, `createdAt`, `members`, `moderators`, `prefix`, `motd`, `home`, `tagEnabled`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + private static final String INSERT_GUILD = "INSERT INTO `guilds` (`name`, `owner`, `createdAt`, `members`, `moderators`, `prefix`, `motd`, `ranks`, `defaultRank`, `home`, `tagEnabled`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static final String DELETE_GUILD = "DELETE FROM `guilds` WHERE owner=?"; public CompletableFuture insertGuild(Guild guild) @@ -41,12 +41,14 @@ public class SQLGuildManager statement.setString(1, guild.getName()); statement.setString(2, guild.getOwner().toString()); statement.setLong(3, guild.getCreatedAt().toInstant().toEpochMilli()); - statement.setString(4, GSON.toJson(guild.getMembers().stream().map(UUID::toString).collect(Collectors.toList()))); + statement.setString(4, GSON.toJson(guild.getMembers())); statement.setString(5, GSON.toJson(guild.getModerators().stream().map(UUID::toString).collect(Collectors.toList()))); statement.setString(6, guild.getPrefix()); statement.setString(7, guild.getMotd()); - statement.setString(8, GSON.toJson(guild.getHome())); - statement.setBoolean(9, guild.isTagEnabled()); + statement.setString(8, GSON.toJson(guild.getRanks())); + statement.setString(9, GSON.toJson(guild.getDefaultRank())); + statement.setString(10, GSON.toJson(guild.getHome())); + statement.setBoolean(11, guild.isTagEnabled()); statement.execute(); return guild; } catch (SQLException e) diff --git a/src/main/java/dev/plex/data/SQLManager.java b/src/main/java/dev/plex/data/SQLManager.java index ad35872..7458b0f 100644 --- a/src/main/java/dev/plex/data/SQLManager.java +++ b/src/main/java/dev/plex/data/SQLManager.java @@ -27,6 +27,8 @@ public class SQLManager "`home` VARCHAR(1000)," + "`members` LONGTEXT, " + "`moderators` LONGTEXT, " + + "`ranks` LONGTEXT, " + + "`defaultRank` LONGTEXT, " + "`tagEnabled` BOOLEAN" + ");" ).execute(); diff --git a/src/main/java/dev/plex/guild/Guild.java b/src/main/java/dev/plex/guild/Guild.java index 90ed994..c167d78 100644 --- a/src/main/java/dev/plex/guild/Guild.java +++ b/src/main/java/dev/plex/guild/Guild.java @@ -4,13 +4,12 @@ import com.google.common.collect.Lists; import dev.morphia.annotations.Entity; import dev.morphia.annotations.Transient; import dev.plex.Plex; +import dev.plex.guild.data.Member; +import dev.plex.guild.data.Rank; import dev.plex.util.CustomLocation; import lombok.Data; -import org.bukkit.Location; import org.bukkit.entity.Player; -import org.json.JSONObject; -import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; @@ -23,14 +22,15 @@ public class Guild private final String name; private final UUID owner; private final ZonedDateTime createdAt; - @Transient - private final List outgoingInvitations = Lists.newArrayList(); - private final List members = Lists.newArrayList(); + private transient final List outgoingInvitations = Lists.newArrayList(); + private final List members = Lists.newArrayList(); private final List moderators = Lists.newArrayList(); + private final List ranks = Lists.newArrayList(); private String prefix; private String motd; private CustomLocation home; private boolean tagEnabled; + private Rank defaultRank = new Rank("default", null); public static Guild create(Player player, String guildName) { diff --git a/src/main/java/dev/plex/guild/GuildHolder.java b/src/main/java/dev/plex/guild/GuildHolder.java index 9ffb286..16a7f8a 100644 --- a/src/main/java/dev/plex/guild/GuildHolder.java +++ b/src/main/java/dev/plex/guild/GuildHolder.java @@ -1,11 +1,13 @@ package dev.plex.guild; import com.google.common.collect.Lists; +import dev.plex.guild.data.Member; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; public class GuildHolder { @@ -23,7 +25,7 @@ public class GuildHolder public Optional getGuild(UUID uuid) { - return GUILDS.stream().filter(guild -> guild.getOwner().equals(uuid) || guild.getMembers().contains(uuid)).findFirst(); + return GUILDS.stream().filter(guild -> guild.getOwner().equals(uuid) || guild.getMembers().stream().map(Member::uuid).toList().contains(uuid)).findFirst(); } } diff --git a/src/main/java/dev/plex/guild/data/Member.java b/src/main/java/dev/plex/guild/data/Member.java new file mode 100644 index 0000000..d9dc285 --- /dev/null +++ b/src/main/java/dev/plex/guild/data/Member.java @@ -0,0 +1,7 @@ +package dev.plex.guild.data; + +import java.util.UUID; + +public record Member(UUID uuid, Rank rank) +{ +} diff --git a/src/main/java/dev/plex/guild/data/Rank.java b/src/main/java/dev/plex/guild/data/Rank.java new file mode 100644 index 0000000..7af27d0 --- /dev/null +++ b/src/main/java/dev/plex/guild/data/Rank.java @@ -0,0 +1,5 @@ +package dev.plex.guild.data; + +public record Rank(String name, String prefix) +{ +} diff --git a/src/main/java/dev/plex/handler/ChatHandlerImpl.java b/src/main/java/dev/plex/handler/ChatHandlerImpl.java new file mode 100644 index 0000000..8269048 --- /dev/null +++ b/src/main/java/dev/plex/handler/ChatHandlerImpl.java @@ -0,0 +1,82 @@ +package dev.plex.handler; + +import dev.plex.Guilds; +import dev.plex.Plex; +import dev.plex.api.chat.IChatHandler; +import dev.plex.cache.PlayerCache; +import dev.plex.player.PlexPlayer; +import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; +import io.papermc.paper.chat.ChatRenderer; +import io.papermc.paper.event.player.AsyncChatEvent; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextReplacementConfig; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +public class ChatHandlerImpl implements IChatHandler +{ + private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig.builder().match("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]").replacement((matchResult, builder) -> Component.empty().content(matchResult.group()).clickEvent(ClickEvent.openUrl(matchResult.group()))).build(); + private final PlexChatRenderer renderer = new PlexChatRenderer(); + + @Override + public void doChat(AsyncChatEvent event) + { + PlexPlayer plexPlayer = PlayerCache.getPlexPlayerMap().get(event.getPlayer().getUniqueId()); + Component prefix = Plex.get().getRankManager().getPrefix(plexPlayer); + + if (prefix != null) + { + renderer.hasPrefix = true; + renderer.prefix = prefix; + } else + { + renderer.hasPrefix = false; + renderer.prefix = null; + } + + event.renderer(renderer); + } + + public static class PlexChatRenderer implements ChatRenderer + { + public boolean hasPrefix; + public Component prefix; + + @Override + public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) + { + String text = PlexUtils.getTextFromComponent(message); + + AtomicBoolean guildPrefix = new AtomicBoolean(false); + AtomicReference component = new AtomicReference<>(Component.empty()); + Guilds.get().getGuildHolder().getGuild(source.getUniqueId()).ifPresent(guild -> { + if (guild.getPrefix() != null) + { + component.set(component.get().append(MiniMessage.miniMessage().deserialize(guild.getPrefix()))); + guildPrefix.set(true); + } + }); + + if (hasPrefix) + { + if (guildPrefix.get()) + { + component.set(component.get().append(Component.space())); + } + component.set(component.get().append(prefix)); + } + + return component.get().append(Component.space()).append(PlexUtils.mmDeserialize(Plex.get().config.getString("chat.name-color", "") + MiniMessage.builder().tags(TagResolver.resolver(StandardTags.color(), StandardTags.rainbow(), StandardTags.decorations(), StandardTags.gradient(), StandardTags.transition())).build().serialize(sourceDisplayName))).append(Component.space()).append(Component.text("ยป").color(NamedTextColor.GRAY)).append(Component.space()).append(SafeMiniMessage.mmDeserializeWithoutEvents(text)).replaceText(URL_REPLACEMENT_CONFIG); + } + } +}