diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..902656b Binary files /dev/null and b/.DS_Store differ diff --git a/pom.xml b/pom.xml index ef78cf8..22064b4 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,10 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + sonatype + https://oss.sonatype.org/content/repositories/snapshots + bungeecord-repo https://oss.sonatype.org/content/repositories/snapshots @@ -40,6 +44,11 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + + central + Maven Central + https://repo.maven.apache.org/maven2 + @@ -53,6 +62,22 @@ 17 + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + false + + @@ -63,6 +88,27 @@ 1.20.1-R0.1-SNAPSHOT provided + + net.kyori + adventure-api + 4.15.0 + + + net.kyori + adventure-platform-bukkit + 4.3.2 + + + net.kyori + adventure-platform-bungeecord + 4.3.2 + compile + + + net.kyori + adventure-text-minimessage + 4.15.0 + net.md-5 bungeecord-api diff --git a/src/main/java/com/omnipico/pluralkitmc/ChatUtils.java b/src/main/java/com/omnipico/pluralkitmc/ChatUtils.java index e9852f0..2c0b95b 100644 --- a/src/main/java/com/omnipico/pluralkitmc/ChatUtils.java +++ b/src/main/java/com/omnipico/pluralkitmc/ChatUtils.java @@ -1,197 +1,154 @@ package com.omnipico.pluralkitmc; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ComponentBuilder; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import java.time.Instant; import java.util.List; -import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.time.format.DateTimeFormatter; +import java.time.LocalDateTime; +import java.time.ZoneId; public class ChatUtils { - final static BaseComponent[] pluginComponent = new ComponentBuilder("Plural").color(ChatColor.WHITE).append("Kit").color(ChatColor.GRAY).append("MC").color(ChatColor.AQUA).create(); - final static BaseComponent[] pluginTag = new ComponentBuilder("[").color(ChatColor.WHITE).append(pluginComponent).append("]").color(ChatColor.WHITE).create(); - final static BaseComponent[] helpMessage = new ComponentBuilder() - .append(pluginTag) - .append(" Help").color(ChatColor.GREEN) - .append("\nCommands: ").color(ChatColor.GREEN) - .append("\n/pk help ").color(ChatColor.AQUA) - .append("-- Lists the ").color(ChatColor.GREEN).append(pluginComponent).append(" commands").color(ChatColor.GREEN) - .append("\n/pk load ").color(ChatColor.AQUA) - .append("-- Links you to the given system id").color(ChatColor.GREEN) - .append("\n/pk update ").color(ChatColor.AQUA) - .append("-- Forces your system information to refresh").color(ChatColor.GREEN) - .append("\n/pk link ").color(ChatColor.AQUA) - .append("-- Links your account to the token from pk;token").color(ChatColor.GREEN) - .append("\n/pk unlink ").color(ChatColor.AQUA) - .append("-- Removes the attached token").color(ChatColor.GREEN) - .append("\n/pk autoproxy ").color(ChatColor.AQUA) - .append("-- Configures your autoproxy settings").color(ChatColor.GREEN) - .append("\n/pk switch [out/member...]").color(ChatColor.AQUA) - .append("-- Switch out or to one or more member").color(ChatColor.GREEN) - .append("\n/pk find ").color(ChatColor.AQUA) - .append("-- Searches for a member by name").color(ChatColor.GREEN) - .append("\n/pk random").color(ChatColor.AQUA) - .append("-- Lists a random member from your system").color(ChatColor.GREEN) - .append("\n/pk member ").color(ChatColor.AQUA) - .append("-- Display information regarding a user in your system").color(ChatColor.GREEN) - .append("\n/pk system [list] [full]").color(ChatColor.AQUA) - .append("-- Display information regarding your system, or list its members").color(ChatColor.GREEN) - .create(); - static Pattern REPLACE_ALL_RGB_PATTERN = Pattern.compile("(&)?&(#[0-9a-fA-F]{6})"); + private static final MiniMessage mm = MiniMessage.miniMessage(); - static String replaceColor(String input) { - input = ChatColor.translateAlternateColorCodes('&', input); - StringBuffer rgbBuilder = new StringBuffer(); - Matcher rgbMatcher = REPLACE_ALL_RGB_PATTERN.matcher(input); - while (rgbMatcher.find()) { - boolean isEscaped = rgbMatcher.group(1) != null; - if (!isEscaped) { - try { - final String hexCode = rgbMatcher.group(2); - rgbMatcher.appendReplacement(rgbBuilder, ChatColor.of(hexCode).toString()); - } catch (NumberFormatException ignored) { - } - } + static final Component pluginComponent = mm.deserialize("PluralKitMC"); + public static final Component pluginTag = mm.deserialize("[PluralKitMC] "); + static final Component helpMessage = mm.deserialize( + mm.serialize(pluginTag) + + " Help\nCommands: " + + "\n/pk help -- Lists the " + mm.serialize(pluginComponent) + " commands" + + "\n/pk load -- Links you to the given system id" + + "\n/pk update -- Forces your system information to refresh" + + "\n/pk link -- Links your account to the token from pk;token" + + "\n/pk unlink -- Removes the attached token" + + "\n/pk autoproxy -- Configures your autoproxy settings" + + "\n/pk switch [out/member...]-- Switch out or to one or more member" + + "\n/pk find -- Searches for a member by name" + + "\n/pk random-- Lists a random member from your system" + + "\n/pk member -- Display information regarding a user in your system" + + "\n/pk system [list] [full]-- Display information regarding your system, or list its members" + ); + + static Pattern REPLACE_ALL_RGB_PATTERN = Pattern.compile("(&)?&(#[0-9a-fA-F]{6})"); + private static String formatCreated(String created) { + try { + Instant instant = Instant.parse(created); + LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + return dateTime.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")); + } catch (Exception e) { + return created; // :c no worky } - rgbMatcher.appendTail(rgbBuilder); - return rgbBuilder.toString(); + } + static String replaceColor(String input) { + // Not needed with MiniMessage, but if you want to support legacy codes: + input = input.replace("&", "ยง"); + return input; } - static public BaseComponent[] displayMemberInfo(PluralKitMember member, PluralKitSystem system) { - ChatColor color = ChatColor.AQUA; - if (member.color != null) { - color = ChatColor.of("#" + member.color); - } - ComponentBuilder memberInfoBuilder = new ComponentBuilder() - .append(pluginTag) - .append(" Member information for ").color(ChatColor.GREEN); - if (system.name != null && system.name.length() > 0) { - memberInfoBuilder.append(member.name + " (" + system.name + ")").color(color); + public static Component displayMemberInfo(PluralKitMember member, PluralKitSystem system) { + String color = member.color != null ? "<#" + member.color + ">" : ""; + StringBuilder sb = new StringBuilder(); + sb.append(mm.serialize(pluginTag)); + sb.append(" Member information for "); + if (system.name != null && !system.name.isEmpty()) { + sb.append(color).append(member.name).append(" (").append(system.name).append(")"); } else { - memberInfoBuilder.append(member.name).color(color); + sb.append(color).append(member.name); } - memberInfoBuilder.append("\nDisplay Name: ").color(ChatColor.GREEN).append(member.name).color(color); + sb.append("\nDisplay Name: ").append(color).append(member.name); if (member.getBirthday() != null) { - memberInfoBuilder.append("\nBirthday: ").color(ChatColor.GREEN).append(member.getBirthday()).color(ChatColor.AQUA); + sb.append("\nBirthday: ").append(member.getBirthday()); } if (member.getPronouns() != null) { - memberInfoBuilder.append("\nPronouns: ").color(ChatColor.GREEN).append(member.getPronouns()).color(ChatColor.AQUA); + sb.append("\nPronouns: ").append(member.getPronouns()); } if (member.getColor() != null) { - memberInfoBuilder.append("\nColor: ").color(ChatColor.GREEN).append("#" + member.getColor()).color(color); - } - if (member.getProxy_tags() != null) { - List proxyTags = member.getProxy_tags(); - if (proxyTags.size() > 0) { - memberInfoBuilder.append("\nProxy Tags: ").color(ChatColor.GREEN); - for (int i = 0; i < proxyTags.size(); i++) { - PluralKitProxy proxyTag = proxyTags.get(i); - if (i > 0) { - memberInfoBuilder.append(", ").color(ChatColor.GREEN); - } - memberInfoBuilder.append(proxyTag.getPrefix() + "text" + proxyTag.getSuffix()).color(ChatColor.GRAY); - } + sb.append("\nColor: ").append(color).append("#").append(member.getColor()); + } + if (member.getProxy_tags() != null && !member.getProxy_tags().isEmpty()) { + sb.append("\nProxy Tags: "); + for (int i = 0; i < member.getProxy_tags().size(); i++) { + if (i > 0) sb.append(", "); + PluralKitProxy proxyTag = member.getProxy_tags().get(i); + sb.append("").append(proxyTag.getPrefix()).append("text").append(proxyTag.getSuffix()); } } if (member.getDescription() != null) { - memberInfoBuilder.append("\nDescription: ").color(ChatColor.GREEN).append(member.getDescription()).color(ChatColor.GRAY); + sb.append("\nDescription: ").append(member.getDescription()); } - memberInfoBuilder.append("\nCreated: ").color(ChatColor.GREEN).append(member.getCreated()).color(ChatColor.AQUA); - memberInfoBuilder.append("\nSystem ID: ").color(ChatColor.GREEN).append(system.getId()).color(ChatColor.GRAY); - memberInfoBuilder.append("\nMember ID: ").color(ChatColor.GREEN).append(member.getId()).color(ChatColor.GRAY); - return memberInfoBuilder.create(); + sb.append("\nCreated: ").append(formatCreated(member.getCreated())); + sb.append("\nSystem ID: ").append(system.getId()); + sb.append("\nMember ID: ").append(member.getId()); + return mm.deserialize(sb.toString()); } - static public BaseComponent[] displaySystemInfo(PluralKitSystem system) { - ComponentBuilder systemInfoBuilder = new ComponentBuilder() - .append(pluginTag) - .append(" System information for ").color(ChatColor.GREEN); - if (system.name != null && system.name.length() > 0) { - systemInfoBuilder.append(system.name).color(ChatColor.AQUA) - .append(" (").color(ChatColor.GREEN) - .append(system.id).color(ChatColor.GRAY) - .append(")").color(ChatColor.GREEN); + public static Component displaySystemInfo(PluralKitSystem system) { + StringBuilder sb = new StringBuilder(); + sb.append(mm.serialize(pluginTag)); + sb.append(" System information for "); + if (system.name != null && !system.name.isEmpty()) { + sb.append("").append(system.name) + .append(" (").append(system.id).append(")"); } else { - systemInfoBuilder.append(system.id).color(ChatColor.GRAY); + sb.append("").append(system.id); } if (system.tag != null) { - systemInfoBuilder.append("\nTag: ").color(ChatColor.GREEN).append(system.tag).color(ChatColor.AQUA); + sb.append("\nTag: ").append(system.tag); } - if (system.description != null && system.description.length() > 0) { - systemInfoBuilder.append("\nDescription: ").color(ChatColor.GREEN).append(system.description).color(ChatColor.GRAY); + if (system.description != null && !system.description.isEmpty()) { + sb.append("\nDescription: ").append(system.description); } - return systemInfoBuilder.create(); + return mm.deserialize(sb.toString()); } - static public BaseComponent[] displayMemberListForm(PluralKitMember member) { - ChatColor color = ChatColor.AQUA; - if (member.color != null) { - color = ChatColor.of("#" + member.color); - } - ComponentBuilder memberInfoBuilder = new ComponentBuilder() - .append("[").color(ChatColor.WHITE) - .append(member.id).color(ChatColor.GRAY) - .append("] ").color(ChatColor.WHITE) - .append(member.name).color(color); - if (member.getProxy_tags() != null) { - List proxyTags = member.getProxy_tags(); - if (proxyTags.size() > 0) { - memberInfoBuilder.append(" (").color(ChatColor.WHITE); - for (int i = 0; i < proxyTags.size(); i++) { - PluralKitProxy proxyTag = proxyTags.get(i); - if (i > 0) { - memberInfoBuilder.append(", ").color(ChatColor.WHITE); - } - memberInfoBuilder.append(proxyTag.getPrefix() + "text" + proxyTag.getSuffix()).color(ChatColor.GRAY); - } - memberInfoBuilder.append(")").color(ChatColor.WHITE); + public static Component displayMemberListForm(PluralKitMember member) { + String color = member.color != null ? "<#" + member.color + ">" : ""; + StringBuilder sb = new StringBuilder(); + sb.append("[").append(member.id).append("] ").append(color).append(member.name); + if (member.getProxy_tags() != null && !member.getProxy_tags().isEmpty()) { + sb.append(" ("); + for (int i = 0; i < member.getProxy_tags().size(); i++) { + if (i > 0) sb.append(", "); + PluralKitProxy proxyTag = member.getProxy_tags().get(i); + sb.append("").append(proxyTag.getPrefix()).append("text").append(proxyTag.getSuffix()); } + sb.append(")"); } - return memberInfoBuilder.create(); + return mm.deserialize(sb.toString()); } - static public BaseComponent[] displayMemberList(List members, PluralKitSystem system) { - ComponentBuilder memberListBuilder = new ComponentBuilder() - .append(pluginTag) - .append(" Members of ").color(ChatColor.GREEN); - if (system.name != null && system.name.length() > 0) { - memberListBuilder.append(system.name).color(ChatColor.AQUA) - .append(" (").color(ChatColor.GREEN) - .append(system.id).color(ChatColor.GRAY) - .append(")").color(ChatColor.GREEN); + public static Component displayMemberList(List members, PluralKitSystem system) { + StringBuilder sb = new StringBuilder(); + sb.append(mm.serialize(pluginTag)); + sb.append(" Members of "); + if (system.name != null && !system.name.isEmpty()) { + sb.append("").append(system.name) + .append(" (").append(system.id).append(")"); } else { - memberListBuilder.append(system.id).color(ChatColor.GRAY); + sb.append("").append(system.id); } - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); - memberListBuilder.append("\n") - .append(displayMemberListForm(member)); - + for (PluralKitMember member : members) { + sb.append("\n").append(mm.serialize(displayMemberListForm(member))); } - return memberListBuilder.create(); + return mm.deserialize(sb.toString()); } - static public BaseComponent[] displayMemberSearch(List members, PluralKitSystem system, String search) { - ComponentBuilder memberListBuilder = new ComponentBuilder() - .append(pluginTag) - .append(" Members of ").color(ChatColor.GREEN); - if (system.name != null && system.name.length() > 0) { - memberListBuilder.append(system.name).color(ChatColor.AQUA) - .append(" (").color(ChatColor.GREEN) - .append(system.id).color(ChatColor.GRAY) - .append(")").color(ChatColor.GREEN); + public static Component displayMemberSearch(List members, PluralKitSystem system, String search) { + StringBuilder sb = new StringBuilder(); + sb.append(mm.serialize(pluginTag)); + sb.append(" Members of "); + if (system.name != null && !system.name.isEmpty()) { + sb.append("").append(system.name) + .append(" (").append(system.id).append(")"); } else { - memberListBuilder.append(system.id).color(ChatColor.GRAY); + sb.append("").append(system.id); } - memberListBuilder.append(" matching ").color(ChatColor.GREEN) - .append(search).color(ChatColor.AQUA); - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); - memberListBuilder.append("\n") - .append(displayMemberListForm(member)); - + sb.append(" matching ").append(search); + for (PluralKitMember member : members) { + sb.append("\n").append(mm.serialize(displayMemberListForm(member))); } - return memberListBuilder.create(); + return mm.deserialize(sb.toString()); } } diff --git a/src/main/java/com/omnipico/pluralkitmc/CommandPK.java b/src/main/java/com/omnipico/pluralkitmc/CommandPK.java index c044460..3200df3 100644 --- a/src/main/java/com/omnipico/pluralkitmc/CommandPK.java +++ b/src/main/java/com/omnipico/pluralkitmc/CommandPK.java @@ -1,20 +1,16 @@ package com.omnipico.pluralkitmc; -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import java.util.ArrayList; import java.util.List; -import java.util.UUID; public class CommandPK implements CommandExecutor, TabCompleter { PluralKitData data; @@ -27,212 +23,256 @@ public CommandPK(PluralKitData data, PluralKitMC plugin) { public List getMemberList(CommandSender sender) { List memberNames = new ArrayList<>(); - if (sender instanceof Player) - { + if (sender instanceof Player) { Player player = (Player) sender; List members = data.getMembers(player.getUniqueId()); - for (int i = 0; i < members.size(); i++) { - memberNames.add(members.get(i).name); + for (PluralKitMember member : members) { + memberNames.add(member.name); } } return memberNames; } - // This method is called, when somebody uses our command @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (sender instanceof Player) { - Player player = (Player) sender; + if (sender instanceof Player player) { if (args.length >= 1) { - if (args[0].toLowerCase().equals("help") || args[0].toLowerCase().equals("h")) { - player.spigot().sendMessage(ChatUtils.helpMessage); - } else if (args[0].toLowerCase().equals("update") || args[0].toLowerCase().equals("u")) { - if (player.hasPermission("pluralkitmc.update") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - data.updateCache(player.getUniqueId(), true); - }); - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Your system is being updated and will be active momentarily.").color(ChatColor.GREEN).create()); - } else { - player.spigot().sendMessage( new ComponentBuilder("You do not have permission for this command.").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("load") || args[0].toLowerCase().equals("l")) { - if (args.length == 2) { - if (args[1].length() == 5 || args[1].length() == 6) { + String arg0 = args[0].toLowerCase(); + switch (arg0) { + case "update": + case "u": + if (player.hasPermission("pluralkitmc.update") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - data.setSystemId(player.getUniqueId(), args[1].toLowerCase()); + data.updateCache(player.getUniqueId(), true); }); - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Set system id to ").color(ChatColor.GREEN) - .append(args[1]).color(ChatColor.AQUA) - .append(", it will be active momentarily").color(ChatColor.GREEN) - .create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Your system is being updated and will be active momentarily.").color(NamedTextColor.GREEN) + )); } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" System ids must be 5/6 characters long.").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED)); } - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk load ").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("link") || args[0].toLowerCase().equals("token") || args[0].toLowerCase().equals("t")) { - if (player.hasPermission("pluralkitmc.update") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { + break; + case "load": + case "l": if (args.length == 2) { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Linking pluralkit...").color(ChatColor.GREEN) - .create()); - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { + if (args[1].length() == 5 || args[1].length() == 6) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + data.setSystemId(player.getUniqueId(), args[1].toLowerCase()); + }); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Set system id to ", NamedTextColor.GREEN) + ).append( + Component.text(args[1], NamedTextColor.AQUA) + ).append( + Component.text(", it will be active momentarily", NamedTextColor.GREEN) + )); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" System ids must be 5/6 characters long.", NamedTextColor.RED) + )); + } + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk load ", NamedTextColor.RED) + )); + } + break; + case "link": + case "token": + case "t": + if (player.hasPermission("pluralkitmc.update") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { + if (args.length == 2) { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Linking pluralkit...", NamedTextColor.GREEN) + )); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { if (data.setToken(player.getUniqueId(), args[1])) { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Your pluralkit has been linked.").color(ChatColor.GREEN) - .create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Your pluralkit has been linked.", NamedTextColor.GREEN) + )); } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Your token was invalid, try refreshing it with pk;token refresh.").color(ChatColor.RED) - .create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Your token was invalid, try refreshing it with pk;token refresh.", NamedTextColor.RED) + )); } - } - }); + }); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk link ", NamedTextColor.RED) + )); + } } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk link ").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED)); } - } else { - player.spigot().sendMessage( new ComponentBuilder("You do not have permission for this command.").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("system") || args[0].toLowerCase().equals("s")) { - if (args.length >= 2) { - if (args[1].toLowerCase().equals("list") || args[1].toLowerCase().equals("l")) { - if (args.length == 3) { - if (args[2].toLowerCase().equals("full") || args[2].toLowerCase().equals("f")) { + break; + case "system": + case "s": + if (args.length >= 2) { + String arg1 = args[1].toLowerCase(); + if (arg1.equals("list") || arg1.equals("l")) { + if (args.length == 3 && (args[2].toLowerCase().equals("full") || args[2].toLowerCase().equals("f"))) { PluralKitSystem system = data.getSystem(player.getUniqueId()); List members = data.getMembers(player.getUniqueId()); if (system != null && members.size() > 0) { - player.spigot().sendMessage(ChatUtils.displayMemberList(members, system)); + plugin.adventure().player(player).sendMessage(ChatUtils.displayMemberList(members, system)); } else { - player.spigot().sendMessage(new ComponentBuilder().append(ChatUtils.pluginTag).append(" System/Members not found :(").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" System/Members not found :(", NamedTextColor.RED) + )); } } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk system [list] [full]").color(ChatColor.RED).create()); + PluralKitSystem system = data.getSystem(player.getUniqueId()); + List members = data.getMembers(player.getUniqueId()); + if (system != null && members.size() > 0) { + plugin.adventure().player(player).sendMessage(ChatUtils.displayMemberList(members, system)); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" System/Members not found :(", NamedTextColor.RED) + )); + } } + } else if (arg1.equals("f")) { + // TODO: Show fronter } else { - PluralKitSystem system = data.getSystem(player.getUniqueId()); - List members = data.getMembers(player.getUniqueId()); - if (system != null && members.size() > 0) { - player.spigot().sendMessage(ChatUtils.displayMemberList(members, system)); - } else { - player.spigot().sendMessage(new ComponentBuilder().append(ChatUtils.pluginTag).append(" System/Members not found :(").color(ChatColor.RED).create()); - } + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk system [list] [full]", NamedTextColor.RED) + )); } - } else if (args[1].toLowerCase().equals("f")) { - //TODO: Show fronter - /*List members = data.getFronters(player.getUniqueId()); - player.spigot().sendMessage(new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Current Fronter(s): ").color(ChatColor.GREEN) - - .create());*/ } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk system [list] [full]").color(ChatColor.RED).create()); + PluralKitSystem system = data.getSystem(player.getUniqueId()); + if (system != null) { + plugin.adventure().player(player).sendMessage(ChatUtils.displaySystemInfo(system)); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" System not found :(", NamedTextColor.RED) + )); + } } - } else { - PluralKitSystem system = data.getSystem(player.getUniqueId()); - if (system != null) { - player.spigot().sendMessage(ChatUtils.displaySystemInfo(system)); + break; + case "find": + case "f": + if (args.length == 2) { + PluralKitSystem system = data.getSystem(player.getUniqueId()); + List members = data.searchMembers(player.getUniqueId(), args[1]); + if (system != null && members.size() > 0) { + plugin.adventure().player(player).sendMessage(ChatUtils.displayMemberSearch(members, system, args[1])); + } else if (system != null) { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" No members found :(", NamedTextColor.RED) + )); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Your system is not currently loaded!", NamedTextColor.RED) + )); + } } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" System not found :(").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk find ", NamedTextColor.RED) + )); } - } - } else if (args[0].toLowerCase().equals("find") || args[0].toLowerCase().equals("f")) { - if (args.length == 2) { - PluralKitSystem system = data.getSystem(player.getUniqueId()); - List members = data.searchMembers(player.getUniqueId(), args[1]); - if (system != null && members.size() > 0) - { - player.spigot().sendMessage(ChatUtils.displayMemberSearch(members, system, args[1])); - } else if (system != null) { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" No members found :(").color(ChatColor.RED).create()); + break; + case "autoproxy": + case "ap": + if (args.length == 2) { + String apMode = args[1].toLowerCase(); + if (apMode.equals("off") || apMode.equals("front") || apMode.equals("latch")) { + data.updateAutoProxyMode(player.getUniqueId(), apMode); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Auto proxy mode set to ", NamedTextColor.GREEN) + ).append( + Component.text(apMode, NamedTextColor.AQUA) + )); + } else { + apMode = "member"; + data.updateAutoProxyMode(player.getUniqueId(), apMode); + if (data.updateAutoProxyMember(player.getUniqueId(), args[1].toLowerCase())) { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Auto proxy set to ", NamedTextColor.GREEN) + ).append( + Component.text(args[1], NamedTextColor.AQUA) + )); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Could not find system member ", NamedTextColor.RED) + ).append( + Component.text(apMode, NamedTextColor.AQUA) + )); + } + } } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Your system is not currently loaded!").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk autoproxy ", NamedTextColor.RED) + )); } - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk find ").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("autoproxy") || args[0].toLowerCase().equals("ap")) { - if (args.length == 2) { - String apMode = args[1].toLowerCase(); - if (apMode.equals("off") || apMode.equals("front") || apMode.equals("latch")) { - data.updateAutoProxyMode(player.getUniqueId(), apMode); - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Auto proxy mode set to ").color(ChatColor.GREEN) - .append(apMode).color(ChatColor.AQUA) - .create()); - } else { - apMode = "member"; - data.updateAutoProxyMode(player.getUniqueId(), apMode); - if (data.updateAutoProxyMember(player.getUniqueId(), args[1].toLowerCase())) { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Auto proxy set to ").color(ChatColor.GREEN) - .append(args[1]).color(ChatColor.AQUA) - .create()); + break; + case "member": + case "m": + if (args.length == 2) { + PluralKitSystem system = data.getSystem(player.getUniqueId()); + PluralKitMember member = data.getMemberByName(player.getUniqueId(), args[1]); + if (system != null && member != null) { + plugin.adventure().player(player).sendMessage(ChatUtils.displayMemberInfo(member, system)); } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Could not find system member ").color(ChatColor.RED) - .append(apMode).color(ChatColor.AQUA) - .create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Member not found :(", NamedTextColor.RED) + )); } + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk member ", NamedTextColor.RED) + )); } - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk autoproxy ").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("member") || args[0].toLowerCase().equals("m")) { - if (args.length == 2) { + break; + case "random": + case "r": PluralKitSystem system = data.getSystem(player.getUniqueId()); - PluralKitMember member = data.getMemberByName(player.getUniqueId(), args[1]); + PluralKitMember member = data.getRandomMember(player.getUniqueId()); if (system != null && member != null) { - player.spigot().sendMessage(ChatUtils.displayMemberInfo(member, system)); + plugin.adventure().player(player).sendMessage(ChatUtils.displayMemberInfo(member, system)); } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Member not found :(").color(ChatColor.RED).create()); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Could not find any members :(", NamedTextColor.RED) + )); } - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk member ").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("random") || args[0].toLowerCase().equals("r")) { - PluralKitSystem system = data.getSystem(player.getUniqueId()); - PluralKitMember member = data.getRandomMember(player.getUniqueId()); - if (system != null && member != null) { - player.spigot().sendMessage(ChatUtils.displayMemberInfo(member, system)); - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Could not find any members :(").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("reload")) { - if (player.hasPermission("pluralkitmc.reload") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { - plugin.reloadConfigData(); - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Config reloaded.").color(ChatColor.GREEN).create()); - } else { - player.spigot().sendMessage( new ComponentBuilder("You do not have permission for this command.").color(ChatColor.RED).create()); - } - } else if (args[0].toLowerCase().equals("switch") || args[0].toLowerCase().equals("sw")) { - if (args.length >= 2) { - List newFronters = new ArrayList<>(); - for (int i = 1; i < args.length; i++) { - String memberName = args[i].toLowerCase(); - if (!memberName.equals("out")) { - newFronters.add(memberName); - } + break; + case "reload": + if (player.hasPermission("pluralkitmc.reload") || player.hasPermission("pluralkitmc.*") || player.hasPermission("*")) { + plugin.reloadConfigData(); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Config reloaded.", NamedTextColor.GREEN) + )); + } else { + plugin.adventure().player(player).sendMessage(Component.text("You do not have permission for this command.").color(NamedTextColor.RED)); } - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { - data.updateFronters(player.getUniqueId(), newFronters); - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag) - .append(" Updated fronters.").color(ChatColor.GREEN) - .create()); + break; + case "switch": + case "sw": + if (args.length >= 2) { + List newFronters = new ArrayList<>(); + for (int i = 1; i < args.length; i++) { + String memberName = args[i].toLowerCase(); + if (!memberName.equals("out")) { + newFronters.add(memberName); + } } - }); - } else { - player.spigot().sendMessage( new ComponentBuilder().append(ChatUtils.pluginTag).append(" Usage: /pk switch [out/member...]").color(ChatColor.RED).create()); - } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + data.updateFronters(player.getUniqueId(), newFronters); + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Updated fronters.", NamedTextColor.GREEN) + )); + }); + } else { + plugin.adventure().player(player).sendMessage(ChatUtils.pluginTag.append( + Component.text(" Usage: /pk switch [out/member...]", NamedTextColor.RED) + )); + } + break; + default: + plugin.adventure().player(player).sendMessage(ChatUtils.helpMessage); + break; } } else { - player.spigot().sendMessage(ChatUtils.helpMessage); + plugin.adventure().player(player).sendMessage(ChatUtils.helpMessage); } return true; } @@ -241,91 +281,53 @@ public void run() { @Override public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { - List subCommands = new ArrayList(); - //PKMC specific commands - subCommands.add("help"); - subCommands.add("update"); - subCommands.add("load"); - subCommands.add("link"); - subCommands.add("unlink"); - //Copies of PluralKit's commands - subCommands.add("system"); - subCommands.add("find"); - subCommands.add("autoproxy"); - subCommands.add("member"); - subCommands.add("random"); - subCommands.add("switch"); - subCommands.add("reload"); + List subCommands = List.of("help", "update", "load", "link", "unlink", "system", "find", "autoproxy", "member", "random", "switch", "reload"); + if (args.length == 1) { - return subCommands; - } else { - String subCommand = args[0].toLowerCase(); - // These are tab completion for clones of PluralKit commands - if (subCommand.equals("system") || subCommand.equals("s")) { - List specificSystemCommands = new ArrayList<>(); - specificSystemCommands.add("list"); - specificSystemCommands.add("fronter"); - //specificSystemCommands.add("fronthistory"); - //specificSystemCommands.add("frontpercent"); - //specificSystemCommands.add("find"); - if (args.length == 2) { - List systemCommands = new ArrayList<>(); - //System subcommands - //systemCommands.add("new"); - //systemCommands.add("rename"); - //systemCommands.add("description"); - //systemCommands.add("avatar"); - //systemCommands.add("tag"); - //systemCommands.add("timezone"); - //systemCommands.add("proxy"); - systemCommands.addAll(specificSystemCommands); - return systemCommands; - } else { - String systemSub = args[1].toLowerCase(); - if (args.length == 3 && systemSub.equals("proxy")) { - List proxyCommands = new ArrayList<>(); - proxyCommands.add("on"); - proxyCommands.add("off"); - return proxyCommands; - } else if (args.length == 3 && systemSub.length() == 5) { - return specificSystemCommands; - } - } - } else if (subCommand.equals("autoproxy") || subCommand.equals("ap")) { - if (args.length == 2) { - List autoProxyCommands = new ArrayList<>(); - autoProxyCommands.add("off"); - autoProxyCommands.add("front"); - autoProxyCommands.add("latch"); - autoProxyCommands.addAll(getMemberList(sender)); - return autoProxyCommands; - } - } else if (subCommand.equals("member") || subCommand.equals("m")) { - if (args.length == 2) { - List subMember = getMemberList(sender); - //subMember.add("new"); - return subMember; - } else if (args.length == 3 && args[1].toLowerCase().equals("new")) { - return null; - } else if (args.length == 3 && args[1].toLowerCase().equals("member")) { - List memberCommands = new ArrayList<>(); - //memberCommands.add("rename"); - //memberCommands.add("displayname"); - //memberCommands.add("servername"); - //memberCommands.add("description"); - //memberCommands.add("avatar"); - //memberCommands.add("proxy"); - //memberCommands.add("keepproxy"); - //memberCommands.add("color"); - //memberCommands.add("birthdate"); - return memberCommands; - } - } else if (subCommand.equals("switch") || subCommand.equals("sw")) { - List subMember = getMemberList(sender); - subMember.add("out"); - return subMember; + String input = args[0].toLowerCase(); + return subCommands.stream() + .filter(cmd -> cmd.startsWith(input)) + .toList(); + } + + String subCommand = args[0].toLowerCase(); + + if ((subCommand.equals("system") || subCommand.equals("s")) && args.length == 2) { + List systemCommands = List.of("list", "fronter"); + String input = args[1].toLowerCase(); + return systemCommands.stream() + .filter(cmd -> cmd.startsWith(input)) + .toList(); + } + + if ((subCommand.equals("autoproxy") || subCommand.equals("ap")) && args.length == 2) { + List autoProxyCommands = new ArrayList<>(List.of("off", "front", "latch")); + autoProxyCommands.addAll(getMemberList(sender)); + String input = args[1].toLowerCase(); + return autoProxyCommands.stream() + .filter(cmd -> cmd.startsWith(input)) + .toList(); + } + + if ((subCommand.equals("member") || subCommand.equals("m")) && args.length == 2) { + String input = args[1].toLowerCase(); + return getMemberList(sender).stream() + .filter(name -> name.toLowerCase().startsWith(input)) + .toList(); + } + + if ((subCommand.equals("switch") || subCommand.equals("sw"))) { + List subMember = getMemberList(sender); + subMember.add("out"); + if (args.length >= 2) { + String input = args[args.length - 1].toLowerCase(); + return subMember.stream() + .filter(name -> name.toLowerCase().startsWith(input)) + .toList(); } + return subMember; } - return null; + + return List.of(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/omnipico/pluralkitmc/PluralKitData.java b/src/main/java/com/omnipico/pluralkitmc/PluralKitData.java index cdeacb1..df0f7d2 100644 --- a/src/main/java/com/omnipico/pluralkitmc/PluralKitData.java +++ b/src/main/java/com/omnipico/pluralkitmc/PluralKitData.java @@ -1,83 +1,59 @@ package com.omnipico.pluralkitmc; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.java.JavaPlugin; +import com.omnipico.pluralkitmc.database.CacheManager; import java.util.*; public class PluralKitData { - FileConfiguration config; PluralKitMC plugin; - Map userCache = new HashMap<>(); long cacheUpdateFrequency; - public PluralKitData(FileConfiguration config, PluralKitMC plugin) { - this.config = config; + public PluralKitData(PluralKitMC plugin) { this.plugin = plugin; - cacheUpdateFrequency = config.getLong("cache_update_frequency"); + this.cacheUpdateFrequency = plugin.getConfig().getLong("cache-update-frequency"); } - public void setConfig(FileConfiguration config) { - this.config = config; - } + public void setConfig(org.bukkit.configuration.file.FileConfiguration config) {} String getSystemId(UUID uuid) { - if (userCache.containsKey(uuid)) { - return userCache.get(uuid).systemId; - } else { - if (this.config.contains("players." + uuid.toString() + ".system")) { - return this.config.getString("players." + uuid.toString() + ".system"); - } else { - return null; - } - } + UserCache user = CacheManager.getFromMemCache(uuid); + return user != null ? user.systemId : null; } String getToken(UUID uuid) { - if (userCache.containsKey(uuid)) { - return userCache.get(uuid).token; - } else { - if (this.config.contains("players." + uuid.toString() + ".token")) { - return this.config.getString("players." + uuid.toString() + ".token"); - } else { - return null; - } - } + UserCache user = CacheManager.getFromMemCache(uuid); + return user != null ? user.token : null; } void setSystemId(UUID uuid, String systemId) { - config.set("players." + uuid.toString() + ".system", systemId); - plugin.saveConfig(); String token = null; - if (userCache.containsKey(uuid)) { - token = userCache.get(uuid).getToken(); + UserCache user = CacheManager.getFromMemCache(uuid); + if (user != null) { + token = user.getToken(); } - userCache.remove(uuid); - UserCache user = new UserCache(uuid, systemId, token, plugin, true); - userCache.put(uuid, user); + UserCache newUser = new UserCache(uuid, systemId, token, plugin, true); + CacheManager.addToMemCache(newUser); + CacheManager.saveToDatabase(newUser, plugin); } void setSystemId(UUID uuid, String systemId, String token) { - config.set("players." + uuid.toString() + ".system", systemId); - plugin.saveConfig(); - - userCache.remove(uuid); - UserCache user = new UserCache(uuid, systemId, token, plugin, true); - userCache.put(uuid, user); + UserCache newUser = new UserCache(uuid, systemId, token, plugin, true); + CacheManager.addToMemCache(newUser); + CacheManager.saveToDatabase(newUser, plugin); } UserCache getCacheOrCreate(UUID uuid, boolean blocking) { - if (userCache.containsKey(uuid)) { - UserCache user = userCache.get(uuid); + UserCache user = CacheManager.getFromMemCache(uuid); + if (user != null) { user.updateIfNeeded(cacheUpdateFrequency, blocking); return user; } else { String systemId = getSystemId(uuid); String token = getToken(uuid); if (systemId != null) { - UserCache user = new UserCache(uuid, systemId, token, plugin, blocking); - userCache.put(uuid, user); - return user; + UserCache newUser = new UserCache(uuid, systemId, token, plugin, blocking); + CacheManager.addToMemCache(newUser); + return newUser; } else { return null; } @@ -89,8 +65,6 @@ UserCache getCacheOrCreate(UUID uuid) { } boolean setToken(UUID uuid, String token) { - config.set("players." + uuid.toString() + ".token", token); - plugin.saveConfig(); UserCache user = getCacheOrCreate(uuid); String systemId = UserCache.verifyToken(plugin, token); if (systemId != null) { @@ -99,8 +73,8 @@ boolean setToken(UUID uuid, String token) { } else { user.setToken(token); user.update(true); + CacheManager.saveToDatabase(user, plugin); } - plugin.saveConfig(); return true; } return false; @@ -110,21 +84,18 @@ void updateAutoProxyMode(UUID uuid, String mode) { UserCache userCache = getCacheOrCreate(uuid); if (userCache != null) { userCache.setAutoProxyMode(mode); + CacheManager.saveToDatabase(userCache, plugin); } - config.set("players." + uuid.toString() + ".ap_mode", mode); - plugin.saveConfig(); } boolean updateAutoProxyMember(UUID uuid, String memberName) { UserCache userCache = getCacheOrCreate(uuid); memberName = memberName.toLowerCase(); if (userCache != null) { - for (int i = 0; i < userCache.members.size(); i++) { - PluralKitMember member = userCache.members.get(i); + for (PluralKitMember member : userCache.members) { if (member.id.equals(memberName) || member.name.toLowerCase().equals(memberName)) { userCache.setAutoProxyMember(member.id); - config.set("players." + uuid.toString() + ".ap_member", member.id); - plugin.saveConfig(); + CacheManager.saveToDatabase(userCache, plugin); return true; } } @@ -136,29 +107,32 @@ void updateFronters(UUID uuid, List fronterNames) { UserCache userCache = getCacheOrCreate(uuid); if (userCache != null) { List members = new ArrayList<>(); - for (int i = 0; i < fronterNames.size(); i++) { - String fronterName = fronterNames.get(i); + for (String fronterName : fronterNames) { PluralKitMember member = userCache.getMemberByIdOrName(fronterName); if (member != null) { members.add(member); } } userCache.setFronters(members); + CacheManager.saveToDatabase(userCache, plugin); } } void updateCache(UUID uuid, boolean blocking) { UserCache user = getCacheOrCreate(uuid, blocking); - user.update(blocking); + if (user != null) { + user.update(blocking); + CacheManager.saveToDatabase(user, plugin); + } } void clearCache(UUID uuid) { - userCache.remove(uuid); + CacheManager.getFromMemCache(uuid); } String getSystemTag(UUID uuid) { UserCache user = getCacheOrCreate(uuid); - if (user != null) { + if (user != null && user.system != null) { return user.system.tag; } else { return null; @@ -170,7 +144,7 @@ List getMembers(UUID uuid) { if (user != null) { return user.members; } else { - return new ArrayList(); + return new ArrayList<>(); } } @@ -215,10 +189,8 @@ PluralKitMember getProxiedUser(UUID uuid, String message) { List members = getMembers(uuid); int fitStrength = 0; PluralKitMember bestFit = null; - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); - for (int j = 0; j < member.proxy_tags.size(); j++) { - PluralKitProxy proxy = member.proxy_tags.get(j); + for (PluralKitMember member : members) { + for (PluralKitProxy proxy : member.proxy_tags) { int proxyLength = 0; if (proxy.getPrefix() != null) { proxyLength += proxy.getPrefix().length(); @@ -226,8 +198,8 @@ PluralKitMember getProxiedUser(UUID uuid, String message) { if (proxy.getSuffix() != null) { proxyLength += proxy.getSuffix().length(); } - if (message.length() > proxyLength && (proxy.getPrefix() == null || message.substring(0, proxy.getPrefix().length()).equals(proxy.getPrefix())) - && (proxy.getSuffix() == null || message.substring(message.length()-proxy.getSuffix().length()).equals(proxy.getSuffix())) + if (message.length() > proxyLength && (proxy.getPrefix() == null || message.startsWith(proxy.getPrefix())) + && (proxy.getSuffix() == null || message.endsWith(proxy.getSuffix())) && (proxy.getPrefix() != null || proxy.getSuffix() != null)) { if (proxyLength > fitStrength) { fitStrength = proxyLength; @@ -246,8 +218,9 @@ PluralKitMember getProxiedUser(UUID uuid, String message) { bestFit = user.getFirstFronter(); } } - if (bestFit != null) { + if (bestFit != null && user != null) { user.setLastProxied(bestFit.id); + CacheManager.saveToDatabase(user, plugin); } return bestFit; } @@ -257,10 +230,8 @@ PluralKitProxy getProxy(UUID uuid, String message) { List members = getMembers(uuid); int fitStrength = 0; PluralKitProxy bestFit = null; - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); - for (int j = 0; j < member.proxy_tags.size(); j++) { - PluralKitProxy proxy = member.proxy_tags.get(j); + for (PluralKitMember member : members) { + for (PluralKitProxy proxy : member.proxy_tags) { int proxyLength = 0; if (proxy.getPrefix() != null) { proxyLength += proxy.getPrefix().length(); @@ -268,8 +239,8 @@ PluralKitProxy getProxy(UUID uuid, String message) { if (proxy.getSuffix() != null) { proxyLength += proxy.getSuffix().length(); } - if (message.length() > proxyLength && (proxy.getPrefix() == null || message.substring(0, proxy.getPrefix().length()).equals(proxy.getPrefix())) - && (proxy.getSuffix() == null || message.substring(message.length()-proxy.getSuffix().length()).equals(proxy.getSuffix())) + if (message.length() > proxyLength && (proxy.getPrefix() == null || message.startsWith(proxy.getPrefix())) + && (proxy.getSuffix() == null || message.endsWith(proxy.getSuffix())) && (proxy.getPrefix() != null || proxy.getSuffix() != null)) { if (proxyLength > fitStrength) { fitStrength = proxyLength; diff --git a/src/main/java/com/omnipico/pluralkitmc/PluralKitMC.java b/src/main/java/com/omnipico/pluralkitmc/PluralKitMC.java index f796974..856ee64 100644 --- a/src/main/java/com/omnipico/pluralkitmc/PluralKitMC.java +++ b/src/main/java/com/omnipico/pluralkitmc/PluralKitMC.java @@ -1,50 +1,70 @@ package com.omnipico.pluralkitmc; +import com.omnipico.pluralkitmc.database.CacheManager; +import com.omnipico.pluralkitmc.database.KeyManager; + import github.scarsz.discordsrv.DiscordSRV; -import me.clip.placeholderapi.PlaceholderAPI; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.milkbowl.vault.chat.Chat; import org.apache.commons.lang3.concurrent.TimedSemaphore; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.java.JavaPlugin; +import java.util.Objects; import java.util.concurrent.TimeUnit; public class PluralKitMC extends JavaPlugin { + private BukkitAudiences adventure; Chat chat; PluralKitData data; ProxyListener proxyListener; DiscordSRV discord; TimedSemaphore apiSemaphore; boolean havePlaceholderAPI = false; + private static PluralKitMC plugin; + public static PluralKitMC getInstance() {return plugin;} + private BukkitAudiences audiences; @Override public void onEnable() { + plugin = this; this.saveDefaultConfig(); - System.currentTimeMillis(); apiSemaphore = new TimedSemaphore(1, TimeUnit.SECONDS, 1); + KeyManager.setKey(); + CacheManager.connect(); + CacheManager.loadFromCache(); - // Soft dependencies + // Soft deps if (Bukkit.getServer().getPluginManager().getPlugin("Vault") != null){ chat = getServer().getServicesManager().load(Chat.class); - } + } else { getLogger().warning("Vault plugin not found!"); } if (Bukkit.getServer().getPluginManager().getPlugin("DiscordSRV") != null){ discord = DiscordSRV.getPlugin(); - } + } else { getLogger().warning("DiscordSRV plugin not found!"); } havePlaceholderAPI = Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null; + if (!havePlaceholderAPI) { + getLogger().warning("PlaceholderAPI plugin not found!"); + } + this.data = new PluralKitData(this); - FileConfiguration config = this.getConfig(); - this.data = new PluralKitData(config, this); - //Fired when the server enables the plugin CommandPK commandPK = new CommandPK(data, this); - this.getCommand("pk").setExecutor(commandPK); - this.getCommand("pk").setTabCompleter(commandPK); - proxyListener = new ProxyListener(data, config, chat, discord, havePlaceholderAPI); + Objects.requireNonNull(this.getCommand("pk")).setExecutor(commandPK); + Objects.requireNonNull(this.getCommand("pk")).setTabCompleter(commandPK); + audiences = BukkitAudiences.create(this); + proxyListener = new ProxyListener(data, chat, discord, havePlaceholderAPI, audiences); + proxyListener.setConfig(this.getConfig()); getServer().getPluginManager().registerEvents(proxyListener, this); + this.adventure = BukkitAudiences.create(this); } @Override public void onDisable() { - //Fired when the server stops and disables all plugins + if (this.adventure != null) this.adventure.close(); + CacheManager.disconnect(); + } + + public BukkitAudiences adventure() { + return this.adventure; } public void reloadConfigData() { @@ -53,5 +73,4 @@ public void reloadConfigData() { proxyListener.setConfig(config); data.setConfig(config); } - } diff --git a/src/main/java/com/omnipico/pluralkitmc/ProxyListener.java b/src/main/java/com/omnipico/pluralkitmc/ProxyListener.java index 313a8a1..0f5ddae 100644 --- a/src/main/java/com/omnipico/pluralkitmc/ProxyListener.java +++ b/src/main/java/com/omnipico/pluralkitmc/ProxyListener.java @@ -1,6 +1,5 @@ package com.omnipico.pluralkitmc; - import github.scarsz.discordsrv.DiscordSRV; import me.clip.placeholderapi.PlaceholderAPI; import net.md_5.bungee.api.chat.BaseComponent; @@ -19,13 +18,15 @@ import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; public class ProxyListener implements Listener { - //TODO: Make this a config option FileConfiguration config; String format; PluralKitData data; @@ -33,24 +34,27 @@ public class ProxyListener implements Listener { Chat chat; DiscordSRV discord; boolean usePlaceholderAPI; + BukkitAudiences audiences; + MiniMessage miniMessage = MiniMessage.miniMessage(); - public ProxyListener(PluralKitData data, FileConfiguration config, Chat chat, DiscordSRV discord, boolean usePlaceholderAPI) { + // Only config is for formatting/options, not data + public ProxyListener(PluralKitData data, Chat chat, DiscordSRV discord, boolean usePlaceholderAPI, BukkitAudiences audiences) { this.data = data; this.chat = chat; this.discord = discord; this.usePlaceholderAPI = usePlaceholderAPI; - - - setConfig(config); + this.audiences = audiences; + // Config will be set via setConfig() after construction } + // Called by main plugin to set/reload config for formatting/options public void setConfig(FileConfiguration config) { this.config = config; defaultNameColor = ChatUtils.replaceColor(config.getString("default_name_color","&b")); if (config.contains("message_format")) { - format = ChatUtils.replaceColor(Objects.requireNonNull(config.getString("message_format")).replace("%message%","%2$s")); + format = Objects.requireNonNull(config.getString("message_format")).replace("%message%","%2$s"); } else { - format = ChatColor.WHITE.toString() + "[PK] " + ChatColor.AQUA.toString() + "%member% " + ChatColor.DARK_GRAY + "> " + ChatColor.WHITE + "%2$s"; + format = "[PK] %member% > %2$s"; } } @@ -83,9 +87,7 @@ private BaseComponent[] getOutputComponent(BaseComponent[] resultComponents, Pla .strikethrough(component.isStrikethrough()) .underlined(component.isUnderlined()) .font(component.getFont()) - .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - hoverText - )) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverText)) .create())); if (component.toPlainText().length() > 8) { BaseComponent[] post = new ComponentBuilder(component.toPlainText().substring(8)) @@ -106,92 +108,76 @@ private BaseComponent[] getOutputComponent(BaseComponent[] resultComponents, Pla return components.toArray(new BaseComponent[0]); } - @EventHandler(priority = EventPriority.HIGHEST) // Listening for the event. + @EventHandler(priority = EventPriority.HIGHEST) public void onChat(AsyncPlayerChatEvent event) { - // Called when a player sends a chat message. - Player player = event.getPlayer(); // Getting the player who sent the message. + Player player = event.getPlayer(); String originalFormat = event.getFormat(); String message = event.getMessage(); PluralKitSystem system = data.getSystem(player.getUniqueId()); PluralKitMember proxiedMember = data.getProxiedUser(player.getUniqueId(), message.toLowerCase()); PluralKitProxy pluralKitProxy = data.getProxy(player.getUniqueId(), message.toLowerCase()); + if (proxiedMember != null && system != null) { String systemTag = data.getSystemTag(player.getUniqueId()); - String memberName; - String fullMemberName; - if (proxiedMember.display_name != null && proxiedMember.display_name.length() > 0) { - memberName = proxiedMember.display_name; - } else { - memberName = proxiedMember.name; - } - if (systemTag != null && systemTag.length() > 0) { - fullMemberName = memberName + " " + systemTag; - } else { - fullMemberName = memberName; - } + String memberName = (proxiedMember.display_name != null && !proxiedMember.display_name.isEmpty()) ? proxiedMember.display_name : proxiedMember.name; + String fullMemberName = (systemTag != null && !systemTag.isEmpty()) ? memberName + " " + systemTag : memberName; + int prefixLength = pluralKitProxy.prefix != null ? pluralKitProxy.prefix.length() : 0; int suffixLength = pluralKitProxy.suffix != null ? pluralKitProxy.suffix.length() : 0; - message = message.substring(prefixLength, message.length()-suffixLength); + message = message.substring(prefixLength, message.length() - suffixLength); event.setMessage(message); + String ourFormat = format; - String nameColor = proxiedMember.color == null ? defaultNameColor : ChatUtils.replaceColor("&#" + proxiedMember.color); - //ourFormat = ourFormat.replace("%member%", nameColor + memberName.replace("%2$s","%%2$s")); - ourFormat = ourFormat.replace("%member%", nameColor + "%member%"); - String prefix = ""; - String suffix = ""; - if (chat != null) { - prefix = ChatUtils.replaceColor(chat.getPlayerPrefix(player)); - suffix = ChatUtils.replaceColor(chat.getPlayerSuffix(player)); + String colorTag; + if (proxiedMember.color != null && !proxiedMember.color.isEmpty()) { + colorTag = "<#" + proxiedMember.color + ">"; + } else { + colorTag = ""; } - ourFormat = ourFormat.replace("%prefix%", prefix); - ourFormat = ourFormat.replace("%suffix%", suffix); - //Bukkit.getLogger().info("format: " + ourFormat); + ourFormat = ourFormat.replace("%member%", colorTag + "%member%"); + + String prefix = chat != null ? ChatUtils.replaceColor(chat.getPlayerPrefix(player)) : ""; + String suffix = chat != null ? ChatUtils.replaceColor(chat.getPlayerSuffix(player)) : ""; + + ourFormat = ourFormat.replace("%prefix%", prefix).replace("%suffix%", suffix); + if (!config.getBoolean("hover_text", false)) { ourFormat = ourFormat.replace("%member%", fullMemberName); } + if (usePlaceholderAPI) { ourFormat = PlaceholderAPI.setPlaceholders(player, ourFormat); } - event.setFormat(ourFormat.replaceAll("%","%%").replace("%%2$s","%2$s")); - if (config.getBoolean("hover_text", false)) { - String resultMessage = String.format(event.getFormat(), player.getDisplayName(), event.getMessage()); - BaseComponent[] resultComponents = TextComponent.fromLegacyText(resultMessage); - BaseComponent[] sendable = getOutputComponent(resultComponents, player, system, fullMemberName); - for (Player p : event.getRecipients()) { - p.spigot().sendMessage(sendable); - } - if (discord != null && config.getBoolean("discordsrv_compatibility", true)) { - if (config.getBoolean("discordsrv_use_member_names", true)) { - String oldDisplayName = player.getDisplayName(); - player.setDisplayName(fullMemberName); - discord.processChatMessage(player, message, "global", false); - player.setDisplayName(oldDisplayName); - } else { - discord.processChatMessage(player, message, "global", false); - } - } - if (config.getBoolean("keep_original_message_event", false)) { - /* - Don't cancel the original message event - Just get rid of recipients, if possible, - this means the console will not see the member name - */ - try { - event.setFormat(originalFormat); - event.getRecipients().clear(); - } catch (UnsupportedOperationException e) { - event.setCancelled(true); - } + + String finalFormatted = String.format(ourFormat.replace("%", "%%").replace("%%2$s", "%2$s"), player.getDisplayName(), message); + finalFormatted = finalFormatted.replace("%member%", fullMemberName); + Component parsed = miniMessage.deserialize(finalFormatted); + + for (Player p : event.getRecipients()) { + audiences.player(p).sendMessage(parsed); + } + + if (discord != null && config.getBoolean("discordsrv_compatibility", true)) { + if (config.getBoolean("discordsrv_use_member_names", true)) { + String oldDisplayName = player.getDisplayName(); + player.setDisplayName(fullMemberName); + discord.processChatMessage(player, message, "global", false, event); + player.setDisplayName(oldDisplayName); } else { - if (config.getBoolean("log_username", true)) { - BaseComponent[] loggable = getOutputComponent(resultComponents, player, system, fullMemberName, true); - Bukkit.getConsoleSender().spigot().sendMessage(loggable); - } else { - Bukkit.getConsoleSender().spigot().sendMessage(sendable); - } - event.setCancelled(true); + discord.processChatMessage(player, message, "global", false, event); } + } + if (config.getBoolean("keep_original_message_event", false)) { + try { + event.setFormat(originalFormat); + event.getRecipients().clear(); + } catch (UnsupportedOperationException e) { + event.setCancelled(true); + } + } else { + audiences.console().sendMessage(parsed); + event.setCancelled(true); } } } @@ -205,5 +191,4 @@ public void onJoin(PlayerJoinEvent event) { public void onQuit(PlayerQuitEvent event) { data.clearCache(event.getPlayer().getUniqueId()); } - } \ No newline at end of file diff --git a/src/main/java/com/omnipico/pluralkitmc/UserCache.java b/src/main/java/com/omnipico/pluralkitmc/UserCache.java index c1d65da..0c60fcb 100644 --- a/src/main/java/com/omnipico/pluralkitmc/UserCache.java +++ b/src/main/java/com/omnipico/pluralkitmc/UserCache.java @@ -1,68 +1,47 @@ package com.omnipico.pluralkitmc; import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; +// import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.java.JavaPlugin; +// import org.bukkit.configuration.file.FileConfiguration; +// import org.bukkit.plugin.java.JavaPlugin; import javax.net.ssl.HttpsURLConnection; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Type; -import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.util.*; +import com.omnipico.pluralkitmc.database.CacheManager; public class UserCache { - UUID uuid; - String systemId = ""; - String token = ""; - List members = new ArrayList<>(); - PluralKitSystem system = null; - long lastUpdated = 0; - boolean updateMembersToggle = false; - String autoProxyMode = "off"; + public UUID uuid; + public String systemId = ""; + public String token = ""; + public List members = new ArrayList<>(); + public PluralKitSystem system = null; + public long lastUpdated = 0; + public boolean updateMembersToggle = false; + public String autoProxyMode = "off"; String autoProxyMember = null; String lastProxied = null; List fronters = new ArrayList<>(); PluralKitMC plugin; - FileConfiguration config; - - public UserCache(UUID uuid, String systemId, PluralKitMC plugin, boolean blocking) { - this.uuid = uuid; - this.systemId = systemId; - this.plugin = plugin; - config = plugin.getConfig(); - loadFromConfig(); - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { - update(blocking); - } - }); - } public UserCache(UUID uuid, String systemId, String token, PluralKitMC plugin, boolean blocking) { this.uuid = uuid; this.systemId = systemId; this.token = token; this.plugin = plugin; - config = plugin.getConfig(); - loadFromConfig(); - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { - update(blocking); - } - }); + // oops this was boom boom line :3 + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> update(blocking)); } public void update(boolean blocking) { Date date = new Date(); lastUpdated = date.getTime(); - // Alternate between updating members and system if this is not blocking (to avoid hitting rate limits) if (blocking) { updateSystem(true); updateMembers(true); @@ -73,27 +52,12 @@ public void update(boolean blocking) { updateSystem(false); updateMembersToggle = !updateMembersToggle; } - if (config.getBoolean("cache_data", false)) { - Gson gson = new Gson(); - config.set("players." + uuid.toString() + ".system_cache", gson.toJson(system)); - config.set("players." + uuid.toString() + ".members_cache", gson.toJson(members)); - plugin.saveConfig(); - } + saveToDatabaseAndCache(); } - private void loadFromConfig() { - autoProxyMode = config.getString("players." + uuid.toString() + ".ap_mode", "off"); - autoProxyMember = config.getString("players." + uuid.toString() + ".ap_member", ""); - if (config.getBoolean("cache_data", false)) { - if (config.contains("players." + uuid.toString() + ".system_cache")) { - system = new Gson().fromJson(config.getString("players." + uuid.toString() + ".system_cache"), PluralKitSystem.class); - } - if (config.contains("players." + uuid.toString() + ".members_cache")) { - Type listType = new TypeToken>() { - }.getType(); - members = new Gson().fromJson(config.getString("players." + uuid.toString() + ".members_cache"), listType); - } - } + private void saveToDatabaseAndCache() { + CacheManager.saveToDatabase(this, plugin); + CacheManager.addToMemCache(this); } private void updateSystem(boolean blocking) { @@ -112,8 +76,8 @@ private void updateSystem(boolean blocking) { } URL url = null; try { - url = new URL("https://api.pluralkit.me/v2/systems/" + systemId); - } catch (MalformedURLException e) { + url = new URI("https://api.pluralkit.me/v2/systems/" + systemId).toURL(); + } catch (Exception e) { system = null; } InputStreamReader reader; @@ -131,8 +95,6 @@ private void updateSystem(boolean blocking) { InputStreamReader errorReader = new InputStreamReader(conn.getErrorStream()); PluralKitError pkError = new Gson().fromJson(errorReader, PluralKitError.class); if (pkError.retryAfter != null) { - // Hit a rate limit - // Unfortunately, we can't really disable the semaphore plugin.getLogger().severe("Hit a rate limit while fetching system info for " + systemId); } } else { @@ -162,8 +124,8 @@ private void updateMembers(boolean blocking) { } URL url = null; try { - url = new URL("https://api.pluralkit.me/v2/systems/" + systemId + "/members"); - } catch (MalformedURLException e) { + url = new URI("https://api.pluralkit.me/v2/systems/" + systemId + "/members").toURL(); + } catch (Exception e) { members = new ArrayList<>(); } InputStreamReader reader; @@ -181,9 +143,7 @@ private void updateMembers(boolean blocking) { InputStreamReader errorReader = new InputStreamReader(conn.getErrorStream()); PluralKitError pkError = new Gson().fromJson(errorReader, PluralKitError.class); if (pkError.retryAfter != null) { - // Hit a rate limit - // Unfortunately, we can't really disable the semaphore - plugin.getLogger().severe("Hit a rate limit while fetching system members for " + systemId); + plugin.getLogger().warning("Hit a rate limit while fetching system members for " + systemId); } } else { plugin.getLogger().warning("Failed to get system members for " + systemId); @@ -219,8 +179,8 @@ public static String verifyToken(PluralKitMC plugin, String token) { } URL url = null; try { - url = new URL("https://api.pluralkit.me/v2/systems/@me"); - } catch (MalformedURLException e) { + url = new URI("https://api.pluralkit.me/v2/systems/@me").toURL(); + } catch (Exception e) { return null; } InputStreamReader reader = null; @@ -243,9 +203,8 @@ public List getMembers() { } public PluralKitMember getMemberById(String id) { - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); - if (member.id.toLowerCase().equals(id.toLowerCase())) { + for (PluralKitMember member : members) { + if (member.id.equalsIgnoreCase(id)) { return member; } } @@ -255,7 +214,7 @@ public PluralKitMember getMemberById(String id) { public PluralKitMember getMemberByIdOrName(String id) { for (int i = 0; i < members.size(); i++) { PluralKitMember member = members.get(i); - if (member.id.toLowerCase().equals(id.toLowerCase()) || member.name.toLowerCase().equals(id.toLowerCase())) { + if (member.id.equalsIgnoreCase(id) || member.name.equalsIgnoreCase(id)) { return member; } } @@ -263,7 +222,7 @@ public PluralKitMember getMemberByIdOrName(String id) { } public PluralKitMember getRandomMember() { - if (members != null && members.size() > 0) + if (members != null && !members.isEmpty()) { return members.get(new Random().nextInt(members.size())); } @@ -272,8 +231,7 @@ public PluralKitMember getRandomMember() { public List searchMembers(String search) { List result = new ArrayList<>(); - for (int i = 0; i < members.size(); i++) { - PluralKitMember member = members.get(i); + for (PluralKitMember member : members) { if (member.name.toLowerCase().contains(search.toLowerCase())) { result.add(member); } @@ -321,7 +279,7 @@ public void setFronters(List fronters) { } public PluralKitMember getFirstFronter() { - if (fronters.size() > 0) { + if (!fronters.isEmpty()) { return fronters.get(0); } else { return null; @@ -335,4 +293,17 @@ public String getLastProxied() { public void setLastProxied(String lastProxied) { this.lastProxied = lastProxied; } + + public static UserCache loadOrCreate(UUID uuid, String systemId, String token, PluralKitMC plugin, boolean blocking) { + UserCache cached = CacheManager.getFromMemCache(uuid); + if (cached != null) return cached; + UserCache dbLoaded = CacheManager.loadFromDatabase(uuid, plugin); + if (dbLoaded != null) { + CacheManager.addToMemCache(dbLoaded); + return dbLoaded; + } + UserCache created = new UserCache(uuid, systemId, token, plugin, blocking); + CacheManager.addToMemCache(created); + return created; + } } diff --git a/src/main/java/com/omnipico/pluralkitmc/database/CacheManager.java b/src/main/java/com/omnipico/pluralkitmc/database/CacheManager.java new file mode 100644 index 0000000..f40d371 --- /dev/null +++ b/src/main/java/com/omnipico/pluralkitmc/database/CacheManager.java @@ -0,0 +1,132 @@ +package com.omnipico.pluralkitmc.database; + +import com.google.gson.Gson; +import com.omnipico.pluralkitmc.PluralKitMember; +import com.omnipico.pluralkitmc.PluralKitSystem; +import com.omnipico.pluralkitmc.UserCache; +import com.omnipico.pluralkitmc.PluralKitMC; + +import java.sql.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import static com.omnipico.pluralkitmc.PluralKitMC.getInstance; +import static com.omnipico.pluralkitmc.database.KeyManager.getKey; +import static com.omnipico.pluralkitmc.database.KeyManager.encrypt; +import static com.omnipico.pluralkitmc.database.KeyManager.decrypt; +import static java.sql.DriverManager.getConnection; + +public class CacheManager { + public static Connection conn; + private static byte[] key; + private static final Map memUserCache = new ConcurrentHashMap<>(); + private static final Gson gson = new Gson(); + + public static void connect() { + try { + conn = getConnection("jdbc:sqlite:" + getInstance().getDataFolder() + "/cache/cache.db"); + Statement state = conn.createStatement(); + state.executeUpdate(""" + CREATE TABLE IF NOT EXISTS players ( + uuid TEXT PRIMARY KEY, + system TEXT, + system_cache TEXT, + members_cache TEXT, + token TEXT, + ap_mode TEXT, + last_updated INTEGER + ) + """); + key = getKey(); + } catch (SQLException e) { + getInstance().getLogger().severe("Could not connect to the database, error: " + e.getMessage()); + } + } + + public static void disconnect() { + try { + if (conn != null && !conn.isClosed()) conn.close(); + } catch (SQLException e) { + getInstance().getLogger().severe("Could not disconnect from the database, error: " + e.getMessage()); + } + } + + public static void loadFromCache() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("SELECT * FROM players"); + while (rs.next()) { + UUID uuid = UUID.fromString(rs.getString("uuid")); + String systemId = decrypt(key, rs.getString("system")); + String token = decrypt(key, rs.getString("token")); + UserCache cache = new UserCache(uuid, systemId, token, getInstance(), true); + + // Optionally, load system and members from JSON cache + String systemCache = rs.getString("system_cache"); + if (systemCache != null && !systemCache.isEmpty()) { + cache.system = gson.fromJson(systemCache, PluralKitSystem.class); + } + String membersCache = rs.getString("members_cache"); + if (membersCache != null && !membersCache.isEmpty()) { + PluralKitMember[] members = gson.fromJson(membersCache, PluralKitMember[].class); + cache.members = Arrays.asList(members); + } + cache.autoProxyMode = rs.getString("ap_mode"); + cache.lastUpdated = rs.getLong("last_updated"); + memUserCache.put(uuid, cache); + } + } catch (Exception e) { + getInstance().getLogger().severe("Could not load from cache, error: " + e.getMessage()); + } + } + + public static void saveToDatabase(UserCache u, PluralKitMC plugin) { + try (PreparedStatement stmt = conn.prepareStatement( + "INSERT OR REPLACE INTO players (uuid, system, system_cache, members_cache, token, ap_mode, last_updated) VALUES (?, ?, ?, ?, ?, ?, ?)")) { + stmt.setString(1, u.uuid.toString()); + stmt.setString(2, encrypt(key, u.systemId)); + stmt.setString(3, u.system != null ? gson.toJson(u.system) : ""); + stmt.setString(4, u.members != null ? gson.toJson(u.members) : ""); + stmt.setString(5, encrypt(key, u.token)); + stmt.setString(6, u.autoProxyMode); + stmt.setLong(7, u.lastUpdated); + stmt.executeUpdate(); + } catch (Exception e) { + plugin.getLogger().severe("Could not save to cache, error: " + e.getMessage()); + } + } + public static void addToMemCache(UserCache u) { + memUserCache.put(u.uuid, u); + } + + public static UserCache getFromMemCache(UUID uuid) { + return memUserCache.get(uuid); + } + + public static UserCache loadFromDatabase(UUID uuid, PluralKitMC plugin) { + try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM players WHERE uuid = ?")) { + stmt.setString(1, uuid.toString()); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + String systemId = decrypt(key, rs.getString("system")); + String token = decrypt(key, rs.getString("token")); + UserCache cache = new UserCache(uuid, systemId, token, plugin, true); + + String systemCache = rs.getString("system_cache"); + if (systemCache != null && !systemCache.isEmpty()) { + cache.system = gson.fromJson(systemCache, PluralKitSystem.class); + } + String membersCache = rs.getString("members_cache"); + if (membersCache != null && !membersCache.isEmpty()) { + PluralKitMember[] members = gson.fromJson(membersCache, PluralKitMember[].class); + cache.members = Arrays.asList(members); + } + cache.autoProxyMode = rs.getString("ap_mode"); + cache.lastUpdated = rs.getLong("last_updated"); + return cache; + } + } catch (Exception e) { + plugin.getLogger().severe("Could not load user from database, error: " + e.getMessage()); + } + return null; + } +} diff --git a/src/main/java/com/omnipico/pluralkitmc/database/KeyManager.java b/src/main/java/com/omnipico/pluralkitmc/database/KeyManager.java new file mode 100644 index 0000000..8401a51 --- /dev/null +++ b/src/main/java/com/omnipico/pluralkitmc/database/KeyManager.java @@ -0,0 +1,91 @@ +package com.omnipico.pluralkitmc.database; + +import com.omnipico.pluralkitmc.PluralKitMC; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.SecureRandom; +import java.util.Base64; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.NoSuchAlgorithmException; + +import static com.omnipico.pluralkitmc.PluralKitMC.getInstance; +import static java.nio.file.StandardOpenOption.CREATE_NEW; + +public class KeyManager { + private static byte[] key; + private static final PluralKitMC plugin = getInstance(); + + public static void setKey() { + File cacheDir = new File(plugin.getDataFolder(), "cache"); + if (!cacheDir.exists() && cacheDir.mkdirs()) { + plugin.getLogger().info("Created cache directory"); + } + + Path keyPath = cacheDir.toPath().resolve("cache.key"); + try { + if (!Files.exists(keyPath)) { + key = SecureRandom.getInstanceStrong().generateSeed(32); + Files.write(keyPath, key, CREATE_NEW); + } else { + key = Files.readAllBytes(keyPath); + } + } catch (IOException | NoSuchAlgorithmException e) { + plugin.getLogger().severe("Could not create key file, error: " + e.getMessage()); + } + } + + public static byte[] getKey() { + if (key == null) { + KeyManager.setKey(); + } + return key; + } + + private static final int IV_LENGTH = 12; + private static final int TAG_LENGTH = 128; + + public static String encrypt(byte[] key, String plaintext) throws Exception { + byte[] iv = new byte[IV_LENGTH]; + SecureRandom.getInstanceStrong().nextBytes(iv); + + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + SecretKey secretKey = new SecretKeySpec(key, "AES"); + GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH, iv); + + cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec); + byte[] ciphertext = cipher.doFinal(plaintext.getBytes()); + + // Prepend IV to ciphertext + byte[] combined = new byte[iv.length + ciphertext.length]; + System.arraycopy(iv, 0, combined, 0, iv.length); + System.arraycopy(ciphertext, 0, combined, iv.length, ciphertext.length); + + return Base64.getEncoder().encodeToString(combined); + } + + public static String decrypt(byte[] key, String encryptedBase64) throws Exception { + byte[] combined = Base64.getDecoder().decode(encryptedBase64); + + byte[] iv = new byte[IV_LENGTH]; + byte[] ciphertext = new byte[combined.length - IV_LENGTH]; + + System.arraycopy(combined, 0, iv, 0, IV_LENGTH); + System.arraycopy(combined, IV_LENGTH, ciphertext, 0, ciphertext.length); + + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + SecretKey secretKey = new SecretKeySpec(key, "AES"); + GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH, iv); + + cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); + byte[] plaintext = cipher.doFinal(ciphertext); + + return new String(plaintext); + } +} + diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index bbdb8fb..9d8caba 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,6 @@ #Configuration #Update frequency, in milliseconds (300000 = 5 minutes) +# Suggestions: 30000 = 30s | 60000 = 1m | 300000 = 5m | 900000 = 15m | 1800000 = 30m cache_update_frequency: 300000 #Message format, %member% is replaced with the member display name, %message% is replaced with the message #If Vault is installed, %prefix% and %suffix% may be used for the player's prefix and suffix, respectively @@ -21,16 +22,4 @@ discordsrv_compatibility: yes #(Requires hover_text and discordsrv_compatibility enabled) discordsrv_use_member_names: yes #This determines whether PluralKitMC saves system & member data to disk for fastest retrieval -cache_data: true -#datatype: -datatype: flat -#Only if datatype is set to DB -db_username: username -db_password: password -db_database: mydb -db_url: example.org -db_port: 3306 -#Only if datatype is set to flat -players: - cf173d12-c079-4213-81f0-9daa0acfd9bd: - system: bpray \ No newline at end of file +cache_data: true # keep true unless specific need, disk is automatically encrypted \ No newline at end of file