diff --git a/README.md b/README.md index 9fad060..e06e25c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # ECATUP (_Efrei Craft's Awesome Tools and Utilities Plugin_) ---- [![Java CI with Gradle](https://github.com/efrei-craft/ECATUP/actions/workflows/gradle.yml/badge.svg)](https://github.com/efrei-craft/ECATUP/actions/workflows/gradle.yml) ## Les commandes et fonctions utiles d'Efrei Craft diff --git a/build.gradle b/build.gradle index 943e712..7839cd9 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group = 'fr.efreicraft' -version = '1.0.9' +version = '1.0.10' compileJava.options.encoding "UTF-8" diff --git a/src/main/java/fr/efreicraft/ecatup/Main.java b/src/main/java/fr/efreicraft/ecatup/Main.java index 5826be0..bc54730 100644 --- a/src/main/java/fr/efreicraft/ecatup/Main.java +++ b/src/main/java/fr/efreicraft/ecatup/Main.java @@ -7,6 +7,7 @@ import fr.efreicraft.ecatup.listeners.Join; import fr.efreicraft.ecatup.listeners.LuckPermsListener; import fr.efreicraft.ecatup.listeners.Quit; +import fr.efreicraft.ecatup.utils.DBConnection; import fr.efreicraft.ecatup.utils.DiscordWebhook; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -24,19 +25,17 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +@SuppressWarnings("UnstableApiUsage") public final class Main extends JavaPlugin { public static JavaPlugin INSTANCE; public static FileConfiguration config; - public static Connection connection; + public static DBConnection DB; public static LuckPerms LP; @@ -56,12 +55,12 @@ public void onEnable() { try { Class.forName("org.mariadb.jdbc.Driver"); - connection = DriverManager.getConnection("jdbc:mariadb://" - + config.getString("database.host") - + ":" + config.getInt("database.port") + "/" + config.getString("database.database") - + "?user=" + config.getString("database.user") - + "&password=" + config.getString("database.password") - + "&autoReconnect=true"); + DB = new DBConnection(config.getString("database.host"), + config.getInt("database.port"), + config.getString("database.database"), + config.getString("database.user"), + config.getString("database.password")); + DB.open(); } catch (Exception e) { e.printStackTrace(); } @@ -77,7 +76,7 @@ public void onEnable() { Bukkit.getPluginManager().registerEvents(new LuckPermsListener((Main) INSTANCE, LP), INSTANCE); // Register commands - if (!config.getString("server_name").equals("lobby")) { + if (!config.getString("server_name", "").equals("lobby")) { registerCommand("lobby", new Lobby()); // Only register /lobby if the server's name is "lobby" } @@ -117,11 +116,7 @@ public void onDisable() { getServer().getMessenger().unregisterIncomingPluginChannel(INSTANCE); // Close database connection - try { - connection.close(); - } catch (SQLException e) { - throw new RuntimeException(e); - } + DB.close(); // Send log to Discord DiscordWebhook webhook = new DiscordWebhook(config.getString("webhook")); @@ -131,10 +126,10 @@ public void onDisable() { .setColor(java.awt.Color.decode("#ffffff")) .setFooter("Efrei Craft", "https://efreicraft.fr/img/favicon.png") ); - - for (Player player : Bukkit.getOnlinePlayers()) { - sendPlayerToServer(player, "lobby"); - } + if (!config.getString("server_name", "").equalsIgnoreCase("lobby")) + for (Player player : Bukkit.getOnlinePlayers()) { + sendPlayerToServer(player, "lobby"); + } try { webhook.execute(); diff --git a/src/main/java/fr/efreicraft/ecatup/commands/Chat.java b/src/main/java/fr/efreicraft/ecatup/commands/Chat.java index 7382f17..500b40d 100644 --- a/src/main/java/fr/efreicraft/ecatup/commands/Chat.java +++ b/src/main/java/fr/efreicraft/ecatup/commands/Chat.java @@ -14,7 +14,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -22,6 +21,7 @@ import static fr.efreicraft.ecatup.utils.Msg.colorize; +@SuppressWarnings("ConstantConditions") public class Chat implements CommandExecutor, TabExecutor { @Override @@ -76,7 +76,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command public void sendChannelPrefToDB(Player player, PreferenceCache.ChatChannel channel) { try { - PreparedStatement verifyIfHasEntry = Main.connection.prepareStatement("SELECT * FROM `usersPrefs` WHERE mcUUID=?"); + PreparedStatement verifyIfHasEntry = Main.DB.openThenGetConnection().prepareStatement("SELECT * FROM `usersPrefs` WHERE mcUUID=?"); verifyIfHasEntry.setString(1, player.getUniqueId().toString()); ResultSet result1 = verifyIfHasEntry.executeQuery(); boolean hasEntryInDB = result1.next(); @@ -84,7 +84,7 @@ public void sendChannelPrefToDB(Player player, PreferenceCache.ChatChannel chann verifyIfHasEntry.close(); result1.close(); - PreparedStatement applyChanges = Main.connection.prepareStatement(hasEntryInDB ? "UPDATE `usersPrefs` SET channel=? WHERE mcUUID=?" + PreparedStatement applyChanges = Main.DB.openThenGetConnection().prepareStatement(hasEntryInDB ? "UPDATE `usersPrefs` SET channel=? WHERE mcUUID=?" : "INSERT INTO `usersPrefs` (channel, mcUUID) VALUES(?,?)"); applyChanges.setInt(1, channel.ID); diff --git a/src/main/java/fr/efreicraft/ecatup/commands/Gmc.java b/src/main/java/fr/efreicraft/ecatup/commands/Gmc.java index a1e535c..06c7b28 100644 --- a/src/main/java/fr/efreicraft/ecatup/commands/Gmc.java +++ b/src/main/java/fr/efreicraft/ecatup/commands/Gmc.java @@ -13,7 +13,7 @@ public class Gmc implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = null; + Player player; if (args.length == 0) { if (sender instanceof Player) { player = (Player) sender; diff --git a/src/main/java/fr/efreicraft/ecatup/commands/Gms.java b/src/main/java/fr/efreicraft/ecatup/commands/Gms.java index 383f743..b7220cb 100644 --- a/src/main/java/fr/efreicraft/ecatup/commands/Gms.java +++ b/src/main/java/fr/efreicraft/ecatup/commands/Gms.java @@ -13,7 +13,7 @@ public class Gms implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = null; + Player player; if (args.length == 0) { if (sender instanceof Player) { player = (Player) sender; diff --git a/src/main/java/fr/efreicraft/ecatup/commands/Gmsp.java b/src/main/java/fr/efreicraft/ecatup/commands/Gmsp.java index da00edd..1a60772 100644 --- a/src/main/java/fr/efreicraft/ecatup/commands/Gmsp.java +++ b/src/main/java/fr/efreicraft/ecatup/commands/Gmsp.java @@ -13,7 +13,7 @@ public class Gmsp implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = null; + Player player; if (args.length == 0) { if (sender instanceof Player) { player = (Player) sender; diff --git a/src/main/java/fr/efreicraft/ecatup/commands/WhoIs.java b/src/main/java/fr/efreicraft/ecatup/commands/WhoIs.java index 1e72dd1..ce77c2d 100644 --- a/src/main/java/fr/efreicraft/ecatup/commands/WhoIs.java +++ b/src/main/java/fr/efreicraft/ecatup/commands/WhoIs.java @@ -28,15 +28,16 @@ public class WhoIs implements CommandExecutor { * Serveur (si connecté): serveur **/ - LuckPerms LP = Main.LP; + final LuckPerms LP = Main.LP; final TextColor KEY_COLOR = NamedTextColor.AQUA; final TextColor VALUE_COLOR = NamedTextColor.WHITE; // Jsuis obligé - HoverEvent CLICK_TO_COPY = HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("Cliquez pour copier !")); + final HoverEvent CLICK_TO_COPY = HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("Cliquez pour copier !")); + @SuppressWarnings("ConstantConditions") @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { // ========== PRECISION : ON PEUT S'AUTO-WHOIS (because I said so) ========== diff --git a/src/main/java/fr/efreicraft/ecatup/listeners/Join.java b/src/main/java/fr/efreicraft/ecatup/listeners/Join.java index 9ecb73e..cbdfd55 100644 --- a/src/main/java/fr/efreicraft/ecatup/listeners/Join.java +++ b/src/main/java/fr/efreicraft/ecatup/listeners/Join.java @@ -5,9 +5,11 @@ import fr.efreicraft.ecatup.utils.DiscordWebhook; import net.kyori.adventure.text.Component; import net.luckperms.api.LuckPerms; +import net.luckperms.api.model.user.User; import net.luckperms.api.node.Node; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import java.awt.*; @@ -15,22 +17,29 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import static fr.efreicraft.ecatup.utils.Msg.colorize; public class Join implements Listener { - LuckPerms LP = Main.LP; - @EventHandler + static final LuckPerms LP = Main.LP; + static Set isNotDone = new HashSet<>(); + + // Histoire d'exécuter cet event APRES le onJoin de LP + @EventHandler(priority = EventPriority.HIGHEST) public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOException { - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).getCachedData().invalidate(); + isNotDone.add(event.getPlayer().getUniqueId()); + User user = LP.getUserManager().loadUser(event.getPlayer().getUniqueId()).join(); // Get player rank from Association Database ResultSet result = null; try { - String rank = "Visiteur"; + String rank; /* ===== ROLES STUFF ===== */ - PreparedStatement mcLinkStatement = Main.connection.prepareStatement("SELECT * FROM `discordmclink` WHERE `mcaccount` = ?"); + PreparedStatement mcLinkStatement = Main.DB.openThenGetConnection().prepareStatement("SELECT * FROM `discordmclink` WHERE `mcaccount` = ?"); mcLinkStatement.setString(1, event.getPlayer().getName()); Bukkit.getLogger().info("Getting discord ID for " + event.getPlayer().getName()); @@ -38,7 +47,7 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOExcep result = mcLinkStatement.executeQuery(); if (result.next()) { String discordId = result.getString("discordid"); - PreparedStatement memberDataStatement = Main.connection.prepareStatement("SELECT * FROM `members` WHERE `discordid` = ?"); + PreparedStatement memberDataStatement = Main.DB.openThenGetConnection().prepareStatement("SELECT * FROM `members` WHERE `discordid` = ?"); memberDataStatement.setString(1, discordId); Bukkit.getLogger().info("Getting rank for " + discordId); // Execute query @@ -47,32 +56,32 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOExcep rank = memberDataResult.getString("rank"); Bukkit.getLogger().info("Rank for " + event.getPlayer().getName() + " is " + rank); // Remove player permissions - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().clear(); + user.data().clear(); // Set player rank switch (rank) { - case "Membre" -> LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.member").build()); + case "Membre" -> user.data().add(Node.builder("group.member").build()); - case "Beta Tester" -> LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.beta").build()); + case "Beta Tester" -> user.data().add(Node.builder("group.beta").build()); - case "Builder" -> LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.builder").build()); + case "Builder" -> user.data().add(Node.builder("group.builder").build()); - case "Responsable 1P" -> LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.respo1p").build()); + case "Responsable 1P" -> user.data().add(Node.builder("group.respo1p").build()); case "Responsable Event", "Responsable Dev", "Responsable Infra", "Responsable Comm", "Responsable Build", "Responsable Design" -> { - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.be").build()); - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("prefix.10.&c&l[" + rank + "] &c").build()); + user.data().add(Node.builder("group.be").build()); + user.data().add(Node.builder("prefix.10.&c&l[" + rank + "] &c").build()); } case "Président", "Vice-Président", "Trésorier", "Secrétaire" -> { - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.br").build()); - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("prefix.10.&4&l[" + rank + "] &4").build()); + user.data().add(Node.builder("group.br").build()); + user.data().add(Node.builder("prefix.10.&4&l[" + rank + "] &4").build()); } - default -> LP.getUserManager().getUser(event.getPlayer().getUniqueId()).data().add(Node.builder("group.visitor").build()); + default -> user.data().add(Node.builder("group.visitor").build()); } - LP.getUserManager().saveUser(LP.getUserManager().getUser(event.getPlayer().getUniqueId())); + LP.getUserManager().saveUser(LP.getUserManager().loadUser(event.getPlayer().getUniqueId()).join()).join(); networkSync(); - + // Check if player has permission to connect to this server if (!event.getPlayer().hasPermission("server." + Main.config.getString("server_name"))) { event.getPlayer().kick(Component.text("§cVous n'avez pas la permission d'accéder ce serveur !")); @@ -99,14 +108,14 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOExcep result.close(); /* ===== PREFERENCES STUFF ===== */ - PreparedStatement userPrefsStatement = Main.connection.prepareStatement("SELECT * FROM `usersPrefs` WHERE `mcUUID` = ?"); + PreparedStatement userPrefsStatement = Main.DB.openThenGetConnection().prepareStatement("SELECT * FROM `usersPrefs` WHERE `mcUUID` = ?"); userPrefsStatement.setString(1, event.getPlayer().getUniqueId().toString()); Bukkit.getLogger().info("Getting " + event.getPlayer().getName() + "'s user preferences"); ResultSet resultPrefs = userPrefsStatement.executeQuery(); if (resultPrefs.next()) { - int channel = resultPrefs.getInt("channel"); // récup 1 par 1 les préférences de l'utilisateur + int channel = resultPrefs.getInt("channel"); PreferenceCache.cache(event.getPlayer(), channel); } else { @@ -116,9 +125,10 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOExcep resultPrefs.close(); userPrefsStatement.close(); } catch (SQLException e) { + isNotDone.remove(event.getPlayer().getUniqueId()); throw new RuntimeException(e); } - LP.getUserManager().getUser(event.getPlayer().getUniqueId()).getCachedData().invalidate(); + user.getCachedData().invalidate(); String prefix = LP.getUserManager().loadUser(event.getPlayer().getUniqueId()).join().getCachedData().getMetaData().getPrefix().replaceAll("&", "§"); event.getPlayer().displayName(Component.text(prefix + event.getPlayer().getName())); event.joinMessage(event.getPlayer().displayName().append(Component.text(colorize("&7 a rejoint le serveur !")))); @@ -135,9 +145,11 @@ public void onJoin(org.bukkit.event.player.PlayerJoinEvent event) throws IOExcep .setFooter("Efrei Craft", "https://efreicraft.fr/img/favicon.png") ); webhook.execute(); + + isNotDone.remove(event.getPlayer().getUniqueId()); } - public void networkSync() { + public static void networkSync() { LP.runUpdateTask(); } diff --git a/src/main/java/fr/efreicraft/ecatup/listeners/LuckPermsListener.java b/src/main/java/fr/efreicraft/ecatup/listeners/LuckPermsListener.java index 505d756..d11fcde 100644 --- a/src/main/java/fr/efreicraft/ecatup/listeners/LuckPermsListener.java +++ b/src/main/java/fr/efreicraft/ecatup/listeners/LuckPermsListener.java @@ -5,7 +5,6 @@ import net.luckperms.api.LuckPerms; import net.luckperms.api.event.EventBus; import net.luckperms.api.event.user.UserDataRecalculateEvent; -import net.luckperms.api.model.user.User; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Listener; @@ -22,13 +21,12 @@ public LuckPermsListener(Main plugin, LuckPerms LP) { } private void onUserDataRecalculate(UserDataRecalculateEvent event) { + if (Join.isNotDone.contains(event.getUser().getUniqueId())) return; Player player = Bukkit.getPlayer(Objects.requireNonNull(event.getUser().getUsername())); if (player != null) { player.displayName(Component.text(colorize(event.getUser().getCachedData().getMetaData().getPrefix()) + player.getName())); player.playerListName(player.displayName()); - User user = Main.LP.getUserManager().getUser(event.getUser().getUsername()); - if (user != null) - user.getCachedData().invalidate(); + event.getUser().getCachedData().invalidate(); } } } diff --git a/src/main/java/fr/efreicraft/ecatup/utils/DBConnection.java b/src/main/java/fr/efreicraft/ecatup/utils/DBConnection.java new file mode 100644 index 0000000..b5f81b2 --- /dev/null +++ b/src/main/java/fr/efreicraft/ecatup/utils/DBConnection.java @@ -0,0 +1,76 @@ +package fr.efreicraft.ecatup.utils; + +import org.bukkit.Bukkit; +import org.mariadb.jdbc.Configuration; +import org.mariadb.jdbc.Connection; +import org.mariadb.jdbc.Driver; + +import javax.annotation.Nullable; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class DBConnection { + + private Connection connection = null; + private final String HOST; + private final String DATABASE; + private final String USER; + private final String PASSWORD; + private final int PORT; + + public DBConnection(String host, int port, String database, String user, String password) { + this.HOST = host; + this.PORT = port; + this.DATABASE = database; + this.USER = user; + this.PASSWORD = password; + } + + public boolean open() { + try { + connection = (Connection) DriverManager.getConnection("jdbc:mariadb://" + + this.HOST + + ":" + this.PORT + "/" + this.DATABASE + + "?user=" + this.USER + + "&password=" + this.PASSWORD + + "&autoReconnect=true"); + } catch (SQLException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("Couldn't open connection to database!"); + return false; + } + return true; + } + + public void close() { + try { + if (connection != null) + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + Bukkit.getLogger().severe("Couldn't close connection to database!"); + } + } + + @Nullable + public Connection openThenGetConnection() { + if (connection == null || connection.isClosed()) { + if (!this.open()) { + Bukkit.getLogger().severe("Tried to reopen a connection, and failed."); + return null; + } + } + + return connection; + } + + /** + * Cette fonction retourne directement la connexion, sans vérifier si elle existe. Elle est bien plus dangereuse ! + * @return connection La connexion à la connexion à la DB + */ + @Nullable + public Connection getConnection() { + return connection; + } + +} diff --git a/src/main/java/fr/efreicraft/ecatup/utils/DiscordWebhook.java b/src/main/java/fr/efreicraft/ecatup/utils/DiscordWebhook.java index 1080ba0..32f8963 100644 --- a/src/main/java/fr/efreicraft/ecatup/utils/DiscordWebhook.java +++ b/src/main/java/fr/efreicraft/ecatup/utils/DiscordWebhook.java @@ -11,9 +11,10 @@ /** * Class used to execute Discord Webhooks with low effort - * Come from: https://gist.github.com/k3kdude/fba6f6b37594eae3d6f9475330733bdb + * Come from: ... */ +@SuppressWarnings("FieldMayBeFinal") public class DiscordWebhook { private final String url; @@ -150,10 +151,11 @@ public void execute() throws IOException { stream.flush(); stream.close(); - connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream + connection.getInputStream().close(); //I'm not sure why, but it doesn't work without getting the InputStream connection.disconnect(); } + @SuppressWarnings("FieldMayBeFinal") public static class EmbedObject { private String title; private String description; @@ -247,6 +249,7 @@ public EmbedObject addField(String name, String value, boolean inline) { return this; } + @SuppressWarnings("FieldMayBeFinal") private class Footer { private String text; private String iconUrl; @@ -265,6 +268,7 @@ private String getIconUrl() { } } + @SuppressWarnings("FieldMayBeFinal") private class Thumbnail { private String url; @@ -277,6 +281,7 @@ private String getUrl() { } } + @SuppressWarnings("FieldMayBeFinal") private class Image { private String url; @@ -289,6 +294,7 @@ private String getUrl() { } } + @SuppressWarnings("FieldMayBeFinal") private class Author { private String name; private String url; @@ -313,6 +319,7 @@ private String getIconUrl() { } } + @SuppressWarnings("FieldMayBeFinal") private class Field { private String name; private String value; @@ -366,7 +373,7 @@ public String toString() { } else if (val instanceof Boolean) { builder.append(val); } else if (val instanceof JSONObject) { - builder.append(val.toString()); + builder.append(val); } else if (val.getClass().isArray()) { builder.append("["); int len = Array.getLength(val); diff --git a/src/main/java/fr/efreicraft/ecatup/utils/Msg.java b/src/main/java/fr/efreicraft/ecatup/utils/Msg.java index 9e15a6e..a89cd78 100644 --- a/src/main/java/fr/efreicraft/ecatup/utils/Msg.java +++ b/src/main/java/fr/efreicraft/ecatup/utils/Msg.java @@ -8,15 +8,10 @@ public class Msg { public static String colorize(String message) { - return ChatColor.translateAlternateColorCodes('&', Objects.requireNonNullElse(message, "null")); + return ChatColor.translateAlternateColorCodes('&', Objects.requireNonNullElse(message, "")); } public static String colorize(TextComponent message) { - return ChatColor.translateAlternateColorCodes('&', Objects.requireNonNullElse(message.content(), nullText())); - } - - private static String nullText() { - Bukkit.getLogger().warning("Tried to colorize a null text (LuckPerms is at it again...)"); - return "null"; + return ChatColor.translateAlternateColorCodes('&', Objects.requireNonNullElse(message.content(), "")); } }