From 53cdb9247e061a2e1e28e467c37fa935d9cca54c Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Fri, 2 May 2025 14:50:30 -0700 Subject: [PATCH 01/40] SQLite connection added --- pom.xml | 5 ++ .../simplexity/simplenicks/SimpleNicks.java | 4 +- .../simplenicks/config/ConfigHandler.java | 49 +++++++----- .../simplenicks/util/NickHandler.java | 4 - .../simplenicks/util/saving/SqlHandler.java | 79 +++++++++++++++++++ .../simplenicks/util/saving/YMLFile.java | 1 + src/main/resources/config.yml | 10 ++- 7 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java diff --git a/pom.xml b/pom.xml index 034851f..19207f6 100644 --- a/pom.xml +++ b/pom.xml @@ -88,5 +88,10 @@ 2.11.5 provided + + com.zaxxer + HikariCP + 6.3.0 + diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 6ea010a..4ceec9a 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -17,6 +17,7 @@ import simplexity.simplenicks.util.Constants; import simplexity.simplenicks.util.NickHandler; import simplexity.simplenicks.util.SNExpansion; +import simplexity.simplenicks.util.saving.SqlHandler; import java.util.Collections; import java.util.HashMap; @@ -53,6 +54,8 @@ public void onEnable() { } instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); configReload(); + SqlHandler.getInstance().setupConfig(); + SqlHandler.getInstance().init(); } public static MiniMessage getMiniMessage() { @@ -82,6 +85,5 @@ private void registerSubCommands() { public static void configReload() { LocaleHandler.getInstance().loadLocale(); ConfigHandler.getInstance().reloadConfig(); - NickHandler.getInstance().loadSavingType(); } } diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index 5a707d1..2c60a30 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -17,18 +17,14 @@ public String getNickPrefix() { return nickPrefix; } - public enum SAVING_TYPE {PDC, FILE} private static ConfigHandler instance; private final Logger logger = SimpleNicks.getSimpleNicksLogger(); - private Pattern regex = Pattern.compile("[A-Za-z0-9_]+"); - private SAVING_TYPE savingType = SAVING_TYPE.FILE; - private int maxLength = 25; - private int maxSaves = 5; - private boolean tablistNick = false; - private String regexString = "[A-Za-z0-9_]+"; - private String nickPrefix; + private Pattern regex; + private boolean mySql, tablistNick; + private int maxLength, maxSaves; + private String regexString, nickPrefix, mySqlIp, mySqlName, mySqlUsername, mySqlPassword; private long usernameProtectionTime = 0; private ConfigHandler() { @@ -48,18 +44,15 @@ public void reloadConfig() { try { String regexSetting = config.getString("nickname-regex", "[A-Za-z0-9_]+"); regexString = regexSetting; - assert !regexSetting.isBlank(); regex = Pattern.compile(regexSetting); } catch (PatternSyntaxException e) { logger.severe(LocaleHandler.getInstance().getInvalidConfigRegex()); } - // Check validity of saving-type. - try { - String savingTypeSetting = config.getString("saving-type", "file"); - savingType = SAVING_TYPE.valueOf(savingTypeSetting.toUpperCase()); - } catch (IllegalArgumentException e) { - logger.severe("INVALID SAVING TYPE"); - } + mySql = config.getBoolean("mysql.enabled", false); + mySqlIp = config.getString("mysql.ip", "localhost:3306"); + mySqlName = config.getString("mysql.name", "simplenicks"); + mySqlUsername = config.getString("mysql.username", "username1"); + mySqlPassword = config.getString("mysql.password", "badpassword!"); maxLength = config.getInt("max-nickname-length", 25); maxSaves = config.getInt("max-saves", 5); tablistNick = config.getBoolean("tablist-nick", false); @@ -72,10 +65,6 @@ public Pattern getRegex() { return regex; } - public SAVING_TYPE getSavingType() { - return savingType; - } - public int getMaxLength() { return maxLength; } @@ -91,4 +80,24 @@ public boolean shouldNickTablist() { public long getUsernameProtectionTime() { return usernameProtectionTime; } + + public boolean isMySql() { + return mySql; + } + + public String getMySqlIp() { + return mySqlIp; + } + + public String getMySqlName() { + return mySqlName; + } + + public String getMySqlUsername() { + return mySqlUsername; + } + + public String getMySqlPassword() { + return mySqlPassword; + } } diff --git a/src/main/java/simplexity/simplenicks/util/NickHandler.java b/src/main/java/simplexity/simplenicks/util/NickHandler.java index 6367dca..5a209a7 100644 --- a/src/main/java/simplexity/simplenicks/util/NickHandler.java +++ b/src/main/java/simplexity/simplenicks/util/NickHandler.java @@ -62,10 +62,6 @@ public boolean refreshNickname(OfflinePlayer p) { } public void loadSavingType() { - switch (ConfigHandler.getInstance().getSavingType()) { - case PDC -> saveHandler = new PlayerPDC(); - case FILE -> saveHandler = new YMLFile(); - } saveHandler.init(); } diff --git a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java new file mode 100644 index 0000000..5b90876 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java @@ -0,0 +1,79 @@ +package simplexity.simplenicks.util.saving; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.config.ConfigHandler; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.logging.Logger; + +public class SqlHandler { + private static SqlHandler instance; + + public SqlHandler() { + } + + public static SqlHandler getInstance() { + if (instance == null) instance = new SqlHandler(); + return instance; + } + private static final HikariConfig hikariConfig = new HikariConfig(); + private static HikariDataSource dataSource; + private final Logger logger = SimpleNicks.getSimpleNicksLogger(); + + String parentTable = """ + CREATE TABLE IF NOT EXISTS players ( + uuid VARCHAR(36) PRIMARY KEY, + last_login DATETIME NOT NULL + ); + """; + + String childTable = """ + CREATE TABLE IF NOT EXISTS nicknames ( + uuid VARCHAR(36) NOT NULL, + nickname VARCHAR(255) NOT NULL, + in_use BOOLEAN NOT NULL DEFAULT 0, + normalized VARCHAR(255) NOT NULL, + PRIMARY KEY (uuid, nickname), + FOREIGN KEY (uuid) + REFERENCES players(uuid) + ON DELETE CASCADE + ); + """; + + public void init(){ + try { + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + statement.execute(parentTable); + statement.execute(childTable); + } catch (SQLException e) { + logger.severe("Issue connecting to database, info below: "); + e.printStackTrace(); + } + } + + + public void setupConfig() { + if (!ConfigHandler.getInstance().isMySql()) { + hikariConfig.setJdbcUrl("jdbc:sqlite:" + SimpleNicks.getInstance().getDataFolder() + "/simplenicks.db?foreign_keys=on"); + dataSource = new HikariDataSource(hikariConfig); + return; + } + hikariConfig.setJdbcUrl("jdbc:mysql://" + ConfigHandler.getInstance().getMySqlIp() + "/" + ConfigHandler.getInstance().getMySqlName()); + hikariConfig.setUsername(ConfigHandler.getInstance().getMySqlUsername()); + hikariConfig.setPassword(ConfigHandler.getInstance().getMySqlPassword()); + dataSource = new HikariDataSource(hikariConfig); + } + + private static Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + + + +} diff --git a/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java b/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java index ca43c6e..f604592 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java +++ b/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; +@SuppressWarnings({"UnusedReturnValue", "CallToPrintStackTrace", "ResultOfMethodCallIgnored"}) public class YMLFile extends AbstractSaving { private final File dataFile = new File(SimpleNicks.getInstance().getDataFolder(), "nickname_data.yml"); private final FileConfiguration nicknameData = new YamlConfiguration(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b3006e8..f0c5d22 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,9 @@ -# Saving and Loading Method -# PDC: Persistent Data Container (Nicknames are inaccessible when the player is offline). -# FILE: information is saved to a YML File (nickname_data.yml). -saving-type: file +mysql: + enabled: false + ip: "localhost:3306" + name: simplenicks + username: username1 + password: badpassword! # The max amount of characters a nickname should be, not including formatting # (so a name like BillyBob would only count 'BillyBob' - and would be 8 characters) From ab37313a26140fd2a6c479938ab7c1a11b30677d Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Fri, 2 May 2025 15:16:33 -0700 Subject: [PATCH 02/40] fix a couple issues. --- .../simplenicks/util/saving/SqlHandler.java | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java index 5b90876..923284e 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java @@ -6,10 +6,11 @@ import simplexity.simplenicks.config.ConfigHandler; import java.sql.Connection; +import java.sql.PreparedStatement; import java.sql.SQLException; -import java.sql.Statement; import java.util.logging.Logger; +@SuppressWarnings("CallToPrintStackTrace") public class SqlHandler { private static SqlHandler instance; @@ -20,36 +21,33 @@ public static SqlHandler getInstance() { if (instance == null) instance = new SqlHandler(); return instance; } + private static final HikariConfig hikariConfig = new HikariConfig(); private static HikariDataSource dataSource; private final Logger logger = SimpleNicks.getSimpleNicksLogger(); - String parentTable = """ - CREATE TABLE IF NOT EXISTS players ( - uuid VARCHAR(36) PRIMARY KEY, - last_login DATETIME NOT NULL - ); - """; - - String childTable = """ - CREATE TABLE IF NOT EXISTS nicknames ( - uuid VARCHAR(36) NOT NULL, - nickname VARCHAR(255) NOT NULL, - in_use BOOLEAN NOT NULL DEFAULT 0, - normalized VARCHAR(255) NOT NULL, - PRIMARY KEY (uuid, nickname), - FOREIGN KEY (uuid) - REFERENCES players(uuid) - ON DELETE CASCADE - ); - """; - - public void init(){ - try { - Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement(); - statement.execute(parentTable); - statement.execute(childTable); + public void init() { + try (Connection connection = getConnection()) { + PreparedStatement parentStatement = connection.prepareStatement(""" + CREATE TABLE IF NOT EXISTS players ( + uuid VARCHAR(36) PRIMARY KEY, + last_login DATETIME NOT NULL + ); + """); + parentStatement.execute(); + PreparedStatement childStatement = connection.prepareStatement(""" + CREATE TABLE IF NOT EXISTS nicknames ( + uuid VARCHAR(36) NOT NULL, + nickname VARCHAR(255) NOT NULL, + in_use BOOLEAN NOT NULL DEFAULT 0, + normalized VARCHAR(255) NOT NULL, + PRIMARY KEY (uuid, nickname), + FOREIGN KEY (uuid) + REFERENCES players(uuid) + ON DELETE CASCADE + ); + """); + childStatement.execute(); } catch (SQLException e) { logger.severe("Issue connecting to database, info below: "); e.printStackTrace(); @@ -74,6 +72,4 @@ private static Connection getConnection() throws SQLException { } - - } From 75e801abf2ae81e131427d6e49c8566df1e2c0e5 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sun, 4 May 2025 15:06:30 -0700 Subject: [PATCH 03/40] . --- .../simplenicks/util/saving/Nickname.java | 4 + .../simplenicks/util/saving/SqlHandler.java | 84 ++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/main/java/simplexity/simplenicks/util/saving/Nickname.java diff --git a/src/main/java/simplexity/simplenicks/util/saving/Nickname.java b/src/main/java/simplexity/simplenicks/util/saving/Nickname.java new file mode 100644 index 0000000..6636dce --- /dev/null +++ b/src/main/java/simplexity/simplenicks/util/saving/Nickname.java @@ -0,0 +1,4 @@ +package simplexity.simplenicks.util.saving; + +public record Nickname(String nickname, String normalizedNickname) { +} diff --git a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java index 923284e..a5ca17a 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java @@ -5,9 +5,14 @@ import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; +import javax.annotation.Nullable; import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import java.util.logging.Logger; @SuppressWarnings("CallToPrintStackTrace") @@ -39,7 +44,7 @@ uuid VARCHAR(36) PRIMARY KEY, CREATE TABLE IF NOT EXISTS nicknames ( uuid VARCHAR(36) NOT NULL, nickname VARCHAR(255) NOT NULL, - in_use BOOLEAN NOT NULL DEFAULT 0, + in_use BOOLEAN NOT NULL DEFAULT false, normalized VARCHAR(255) NOT NULL, PRIMARY KEY (uuid, nickname), FOREIGN KEY (uuid) @@ -54,6 +59,83 @@ REFERENCES players(uuid) } } + public boolean playerSaveExists(UUID uuid) { + String queryString = "SELECT 1 FROM players WHERE uuid = ? LIMIT 1"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.severe("Failed to check if player exists: " + uuid); + e.printStackTrace(); + return false; + } + } + + public boolean nickAlreadyExists(String normalizedName) { + String queryString = "SELECT 1 FROM nicknames WHERE nickname = ? AND in_use = true LIMIT 1"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(normalizedName)); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.severe("Failed to check if nickname exists: " + normalizedName); + e.printStackTrace(); + return false; + } + } + + @Nullable + public List getSavedNicknamesForPlayer(UUID uuid) { + List savedNicknames = new ArrayList<>(); + String queryString = "SELECT nickname AND normalized FROM nicknames WHERE uuid = ? AND in_use = false"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = statement.executeQuery(); + if (!resultSet.next()) return null; + while (resultSet.next()) { + String nicknameString = resultSet.getString("nickname"); + String normalizedString = resultSet.getString("normalized"); + Nickname nick = new Nickname(nicknameString, normalizedString); + savedNicknames.add(nick); + } + } catch (SQLException e) { + logger.severe("Failed to get saved nicknames for player: " + uuid); + e.printStackTrace(); + } + return savedNicknames; + } + + public void saveNickname(UUID uuid, String nickname, String normalizedNickname, boolean inUse) { + String saveString = "REPLACE INTO nicknames (uuid, nickname, in_use, normalized) VALUES (?, ?, ?, ?)"; + if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); + try (Connection connection = getConnection()) { + PreparedStatement saveStatement = connection.prepareStatement(saveString); + saveStatement.setString(1, String.valueOf(uuid)); + saveStatement.setString(2, nickname); + saveStatement.setBoolean(3, inUse); + saveStatement.setString(4, normalizedNickname); + saveStatement.executeUpdate(); + } catch (SQLException e) { + logger.severe("Failed to save nickname: " + nickname + " for UUID: " + uuid); + e.printStackTrace(); + } + } + + private void addPlayerToPlayers(UUID uuid) { + String insertQuery = "REPLACE INTO players (uuid, last_login) VALUES (?, CURRENT_TIMESTAMP)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(insertQuery); + statement.setString(1, String.valueOf(uuid)); + statement.executeUpdate(); + } catch (SQLException e) { + logger.severe("Failed to save player: " + uuid); + e.printStackTrace(); + } + } public void setupConfig() { if (!ConfigHandler.getInstance().isMySql()) { From b31012eacf670c72da059550e479322e7a386568 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Mon, 5 May 2025 20:41:13 -0700 Subject: [PATCH 04/40] add another table for active nicks --- .../simplenicks/util/saving/SqlHandler.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java index a5ca17a..3a484eb 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java @@ -40,11 +40,10 @@ uuid VARCHAR(36) PRIMARY KEY, ); """); parentStatement.execute(); - PreparedStatement childStatement = connection.prepareStatement(""" - CREATE TABLE IF NOT EXISTS nicknames ( + PreparedStatement savedNickStatement = connection.prepareStatement(""" + CREATE TABLE IF NOT EXISTS saved_nicknames ( uuid VARCHAR(36) NOT NULL, nickname VARCHAR(255) NOT NULL, - in_use BOOLEAN NOT NULL DEFAULT false, normalized VARCHAR(255) NOT NULL, PRIMARY KEY (uuid, nickname), FOREIGN KEY (uuid) @@ -52,7 +51,19 @@ REFERENCES players(uuid) ON DELETE CASCADE ); """); - childStatement.execute(); + savedNickStatement.execute(); + PreparedStatement currentNickStatement = connection.prepareStatement(""" + CREATE TABLE IF NOT EXISTS current_nicknames ( + uuid VARCHAR(36) NOT NULL, + nickname VARCHAR(255) NOT NULL, + normalized VARCHAR(255) NOT NULL, + PRIMARY KEY (uuid, nickname), + FOREIGN KEY (uuid) + REFERENCES players(uuid) + ON DELETE CASCADE + ); + """); + currentNickStatement.execute(); } catch (SQLException e) { logger.severe("Issue connecting to database, info below: "); e.printStackTrace(); @@ -74,7 +85,7 @@ public boolean playerSaveExists(UUID uuid) { } public boolean nickAlreadyExists(String normalizedName) { - String queryString = "SELECT 1 FROM nicknames WHERE nickname = ? AND in_use = true LIMIT 1"; + String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? LIMIT 1"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(normalizedName)); @@ -90,7 +101,7 @@ public boolean nickAlreadyExists(String normalizedName) { @Nullable public List getSavedNicknamesForPlayer(UUID uuid) { List savedNicknames = new ArrayList<>(); - String queryString = "SELECT nickname AND normalized FROM nicknames WHERE uuid = ? AND in_use = false"; + String queryString = "SELECT nickname AND normalized FROM saved_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(uuid)); @@ -109,15 +120,14 @@ public List getSavedNicknamesForPlayer(UUID uuid) { return savedNicknames; } - public void saveNickname(UUID uuid, String nickname, String normalizedNickname, boolean inUse) { - String saveString = "REPLACE INTO nicknames (uuid, nickname, in_use, normalized) VALUES (?, ?, ?, ?)"; + public void saveNickname(UUID uuid, String nickname, String normalizedNickname) { + String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); try (Connection connection = getConnection()) { PreparedStatement saveStatement = connection.prepareStatement(saveString); saveStatement.setString(1, String.valueOf(uuid)); saveStatement.setString(2, nickname); - saveStatement.setBoolean(3, inUse); - saveStatement.setString(4, normalizedNickname); + saveStatement.setString(3, normalizedNickname); saveStatement.executeUpdate(); } catch (SQLException e) { logger.severe("Failed to save nickname: " + nickname + " for UUID: " + uuid); From 25a3b99bc4fe881cf3669f4b29f7b4206c7c34a9 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 6 May 2025 15:02:06 -0700 Subject: [PATCH 05/40] compiles but doesn't work --- .../simplexity/simplenicks/SimpleNicks.java | 5 +- .../simplenicks/commands/Delete.java | 19 ++-- .../simplenicks/commands/Reset.java | 8 +- .../simplenicks/commands/SNReload.java | 4 +- .../simplexity/simplenicks/commands/Save.java | 14 ++- .../simplexity/simplenicks/commands/Set.java | 64 ++++++------- .../{util => hooks}/SNExpansion.java | 10 +- .../simplenicks/listener/LoginListener.java | 4 +- .../{util => }/saving/AbstractSaving.java | 2 +- .../simplexity/simplenicks/saving/Cache.java | 76 +++++++++++++++ .../simplenicks/saving/NickHandler.java | 68 ++++++++++++++ .../{util => }/saving/Nickname.java | 2 +- .../{util => }/saving/PlayerPDC.java | 2 +- .../{util => }/saving/SqlHandler.java | 93 +++++++++++++++++-- .../{util => }/saving/YMLFile.java | 2 +- .../simplenicks/util/NickHandler.java | 79 ---------------- 16 files changed, 300 insertions(+), 152 deletions(-) rename src/main/java/simplexity/simplenicks/{util => hooks}/SNExpansion.java (71%) rename src/main/java/simplexity/simplenicks/{util => }/saving/AbstractSaving.java (93%) create mode 100644 src/main/java/simplexity/simplenicks/saving/Cache.java create mode 100644 src/main/java/simplexity/simplenicks/saving/NickHandler.java rename src/main/java/simplexity/simplenicks/{util => }/saving/Nickname.java (62%) rename src/main/java/simplexity/simplenicks/{util => }/saving/PlayerPDC.java (97%) rename src/main/java/simplexity/simplenicks/{util => }/saving/SqlHandler.java (61%) rename src/main/java/simplexity/simplenicks/{util => }/saving/YMLFile.java (98%) delete mode 100644 src/main/java/simplexity/simplenicks/util/NickHandler.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 4ceec9a..f091b46 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -15,9 +15,8 @@ import simplexity.simplenicks.config.LocaleHandler; import simplexity.simplenicks.listener.LoginListener; import simplexity.simplenicks.util.Constants; -import simplexity.simplenicks.util.NickHandler; -import simplexity.simplenicks.util.SNExpansion; -import simplexity.simplenicks.util.saving.SqlHandler; +import simplexity.simplenicks.hooks.SNExpansion; +import simplexity.simplenicks.saving.SqlHandler; import java.util.Collections; import java.util.HashMap; diff --git a/src/main/java/simplexity/simplenicks/commands/Delete.java b/src/main/java/simplexity/simplenicks/commands/Delete.java index 6e69be3..ef2ea41 100644 --- a/src/main/java/simplexity/simplenicks/commands/Delete.java +++ b/src/main/java/simplexity/simplenicks/commands/Delete.java @@ -4,10 +4,13 @@ import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.NickHandler; +import simplexity.simplenicks.saving.Nickname; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class Delete extends SubCommand{ public Delete(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { @@ -38,13 +41,12 @@ public void executeOnSelf(CommandSender sender, Player player, String[] args) { } private boolean removeSavedNick(CommandSender sender, Player player, String nickname) { - List savedNicks = NickHandler.getInstance().getSavedNicknames(player); - if (!savedNicks.contains(nickname)) { + UUID playerUuid = player.getUniqueId(); + if (!Cache.getInstance().deleteSavedNickname(nickname, playerUuid)) { sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getNameNonexistent(), nickname)); return false; } - NickHandler.getInstance().deleteNickname(player, nickname); - NickHandler.getInstance().refreshNickname(player); + NickHandler.getInstance().refreshNickname(playerUuid); return true; } @@ -53,7 +55,10 @@ public ArrayList tabComplete(CommandSender sender, String[] args, Player if (player == null) { return null; } - List savedNickNames = NickHandler.getInstance().getSavedNicknames(player); - return (ArrayList) savedNickNames; + ArrayList savedNickNames = new ArrayList<>(); + for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { + savedNickNames.add(nick.nickname()); + } + return savedNickNames; } } diff --git a/src/main/java/simplexity/simplenicks/commands/Reset.java b/src/main/java/simplexity/simplenicks/commands/Reset.java index 8015aac..89c9254 100644 --- a/src/main/java/simplexity/simplenicks/commands/Reset.java +++ b/src/main/java/simplexity/simplenicks/commands/Reset.java @@ -5,7 +5,8 @@ import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.NickHandler; import java.util.ArrayList; @@ -29,9 +30,8 @@ public void executeOnSelf(CommandSender sender, Player player, String[] args) { } public void resetName(Player player) { - String username = player.getName(); - player.displayName(Component.text(username)); - NickHandler.getInstance().resetNickname(player); + player.displayName(null); + Cache.getInstance().clearCurrentNickname(player.getUniqueId()); } @Override diff --git a/src/main/java/simplexity/simplenicks/commands/SNReload.java b/src/main/java/simplexity/simplenicks/commands/SNReload.java index 3dbb25b..6c2bc6b 100644 --- a/src/main/java/simplexity/simplenicks/commands/SNReload.java +++ b/src/main/java/simplexity/simplenicks/commands/SNReload.java @@ -10,7 +10,7 @@ import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.NickHandler; public class SNReload implements CommandExecutor { @Override @@ -20,7 +20,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command sender.sendMessage(SimpleNicks.getMiniMessage().deserialize(LocaleHandler.getInstance().getConfigReloaded(), Placeholder.parsed("prefix", LocaleHandler.getInstance().getPluginPrefix()))); for (Player player : Bukkit.getServer().getOnlinePlayers()) { - NickHandler.getInstance().refreshNickname(player); + NickHandler.getInstance().refreshNickname(player.getUniqueId()); } return false; } diff --git a/src/main/java/simplexity/simplenicks/commands/Save.java b/src/main/java/simplexity/simplenicks/commands/Save.java index 08b3f7a..6612e7f 100644 --- a/src/main/java/simplexity/simplenicks/commands/Save.java +++ b/src/main/java/simplexity/simplenicks/commands/Save.java @@ -5,10 +5,13 @@ import org.bukkit.permissions.Permission; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.NickHandler; +import simplexity.simplenicks.saving.Nickname; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class Save extends SubCommand{ public Save(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { @@ -35,15 +38,16 @@ public void executeOnSelf(CommandSender sender, Player player, String[] args) { } public boolean savePlayerNick(Player player) { - String nameToSave = miniMessage.serialize(player.displayName()); - List nameList = NickHandler.getInstance().getSavedNicknames(player); - if (nameList.contains(nameToSave)) { + UUID playerUuid = player.getUniqueId(); + Nickname nick = Cache.getInstance().getActiveNickname(playerUuid); + if (nick == null) { return false; } + List nameList = Cache.getInstance().getSavedNicknames(playerUuid); if (nameList.size() >= ConfigHandler.getInstance().getMaxSaves()) { return false; } - NickHandler.getInstance().saveNickname(player, nameToSave); + Cache.getInstance().saveNickname(nick.nickname(), playerUuid); return true; } diff --git a/src/main/java/simplexity/simplenicks/commands/Set.java b/src/main/java/simplexity/simplenicks/commands/Set.java index 5c685d0..9412fb9 100644 --- a/src/main/java/simplexity/simplenicks/commands/Set.java +++ b/src/main/java/simplexity/simplenicks/commands/Set.java @@ -3,7 +3,6 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -11,12 +10,15 @@ import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.LocaleHandler; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.NickHandler; import simplexity.simplenicks.util.TagPermission; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -33,18 +35,11 @@ public void executeOnOther(CommandSender sender, Player player, String[] args) { return; } String nickname = args[2]; - Component nickComponent = Component.empty(); - if (sender.hasPermission(Constants.NICK_OTHERS_FULL)) { - nickComponent = miniMessage.deserialize(nickname); - } else if (sender.hasPermission(Constants.NICK_OTHERS_BASIC)) { - nickComponent = getNickComponent(sender, nickname); - } else if (sender.hasPermission(Constants.NICK_OTHERS_RESTRICTIVE)) { - nickComponent = getNickComponent(player, nickname); - } + nickname = processName(nickname, sender, player); if (!passesChecks(sender, nickname, player)) { return; } - if (setPlayerNick(player, nickComponent)) { + if (setPlayerNick(player, nickname)) { sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedOther(), nickname)); player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedByOther(), nickname)); } else { @@ -59,48 +54,45 @@ public void executeOnSelf(CommandSender sender, Player player, String[] args) { if (!passesChecks(sender, nickname, player)) { return; } - Component nickComponent = getNickComponent(sender, nickname); - if (setPlayerNick(player, nickComponent)) { + nickname = processName(nickname, sender, player); + if (setPlayerNick(player, nickname)) { player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedSelf(), nickname)); } else { player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getInvalidTags(), nickname)); } } - private boolean setPlayerNick(Player player, Component nickComponent) { - if (nickComponent == null) { + private boolean setPlayerNick(Player player, String nickString) { + if (nickString == null) { return false; } - String nickToSave = miniMessage.serialize(nickComponent); - NickHandler.getInstance().setNickname(player, nickToSave); - return true; + UUID playerUuid = player.getUniqueId(); + //todo Checks for existing versions of this nick + //Cache.getInstance().nickInUseActiveStorage(nickString, playerUuid); + return Cache.getInstance().setActiveNickname(playerUuid, nickString); } + private String processName(String nickArg, CommandSender sender, Player player) { + if (sender.hasPermission(Constants.NICK_OTHERS_FULL)) return nickArg; + if (sender.hasPermission(Constants.NICK_OTHERS_BASIC)) { + return NickHandler.getInstance().cleanNonPermittedTags(sender, nickArg); + } + if (sender.hasPermission(Constants.NICK_OTHERS_RESTRICTIVE)) { + return NickHandler.getInstance().cleanNonPermittedTags(player, nickArg); + } + return null; + } @Override public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { if (player == null) { return null; } - List savedNickNames = NickHandler.getInstance().getSavedNicknames(player); - return (ArrayList) savedNickNames; - } - - private Component getNickComponent(CommandSender user, String nick) { - int permissionCount = 0; - String strippedMessage = miniMessage.stripTags(nick); - TagResolver.Builder resolver = TagResolver.builder(); - for (TagPermission tagPermission : TagPermission.values()) { - if (user.hasPermission(tagPermission.getPermission())) { - permissionCount++; - resolver.resolver(tagPermission.getTagResolver()); - } - } - if (permissionCount == 0) { - return Component.text(strippedMessage); + ArrayList savedNickNames = new ArrayList<>(); + for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { + savedNickNames.add(nick.nickname()); } - MiniMessage parser = MiniMessage.builder().tags(resolver.build()).build(); - return parser.deserialize(nick); + return savedNickNames; } diff --git a/src/main/java/simplexity/simplenicks/util/SNExpansion.java b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java similarity index 71% rename from src/main/java/simplexity/simplenicks/util/SNExpansion.java rename to src/main/java/simplexity/simplenicks/hooks/SNExpansion.java index 9af5ffc..30c9ca5 100644 --- a/src/main/java/simplexity/simplenicks/util/SNExpansion.java +++ b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java @@ -1,9 +1,11 @@ -package simplexity.simplenicks.util; +package simplexity.simplenicks.hooks; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.NickHandler; +import simplexity.simplenicks.saving.Nickname; public class SNExpansion extends PlaceholderExpansion { @Override @@ -29,9 +31,9 @@ public boolean persist() { @Override public String onRequest(OfflinePlayer player, @NotNull String params) { if (params.equalsIgnoreCase("mininick")) { - String nickname = NickHandler.getInstance().getNickname(player); + Nickname nickname = Cache.getInstance().getActiveNickname(player.getUniqueId()); if (nickname != null) { - return nickname; + return nickname.nickname(); } return player.getName(); } diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index b43f4f3..cb287e7 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -4,11 +4,11 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import simplexity.simplenicks.util.NickHandler; +import simplexity.simplenicks.saving.NickHandler; public class LoginListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerLogin(PlayerJoinEvent joinEvent) { - NickHandler.getInstance().refreshNickname(joinEvent.getPlayer()); + NickHandler.getInstance().refreshNickname(joinEvent.getPlayer().getUniqueId()); } } diff --git a/src/main/java/simplexity/simplenicks/util/saving/AbstractSaving.java b/src/main/java/simplexity/simplenicks/saving/AbstractSaving.java similarity index 93% rename from src/main/java/simplexity/simplenicks/util/saving/AbstractSaving.java rename to src/main/java/simplexity/simplenicks/saving/AbstractSaving.java index 04402ca..481ea6e 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/AbstractSaving.java +++ b/src/main/java/simplexity/simplenicks/saving/AbstractSaving.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.util.saving; +package simplexity.simplenicks.saving; import org.bukkit.OfflinePlayer; diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java new file mode 100644 index 0000000..5410698 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -0,0 +1,76 @@ +package simplexity.simplenicks.saving; + +import net.kyori.adventure.text.minimessage.MiniMessage; +import simplexity.simplenicks.SimpleNicks; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +public class Cache { + private static Cache instance; + + public Cache() { + } + + public static Cache getInstance() { + if (instance == null) instance = new Cache(); + return instance; + } + + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + private final HashMap activeNicknames = new HashMap<>(); + + @Nullable + public Nickname getActiveNickname(UUID uuid){ + if (activeNicknames.containsKey(uuid)) return activeNicknames.get(uuid); + Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid); + if (currentNick == null) return null; + activeNicknames.put(uuid, currentNick); + return currentNick; + } + + public boolean setActiveNickname(UUID uuid, String nickname){ + String normalizedNick = miniMessage.stripTags(nickname); + Nickname nick = new Nickname(nickname, normalizedNick); + activeNicknames.put(uuid, nick); + return SqlHandler.getInstance().setActiveNickname(uuid, nickname, normalizedNick); + } + + public boolean deleteSavedNickname(String nickname, UUID uuid) { + return SqlHandler.getInstance().deleteNickname(uuid, nickname); + } + + public boolean clearCurrentNickname(UUID uuid) { + activeNicknames.remove(uuid); + return SqlHandler.getInstance().clearActiveNickname(uuid); + } + + public boolean userAlreadySavedThis(String name, UUID uuid) { + return SqlHandler.getInstance().userAlreadySavedThisName(uuid, name); + } + + public boolean nickInUseActiveStorage(String name, UUID uuid) { + String strippedNick = miniMessage.stripTags(name); + return SqlHandler.getInstance().nickAlreadyExists(strippedNick, uuid); + } + + public boolean nickInUseOnlinePlayers(String name, UUID uuid) { + String strippedNick = miniMessage.stripTags(name); + for (UUID playerUuid : activeNicknames.keySet()) { + if (playerUuid.equals(uuid)) continue; + if (activeNicknames.get(playerUuid).normalizedNickname().equals(strippedNick)) return true; + } + return false; + } + + public boolean saveNickname(String name, UUID uuid) { + String strippedNick = miniMessage.stripTags(name); + return SqlHandler.getInstance().saveNickname(uuid, name, strippedNick); + } + + public List getSavedNicknames(UUID uuid) { + return SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); + } +} diff --git a/src/main/java/simplexity/simplenicks/saving/NickHandler.java b/src/main/java/simplexity/simplenicks/saving/NickHandler.java new file mode 100644 index 0000000..d268a10 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/saving/NickHandler.java @@ -0,0 +1,68 @@ +package simplexity.simplenicks.saving; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.util.TagPermission; + +import java.util.UUID; + +@SuppressWarnings("UnusedReturnValue") +public class NickHandler { + + private static NickHandler instance; + + private AbstractSaving saveHandler; + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + private NickHandler() { + } + + public static NickHandler getInstance() { + if (instance != null) return instance; + instance = new NickHandler(); + return instance; + } + + + public boolean refreshNickname(UUID uuid) { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return false; + Nickname nickname = Cache.getInstance().getActiveNickname(uuid); + if (nickname == null) { + player.displayName(null); + return true; + } + player.displayName(miniMessage.deserialize(ConfigHandler.getInstance().getNickPrefix() + nickname.nickname())); + if (ConfigHandler.getInstance().shouldNickTablist()) { + player.playerListName(miniMessage.deserialize(nickname.nickname())); + } + return true; + } + + public String cleanNonPermittedTags(CommandSender user, String nick) { + int permissionCount = 0; + String strippedMessage = miniMessage.stripTags(nick); + TagResolver.Builder resolver = TagResolver.builder(); + for (TagPermission tagPermission : TagPermission.values()) { + if (user.hasPermission(tagPermission.getPermission())) { + permissionCount++; + resolver.resolver(tagPermission.getTagResolver()); + } + } + if (permissionCount == 0) { + return miniMessage.stripTags(nick); + } + MiniMessage parser = MiniMessage.builder() + .strict(false) + .tags(resolver.build()) + .build(); + Component permissionParsed = parser.deserialize(nick); + return miniMessage.serialize(permissionParsed); + } +} diff --git a/src/main/java/simplexity/simplenicks/util/saving/Nickname.java b/src/main/java/simplexity/simplenicks/saving/Nickname.java similarity index 62% rename from src/main/java/simplexity/simplenicks/util/saving/Nickname.java rename to src/main/java/simplexity/simplenicks/saving/Nickname.java index 6636dce..38906d2 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/Nickname.java +++ b/src/main/java/simplexity/simplenicks/saving/Nickname.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.util.saving; +package simplexity.simplenicks.saving; public record Nickname(String nickname, String normalizedNickname) { } diff --git a/src/main/java/simplexity/simplenicks/util/saving/PlayerPDC.java b/src/main/java/simplexity/simplenicks/saving/PlayerPDC.java similarity index 97% rename from src/main/java/simplexity/simplenicks/util/saving/PlayerPDC.java rename to src/main/java/simplexity/simplenicks/saving/PlayerPDC.java index 4a5b339..5c392fc 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/PlayerPDC.java +++ b/src/main/java/simplexity/simplenicks/saving/PlayerPDC.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.util.saving; +package simplexity.simplenicks.saving; import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; diff --git a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java similarity index 61% rename from src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java rename to src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 3a484eb..f073d9d 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.util.saving; +package simplexity.simplenicks.saving; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -57,7 +57,7 @@ CREATE TABLE IF NOT EXISTS current_nicknames ( uuid VARCHAR(36) NOT NULL, nickname VARCHAR(255) NOT NULL, normalized VARCHAR(255) NOT NULL, - PRIMARY KEY (uuid, nickname), + PRIMARY KEY (uuid), FOREIGN KEY (uuid) REFERENCES players(uuid) ON DELETE CASCADE @@ -84,11 +84,12 @@ public boolean playerSaveExists(UUID uuid) { } } - public boolean nickAlreadyExists(String normalizedName) { - String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? LIMIT 1"; + public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { + String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? AND uuid != ? LIMIT 1"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(normalizedName)); + statement.setString(2, String.valueOf(uuidToExclude)); ResultSet resultSet = statement.executeQuery(); return resultSet.next(); } catch (SQLException e) { @@ -120,7 +121,40 @@ public List getSavedNicknamesForPlayer(UUID uuid) { return savedNicknames; } - public void saveNickname(UUID uuid, String nickname, String normalizedNickname) { + public boolean userAlreadySavedThisName(UUID uuid, String nickname) { + String queryString = "SELECT nickname FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nickname); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.warning("Failed to check if UUID '" + uuid + "' has already saved the nickname '" + nickname +"'"); + e.printStackTrace(); + return false; + } + } + + @Nullable + public Nickname getCurrentNicknameForPlayer(UUID uuid) { + String queryString = "SELECT nickname AND normalized FROM current_nicknames WHERE uuid = ?"; + try (Connection connection = getConnection()) { + PreparedStatement getStatement = connection.prepareStatement(queryString); + getStatement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = getStatement.executeQuery(); + if (!resultSet.next()) return null; + String nickString = resultSet.getString("nickname"); + String normalizedString = resultSet.getString("normalized"); + return new Nickname(nickString, normalizedString); + } catch (SQLException e) { + logger.warning("Failed to get active nickname for UUID: " + uuid); + e.printStackTrace(); + } + return null; + } + + public boolean saveNickname(UUID uuid, String nickname, String normalizedNickname) { String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); try (Connection connection = getConnection()) { @@ -128,10 +162,57 @@ public void saveNickname(UUID uuid, String nickname, String normalizedNickname) saveStatement.setString(1, String.valueOf(uuid)); saveStatement.setString(2, nickname); saveStatement.setString(3, normalizedNickname); - saveStatement.executeUpdate(); + int rowsModified = saveStatement.executeUpdate(); + return rowsModified > 0; } catch (SQLException e) { logger.severe("Failed to save nickname: " + nickname + " for UUID: " + uuid); e.printStackTrace(); + return false; + } + } + + public boolean deleteNickname(UUID uuid, String nickname) { + String deleteQuery = "DELETE FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(deleteQuery); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nickname); + int rowsAffected = statement.executeUpdate(); + return rowsAffected > 0; + } catch (SQLException e) { + logger.warning("Failed to delete nickname '" + nickname + "' for UUID '" + uuid + "'"); + e.printStackTrace(); + return false; + } + } + + public boolean clearActiveNickname(UUID uuid) { + String deleteQuery = "DELETE FROM current_nicknames WHERE uuid = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(deleteQuery); + statement.setString(1, String.valueOf(uuid)); + int rowsAffected = statement.executeUpdate(); + return rowsAffected > 0; + } catch (SQLException e) { + logger.warning("Failed to clear active nickname for UUID: " + uuid); + e.printStackTrace(); + return false; + } + } + + public boolean setActiveNickname(UUID uuid, String nicknameString, String normalizedString) { + String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(setQuery); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nicknameString); + statement.setString(3, normalizedString); + int rowsModified = statement.executeUpdate(); + return rowsModified > 0; + } catch (SQLException e) { + logger.warning("Failed to set active nickname '" + nicknameString + "' for UUID '" + uuid + "'"); + e.printStackTrace(); + return false; } } diff --git a/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java b/src/main/java/simplexity/simplenicks/saving/YMLFile.java similarity index 98% rename from src/main/java/simplexity/simplenicks/util/saving/YMLFile.java rename to src/main/java/simplexity/simplenicks/saving/YMLFile.java index f604592..326c647 100644 --- a/src/main/java/simplexity/simplenicks/util/saving/YMLFile.java +++ b/src/main/java/simplexity/simplenicks/saving/YMLFile.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.util.saving; +package simplexity.simplenicks.saving; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/main/java/simplexity/simplenicks/util/NickHandler.java b/src/main/java/simplexity/simplenicks/util/NickHandler.java deleted file mode 100644 index 5a209a7..0000000 --- a/src/main/java/simplexity/simplenicks/util/NickHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -package simplexity.simplenicks.util; - -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.util.saving.AbstractSaving; -import simplexity.simplenicks.util.saving.PlayerPDC; -import simplexity.simplenicks.util.saving.YMLFile; - -import java.util.List; - -@SuppressWarnings("UnusedReturnValue") -public class NickHandler { - - private static NickHandler instance; - - private AbstractSaving saveHandler; - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - - private NickHandler() { - } - - public static NickHandler getInstance() { - if (instance != null) return instance; - instance = new NickHandler(); - instance.loadSavingType(); - return instance; - } - - public String getNickname(OfflinePlayer player) { - return saveHandler.getNickname(player); - } - - public boolean setNickname(OfflinePlayer player, String nickname) { - if (!saveHandler.setNickname(player, nickname)) return false; - refreshNickname(player); - return true; - } - - public boolean resetNickname(OfflinePlayer player) { - if (!saveHandler.resetNickname(player)) return false; - refreshNickname(player); - return true; - } - - public boolean refreshNickname(OfflinePlayer p) { - Player player = p.getPlayer(); - if (player == null) return false; - String nicknameRaw = getNickname(p); - if (nicknameRaw == null || nicknameRaw.isBlank()) { - player.displayName(null); - } else { - player.displayName(miniMessage.deserialize(ConfigHandler.getInstance().getNickPrefix() + nicknameRaw)); - if (ConfigHandler.getInstance().shouldNickTablist()) { - player.playerListName(miniMessage.deserialize(nicknameRaw)); - } - } - - return true; - } - - public void loadSavingType() { - saveHandler.init(); - } - - public boolean saveNickname(OfflinePlayer player, String nickname) { - return saveHandler.saveNickname(player, nickname); - } - - public boolean deleteNickname(OfflinePlayer player, String nickname) { - return saveHandler.deleteNickname(player, nickname); - } - - public List getSavedNicknames(OfflinePlayer player) { - return saveHandler.getSavedNicknames(player); - } -} From 1c7ed1f8a3fcb4cc0e3f65f44520ab6572503feb Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 6 May 2025 15:14:12 -0700 Subject: [PATCH 06/40] now using /nick works, save doesn't --- src/main/java/simplexity/simplenicks/commands/Save.java | 1 + src/main/java/simplexity/simplenicks/saving/SqlHandler.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/simplexity/simplenicks/commands/Save.java b/src/main/java/simplexity/simplenicks/commands/Save.java index 6612e7f..39620b2 100644 --- a/src/main/java/simplexity/simplenicks/commands/Save.java +++ b/src/main/java/simplexity/simplenicks/commands/Save.java @@ -44,6 +44,7 @@ public boolean savePlayerNick(Player player) { return false; } List nameList = Cache.getInstance().getSavedNicknames(playerUuid); + if (nameList == null) return false; if (nameList.size() >= ConfigHandler.getInstance().getMaxSaves()) { return false; } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index f073d9d..2b8b137 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -202,6 +202,7 @@ public boolean clearActiveNickname(UUID uuid) { public boolean setActiveNickname(UUID uuid, String nicknameString, String normalizedString) { String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; + if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(setQuery); statement.setString(1, String.valueOf(uuid)); From 667cbb9bd7ba8454edb4f615dea3fe081abdac11 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 6 May 2025 20:11:55 -0700 Subject: [PATCH 07/40] genuinely not sure what's wrong here --- .../simplexity/simplenicks/commands/Save.java | 2 +- .../simplenicks/hooks/SNExpansion.java | 5 ++- .../simplenicks/saving/SqlHandler.java | 34 +++++++++++-------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/Save.java b/src/main/java/simplexity/simplenicks/commands/Save.java index 39620b2..505123c 100644 --- a/src/main/java/simplexity/simplenicks/commands/Save.java +++ b/src/main/java/simplexity/simplenicks/commands/Save.java @@ -44,7 +44,7 @@ public boolean savePlayerNick(Player player) { return false; } List nameList = Cache.getInstance().getSavedNicknames(playerUuid); - if (nameList == null) return false; + if (nameList == null) nameList = new ArrayList<>(); if (nameList.size() >= ConfigHandler.getInstance().getMaxSaves()) { return false; } diff --git a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java index 30c9ca5..d505450 100644 --- a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java +++ b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java @@ -3,6 +3,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.NickHandler; import simplexity.simplenicks.saving.Nickname; @@ -33,7 +34,9 @@ public String onRequest(OfflinePlayer player, @NotNull String params) { if (params.equalsIgnoreCase("mininick")) { Nickname nickname = Cache.getInstance().getActiveNickname(player.getUniqueId()); if (nickname != null) { - return nickname.nickname(); + String prefix = ConfigHandler.getInstance().getNickPrefix(); + if (prefix == null || prefix.isEmpty()) return nickname.nickname(); + return prefix + nickname.nickname(); } return player.getName(); } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 2b8b137..bae5728 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -15,7 +15,7 @@ import java.util.UUID; import java.util.logging.Logger; -@SuppressWarnings("CallToPrintStackTrace") +@SuppressWarnings({"CallToPrintStackTrace", "BooleanMethodIsAlwaysInverted"}) public class SqlHandler { private static SqlHandler instance; @@ -70,19 +70,6 @@ REFERENCES players(uuid) } } - public boolean playerSaveExists(UUID uuid) { - String queryString = "SELECT 1 FROM players WHERE uuid = ? LIMIT 1"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, String.valueOf(uuid)); - ResultSet resultSet = statement.executeQuery(); - return resultSet.next(); - } catch (SQLException e) { - logger.severe("Failed to check if player exists: " + uuid); - e.printStackTrace(); - return false; - } - } public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? AND uuid != ? LIMIT 1"; @@ -101,6 +88,7 @@ public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { @Nullable public List getSavedNicknamesForPlayer(UUID uuid) { + if (!playerSaveExists(uuid)) return null; List savedNicknames = new ArrayList<>(); String queryString = "SELECT nickname AND normalized FROM saved_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { @@ -122,6 +110,7 @@ public List getSavedNicknamesForPlayer(UUID uuid) { } public boolean userAlreadySavedThisName(UUID uuid, String nickname) { + if (!playerSaveExists(uuid)) return false; String queryString = "SELECT nickname FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); @@ -138,6 +127,7 @@ public boolean userAlreadySavedThisName(UUID uuid, String nickname) { @Nullable public Nickname getCurrentNicknameForPlayer(UUID uuid) { + if (!playerSaveExists(uuid)) return null; String queryString = "SELECT nickname AND normalized FROM current_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement getStatement = connection.prepareStatement(queryString); @@ -172,6 +162,7 @@ public boolean saveNickname(UUID uuid, String nickname, String normalizedNicknam } public boolean deleteNickname(UUID uuid, String nickname) { + if (!playerSaveExists(uuid)) return false; String deleteQuery = "DELETE FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(deleteQuery); @@ -187,6 +178,7 @@ public boolean deleteNickname(UUID uuid, String nickname) { } public boolean clearActiveNickname(UUID uuid) { + if (!playerSaveExists(uuid)) return true; String deleteQuery = "DELETE FROM current_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(deleteQuery); @@ -217,6 +209,20 @@ public boolean setActiveNickname(UUID uuid, String nicknameString, String normal } } + public boolean playerSaveExists(UUID uuid) { + String queryString = "SELECT 1 FROM players WHERE uuid = ? LIMIT 1"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.severe("Failed to check if player exists: " + uuid); + e.printStackTrace(); + return false; + } + } + private void addPlayerToPlayers(UUID uuid) { String insertQuery = "REPLACE INTO players (uuid, last_login) VALUES (?, CURRENT_TIMESTAMP)"; try (Connection connection = getConnection()) { From aa097607cb315b102e51f13ebb72b7aed41457d4 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 6 May 2025 20:23:33 -0700 Subject: [PATCH 08/40] it was a syntax error. Anyways, it works, autocomplete is still broken --- src/main/java/simplexity/simplenicks/saving/SqlHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index bae5728..ce44892 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -90,7 +90,7 @@ public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { public List getSavedNicknamesForPlayer(UUID uuid) { if (!playerSaveExists(uuid)) return null; List savedNicknames = new ArrayList<>(); - String queryString = "SELECT nickname AND normalized FROM saved_nicknames WHERE uuid = ?"; + String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(uuid)); @@ -128,7 +128,7 @@ public boolean userAlreadySavedThisName(UUID uuid, String nickname) { @Nullable public Nickname getCurrentNicknameForPlayer(UUID uuid) { if (!playerSaveExists(uuid)) return null; - String queryString = "SELECT nickname AND normalized FROM current_nicknames WHERE uuid = ?"; + String queryString = "SELECT nickname, normalized FROM current_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement getStatement = connection.prepareStatement(queryString); getStatement.setString(1, String.valueOf(uuid)); From 316371345601d77d4e34378a6cb029ab84394fca Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Wed, 7 May 2025 16:29:29 -0700 Subject: [PATCH 09/40] aaaaaaaaa --- .../simplenicks/commands/Delete.java | 7 ++---- .../simplexity/simplenicks/commands/Set.java | 23 ++++++++----------- .../simplexity/simplenicks/saving/Cache.java | 21 +++++++++++++++-- .../simplenicks/saving/NickHandler.java | 1 - .../simplenicks/saving/SqlHandler.java | 4 ++-- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/Delete.java b/src/main/java/simplexity/simplenicks/commands/Delete.java index ef2ea41..d5f939c 100644 --- a/src/main/java/simplexity/simplenicks/commands/Delete.java +++ b/src/main/java/simplexity/simplenicks/commands/Delete.java @@ -3,13 +3,13 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.config.LocaleHandler; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.NickHandler; import simplexity.simplenicks.saving.Nickname; import java.util.ArrayList; -import java.util.List; import java.util.UUID; public class Delete extends SubCommand{ @@ -51,10 +51,7 @@ private boolean removeSavedNick(CommandSender sender, Player player, String nick } @Override - public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { - if (player == null) { - return null; - } + public ArrayList tabComplete(CommandSender sender, String[] args, @NotNull Player player) { ArrayList savedNickNames = new ArrayList<>(); for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { savedNickNames.add(nick.nickname()); diff --git a/src/main/java/simplexity/simplenicks/commands/Set.java b/src/main/java/simplexity/simplenicks/commands/Set.java index 9412fb9..4d613ec 100644 --- a/src/main/java/simplexity/simplenicks/commands/Set.java +++ b/src/main/java/simplexity/simplenicks/commands/Set.java @@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.LocaleHandler; @@ -83,19 +84,6 @@ private String processName(String nickArg, CommandSender sender, Player player) return null; } - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { - if (player == null) { - return null; - } - ArrayList savedNickNames = new ArrayList<>(); - for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { - savedNickNames.add(nick.nickname()); - } - return savedNickNames; - } - - private boolean passesChecks(CommandSender sender, String nickname, Player player) { String strippedMessage = miniMessage.stripTags(nickname); Pattern regexPattern = ConfigHandler.getInstance().getRegex(); @@ -127,4 +115,13 @@ private boolean passesChecks(CommandSender sender, String nickname, Player playe return true; } + @Override + public ArrayList tabComplete(CommandSender sender, String[] args, @NotNull Player player) { + ArrayList savedNickNames = new ArrayList<>(); + for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { + savedNickNames.add(nick.nickname()); + } + return savedNickNames; + } + } diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index 5410698..051fce7 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -4,6 +4,7 @@ import simplexity.simplenicks.SimpleNicks; import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; @@ -21,6 +22,7 @@ public static Cache getInstance() { private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); private final HashMap activeNicknames = new HashMap<>(); + private final HashMap> savedNicknames = new HashMap<>(); @Nullable public Nickname getActiveNickname(UUID uuid){ @@ -39,6 +41,9 @@ public boolean setActiveNickname(UUID uuid, String nickname){ } public boolean deleteSavedNickname(String nickname, UUID uuid) { + ArrayList userSavedNicknames = getSavedNicknames(uuid); + userSavedNicknames.removeIf(name -> name.nickname().equals(nickname)); + savedNicknames.put(uuid, userSavedNicknames); return SqlHandler.getInstance().deleteNickname(uuid, nickname); } @@ -67,10 +72,22 @@ public boolean nickInUseOnlinePlayers(String name, UUID uuid) { public boolean saveNickname(String name, UUID uuid) { String strippedNick = miniMessage.stripTags(name); + Nickname nick = new Nickname(name, strippedNick); + ArrayList userSavedNicknames = getSavedNicknames(uuid); + userSavedNicknames.add(nick); + savedNicknames.put(uuid, userSavedNicknames); return SqlHandler.getInstance().saveNickname(uuid, name, strippedNick); } - public List getSavedNicknames(UUID uuid) { - return SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); + public ArrayList getSavedNicknames(UUID uuid) { + if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid); + ArrayList userSavedNicknames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); + savedNicknames.put(uuid, userSavedNicknames); + return userSavedNicknames; + } + + public void removePlayerFromCache(UUID uuid){ + savedNicknames.remove(uuid); + activeNicknames.remove(uuid); } } diff --git a/src/main/java/simplexity/simplenicks/saving/NickHandler.java b/src/main/java/simplexity/simplenicks/saving/NickHandler.java index d268a10..ad48ac3 100644 --- a/src/main/java/simplexity/simplenicks/saving/NickHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/NickHandler.java @@ -47,7 +47,6 @@ public boolean refreshNickname(UUID uuid) { public String cleanNonPermittedTags(CommandSender user, String nick) { int permissionCount = 0; - String strippedMessage = miniMessage.stripTags(nick); TagResolver.Builder resolver = TagResolver.builder(); for (TagPermission tagPermission : TagPermission.values()) { if (user.hasPermission(tagPermission.getPermission())) { diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index ce44892..7e4f85a 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -87,9 +87,9 @@ public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { } @Nullable - public List getSavedNicknamesForPlayer(UUID uuid) { + public ArrayList getSavedNicknamesForPlayer(UUID uuid) { if (!playerSaveExists(uuid)) return null; - List savedNicknames = new ArrayList<>(); + ArrayList savedNicknames = new ArrayList<>(); String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); From b766fae4b9c8b96ecbfe4a689784fa4bf04540ad Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Wed, 7 May 2025 19:09:49 -0700 Subject: [PATCH 10/40] It fixed,,, and I ,, don't know why --- .../simplenicks/listener/LoginListener.java | 8 ++- .../simplexity/simplenicks/saving/Cache.java | 52 ++++++++++++------- .../simplenicks/saving/SqlHandler.java | 9 ++-- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index cb287e7..13eaf3b 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -4,11 +4,17 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.NickHandler; +import java.util.UUID; + public class LoginListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerLogin(PlayerJoinEvent joinEvent) { - NickHandler.getInstance().refreshNickname(joinEvent.getPlayer().getUniqueId()); + UUID playerUuid = joinEvent.getPlayer().getUniqueId(); + Cache.getInstance().loadCurrentNickname(playerUuid); + Cache.getInstance().loadSavedNicknames(playerUuid); + NickHandler.getInstance().refreshNickname(playerUuid); } } diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index 051fce7..d601329 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -22,34 +22,55 @@ public static Cache getInstance() { private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); private final HashMap activeNicknames = new HashMap<>(); - private final HashMap> savedNicknames = new HashMap<>(); + private final HashMap> savedNicknames = new HashMap<>(); + + public void loadCurrentNickname(UUID uuid) { + Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid); + if (currentNick == null) return; + activeNicknames.put(uuid, currentNick); + } @Nullable public Nickname getActiveNickname(UUID uuid){ if (activeNicknames.containsKey(uuid)) return activeNicknames.get(uuid); - Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid); - if (currentNick == null) return null; - activeNicknames.put(uuid, currentNick); - return currentNick; + return null; + } + + public void loadSavedNicknames(UUID uuid) { + List savedNames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); + if (savedNames == null || savedNames.isEmpty()) return; + savedNicknames.put(uuid, savedNames); + } + + public List getSavedNicknames(UUID uuid) { + if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid); + return new ArrayList<>(); } public boolean setActiveNickname(UUID uuid, String nickname){ String normalizedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, normalizedNick); + boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, nickname, normalizedNick); + if (!sqlActiveNameSet) return false; activeNicknames.put(uuid, nick); - return SqlHandler.getInstance().setActiveNickname(uuid, nickname, normalizedNick); + return true; } public boolean deleteSavedNickname(String nickname, UUID uuid) { - ArrayList userSavedNicknames = getSavedNicknames(uuid); + boolean sqlDeleted = SqlHandler.getInstance().deleteNickname(uuid, nickname); + if (!sqlDeleted) return false; + if (!savedNicknames.containsKey(uuid)) return false; + List userSavedNicknames = savedNicknames.get(uuid); userSavedNicknames.removeIf(name -> name.nickname().equals(nickname)); savedNicknames.put(uuid, userSavedNicknames); - return SqlHandler.getInstance().deleteNickname(uuid, nickname); + return true; } public boolean clearCurrentNickname(UUID uuid) { + boolean sqlNickRemoved = SqlHandler.getInstance().clearActiveNickname(uuid); + if (!sqlNickRemoved) return false; activeNicknames.remove(uuid); - return SqlHandler.getInstance().clearActiveNickname(uuid); + return true; } public boolean userAlreadySavedThis(String name, UUID uuid) { @@ -73,17 +94,12 @@ public boolean nickInUseOnlinePlayers(String name, UUID uuid) { public boolean saveNickname(String name, UUID uuid) { String strippedNick = miniMessage.stripTags(name); Nickname nick = new Nickname(name, strippedNick); - ArrayList userSavedNicknames = getSavedNicknames(uuid); + List userSavedNicknames = getSavedNicknames(uuid); userSavedNicknames.add(nick); + boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, name, strippedNick); + if (!savedToSql) return false; savedNicknames.put(uuid, userSavedNicknames); - return SqlHandler.getInstance().saveNickname(uuid, name, strippedNick); - } - - public ArrayList getSavedNicknames(UUID uuid) { - if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid); - ArrayList userSavedNicknames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); - savedNicknames.put(uuid, userSavedNicknames); - return userSavedNicknames; + return true; } public void removePlayerFromCache(UUID uuid){ diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 7e4f85a..72173cf 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -87,15 +87,15 @@ public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { } @Nullable - public ArrayList getSavedNicknamesForPlayer(UUID uuid) { - if (!playerSaveExists(uuid)) return null; - ArrayList savedNicknames = new ArrayList<>(); + public List getSavedNicknamesForPlayer(UUID uuid) { + List savedNicknames = new ArrayList<>(); + if (!playerSaveExists(uuid)) return savedNicknames; String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(uuid)); ResultSet resultSet = statement.executeQuery(); - if (!resultSet.next()) return null; + if (!resultSet.next()) return savedNicknames; while (resultSet.next()) { String nicknameString = resultSet.getString("nickname"); String normalizedString = resultSet.getString("normalized"); @@ -105,6 +105,7 @@ public ArrayList getSavedNicknamesForPlayer(UUID uuid) { } catch (SQLException e) { logger.severe("Failed to get saved nicknames for player: " + uuid); e.printStackTrace(); + return null; } return savedNicknames; } From f828b4f6569ff3b7a63e54976d04c54e573e504b Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Thu, 8 May 2025 16:45:26 -0700 Subject: [PATCH 11/40] Work on commands, but not much has been done --- .../simplexity/simplenicks/SimpleNicks.java | 4 +- .../simplenicks/commands/CommandHandler.java | 137 ----------- .../simplenicks/commands/Delete.java | 6 +- .../simplexity/simplenicks/commands/Help.java | 2 +- .../simplenicks/commands/Reset.java | 2 +- .../simplexity/simplenicks/commands/Save.java | 2 +- .../simplexity/simplenicks/commands/Set.java | 34 +-- .../simplenicks/commands/SubCommand.java | 16 +- .../simplenicks/commands/admin/AdminNick.java | 48 ++++ .../simplenicks/config/ConfigHandler.java | 4 +- .../simplenicks/config/LocaleHandler.java | 215 ++++-------------- .../simplenicks/config/Message.java | 54 +++++ .../simplexity/simplenicks/saving/Cache.java | 12 +- .../simplenicks/saving/NickHandler.java | 28 +++ .../simplenicks/saving/SqlHandler.java | 22 +- 15 files changed, 236 insertions(+), 350 deletions(-) delete mode 100644 src/main/java/simplexity/simplenicks/commands/CommandHandler.java create mode 100644 src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java create mode 100644 src/main/java/simplexity/simplenicks/config/Message.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index f091b46..ab6d037 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -3,7 +3,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import simplexity.simplenicks.commands.CommandHandler; +import simplexity.simplenicks.commands.NickCommandHandler; import simplexity.simplenicks.commands.Delete; import simplexity.simplenicks.commands.Help; import simplexity.simplenicks.commands.Reset; @@ -46,7 +46,7 @@ public void onEnable() { this.saveDefaultConfig(); getConfig().options().copyDefaults(true); saveConfig(); - this.getCommand("nick").setExecutor(new CommandHandler()); + this.getCommand("nick").setExecutor(new NickCommandHandler()); this.getCommand("snreload").setExecutor(new SNReload()); if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); diff --git a/src/main/java/simplexity/simplenicks/commands/CommandHandler.java b/src/main/java/simplexity/simplenicks/commands/CommandHandler.java deleted file mode 100644 index 7fa9e5c..0000000 --- a/src/main/java/simplexity/simplenicks/commands/CommandHandler.java +++ /dev/null @@ -1,137 +0,0 @@ -package simplexity.simplenicks.commands; - -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.LocaleHandler; - -import java.util.ArrayList; -import java.util.List; - -public class CommandHandler implements TabExecutor { - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - private final ArrayList tabComplete = new ArrayList<>(); - - // /nick - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - if (args.length < 1) { - sendMessage(sender, LocaleHandler.getInstance().getNotEnoughArgs()); - return false; - } - if (args.length >= 2) { - Player player = getPlayerFromArgs(args); - String subCommandString = args[0].toLowerCase(); - SubCommand subCommand = SimpleNicks.getSubCommands().get(subCommandString); - if (subCommand != null && sender.hasPermission(subCommand.adminPermission) && (player != null)) { - commandOnOther(sender, args, player); - return true; - } - } - commandOnSelf(sender, args); - return true; - - } - - private Player getPlayerFromArgs(String[] args) { - return SimpleNicks.getInstance().getServer().getPlayer(args[1]); - } - - private void commandOnOther(CommandSender sender, String[] args, Player player) { - String command = args[0].toLowerCase(); - SubCommand subCommand = SimpleNicks.getSubCommands().get(command); - if (subCommand == null) { - sendMessage(sender, LocaleHandler.getInstance().getInvalidCommand()); - return; - } - if (!sender.hasPermission(subCommand.adminPermission)) { - sendMessage(sender, LocaleHandler.getInstance().getNoPermission()); - return; - } - subCommand.executeOnOther(sender, player, args); - } - - private void commandOnSelf(CommandSender sender, String[] args) { - String command = args[0].toLowerCase(); - SubCommand subCommand = SimpleNicks.getSubCommands().get(command); - if (subCommand == null) { - sendMessage(sender, LocaleHandler.getInstance().getInvalidCommand()); - return; - } - if (!sender.hasPermission(subCommand.basicPermission)) { - sendMessage(sender, LocaleHandler.getInstance().getNoPermission()); - return; - } - Player player = null; - if (sender instanceof Player) { - player = (Player) sender; - } - if (player == null && !subCommand.canRunWithoutPlayer()) { - sendMessage(sender, LocaleHandler.getInstance().getMustBePlayer()); - return; - } - subCommand.executeOnSelf(sender, player, args); - } - - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - tabComplete.clear(); - Player player = getPlayerForTabComplete(sender, args); - switch (args.length) { - case 0, 1 -> addSubCommandsToTabComplete(sender); - case 2 -> { - SubCommand subCommand = SimpleNicks.getSubCommands().get(args[0].toLowerCase()); - if (SimpleNicks.getSubCommands().containsKey(args[0].toLowerCase())) { - if (sender.hasPermission(subCommand.adminPermission) && (player != null)) { - return null; - } else { - return subCommand.tabComplete(sender, args, player); - } - } - } - case 3 -> { - SubCommand subCommand = SimpleNicks.getSubCommands().get(args[0].toLowerCase()); - if (subCommand == null) { - return null; - } - return subCommand.tabComplete(sender, args, player); - } - } - - return tabComplete; - } - - private Player getPlayerForTabComplete(CommandSender sender, String[] args) { - if (args.length < 2) { - return null; - } - Player player = getPlayerFromArgs(args); - if (player != null) { - return player; - } - if (sender instanceof Player playerSender) { - return playerSender; - } - return null; - } - - private void addSubCommandsToTabComplete(CommandSender sender) { - for (String key : SimpleNicks.getSubCommands().keySet()) { - SubCommand subCommand = SimpleNicks.getSubCommands().get(key); - if (sender.hasPermission(subCommand.basicPermission) || sender.hasPermission(subCommand.adminPermission)) { - tabComplete.add(key); - } - } - } - - private void sendMessage(CommandSender sender, String message) { - sender.sendMessage(miniMessage.deserialize(message, Placeholder.parsed("prefix", LocaleHandler.getInstance().getPluginPrefix()))); - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/Delete.java b/src/main/java/simplexity/simplenicks/commands/Delete.java index d5f939c..250dc6f 100644 --- a/src/main/java/simplexity/simplenicks/commands/Delete.java +++ b/src/main/java/simplexity/simplenicks/commands/Delete.java @@ -18,8 +18,8 @@ public Delete(String commandName, Permission basicPermission, Permission adminPe } @Override - public void executeOnOther(CommandSender sender, Player player, String[] args) { - if (!isValidArgsLength(sender, player, args, 3)) { + public void execute(CommandSender sender, Player player, String[] args) { + if (!validArgsLength(sender, player, args, 3)) { return; } String nickname = args[2]; @@ -31,7 +31,7 @@ public void executeOnOther(CommandSender sender, Player player, String[] args) { @Override public void executeOnSelf(CommandSender sender, Player player, String[] args) { - if (!isValidArgsLength(sender, player, args, 2)) { + if (!validArgsLength(sender, player, args, 2)) { return; } String nickname = args[1]; diff --git a/src/main/java/simplexity/simplenicks/commands/Help.java b/src/main/java/simplexity/simplenicks/commands/Help.java index 1bc4fd6..56d5a71 100644 --- a/src/main/java/simplexity/simplenicks/commands/Help.java +++ b/src/main/java/simplexity/simplenicks/commands/Help.java @@ -14,7 +14,7 @@ public Help(String commandName, Permission basicPermission, Permission adminPerm } @Override - public void executeOnOther(CommandSender sender, Player player, String[] args) { + public void execute(CommandSender sender, Player player, String[] args) { sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getShownHelp(), player.getName())); player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getHelpMessage(), "")); } diff --git a/src/main/java/simplexity/simplenicks/commands/Reset.java b/src/main/java/simplexity/simplenicks/commands/Reset.java index 89c9254..610f7b4 100644 --- a/src/main/java/simplexity/simplenicks/commands/Reset.java +++ b/src/main/java/simplexity/simplenicks/commands/Reset.java @@ -17,7 +17,7 @@ public Reset(String commandName, Permission basicPermission, Permission adminPer } @Override - public void executeOnOther(CommandSender sender, Player player, String[] args) { + public void execute(CommandSender sender, Player player, String[] args) { resetName(player); sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getResetOther(), player.getName())); player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getResetByOther(), player.getName())); diff --git a/src/main/java/simplexity/simplenicks/commands/Save.java b/src/main/java/simplexity/simplenicks/commands/Save.java index 505123c..29e3005 100644 --- a/src/main/java/simplexity/simplenicks/commands/Save.java +++ b/src/main/java/simplexity/simplenicks/commands/Save.java @@ -19,7 +19,7 @@ public Save(String commandName, Permission basicPermission, Permission adminPerm } @Override - public void executeOnOther(CommandSender sender, Player player, String[] args) { + public void execute(CommandSender sender, Player player, String[] args) { if (savePlayerNick(player)) { sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveNick(), miniMessage.serialize(player.displayName()))); player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveNick(), miniMessage.serialize(player.displayName()))); diff --git a/src/main/java/simplexity/simplenicks/commands/Set.java b/src/main/java/simplexity/simplenicks/commands/Set.java index 4d613ec..f2ec250 100644 --- a/src/main/java/simplexity/simplenicks/commands/Set.java +++ b/src/main/java/simplexity/simplenicks/commands/Set.java @@ -1,8 +1,5 @@ package simplexity.simplenicks.commands; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -15,10 +12,8 @@ import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; import simplexity.simplenicks.saving.NickHandler; -import simplexity.simplenicks.util.TagPermission; import java.util.ArrayList; -import java.util.List; import java.util.UUID; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -31,8 +26,16 @@ public Set(String commandName, Permission basicPermission, Permission adminPermi } @Override - public void executeOnOther(CommandSender sender, Player player, String[] args) { - if (!isValidArgsLength(sender, player, args, 3)) { + public void execute(CommandSender sender, Player player, String[] args, boolean adminCommand) { + + } + + + + + /*@Override + public void execute(CommandSender sender, Player player, String[] args, boolean adminCommand) { + if (!validArgsLength(args, 3)) { return; } String nickname = args[2]; @@ -48,21 +51,6 @@ public void executeOnOther(CommandSender sender, Player player, String[] args) { } } - @Override - public void executeOnSelf(CommandSender sender, Player player, String[] args) { - if (!isValidArgsLength(sender, player, args, 2)) return; - String nickname = args[1]; - if (!passesChecks(sender, nickname, player)) { - return; - } - nickname = processName(nickname, sender, player); - if (setPlayerNick(player, nickname)) { - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedSelf(), nickname)); - } else { - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getInvalidTags(), nickname)); - } - } - private boolean setPlayerNick(Player player, String nickString) { if (nickString == null) { return false; @@ -113,7 +101,7 @@ private boolean passesChecks(CommandSender sender, String nickname, Player playe } } return true; - } + }*/ @Override public ArrayList tabComplete(CommandSender sender, String[] args, @NotNull Player player) { diff --git a/src/main/java/simplexity/simplenicks/commands/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/SubCommand.java index 75d0400..82c9d85 100644 --- a/src/main/java/simplexity/simplenicks/commands/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/SubCommand.java @@ -7,7 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.LocaleHandler; +import simplexity.simplenicks.config.Message; import java.util.ArrayList; @@ -24,9 +24,7 @@ public SubCommand(String commandName, Permission basicPermission, Permission adm this.canRunWithoutPlayer = consoleRunNoPlayer; } - public abstract void executeOnOther(CommandSender sender, Player player, String[] args); - - public abstract void executeOnSelf(CommandSender sender, Player player, String[] args); + public abstract void execute(CommandSender sender, Player player, String[] args, boolean adminCommand); public abstract ArrayList tabComplete(CommandSender sender, String[] args, Player player); @@ -60,17 +58,13 @@ public Component parsedMessage(CommandSender sender, Player player, String messa playerName = player.name(); } return miniMessage.deserialize(message, - Placeholder.parsed("prefix", LocaleHandler.getInstance().getPluginPrefix()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), Placeholder.component("initiator", senderName), Placeholder.component("target", playerName), Placeholder.parsed("value", value)); } - public boolean isValidArgsLength(CommandSender sender, Player player, String[] args, int minArgsLength) { - if (args.length < minArgsLength) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getNotEnoughArgs(), "")); - return false; - } - return true; + public boolean validArgsLength(String[] args, int minArgsLength) { + return args.length >= minArgsLength; } } diff --git a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java new file mode 100644 index 0000000..30de7b9 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java @@ -0,0 +1,48 @@ +package simplexity.simplenicks.commands.admin; + +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.saving.NickHandler; + +import java.util.List; + +public class AdminNick implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { + if (args.length < 2) { + sender.sendRichMessage(Message.NOT_ENOUGH_ARGS.getMessage()); + return false; + } + + + return false; + } + + private Player validateProvidedPlayer(String string, CommandSender sender) { + Player player = Bukkit.getPlayer(string); + if (player != null) return player; + List playersFromName = NickHandler.getInstance().getOnlinePlayersByNickname(string); + if (playersFromName.isEmpty()) { + sender.sendRichMessage( + Message.INVALID_PLAYER.getMessage() + ); + return null; + } + if (playersFromName.size() > 1) { + + } + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) { + return List.of(); + } +} diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index 2c60a30..24eba72 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -38,7 +38,7 @@ public static ConfigHandler getInstance() { public void reloadConfig() { SimpleNicks.getInstance().reloadConfig(); - LocaleHandler.getInstance().loadLocale(); + LocaleHandler.getInstance().reloadLocale(); FileConfiguration config = SimpleNicks.getInstance().getConfig(); // Check the validity of the regex. try { @@ -46,7 +46,7 @@ public void reloadConfig() { regexString = regexSetting; regex = Pattern.compile(regexSetting); } catch (PatternSyntaxException e) { - logger.severe(LocaleHandler.getInstance().getInvalidConfigRegex()); + logger.severe(Message.INVALID_CONFIG_REGEX.getMessage()); } mySql = config.getBoolean("mysql.enabled", false); mySqlIp = config.getString("mysql.ip", "localhost:3306"); diff --git a/src/main/java/simplexity/simplenicks/config/LocaleHandler.java b/src/main/java/simplexity/simplenicks/config/LocaleHandler.java index 1ff7d86..a4c9529 100644 --- a/src/main/java/simplexity/simplenicks/config/LocaleHandler.java +++ b/src/main/java/simplexity/simplenicks/config/LocaleHandler.java @@ -7,198 +7,83 @@ import java.io.File; import java.io.IOException; -import java.util.logging.Logger; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@SuppressWarnings({"CallToPrintStackTrace", "CollectionAddAllCanBeReplacedWithConstructor", "ResultOfMethodCallIgnored"}) public class LocaleHandler { private static LocaleHandler instance; private final String fileName = "locale.yml"; - private final File localeFile = new File(SimpleNicks.getInstance().getDataFolder(), fileName); - private final FileConfiguration localeConfig = new YamlConfiguration(); - private final Logger logger = SimpleNicks.getInstance().getLogger(); - //Plugin - private String pluginPrefix, helpMessage, configReloaded, shownHelp; - //Errors - private String invalidCommand, invalidPlayer, invalidNick, invalidNickLength, invalidTags, invalidConfigRegex, - tooManyArgs, notEnoughArgs, nickIsNull, deleteFailure, nameNonexistent, saveFailure, tooManyToSave, otherPlayersUsername, - noPermission, mustBePlayer; - //Nick - private String changedSelf, changedOther, changedByOther, resetSelf, resetOther, resetByOther, saveNick, deleteNick; - + private final File dataFile = new File(SimpleNicks.getInstance().getDataFolder(), fileName); + private FileConfiguration locale = new YamlConfiguration(); private LocaleHandler() { - if (!localeFile.exists()) { - SimpleNicks.getInstance().saveResource(fileName, false); + try { + dataFile.getParentFile().mkdirs(); + dataFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); } + reloadLocale(); } public static LocaleHandler getInstance() { - if (instance == null) instance = new LocaleHandler(); + if (instance == null) { + instance = new LocaleHandler(); + } return instance; } - public FileConfiguration getLocaleConfig() { - return localeConfig; - } - - - public void loadLocale() { + public void reloadLocale() { try { - localeConfig.load(localeFile); + locale.load(dataFile); } catch (IOException | InvalidConfigurationException e) { - logger.severe("Issue loading locale.yml"); e.printStackTrace(); } - pluginPrefix = localeConfig.getString("plugin.prefix", "SimpleNicks » "); - helpMessage = localeConfig.getString("plugin.help-message", - """ - ======================== - · Setting a nickname:\s - /nick set - · removing a nickname:\s - /nick reset" - · Formatting:\s - This plugin uses minimessage formatting. You can find a format viewer here" - \ - """); - shownHelp = localeConfig.getString("plugin.shown-help", " has been shown the help screen"); - configReloaded = localeConfig.getString("plugin.config-reloaded", "SimpleNicks config and locale reloaded"); - invalidCommand = localeConfig.getString("error.invalid.command", "Invalid command."); - invalidPlayer = localeConfig.getString("error.invalid.player", "Invalid player specified"); - invalidNick = localeConfig.getString("error.invalid.nick", "Not a valid nickname, must follow regex: "); - invalidNickLength = localeConfig.getString("error.invalid.nick-length", "Nickname is too long, must be <= "); - invalidTags = localeConfig.getString("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"); - invalidConfigRegex = localeConfig.getString("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"); - notEnoughArgs = localeConfig.getString("error.arguments.not-enough", "No arguments provided."); - tooManyArgs = localeConfig.getString("error.arguments.too-many", "Too many arguments provided."); - nickIsNull = localeConfig.getString("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"); - deleteFailure = localeConfig.getString("error.nickname.delete-failure", "Failed to delete given username."); - saveFailure = localeConfig.getString("error.nickname.save-failure", "Failed to save current username."); - tooManyToSave = localeConfig.getString("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "); - otherPlayersUsername = localeConfig.getString("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"); - nameNonexistent = localeConfig.getString("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"); - noPermission = localeConfig.getString("error.no-permission", "You do not have permission to run this command"); - mustBePlayer = localeConfig.getString("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"); - changedSelf = localeConfig.getString("nick.changed.self", "Changed your nickname to !"); - changedOther = localeConfig.getString("nick.changed.other", "Changed 's nickname to "); - changedByOther = localeConfig.getString("nick.changed.by-other", " changed your nickname to !"); - resetSelf = localeConfig.getString("nick.reset.self", "Reset your nickname!"); - resetOther = localeConfig.getString("nick.reset.other", "Reset 's nickname."); - resetByOther = localeConfig.getString("nick.reset.reset-by-other", "Your nickname was reset by "); - saveNick = localeConfig.getString("nick.save", "Success! The nickname has been saved for future use"); - deleteNick = localeConfig.getString("nick.delete", "The nickname has been successfully removed from your saved names"); - } - - - public String getPluginPrefix() { - return pluginPrefix; - } - - public String getHelpMessage() { - return helpMessage; - } - - public String getConfigReloaded() { - return configReloaded; - } - - public String getInvalidCommand() { - return invalidCommand; - } - - public String getInvalidPlayer() { - return invalidPlayer; - } - - public String getInvalidNick() { - return invalidNick; - } - - public String getInvalidNickLength() { - return invalidNickLength; - } - - public String getInvalidTags() { - return invalidTags; - } - - public String getInvalidConfigRegex() { - return invalidConfigRegex; - } - - public String getTooManyArgs() { - return tooManyArgs; - } - - public String getNotEnoughArgs() { - return notEnoughArgs; - } - - public String getNickIsNull() { - return nickIsNull; - } - - public String getDeleteFailure() { - return deleteFailure; - } - - public String getSaveFailure() { - return saveFailure; - } - - public String getTooManyToSave() { - return tooManyToSave; - } - - public String getOtherPlayersUsername() { - return otherPlayersUsername; - } - - public String getNoPermission() { - return noPermission; - } - - public String getMustBePlayer() { - return mustBePlayer; + populateLocale(); + sortLocale(); + saveLocale(); } - public String getChangedSelf() { - return changedSelf; - } - - public String getChangedOther() { - return changedOther; - } - - public String getChangedByOther() { - return changedByOther; - } - public String getResetSelf() { - return resetSelf; - } + private void populateLocale() { + Set missing = new HashSet<>(Arrays.asList(Message.values())); + for (Message message : Message.values()) { + if (locale.contains(message.getPath())) { + message.setMessage(locale.getString(message.getPath())); + missing.remove(message); + } + } - public String getResetOther() { - return resetOther; - } + for (Message message : missing) { + locale.set(message.getPath(), message.getMessage()); + } - public String getResetByOther() { - return resetByOther; - } - public String getSaveNick() { - return saveNick; } - public String getDeleteNick() { - return deleteNick; + private void sortLocale() { + FileConfiguration newLocale = new YamlConfiguration(); + List keys = new ArrayList<>(); + keys.addAll(locale.getKeys(true)); + Collections.sort(keys); + for (String key : keys) { + newLocale.set(key, locale.getString(key)); + } + locale = newLocale; } - public String getNameNonexistent() { - return nameNonexistent; + private void saveLocale() { + try { + locale.save(dataFile); + } catch (IOException e) { + e.printStackTrace(); + } } - public String getShownHelp() { - return shownHelp; - } } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java new file mode 100644 index 0000000..fb2cd73 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -0,0 +1,54 @@ +package simplexity.simplenicks.config; + +public enum Message { + PLUGIN_PREFIX("plugin.prefix", "SimpleNicks » "), + HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), + SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), + CONFIG_RELOADED("plugin.config-reloaded", "SimpleNicks config and locale reloaded"), + INVALID_COMMAND("error.invalid.command", "Invalid command."), + INVALID_PLAYER("error.invalid.player", "Invalid player specified"), + INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), + INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= "), + INVALID_TAGS("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"), + INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), + NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), + TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), + NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), + DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given username."), + SAVE_FAILURE("error.nickname.save-failure", "Failed to save current username."), + TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), + OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), + NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), + NO_PERMISSION("error.no-permission", "You do not have permission to run this command"), + MUST_BE_PLAYER("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"), + MULTIPLE_PLAYERS_BY_THAT_NAME("error.multiple-players-by-that-name", "There are multiple online players by that name, please try using the actual username."), + CHANGED_SELF("nick.changed.self", "Changed your nickname to !"), + CHANGED_OTHER("nick.changed.other", "Changed 's nickname to "), + CHANGED_BY_OTHER("nick.changed.by-other", " changed your nickname to !"), + RESET_SELF("nick.reset.self", "Reset your nickname!"), + RESET_OTHER("nick.reset.other", "Reset 's nickname."), + RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), + SAVE_NICK("nick.save", "Success! The nickname has been saved for future use"), + DELETE_NICK("nick.delete", "The nickname has been successfully removed from your saved names"); + + + private final String path; + private String message; + + Message(String path, String message) { + this.path = path; + this.message = message; + } + + public String getPath() { + return path; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index d601329..bdeb008 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -31,7 +31,7 @@ public void loadCurrentNickname(UUID uuid) { } @Nullable - public Nickname getActiveNickname(UUID uuid){ + public Nickname getActiveNickname(UUID uuid) { if (activeNicknames.containsKey(uuid)) return activeNicknames.get(uuid); return null; } @@ -47,7 +47,7 @@ public List getSavedNicknames(UUID uuid) { return new ArrayList<>(); } - public boolean setActiveNickname(UUID uuid, String nickname){ + public boolean setActiveNickname(UUID uuid, String nickname) { String normalizedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, normalizedNick); boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, nickname, normalizedNick); @@ -73,6 +73,12 @@ public boolean clearCurrentNickname(UUID uuid) { return true; } + public List getUuidOfNormalizedName(String nickname) { + List uuids = SqlHandler.getInstance().getUuidsOfNickname(nickname); + if (uuids == null) return new ArrayList<>(); + return uuids; + } + public boolean userAlreadySavedThis(String name, UUID uuid) { return SqlHandler.getInstance().userAlreadySavedThisName(uuid, name); } @@ -102,7 +108,7 @@ public boolean saveNickname(String name, UUID uuid) { return true; } - public void removePlayerFromCache(UUID uuid){ + public void removePlayerFromCache(UUID uuid) { savedNicknames.remove(uuid); activeNicknames.remove(uuid); } diff --git a/src/main/java/simplexity/simplenicks/saving/NickHandler.java b/src/main/java/simplexity/simplenicks/saving/NickHandler.java index ad48ac3..578c63b 100644 --- a/src/main/java/simplexity/simplenicks/saving/NickHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/NickHandler.java @@ -4,12 +4,15 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.util.TagPermission; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; @SuppressWarnings("UnusedReturnValue") @@ -64,4 +67,29 @@ public String cleanNonPermittedTags(CommandSender user, String nick) { Component permissionParsed = parser.deserialize(nick); return miniMessage.serialize(permissionParsed); } + + + public List getOnlinePlayersByNickname(String nickname){ + List usersWithThisName = Cache.getInstance().getUuidOfNormalizedName(nickname); + if (usersWithThisName.isEmpty()) return new ArrayList<>(); + List playersByNick = new ArrayList<>(); + for (UUID uuid : usersWithThisName) { + Player player = Bukkit.getPlayer(uuid); + if (player == null) continue; + playersByNick.add(player); + } + return playersByNick; + } + + public List getOfflinePlayersByNickname(String nickname) { + List usersWithThisName = Cache.getInstance().getUuidOfNormalizedName(nickname); + if (usersWithThisName.isEmpty()) return new ArrayList<>(); + List playersByNick = new ArrayList<>(); + for (UUID uuid : usersWithThisName) { + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid); + if (!offlinePlayer.hasPlayedBefore()) continue; + playersByNick.add(offlinePlayer); + } + return playersByNick; + } } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 72173cf..cf97b63 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -120,7 +120,7 @@ public boolean userAlreadySavedThisName(UUID uuid, String nickname) { ResultSet resultSet = statement.executeQuery(); return resultSet.next(); } catch (SQLException e) { - logger.warning("Failed to check if UUID '" + uuid + "' has already saved the nickname '" + nickname +"'"); + logger.warning("Failed to check if UUID '" + uuid + "' has already saved the nickname '" + nickname + "'"); e.printStackTrace(); return false; } @@ -145,6 +145,26 @@ public Nickname getCurrentNicknameForPlayer(UUID uuid) { return null; } + @Nullable + public List getUuidsOfNickname(String normalizeName) { + String queryString = "SELECT uuid FROM current_nicknames WHERE normalized = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, normalizeName); + ResultSet resultSet = statement.executeQuery(); + if (!resultSet.next()) return new ArrayList<>(); + List uuids = new ArrayList<>(); + while (resultSet.next()) { + uuids.add(UUID.fromString(resultSet.getString("uuid"))); + } + return uuids; + } catch (SQLException e) { + logger.warning("Failed to get UUID list from normalized nickname"); + e.printStackTrace(); + return null; + } + } + public boolean saveNickname(UUID uuid, String nickname, String normalizedNickname) { String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); From 871e04a3f17ba33b3b96b6dc3ebf6387d0afb416 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sat, 10 May 2025 14:10:34 -0700 Subject: [PATCH 12/40] Work on processing nicknames, Cache, SqlHandler --- .../simplexity/simplenicks/SimpleNicks.java | 31 +---- .../simplenicks/commands/Delete.java | 61 --------- .../simplexity/simplenicks/commands/Help.java | 31 ----- .../commands/NicknameProcessor.java | 121 ++++++++++++++++++ .../simplenicks/commands/Reset.java | 41 ------ .../simplenicks/commands/SNReload.java | 27 ---- .../simplexity/simplenicks/commands/Save.java | 59 --------- .../simplexity/simplenicks/commands/Set.java | 115 ----------------- .../simplenicks/commands/SubCommand.java | 70 ---------- .../simplenicks/commands/admin/AdminNick.java | 53 +++++++- .../simplenicks/config/ConfigHandler.java | 2 +- .../simplenicks/config/Message.java | 39 +++--- .../simplenicks/hooks/SNExpansion.java | 1 - .../simplenicks/listener/LoginListener.java | 4 +- .../NickHandler.java => logic/NickUtils.java} | 25 +++- .../simplexity/simplenicks/saving/Cache.java | 56 +++++--- .../simplenicks/saving/SqlHandler.java | 2 +- .../simplenicks/util/Constants.java | 12 +- 18 files changed, 260 insertions(+), 490 deletions(-) delete mode 100644 src/main/java/simplexity/simplenicks/commands/Delete.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/Help.java create mode 100644 src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/Reset.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/SNReload.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/Save.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/Set.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/SubCommand.java rename src/main/java/simplexity/simplenicks/{saving/NickHandler.java => logic/NickUtils.java} (83%) diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index ab6d037..beb8ac4 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -3,24 +3,11 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import simplexity.simplenicks.commands.NickCommandHandler; -import simplexity.simplenicks.commands.Delete; -import simplexity.simplenicks.commands.Help; -import simplexity.simplenicks.commands.Reset; -import simplexity.simplenicks.commands.Save; -import simplexity.simplenicks.commands.Set; -import simplexity.simplenicks.commands.SNReload; -import simplexity.simplenicks.commands.SubCommand; import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.listener.LoginListener; -import simplexity.simplenicks.util.Constants; import simplexity.simplenicks.hooks.SNExpansion; +import simplexity.simplenicks.listener.LoginListener; import simplexity.simplenicks.saving.SqlHandler; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import java.util.logging.Logger; /*command based @@ -37,17 +24,13 @@ public final class SimpleNicks extends JavaPlugin { private static final MiniMessage miniMessage = MiniMessage.miniMessage(); private static Plugin instance; - private static final HashMap subCommands = new HashMap<>(); @Override public void onEnable() { instance = this; - registerSubCommands(); this.saveDefaultConfig(); getConfig().options().copyDefaults(true); saveConfig(); - this.getCommand("nick").setExecutor(new NickCommandHandler()); - this.getCommand("snreload").setExecutor(new SNReload()); if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); } @@ -65,24 +48,12 @@ public static Plugin getInstance() { return instance; } - public static Map getSubCommands() { - return Collections.unmodifiableMap(subCommands); - } - public static Logger getSimpleNicksLogger() { return instance.getLogger(); } - private void registerSubCommands() { - subCommands.put("reset", new Reset("reset", Constants.NICK_RESET, Constants.NICK_RESET_OTHERS, false)); - subCommands.put("help", new Help("help", Constants.NICK_COMMAND, Constants.NICK_OTHERS_COMMAND, true)); - subCommands.put("set", new Set("set", Constants.NICK_COMMAND, Constants.NICK_OTHERS_RESTRICTIVE, false)); - subCommands.put("save", new Save("save", Constants.NICK_SAVE, Constants.NICK_OTHERS_SAVE, false)); - subCommands.put("delete", new Delete("delete", Constants.NICK_DELETE, Constants.NICK_OTHERS_DELETE, false)); - } public static void configReload() { - LocaleHandler.getInstance().loadLocale(); ConfigHandler.getInstance().reloadConfig(); } } diff --git a/src/main/java/simplexity/simplenicks/commands/Delete.java b/src/main/java/simplexity/simplenicks/commands/Delete.java deleted file mode 100644 index 250dc6f..0000000 --- a/src/main/java/simplexity/simplenicks/commands/Delete.java +++ /dev/null @@ -1,61 +0,0 @@ -package simplexity.simplenicks.commands; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.NickHandler; -import simplexity.simplenicks.saving.Nickname; - -import java.util.ArrayList; -import java.util.UUID; - -public class Delete extends SubCommand{ - public Delete(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - super(commandName, basicPermission, adminPermission, consoleRunNoPlayer); - } - - @Override - public void execute(CommandSender sender, Player player, String[] args) { - if (!validArgsLength(sender, player, args, 3)) { - return; - } - String nickname = args[2]; - if (removeSavedNick(sender, player, nickname)) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getDeleteNick(), nickname)); - } - - } - - @Override - public void executeOnSelf(CommandSender sender, Player player, String[] args) { - if (!validArgsLength(sender, player, args, 2)) { - return; - } - String nickname = args[1]; - if (removeSavedNick(sender, player, nickname)) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getDeleteNick(), nickname)); - } - } - - private boolean removeSavedNick(CommandSender sender, Player player, String nickname) { - UUID playerUuid = player.getUniqueId(); - if (!Cache.getInstance().deleteSavedNickname(nickname, playerUuid)) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getNameNonexistent(), nickname)); - return false; - } - NickHandler.getInstance().refreshNickname(playerUuid); - return true; - } - - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, @NotNull Player player) { - ArrayList savedNickNames = new ArrayList<>(); - for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { - savedNickNames.add(nick.nickname()); - } - return savedNickNames; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/Help.java b/src/main/java/simplexity/simplenicks/commands/Help.java deleted file mode 100644 index 56d5a71..0000000 --- a/src/main/java/simplexity/simplenicks/commands/Help.java +++ /dev/null @@ -1,31 +0,0 @@ -package simplexity.simplenicks.commands; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import simplexity.simplenicks.config.LocaleHandler; - -import java.util.ArrayList; - -public class Help extends SubCommand { - - public Help(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - super(commandName, basicPermission, adminPermission, consoleRunNoPlayer); - } - - @Override - public void execute(CommandSender sender, Player player, String[] args) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getShownHelp(), player.getName())); - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getHelpMessage(), "")); - } - - @Override - public void executeOnSelf(CommandSender sender, Player player, String[] args) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getHelpMessage(), "")); - } - - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { - return null; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java new file mode 100644 index 0000000..56f5b33 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -0,0 +1,121 @@ +package simplexity.simplenicks.commands; + +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.OfflinePlayer; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.saving.SqlHandler; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class NicknameProcessor { + private static NicknameProcessor instance; + + public NicknameProcessor() { + } + + public static NicknameProcessor getInstance() { + if (instance == null) instance = new NicknameProcessor(); + return instance; + } + + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + public boolean setNickname(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) { + boolean success = Cache.getInstance().setActiveNickname(playerUuid, nickname); + if (!success) return false; + NickUtils.getInstance().refreshNickname(playerUuid); + } + String normalizedNick = miniMessage.stripTags(nickname); + return SqlHandler.getInstance().setActiveNickname(playerUuid, nickname, normalizedNick); + } + + public boolean resetNickname(OfflinePlayer player) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) { + boolean success = Cache.getInstance().clearCurrentNickname(playerUuid); + if (!success) return false; + NickUtils.getInstance().refreshNickname(playerUuid); + return true; + } + return SqlHandler.getInstance().clearActiveNickname(playerUuid); + } + + public boolean saveNickname(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) { + boolean success = Cache.getInstance().saveNickname(playerUuid, nickname); + if (!success) return false; + NickUtils.getInstance().refreshNickname(playerUuid); + return true; + } + String normalizedNick = miniMessage.stripTags(nickname); + return SqlHandler.getInstance().saveNickname(playerUuid, nickname, normalizedNick); + } + + public boolean deleteNickname(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) { + boolean success = Cache.getInstance().deleteSavedNickname(playerUuid, nickname); + if (!success) return false; + NickUtils.getInstance().refreshNickname(playerUuid); + return true; + } + return SqlHandler.getInstance().deleteNickname(playerUuid, nickname); + } + + public List getSavedNicknames(OfflinePlayer player) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) return Cache.getInstance().getSavedNicknames(playerUuid); + List nicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); + if (nicks == null) return new ArrayList<>(); + return nicks; + } + + public Nickname getCurrentNickname(OfflinePlayer player) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) return Cache.getInstance().getActiveNickname(playerUuid); + return SqlHandler.getInstance().getCurrentNicknameForPlayer(playerUuid); + } + + public int getCurrentSavedNickCount(OfflinePlayer player) { + UUID playerUuid = player.getUniqueId(); + boolean online = player.isOnline(); + if (online) return Cache.getInstance().getSavedNickCount(playerUuid); + List savedNicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); + if (savedNicks == null || savedNicks.isEmpty()) return 0; + return savedNicks.size(); + } + + public boolean someoneOnlineUsingThis(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + return Cache.getInstance().nickInUseOnlinePlayers(playerUuid, nickname); + } + + public boolean someoneSavedUsingThis(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + String strippedNick = miniMessage.stripTags(nickname); + return SqlHandler.getInstance().nickAlreadyExists(playerUuid, strippedNick); + } + + public boolean playerAlreadySavedThis(OfflinePlayer player, String nickname) { + UUID playerUuid = player.getUniqueId(); + return SqlHandler.getInstance().userAlreadySavedThisName(playerUuid, nickname); + } + + + + +} diff --git a/src/main/java/simplexity/simplenicks/commands/Reset.java b/src/main/java/simplexity/simplenicks/commands/Reset.java deleted file mode 100644 index 610f7b4..0000000 --- a/src/main/java/simplexity/simplenicks/commands/Reset.java +++ /dev/null @@ -1,41 +0,0 @@ -package simplexity.simplenicks.commands; - -import net.kyori.adventure.text.Component; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.NickHandler; - -import java.util.ArrayList; - -public class Reset extends SubCommand { - - public Reset(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - super(commandName, basicPermission, adminPermission, consoleRunNoPlayer); - } - - @Override - public void execute(CommandSender sender, Player player, String[] args) { - resetName(player); - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getResetOther(), player.getName())); - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getResetByOther(), player.getName())); - } - - @Override - public void executeOnSelf(CommandSender sender, Player player, String[] args) { - resetName(player); - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getResetSelf(), player.getName())); - } - - public void resetName(Player player) { - player.displayName(null); - Cache.getInstance().clearCurrentNickname(player.getUniqueId()); - } - - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { - return null; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/SNReload.java b/src/main/java/simplexity/simplenicks/commands/SNReload.java deleted file mode 100644 index 6c2bc6b..0000000 --- a/src/main/java/simplexity/simplenicks/commands/SNReload.java +++ /dev/null @@ -1,27 +0,0 @@ -package simplexity.simplenicks.commands; - -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.saving.NickHandler; - -public class SNReload implements CommandExecutor { - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - ConfigHandler.getInstance().reloadConfig(); - LocaleHandler.getInstance().loadLocale(); - sender.sendMessage(SimpleNicks.getMiniMessage().deserialize(LocaleHandler.getInstance().getConfigReloaded(), - Placeholder.parsed("prefix", LocaleHandler.getInstance().getPluginPrefix()))); - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - NickHandler.getInstance().refreshNickname(player.getUniqueId()); - } - return false; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/Save.java b/src/main/java/simplexity/simplenicks/commands/Save.java deleted file mode 100644 index 29e3005..0000000 --- a/src/main/java/simplexity/simplenicks/commands/Save.java +++ /dev/null @@ -1,59 +0,0 @@ -package simplexity.simplenicks.commands; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.NickHandler; -import simplexity.simplenicks.saving.Nickname; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public class Save extends SubCommand{ - public Save(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - super(commandName, basicPermission, adminPermission, consoleRunNoPlayer); - } - - @Override - public void execute(CommandSender sender, Player player, String[] args) { - if (savePlayerNick(player)) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveNick(), miniMessage.serialize(player.displayName()))); - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveNick(), miniMessage.serialize(player.displayName()))); - } else { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveFailure(), String.valueOf(ConfigHandler.getInstance().getMaxSaves()))); - } - } - - @Override - public void executeOnSelf(CommandSender sender, Player player, String[] args) { - if (savePlayerNick(player)) { - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveNick(), miniMessage.serialize(player.displayName()))); - } else { - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getSaveFailure(), String.valueOf(ConfigHandler.getInstance().getMaxSaves()))); - } - } - - public boolean savePlayerNick(Player player) { - UUID playerUuid = player.getUniqueId(); - Nickname nick = Cache.getInstance().getActiveNickname(playerUuid); - if (nick == null) { - return false; - } - List nameList = Cache.getInstance().getSavedNicknames(playerUuid); - if (nameList == null) nameList = new ArrayList<>(); - if (nameList.size() >= ConfigHandler.getInstance().getMaxSaves()) { - return false; - } - Cache.getInstance().saveNickname(nick.nickname(), playerUuid); - return true; - } - - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, Player player) { - return null; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/Set.java b/src/main/java/simplexity/simplenicks/commands/Set.java deleted file mode 100644 index f2ec250..0000000 --- a/src/main/java/simplexity/simplenicks/commands/Set.java +++ /dev/null @@ -1,115 +0,0 @@ -package simplexity.simplenicks.commands; - -import org.bukkit.OfflinePlayer; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.LocaleHandler; -import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.Nickname; -import simplexity.simplenicks.util.Constants; -import simplexity.simplenicks.saving.NickHandler; - -import java.util.ArrayList; -import java.util.UUID; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -public class Set extends SubCommand { - Logger logger = SimpleNicks.getSimpleNicksLogger(); - - public Set(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - super(commandName, basicPermission, adminPermission, consoleRunNoPlayer); - } - - @Override - public void execute(CommandSender sender, Player player, String[] args, boolean adminCommand) { - - } - - - - - /*@Override - public void execute(CommandSender sender, Player player, String[] args, boolean adminCommand) { - if (!validArgsLength(args, 3)) { - return; - } - String nickname = args[2]; - nickname = processName(nickname, sender, player); - if (!passesChecks(sender, nickname, player)) { - return; - } - if (setPlayerNick(player, nickname)) { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedOther(), nickname)); - player.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getChangedByOther(), nickname)); - } else { - sender.sendMessage(parsedMessage(sender, player, LocaleHandler.getInstance().getInvalidTags(), nickname)); - } - } - - private boolean setPlayerNick(Player player, String nickString) { - if (nickString == null) { - return false; - } - UUID playerUuid = player.getUniqueId(); - //todo Checks for existing versions of this nick - //Cache.getInstance().nickInUseActiveStorage(nickString, playerUuid); - return Cache.getInstance().setActiveNickname(playerUuid, nickString); - } - - private String processName(String nickArg, CommandSender sender, Player player) { - if (sender.hasPermission(Constants.NICK_OTHERS_FULL)) return nickArg; - if (sender.hasPermission(Constants.NICK_OTHERS_BASIC)) { - return NickHandler.getInstance().cleanNonPermittedTags(sender, nickArg); - } - if (sender.hasPermission(Constants.NICK_OTHERS_RESTRICTIVE)) { - return NickHandler.getInstance().cleanNonPermittedTags(player, nickArg); - } - return null; - } - - private boolean passesChecks(CommandSender sender, String nickname, Player player) { - String strippedMessage = miniMessage.stripTags(nickname); - Pattern regexPattern = ConfigHandler.getInstance().getRegex(); - if (strippedMessage.length() > ConfigHandler.getInstance().getMaxLength() && !sender.hasPermission(Constants.NICK_LENGTH_BYPASS)) { - sender.sendMessage(parsedMessage(sender, null, LocaleHandler.getInstance().getInvalidNickLength(), "")); - return false; - } - if (!regexPattern.matcher(strippedMessage).matches() && !sender.hasPermission(Constants.NICK_REGEX_BYPASS)) { - sender.sendMessage(parsedMessage(sender, null, LocaleHandler.getInstance().getInvalidNick(), ConfigHandler.getInstance().getRegexString())); - return false; - } - OfflinePlayer playerToCheck = SimpleNicks.getInstance().getServer().getOfflinePlayer(strippedMessage); - if (!playerToCheck.hasPlayedBefore()) { - return true; - } - if (playerToCheck.getPlayer() == player) { - return true; - - } - if (!sender.hasPermission(Constants.NICK_USERNAME_BYPASS)) { - long lastSeen = playerToCheck.getLastSeen(); - long now = System.currentTimeMillis(); - long diff = now - lastSeen; - if (diff < ConfigHandler.getInstance().getUsernameProtectionTime()) { - sender.sendMessage(parsedMessage(sender, null, LocaleHandler.getInstance().getOtherPlayersUsername(), nickname)); - return false; - } - } - return true; - }*/ - - @Override - public ArrayList tabComplete(CommandSender sender, String[] args, @NotNull Player player) { - ArrayList savedNickNames = new ArrayList<>(); - for (Nickname nick : Cache.getInstance().getSavedNicknames(player.getUniqueId())) { - savedNickNames.add(nick.nickname()); - } - return savedNickNames; - } - -} diff --git a/src/main/java/simplexity/simplenicks/commands/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/SubCommand.java deleted file mode 100644 index 82c9d85..0000000 --- a/src/main/java/simplexity/simplenicks/commands/SubCommand.java +++ /dev/null @@ -1,70 +0,0 @@ -package simplexity.simplenicks.commands; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.Message; - -import java.util.ArrayList; - -public abstract class SubCommand { - public final String commandName; - public final Permission basicPermission; - public final Permission adminPermission; - public final boolean canRunWithoutPlayer; - public final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - public SubCommand(String commandName, Permission basicPermission, Permission adminPermission, boolean consoleRunNoPlayer) { - this.commandName = commandName; - this.basicPermission = basicPermission; - this.adminPermission = adminPermission; - this.canRunWithoutPlayer = consoleRunNoPlayer; - } - - public abstract void execute(CommandSender sender, Player player, String[] args, boolean adminCommand); - - public abstract ArrayList tabComplete(CommandSender sender, String[] args, Player player); - - public String getCommandName() { - return commandName; - } - - public Permission getBasicPermission() { - return basicPermission; - } - - public Permission getAdminPermission() { - return adminPermission; - } - - public boolean canRunWithoutPlayer() { - return canRunWithoutPlayer; - } - - public Component parsedMessage(CommandSender sender, Player player, String message, String value) { - Component senderName; - Component playerName; - if (sender == null) { - senderName = Component.empty(); - } else { - senderName = sender.name(); - } - if (player == null) { - playerName = Component.empty(); - } else { - playerName = player.name(); - } - return miniMessage.deserialize(message, - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), - Placeholder.component("initiator", senderName), - Placeholder.component("target", playerName), - Placeholder.parsed("value", value)); - } - - public boolean validArgsLength(String[] args, int minArgsLength) { - return args.length >= minArgsLength; - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java index 30de7b9..e300c9d 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java +++ b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java @@ -1,6 +1,5 @@ package simplexity.simplenicks.commands.admin; -import io.papermc.paper.command.brigadier.Commands; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -9,7 +8,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import simplexity.simplenicks.config.Message; -import simplexity.simplenicks.saving.NickHandler; +import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.util.Constants; import java.util.List; @@ -18,27 +18,70 @@ public class AdminNick implements TabExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { if (args.length < 2) { - sender.sendRichMessage(Message.NOT_ENOUGH_ARGS.getMessage()); + sender.sendRichMessage(Message.ERROR_NOT_ENOUGH_ARGS.getMessage()); return false; } + Player providedPlayer = validateProvidedPlayer(args[0], sender); + if (providedPlayer == null) return false; + String commandArg = args[1].toLowerCase(); + switch (commandArg) { + + } + + + return false; } + // /adminnick user set name + private void handleSet(CommandSender sender, Player target, String[] args){ + if (!sender.hasPermission(Constants.NICK_SET_OTHERS)) { + sender.sendRichMessage(Message.ERROR_NO_PERMISSION.getMessage()); + return; + } + if (args.length < 3) { + sender.sendRichMessage(""); + } + + + } + + + + @Nullable private Player validateProvidedPlayer(String string, CommandSender sender) { Player player = Bukkit.getPlayer(string); if (player != null) return player; - List playersFromName = NickHandler.getInstance().getOnlinePlayersByNickname(string); + List playersFromName = NickUtils.getInstance().getOnlinePlayersByNickname(string); if (playersFromName.isEmpty()) { sender.sendRichMessage( - Message.INVALID_PLAYER.getMessage() + Message.ERROR_INVALID_PLAYER.getMessage() ); return null; } if (playersFromName.size() > 1) { + sender.sendRichMessage( + Message.ERROR_MULTIPLE_PLAYERS_BY_THAT_NAME.getMessage() + ); + return null; + } + return playersFromName.getFirst(); + } + @Nullable + private String getPermissionProcessedNickname(String nickname, CommandSender sender, Player player){ + if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { + return nickname; + } + if (sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC)) { + return NickUtils.getInstance().cleanNonPermittedTags(sender, nickname); + } + if (sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE)) { + return NickUtils.getInstance().cleanNonPermittedTags(player, nickname); } + return null; } @Override diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index 24eba72..f034697 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -46,7 +46,7 @@ public void reloadConfig() { regexString = regexSetting; regex = Pattern.compile(regexSetting); } catch (PatternSyntaxException e) { - logger.severe(Message.INVALID_CONFIG_REGEX.getMessage()); + logger.severe(Message.ERROR_INVALID_CONFIG_REGEX.getMessage()); } mySql = config.getBoolean("mysql.enabled", false); mySqlIp = config.getString("mysql.ip", "localhost:3306"); diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index fb2cd73..92311a5 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -5,31 +5,32 @@ public enum Message { HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), CONFIG_RELOADED("plugin.config-reloaded", "SimpleNicks config and locale reloaded"), - INVALID_COMMAND("error.invalid.command", "Invalid command."), - INVALID_PLAYER("error.invalid.player", "Invalid player specified"), - INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), - INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= "), - INVALID_TAGS("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"), - INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), - NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), - TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), - NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), - DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given username."), - SAVE_FAILURE("error.nickname.save-failure", "Failed to save current username."), - TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), - OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), - NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), - NO_PERMISSION("error.no-permission", "You do not have permission to run this command"), - MUST_BE_PLAYER("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"), - MULTIPLE_PLAYERS_BY_THAT_NAME("error.multiple-players-by-that-name", "There are multiple online players by that name, please try using the actual username."), CHANGED_SELF("nick.changed.self", "Changed your nickname to !"), CHANGED_OTHER("nick.changed.other", "Changed 's nickname to "), CHANGED_BY_OTHER("nick.changed.by-other", " changed your nickname to !"), RESET_SELF("nick.reset.self", "Reset your nickname!"), RESET_OTHER("nick.reset.other", "Reset 's nickname."), RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), - SAVE_NICK("nick.save", "Success! The nickname has been saved for future use"), - DELETE_NICK("nick.delete", "The nickname has been successfully removed from your saved names"); + SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), + DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), + ERROR_INVALID_COMMAND("error.invalid.command", "Invalid command."), + ERROR_INVALID_PLAYER("error.invalid.player", "Invalid player specified"), + ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), + ERROR_INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= "), + ERROR_INVALID_TAGS("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"), + ERROR_INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), + ERROR_NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), + ERROR_TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), + ERROR_NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), + ERROR_DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given username."), + ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current username."), + ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), + ERROR_OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), + ERROR_NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), + ERROR_NO_PERMISSION("error.no-permission", "You do not have permission to run this command"), + ERROR_MUST_BE_PLAYER("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"), + ERROR_MULTIPLE_PLAYERS_BY_THAT_NAME("error.multiple-players-by-that-name", "There are multiple online players by that name, please try using the actual username."), + ; private final String path; diff --git a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java index d505450..f5bb7cd 100644 --- a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java +++ b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java @@ -5,7 +5,6 @@ import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.NickHandler; import simplexity.simplenicks.saving.Nickname; public class SNExpansion extends PlaceholderExpansion { diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index 13eaf3b..8fda50d 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -5,7 +5,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import simplexity.simplenicks.saving.Cache; -import simplexity.simplenicks.saving.NickHandler; +import simplexity.simplenicks.logic.NickUtils; import java.util.UUID; @@ -15,6 +15,6 @@ public void onPlayerLogin(PlayerJoinEvent joinEvent) { UUID playerUuid = joinEvent.getPlayer().getUniqueId(); Cache.getInstance().loadCurrentNickname(playerUuid); Cache.getInstance().loadSavedNicknames(playerUuid); - NickHandler.getInstance().refreshNickname(playerUuid); + NickUtils.getInstance().refreshNickname(playerUuid); } } diff --git a/src/main/java/simplexity/simplenicks/saving/NickHandler.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java similarity index 83% rename from src/main/java/simplexity/simplenicks/saving/NickHandler.java rename to src/main/java/simplexity/simplenicks/logic/NickUtils.java index 578c63b..7617306 100644 --- a/src/main/java/simplexity/simplenicks/saving/NickHandler.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.saving; +package simplexity.simplenicks.logic; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -9,26 +9,31 @@ import org.bukkit.entity.Player; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.saving.AbstractSaving; +import simplexity.simplenicks.saving.Cache; +import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.TagPermission; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @SuppressWarnings("UnusedReturnValue") -public class NickHandler { +public class NickUtils { - private static NickHandler instance; + private static NickUtils instance; private AbstractSaving saveHandler; private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - private NickHandler() { + private NickUtils() { } - public static NickHandler getInstance() { + public static NickUtils getInstance() { if (instance != null) return instance; - instance = new NickHandler(); + instance = new NickUtils(); return instance; } @@ -92,4 +97,12 @@ public List getOfflinePlayersByNickname(String nickname) { } return playersByNick; } + + public boolean passesRegexCheck(String normalizedNick) { + Pattern configRegex = ConfigHandler.getInstance().getRegex(); + Matcher matcher = configRegex.matcher(normalizedNick); + return !matcher.find(); + } + + } diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index bdeb008..b8e2b97 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -1,6 +1,7 @@ package simplexity.simplenicks.saving; import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; import simplexity.simplenicks.SimpleNicks; import javax.annotation.Nullable; @@ -24,29 +25,54 @@ public static Cache getInstance() { private final HashMap activeNicknames = new HashMap<>(); private final HashMap> savedNicknames = new HashMap<>(); + /** + * Loads the player's active nickname from SQL and into cache + * @param uuid player UUID + */ + public void loadCurrentNickname(UUID uuid) { Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid); if (currentNick == null) return; activeNicknames.put(uuid, currentNick); } + /** + * Gets the active nickname from cache, + * @param uuid Player uuid + * @return Nickname player has set, null if no nickname is set + */ @Nullable public Nickname getActiveNickname(UUID uuid) { if (activeNicknames.containsKey(uuid)) return activeNicknames.get(uuid); return null; } + /** + * Loads a player's saved nicknames into the cache from SQL + * @param uuid Player's UUID + */ public void loadSavedNicknames(UUID uuid) { List savedNames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); if (savedNames == null || savedNames.isEmpty()) return; savedNicknames.put(uuid, savedNames); } + /** + * Gets the saved nicknames from the cache + * @param uuid Player UUID + * @return List - if no nicks exist, returns empty list + */ public List getSavedNicknames(UUID uuid) { if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid); return new ArrayList<>(); } + /** + * Sets the active nickname for the player + * @param uuid Player UUID + * @param nickname Version of the nickname with tags included + * @return boolean - whether nickname was successfully set or not + */ public boolean setActiveNickname(UUID uuid, String nickname) { String normalizedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, normalizedNick); @@ -56,7 +82,7 @@ public boolean setActiveNickname(UUID uuid, String nickname) { return true; } - public boolean deleteSavedNickname(String nickname, UUID uuid) { + public boolean deleteSavedNickname(UUID uuid, String nickname) { boolean sqlDeleted = SqlHandler.getInstance().deleteNickname(uuid, nickname); if (!sqlDeleted) return false; if (!savedNicknames.containsKey(uuid)) return false; @@ -79,17 +105,8 @@ public List getUuidOfNormalizedName(String nickname) { return uuids; } - public boolean userAlreadySavedThis(String name, UUID uuid) { - return SqlHandler.getInstance().userAlreadySavedThisName(uuid, name); - } - - public boolean nickInUseActiveStorage(String name, UUID uuid) { - String strippedNick = miniMessage.stripTags(name); - return SqlHandler.getInstance().nickAlreadyExists(strippedNick, uuid); - } - - public boolean nickInUseOnlinePlayers(String name, UUID uuid) { - String strippedNick = miniMessage.stripTags(name); + public boolean nickInUseOnlinePlayers(UUID uuid, String nickname) { + String strippedNick = miniMessage.stripTags(nickname); for (UUID playerUuid : activeNicknames.keySet()) { if (playerUuid.equals(uuid)) continue; if (activeNicknames.get(playerUuid).normalizedNickname().equals(strippedNick)) return true; @@ -97,19 +114,26 @@ public boolean nickInUseOnlinePlayers(String name, UUID uuid) { return false; } - public boolean saveNickname(String name, UUID uuid) { - String strippedNick = miniMessage.stripTags(name); - Nickname nick = new Nickname(name, strippedNick); + public boolean saveNickname(UUID uuid, String nickname) { + String strippedNick = miniMessage.stripTags(nickname); + Nickname nick = new Nickname(nickname, strippedNick); List userSavedNicknames = getSavedNicknames(uuid); userSavedNicknames.add(nick); - boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, name, strippedNick); + boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, nickname, strippedNick); if (!savedToSql) return false; savedNicknames.put(uuid, userSavedNicknames); return true; } + public int getSavedNickCount(UUID uuid){ + if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid).size(); + return 0; + } + public void removePlayerFromCache(UUID uuid) { savedNicknames.remove(uuid); activeNicknames.remove(uuid); } + + } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index cf97b63..ceb06ec 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -71,7 +71,7 @@ REFERENCES players(uuid) } - public boolean nickAlreadyExists(String normalizedName, UUID uuidToExclude) { + public boolean nickAlreadyExists(UUID uuidToExclude, String normalizedName) { String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? AND uuid != ? LIMIT 1"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index 1e1bab6..5e8ebc0 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -4,12 +4,14 @@ public class Constants { public static Permission NICK_OTHERS_COMMAND = new Permission("simplenick.admin"); - public static Permission NICK_OTHERS_RESTRICTIVE = new Permission("simplenick.admin.restrictive"); - public static Permission NICK_OTHERS_BASIC = new Permission("simplenick.admin.basic"); - public static Permission NICK_OTHERS_FULL = new Permission("simplenick.admin.full"); + public static Permission NICK_SET_OTHERS = new Permission("simplenick.admin.set"); + public static Permission NICK_SET_OTHERS_RESTRICTIVE = new Permission("simplenick.admin.set.restrictive"); + public static Permission NICK_SET_OTHERS_BASIC = new Permission("simplenick.admin.set.basic"); + public static Permission NICK_SET_OTHERS_FULL = new Permission("simplenick.admin.set.full"); public static Permission NICK_RESET_OTHERS = new Permission("simplenick.admin.reset"); - public static Permission NICK_OTHERS_SAVE = new Permission("simplenick.admin.save"); - public static Permission NICK_OTHERS_DELETE = new Permission("simplenick.admin.delete"); + public static Permission NICK_SAVE_OTHERS = new Permission("simplenick.admin.save"); + public static Permission NICK_DELETE_OTHERS = new Permission("simplenick.admin.delete"); + public static Permission NICK_GET_OTHERS = new Permission("simplenick.admin.get"); public static Permission NICK_COMMAND = new Permission("simplenick.nick"); public static Permission NICK_RESET = new Permission("simplenick.nick.reset"); public static Permission NICK_SAVE = new Permission("simplenick.nick.save"); From 5ebaa2e5410f99bdde4165ed7ee6ac5791c52c4a Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sat, 10 May 2025 15:06:27 -0700 Subject: [PATCH 13/40] this is taking so long --- .../simplexity/simplenicks/SimpleNicks.java | 2 ++ .../simplenicks/commands/admin/AdminNick.java | 33 ++++++++++++++----- .../simplenicks/config/Message.java | 2 ++ src/main/resources/plugin.yml | 3 ++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index beb8ac4..28a7b3e 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -3,6 +3,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import simplexity.simplenicks.commands.admin.AdminNick; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.hooks.SNExpansion; import simplexity.simplenicks.listener.LoginListener; @@ -34,6 +35,7 @@ public void onEnable() { if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); } + getCommand("adminnick").setExecutor(new AdminNick()); instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); configReload(); SqlHandler.getInstance().setupConfig(); diff --git a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java index e300c9d..7757390 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java +++ b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java @@ -1,12 +1,15 @@ package simplexity.simplenicks.commands.admin; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.config.Message; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.util.Constants; @@ -24,28 +27,39 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command Player providedPlayer = validateProvidedPlayer(args[0], sender); if (providedPlayer == null) return false; String commandArg = args[1].toLowerCase(); - switch (commandArg) { - + if (commandArg.equals("set")) { + handleSet(sender, providedPlayer, args); } - return false; } // /adminnick user set name - private void handleSet(CommandSender sender, Player target, String[] args){ + private void handleSet(CommandSender sender, OfflinePlayer target, String[] args){ if (!sender.hasPermission(Constants.NICK_SET_OTHERS)) { sender.sendRichMessage(Message.ERROR_NO_PERMISSION.getMessage()); return; } if (args.length < 3) { - sender.sendRichMessage(""); + sender.sendRichMessage(Message.ERROR_NOT_ENOUGH_ARGS.getMessage()); + return; } - - + String nickname = getPermissionProcessedNickname(args[2], sender, target); + if (nickname == null) { + sender.sendRichMessage(Message.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage()); + return; + } + boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, nickname); + if (!setSuccessfully) { + sender.sendRichMessage(Message.ERROR_SET_FAILURE.getMessage()); + return; + } + sender.sendRichMessage(Message.CHANGED_OTHER.getMessage(), + Placeholder.parsed("target", target.getName()), + Placeholder.parsed("value", nickname)); } @@ -71,7 +85,7 @@ private Player validateProvidedPlayer(String string, CommandSender sender) { } @Nullable - private String getPermissionProcessedNickname(String nickname, CommandSender sender, Player player){ + private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player){ if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { return nickname; } @@ -79,7 +93,8 @@ private String getPermissionProcessedNickname(String nickname, CommandSender sen return NickUtils.getInstance().cleanNonPermittedTags(sender, nickname); } if (sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE)) { - return NickUtils.getInstance().cleanNonPermittedTags(player, nickname); + if (!(player instanceof Player onlinePlayer)) return null; + return NickUtils.getInstance().cleanNonPermittedTags(onlinePlayer, nickname); } return null; } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index 92311a5..2b716b0 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -22,7 +22,9 @@ public enum Message { ERROR_NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), ERROR_TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), ERROR_NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), + ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS("error.nickname.cannot-access-permissions", "Unable to process. If you are attempting to use a command with the 'restrictive' permission and the other user is offline, the server is unable to access the user's permissions while the user is offline."), ERROR_DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given username."), + ERROR_SET_FAILURE("error.nickname.set-failure", "Failed to set the given username."), ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current username."), ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), ERROR_OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c3d96c3..1e7f240 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -7,6 +7,9 @@ description: "A simple plugin to allow players to set and reset nicknames." softdepend: - PlaceholderAPI commands: + adminnick: + description: e + permission: simplenick.admin nick: description: "Base command for SimpleNicks, Admin permission required to alter other's names." aliases: [simplenicks, simplenick, snick] From 098c48c96eb6d02fb4855be8dd6880f721cf7a53 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sun, 11 May 2025 13:57:10 -0700 Subject: [PATCH 14/40] committing basic changes --- .../simplenicks/commands/admin/AdminNick.java | 69 ++++++++++++++----- .../simplenicks/config/Message.java | 1 + 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java index 7757390..c74cbe0 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java +++ b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java @@ -1,5 +1,7 @@ package simplexity.simplenicks.commands.admin; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -9,6 +11,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.config.Message; import simplexity.simplenicks.logic.NickUtils; @@ -18,13 +21,21 @@ public class AdminNick implements TabExecutor { + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + /* + /anick user subcommand name + /anick subcommand user name + /anick subcommand name user + */ + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { if (args.length < 2) { sender.sendRichMessage(Message.ERROR_NOT_ENOUGH_ARGS.getMessage()); return false; } - Player providedPlayer = validateProvidedPlayer(args[0], sender); + OfflinePlayer providedPlayer = validateProvidedPlayer(args[0], sender); if (providedPlayer == null) return false; String commandArg = args[1].toLowerCase(); if (commandArg.equals("set")) { @@ -32,13 +43,11 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } - - return false; } // /adminnick user set name - private void handleSet(CommandSender sender, OfflinePlayer target, String[] args){ + private void handleSet(CommandSender sender, OfflinePlayer target, String[] args) { if (!sender.hasPermission(Constants.NICK_SET_OTHERS)) { sender.sendRichMessage(Message.ERROR_NO_PERMISSION.getMessage()); return; @@ -57,35 +66,39 @@ private void handleSet(CommandSender sender, OfflinePlayer target, String[] args sender.sendRichMessage(Message.ERROR_SET_FAILURE.getMessage()); return; } - sender.sendRichMessage(Message.CHANGED_OTHER.getMessage(), - Placeholder.parsed("target", target.getName()), - Placeholder.parsed("value", nickname)); + sender.sendMessage(parseMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); + if (target instanceof Player onlineTarget) { + onlineTarget.sendMessage(parseMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); + } } - @Nullable - private Player validateProvidedPlayer(String string, CommandSender sender) { - Player player = Bukkit.getPlayer(string); - if (player != null) return player; - List playersFromName = NickUtils.getInstance().getOnlinePlayersByNickname(string); - if (playersFromName.isEmpty()) { - sender.sendRichMessage( - Message.ERROR_INVALID_PLAYER.getMessage() - ); - return null; + private OfflinePlayer validateProvidedPlayer(String string, CommandSender sender) { + OfflinePlayer player = Bukkit.getOfflinePlayer(string); + if (player.isOnline()) return player; + if (player.hasPlayedBefore()) { + return player; } + // player is no longer valid, check the online players' nicknames against the provided string. + List playersFromName = NickUtils.getInstance().getOnlinePlayersByNickname(string); if (playersFromName.size() > 1) { sender.sendRichMessage( Message.ERROR_MULTIPLE_PLAYERS_BY_THAT_NAME.getMessage() ); return null; } - return playersFromName.getFirst(); + if (playersFromName.size() == 1) { + return playersFromName.getFirst(); + } + sender.sendRichMessage( + Message.ERROR_INVALID_PLAYER.getMessage() + ); + return null; } @Nullable - private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player){ + private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player) { if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { return nickname; } @@ -99,6 +112,24 @@ private String getPermissionProcessedNickname(String nickname, CommandSender sen return null; } + private Component parseMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { + Component initiatorName; + String targetUserName = target.getName(); + if (targetUserName == null) { + targetUserName = "[Username not found, idk how but you got this error.]"; + } + if (initiator instanceof Player playerInitiator) { + initiatorName = playerInitiator.displayName(); + } else { + initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); + } + return miniMessage.deserialize(message, + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("value", value), + Placeholder.component("initiator", initiatorName), + Placeholder.parsed("target", targetUserName)); + } + @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) { return List.of(); diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index 2b716b0..e12233a 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -5,6 +5,7 @@ public enum Message { HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), CONFIG_RELOADED("plugin.config-reloaded", "SimpleNicks config and locale reloaded"), + SERVER_DISPLAY_NAME("plugin.server-display-name", "[Server]"), CHANGED_SELF("nick.changed.self", "Changed your nickname to !"), CHANGED_OTHER("nick.changed.other", "Changed 's nickname to "), CHANGED_BY_OTHER("nick.changed.by-other", " changed your nickname to !"), From 5a9319d41ea9835c4cd0c5d4ee23ed230d3826ab Mon Sep 17 00:00:00 2001 From: Peashooter101 Date: Sun, 11 May 2025 18:55:06 -0500 Subject: [PATCH 15/40] Brig save and set commands --- pom.xml | 2 +- .../simplexity/simplenicks/SimpleNicks.java | 6 ++ .../commands/admin/NicknameCommand.java | 23 ++++++ .../commands/arguments/NicknameArgument.java | 82 +++++++++++++++++++ .../commands/subcommands/SaveSubCommand.java | 35 ++++++++ .../commands/subcommands/SetSubCommand.java | 38 +++++++++ .../simplenicks/util/Constants.java | 1 + 7 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java diff --git a/pom.xml b/pom.xml index 19207f6..996715d 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ io.papermc.paper paper-api - 1.21-R0.1-SNAPSHOT + 1.21.5-R0.1-SNAPSHOT provided diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 28a7b3e..c5a5958 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -1,9 +1,11 @@ package simplexity.simplenicks; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import simplexity.simplenicks.commands.admin.AdminNick; +import simplexity.simplenicks.commands.admin.NicknameCommand; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.hooks.SNExpansion; import simplexity.simplenicks.listener.LoginListener; @@ -21,6 +23,7 @@ PlaceholderAPI placeholder for before parsing, and after */ +@SuppressWarnings("UnstableApiUsage") public final class SimpleNicks extends JavaPlugin { private static final MiniMessage miniMessage = MiniMessage.miniMessage(); @@ -40,6 +43,9 @@ public void onEnable() { configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); + this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { + commands.registrar().register(NicknameCommand.createCommand().build()); + }); } public static MiniMessage getMiniMessage() { diff --git a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java new file mode 100644 index 0000000..2dd0d07 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java @@ -0,0 +1,23 @@ +package simplexity.simplenicks.commands.admin; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import simplexity.simplenicks.commands.subcommands.SaveSubCommand; +import simplexity.simplenicks.commands.subcommands.SetSubCommand; + +@SuppressWarnings("UnstableApiUsage") +public class NicknameCommand { + + public static LiteralArgumentBuilder createCommand() { + LiteralArgumentBuilder builder = Commands.literal("nick"); + + SetSubCommand.subcommandTo(builder); + SaveSubCommand.subcommandTo(builder); + + return builder; + } + + + +} diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java new file mode 100644 index 0000000..c9cf9fd --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -0,0 +1,82 @@ +package simplexity.simplenicks.commands.arguments; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +import java.util.concurrent.CompletableFuture; + +@SuppressWarnings("UnstableApiUsage") +public class NicknameArgument implements CustomArgumentType { + + private static final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + Component.text("Nicknames must be <=" + ConfigHandler.getInstance().getMaxLength() + " after tags are stripped. Your nickname stripped is: " + nickname) + ) + ); + + private static final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + Component.text("The nickname " + nickname + " is invalid.") + ) + ); + + @Override + public @NotNull Nickname parse(@NotNull StringReader stringReader) throws CommandSyntaxException { + throw new UnsupportedOperationException("This method will never be called."); + } + + @Override + public @NotNull Nickname parse(final StringReader reader, final @NotNull S source) throws CommandSyntaxException { + String nickname = reader.readQuotedString(); + String normalizedNickname = SimpleNicks.getMiniMessage().stripTags(nickname); + Player player = (Player) ((CommandSourceStack) source).getSender(); + if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && normalizedNickname.length() > ConfigHandler.getInstance().getMaxLength()) throw ERROR_LENGTH.create(normalizedNickname); + if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(normalizedNickname).matches()) throw ERROR_REGEX.create(normalizedNickname); + return new Nickname(nickname, normalizedNickname); + } + + @Override + public @NotNull ArgumentType getNativeType() { + return StringArgumentType.string(); + } + + @Override + public @NotNull CompletableFuture listSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { + CommandSourceStack css = (CommandSourceStack) context.getSource(); + OfflinePlayer player = (OfflinePlayer) css.getSender(); + MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + for (Nickname nickname : NicknameProcessor.getInstance().getSavedNicknames(player)) { + String suggestion = "\"" + nickname.nickname() + "\""; + String suggestionStripped = "\"" + nickname.normalizedNickname() + "\""; + if (suggestionStripped.toLowerCase().contains(builder.getRemainingLowerCase()) || suggestion.toLowerCase().contains(builder.getRemainingLowerCase())) { + builder.suggest( + suggestion, + MessageComponentSerializer.message().serialize( + miniMessage.deserialize("Preview: " + nickname.nickname()) + ) + ); + } + } + return builder.buildFuture(); + } + +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java new file mode 100644 index 0000000..eb26625 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java @@ -0,0 +1,35 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class SaveSubCommand { + + public static void subcommandTo(LiteralArgumentBuilder root) { + + root.then(Commands.literal("save").requires(SaveSubCommand::canExecute) + .executes(SaveSubCommand::execute) + ); + + } + + public static int execute(CommandContext ctx) { + OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); + Nickname nickname = NicknameProcessor.getInstance().getCurrentNickname(player); + NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + return Command.SINGLE_SUCCESS; + } + + public static boolean canExecute(CommandSourceStack css) { + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SAVE); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java new file mode 100644 index 0000000..774ae9d --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java @@ -0,0 +1,38 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class SetSubCommand { + + public static void subcommandTo(LiteralArgumentBuilder root) { + + root.then(Commands.literal("set").requires(SetSubCommand::canExecute) + .then(Commands.argument("nickname", new NicknameArgument()) + .executes(SetSubCommand::execute) + ) + ); + + } + + public static int execute(CommandContext ctx) { + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); + return Command.SINGLE_SUCCESS; + } + + public static boolean canExecute(CommandSourceStack css) { + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SET); + } + +} diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index 5e8ebc0..c01736d 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -13,6 +13,7 @@ public class Constants { public static Permission NICK_DELETE_OTHERS = new Permission("simplenick.admin.delete"); public static Permission NICK_GET_OTHERS = new Permission("simplenick.admin.get"); public static Permission NICK_COMMAND = new Permission("simplenick.nick"); + public static Permission NICK_SET = new Permission("simplenick.nick.set"); public static Permission NICK_RESET = new Permission("simplenick.nick.reset"); public static Permission NICK_SAVE = new Permission("simplenick.nick.save"); public static Permission NICK_DELETE = new Permission("simplenick.nick.delete"); From c9dafd391db0abc55be50b3d4106ab6d3815e7c5 Mon Sep 17 00:00:00 2001 From: Peashooter101 Date: Mon, 12 May 2025 03:23:58 -0500 Subject: [PATCH 16/40] Abstract SubCommand, Brig reset and delete commands --- .../commands/admin/NicknameCommand.java | 8 ++- .../commands/arguments/NicknameArgument.java | 37 ++++--------- .../subcommands/DeleteSubCommand.java | 41 ++++++++++++++ .../commands/subcommands/ResetSubCommand.java | 36 +++++++++++++ .../commands/subcommands/SaveSubCommand.java | 17 +++--- .../commands/subcommands/SetSubCommand.java | 41 +++++++++++--- .../commands/subcommands/SubCommand.java | 54 +++++++++++++++++++ 7 files changed, 190 insertions(+), 44 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java diff --git a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java index 2dd0d07..ecf1abf 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java @@ -3,6 +3,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import simplexity.simplenicks.commands.subcommands.DeleteSubCommand; +import simplexity.simplenicks.commands.subcommands.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.SaveSubCommand; import simplexity.simplenicks.commands.subcommands.SetSubCommand; @@ -12,8 +14,10 @@ public class NicknameCommand { public static LiteralArgumentBuilder createCommand() { LiteralArgumentBuilder builder = Commands.literal("nick"); - SetSubCommand.subcommandTo(builder); - SaveSubCommand.subcommandTo(builder); + new SetSubCommand().subcommandTo(builder); + new SaveSubCommand().subcommandTo(builder); + new ResetSubCommand().subcommandTo(builder); + new DeleteSubCommand().subcommandTo(builder); return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java index c9cf9fd..7aa1d38 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -5,52 +5,27 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.MessageComponentSerializer; import io.papermc.paper.command.brigadier.argument.CustomArgumentType; -import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; -import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.saving.Nickname; -import simplexity.simplenicks.util.Constants; import java.util.concurrent.CompletableFuture; @SuppressWarnings("UnstableApiUsage") public class NicknameArgument implements CustomArgumentType { - private static final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( - nickname -> MessageComponentSerializer.message().serialize( - Component.text("Nicknames must be <=" + ConfigHandler.getInstance().getMaxLength() + " after tags are stripped. Your nickname stripped is: " + nickname) - ) - ); - - private static final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( - nickname -> MessageComponentSerializer.message().serialize( - Component.text("The nickname " + nickname + " is invalid.") - ) - ); - - @Override - public @NotNull Nickname parse(@NotNull StringReader stringReader) throws CommandSyntaxException { - throw new UnsupportedOperationException("This method will never be called."); - } - @Override - public @NotNull Nickname parse(final StringReader reader, final @NotNull S source) throws CommandSyntaxException { + public @NotNull Nickname parse(@NotNull StringReader reader) throws CommandSyntaxException { String nickname = reader.readQuotedString(); String normalizedNickname = SimpleNicks.getMiniMessage().stripTags(nickname); - Player player = (Player) ((CommandSourceStack) source).getSender(); - if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && normalizedNickname.length() > ConfigHandler.getInstance().getMaxLength()) throw ERROR_LENGTH.create(normalizedNickname); - if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(normalizedNickname).matches()) throw ERROR_REGEX.create(normalizedNickname); return new Nickname(nickname, normalizedNickname); } @@ -59,8 +34,14 @@ public class NicknameArgument implements CustomArgumentType { return StringArgumentType.string(); } - @Override - public @NotNull CompletableFuture listSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { + /** + * Provides suggestions for nicknames based on the CommandSender + * @param context Command context + * @param builder SuggestionsBuilder object for adding suggestions to + * @return Suggestions as a CompletableFuture + * @param For Paper, generally CommandSourceStack + */ + public @NotNull CompletableFuture suggestOwnNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { CommandSourceStack css = (CommandSourceStack) context.getSource(); OfflinePlayer player = (OfflinePlayer) css.getSender(); MiniMessage miniMessage = SimpleNicks.getMiniMessage(); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java new file mode 100644 index 0000000..e8dfd98 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java @@ -0,0 +1,41 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class DeleteSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + + NicknameArgument argument = new NicknameArgument(); + + root.then(Commands.literal("delete").requires(this::canExecute) + .then(Commands.argument("nickname", argument) + .suggests(argument::suggestOwnNicknames) + .executes(this::execute)) + ); + + } + + @Override + public int execute(@NotNull CommandContext ctx) { + OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); + NicknameProcessor.getInstance().deleteNickname(player,""); + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_DELETE); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java new file mode 100644 index 0000000..a776946 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java @@ -0,0 +1,36 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class ResetSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + + root.then(Commands.literal("reset").requires(this::canExecute) + .executes(this::execute) + ); + + } + + @Override + public int execute(@NotNull CommandContext ctx) { + OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); + NicknameProcessor.getInstance().resetNickname(player); + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_RESET); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java index eb26625..0ad24f3 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java @@ -7,29 +7,32 @@ import io.papermc.paper.command.brigadier.Commands; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") -public class SaveSubCommand { +public class SaveSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder root) { - public static void subcommandTo(LiteralArgumentBuilder root) { - - root.then(Commands.literal("save").requires(SaveSubCommand::canExecute) - .executes(SaveSubCommand::execute) + root.then(Commands.literal("save").requires(this::canExecute) + .executes(this::execute) ); } - public static int execute(CommandContext ctx) { + @Override + public int execute(@NotNull CommandContext ctx) { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); Nickname nickname = NicknameProcessor.getInstance().getCurrentNickname(player); NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); return Command.SINGLE_SUCCESS; } - public static boolean canExecute(CommandSourceStack css) { + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SAVE); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java index 774ae9d..102a2a2 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java @@ -3,35 +3,62 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import net.kyori.adventure.text.Component; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") -public class SetSubCommand { +public class SetSubCommand implements SubCommand{ - public static void subcommandTo(LiteralArgumentBuilder root) { + private final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + Component.text("Nicknames must be <=" + ConfigHandler.getInstance().getMaxLength() + " characters after tags are stripped.\nYour nickname stripped is:\n" + nickname) + ) + ); - root.then(Commands.literal("set").requires(SetSubCommand::canExecute) - .then(Commands.argument("nickname", new NicknameArgument()) - .executes(SetSubCommand::execute) + private final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + Component.text("The nickname " + nickname + " is invalid.") + ) + ); + + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + + NicknameArgument argument = new NicknameArgument(); + + root.then(Commands.literal("set").requires(this::canExecute) + .then(Commands.argument("nickname", argument) + .suggests(argument::suggestOwnNicknames) + .executes(this::execute) ) ); } - public static int execute(CommandContext ctx) { + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { Nickname nickname = ctx.getArgument("nickname", Nickname.class); + Player player = (Player) ctx.getSource().getSender(); + if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) throw ERROR_LENGTH.create(nickname.normalizedNickname()); + if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) throw ERROR_REGEX.create(nickname.normalizedNickname()); NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); return Command.SINGLE_SUCCESS; } - public static boolean canExecute(CommandSourceStack css) { + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SET); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java new file mode 100644 index 0000000..725e827 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java @@ -0,0 +1,54 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.apache.commons.lang3.NotImplementedException; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; + +@SuppressWarnings("UnstableApiUsage") +public interface SubCommand { + + /** + * Attaches this subcommand to the given root. + * @param root Root of the command builder + */ + void subcommandTo(@NotNull LiteralArgumentBuilder root); + + /** + * Defines the execution logic for this command. + * @param ctx CommandSourceStack context + * @return 1 indicating Success + * @throws CommandSyntaxException On failure + */ + int execute(@NotNull CommandContext ctx) throws CommandSyntaxException; + + /** + * Defines the "can use" logic.
+ * ie: Is a player? Has permission? + * @param css CommandSourceStack + * @return true if the command can executed, false otherwise + */ + boolean canExecute(@NotNull CommandSourceStack css); + + /** + * Defines suggestions that can be provided to the client.
+ * This is not necessary for every command.
+ * This function can be defined elsewhere and method referenced instead of using this interface.
+ * ie: nicknameArg::suggestOwnNicknames + * @param context Command context + * @param builder SuggestionsBuilder object for adding suggestions to + * @return Suggestions as a CompletableFuture + * @param For Paper, generally CommandSourceStack + */ + @SuppressWarnings("unused") + default @NotNull CompletableFuture listSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { + throw new NotImplementedException("listSuggestions was used, but not implemented."); + } + +} From 7072f2958f6181d370e3e9a5c54ae7e999da6d67 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Mon, 12 May 2025 13:20:01 -0700 Subject: [PATCH 17/40] Add leave listener, fix delete subcommand --- .../simplexity/simplenicks/SimpleNicks.java | 2 ++ .../commands/subcommands/DeleteSubCommand.java | 7 +++++-- .../simplenicks/listener/LeaveListener.java | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/listener/LeaveListener.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index c5a5958..92efec0 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -8,6 +8,7 @@ import simplexity.simplenicks.commands.admin.NicknameCommand; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.hooks.SNExpansion; +import simplexity.simplenicks.listener.LeaveListener; import simplexity.simplenicks.listener.LoginListener; import simplexity.simplenicks.saving.SqlHandler; @@ -40,6 +41,7 @@ public void onEnable() { } getCommand("adminnick").setExecutor(new AdminNick()); instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); + instance.getServer().getPluginManager().registerEvents(new LeaveListener(), this); configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java index e8dfd98..7b3110e 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -30,8 +31,10 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo @Override public int execute(@NotNull CommandContext ctx) { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); - NicknameProcessor.getInstance().deleteNickname(player,""); - return Command.SINGLE_SUCCESS; + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.nickname()); + if (deleted) return Command.SINGLE_SUCCESS; + return 0; } @Override diff --git a/src/main/java/simplexity/simplenicks/listener/LeaveListener.java b/src/main/java/simplexity/simplenicks/listener/LeaveListener.java new file mode 100644 index 0000000..cbde78f --- /dev/null +++ b/src/main/java/simplexity/simplenicks/listener/LeaveListener.java @@ -0,0 +1,17 @@ +package simplexity.simplenicks.listener; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; +import simplexity.simplenicks.saving.Cache; + +import java.util.UUID; + +public class LeaveListener implements Listener { + + @EventHandler + public void onPlayerLeave(PlayerQuitEvent quitEvent) { + UUID playerUuid = quitEvent.getPlayer().getUniqueId(); + Cache.getInstance().removePlayerFromCache(playerUuid); + } +} From 6ce4e38cb6a8d984c3c9205ebb7076c9b5685cad Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Mon, 12 May 2025 14:57:36 -0700 Subject: [PATCH 18/40] Implement more feedback messages --- .../commands/NicknameProcessor.java | 2 ++ .../subcommands/DeleteSubCommand.java | 30 +++++++++++++++++-- .../commands/subcommands/ResetSubCommand.java | 2 ++ .../commands/subcommands/SaveSubCommand.java | 23 +++++++++++++- .../commands/subcommands/SetSubCommand.java | 22 ++++++++++++-- .../commands/subcommands/SubCommand.java | 27 ++++++++++++++++- .../simplenicks/config/Message.java | 8 ++--- 7 files changed, 102 insertions(+), 12 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index 56f5b33..fee67d8 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -8,6 +8,7 @@ import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.saving.SqlHandler; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -83,6 +84,7 @@ public List getSavedNicknames(OfflinePlayer player) { return nicks; } + @Nullable public Nickname getCurrentNickname(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java index 7b3110e..e50a8f5 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java @@ -3,18 +3,37 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") public class DeleteSubCommand implements SubCommand { + + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + private final SimpleCommandExceptionType ERROR_CANNOT_DELETE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_DELETE_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + @Override public void subcommandTo(@NotNull LiteralArgumentBuilder root) { @@ -29,14 +48,19 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo } @Override - public int execute(@NotNull CommandContext ctx) { + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.nickname()); - if (deleted) return Command.SINGLE_SUCCESS; - return 0; + if (deleted) { + if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.DELETE_NICK, nickname); + return Command.SINGLE_SUCCESS; + } + throw ERROR_CANNOT_DELETE.create(); } + + @Override public boolean canExecute(@NotNull CommandSourceStack css) { return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_DELETE); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java index a776946..70133cb 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java @@ -9,6 +9,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.config.Message; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -26,6 +27,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo public int execute(@NotNull CommandContext ctx) { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); NicknameProcessor.getInstance().resetNickname(player); + if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.RESET_SELF, null); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java index 0ad24f3..e3166d5 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java @@ -3,17 +3,36 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") public class SaveSubCommand implements SubCommand { + + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + private final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_SAVE_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + @Override public void subcommandTo(@NotNull LiteralArgumentBuilder root) { @@ -24,10 +43,12 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo } @Override - public int execute(@NotNull CommandContext ctx) { + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); Nickname nickname = NicknameProcessor.getInstance().getCurrentNickname(player); + if (nickname == null) throw ERROR_CANNOT_SAVE.create(); NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.SAVE_NICK, nickname); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java index 102a2a2..5addc55 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java @@ -8,31 +8,46 @@ import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; import io.papermc.paper.command.brigadier.MessageComponentSerializer; -import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") public class SetSubCommand implements SubCommand{ + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); private final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( - Component.text("Nicknames must be <=" + ConfigHandler.getInstance().getMaxLength() + " characters after tags are stripped.\nYour nickname stripped is:\n" + nickname) + miniMessage.deserialize( + Message.ERROR_INVALID_NICK_LENGTH.getMessage(), + Placeholder.unparsed("value", String.valueOf(ConfigHandler.getInstance().getMaxLength())), + Placeholder.unparsed("name", nickname.toString()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) ) ); private final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( - Component.text("The nickname " + nickname + " is invalid.") + miniMessage.deserialize( + Message.ERROR_INVALID_NICK.getMessage(), + Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) ) ); + + @Override public void subcommandTo(@NotNull LiteralArgumentBuilder root) { @@ -54,6 +69,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) throw ERROR_LENGTH.create(nickname.normalizedNickname()); if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) throw ERROR_REGEX.create(nickname.normalizedNickname()); NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); + sendFeedback(player, Message.CHANGED_SELF, nickname); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java index 725e827..0f5d7b2 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java @@ -6,8 +6,12 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.apache.commons.lang3.NotImplementedException; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.saving.Nickname; import java.util.concurrent.CompletableFuture; @@ -16,12 +20,14 @@ public interface SubCommand { /** * Attaches this subcommand to the given root. + * * @param root Root of the command builder */ void subcommandTo(@NotNull LiteralArgumentBuilder root); /** * Defines the execution logic for this command. + * * @param ctx CommandSourceStack context * @return 1 indicating Success * @throws CommandSyntaxException On failure @@ -31,24 +37,43 @@ public interface SubCommand { /** * Defines the "can use" logic.
* ie: Is a player? Has permission? + * * @param css CommandSourceStack * @return true if the command can executed, false otherwise */ boolean canExecute(@NotNull CommandSourceStack css); + /** + * Sends a feedback message to the player, confirming the command went through properly + * + * @param player Player + * @param message Message + * @param nickname Nickname + */ + default void sendFeedback(Player player, Message message, Nickname nickname) { + if (nickname == null) nickname = new Nickname("", ""); + player.sendRichMessage( + message.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("value", nickname.nickname()) + ); + } + /** * Defines suggestions that can be provided to the client.
* This is not necessary for every command.
* This function can be defined elsewhere and method referenced instead of using this interface.
* ie: nicknameArg::suggestOwnNicknames + * * @param context Command context * @param builder SuggestionsBuilder object for adding suggestions to + * @param For Paper, generally CommandSourceStack * @return Suggestions as a CompletableFuture - * @param For Paper, generally CommandSourceStack */ @SuppressWarnings("unused") default @NotNull CompletableFuture listSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { throw new NotImplementedException("listSuggestions was used, but not implemented."); } + } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index e12233a..bff2af8 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -16,17 +16,17 @@ public enum Message { DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), ERROR_INVALID_COMMAND("error.invalid.command", "Invalid command."), ERROR_INVALID_PLAYER("error.invalid.player", "Invalid player specified"), - ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), - ERROR_INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= "), + ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), + ERROR_INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= characters stripped of formatting. Your nickname stripped is: "), ERROR_INVALID_TAGS("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"), ERROR_INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), ERROR_NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), ERROR_TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), ERROR_NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS("error.nickname.cannot-access-permissions", "Unable to process. If you are attempting to use a command with the 'restrictive' permission and the other user is offline, the server is unable to access the user's permissions while the user is offline."), - ERROR_DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given username."), + ERROR_DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given nickname, it was likely already deleted."), ERROR_SET_FAILURE("error.nickname.set-failure", "Failed to set the given username."), - ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current username."), + ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current name, you likely do not have a nickname currently."), ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), ERROR_OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), ERROR_NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), From 41cd10ea3906cbef7367fca705f7128697b5bb1a Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Mon, 12 May 2025 16:14:06 -0700 Subject: [PATCH 19/40] Fix nicknames requiring quotes --- .../commands/arguments/NicknameArgument.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java index 7aa1d38..24204d2 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -20,34 +20,37 @@ import java.util.concurrent.CompletableFuture; @SuppressWarnings("UnstableApiUsage") -public class NicknameArgument implements CustomArgumentType { +public class NicknameArgument implements CustomArgumentType { + @Override - public @NotNull Nickname parse(@NotNull StringReader reader) throws CommandSyntaxException { - String nickname = reader.readQuotedString(); + public @NotNull Nickname parse(@NotNull StringReader reader) { + String nickname = reader.getRemaining(); + reader.setCursor(reader.getTotalLength()); String normalizedNickname = SimpleNicks.getMiniMessage().stripTags(nickname); return new Nickname(nickname, normalizedNickname); } @Override public @NotNull ArgumentType getNativeType() { - return StringArgumentType.string(); + return StringArgumentType.greedyString(); } /** * Provides suggestions for nicknames based on the CommandSender + * * @param context Command context * @param builder SuggestionsBuilder object for adding suggestions to + * @param For Paper, generally CommandSourceStack * @return Suggestions as a CompletableFuture - * @param For Paper, generally CommandSourceStack */ public @NotNull CompletableFuture suggestOwnNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { CommandSourceStack css = (CommandSourceStack) context.getSource(); OfflinePlayer player = (OfflinePlayer) css.getSender(); MiniMessage miniMessage = SimpleNicks.getMiniMessage(); for (Nickname nickname : NicknameProcessor.getInstance().getSavedNicknames(player)) { - String suggestion = "\"" + nickname.nickname() + "\""; - String suggestionStripped = "\"" + nickname.normalizedNickname() + "\""; + String suggestion = nickname.nickname(); + String suggestionStripped = nickname.normalizedNickname(); if (suggestionStripped.toLowerCase().contains(builder.getRemainingLowerCase()) || suggestion.toLowerCase().contains(builder.getRemainingLowerCase())) { builder.suggest( suggestion, From bf9cbcfaa4ae5f6232d2e4c0a7e5134ad1923cd2 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Wed, 14 May 2025 15:01:24 -0700 Subject: [PATCH 20/40] Fix SQL issue and allow saving nicknames that are not currently on your player --- .../commands/admin/NicknameCommand.java | 10 +-- .../commands/subcommands/Exceptions.java | 65 ++++++++++++++++ .../commands/subcommands/SaveSubCommand.java | 59 -------------- .../{ => basic}/DeleteSubCommand.java | 21 +---- .../{ => basic}/ResetSubCommand.java | 8 +- .../subcommands/basic/SaveSubCommand.java | 76 +++++++++++++++++++ .../{ => basic}/SetSubCommand.java | 44 +++-------- .../subcommands/{ => basic}/SubCommand.java | 2 +- .../simplenicks/saving/SqlHandler.java | 1 - 9 files changed, 164 insertions(+), 122 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java delete mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java rename src/main/java/simplexity/simplenicks/commands/subcommands/{ => basic}/DeleteSubCommand.java (69%) rename src/main/java/simplexity/simplenicks/commands/subcommands/{ => basic}/ResetSubCommand.java (81%) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java rename src/main/java/simplexity/simplenicks/commands/subcommands/{ => basic}/SetSubCommand.java (54%) rename src/main/java/simplexity/simplenicks/commands/subcommands/{ => basic}/SubCommand.java (98%) diff --git a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java index ecf1abf..cd36ae6 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java @@ -3,22 +3,20 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import simplexity.simplenicks.commands.subcommands.DeleteSubCommand; -import simplexity.simplenicks.commands.subcommands.ResetSubCommand; -import simplexity.simplenicks.commands.subcommands.SaveSubCommand; -import simplexity.simplenicks.commands.subcommands.SetSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.DeleteSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.SetSubCommand; @SuppressWarnings("UnstableApiUsage") public class NicknameCommand { public static LiteralArgumentBuilder createCommand() { LiteralArgumentBuilder builder = Commands.literal("nick"); - new SetSubCommand().subcommandTo(builder); new SaveSubCommand().subcommandTo(builder); new ResetSubCommand().subcommandTo(builder); new DeleteSubCommand().subcommandTo(builder); - return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java new file mode 100644 index 0000000..7c5b472 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -0,0 +1,65 @@ +package simplexity.simplenicks.commands.subcommands; + +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.config.Message; + +@SuppressWarnings("UnstableApiUsage") +public class Exceptions { + + private static final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + public static final SimpleCommandExceptionType ERROR_CANNOT_DELETE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_DELETE_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final SimpleCommandExceptionType ERROR_NICK_IS_NULL = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_NICK_IS_NULL.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_SAVE_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_INVALID_NICK_LENGTH.getMessage(), + Placeholder.unparsed("value", String.valueOf(ConfigHandler.getInstance().getMaxLength())), + Placeholder.unparsed("name", nickname.toString()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_INVALID_NICK.getMessage(), + Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java deleted file mode 100644 index e3166d5..0000000 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SaveSubCommand.java +++ /dev/null @@ -1,59 +0,0 @@ -package simplexity.simplenicks.commands.subcommands; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import io.papermc.paper.command.brigadier.CommandSourceStack; -import io.papermc.paper.command.brigadier.Commands; -import io.papermc.paper.command.brigadier.MessageComponentSerializer; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.commands.NicknameProcessor; -import simplexity.simplenicks.config.Message; -import simplexity.simplenicks.saving.Nickname; -import simplexity.simplenicks.util.Constants; - -@SuppressWarnings("UnstableApiUsage") -public class SaveSubCommand implements SubCommand { - - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - - private final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( - MessageComponentSerializer.message().serialize( - miniMessage.deserialize( - Message.ERROR_SAVE_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) - ) - ) - ); - - @Override - public void subcommandTo(@NotNull LiteralArgumentBuilder root) { - - root.then(Commands.literal("save").requires(this::canExecute) - .executes(this::execute) - ); - - } - - @Override - public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { - OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); - Nickname nickname = NicknameProcessor.getInstance().getCurrentNickname(player); - if (nickname == null) throw ERROR_CANNOT_SAVE.create(); - NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); - if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.SAVE_NICK, nickname); - return Command.SINGLE_SUCCESS; - } - - @Override - public boolean canExecute(@NotNull CommandSourceStack css) { - return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SAVE); - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java similarity index 69% rename from src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java rename to src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index e50a8f5..798dca4 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -1,21 +1,17 @@ -package simplexity.simplenicks.commands.subcommands; +package simplexity.simplenicks.commands.subcommands.basic; import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import io.papermc.paper.command.brigadier.MessageComponentSerializer; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -23,16 +19,6 @@ @SuppressWarnings("UnstableApiUsage") public class DeleteSubCommand implements SubCommand { - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - - private final SimpleCommandExceptionType ERROR_CANNOT_DELETE = new SimpleCommandExceptionType( - MessageComponentSerializer.message().serialize( - miniMessage.deserialize( - Message.ERROR_DELETE_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) - ) - ) - ); @Override public void subcommandTo(@NotNull LiteralArgumentBuilder root) { @@ -56,11 +42,10 @@ public int execute(@NotNull CommandContext ctx) throws Comma if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.DELETE_NICK, nickname); return Command.SINGLE_SUCCESS; } - throw ERROR_CANNOT_DELETE.create(); + throw Exceptions.ERROR_CANNOT_DELETE.create(); } - @Override public boolean canExecute(@NotNull CommandSourceStack css) { return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_DELETE); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java similarity index 81% rename from src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java rename to src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java index 70133cb..58b8880 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java @@ -1,11 +1,10 @@ -package simplexity.simplenicks.commands.subcommands; +package simplexity.simplenicks.commands.subcommands.basic; import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; @@ -20,14 +19,13 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo root.then(Commands.literal("reset").requires(this::canExecute) .executes(this::execute) ); - } @Override public int execute(@NotNull CommandContext ctx) { - OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); + Player player = (Player) ctx.getSource().getSender(); NicknameProcessor.getInstance().resetNickname(player); - if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.RESET_SELF, null); + sendFeedback(player, Message.RESET_SELF, null); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java new file mode 100644 index 0000000..9fdb660 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -0,0 +1,76 @@ +package simplexity.simplenicks.commands.subcommands.basic; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; +import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class SaveSubCommand implements SubCommand { + + + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + + NicknameArgument argument = new NicknameArgument(); + + root.then(Commands.literal("save").requires(this::canExecute) + .executes(this::execute) + .then(Commands.argument("nickname", argument) + .suggests(argument::suggestOwnNicknames) + .executes(this::executeWithArgument)) + ); + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + Player player = (Player) ctx.getSource().getSender(); + Nickname nickname = NicknameProcessor.getInstance().getCurrentNickname(player); + if (nickname == null) { + throw Exceptions.ERROR_CANNOT_SAVE.create(); + } + boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + if (!saved) { + throw Exceptions.ERROR_CANNOT_SAVE.create(); + } + sendFeedback(player, Message.SAVE_NICK, nickname); + return Command.SINGLE_SUCCESS; + } + + public int executeWithArgument(@NotNull CommandContext ctx) throws CommandSyntaxException { + Player player = (Player) ctx.getSource().getSender(); + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + if (nickname == null) { + throw Exceptions.ERROR_NICK_IS_NULL.create(); + } + if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { + throw Exceptions.ERROR_LENGTH.create(nickname.normalizedNickname()); + } + if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) { + throw Exceptions.ERROR_REGEX.create(nickname.normalizedNickname()); + } + boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + if (!saved) { + throw Exceptions.ERROR_CANNOT_SAVE.create(); + } + sendFeedback(player, Message.SAVE_NICK, nickname); + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SAVE); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java similarity index 54% rename from src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java rename to src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index 5addc55..f0ce5f8 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -1,51 +1,24 @@ -package simplexity.simplenicks.commands.subcommands; +package simplexity.simplenicks.commands.subcommands.basic; import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import io.papermc.paper.command.brigadier.MessageComponentSerializer; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") -public class SetSubCommand implements SubCommand{ - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - - private final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( - nickname -> MessageComponentSerializer.message().serialize( - miniMessage.deserialize( - Message.ERROR_INVALID_NICK_LENGTH.getMessage(), - Placeholder.unparsed("value", String.valueOf(ConfigHandler.getInstance().getMaxLength())), - Placeholder.unparsed("name", nickname.toString()), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) - ) - ) - ); - - private final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( - nickname -> MessageComponentSerializer.message().serialize( - miniMessage.deserialize( - Message.ERROR_INVALID_NICK.getMessage(), - Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) - ) - ) - ); - +public class SetSubCommand implements SubCommand { @Override @@ -65,9 +38,16 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder roo @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { Nickname nickname = ctx.getArgument("nickname", Nickname.class); + if (nickname == null) { + throw Exceptions.ERROR_NICK_IS_NULL.create(); + } Player player = (Player) ctx.getSource().getSender(); - if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) throw ERROR_LENGTH.create(nickname.normalizedNickname()); - if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) throw ERROR_REGEX.create(nickname.normalizedNickname()); + if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { + throw Exceptions.ERROR_LENGTH.create(nickname.normalizedNickname()); + } + if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) { + throw Exceptions.ERROR_REGEX.create(nickname.normalizedNickname()); + } NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); sendFeedback(player, Message.CHANGED_SELF, nickname); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java similarity index 98% rename from src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java rename to src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index 0f5d7b2..bfd175c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -1,4 +1,4 @@ -package simplexity.simplenicks.commands.subcommands; +package simplexity.simplenicks.commands.subcommands.basic; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index ceb06ec..cfd0ad2 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -95,7 +95,6 @@ public List getSavedNicknamesForPlayer(UUID uuid) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(uuid)); ResultSet resultSet = statement.executeQuery(); - if (!resultSet.next()) return savedNicknames; while (resultSet.next()) { String nicknameString = resultSet.getString("nickname"); String normalizedString = resultSet.getString("normalized"); From 839aca2459bc2b322cd753d874abe1b2a553c80a Mon Sep 17 00:00:00 2001 From: Peashooter101 Date: Wed, 14 May 2025 19:54:38 -0500 Subject: [PATCH 21/40] Brig admin and admin-set commands. --- .../simplexity/simplenicks/SimpleNicks.java | 4 +- .../commands/{admin => }/NicknameCommand.java | 4 +- .../commands/arguments/NicknameArgument.java | 41 ++++++- .../arguments/OfflinePlayerArgument.java | 63 ++++++++++ .../commands/subcommands/Exceptions.java | 38 ++++++ .../subcommands/admin/AdminSetSubCommand.java | 112 ++++++++++++++++++ .../subcommands/admin/AdminSubCommand.java | 37 ++++++ .../subcommands/basic/DeleteSubCommand.java | 4 +- .../subcommands/basic/ResetSubCommand.java | 4 +- .../subcommands/basic/SaveSubCommand.java | 4 +- .../subcommands/basic/SetSubCommand.java | 4 +- .../subcommands/basic/SubCommand.java | 6 +- 12 files changed, 306 insertions(+), 15 deletions(-) rename src/main/java/simplexity/simplenicks/commands/{admin => }/NicknameCommand.java (84%) create mode 100644 src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 92efec0..417193f 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -5,7 +5,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import simplexity.simplenicks.commands.admin.AdminNick; -import simplexity.simplenicks.commands.admin.NicknameCommand; +import simplexity.simplenicks.commands.NicknameCommand; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.hooks.SNExpansion; import simplexity.simplenicks.listener.LeaveListener; @@ -39,12 +39,14 @@ public void onEnable() { if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); } + //noinspection DataFlowIssue getCommand("adminnick").setExecutor(new AdminNick()); instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); instance.getServer().getPluginManager().registerEvents(new LeaveListener(), this); configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); + //noinspection CodeBlock2Expr this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { commands.registrar().register(NicknameCommand.createCommand().build()); }); diff --git a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java similarity index 84% rename from src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java rename to src/main/java/simplexity/simplenicks/commands/NicknameCommand.java index cd36ae6..e977ef8 100644 --- a/src/main/java/simplexity/simplenicks/commands/admin/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java @@ -1,8 +1,9 @@ -package simplexity.simplenicks.commands.admin; +package simplexity.simplenicks.commands; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import simplexity.simplenicks.commands.subcommands.admin.AdminSubCommand; import simplexity.simplenicks.commands.subcommands.basic.DeleteSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; @@ -17,6 +18,7 @@ public static LiteralArgumentBuilder createCommand() { new SaveSubCommand().subcommandTo(builder); new ResetSubCommand().subcommandTo(builder); new DeleteSubCommand().subcommandTo(builder); + new AdminSubCommand().subcommandTo(builder); return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java index 24204d2..2681dcb 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -4,7 +4,6 @@ import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; @@ -12,6 +11,7 @@ import io.papermc.paper.command.brigadier.argument.CustomArgumentType; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; @@ -47,6 +47,44 @@ public class NicknameArgument implements CustomArgumentType { public @NotNull CompletableFuture suggestOwnNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { CommandSourceStack css = (CommandSourceStack) context.getSource(); OfflinePlayer player = (OfflinePlayer) css.getSender(); + addSuggestionsForPlayer(builder, player); + return builder.buildFuture(); + } + + /** + * Provides suggestions for nicknames based on the player argument. + * + * @param context Command context + * @param builder SuggestionsBuilder object for adding suggestions to + * @param For Paper, generally CommandSourceStack + * @return Suggestions as a CompletableFuture + */ + @SuppressWarnings("unused") + public @NotNull CompletableFuture suggestOtherNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { + OfflinePlayer player = context.getArgument("player", OfflinePlayer.class); + if (player == null) return builder.buildFuture(); + addSuggestionsForPlayer(builder, player); + return builder.buildFuture(); + } + + /** + * Provides suggestions for nicknames based on the player argument and CommandSender. + * + * @param context Command context + * @param builder SuggestionsBuilder object for adding suggestions to + * @param For Paper, generally CommandSourceStack + * @return Suggestions as a CompletableFuture + */ + public @NotNull CompletableFuture suggestOwnAndOtherNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) { + OfflinePlayer player = context.getArgument("player", OfflinePlayer.class); + CommandSourceStack css = (CommandSourceStack) context.getSource(); + if (player == null) return builder.buildFuture(); + addSuggestionsForPlayer(builder, player); + if (css.getSender() instanceof Player sender) addSuggestionsForPlayer(builder, sender); + return builder.buildFuture(); + } + + private void addSuggestionsForPlayer(@NotNull SuggestionsBuilder builder, OfflinePlayer player) { MiniMessage miniMessage = SimpleNicks.getMiniMessage(); for (Nickname nickname : NicknameProcessor.getInstance().getSavedNicknames(player)) { String suggestion = nickname.nickname(); @@ -60,7 +98,6 @@ public class NicknameArgument implements CustomArgumentType { ); } } - return builder.buildFuture(); } } diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java new file mode 100644 index 0000000..3c800d2 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java @@ -0,0 +1,63 @@ +package simplexity.simplenicks.commands.arguments; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.subcommands.Exceptions; + +import java.util.concurrent.CompletableFuture; + +@SuppressWarnings("UnstableApiUsage") +public class OfflinePlayerArgument implements CustomArgumentType { + + @Override + public @NotNull OfflinePlayer parse(@NotNull StringReader reader) throws CommandSyntaxException { + String playerName = reader.readString(); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayerIfCached(playerName); + if (offlinePlayer == null || !offlinePlayer.hasPlayedBefore()) throw Exceptions.ERROR_PLAYER_NOT_FOUND.create(playerName); + return offlinePlayer; + } + + @Override + public @NotNull ArgumentType getNativeType() { + return StringArgumentType.word(); + } + + /** + * Provides suggestions for players based on the online player list. + * Will also provide a hoverable element that shows their current nickname. + * + * @param ignoredContext Command context Unused + * @param builder SuggestionsBuilder object for adding suggestions to + * @param For Paper, generally CommandSourceStack + * @return Suggestions as a CompletableFuture + */ + public @NotNull CompletableFuture suggestOnlinePlayers(@NotNull CommandContext ignoredContext, @NotNull SuggestionsBuilder builder) { + MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + for (Player player : Bukkit.getOnlinePlayers()) { + String suggestion = player.getName(); + if (suggestion.toLowerCase().contains(builder.getRemainingLowerCase())) { + builder.suggest( + suggestion, + MessageComponentSerializer.message().serialize( + miniMessage.deserialize("Current Nickname: " + NicknameProcessor.getInstance().getCurrentNickname(player)) + ) + ); + } + } + return builder.buildFuture(); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index 7c5b472..9b0f7c6 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -41,6 +41,34 @@ public class Exceptions { ) ); + @SuppressWarnings("unused") + public static final SimpleCommandExceptionType ERROR_INVALID_COMMAND = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_INVALID_COMMAND.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final SimpleCommandExceptionType ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + + public static final SimpleCommandExceptionType ERROR_SET_FAILURE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_SET_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + public static final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( @@ -62,4 +90,14 @@ public class Exceptions { ) ); + public static final DynamicCommandExceptionType ERROR_PLAYER_NOT_FOUND = new DynamicCommandExceptionType( + playerName -> MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_INVALID_PLAYER.getMessage(), + Placeholder.unparsed("player_name", playerName.toString()), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java new file mode 100644 index 0000000..fd51075 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -0,0 +1,112 @@ +package simplexity.simplenicks.commands.subcommands.admin; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; +import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class AdminSetSubCommand implements SubCommand { + + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + + OfflinePlayerArgument offlinePlayerArgument = new OfflinePlayerArgument(); + NicknameArgument nicknameArgument = new NicknameArgument(); + + parent.then(Commands.literal("set") + .requires(this::canExecute) + .then(Commands.argument("player", offlinePlayerArgument) + .suggests(offlinePlayerArgument::suggestOnlinePlayers) + .then(Commands.argument("nickname", nicknameArgument) + .suggests(nicknameArgument::suggestOwnAndOtherNicknames) + .executes(this::execute) + ) + ) + ); + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + CommandSender sender = ctx.getSource().getSender(); + OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); + Nickname inputNickname = ctx.getArgument("nickname", Nickname.class); + + String nickname = getPermissionProcessedNickname(inputNickname.nickname(), sender, target); + if (nickname == null) throw Exceptions.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.create(); + + boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, nickname); + if (!setSuccessfully) throw Exceptions.ERROR_SET_FAILURE.create(); + + sender.sendMessage(parseMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); + if (target instanceof Player onlineTarget) onlineTarget.sendMessage(parseMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); + + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + boolean canUse = sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC) || + sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE) || + sender.hasPermission(Constants.NICK_SET_OTHERS_FULL); + return sender.hasPermission(Constants.NICK_SET_OTHERS) && canUse; + } + + @Nullable + private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player) { + if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { + return nickname; + } + if (sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC)) { + return NickUtils.getInstance().cleanNonPermittedTags(sender, nickname); + } + if (sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE)) { + if (!(player instanceof Player onlinePlayer)) return null; + return NickUtils.getInstance().cleanNonPermittedTags(onlinePlayer, nickname); + } + return null; + } + + private Component parseMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { + MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + Component initiatorName; + String targetUserName = target.getName(); + if (targetUserName == null) { + targetUserName = "[Username not found, idk how but you got this error.]"; + } + if (initiator instanceof Player playerInitiator) { + initiatorName = playerInitiator.displayName(); + } else { + initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); + } + return miniMessage.deserialize(message, + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("value", value), + Placeholder.component("initiator", initiatorName), + Placeholder.parsed("target", targetUserName) + ); + } + +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java new file mode 100644 index 0000000..e9fb66d --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java @@ -0,0 +1,37 @@ +package simplexity.simplenicks.commands.subcommands.admin; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.apache.commons.lang3.NotImplementedException; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class AdminSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + + LiteralArgumentBuilder admin = + Commands.literal("admin") + .requires(this::canExecute); + + new AdminSetSubCommand().subcommandTo(admin); + + parent.then(admin); + + } + + @Override + public int execute(@NotNull CommandContext ctx) { + throw new NotImplementedException("AdminSubCommand::execute was used, this should be impossible."); + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + return css.getSender().hasPermission(Constants.NICK_OTHERS_COMMAND); + } + +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index 798dca4..3a0226e 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -21,11 +21,11 @@ public class DeleteSubCommand implements SubCommand { @Override - public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { NicknameArgument argument = new NicknameArgument(); - root.then(Commands.literal("delete").requires(this::canExecute) + parent.then(Commands.literal("delete").requires(this::canExecute) .then(Commands.argument("nickname", argument) .suggests(argument::suggestOwnNicknames) .executes(this::execute)) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java index 58b8880..6ba1f44 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java @@ -14,9 +14,9 @@ @SuppressWarnings("UnstableApiUsage") public class ResetSubCommand implements SubCommand { @Override - public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { - root.then(Commands.literal("reset").requires(this::canExecute) + parent.then(Commands.literal("reset").requires(this::canExecute) .executes(this::execute) ); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java index 9fdb660..d3c1530 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -21,11 +21,11 @@ public class SaveSubCommand implements SubCommand { @Override - public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { NicknameArgument argument = new NicknameArgument(); - root.then(Commands.literal("save").requires(this::canExecute) + parent.then(Commands.literal("save").requires(this::canExecute) .executes(this::execute) .then(Commands.argument("nickname", argument) .suggests(argument::suggestOwnNicknames) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index f0ce5f8..94466c7 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -22,11 +22,11 @@ public class SetSubCommand implements SubCommand { @Override - public void subcommandTo(@NotNull LiteralArgumentBuilder root) { + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { NicknameArgument argument = new NicknameArgument(); - root.then(Commands.literal("set").requires(this::canExecute) + parent.then(Commands.literal("set").requires(this::canExecute) .then(Commands.argument("nickname", argument) .suggests(argument::suggestOwnNicknames) .executes(this::execute) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index bfd175c..765fd32 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -19,11 +19,11 @@ public interface SubCommand { /** - * Attaches this subcommand to the given root. + * Attaches this subcommand to the given parent. * - * @param root Root of the command builder + * @param parent Parent node of the command builder */ - void subcommandTo(@NotNull LiteralArgumentBuilder root); + void subcommandTo(@NotNull LiteralArgumentBuilder parent); /** * Defines the execution logic for this command. From 59ef4fda605b2c208e1e144c08d9cb6531359b1f Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Thu, 15 May 2025 17:51:17 -0700 Subject: [PATCH 22/40] Attempt at extracting nickname checks, it's broken now. removed: - simplenick.nick.reset - simplenick.nick.delete - simplenick.admin.set.basic - simplenick.admin.set.full - simplenick.admin.set.restrictive --- .../simplexity/simplenicks/SimpleNicks.java | 3 - .../simplenicks/commands/NicknameCommand.java | 4 +- .../commands/NicknameProcessor.java | 13 +- .../simplenicks/commands/admin/AdminNick.java | 137 ------------------ .../arguments/OfflinePlayerArgument.java | 2 +- .../commands/subcommands/Exceptions.java | 30 ++++ .../subcommands/admin/AdminSetSubCommand.java | 58 +------- .../subcommands/basic/DeleteSubCommand.java | 2 +- .../subcommands/basic/ResetSubCommand.java | 2 +- .../subcommands/basic/SaveSubCommand.java | 12 +- .../subcommands/basic/SetSubCommand.java | 11 +- .../subcommands/basic/SubCommand.java | 33 +++++ .../simplenicks/config/ConfigHandler.java | 19 ++- .../simplenicks/config/Message.java | 8 +- .../simplenicks/logic/NickUtils.java | 58 +++++++- .../simplexity/simplenicks/saving/Cache.java | 15 +- .../simplenicks/saving/SqlHandler.java | 15 +- .../simplenicks/util/Constants.java | 8 +- src/main/resources/config.yml | 11 +- src/main/resources/plugin.yml | 3 - 20 files changed, 191 insertions(+), 253 deletions(-) delete mode 100644 src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 417193f..5b702a1 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -4,7 +4,6 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import simplexity.simplenicks.commands.admin.AdminNick; import simplexity.simplenicks.commands.NicknameCommand; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.hooks.SNExpansion; @@ -39,8 +38,6 @@ public void onEnable() { if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); } - //noinspection DataFlowIssue - getCommand("adminnick").setExecutor(new AdminNick()); instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); instance.getServer().getPluginManager().registerEvents(new LeaveListener(), this); configReload(); diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java index e977ef8..fe059c3 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java @@ -8,12 +8,14 @@ import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SetSubCommand; +import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") public class NicknameCommand { public static LiteralArgumentBuilder createCommand() { - LiteralArgumentBuilder builder = Commands.literal("nick"); + LiteralArgumentBuilder builder = Commands.literal("nick") + .requires(src -> src.getSender().hasPermission(Constants.NICK_COMMAND)); new SetSubCommand().subcommandTo(builder); new SaveSubCommand().subcommandTo(builder); new ResetSubCommand().subcommandTo(builder); diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index fee67d8..2a23a7b 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.UUID; +@SuppressWarnings("UnusedReturnValue") public class NicknameProcessor { private static NicknameProcessor instance; @@ -101,16 +102,6 @@ public int getCurrentSavedNickCount(OfflinePlayer player) { return savedNicks.size(); } - public boolean someoneOnlineUsingThis(OfflinePlayer player, String nickname) { - UUID playerUuid = player.getUniqueId(); - return Cache.getInstance().nickInUseOnlinePlayers(playerUuid, nickname); - } - - public boolean someoneSavedUsingThis(OfflinePlayer player, String nickname) { - UUID playerUuid = player.getUniqueId(); - String strippedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().nickAlreadyExists(playerUuid, strippedNick); - } public boolean playerAlreadySavedThis(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); @@ -118,6 +109,4 @@ public boolean playerAlreadySavedThis(OfflinePlayer player, String nickname) { } - - } diff --git a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java b/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java deleted file mode 100644 index c74cbe0..0000000 --- a/src/main/java/simplexity/simplenicks/commands/admin/AdminNick.java +++ /dev/null @@ -1,137 +0,0 @@ -package simplexity.simplenicks.commands.admin; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.commands.NicknameProcessor; -import simplexity.simplenicks.config.Message; -import simplexity.simplenicks.logic.NickUtils; -import simplexity.simplenicks.util.Constants; - -import java.util.List; - -public class AdminNick implements TabExecutor { - - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - - /* - /anick user subcommand name - /anick subcommand user name - /anick subcommand name user - */ - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - if (args.length < 2) { - sender.sendRichMessage(Message.ERROR_NOT_ENOUGH_ARGS.getMessage()); - return false; - } - OfflinePlayer providedPlayer = validateProvidedPlayer(args[0], sender); - if (providedPlayer == null) return false; - String commandArg = args[1].toLowerCase(); - if (commandArg.equals("set")) { - handleSet(sender, providedPlayer, args); - } - - - return false; - } - - // /adminnick user set name - private void handleSet(CommandSender sender, OfflinePlayer target, String[] args) { - if (!sender.hasPermission(Constants.NICK_SET_OTHERS)) { - sender.sendRichMessage(Message.ERROR_NO_PERMISSION.getMessage()); - return; - } - if (args.length < 3) { - sender.sendRichMessage(Message.ERROR_NOT_ENOUGH_ARGS.getMessage()); - return; - } - String nickname = getPermissionProcessedNickname(args[2], sender, target); - if (nickname == null) { - sender.sendRichMessage(Message.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage()); - return; - } - boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, nickname); - if (!setSuccessfully) { - sender.sendRichMessage(Message.ERROR_SET_FAILURE.getMessage()); - return; - } - sender.sendMessage(parseMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); - if (target instanceof Player onlineTarget) { - onlineTarget.sendMessage(parseMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); - } - } - - - @Nullable - private OfflinePlayer validateProvidedPlayer(String string, CommandSender sender) { - OfflinePlayer player = Bukkit.getOfflinePlayer(string); - if (player.isOnline()) return player; - if (player.hasPlayedBefore()) { - return player; - } - // player is no longer valid, check the online players' nicknames against the provided string. - List playersFromName = NickUtils.getInstance().getOnlinePlayersByNickname(string); - if (playersFromName.size() > 1) { - sender.sendRichMessage( - Message.ERROR_MULTIPLE_PLAYERS_BY_THAT_NAME.getMessage() - ); - return null; - } - if (playersFromName.size() == 1) { - return playersFromName.getFirst(); - } - sender.sendRichMessage( - Message.ERROR_INVALID_PLAYER.getMessage() - ); - return null; - } - - @Nullable - private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player) { - if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { - return nickname; - } - if (sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC)) { - return NickUtils.getInstance().cleanNonPermittedTags(sender, nickname); - } - if (sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE)) { - if (!(player instanceof Player onlinePlayer)) return null; - return NickUtils.getInstance().cleanNonPermittedTags(onlinePlayer, nickname); - } - return null; - } - - private Component parseMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { - Component initiatorName; - String targetUserName = target.getName(); - if (targetUserName == null) { - targetUserName = "[Username not found, idk how but you got this error.]"; - } - if (initiator instanceof Player playerInitiator) { - initiatorName = playerInitiator.displayName(); - } else { - initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); - } - return miniMessage.deserialize(message, - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), - Placeholder.parsed("value", value), - Placeholder.component("initiator", initiatorName), - Placeholder.parsed("target", targetUserName)); - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) { - return List.of(); - } -} diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java index 3c800d2..783e257 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java @@ -38,7 +38,7 @@ public class OfflinePlayerArgument implements CustomArgumentTypeCommand context Unused * @param builder SuggestionsBuilder object for adding suggestions to diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index 9b0f7c6..2187652 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -32,6 +32,15 @@ public class Exceptions { ) ); + public static final SimpleCommandExceptionType ERROR_EMPTY_NICK_AFTER_PARSE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_INVALID_NICK_EMPTY.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + public static final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( @@ -100,4 +109,25 @@ public class Exceptions { ) ); + public static final DynamicCommandExceptionType ERROR_NICKNAME_IS_SOMEONES_USERNAME = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_OTHER_PLAYERS_USERNAME.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.unparsed("value", nickname.toString()) + ) + ) + ); + + + public static final DynamicCommandExceptionType ERROR_SOMEONE_USING_THAT_NICKNAME = new DynamicCommandExceptionType( + nickname -> MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_OTHER_PLAYERS_NICKNAME.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.unparsed("value", nickname.toString()) + ) + ) + ); + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java index fd51075..94fd49d 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -6,14 +6,10 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; @@ -52,61 +48,21 @@ public int execute(@NotNull CommandContext ctx) throws Comma CommandSender sender = ctx.getSource().getSender(); OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); Nickname inputNickname = ctx.getArgument("nickname", Nickname.class); - - String nickname = getPermissionProcessedNickname(inputNickname.nickname(), sender, target); - if (nickname == null) throw Exceptions.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.create(); - + String nickname = NickUtils.getInstance().cleanNonPermittedTags(sender, inputNickname.nickname()); + //todo idk my brain is broken, this needs straightening up tho + Nickname cleanedNickname = new Nickname(nickname, SimpleNicks.getMiniMessage().stripTags(nickname)); + NickUtils.getInstance().nicknameChecks(sender, cleanedNickname); boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, nickname); if (!setSuccessfully) throw Exceptions.ERROR_SET_FAILURE.create(); - - sender.sendMessage(parseMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); - if (target instanceof Player onlineTarget) onlineTarget.sendMessage(parseMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); - + sender.sendMessage(parseAdminMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); + if (target instanceof Player onlineTarget) onlineTarget.sendMessage(parseAdminMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); return Command.SINGLE_SUCCESS; } @Override public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); - boolean canUse = sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC) || - sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE) || - sender.hasPermission(Constants.NICK_SET_OTHERS_FULL); - return sender.hasPermission(Constants.NICK_SET_OTHERS) && canUse; - } - - @Nullable - private String getPermissionProcessedNickname(String nickname, CommandSender sender, OfflinePlayer player) { - if (sender.hasPermission(Constants.NICK_SET_OTHERS_FULL)) { - return nickname; - } - if (sender.hasPermission(Constants.NICK_SET_OTHERS_BASIC)) { - return NickUtils.getInstance().cleanNonPermittedTags(sender, nickname); - } - if (sender.hasPermission(Constants.NICK_SET_OTHERS_RESTRICTIVE)) { - if (!(player instanceof Player onlinePlayer)) return null; - return NickUtils.getInstance().cleanNonPermittedTags(onlinePlayer, nickname); - } - return null; - } - - private Component parseMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { - MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - Component initiatorName; - String targetUserName = target.getName(); - if (targetUserName == null) { - targetUserName = "[Username not found, idk how but you got this error.]"; - } - if (initiator instanceof Player playerInitiator) { - initiatorName = playerInitiator.displayName(); - } else { - initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); - } - return miniMessage.deserialize(message, - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), - Placeholder.parsed("value", value), - Placeholder.component("initiator", initiatorName), - Placeholder.parsed("target", targetUserName) - ); + return sender.hasPermission(Constants.NICK_SET_OTHERS); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index 3a0226e..439b8a7 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -48,6 +48,6 @@ public int execute(@NotNull CommandContext ctx) throws Comma @Override public boolean canExecute(@NotNull CommandSourceStack css) { - return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_DELETE); + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SAVE); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java index 6ba1f44..2364e38 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java @@ -31,6 +31,6 @@ public int execute(@NotNull CommandContext ctx) { @Override public boolean canExecute(@NotNull CommandSourceStack css) { - return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_RESET); + return css.getSender() instanceof Player player && player.hasPermission(Constants.NICK_SET); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java index d3c1530..2f9a669 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -11,8 +11,8 @@ import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -52,15 +52,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma public int executeWithArgument(@NotNull CommandContext ctx) throws CommandSyntaxException { Player player = (Player) ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); - if (nickname == null) { - throw Exceptions.ERROR_NICK_IS_NULL.create(); - } - if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { - throw Exceptions.ERROR_LENGTH.create(nickname.normalizedNickname()); - } - if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) { - throw Exceptions.ERROR_REGEX.create(nickname.normalizedNickname()); - } + NickUtils.getInstance().nicknameChecks(player, nickname); boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); if (!saved) { throw Exceptions.ERROR_CANNOT_SAVE.create(); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index 94466c7..464f87e 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -12,8 +12,8 @@ import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -38,16 +38,11 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { Nickname nickname = ctx.getArgument("nickname", Nickname.class); - if (nickname == null) { + if (nickname.normalizedNickname().isEmpty()) { throw Exceptions.ERROR_NICK_IS_NULL.create(); } Player player = (Player) ctx.getSource().getSender(); - if (!player.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { - throw Exceptions.ERROR_LENGTH.create(nickname.normalizedNickname()); - } - if (!player.hasPermission(Constants.NICK_REGEX_BYPASS) && !ConfigHandler.getInstance().getRegex().matcher(nickname.normalizedNickname()).matches()) { - throw Exceptions.ERROR_REGEX.create(nickname.normalizedNickname()); - } + NickUtils.getInstance().nicknameChecks(player, nickname); NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); sendFeedback(player, Message.CHANGED_SELF, nickname); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index 765fd32..606a147 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -6,10 +6,15 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.papermc.paper.command.brigadier.CommandSourceStack; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.apache.commons.lang3.NotImplementedException; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.Message; import simplexity.simplenicks.saving.Nickname; @@ -59,6 +64,34 @@ default void sendFeedback(Player player, Message message, Nickname nickname) { ); } + /** + * Parses a message for admin commands. + * @param message Message to parse + * @param value Placeholder value from message, usually nickname, sometimes something else like a config value + * @param initiator CommandSender who initiated the command, the admin + * @param target OfflinePlayer who this command is being run on + * @return Component parsed message + */ + default Component parseAdminMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { + MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + Component initiatorName; + String targetUserName = target.getName(); + if (targetUserName == null) { + targetUserName = "[Username not found, idk how but you got this error.]"; + } + if (initiator instanceof Player playerInitiator) { + initiatorName = playerInitiator.displayName(); + } else { + initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); + } + return miniMessage.deserialize(message, + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("value", value), + Placeholder.component("initiator", initiatorName), + Placeholder.parsed("target", targetUserName) + ); + } + /** * Defines suggestions that can be provided to the client.
* This is not necessary for every command.
diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index f034697..bd59925 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -22,10 +22,10 @@ public String getNickPrefix() { private final Logger logger = SimpleNicks.getSimpleNicksLogger(); private Pattern regex; - private boolean mySql, tablistNick; + private boolean mySql, tablistNick, onlineNickProtection, offlineNickProtection; private int maxLength, maxSaves; private String regexString, nickPrefix, mySqlIp, mySqlName, mySqlUsername, mySqlPassword; - private long usernameProtectionTime = 0; + private long usernameProtectionTime, offlineNickProtectionTime = 0; private ConfigHandler() { } @@ -58,6 +58,9 @@ public void reloadConfig() { tablistNick = config.getBoolean("tablist-nick", false); usernameProtectionTime = config.getLong("username-protection", 30) * 86400000; nickPrefix = config.getString("nickname-prefix", ""); + onlineNickProtection = config.getBoolean("nickname-protection.online.enabled", false); + offlineNickProtection = config.getBoolean("nickname-protection.offline.enabled", false); + offlineNickProtectionTime = config.getLong("nickname-protection.offline.expires", 30) * 86400000; } @@ -100,4 +103,16 @@ public String getMySqlUsername() { public String getMySqlPassword() { return mySqlPassword; } + + public long getOfflineNickProtectionTime() { + return offlineNickProtectionTime; + } + + public boolean shouldOnlineNicksBeProtected() { + return onlineNickProtection; + } + + public boolean shouldOfflineNicksBeProtected() { + return offlineNickProtection; + } } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index bff2af8..fb68118 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -16,10 +16,11 @@ public enum Message { DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), ERROR_INVALID_COMMAND("error.invalid.command", "Invalid command."), ERROR_INVALID_PLAYER("error.invalid.player", "Invalid player specified"), - ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), - ERROR_INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= characters stripped of formatting. Your nickname stripped is: "), + ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), + ERROR_INVALID_NICK_LENGTH("error.invalid.nick-length", "Nickname is too long, must be <= characters stripped of formatting. Your nickname stripped is: "), + ERROR_INVALID_NICK_EMPTY("error.invalid.nick-empty", "Nickname after parsing must actually contain characters. The nickname you provided was blank after parsing."), ERROR_INVALID_TAGS("error.invalid.tags", "You have used a color or formatting tag you do not have permission to use. Please try again"), - ERROR_INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), + ERROR_INVALID_CONFIG_REGEX("error.invalid.config-regex", "nickname-regex is null or malformed in file 'config.yml'. Please fix this"), ERROR_NOT_ENOUGH_ARGS("error.arguments.not-enough", "No arguments provided."), ERROR_TOO_MANY_ARGS("error.arguments.too-many", "Too many arguments provided."), ERROR_NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), @@ -29,6 +30,7 @@ public enum Message { ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current name, you likely do not have a nickname currently."), ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), ERROR_OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), + ERROR_OTHER_PLAYERS_NICKNAME("error.nickname.other-players-nickname", "Sorry! Someone online is already using the nickname ! Try another one!"), ERROR_NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), ERROR_NO_PERMISSION("error.no-permission", "You do not have permission to run this command"), ERROR_MUST_BE_PLAYER("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"), diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index 7617306..3b53ec9 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -1,5 +1,6 @@ package simplexity.simplenicks.logic; +import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -8,10 +9,13 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.ConfigHandler; import simplexity.simplenicks.saving.AbstractSaving; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.saving.SqlHandler; +import simplexity.simplenicks.util.Constants; import simplexity.simplenicks.util.TagPermission; import java.util.ArrayList; @@ -37,6 +41,27 @@ public static NickUtils getInstance() { return instance; } + public void nicknameChecks(CommandSender sender, Nickname nickname) throws CommandSyntaxException { + if (nickname.normalizedNickname().isEmpty()) { + throw Exceptions.ERROR_EMPTY_NICK_AFTER_PARSE.create(); + } + if (!sender.hasPermission(Constants.NICK_USERNAME_BYPASS) && thisIsSomeonesUsername(nickname.normalizedNickname())) { + throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(nickname.normalizedNickname()); + } + if (!sender.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { + throw Exceptions.ERROR_LENGTH.create(nickname); + } + if (!sender.hasPermission(Constants.NICK_REGEX_BYPASS) && !passesRegexCheck(nickname.normalizedNickname())) { + throw Exceptions.ERROR_REGEX.create(nickname); + } + if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneOnlineUsingThis(sender, nickname.normalizedNickname())) { + throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(nickname); + } + if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneSavedUsingThis(sender, nickname.normalizedNickname())) { + throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(nickname); + } + } + public boolean refreshNickname(UUID uuid) { Player player = Bukkit.getPlayer(uuid); @@ -74,7 +99,7 @@ public String cleanNonPermittedTags(CommandSender user, String nick) { } - public List getOnlinePlayersByNickname(String nickname){ + public List getOnlinePlayersByNickname(String nickname) { List usersWithThisName = Cache.getInstance().getUuidOfNormalizedName(nickname); if (usersWithThisName.isEmpty()) return new ArrayList<>(); List playersByNick = new ArrayList<>(); @@ -104,5 +129,36 @@ public boolean passesRegexCheck(String normalizedNick) { return !matcher.find(); } + public boolean thisIsSomeonesUsername(String normalizedName) { + long protectionTime = ConfigHandler.getInstance().getUsernameProtectionTime(); + if (protectionTime < 0) return false; + OfflinePlayer player = Bukkit.getOfflinePlayer(normalizedName); + long lastSeen = player.getLastSeen(); + if (lastSeen == 0) return false; + long timeSinceSeen = System.currentTimeMillis() - lastSeen; + return timeSinceSeen <= protectionTime; + } + + public boolean someoneOnlineUsingThis(CommandSender sender, String normalizedNick) { + if (!ConfigHandler.getInstance().shouldOnlineNicksBeProtected()) return false; + UUID playerUuid = null; + if (sender instanceof Player playerSender) playerUuid = playerSender.getUniqueId(); + return Cache.getInstance().nickInUseOnlinePlayers(playerUuid, normalizedNick); + } + + public boolean someoneSavedUsingThis(CommandSender sender, String nickname) { + if (!ConfigHandler.getInstance().shouldOfflineNicksBeProtected()) return false; + UUID playerUuid = null; + if (sender instanceof Player playerSender) playerUuid = playerSender.getUniqueId(); + String strippedNick = miniMessage.stripTags(nickname); + UUID userWhoHasThis = SqlHandler.getInstance().nickAlreadySavedTo(playerUuid, strippedNick); + if (userWhoHasThis == null) return false; + OfflinePlayer player = Bukkit.getOfflinePlayer(userWhoHasThis); + long lastSeen = player.getLastSeen(); + long timeToProtect = ConfigHandler.getInstance().getOfflineNickProtectionTime(); + long currentTime = System.currentTimeMillis(); + return currentTime - lastSeen < timeToProtect; + } + } diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index b8e2b97..9a35065 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -1,7 +1,6 @@ package simplexity.simplenicks.saving; import net.kyori.adventure.text.minimessage.MiniMessage; -import org.bukkit.Bukkit; import simplexity.simplenicks.SimpleNicks; import javax.annotation.Nullable; @@ -27,6 +26,7 @@ public static Cache getInstance() { /** * Loads the player's active nickname from SQL and into cache + * * @param uuid player UUID */ @@ -38,6 +38,7 @@ public void loadCurrentNickname(UUID uuid) { /** * Gets the active nickname from cache, + * * @param uuid Player uuid * @return Nickname player has set, null if no nickname is set */ @@ -49,6 +50,7 @@ public Nickname getActiveNickname(UUID uuid) { /** * Loads a player's saved nicknames into the cache from SQL + * * @param uuid Player's UUID */ public void loadSavedNicknames(UUID uuid) { @@ -59,6 +61,7 @@ public void loadSavedNicknames(UUID uuid) { /** * Gets the saved nicknames from the cache + * * @param uuid Player UUID * @return List - if no nicks exist, returns empty list */ @@ -69,7 +72,8 @@ public List getSavedNicknames(UUID uuid) { /** * Sets the active nickname for the player - * @param uuid Player UUID + * + * @param uuid Player UUID * @param nickname Version of the nickname with tags included * @return boolean - whether nickname was successfully set or not */ @@ -105,11 +109,10 @@ public List getUuidOfNormalizedName(String nickname) { return uuids; } - public boolean nickInUseOnlinePlayers(UUID uuid, String nickname) { - String strippedNick = miniMessage.stripTags(nickname); + public boolean nickInUseOnlinePlayers(@Nullable UUID uuid, String normalizedNick) { for (UUID playerUuid : activeNicknames.keySet()) { if (playerUuid.equals(uuid)) continue; - if (activeNicknames.get(playerUuid).normalizedNickname().equals(strippedNick)) return true; + if (activeNicknames.get(playerUuid).normalizedNickname().equals(normalizedNick)) return true; } return false; } @@ -125,7 +128,7 @@ public boolean saveNickname(UUID uuid, String nickname) { return true; } - public int getSavedNickCount(UUID uuid){ + public int getSavedNickCount(UUID uuid) { if (savedNicknames.containsKey(uuid)) return savedNicknames.get(uuid).size(); return 0; } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index cfd0ad2..a7642f9 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -71,19 +71,24 @@ REFERENCES players(uuid) } - public boolean nickAlreadyExists(UUID uuidToExclude, String normalizedName) { - String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? AND uuid != ? LIMIT 1"; + @Nullable + public UUID nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { + String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? " + + ((uuidToExclude != null) ? "AND uuid != ? " : "") + "LIMIT 1"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(normalizedName)); - statement.setString(2, String.valueOf(uuidToExclude)); + if (uuidToExclude != null) statement.setString(2, String.valueOf(uuidToExclude)); ResultSet resultSet = statement.executeQuery(); - return resultSet.next(); + if (resultSet.next()) { + return UUID.fromString(resultSet.getString("uuid")); + } } catch (SQLException e) { logger.severe("Failed to check if nickname exists: " + normalizedName); e.printStackTrace(); - return false; + return null; } + return null; } @Nullable diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index c01736d..0e4bc6f 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -5,19 +5,13 @@ public class Constants { public static Permission NICK_OTHERS_COMMAND = new Permission("simplenick.admin"); public static Permission NICK_SET_OTHERS = new Permission("simplenick.admin.set"); - public static Permission NICK_SET_OTHERS_RESTRICTIVE = new Permission("simplenick.admin.set.restrictive"); - public static Permission NICK_SET_OTHERS_BASIC = new Permission("simplenick.admin.set.basic"); - public static Permission NICK_SET_OTHERS_FULL = new Permission("simplenick.admin.set.full"); public static Permission NICK_RESET_OTHERS = new Permission("simplenick.admin.reset"); - public static Permission NICK_SAVE_OTHERS = new Permission("simplenick.admin.save"); - public static Permission NICK_DELETE_OTHERS = new Permission("simplenick.admin.delete"); public static Permission NICK_GET_OTHERS = new Permission("simplenick.admin.get"); public static Permission NICK_COMMAND = new Permission("simplenick.nick"); public static Permission NICK_SET = new Permission("simplenick.nick.set"); - public static Permission NICK_RESET = new Permission("simplenick.nick.reset"); public static Permission NICK_SAVE = new Permission("simplenick.nick.save"); - public static Permission NICK_DELETE = new Permission("simplenick.nick.delete"); public static Permission NICK_USERNAME_BYPASS = new Permission("simplenick.bypass.username"); public static Permission NICK_LENGTH_BYPASS = new Permission("simplenick.bypass.length"); public static Permission NICK_REGEX_BYPASS = new Permission("simplenick.bypass.regex"); + public static Permission NICK_PROTECTION_BYPASS = new Permission("simplenick.bypass.nick-protection"); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f0c5d22..5548ccf 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -27,4 +27,13 @@ tablist-nick: false username-protection: 30 # What prefix should be given for players who have a nickname? put "" if you want no prefix -nickname-prefix: "" \ No newline at end of file +nickname-prefix: "" + +# Feature to prevent people from having the same nicknames. This will prevent the same nicknames from being used, after formatting. +# Saved names are not checked for this, only actively applied ones. +nickname-protection: + online: + enabled: false + offline: + enabled: false + expires: 30 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1e7f240..c3d96c3 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -7,9 +7,6 @@ description: "A simple plugin to allow players to set and reset nicknames." softdepend: - PlaceholderAPI commands: - adminnick: - description: e - permission: simplenick.admin nick: description: "Base command for SimpleNicks, Admin permission required to alter other's names." aliases: [simplenicks, simplenick, snick] From d9d8ccbdb92e11dc6d099d14671826aff2cc6539 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sat, 17 May 2025 14:04:27 -0700 Subject: [PATCH 23/40] idk why it keeps saying regex error --- .../commands/NicknameProcessor.java | 10 ++++++---- .../arguments/OfflinePlayerArgument.java | 10 +++++++++- .../simplenicks/logic/NickUtils.java | 13 ++++++++++-- .../simplexity/simplenicks/saving/Cache.java | 8 ++++---- .../simplenicks/saving/SqlHandler.java | 20 +++++++++++-------- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index 2a23a7b..9491205 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -29,14 +29,15 @@ public static NicknameProcessor getInstance() { public boolean setNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); + String username = player.getName(); boolean online = player.isOnline(); if (online) { - boolean success = Cache.getInstance().setActiveNickname(playerUuid, nickname); + boolean success = Cache.getInstance().setActiveNickname(playerUuid, username, nickname); if (!success) return false; NickUtils.getInstance().refreshNickname(playerUuid); } String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().setActiveNickname(playerUuid, nickname, normalizedNick); + return SqlHandler.getInstance().setActiveNickname(playerUuid, username, nickname, normalizedNick); } public boolean resetNickname(OfflinePlayer player) { @@ -53,15 +54,16 @@ public boolean resetNickname(OfflinePlayer player) { public boolean saveNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); + String username = player.getName(); boolean online = player.isOnline(); if (online) { - boolean success = Cache.getInstance().saveNickname(playerUuid, nickname); + boolean success = Cache.getInstance().saveNickname(playerUuid, username, nickname); if (!success) return false; NickUtils.getInstance().refreshNickname(playerUuid); return true; } String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().saveNickname(playerUuid, nickname, normalizedNick); + return SqlHandler.getInstance().saveNickname(playerUuid, username, nickname, normalizedNick); } public boolean deleteNickname(OfflinePlayer player, String nickname) { diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java index 783e257..8267d15 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/OfflinePlayerArgument.java @@ -26,7 +26,15 @@ public class OfflinePlayerArgument implements CustomArgumentType getSavedNicknames(UUID uuid) { * @param nickname Version of the nickname with tags included * @return boolean - whether nickname was successfully set or not */ - public boolean setActiveNickname(UUID uuid, String nickname) { + public boolean setActiveNickname(UUID uuid, String username, String nickname) { String normalizedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, normalizedNick); - boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, nickname, normalizedNick); + boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, username, nickname, normalizedNick); if (!sqlActiveNameSet) return false; activeNicknames.put(uuid, nick); return true; @@ -117,12 +117,12 @@ public boolean nickInUseOnlinePlayers(@Nullable UUID uuid, String normalizedNick return false; } - public boolean saveNickname(UUID uuid, String nickname) { + public boolean saveNickname(UUID uuid, String username, String nickname) { String strippedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, strippedNick); List userSavedNicknames = getSavedNicknames(uuid); userSavedNicknames.add(nick); - boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, nickname, strippedNick); + boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, username, nickname, strippedNick); if (!savedToSql) return false; savedNicknames.put(uuid, userSavedNicknames); return true; diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index a7642f9..7de4e12 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -35,7 +35,8 @@ public void init() { try (Connection connection = getConnection()) { PreparedStatement parentStatement = connection.prepareStatement(""" CREATE TABLE IF NOT EXISTS players ( - uuid VARCHAR(36) PRIMARY KEY, + uuid VARCHAR(36) PRIMARY KEY NOT NULL, + last_known_name VARCHAR(16) NOT NULL, last_login DATETIME NOT NULL ); """); @@ -169,9 +170,9 @@ public List getUuidsOfNickname(String normalizeName) { } } - public boolean saveNickname(UUID uuid, String nickname, String normalizedNickname) { + public boolean saveNickname(UUID uuid, String username, String nickname, String normalizedNickname) { String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); + if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid, username); try (Connection connection = getConnection()) { PreparedStatement saveStatement = connection.prepareStatement(saveString); saveStatement.setString(1, String.valueOf(uuid)); @@ -217,9 +218,9 @@ public boolean clearActiveNickname(UUID uuid) { } } - public boolean setActiveNickname(UUID uuid, String nicknameString, String normalizedString) { + public boolean setActiveNickname(UUID uuid, String username, String nicknameString, String normalizedString) { String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid); + if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid, username); try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(setQuery); statement.setString(1, String.valueOf(uuid)); @@ -248,14 +249,17 @@ public boolean playerSaveExists(UUID uuid) { } } - private void addPlayerToPlayers(UUID uuid) { - String insertQuery = "REPLACE INTO players (uuid, last_login) VALUES (?, CURRENT_TIMESTAMP)"; + //todo: Add updating last login and last known name + + private void addPlayerToPlayers(UUID uuid, String username) { + String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(insertQuery); statement.setString(1, String.valueOf(uuid)); + statement.setString(2, username); statement.executeUpdate(); } catch (SQLException e) { - logger.severe("Failed to save player: " + uuid); + logger.severe("Failed to save player: " + uuid + ", username: " + username); e.printStackTrace(); } } From 80022a32dbb0b0aff50070937c61ec94404f7ac4 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sun, 18 May 2025 11:59:55 -0700 Subject: [PATCH 24/40] regex error is fixed, slight work on username check --- .../simplenicks/logic/NickUtils.java | 7 ++++--- .../simplenicks/saving/SqlHandler.java | 21 ++++++++++++++++--- src/main/resources/config.yml | 6 ++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index 61779c9..ce2e82d 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,7 +30,7 @@ public class NickUtils { private static NickUtils instance; - private AbstractSaving saveHandler; + private final Logger logger = SimpleNicks.getSimpleNicksLogger(); private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); private NickUtils() { @@ -52,6 +53,7 @@ public void nicknameChecks(CommandSender sender, Nickname nickname) throws Comma throw Exceptions.ERROR_LENGTH.create(nickname); } if (!sender.hasPermission(Constants.NICK_REGEX_BYPASS) && !passesRegexCheck(nickname.normalizedNickname())) { + logger.info("regex failed here"); throw Exceptions.ERROR_REGEX.create(nickname); } if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneOnlineUsingThis(sender, nickname.normalizedNickname())) { @@ -125,8 +127,7 @@ public List getOfflinePlayersByNickname(String nickname) { public boolean passesRegexCheck(String normalizedNick) { Pattern configRegex = ConfigHandler.getInstance().getRegex(); - Matcher matcher = configRegex.matcher(normalizedNick); - return !matcher.find(); + return configRegex.matcher(normalizedNick).matches(); } public boolean thisIsSomeonesUsername(String normalizedName) { diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 7de4e12..a735907 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -172,7 +172,7 @@ public List getUuidsOfNickname(String normalizeName) { public boolean saveNickname(UUID uuid, String username, String nickname, String normalizedNickname) { String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid, username); + if (!playerSaveExists(uuid)) savePlayerToPlayers(uuid, username); try (Connection connection = getConnection()) { PreparedStatement saveStatement = connection.prepareStatement(saveString); saveStatement.setString(1, String.valueOf(uuid)); @@ -220,7 +220,7 @@ public boolean clearActiveNickname(UUID uuid) { public boolean setActiveNickname(UUID uuid, String username, String nicknameString, String normalizedString) { String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) addPlayerToPlayers(uuid, username); + if (!playerSaveExists(uuid)) savePlayerToPlayers(uuid, username); try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(setQuery); statement.setString(1, String.valueOf(uuid)); @@ -249,9 +249,24 @@ public boolean playerSaveExists(UUID uuid) { } } + public Long lastLongOfUsername(String username) { + String queryString = "SELECT last_login FROM players WHERE last_known_name = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, username); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) return resultSet.getLong("last_login"); + return null; + } catch (SQLException e) { + logger.severe("Failed to get last login for username: " + username); + e.printStackTrace(); + return null; + } + } + //todo: Add updating last login and last known name - private void addPlayerToPlayers(UUID uuid, String username) { + private void savePlayerToPlayers(UUID uuid, String username) { String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(insertQuery); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5548ccf..04a7665 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -14,6 +14,12 @@ max-nickname-length: 30 # Be warned that putting non-alphanumeric characters may result in issues with other plugins and other unintended side effects nickname-regex: "[A-Za-z0-9_]+" +# Nickname Blacklist +# Blacklist of names that cannot be used (After formatting, capitalization ignored) +nickname-blacklist: + - notch + - slur + # How many nicknames can be saved? max-saves: 5 From b26ba6c23bae295867dcba800e76c7eff43cf3ee Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 20 May 2025 15:15:15 -0700 Subject: [PATCH 25/40] Change Nickname from a record to a class (needed to be able to set) - added admin reset command and nick reload command, added nickname protection check and adjusted username protection check to use plugin's save system and not bukkit's. --- .../simplexity/simplenicks/SimpleNicks.java | 1 - .../simplenicks/commands/NicknameCommand.java | 2 + .../commands/arguments/NicknameArgument.java | 6 +- .../commands/subcommands/Exceptions.java | 9 +++ .../admin/AdminResetSubCommand.java | 58 ++++++++++++++ .../subcommands/admin/AdminSetSubCommand.java | 17 ++--- .../subcommands/admin/AdminSubCommand.java | 1 + .../subcommands/basic/DeleteSubCommand.java | 2 +- .../subcommands/basic/ReloadSubCommand.java | 39 ++++++++++ .../subcommands/basic/SaveSubCommand.java | 4 +- .../subcommands/basic/SetSubCommand.java | 4 +- .../subcommands/basic/SubCommand.java | 2 +- .../simplenicks/config/Message.java | 1 + .../simplenicks/hooks/SNExpansion.java | 4 +- .../simplenicks/listener/LoginListener.java | 3 + .../simplenicks/logic/NickUtils.java | 75 ++++++++----------- .../simplexity/simplenicks/saving/Cache.java | 4 +- .../simplenicks/saving/Nickname.java | 33 +++++++- .../simplenicks/saving/SqlHandler.java | 44 ++++++++--- .../simplenicks/util/Constants.java | 1 + src/main/resources/locale.yml | 44 ----------- src/main/resources/plugin.yml | 20 ----- 22 files changed, 230 insertions(+), 144 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java delete mode 100644 src/main/resources/locale.yml diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 5b702a1..e987c2c 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -43,7 +43,6 @@ public void onEnable() { configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); - //noinspection CodeBlock2Expr this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { commands.registrar().register(NicknameCommand.createCommand().build()); }); diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java index fe059c3..6dc00c1 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java @@ -5,6 +5,7 @@ import io.papermc.paper.command.brigadier.Commands; import simplexity.simplenicks.commands.subcommands.admin.AdminSubCommand; import simplexity.simplenicks.commands.subcommands.basic.DeleteSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.ReloadSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SetSubCommand; @@ -21,6 +22,7 @@ public static LiteralArgumentBuilder createCommand() { new ResetSubCommand().subcommandTo(builder); new DeleteSubCommand().subcommandTo(builder); new AdminSubCommand().subcommandTo(builder); + new ReloadSubCommand().subcommandTo(builder); return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java index 2681dcb..028e390 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -87,13 +87,13 @@ public class NicknameArgument implements CustomArgumentType { private void addSuggestionsForPlayer(@NotNull SuggestionsBuilder builder, OfflinePlayer player) { MiniMessage miniMessage = SimpleNicks.getMiniMessage(); for (Nickname nickname : NicknameProcessor.getInstance().getSavedNicknames(player)) { - String suggestion = nickname.nickname(); - String suggestionStripped = nickname.normalizedNickname(); + String suggestion = nickname.getNickname(); + String suggestionStripped = nickname.getNormalizedNickname(); if (suggestionStripped.toLowerCase().contains(builder.getRemainingLowerCase()) || suggestion.toLowerCase().contains(builder.getRemainingLowerCase())) { builder.suggest( suggestion, MessageComponentSerializer.message().serialize( - miniMessage.deserialize("Preview: " + nickname.nickname()) + miniMessage.deserialize("Preview: " + nickname.getNickname()) ) ); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index 2187652..2a83cab 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -69,6 +69,15 @@ public class Exceptions { ) ); + public static final SimpleCommandExceptionType ERROR_UNABLE_TO_RESET_NICK = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + Message.ERROR_RESET_FAILURE.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + ) + ) + ); + public static final SimpleCommandExceptionType ERROR_SET_FAILURE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java new file mode 100644 index 0000000..6edc7d0 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java @@ -0,0 +1,58 @@ +package simplexity.simplenicks.commands.subcommands.admin; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import net.kyori.adventure.text.Component; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; +import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class AdminResetSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + + OfflinePlayerArgument offlinePlayerArgument = new OfflinePlayerArgument(); + + parent.then(Commands.literal("reset") + .requires(this::canExecute) + .then(Commands.argument("player", offlinePlayerArgument) + .suggests(offlinePlayerArgument::suggestOnlinePlayers) + .executes(this::execute))); + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + CommandSender sender = ctx.getSource().getSender(); + OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); + boolean resetNick = NicknameProcessor.getInstance().resetNickname(target); + if (!resetNick) throw Exceptions.ERROR_UNABLE_TO_RESET_NICK.create(); + sender.sendMessage(parseAdminMessage(Message.RESET_OTHER.getMessage(), "", sender, target)); + if (target instanceof Player onlineTarget) + onlineTarget.sendMessage(parseAdminMessage(Message.RESET_BY_OTHER.getMessage(), "", sender, target)); + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + return sender.hasPermission(Constants.NICK_RESET_OTHERS); + } + + @Override + public Component parseAdminMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { + return SubCommand.super.parseAdminMessage(message, value, initiator, target); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java index 94fd49d..c59f528 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -10,7 +10,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; @@ -47,15 +46,15 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); - Nickname inputNickname = ctx.getArgument("nickname", Nickname.class); - String nickname = NickUtils.getInstance().cleanNonPermittedTags(sender, inputNickname.nickname()); - //todo idk my brain is broken, this needs straightening up tho - Nickname cleanedNickname = new Nickname(nickname, SimpleNicks.getMiniMessage().stripTags(nickname)); - NickUtils.getInstance().nicknameChecks(sender, cleanedNickname); - boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, nickname); + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + String cleanedNick = NickUtils.getInstance().cleanNonPermittedTags(sender, nickname.getNickname()); + nickname.setNickname(cleanedNick); + NickUtils.getInstance().nicknameChecks(sender, nickname); + boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, cleanedNick); if (!setSuccessfully) throw Exceptions.ERROR_SET_FAILURE.create(); - sender.sendMessage(parseAdminMessage(Message.CHANGED_OTHER.getMessage(), nickname, sender, target)); - if (target instanceof Player onlineTarget) onlineTarget.sendMessage(parseAdminMessage(Message.CHANGED_BY_OTHER.getMessage(), nickname, sender, target)); + sender.sendMessage(parseAdminMessage(Message.CHANGED_OTHER.getMessage(), cleanedNick, sender, target)); + if (target instanceof Player onlineTarget) + onlineTarget.sendMessage(parseAdminMessage(Message.CHANGED_BY_OTHER.getMessage(), cleanedNick, sender, target)); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java index e9fb66d..f4d6872 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java @@ -19,6 +19,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par .requires(this::canExecute); new AdminSetSubCommand().subcommandTo(admin); + new AdminResetSubCommand().subcommandTo(admin); parent.then(admin); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index 439b8a7..f8e8761 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -37,7 +37,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); - boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.nickname()); + boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.getNickname()); if (deleted) { if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.DELETE_NICK, nickname); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java new file mode 100644 index 0000000..1eaafbe --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java @@ -0,0 +1,39 @@ +package simplexity.simplenicks.commands.subcommands.basic; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.config.ConfigHandler; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.util.Constants; + +@SuppressWarnings("UnstableApiUsage") +public class ReloadSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + parent.then(Commands.literal("reload").requires(this::canExecute) + .executes(this::execute)); + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + CommandSender sender = ctx.getSource().getSender(); + ConfigHandler.getInstance().reloadConfig(); + sender.sendRichMessage(Message.CONFIG_RELOADED.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage())); + return Command.SINGLE_SUCCESS; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + return sender.hasPermission(Constants.NICK_RELOAD); + } + +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java index 2f9a669..1c7c28b 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -41,7 +41,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma if (nickname == null) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } - boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.getNickname()); if (!saved) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } @@ -53,7 +53,7 @@ public int executeWithArgument(@NotNull CommandContext ctx) Player player = (Player) ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); NickUtils.getInstance().nicknameChecks(player, nickname); - boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.nickname()); + boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.getNickname()); if (!saved) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index 464f87e..bd04c05 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -38,12 +38,12 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { Nickname nickname = ctx.getArgument("nickname", Nickname.class); - if (nickname.normalizedNickname().isEmpty()) { + if (nickname.getNormalizedNickname().isEmpty()) { throw Exceptions.ERROR_NICK_IS_NULL.create(); } Player player = (Player) ctx.getSource().getSender(); NickUtils.getInstance().nicknameChecks(player, nickname); - NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.nickname()); + NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.getNickname()); sendFeedback(player, Message.CHANGED_SELF, nickname); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index 606a147..27be116 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -60,7 +60,7 @@ default void sendFeedback(Player player, Message message, Nickname nickname) { player.sendRichMessage( message.getMessage(), Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), - Placeholder.parsed("value", nickname.nickname()) + Placeholder.parsed("value", nickname.getNickname()) ); } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index fb68118..be531f5 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -26,6 +26,7 @@ public enum Message { ERROR_NICK_IS_NULL("error.nickname.is-null", "Something went wrong and the nickname is null, please check your formatting"), ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS("error.nickname.cannot-access-permissions", "Unable to process. If you are attempting to use a command with the 'restrictive' permission and the other user is offline, the server is unable to access the user's permissions while the user is offline."), ERROR_DELETE_FAILURE("error.nickname.delete-failure", "Failed to delete given nickname, it was likely already deleted."), + ERROR_RESET_FAILURE("error.nickname.reset-failure", "Failed to reset nickname"), ERROR_SET_FAILURE("error.nickname.set-failure", "Failed to set the given username."), ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current name, you likely do not have a nickname currently."), ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), diff --git a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java index f5bb7cd..0bbd9c1 100644 --- a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java +++ b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java @@ -34,8 +34,8 @@ public String onRequest(OfflinePlayer player, @NotNull String params) { Nickname nickname = Cache.getInstance().getActiveNickname(player.getUniqueId()); if (nickname != null) { String prefix = ConfigHandler.getInstance().getNickPrefix(); - if (prefix == null || prefix.isEmpty()) return nickname.nickname(); - return prefix + nickname.nickname(); + if (prefix == null || prefix.isEmpty()) return nickname.getNickname(); + return prefix + nickname.getNickname(); } return player.getName(); } diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index 8fda50d..47266b2 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -6,6 +6,7 @@ import org.bukkit.event.player.PlayerJoinEvent; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.saving.SqlHandler; import java.util.UUID; @@ -16,5 +17,7 @@ public void onPlayerLogin(PlayerJoinEvent joinEvent) { Cache.getInstance().loadCurrentNickname(playerUuid); Cache.getInstance().loadSavedNicknames(playerUuid); NickUtils.getInstance().refreshNickname(playerUuid); + String username = joinEvent.getPlayer().getName(); + SqlHandler.getInstance().savePlayerToPlayers(playerUuid, username); } } diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index ce2e82d..40c8721 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -11,7 +11,6 @@ import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.saving.AbstractSaving; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.saving.SqlHandler; @@ -22,7 +21,6 @@ import java.util.List; import java.util.UUID; import java.util.logging.Logger; -import java.util.regex.Matcher; import java.util.regex.Pattern; @SuppressWarnings("UnusedReturnValue") @@ -30,7 +28,6 @@ public class NickUtils { private static NickUtils instance; - private final Logger logger = SimpleNicks.getSimpleNicksLogger(); private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); private NickUtils() { @@ -43,24 +40,28 @@ public static NickUtils getInstance() { } public void nicknameChecks(CommandSender sender, Nickname nickname) throws CommandSyntaxException { - if (nickname.normalizedNickname().isEmpty()) { + String normalizedNick = nickname.getNormalizedNickname(); + if (normalizedNick.isEmpty()) { throw Exceptions.ERROR_EMPTY_NICK_AFTER_PARSE.create(); } - if (!sender.hasPermission(Constants.NICK_USERNAME_BYPASS) && thisIsSomeonesUsername(nickname.normalizedNickname())) { - throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(nickname.normalizedNickname()); + if (!sender.hasPermission(Constants.NICK_USERNAME_BYPASS) && thisIsSomeonesUsername(normalizedNick)) { + throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(normalizedNick); } - if (!sender.hasPermission(Constants.NICK_LENGTH_BYPASS) && nickname.normalizedNickname().length() > ConfigHandler.getInstance().getMaxLength()) { - throw Exceptions.ERROR_LENGTH.create(nickname); + if (!sender.hasPermission(Constants.NICK_LENGTH_BYPASS) && normalizedNick.length() > ConfigHandler.getInstance().getMaxLength()) { + throw Exceptions.ERROR_LENGTH.create(normalizedNick); } - if (!sender.hasPermission(Constants.NICK_REGEX_BYPASS) && !passesRegexCheck(nickname.normalizedNickname())) { - logger.info("regex failed here"); - throw Exceptions.ERROR_REGEX.create(nickname); + if (!sender.hasPermission(Constants.NICK_REGEX_BYPASS) && !passesRegexCheck(normalizedNick)) { + throw Exceptions.ERROR_REGEX.create(normalizedNick); } - if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneOnlineUsingThis(sender, nickname.normalizedNickname())) { - throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(nickname); + if (ConfigHandler.getInstance().shouldOnlineNicksBeProtected()) { + if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneOnlineUsingThis(sender, normalizedNick)) { + throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(normalizedNick); + } } - if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneSavedUsingThis(sender, nickname.normalizedNickname())) { - throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(nickname); + if (ConfigHandler.getInstance().shouldOfflineNicksBeProtected()) { + if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneSavedUsingThis(sender, normalizedNick)) { + throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(normalizedNick); + } } } @@ -73,13 +74,14 @@ public boolean refreshNickname(UUID uuid) { player.displayName(null); return true; } - player.displayName(miniMessage.deserialize(ConfigHandler.getInstance().getNickPrefix() + nickname.nickname())); + player.displayName(miniMessage.deserialize(ConfigHandler.getInstance().getNickPrefix() + nickname.getNickname())); if (ConfigHandler.getInstance().shouldNickTablist()) { - player.playerListName(miniMessage.deserialize(nickname.nickname())); + player.playerListName(miniMessage.deserialize(nickname.getNickname())); } return true; } + public String cleanNonPermittedTags(CommandSender user, String nick) { int permissionCount = 0; TagResolver.Builder resolver = TagResolver.builder(); @@ -133,41 +135,26 @@ public boolean passesRegexCheck(String normalizedNick) { public boolean thisIsSomeonesUsername(String normalizedName) { long protectionTime = ConfigHandler.getInstance().getUsernameProtectionTime(); if (protectionTime < 0) return false; - OfflinePlayer[] offlinePlayers = Bukkit.getOfflinePlayers(); - OfflinePlayer offlinePlayer = null; - for (OfflinePlayer player : offlinePlayers) { - if (player.getName() == null || player.getName().isEmpty()) continue; - if (player.getName().equalsIgnoreCase(normalizedName)) { - offlinePlayer = player; - break; - } - } - if (offlinePlayer == null) return false; - long lastSeen = offlinePlayer.getLastSeen(); - if (lastSeen == 0) return false; - long timeSinceSeen = System.currentTimeMillis() - lastSeen; - return timeSinceSeen <= protectionTime; + normalizedName = normalizedName.toLowerCase(); + return SqlHandler.getInstance().lastLongOfUsername(normalizedName, ConfigHandler.getInstance().getUsernameProtectionTime()) != null; } public boolean someoneOnlineUsingThis(CommandSender sender, String normalizedNick) { - if (!ConfigHandler.getInstance().shouldOnlineNicksBeProtected()) return false; UUID playerUuid = null; if (sender instanceof Player playerSender) playerUuid = playerSender.getUniqueId(); return Cache.getInstance().nickInUseOnlinePlayers(playerUuid, normalizedNick); } - public boolean someoneSavedUsingThis(CommandSender sender, String nickname) { - if (!ConfigHandler.getInstance().shouldOfflineNicksBeProtected()) return false; - UUID playerUuid = null; - if (sender instanceof Player playerSender) playerUuid = playerSender.getUniqueId(); - String strippedNick = miniMessage.stripTags(nickname); - UUID userWhoHasThis = SqlHandler.getInstance().nickAlreadySavedTo(playerUuid, strippedNick); - if (userWhoHasThis == null) return false; - OfflinePlayer player = Bukkit.getOfflinePlayer(userWhoHasThis); - long lastSeen = player.getLastSeen(); - long timeToProtect = ConfigHandler.getInstance().getOfflineNickProtectionTime(); - long currentTime = System.currentTimeMillis(); - return currentTime - lastSeen < timeToProtect; + public boolean someoneSavedUsingThis(CommandSender sender, String normalizedNick) { + UUID senderUuid = null; + if (sender instanceof Player playerSender) senderUuid = playerSender.getUniqueId(); + List uuidsWithThis = SqlHandler.getInstance().nickAlreadySavedTo(senderUuid, normalizedNick); + if (uuidsWithThis == null || uuidsWithThis.isEmpty()) return false; + for (UUID uuid : uuidsWithThis) { + if (SqlHandler.getInstance().lastLongOfUuid(uuid, ConfigHandler.getInstance().getOfflineNickProtectionTime()) != null) + return true; + } + return false; } diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index 3967bcb..0967b5d 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -91,7 +91,7 @@ public boolean deleteSavedNickname(UUID uuid, String nickname) { if (!sqlDeleted) return false; if (!savedNicknames.containsKey(uuid)) return false; List userSavedNicknames = savedNicknames.get(uuid); - userSavedNicknames.removeIf(name -> name.nickname().equals(nickname)); + userSavedNicknames.removeIf(name -> name.getNickname().equals(nickname)); savedNicknames.put(uuid, userSavedNicknames); return true; } @@ -112,7 +112,7 @@ public List getUuidOfNormalizedName(String nickname) { public boolean nickInUseOnlinePlayers(@Nullable UUID uuid, String normalizedNick) { for (UUID playerUuid : activeNicknames.keySet()) { if (playerUuid.equals(uuid)) continue; - if (activeNicknames.get(playerUuid).normalizedNickname().equals(normalizedNick)) return true; + if (activeNicknames.get(playerUuid).getNormalizedNickname().equals(normalizedNick)) return true; } return false; } diff --git a/src/main/java/simplexity/simplenicks/saving/Nickname.java b/src/main/java/simplexity/simplenicks/saving/Nickname.java index 38906d2..8896e83 100644 --- a/src/main/java/simplexity/simplenicks/saving/Nickname.java +++ b/src/main/java/simplexity/simplenicks/saving/Nickname.java @@ -1,4 +1,35 @@ package simplexity.simplenicks.saving; -public record Nickname(String nickname, String normalizedNickname) { +public class Nickname { + private String nickname; + private String normalizedNickname; + + public Nickname(String nickname, String normalizedNickname) { + this.nickname = nickname; + this.normalizedNickname = normalizedNickname; + } + + public String getNickname(){ + return nickname; + } + + public String getNormalizedNickname(){ + return normalizedNickname; + } + + public void setNickname(String newNick){ + nickname = newNick; + } + + public void setNormalizedNick(String newNormalizedNick){ + normalizedNickname = newNormalizedNick; + } + + @Override + public String toString(){ + return "[nickname=" + nickname + + ", normalizedNickname=" + normalizedNickname + + "]"; + } + } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index a735907..cf16194 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -73,23 +73,24 @@ REFERENCES players(uuid) @Nullable - public UUID nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { - String queryString = "SELECT 1 FROM current_nicknames WHERE nickname = ? " - + ((uuidToExclude != null) ? "AND uuid != ? " : "") + "LIMIT 1"; + public List nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { + String queryString = "SELECT uuid FROM current_nicknames WHERE nickname = ?"; + List uuidsWithName = new ArrayList<>(); try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(normalizedName)); - if (uuidToExclude != null) statement.setString(2, String.valueOf(uuidToExclude)); ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) { - return UUID.fromString(resultSet.getString("uuid")); + while (resultSet.next()) { + UUID uuid = UUID.fromString(resultSet.getString("uuid")); + if (uuid.equals(uuidToExclude)) continue; + uuidsWithName.add(uuid); } + return uuidsWithName; } catch (SQLException e) { logger.severe("Failed to check if nickname exists: " + normalizedName); e.printStackTrace(); return null; } - return null; } @Nullable @@ -249,11 +250,14 @@ public boolean playerSaveExists(UUID uuid) { } } - public Long lastLongOfUsername(String username) { - String queryString = "SELECT last_login FROM players WHERE last_known_name = ?"; + public Long lastLongOfUsername(String username, long expiryTime) { + String queryString = "SELECT last_login FROM players WHERE last_known_name = ? AND (? < 0 OR last_login >= ?)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); + long minTimeStamp = System.currentTimeMillis() - expiryTime; statement.setString(1, username); + statement.setLong(2, expiryTime); + statement.setLong(3, minTimeStamp); ResultSet resultSet = statement.executeQuery(); if (resultSet.next()) return resultSet.getLong("last_login"); return null; @@ -264,14 +268,30 @@ public Long lastLongOfUsername(String username) { } } - //todo: Add updating last login and last known name + public Long lastLongOfUuid(UUID uuid, long expiryTime) { + String queryString = "SELECT last_login FROM players WHERE uuid = ? AND (? < 0 OR last_login >= ?)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + long minTimeStamp = System.currentTimeMillis() - expiryTime; + statement.setString(1, String.valueOf(uuid)); + statement.setLong(2, expiryTime); + statement.setLong(3, minTimeStamp); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) return resultSet.getLong("last_login"); + return null; + } catch (SQLException e) { + logger.severe("Failed to get last login for UUID: " + uuid + ", with expiry time: " + expiryTime); + e.printStackTrace(); + return null; + } + } - private void savePlayerToPlayers(UUID uuid, String username) { + public void savePlayerToPlayers(UUID uuid, String username) { String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(insertQuery); statement.setString(1, String.valueOf(uuid)); - statement.setString(2, username); + statement.setString(2, username.toLowerCase()); statement.executeUpdate(); } catch (SQLException e) { logger.severe("Failed to save player: " + uuid + ", username: " + username); diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index 0e4bc6f..1857c79 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -14,4 +14,5 @@ public class Constants { public static Permission NICK_LENGTH_BYPASS = new Permission("simplenick.bypass.length"); public static Permission NICK_REGEX_BYPASS = new Permission("simplenick.bypass.regex"); public static Permission NICK_PROTECTION_BYPASS = new Permission("simplenick.bypass.nick-protection"); + public static Permission NICK_RELOAD = new Permission("simplenick.reload"); } diff --git a/src/main/resources/locale.yml b/src/main/resources/locale.yml deleted file mode 100644 index 98a8983..0000000 --- a/src/main/resources/locale.yml +++ /dev/null @@ -1,44 +0,0 @@ -plugin: - prefix: "SimpleNicks » " - help-message: > - ======================== - · Setting a nickname: - /nick set - · removing a nickname: - /nick reset" - · Formatting: - This plugin uses minimessage formatting. You can find a format viewer here" - shown-help: " has been shown the help screen" - config-reloaded: "SimpleNicks config and locale reloaded" - -error: - invalid: - command: "Invalid command." - player: "Invalid player specified" - nick: "Not a valid nickname, must follow regex: " - nick-length: "Nickname is too long, must be <= " - tags: "You have used a color or formatting tag you do not have permission to use. Please try again" - config-regex: "nickname-regex is null or malformed in file 'config.yml'. Please fix this" - arguments: - not-enough: "No arguments provided." - too-many: "Too many arguments provided." - nickname: - is-null: "Something went wrong and the nickname is null, please check your formatting" - delete-failure: "Failed to delete given username." - name-nonexistent: "Cannot delete this name because it does not exist" - save-failure: "Failed to save current username." - too-many-to-save: "You have too many saved usernames, please remove some with /nick delete " - other-players-username: "You cannot name yourself , as that is the username of another player on this server. Pick another name" - no-permission: "You do not have permission to run this command" - must-be-player: "This command cannot be run on the Console. You must be a player to run this command" -nick: - changed: - self: "Changed your nickname to !" - other: "Changed 's nickname to " - by-other: " changed your nickname to !" - reset: - self: "Reset your nickname!" - other: "Reset 's nickname." - by-other: "Your nickname was reset by " - save: "Success! The nickname has been saved for future use" - delete: "The nickname has been successfully removed from your saved names" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c3d96c3..bc3f057 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -9,13 +9,8 @@ softdepend: commands: nick: description: "Base command for SimpleNicks, Admin permission required to alter other's names." - aliases: [simplenicks, simplenick, snick] usage: "Usage: /nick [save|delete|set|reset|help|reload] [player]" permission: simplenick.nick.set - snreload: - description: "Reloads the config and locale of SimpleNicks." - aliases: [simplenicksreload, simplenickreload, snreload] - permission: simplenick.reload permissions: simplenick.admin: description: allows user to set and reset other players' nicknames @@ -28,21 +23,6 @@ permissions: description: Allows the user to clear another player's nickname children: simplenick.admin: true - simplenick.admin.restrictive: - default: op - description: Allows the user to set another player's nickname, but uses the formatting permissions of the other player - children: - simplenick.admin: true - simplenick.admin.basic: - default: op - description: Allows the user to set another player's nickname, using the formatting permissions assigned to the player with the 'admin.basic' permission - children: - simplenick.admin: true - simplenick.admin.full: - default: false - description: Allows the user to set another player's nickname, does not check the formatting permissions delegated to either player - children: - simplenick.admin: true simplenick.admin.save: default: op description: Allows the user to save another player's nickname for future use From 392257d9d354adf39e14189db6e10834d8c58039 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 20 May 2025 16:36:44 -0700 Subject: [PATCH 26/40] Added nick lookup command, incomplete --- .../simplenicks/commands/NicknameCommand.java | 2 + .../commands/arguments/NicknameArgument.java | 10 +++ .../commands/subcommands/Exceptions.java | 2 + .../subcommands/basic/LookupSubCommand.java | 63 +++++++++++++++++++ .../simplenicks/config/Message.java | 1 + .../simplenicks/logic/NickUtils.java | 5 +- .../simplexity/simplenicks/saving/Cache.java | 6 ++ .../simplenicks/saving/SqlHandler.java | 13 ++-- .../simplenicks/util/Constants.java | 1 + 9 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java index 6dc00c1..bd68943 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java @@ -5,6 +5,7 @@ import io.papermc.paper.command.brigadier.Commands; import simplexity.simplenicks.commands.subcommands.admin.AdminSubCommand; import simplexity.simplenicks.commands.subcommands.basic.DeleteSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.LookupSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ReloadSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; @@ -23,6 +24,7 @@ public static LiteralArgumentBuilder createCommand() { new DeleteSubCommand().subcommandTo(builder); new AdminSubCommand().subcommandTo(builder); new ReloadSubCommand().subcommandTo(builder); + new LookupSubCommand().subcommandTo(builder); return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java index 028e390..796cf72 100644 --- a/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java +++ b/src/main/java/simplexity/simplenicks/commands/arguments/NicknameArgument.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.Nickname; import java.util.concurrent.CompletableFuture; @@ -84,6 +85,13 @@ public class NicknameArgument implements CustomArgumentType { return builder.buildFuture(); } + public @NotNull CompletableFuture suggestAllOnlineNicknames(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder){ + for (Nickname nickname : Cache.getInstance().getOnlineNicknames().values()) { + builder.suggest(nickname.getNormalizedNickname()); + } + return builder.buildFuture(); + } + private void addSuggestionsForPlayer(@NotNull SuggestionsBuilder builder, OfflinePlayer player) { MiniMessage miniMessage = SimpleNicks.getMiniMessage(); for (Nickname nickname : NicknameProcessor.getInstance().getSavedNicknames(player)) { @@ -100,4 +108,6 @@ private void addSuggestionsForPlayer(@NotNull SuggestionsBuilder builder, Offlin } } + + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index 2a83cab..c36228f 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -139,4 +139,6 @@ public class Exceptions { ) ); + + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java new file mode 100644 index 0000000..e0895eb --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java @@ -0,0 +1,63 @@ +package simplexity.simplenicks.commands.subcommands.basic; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; +import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +import java.util.List; + +@SuppressWarnings("UnstableApiUsage") +public class LookupSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + NicknameArgument argument = new NicknameArgument(); + parent.then(Commands.literal("lookup").requires(this::canExecute) + .then(Commands.argument("nickname", argument) + .suggests(argument::suggestAllOnlineNicknames) + .executes(this::execute))); + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + CommandSender sender = ctx.getSource().getSender(); + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + List playersWithNick = NickUtils.getInstance().getOfflinePlayersByNickname(nickname.getNormalizedNickname()); + if (playersWithNick == null) throw Exceptions.ERROR_NICK_IS_NULL.create(); + sender.sendMessage("Users with name: " + nickname.getNormalizedNickname()); + if (playersWithNick.isEmpty()) { + sender.sendMessage("none"); + return 1; + } + for (OfflinePlayer player : playersWithNick) { + String username = player.getName(); + long lastSeen = player.getLastSeen(); + long currentTime = System.currentTimeMillis(); + long timeDiff = currentTime - lastSeen; + timeDiff = timeDiff / 1000; + long seconds = timeDiff % 60; + long minutes = (timeDiff / 60) % 60; + long hours = (timeDiff / (60 * 60)) % 24; + long days = (timeDiff / (60 * 60 * 24)) % 365; + sender.sendMessage("User: " + username); + sender.sendMessage("Last Seen: " + days + " days, " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds ago"); + } + return 1; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + return sender.hasPermission(Constants.NICK_LOOKUP); + } +} diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index be531f5..7f42dbf 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -30,6 +30,7 @@ public enum Message { ERROR_SET_FAILURE("error.nickname.set-failure", "Failed to set the given username."), ERROR_SAVE_FAILURE("error.nickname.save-failure", "Failed to save current name, you likely do not have a nickname currently."), ERROR_TOO_MANY_TO_SAVE("error.nickname.too-many-to-save", "You have too many saved usernames, please remove some with /nick delete "), + ERROR_NO_PLAYERS_FOUND_BY_THIS_NAME("error.nickname.no-players-found-by-this-name", "No players were found using this nickname"), ERROR_OTHER_PLAYERS_USERNAME("error.nickname.other-players-username", "You cannot name yourself , as that is the username of another player on this server. Pick another name"), ERROR_OTHER_PLAYERS_NICKNAME("error.nickname.other-players-nickname", "Sorry! Someone online is already using the nickname ! Try another one!"), ERROR_NAME_NONEXISTENT("error.nickname.name-nonexistent", "Cannot delete this name because it does not exist"), diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index 40c8721..cd61094 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -115,8 +115,9 @@ public List getOnlinePlayersByNickname(String nickname) { return playersByNick; } - public List getOfflinePlayersByNickname(String nickname) { - List usersWithThisName = Cache.getInstance().getUuidOfNormalizedName(nickname); + public List getOfflinePlayersByNickname(String normalizedNickname) { + List usersWithThisName = SqlHandler.getInstance().getUuidsOfNickname(normalizedNickname); + if (usersWithThisName == null) return null; if (usersWithThisName.isEmpty()) return new ArrayList<>(); List playersByNick = new ArrayList<>(); for (UUID uuid : usersWithThisName) { diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index 0967b5d..d1b2f22 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -5,8 +5,10 @@ import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; public class Cache { @@ -138,5 +140,9 @@ public void removePlayerFromCache(UUID uuid) { activeNicknames.remove(uuid); } + public Map getOnlineNicknames(){ + return Collections.unmodifiableMap(activeNicknames); + } + } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index cf16194..5a8630e 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -140,10 +140,12 @@ public Nickname getCurrentNicknameForPlayer(UUID uuid) { PreparedStatement getStatement = connection.prepareStatement(queryString); getStatement.setString(1, String.valueOf(uuid)); ResultSet resultSet = getStatement.executeQuery(); - if (!resultSet.next()) return null; - String nickString = resultSet.getString("nickname"); - String normalizedString = resultSet.getString("normalized"); - return new Nickname(nickString, normalizedString); + if (resultSet.next()) { + String nickString = resultSet.getString("nickname"); + String normalizedString = resultSet.getString("normalized"); + return new Nickname(nickString, normalizedString); + } + return null; } catch (SQLException e) { logger.warning("Failed to get active nickname for UUID: " + uuid); e.printStackTrace(); @@ -158,7 +160,6 @@ public List getUuidsOfNickname(String normalizeName) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, normalizeName); ResultSet resultSet = statement.executeQuery(); - if (!resultSet.next()) return new ArrayList<>(); List uuids = new ArrayList<>(); while (resultSet.next()) { uuids.add(UUID.fromString(resultSet.getString("uuid"))); @@ -294,7 +295,7 @@ public void savePlayerToPlayers(UUID uuid, String username) { statement.setString(2, username.toLowerCase()); statement.executeUpdate(); } catch (SQLException e) { - logger.severe("Failed to save player: " + uuid + ", username: " + username); + logger.severe("Failed to save player: " + uuid + ", username: " + username); e.printStackTrace(); } } diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index 1857c79..d0f5754 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -10,6 +10,7 @@ public class Constants { public static Permission NICK_COMMAND = new Permission("simplenick.nick"); public static Permission NICK_SET = new Permission("simplenick.nick.set"); public static Permission NICK_SAVE = new Permission("simplenick.nick.save"); + public static Permission NICK_LOOKUP = new Permission("simplenick.nick.lookup"); public static Permission NICK_USERNAME_BYPASS = new Permission("simplenick.bypass.username"); public static Permission NICK_LENGTH_BYPASS = new Permission("simplenick.bypass.length"); public static Permission NICK_REGEX_BYPASS = new Permission("simplenick.bypass.regex"); From 455694e1103fa89c392e530ee336bfe93560bdac Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Wed, 21 May 2025 13:53:20 -0700 Subject: [PATCH 27/40] rename lookup to who, fix formatting of message, idk what else I did --- .../simplenicks/commands/NicknameCommand.java | 4 +- .../admin/AdminResetSubCommand.java | 2 +- .../subcommands/admin/AdminSetSubCommand.java | 2 +- .../subcommands/admin/AdminSubCommand.java | 2 +- ...okupSubCommand.java => WhoSubCommand.java} | 41 ++++++++---- .../simplenicks/config/Message.java | 14 +++++ .../simplenicks/config/MessageUtils.java | 63 +++++++++++++++++++ .../simplenicks/logic/NickUtils.java | 11 ++-- .../simplenicks/util/Constants.java | 19 +++--- 9 files changed, 125 insertions(+), 33 deletions(-) rename src/main/java/simplexity/simplenicks/commands/subcommands/basic/{LookupSubCommand.java => WhoSubCommand.java} (58%) create mode 100644 src/main/java/simplexity/simplenicks/config/MessageUtils.java diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java index bd68943..2a951ff 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameCommand.java @@ -5,7 +5,7 @@ import io.papermc.paper.command.brigadier.Commands; import simplexity.simplenicks.commands.subcommands.admin.AdminSubCommand; import simplexity.simplenicks.commands.subcommands.basic.DeleteSubCommand; -import simplexity.simplenicks.commands.subcommands.basic.LookupSubCommand; +import simplexity.simplenicks.commands.subcommands.basic.WhoSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ReloadSubCommand; import simplexity.simplenicks.commands.subcommands.basic.ResetSubCommand; import simplexity.simplenicks.commands.subcommands.basic.SaveSubCommand; @@ -24,7 +24,7 @@ public static LiteralArgumentBuilder createCommand() { new DeleteSubCommand().subcommandTo(builder); new AdminSubCommand().subcommandTo(builder); new ReloadSubCommand().subcommandTo(builder); - new LookupSubCommand().subcommandTo(builder); + new WhoSubCommand().subcommandTo(builder); return builder; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java index 6edc7d0..1d1589b 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java @@ -48,7 +48,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma @Override public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); - return sender.hasPermission(Constants.NICK_RESET_OTHERS); + return sender.hasPermission(Constants.NICK_ADMIN_RESET); } @Override diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java index c59f528..d8eb249 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -61,7 +61,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma @Override public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); - return sender.hasPermission(Constants.NICK_SET_OTHERS); + return sender.hasPermission(Constants.NICK_ADMIN_SET); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java index f4d6872..8197914 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java @@ -32,7 +32,7 @@ public int execute(@NotNull CommandContext ctx) { @Override public boolean canExecute(@NotNull CommandSourceStack css) { - return css.getSender().hasPermission(Constants.NICK_OTHERS_COMMAND); + return css.getSender().hasPermission(Constants.NICK_ADMIN); } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java similarity index 58% rename from src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java rename to src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java index e0895eb..5801572 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/LookupSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java @@ -1,15 +1,22 @@ package simplexity.simplenicks.commands.subcommands.basic; +import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; +import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.MessageUtils; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -17,11 +24,14 @@ import java.util.List; @SuppressWarnings("UnstableApiUsage") -public class LookupSubCommand implements SubCommand { +public class WhoSubCommand implements SubCommand { + + private static final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + @Override public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { NicknameArgument argument = new NicknameArgument(); - parent.then(Commands.literal("lookup").requires(this::canExecute) + parent.then(Commands.literal("who").requires(this::canExecute) .then(Commands.argument("nickname", argument) .suggests(argument::suggestAllOnlineNicknames) .executes(this::execute))); @@ -34,30 +44,35 @@ public int execute(@NotNull CommandContext ctx) throws Comma Nickname nickname = ctx.getArgument("nickname", Nickname.class); List playersWithNick = NickUtils.getInstance().getOfflinePlayersByNickname(nickname.getNormalizedNickname()); if (playersWithNick == null) throw Exceptions.ERROR_NICK_IS_NULL.create(); - sender.sendMessage("Users with name: " + nickname.getNormalizedNickname()); + Component messageComponent = miniMessage.deserialize(Message.NICK_LOOKUP_HEADER.getMessage(), + Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("value", nickname.getNormalizedNickname())); if (playersWithNick.isEmpty()) { - sender.sendMessage("none"); - return 1; + messageComponent = messageComponent.append(miniMessage.deserialize( + Message.INSERT_NONE.getMessage())); + sender.sendMessage(messageComponent); + return Command.SINGLE_SUCCESS; } for (OfflinePlayer player : playersWithNick) { String username = player.getName(); + if (username == null) continue; long lastSeen = player.getLastSeen(); long currentTime = System.currentTimeMillis(); long timeDiff = currentTime - lastSeen; timeDiff = timeDiff / 1000; - long seconds = timeDiff % 60; - long minutes = (timeDiff / 60) % 60; - long hours = (timeDiff / (60 * 60)) % 24; - long days = (timeDiff / (60 * 60 * 24)) % 365; - sender.sendMessage("User: " + username); - sender.sendMessage("Last Seen: " + days + " days, " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds ago"); + messageComponent = messageComponent.append(miniMessage.deserialize( + Message.NICK_LOOKUP_USER.getMessage() + Message.INSERT_TIME_FORMAT_AGO.getMessage(), + Placeholder.parsed("name", username), + MessageUtils.getTimeFormat(timeDiff))); + } - return 1; + sender.sendMessage(messageComponent); + return Command.SINGLE_SUCCESS; } @Override public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); - return sender.hasPermission(Constants.NICK_LOOKUP); + return sender.hasPermission(Constants.NICK_WHO); } } diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index 7f42dbf..9d6869d 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -14,6 +14,20 @@ public enum Message { RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), + NICK_LOOKUP_HEADER("nick.lookup.header", "Users with the name : "), + NICK_LOOKUP_USER("nick.lookup.user", "\n- - Last Seen: "), + INSERT_TIME_FORMAT_GROUP("insert.time-format.group", ""), + INSERT_TIME_FORMAT_DAY("insert.time-format.day", " day"), + INSERT_TIME_FORMAT_DAYS("insert.time-format.days", " days"), + INSERT_TIME_FORMAT_HOUR("insert.time-format.hour", " hour"), + INSERT_TIME_FORMAT_HOURS("insert.time-format.hours", " hours"), + INSERT_TIME_FORMAT_MINUTE("insert.time-format.minute", " min"), + INSERT_TIME_FORMAT_MINUTES("insert.time-format.minute", " mins"), + INSERT_TIME_FORMAT_SECOND("insert.time-format.second", " sec"), + INSERT_TIME_FORMAT_SECONDS("insert.time-format.second", " secs"), + INSERT_TIME_FORMAT_NOW("insert.time-format.now", "Now"), + INSERT_TIME_FORMAT_AGO("insert.time-format.ago", " ago"), + INSERT_NONE("insert.none", "None"), ERROR_INVALID_COMMAND("error.invalid.command", "Invalid command."), ERROR_INVALID_PLAYER("error.invalid.player", "Invalid player specified"), ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), diff --git a/src/main/java/simplexity/simplenicks/config/MessageUtils.java b/src/main/java/simplexity/simplenicks/config/MessageUtils.java new file mode 100644 index 0000000..1b35860 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/config/MessageUtils.java @@ -0,0 +1,63 @@ +package simplexity.simplenicks.config; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import simplexity.simplenicks.SimpleNicks; + +public class MessageUtils { + + + private static final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + public static TagResolver getTimeFormat(long timeSeconds) { + long seconds = timeSeconds % 60; + long minutes = (timeSeconds / 60) % 60; + long hours = (timeSeconds / (60 * 60)) % 24; + long days = (timeSeconds / (60 * 60 * 24)) % 365; + Component dayComponent = Component.empty(); + Component hourComponent = Component.empty(); + Component minuteComponent = Component.empty(); + Component secondComponent = Component.empty(); + if (days > 0) { + if (days == 1) { + dayComponent = parseNumber(Message.INSERT_TIME_FORMAT_DAY.getMessage(), days); + } else { + dayComponent = parseNumber(Message.INSERT_TIME_FORMAT_DAYS.getMessage(), days); + } + } + if (hours > 0) { + if (hours == 1) { + hourComponent = parseNumber(Message.INSERT_TIME_FORMAT_HOUR.getMessage(), hours); + } else { + hourComponent = parseNumber(Message.INSERT_TIME_FORMAT_HOURS.getMessage(), hours); + } + } + if (minutes > 0) { + if (minutes == 1) { + minuteComponent = parseNumber(Message.INSERT_TIME_FORMAT_MINUTE.getMessage(), minutes); + } else { + minuteComponent = parseNumber(Message.INSERT_TIME_FORMAT_MINUTES.getMessage(), minutes); + } + } + if (seconds > 0) { + if (seconds == 1) { + secondComponent = parseNumber(Message.INSERT_TIME_FORMAT_SECOND.getMessage(), seconds); + } else { + secondComponent = parseNumber(Message.INSERT_TIME_FORMAT_SECONDS.getMessage(), seconds); + } + } + Component finalComponent = miniMessage.deserialize(Message.INSERT_TIME_FORMAT_GROUP.getMessage(), + Placeholder.component("day", dayComponent), + Placeholder.component("hour", hourComponent), + Placeholder.component("min", minuteComponent), + Placeholder.component("sec", secondComponent)); + return TagResolver.resolver(Placeholder.component("time", finalComponent)); + } + + private static Component parseNumber(String message, long number) { + return miniMessage.deserialize(message, + Placeholder.parsed("count", String.valueOf(number))); + } +} diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index cd61094..cfe8635 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import java.util.logging.Logger; import java.util.regex.Pattern; @SuppressWarnings("UnusedReturnValue") @@ -44,22 +43,22 @@ public void nicknameChecks(CommandSender sender, Nickname nickname) throws Comma if (normalizedNick.isEmpty()) { throw Exceptions.ERROR_EMPTY_NICK_AFTER_PARSE.create(); } - if (!sender.hasPermission(Constants.NICK_USERNAME_BYPASS) && thisIsSomeonesUsername(normalizedNick)) { + if (!sender.hasPermission(Constants.NICK_BYPASS_USERNAME) && thisIsSomeonesUsername(normalizedNick)) { throw Exceptions.ERROR_NICKNAME_IS_SOMEONES_USERNAME.create(normalizedNick); } - if (!sender.hasPermission(Constants.NICK_LENGTH_BYPASS) && normalizedNick.length() > ConfigHandler.getInstance().getMaxLength()) { + if (!sender.hasPermission(Constants.NICK_BYPASS_LENGTH) && normalizedNick.length() > ConfigHandler.getInstance().getMaxLength()) { throw Exceptions.ERROR_LENGTH.create(normalizedNick); } - if (!sender.hasPermission(Constants.NICK_REGEX_BYPASS) && !passesRegexCheck(normalizedNick)) { + if (!sender.hasPermission(Constants.NICK_BYPASS_REGEX) && !passesRegexCheck(normalizedNick)) { throw Exceptions.ERROR_REGEX.create(normalizedNick); } if (ConfigHandler.getInstance().shouldOnlineNicksBeProtected()) { - if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneOnlineUsingThis(sender, normalizedNick)) { + if (!sender.hasPermission(Constants.NICK_BYPASS_NICK_PROTECTION) && someoneOnlineUsingThis(sender, normalizedNick)) { throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(normalizedNick); } } if (ConfigHandler.getInstance().shouldOfflineNicksBeProtected()) { - if (!sender.hasPermission(Constants.NICK_PROTECTION_BYPASS) && someoneSavedUsingThis(sender, normalizedNick)) { + if (!sender.hasPermission(Constants.NICK_BYPASS_NICK_PROTECTION) && someoneSavedUsingThis(sender, normalizedNick)) { throw Exceptions.ERROR_SOMEONE_USING_THAT_NICKNAME.create(normalizedNick); } } diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index d0f5754..2accab6 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -3,17 +3,18 @@ import org.bukkit.permissions.Permission; public class Constants { - public static Permission NICK_OTHERS_COMMAND = new Permission("simplenick.admin"); - public static Permission NICK_SET_OTHERS = new Permission("simplenick.admin.set"); - public static Permission NICK_RESET_OTHERS = new Permission("simplenick.admin.reset"); - public static Permission NICK_GET_OTHERS = new Permission("simplenick.admin.get"); + public static Permission NICK_ADMIN = new Permission("simplenick.admin"); + public static Permission NICK_ADMIN_SET = new Permission("simplenick.admin.set"); + public static Permission NICK_ADMIN_RESET = new Permission("simplenick.admin.reset"); + public static Permission NICK_ADMIN_REMOVE = new Permission("simplenick.admin.remove"); + public static Permission NICK_ADMIN_LOOKUP = new Permission("simplenick.admin.lookup"); public static Permission NICK_COMMAND = new Permission("simplenick.nick"); public static Permission NICK_SET = new Permission("simplenick.nick.set"); public static Permission NICK_SAVE = new Permission("simplenick.nick.save"); - public static Permission NICK_LOOKUP = new Permission("simplenick.nick.lookup"); - public static Permission NICK_USERNAME_BYPASS = new Permission("simplenick.bypass.username"); - public static Permission NICK_LENGTH_BYPASS = new Permission("simplenick.bypass.length"); - public static Permission NICK_REGEX_BYPASS = new Permission("simplenick.bypass.regex"); - public static Permission NICK_PROTECTION_BYPASS = new Permission("simplenick.bypass.nick-protection"); + public static Permission NICK_WHO = new Permission("simplenick.nick.who"); + public static Permission NICK_BYPASS_USERNAME = new Permission("simplenick.bypass.username"); + public static Permission NICK_BYPASS_LENGTH = new Permission("simplenick.bypass.length"); + public static Permission NICK_BYPASS_REGEX = new Permission("simplenick.bypass.regex"); + public static Permission NICK_BYPASS_NICK_PROTECTION = new Permission("simplenick.bypass.nick-protection"); public static Permission NICK_RELOAD = new Permission("simplenick.reload"); } From f41681771f8cc1e8965cd571b5a410babc5f77ab Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 27 May 2025 09:54:40 -0700 Subject: [PATCH 28/40] start on admin lookup command --- .../admin/AdminLookupSubCommand.java | 46 +++++++++++++++++++ .../subcommands/basic/WhoSubCommand.java | 4 +- .../simplenicks/config/Message.java | 4 +- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java new file mode 100644 index 0000000..42384cf --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java @@ -0,0 +1,46 @@ +package simplexity.simplenicks.commands.subcommands.admin; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; +import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.saving.Nickname; +import simplexity.simplenicks.util.Constants; + +import java.util.List; + +@SuppressWarnings("UnstableApiUsage") +public class AdminLookupSubCommand implements SubCommand { + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + OfflinePlayerArgument offlinePlayerArg = new OfflinePlayerArgument(); + parent.then(Commands.literal("lookup") + .requires(this::canExecute) + .then(Commands.argument("player", offlinePlayerArg) + .suggests(offlinePlayerArg::suggestOnlinePlayers) + .executes(this::execute))); + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + CommandSender sender = ctx.getSource().getSender(); + OfflinePlayer lookupTarget = ctx.getArgument("player", OfflinePlayer.class); + Nickname currentNickname = NicknameProcessor.getInstance().getCurrentNickname(lookupTarget); + List savedNicknames = NicknameProcessor.getInstance().getSavedNicknames(lookupTarget); + return 0; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + return sender.hasPermission(Constants.NICK_ADMIN_LOOKUP); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java index 5801572..ba147c3 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java @@ -44,7 +44,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma Nickname nickname = ctx.getArgument("nickname", Nickname.class); List playersWithNick = NickUtils.getInstance().getOfflinePlayersByNickname(nickname.getNormalizedNickname()); if (playersWithNick == null) throw Exceptions.ERROR_NICK_IS_NULL.create(); - Component messageComponent = miniMessage.deserialize(Message.NICK_LOOKUP_HEADER.getMessage(), + Component messageComponent = miniMessage.deserialize(Message.NICK_WHO_HEADER.getMessage(), Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", nickname.getNormalizedNickname())); if (playersWithNick.isEmpty()) { @@ -61,7 +61,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma long timeDiff = currentTime - lastSeen; timeDiff = timeDiff / 1000; messageComponent = messageComponent.append(miniMessage.deserialize( - Message.NICK_LOOKUP_USER.getMessage() + Message.INSERT_TIME_FORMAT_AGO.getMessage(), + Message.NICK_WHO_USER.getMessage() + Message.INSERT_TIME_FORMAT_AGO.getMessage(), Placeholder.parsed("name", username), MessageUtils.getTimeFormat(timeDiff))); diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/Message.java index 9d6869d..80dace7 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/Message.java @@ -14,8 +14,8 @@ public enum Message { RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), - NICK_LOOKUP_HEADER("nick.lookup.header", "Users with the name : "), - NICK_LOOKUP_USER("nick.lookup.user", "\n- - Last Seen: "), + NICK_WHO_HEADER("nick.who.header", "Users with the name : "), + NICK_WHO_USER("nick.who.user", "\n- - Last Seen: "), INSERT_TIME_FORMAT_GROUP("insert.time-format.group", ""), INSERT_TIME_FORMAT_DAY("insert.time-format.day", " day"), INSERT_TIME_FORMAT_DAYS("insert.time-format.days", " days"), From b391a2dabcec5d1f9bac60d019d2671f0d4fb6b2 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 10 Jun 2025 16:20:07 -0700 Subject: [PATCH 29/40] Admin lookup command works now, refactor Message class to be called LocaleMessage --- .../simplexity/simplenicks/SimpleNicks.java | 4 +- .../commands/NicknameProcessor.java | 16 +- .../commands/subcommands/Exceptions.java | 70 +-- .../admin/AdminDeleteSubCommand.java | 29 ++ .../admin/AdminLookupSubCommand.java | 43 +- .../admin/AdminResetSubCommand.java | 9 +- .../subcommands/admin/AdminSetSubCommand.java | 6 +- .../subcommands/admin/AdminSubCommand.java | 1 + .../subcommands/basic/DeleteSubCommand.java | 4 +- .../subcommands/basic/ReloadSubCommand.java | 6 +- .../subcommands/basic/ResetSubCommand.java | 4 +- .../subcommands/basic/SaveSubCommand.java | 6 +- .../subcommands/basic/SetSubCommand.java | 4 +- .../subcommands/basic/SubCommand.java | 14 +- .../subcommands/basic/WhoSubCommand.java | 10 +- .../simplenicks/config/ConfigHandler.java | 2 +- .../simplenicks/config/LocaleHandler.java | 15 +- .../{Message.java => LocaleMessage.java} | 12 +- .../simplenicks/config/MessageUtils.java | 40 +- .../simplenicks/hooks/SNExpansion.java | 22 +- .../simplenicks/logic/NickUtils.java | 8 +- .../simplexity/simplenicks/saving/Cache.java | 14 +- .../simplenicks/saving/SqlHandler.java | 429 +++++++++--------- .../simplenicks/util/Constants.java | 2 +- 24 files changed, 458 insertions(+), 312 deletions(-) create mode 100644 src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java rename src/main/java/simplexity/simplenicks/config/{Message.java => LocaleMessage.java} (87%) diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index e987c2c..e24d90b 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -38,8 +38,8 @@ public void onEnable() { if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { new SNExpansion().register(); } - instance.getServer().getPluginManager().registerEvents(new LoginListener(), this); - instance.getServer().getPluginManager().registerEvents(new LeaveListener(), this); + getServer().getPluginManager().registerEvents(new LoginListener(), this); + getServer().getPluginManager().registerEvents(new LeaveListener(), this); configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index 9491205..aded1e0 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -37,7 +37,7 @@ public boolean setNickname(OfflinePlayer player, String nickname) { NickUtils.getInstance().refreshNickname(playerUuid); } String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().setActiveNickname(playerUuid, username, nickname, normalizedNick); + return SqlHandler.getInstance().setActiveNickname(playerUuid, username, nickname, normalizedNick).join(); } public boolean resetNickname(OfflinePlayer player) { @@ -49,7 +49,7 @@ public boolean resetNickname(OfflinePlayer player) { NickUtils.getInstance().refreshNickname(playerUuid); return true; } - return SqlHandler.getInstance().clearActiveNickname(playerUuid); + return SqlHandler.getInstance().clearActiveNickname(playerUuid).join(); } public boolean saveNickname(OfflinePlayer player, String nickname) { @@ -63,7 +63,7 @@ public boolean saveNickname(OfflinePlayer player, String nickname) { return true; } String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().saveNickname(playerUuid, username, nickname, normalizedNick); + return SqlHandler.getInstance().saveNickname(playerUuid, username, nickname, normalizedNick).join(); } public boolean deleteNickname(OfflinePlayer player, String nickname) { @@ -75,14 +75,14 @@ public boolean deleteNickname(OfflinePlayer player, String nickname) { NickUtils.getInstance().refreshNickname(playerUuid); return true; } - return SqlHandler.getInstance().deleteNickname(playerUuid, nickname); + return SqlHandler.getInstance().deleteNickname(playerUuid, nickname).join(); } public List getSavedNicknames(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getSavedNicknames(playerUuid); - List nicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); + List nicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid).join(); if (nicks == null) return new ArrayList<>(); return nicks; } @@ -92,14 +92,14 @@ public Nickname getCurrentNickname(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getActiveNickname(playerUuid); - return SqlHandler.getInstance().getCurrentNicknameForPlayer(playerUuid); + return SqlHandler.getInstance().getCurrentNicknameForPlayer(playerUuid).join(); } public int getCurrentSavedNickCount(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getSavedNickCount(playerUuid); - List savedNicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); + List savedNicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid).join(); if (savedNicks == null || savedNicks.isEmpty()) return 0; return savedNicks.size(); } @@ -107,7 +107,7 @@ public int getCurrentSavedNickCount(OfflinePlayer player) { public boolean playerAlreadySavedThis(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); - return SqlHandler.getInstance().userAlreadySavedThisName(playerUuid, nickname); + return SqlHandler.getInstance().userAlreadySavedThisName(playerUuid, nickname).join(); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index c36228f..390ac16 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -7,7 +7,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; @SuppressWarnings("UnstableApiUsage") public class Exceptions { @@ -17,8 +17,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_DELETE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_DELETE_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_DELETE_FAILURE.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -26,8 +26,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_NICK_IS_NULL = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_NICK_IS_NULL.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_NICK_IS_NULL.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -35,8 +35,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_EMPTY_NICK_AFTER_PARSE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_INVALID_NICK_EMPTY.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_INVALID_NICK_EMPTY.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -44,8 +44,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_SAVE_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_SAVE_FAILURE.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -54,8 +54,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_INVALID_COMMAND = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_INVALID_COMMAND.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_INVALID_COMMAND.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -63,8 +63,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -72,8 +72,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_UNABLE_TO_RESET_NICK = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_RESET_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_RESET_FAILURE.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -81,8 +81,8 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_SET_FAILURE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_SET_FAILURE.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_SET_FAILURE.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -90,10 +90,10 @@ public class Exceptions { public static final DynamicCommandExceptionType ERROR_LENGTH = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_INVALID_NICK_LENGTH.getMessage(), + LocaleMessage.ERROR_INVALID_NICK_LENGTH.getMessage(), Placeholder.unparsed("value", String.valueOf(ConfigHandler.getInstance().getMaxLength())), Placeholder.unparsed("name", nickname.toString()), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -101,9 +101,9 @@ public class Exceptions { public static final DynamicCommandExceptionType ERROR_REGEX = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_INVALID_NICK.getMessage(), + LocaleMessage.ERROR_INVALID_NICK.getMessage(), Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -111,9 +111,9 @@ public class Exceptions { public static final DynamicCommandExceptionType ERROR_PLAYER_NOT_FOUND = new DynamicCommandExceptionType( playerName -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_INVALID_PLAYER.getMessage(), + LocaleMessage.ERROR_INVALID_PLAYER.getMessage(), Placeholder.unparsed("player_name", playerName.toString()), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()) + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) ) ) ); @@ -121,8 +121,8 @@ public class Exceptions { public static final DynamicCommandExceptionType ERROR_NICKNAME_IS_SOMEONES_USERNAME = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_OTHER_PLAYERS_USERNAME.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + LocaleMessage.ERROR_OTHER_PLAYERS_USERNAME.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.unparsed("value", nickname.toString()) ) ) @@ -132,13 +132,29 @@ public class Exceptions { public static final DynamicCommandExceptionType ERROR_SOMEONE_USING_THAT_NICKNAME = new DynamicCommandExceptionType( nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( - Message.ERROR_OTHER_PLAYERS_NICKNAME.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + LocaleMessage.ERROR_OTHER_PLAYERS_NICKNAME.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.unparsed("value", nickname.toString()) ) ) ); + public static final SimpleCommandExceptionType ERROR_DATABASE_ISSUE = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + LocaleMessage.ERROR_CANNOT_REACH_DATABASE.getMessage() + ) + ) + ); + + public static final SimpleCommandExceptionType ERROR_NO_NICKNAMES = new SimpleCommandExceptionType( + MessageComponentSerializer.message().serialize( + miniMessage.deserialize( + LocaleMessage.ERROR_USER_HAS_NO_NICKNAMES.getMessage() + ) + ) + ); + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java new file mode 100644 index 0000000..a09e875 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java @@ -0,0 +1,29 @@ +package simplexity.simplenicks.commands.subcommands.admin; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.util.Constants; + +public class AdminDeleteSubCommand implements SubCommand { + + @Override + public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + + } + + @Override + public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { + return 0; + } + + @Override + public boolean canExecute(@NotNull CommandSourceStack css) { + CommandSender sender = css.getSender(); + return sender.hasPermission(Constants.NICK_ADMIN_DELETE); + } +} diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java index 42384cf..ecbe651 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java @@ -1,16 +1,24 @@ package simplexity.simplenicks.commands.subcommands.admin; +import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.config.MessageUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -18,6 +26,10 @@ @SuppressWarnings("UnstableApiUsage") public class AdminLookupSubCommand implements SubCommand { + + private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); + + @Override public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { OfflinePlayerArgument offlinePlayerArg = new OfflinePlayerArgument(); @@ -33,9 +45,11 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); OfflinePlayer lookupTarget = ctx.getArgument("player", OfflinePlayer.class); + String username = lookupTarget.getName(); Nickname currentNickname = NicknameProcessor.getInstance().getCurrentNickname(lookupTarget); List savedNicknames = NicknameProcessor.getInstance().getSavedNicknames(lookupTarget); - return 0; + sender.sendMessage(lookupInfoComponent(username, currentNickname, savedNicknames)); + return Command.SINGLE_SUCCESS; } @Override @@ -43,4 +57,31 @@ public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); return sender.hasPermission(Constants.NICK_ADMIN_LOOKUP); } + + public Component lookupInfoComponent(String username, Nickname currentNick, List savedNames) throws CommandSyntaxException { + if (currentNick == null && (savedNames == null || savedNames.isEmpty())) + throw Exceptions.ERROR_NO_NICKNAMES.create(); + Component nickname; + if (currentNick == null) { + nickname = miniMessage.deserialize(LocaleMessage.INSERT_NONE.getMessage()); + } else { + nickname = miniMessage.deserialize(currentNick.getNickname()); + } + + Component infoComponent = miniMessage.deserialize( + LocaleMessage.ADMIN_NICK_LOOKUP_HEADER.getMessage(), + Placeholder.unparsed("username", username)); + infoComponent = infoComponent.append( + miniMessage.deserialize( + LocaleMessage.ADMIN_NICK_LOOKUP_CURRENT_NICK.getMessage(), + Placeholder.component("name", nickname)) + ); + infoComponent = infoComponent.append( + miniMessage.deserialize( + LocaleMessage.ADMIN_NICK_LOOKUP_SAVED_NICKS_HEADER.getMessage(), + MessageUtils.savedNickListResolver(savedNames) + ) + ); + return infoComponent; + } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java index 1d1589b..c5f56a9 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java @@ -15,7 +15,7 @@ import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -39,9 +39,10 @@ public int execute(@NotNull CommandContext ctx) throws Comma OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); boolean resetNick = NicknameProcessor.getInstance().resetNickname(target); if (!resetNick) throw Exceptions.ERROR_UNABLE_TO_RESET_NICK.create(); - sender.sendMessage(parseAdminMessage(Message.RESET_OTHER.getMessage(), "", sender, target)); - if (target instanceof Player onlineTarget) - onlineTarget.sendMessage(parseAdminMessage(Message.RESET_BY_OTHER.getMessage(), "", sender, target)); + sender.sendMessage(parseAdminMessage(LocaleMessage.RESET_OTHER.getMessage(), "", sender, target)); + if (target instanceof Player onlineTarget) { + onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.RESET_BY_OTHER.getMessage(), "", sender, target)); + } return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java index d8eb249..c5c5c07 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -15,7 +15,7 @@ import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -52,9 +52,9 @@ public int execute(@NotNull CommandContext ctx) throws Comma NickUtils.getInstance().nicknameChecks(sender, nickname); boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, cleanedNick); if (!setSuccessfully) throw Exceptions.ERROR_SET_FAILURE.create(); - sender.sendMessage(parseAdminMessage(Message.CHANGED_OTHER.getMessage(), cleanedNick, sender, target)); + sender.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_OTHER.getMessage(), cleanedNick, sender, target)); if (target instanceof Player onlineTarget) - onlineTarget.sendMessage(parseAdminMessage(Message.CHANGED_BY_OTHER.getMessage(), cleanedNick, sender, target)); + onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_BY_OTHER.getMessage(), cleanedNick, sender, target)); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java index 8197914..a757d3f 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java @@ -20,6 +20,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par new AdminSetSubCommand().subcommandTo(admin); new AdminResetSubCommand().subcommandTo(admin); + new AdminLookupSubCommand().subcommandTo(admin); parent.then(admin); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index f8e8761..f03a113 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -12,7 +12,7 @@ import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -39,7 +39,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma Nickname nickname = ctx.getArgument("nickname", Nickname.class); boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.getNickname()); if (deleted) { - if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, Message.DELETE_NICK, nickname); + if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, LocaleMessage.DELETE_NICK, nickname); return Command.SINGLE_SUCCESS; } throw Exceptions.ERROR_CANNOT_DELETE.create(); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java index 1eaafbe..536999a 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java @@ -10,7 +10,7 @@ import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.config.ConfigHandler; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -25,8 +25,8 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); ConfigHandler.getInstance().reloadConfig(); - sender.sendRichMessage(Message.CONFIG_RELOADED.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage())); + sender.sendRichMessage(LocaleMessage.CONFIG_RELOADED.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage())); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java index 2364e38..7e8f7a9 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java @@ -8,7 +8,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.commands.NicknameProcessor; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -25,7 +25,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) { Player player = (Player) ctx.getSource().getSender(); NicknameProcessor.getInstance().resetNickname(player); - sendFeedback(player, Message.RESET_SELF, null); + sendFeedback(player, LocaleMessage.RESET_SELF, null); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java index 1c7c28b..cbd093d 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -11,7 +11,7 @@ import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -45,7 +45,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma if (!saved) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } - sendFeedback(player, Message.SAVE_NICK, nickname); + sendFeedback(player, LocaleMessage.SAVE_NICK, nickname); return Command.SINGLE_SUCCESS; } @@ -57,7 +57,7 @@ public int executeWithArgument(@NotNull CommandContext ctx) if (!saved) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } - sendFeedback(player, Message.SAVE_NICK, nickname); + sendFeedback(player, LocaleMessage.SAVE_NICK, nickname); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index bd04c05..d4b621c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -12,7 +12,7 @@ import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -44,7 +44,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma Player player = (Player) ctx.getSource().getSender(); NickUtils.getInstance().nicknameChecks(player, nickname); NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.getNickname()); - sendFeedback(player, Message.CHANGED_SELF, nickname); + sendFeedback(player, LocaleMessage.CHANGED_SELF, nickname); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index 27be116..7151d79 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -15,7 +15,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.saving.Nickname; import java.util.concurrent.CompletableFuture; @@ -52,14 +52,14 @@ public interface SubCommand { * Sends a feedback message to the player, confirming the command went through properly * * @param player Player - * @param message Message + * @param localeMessage Message * @param nickname Nickname */ - default void sendFeedback(Player player, Message message, Nickname nickname) { + default void sendFeedback(Player player, LocaleMessage localeMessage, Nickname nickname) { if (nickname == null) nickname = new Nickname("", ""); player.sendRichMessage( - message.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + localeMessage.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", nickname.getNickname()) ); } @@ -82,10 +82,10 @@ default Component parseAdminMessage(String message, String value, CommandSender if (initiator instanceof Player playerInitiator) { initiatorName = playerInitiator.displayName(); } else { - initiatorName = miniMessage.deserialize(Message.SERVER_DISPLAY_NAME.getMessage()); + initiatorName = miniMessage.deserialize(LocaleMessage.SERVER_DISPLAY_NAME.getMessage()); } return miniMessage.deserialize(message, - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", value), Placeholder.component("initiator", initiatorName), Placeholder.parsed("target", targetUserName) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java index ba147c3..7a36aac 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java @@ -15,7 +15,7 @@ import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; -import simplexity.simplenicks.config.Message; +import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.config.MessageUtils; import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; @@ -44,12 +44,12 @@ public int execute(@NotNull CommandContext ctx) throws Comma Nickname nickname = ctx.getArgument("nickname", Nickname.class); List playersWithNick = NickUtils.getInstance().getOfflinePlayersByNickname(nickname.getNormalizedNickname()); if (playersWithNick == null) throw Exceptions.ERROR_NICK_IS_NULL.create(); - Component messageComponent = miniMessage.deserialize(Message.NICK_WHO_HEADER.getMessage(), - Placeholder.parsed("prefix", Message.PLUGIN_PREFIX.getMessage()), + Component messageComponent = miniMessage.deserialize(LocaleMessage.NICK_WHO_HEADER.getMessage(), + Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", nickname.getNormalizedNickname())); if (playersWithNick.isEmpty()) { messageComponent = messageComponent.append(miniMessage.deserialize( - Message.INSERT_NONE.getMessage())); + LocaleMessage.INSERT_NONE.getMessage())); sender.sendMessage(messageComponent); return Command.SINGLE_SUCCESS; } @@ -61,7 +61,7 @@ public int execute(@NotNull CommandContext ctx) throws Comma long timeDiff = currentTime - lastSeen; timeDiff = timeDiff / 1000; messageComponent = messageComponent.append(miniMessage.deserialize( - Message.NICK_WHO_USER.getMessage() + Message.INSERT_TIME_FORMAT_AGO.getMessage(), + LocaleMessage.NICK_WHO_USER.getMessage() + LocaleMessage.INSERT_TIME_FORMAT_AGO.getMessage(), Placeholder.parsed("name", username), MessageUtils.getTimeFormat(timeDiff))); diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index bd59925..d703e5d 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -46,7 +46,7 @@ public void reloadConfig() { regexString = regexSetting; regex = Pattern.compile(regexSetting); } catch (PatternSyntaxException e) { - logger.severe(Message.ERROR_INVALID_CONFIG_REGEX.getMessage()); + logger.severe(LocaleMessage.ERROR_INVALID_CONFIG_REGEX.getMessage()); } mySql = config.getBoolean("mysql.enabled", false); mySqlIp = config.getString("mysql.ip", "localhost:3306"); diff --git a/src/main/java/simplexity/simplenicks/config/LocaleHandler.java b/src/main/java/simplexity/simplenicks/config/LocaleHandler.java index a4c9529..075e7ca 100644 --- a/src/main/java/simplexity/simplenicks/config/LocaleHandler.java +++ b/src/main/java/simplexity/simplenicks/config/LocaleHandler.java @@ -51,16 +51,16 @@ public void reloadLocale() { private void populateLocale() { - Set missing = new HashSet<>(Arrays.asList(Message.values())); - for (Message message : Message.values()) { - if (locale.contains(message.getPath())) { - message.setMessage(locale.getString(message.getPath())); - missing.remove(message); + Set missing = new HashSet<>(Arrays.asList(LocaleMessage.values())); + for (LocaleMessage localeMessage : LocaleMessage.values()) { + if (locale.contains(localeMessage.getPath())) { + localeMessage.setMessage(locale.getString(localeMessage.getPath())); + missing.remove(localeMessage); } } - for (Message message : missing) { - locale.set(message.getPath(), message.getMessage()); + for (LocaleMessage localeMessage : missing) { + locale.set(localeMessage.getPath(), localeMessage.getMessage()); } @@ -86,4 +86,3 @@ private void saveLocale() { } } - diff --git a/src/main/java/simplexity/simplenicks/config/Message.java b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java similarity index 87% rename from src/main/java/simplexity/simplenicks/config/Message.java rename to src/main/java/simplexity/simplenicks/config/LocaleMessage.java index 80dace7..58f3753 100644 --- a/src/main/java/simplexity/simplenicks/config/Message.java +++ b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java @@ -1,6 +1,6 @@ package simplexity.simplenicks.config; -public enum Message { +public enum LocaleMessage { PLUGIN_PREFIX("plugin.prefix", "SimpleNicks » "), HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), @@ -16,6 +16,9 @@ public enum Message { DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), NICK_WHO_HEADER("nick.who.header", "Users with the name : "), NICK_WHO_USER("nick.who.user", "\n- - Last Seen: "), + ADMIN_NICK_LOOKUP_HEADER("nick.admin.lookup.header", "'s nickname info:"), + ADMIN_NICK_LOOKUP_CURRENT_NICK("nick.admin.lookup.current-nick", "\nCurrent Nick: "), + ADMIN_NICK_LOOKUP_SAVED_NICKS_HEADER("nick.admin.lookup.saved-nicks", "\nSaved Nicknames:"), INSERT_TIME_FORMAT_GROUP("insert.time-format.group", ""), INSERT_TIME_FORMAT_DAY("insert.time-format.day", " day"), INSERT_TIME_FORMAT_DAYS("insert.time-format.days", " days"), @@ -28,6 +31,8 @@ public enum Message { INSERT_TIME_FORMAT_NOW("insert.time-format.now", "Now"), INSERT_TIME_FORMAT_AGO("insert.time-format.ago", " ago"), INSERT_NONE("insert.none", "None"), + INSERT_SAVED_NICK("insert.saved-nick.format", "\n- "), + INSERT_NO_SAVED_NICKS("insert.saved-nick.none", "\n(none)"), ERROR_INVALID_COMMAND("error.invalid.command", "Invalid command."), ERROR_INVALID_PLAYER("error.invalid.player", "Invalid player specified"), ERROR_INVALID_NICK("error.invalid.nick", "Not a valid nickname, must follow regex: "), @@ -51,13 +56,14 @@ public enum Message { ERROR_NO_PERMISSION("error.no-permission", "You do not have permission to run this command"), ERROR_MUST_BE_PLAYER("error.must-be-player", "This command cannot be run on the Console. You must be a player to run this command"), ERROR_MULTIPLE_PLAYERS_BY_THAT_NAME("error.multiple-players-by-that-name", "There are multiple online players by that name, please try using the actual username."), - ; + ERROR_CANNOT_REACH_DATABASE("error.cannot-reach-database", "There was an issue reaching the database and your command was unable to be completed. Please let a staff member know about this issue if it continues"), + ERROR_USER_HAS_NO_NICKNAMES("error.user-has-no-nicknames", "This user is not associated with any nicknames"); private final String path; private String message; - Message(String path, String message) { + LocaleMessage(String path, String message) { this.path = path; this.message = message; } diff --git a/src/main/java/simplexity/simplenicks/config/MessageUtils.java b/src/main/java/simplexity/simplenicks/config/MessageUtils.java index 1b35860..75cad16 100644 --- a/src/main/java/simplexity/simplenicks/config/MessageUtils.java +++ b/src/main/java/simplexity/simplenicks/config/MessageUtils.java @@ -5,6 +5,9 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import simplexity.simplenicks.SimpleNicks; +import simplexity.simplenicks.saving.Nickname; + +import java.util.List; public class MessageUtils { @@ -22,33 +25,33 @@ public static TagResolver getTimeFormat(long timeSeconds) { Component secondComponent = Component.empty(); if (days > 0) { if (days == 1) { - dayComponent = parseNumber(Message.INSERT_TIME_FORMAT_DAY.getMessage(), days); + dayComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_DAY.getMessage(), days); } else { - dayComponent = parseNumber(Message.INSERT_TIME_FORMAT_DAYS.getMessage(), days); + dayComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_DAYS.getMessage(), days); } } if (hours > 0) { if (hours == 1) { - hourComponent = parseNumber(Message.INSERT_TIME_FORMAT_HOUR.getMessage(), hours); + hourComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_HOUR.getMessage(), hours); } else { - hourComponent = parseNumber(Message.INSERT_TIME_FORMAT_HOURS.getMessage(), hours); + hourComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_HOURS.getMessage(), hours); } } if (minutes > 0) { if (minutes == 1) { - minuteComponent = parseNumber(Message.INSERT_TIME_FORMAT_MINUTE.getMessage(), minutes); + minuteComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_MINUTE.getMessage(), minutes); } else { - minuteComponent = parseNumber(Message.INSERT_TIME_FORMAT_MINUTES.getMessage(), minutes); + minuteComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_MINUTES.getMessage(), minutes); } } if (seconds > 0) { if (seconds == 1) { - secondComponent = parseNumber(Message.INSERT_TIME_FORMAT_SECOND.getMessage(), seconds); + secondComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_SECOND.getMessage(), seconds); } else { - secondComponent = parseNumber(Message.INSERT_TIME_FORMAT_SECONDS.getMessage(), seconds); + secondComponent = parseNumber(LocaleMessage.INSERT_TIME_FORMAT_SECONDS.getMessage(), seconds); } } - Component finalComponent = miniMessage.deserialize(Message.INSERT_TIME_FORMAT_GROUP.getMessage(), + Component finalComponent = miniMessage.deserialize(LocaleMessage.INSERT_TIME_FORMAT_GROUP.getMessage(), Placeholder.component("day", dayComponent), Placeholder.component("hour", hourComponent), Placeholder.component("min", minuteComponent), @@ -56,8 +59,27 @@ public static TagResolver getTimeFormat(long timeSeconds) { return TagResolver.resolver(Placeholder.component("time", finalComponent)); } + public static TagResolver savedNickListResolver(List nicknames) { + if (nicknames == null || nicknames.isEmpty()) { + return TagResolver.resolver(Placeholder.component("list", + miniMessage.deserialize(LocaleMessage.INSERT_NO_SAVED_NICKS.getMessage()))); + } + Component finalComponent = Component.empty(); + for (Nickname nick : nicknames) { + Component nickname = miniMessage.deserialize(nick.getNickname()); + finalComponent = finalComponent.append( + miniMessage.deserialize( + LocaleMessage.INSERT_SAVED_NICK.getMessage(), + Placeholder.component("name", nickname) + )); + } + return TagResolver.resolver(Placeholder.component("list", finalComponent)); + } + private static Component parseNumber(String message, long number) { return miniMessage.deserialize(message, Placeholder.parsed("count", String.valueOf(number))); } + + } diff --git a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java index 0bbd9c1..3281fbb 100644 --- a/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java +++ b/src/main/java/simplexity/simplenicks/hooks/SNExpansion.java @@ -20,7 +20,7 @@ public class SNExpansion extends PlaceholderExpansion { @Override public @NotNull String getVersion() { - return "1.0.0"; + return "1.1.0"; } @Override @@ -30,14 +30,20 @@ public boolean persist() { @Override public String onRequest(OfflinePlayer player, @NotNull String params) { - if (params.equalsIgnoreCase("mininick")) { - Nickname nickname = Cache.getInstance().getActiveNickname(player.getUniqueId()); - if (nickname != null) { - String prefix = ConfigHandler.getInstance().getNickPrefix(); - if (prefix == null || prefix.isEmpty()) return nickname.getNickname(); - return prefix + nickname.getNickname(); + Nickname nickname = Cache.getInstance().getActiveNickname(player.getUniqueId()); + if (params.equalsIgnoreCase("nick-no-prefix")) { + if (nickname == null) { + return player.getName(); } - return player.getName(); + return nickname.getNickname(); + } + if (params.equalsIgnoreCase("mininick") || params.equalsIgnoreCase("nick")) { + if (nickname == null) { + return player.getName(); + } + String prefix = ConfigHandler.getInstance().getNickPrefix(); + if (prefix == null || prefix.isEmpty()) return nickname.getNickname(); + return prefix + nickname.getNickname(); } return null; } diff --git a/src/main/java/simplexity/simplenicks/logic/NickUtils.java b/src/main/java/simplexity/simplenicks/logic/NickUtils.java index cfe8635..6735259 100644 --- a/src/main/java/simplexity/simplenicks/logic/NickUtils.java +++ b/src/main/java/simplexity/simplenicks/logic/NickUtils.java @@ -115,7 +115,7 @@ public List getOnlinePlayersByNickname(String nickname) { } public List getOfflinePlayersByNickname(String normalizedNickname) { - List usersWithThisName = SqlHandler.getInstance().getUuidsOfNickname(normalizedNickname); + List usersWithThisName = SqlHandler.getInstance().getUuidsOfNickname(normalizedNickname).join(); if (usersWithThisName == null) return null; if (usersWithThisName.isEmpty()) return new ArrayList<>(); List playersByNick = new ArrayList<>(); @@ -136,7 +136,7 @@ public boolean thisIsSomeonesUsername(String normalizedName) { long protectionTime = ConfigHandler.getInstance().getUsernameProtectionTime(); if (protectionTime < 0) return false; normalizedName = normalizedName.toLowerCase(); - return SqlHandler.getInstance().lastLongOfUsername(normalizedName, ConfigHandler.getInstance().getUsernameProtectionTime()) != null; + return SqlHandler.getInstance().lastLongOfUsername(normalizedName, ConfigHandler.getInstance().getUsernameProtectionTime()).join() != null; } public boolean someoneOnlineUsingThis(CommandSender sender, String normalizedNick) { @@ -148,10 +148,10 @@ public boolean someoneOnlineUsingThis(CommandSender sender, String normalizedNic public boolean someoneSavedUsingThis(CommandSender sender, String normalizedNick) { UUID senderUuid = null; if (sender instanceof Player playerSender) senderUuid = playerSender.getUniqueId(); - List uuidsWithThis = SqlHandler.getInstance().nickAlreadySavedTo(senderUuid, normalizedNick); + List uuidsWithThis = SqlHandler.getInstance().nickAlreadySavedTo(senderUuid, normalizedNick).join(); if (uuidsWithThis == null || uuidsWithThis.isEmpty()) return false; for (UUID uuid : uuidsWithThis) { - if (SqlHandler.getInstance().lastLongOfUuid(uuid, ConfigHandler.getInstance().getOfflineNickProtectionTime()) != null) + if (SqlHandler.getInstance().lastLongOfUuid(uuid, ConfigHandler.getInstance().getOfflineNickProtectionTime()).join() != null) return true; } return false; diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index d1b2f22..3ae6a02 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -33,7 +33,7 @@ public static Cache getInstance() { */ public void loadCurrentNickname(UUID uuid) { - Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid); + Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid).join(); if (currentNick == null) return; activeNicknames.put(uuid, currentNick); } @@ -56,7 +56,7 @@ public Nickname getActiveNickname(UUID uuid) { * @param uuid Player's UUID */ public void loadSavedNicknames(UUID uuid) { - List savedNames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid); + List savedNames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid).join(); if (savedNames == null || savedNames.isEmpty()) return; savedNicknames.put(uuid, savedNames); } @@ -82,14 +82,14 @@ public List getSavedNicknames(UUID uuid) { public boolean setActiveNickname(UUID uuid, String username, String nickname) { String normalizedNick = miniMessage.stripTags(nickname); Nickname nick = new Nickname(nickname, normalizedNick); - boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, username, nickname, normalizedNick); + boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, username, nickname, normalizedNick).join(); if (!sqlActiveNameSet) return false; activeNicknames.put(uuid, nick); return true; } public boolean deleteSavedNickname(UUID uuid, String nickname) { - boolean sqlDeleted = SqlHandler.getInstance().deleteNickname(uuid, nickname); + boolean sqlDeleted = SqlHandler.getInstance().deleteNickname(uuid, nickname).join(); if (!sqlDeleted) return false; if (!savedNicknames.containsKey(uuid)) return false; List userSavedNicknames = savedNicknames.get(uuid); @@ -99,14 +99,14 @@ public boolean deleteSavedNickname(UUID uuid, String nickname) { } public boolean clearCurrentNickname(UUID uuid) { - boolean sqlNickRemoved = SqlHandler.getInstance().clearActiveNickname(uuid); + boolean sqlNickRemoved = SqlHandler.getInstance().clearActiveNickname(uuid).join(); if (!sqlNickRemoved) return false; activeNicknames.remove(uuid); return true; } public List getUuidOfNormalizedName(String nickname) { - List uuids = SqlHandler.getInstance().getUuidsOfNickname(nickname); + List uuids = SqlHandler.getInstance().getUuidsOfNickname(nickname).join(); if (uuids == null) return new ArrayList<>(); return uuids; } @@ -124,7 +124,7 @@ public boolean saveNickname(UUID uuid, String username, String nickname) { Nickname nick = new Nickname(nickname, strippedNick); List userSavedNicknames = getSavedNicknames(uuid); userSavedNicknames.add(nick); - boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, username, nickname, strippedNick); + boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, username, nickname, strippedNick).join(); if (!savedToSql) return false; savedNicknames.put(uuid, userSavedNicknames); return true; diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 5a8630e..978f8dc 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -2,6 +2,7 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import org.slf4j.Logger; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.ConfigHandler; @@ -13,7 +14,8 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import java.util.logging.Logger; +import java.util.concurrent.CompletableFuture; + @SuppressWarnings({"CallToPrintStackTrace", "BooleanMethodIsAlwaysInverted"}) public class SqlHandler { @@ -29,7 +31,7 @@ public static SqlHandler getInstance() { private static final HikariConfig hikariConfig = new HikariConfig(); private static HikariDataSource dataSource; - private final Logger logger = SimpleNicks.getSimpleNicksLogger(); + private final Logger logger = SimpleNicks.getInstance().getSLF4JLogger(); public void init() { try (Connection connection = getConnection()) { @@ -66,238 +68,261 @@ REFERENCES players(uuid) """); currentNickStatement.execute(); } catch (SQLException e) { - logger.severe("Issue connecting to database, info below: "); - e.printStackTrace(); + logger.warn("Issue connecting to database: {} ", e.getMessage(), e); } } - @Nullable - public List nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { - String queryString = "SELECT uuid FROM current_nicknames WHERE nickname = ?"; - List uuidsWithName = new ArrayList<>(); - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, String.valueOf(normalizedName)); - ResultSet resultSet = statement.executeQuery(); - while (resultSet.next()) { - UUID uuid = UUID.fromString(resultSet.getString("uuid")); - if (uuid.equals(uuidToExclude)) continue; - uuidsWithName.add(uuid); + public CompletableFuture> nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { + return CompletableFuture.supplyAsync(() -> { + String queryString = "SELECT uuid FROM current_nicknames WHERE nickname = ?"; + List uuidsWithName = new ArrayList<>(); + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(normalizedName)); + ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + UUID uuid = UUID.fromString(resultSet.getString("uuid")); + if (uuid.equals(uuidToExclude)) continue; + uuidsWithName.add(uuid); + } + return uuidsWithName; + } catch (SQLException e) { + logger.warn("Failed to check if nickname exists: {}", normalizedName, e); + return null; } - return uuidsWithName; - } catch (SQLException e) { - logger.severe("Failed to check if nickname exists: " + normalizedName); - e.printStackTrace(); - return null; - } + }); } - @Nullable - public List getSavedNicknamesForPlayer(UUID uuid) { - List savedNicknames = new ArrayList<>(); - if (!playerSaveExists(uuid)) return savedNicknames; - String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, String.valueOf(uuid)); - ResultSet resultSet = statement.executeQuery(); - while (resultSet.next()) { - String nicknameString = resultSet.getString("nickname"); - String normalizedString = resultSet.getString("normalized"); - Nickname nick = new Nickname(nicknameString, normalizedString); - savedNicknames.add(nick); + public CompletableFuture> getSavedNicknamesForPlayer(UUID uuid) { + return CompletableFuture.supplyAsync(() -> { + List savedNicknames = new ArrayList<>(); + if (!playerSaveExists(uuid).join()) return savedNicknames; + String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + String nicknameString = resultSet.getString("nickname"); + String normalizedString = resultSet.getString("normalized"); + Nickname nick = new Nickname(nicknameString, normalizedString); + savedNicknames.add(nick); + } + } catch (SQLException e) { + logger.warn("Failed to get saved nicknames for player with UUID: {}", uuid, e); + return null; } - } catch (SQLException e) { - logger.severe("Failed to get saved nicknames for player: " + uuid); - e.printStackTrace(); - return null; - } - return savedNicknames; + return savedNicknames; + }); } - public boolean userAlreadySavedThisName(UUID uuid, String nickname) { - if (!playerSaveExists(uuid)) return false; - String queryString = "SELECT nickname FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, String.valueOf(uuid)); - statement.setString(2, nickname); - ResultSet resultSet = statement.executeQuery(); - return resultSet.next(); - } catch (SQLException e) { - logger.warning("Failed to check if UUID '" + uuid + "' has already saved the nickname '" + nickname + "'"); - e.printStackTrace(); - return false; - } + public CompletableFuture userAlreadySavedThisName(UUID uuid, String nickname) { + return CompletableFuture.supplyAsync(() -> { + if (!playerSaveExists(uuid).join()) return false; + String queryString = "SELECT nickname FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nickname); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.warn("Failed to check if UUID '{}' has already saved the nickname '{}'", uuid, nickname, e); + return false; + } + }); } - @Nullable - public Nickname getCurrentNicknameForPlayer(UUID uuid) { - if (!playerSaveExists(uuid)) return null; - String queryString = "SELECT nickname, normalized FROM current_nicknames WHERE uuid = ?"; - try (Connection connection = getConnection()) { - PreparedStatement getStatement = connection.prepareStatement(queryString); - getStatement.setString(1, String.valueOf(uuid)); - ResultSet resultSet = getStatement.executeQuery(); - if (resultSet.next()) { - String nickString = resultSet.getString("nickname"); - String normalizedString = resultSet.getString("normalized"); - return new Nickname(nickString, normalizedString); + + public CompletableFuture getCurrentNicknameForPlayer(UUID uuid) { + return CompletableFuture.supplyAsync(() -> { + if (!playerSaveExists(uuid).join()) return null; + String queryString = "SELECT nickname, normalized FROM current_nicknames WHERE uuid = ?"; + try (Connection connection = getConnection()) { + PreparedStatement getStatement = connection.prepareStatement(queryString); + getStatement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = getStatement.executeQuery(); + if (resultSet.next()) { + String nickString = resultSet.getString("nickname"); + String normalizedString = resultSet.getString("normalized"); + return new Nickname(nickString, normalizedString); + } + return null; + } catch (SQLException e) { + logger.warn("Failed to get active nickname for UUID: {}", uuid, e); + return null; } - return null; - } catch (SQLException e) { - logger.warning("Failed to get active nickname for UUID: " + uuid); - e.printStackTrace(); - } - return null; + }); } - @Nullable - public List getUuidsOfNickname(String normalizeName) { - String queryString = "SELECT uuid FROM current_nicknames WHERE normalized = ?"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, normalizeName); - ResultSet resultSet = statement.executeQuery(); - List uuids = new ArrayList<>(); - while (resultSet.next()) { - uuids.add(UUID.fromString(resultSet.getString("uuid"))); + + public CompletableFuture> getUuidsOfNickname(String normalizeName) { + return CompletableFuture.supplyAsync(() -> { + String queryString = "SELECT uuid FROM current_nicknames WHERE normalized = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, normalizeName); + ResultSet resultSet = statement.executeQuery(); + List uuids = new ArrayList<>(); + while (resultSet.next()) { + uuids.add(UUID.fromString(resultSet.getString("uuid"))); + } + return uuids; + } catch (SQLException e) { + logger.warn("Failed to get UUID list from normalized nickname: {}", normalizeName, e); + return null; } - return uuids; - } catch (SQLException e) { - logger.warning("Failed to get UUID list from normalized nickname"); - e.printStackTrace(); - return null; - } + }); } - public boolean saveNickname(UUID uuid, String username, String nickname, String normalizedNickname) { - String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) savePlayerToPlayers(uuid, username); - try (Connection connection = getConnection()) { - PreparedStatement saveStatement = connection.prepareStatement(saveString); - saveStatement.setString(1, String.valueOf(uuid)); - saveStatement.setString(2, nickname); - saveStatement.setString(3, normalizedNickname); - int rowsModified = saveStatement.executeUpdate(); - return rowsModified > 0; - } catch (SQLException e) { - logger.severe("Failed to save nickname: " + nickname + " for UUID: " + uuid); - e.printStackTrace(); - return false; - } + public CompletableFuture saveNickname(UUID uuid, String username, String nickname, String normalizedNickname) { + return CompletableFuture.supplyAsync(() -> { + String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; + if (!playerSaveExists(uuid).join()) { + if (!savePlayerToPlayers(uuid, username).join()) return false; + } + try (Connection connection = getConnection()) { + PreparedStatement saveStatement = connection.prepareStatement(saveString); + saveStatement.setString(1, String.valueOf(uuid)); + saveStatement.setString(2, nickname); + saveStatement.setString(3, normalizedNickname); + int rowsChanged = saveStatement.executeUpdate(); + return rowsChanged > 0; + } catch (SQLException e) { + logger.warn("Failed to save nickname '{}' for UUID '{}'. Normalized nickname: {}, Username: {} ", + nickname, uuid, normalizedNickname, username, e); + return false; + } + }); } - public boolean deleteNickname(UUID uuid, String nickname) { - if (!playerSaveExists(uuid)) return false; - String deleteQuery = "DELETE FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(deleteQuery); - statement.setString(1, String.valueOf(uuid)); - statement.setString(2, nickname); - int rowsAffected = statement.executeUpdate(); - return rowsAffected > 0; - } catch (SQLException e) { - logger.warning("Failed to delete nickname '" + nickname + "' for UUID '" + uuid + "'"); - e.printStackTrace(); - return false; - } + public CompletableFuture deleteNickname(UUID uuid, String nickname) { + return CompletableFuture.supplyAsync(() -> { + if (!playerSaveExists(uuid).join()) return null; + String deleteQuery = "DELETE FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(deleteQuery); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nickname); + int rowsChanged = statement.executeUpdate(); + return rowsChanged > 0; + } catch (SQLException e) { + logger.warn("Failed to delete nickname '{}' for UUID '{}'", nickname, uuid, e); + return false; + } + }); } - public boolean clearActiveNickname(UUID uuid) { - if (!playerSaveExists(uuid)) return true; - String deleteQuery = "DELETE FROM current_nicknames WHERE uuid = ?"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(deleteQuery); - statement.setString(1, String.valueOf(uuid)); - int rowsAffected = statement.executeUpdate(); - return rowsAffected > 0; - } catch (SQLException e) { - logger.warning("Failed to clear active nickname for UUID: " + uuid); - e.printStackTrace(); - return false; - } + + public CompletableFuture clearActiveNickname(UUID uuid) { + return CompletableFuture.supplyAsync(() -> { + if (!playerSaveExists(uuid).join()) return false; + String deleteQuery = "DELETE FROM current_nicknames WHERE uuid = ?"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(deleteQuery); + statement.setString(1, String.valueOf(uuid)); + int rowsAffected = statement.executeUpdate(); + return rowsAffected > 0; + } catch (SQLException e) { + logger.warn("Failed to clear active nickname for UUID '{}'", uuid, e); + return false; + } + }); } - public boolean setActiveNickname(UUID uuid, String username, String nicknameString, String normalizedString) { - String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; - if (!playerSaveExists(uuid)) savePlayerToPlayers(uuid, username); - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(setQuery); - statement.setString(1, String.valueOf(uuid)); - statement.setString(2, nicknameString); - statement.setString(3, normalizedString); - int rowsModified = statement.executeUpdate(); - return rowsModified > 0; - } catch (SQLException e) { - logger.warning("Failed to set active nickname '" + nicknameString + "' for UUID '" + uuid + "'"); - e.printStackTrace(); - return false; - } + + public CompletableFuture setActiveNickname(UUID uuid, String username, String nicknameString, String normalizedString) { + return CompletableFuture.supplyAsync(() -> { + String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; + if (!playerSaveExists(uuid).join()) { + if (!savePlayerToPlayers(uuid, username).join()) return false; + } + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(setQuery); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, nicknameString); + statement.setString(3, normalizedString); + int rowsModified = statement.executeUpdate(); + return rowsModified > 0; + } catch (SQLException e) { + logger.warn("Failed to set active nickname '{}' for UUID '{}'. Normalized name: {}, Username: {}", + nicknameString, uuid, normalizedString, username, e); + e.printStackTrace(); + return false; + } + }); } - public boolean playerSaveExists(UUID uuid) { - String queryString = "SELECT 1 FROM players WHERE uuid = ? LIMIT 1"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, String.valueOf(uuid)); - ResultSet resultSet = statement.executeQuery(); - return resultSet.next(); - } catch (SQLException e) { - logger.severe("Failed to check if player exists: " + uuid); - e.printStackTrace(); - return false; - } + + public CompletableFuture playerSaveExists(UUID uuid) { + return CompletableFuture.supplyAsync(() -> { + String queryString = "SELECT 1 FROM players WHERE uuid = ? LIMIT 1"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + statement.setString(1, String.valueOf(uuid)); + ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.warn("Failed to check if player with UUID {} exists", uuid, e); + e.printStackTrace(); + return false; + } + }); } - public Long lastLongOfUsername(String username, long expiryTime) { - String queryString = "SELECT last_login FROM players WHERE last_known_name = ? AND (? < 0 OR last_login >= ?)"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - long minTimeStamp = System.currentTimeMillis() - expiryTime; - statement.setString(1, username); - statement.setLong(2, expiryTime); - statement.setLong(3, minTimeStamp); - ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) return resultSet.getLong("last_login"); - return null; - } catch (SQLException e) { - logger.severe("Failed to get last login for username: " + username); - e.printStackTrace(); - return null; - } + public CompletableFuture lastLongOfUsername(String username, long expiryTime) { + return CompletableFuture.supplyAsync(() -> { + String queryString = "SELECT last_login FROM players WHERE last_known_name = ? AND (? < 0 OR last_login >= ?)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + long minTimeStamp = System.currentTimeMillis() - expiryTime; + statement.setString(1, username); + statement.setLong(2, expiryTime); + statement.setLong(3, minTimeStamp); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) return resultSet.getLong("last_login"); + return null; + } catch (SQLException e) { + logger.warn("Failed to get last login for username: {}, expiry time: {}", username, expiryTime, e); + return null; + } + }); } - public Long lastLongOfUuid(UUID uuid, long expiryTime) { - String queryString = "SELECT last_login FROM players WHERE uuid = ? AND (? < 0 OR last_login >= ?)"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(queryString); - long minTimeStamp = System.currentTimeMillis() - expiryTime; - statement.setString(1, String.valueOf(uuid)); - statement.setLong(2, expiryTime); - statement.setLong(3, minTimeStamp); - ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) return resultSet.getLong("last_login"); - return null; - } catch (SQLException e) { - logger.severe("Failed to get last login for UUID: " + uuid + ", with expiry time: " + expiryTime); - e.printStackTrace(); - return null; - } + public CompletableFuture lastLongOfUuid(UUID uuid, long expiryTime) { + return CompletableFuture.supplyAsync(() -> { + String queryString = "SELECT last_login FROM players WHERE uuid = ? AND (? < 0 OR last_login >= ?)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(queryString); + long minTimeStamp = System.currentTimeMillis() - expiryTime; + statement.setString(1, String.valueOf(uuid)); + statement.setLong(2, expiryTime); + statement.setLong(3, minTimeStamp); + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) return resultSet.getLong("last_login"); + return null; + } catch (SQLException e) { + logger.warn("Failed to get last login for UUID: {}, with expiry time: {}", uuid, expiryTime, e); + return null; + } + }); } - public void savePlayerToPlayers(UUID uuid, String username) { - String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; - try (Connection connection = getConnection()) { - PreparedStatement statement = connection.prepareStatement(insertQuery); - statement.setString(1, String.valueOf(uuid)); - statement.setString(2, username.toLowerCase()); - statement.executeUpdate(); - } catch (SQLException e) { - logger.severe("Failed to save player: " + uuid + ", username: " + username); - e.printStackTrace(); - } + public CompletableFuture savePlayerToPlayers(UUID uuid, String username) { + return CompletableFuture.supplyAsync(() -> { + String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; + try (Connection connection = getConnection()) { + PreparedStatement statement = connection.prepareStatement(insertQuery); + statement.setString(1, String.valueOf(uuid)); + statement.setString(2, username.toLowerCase()); + int rowsChanged = statement.executeUpdate(); + return rowsChanged > 0; + } catch (SQLException e) { + logger.warn("Failed to save player with UUID: {}, username: {}", uuid, username, e); + return false; + } + }); } public void setupConfig() { diff --git a/src/main/java/simplexity/simplenicks/util/Constants.java b/src/main/java/simplexity/simplenicks/util/Constants.java index 2accab6..d21c352 100644 --- a/src/main/java/simplexity/simplenicks/util/Constants.java +++ b/src/main/java/simplexity/simplenicks/util/Constants.java @@ -6,7 +6,7 @@ public class Constants { public static Permission NICK_ADMIN = new Permission("simplenick.admin"); public static Permission NICK_ADMIN_SET = new Permission("simplenick.admin.set"); public static Permission NICK_ADMIN_RESET = new Permission("simplenick.admin.reset"); - public static Permission NICK_ADMIN_REMOVE = new Permission("simplenick.admin.remove"); + public static Permission NICK_ADMIN_DELETE = new Permission("simplenick.admin.delete"); public static Permission NICK_ADMIN_LOOKUP = new Permission("simplenick.admin.lookup"); public static Permission NICK_COMMAND = new Permission("simplenick.nick"); public static Permission NICK_SET = new Permission("simplenick.nick.set"); From e2b82e61bc7e880a8ef031bc79089a4b4aa7562a Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Fri, 25 Jul 2025 18:12:56 -0700 Subject: [PATCH 30/40] Admin delete command works --- .../admin/AdminDeleteSubCommand.java | 33 +++++++++++++++- .../subcommands/admin/AdminSubCommand.java | 1 + .../simplenicks/config/LocaleMessage.java | 2 + src/main/resources/plugin.yml | 38 ------------------- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java index a09e875..bc055d6 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java @@ -1,24 +1,54 @@ package simplexity.simplenicks.commands.subcommands.admin; +import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.commands.NicknameProcessor; +import simplexity.simplenicks.commands.arguments.NicknameArgument; +import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; +import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; +import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; +@SuppressWarnings("UnstableApiUsage") public class AdminDeleteSubCommand implements SubCommand { @Override public void subcommandTo(@NotNull LiteralArgumentBuilder parent) { + OfflinePlayerArgument offlinePlayerArg = new OfflinePlayerArgument(); + NicknameArgument nicknameArg = new NicknameArgument(); + parent.then(Commands.literal("delete") + .requires(this::canExecute) + .then(Commands.argument("player", offlinePlayerArg) + .suggests(offlinePlayerArg::suggestOnlinePlayers) + .then(Commands.argument("nickname", nicknameArg) + .suggests(nicknameArg::suggestOtherNicknames) + .executes(this::execute)))); } @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { - return 0; + CommandSender sender = ctx.getSource().getSender(); + OfflinePlayer targetPlayer = ctx.getArgument("player", OfflinePlayer.class); + Nickname nickname = ctx.getArgument("nickname", Nickname.class); + boolean deleted = NicknameProcessor.getInstance().deleteNickname(targetPlayer, nickname.getNickname()); + if (deleted) { + sender.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_OTHER.getMessage(), nickname.getNickname(), sender, targetPlayer)); + if (targetPlayer instanceof Player player) + player.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_BY_OTHER.getMessage(), nickname.getNickname(), sender, targetPlayer)); + return Command.SINGLE_SUCCESS; + } + throw Exceptions.ERROR_CANNOT_DELETE.create(); } @Override @@ -26,4 +56,5 @@ public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); return sender.hasPermission(Constants.NICK_ADMIN_DELETE); } + } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java index a757d3f..2c1101f 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSubCommand.java @@ -21,6 +21,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par new AdminSetSubCommand().subcommandTo(admin); new AdminResetSubCommand().subcommandTo(admin); new AdminLookupSubCommand().subcommandTo(admin); + new AdminDeleteSubCommand().subcommandTo(admin); parent.then(admin); diff --git a/src/main/java/simplexity/simplenicks/config/LocaleMessage.java b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java index 58f3753..e2ce769 100644 --- a/src/main/java/simplexity/simplenicks/config/LocaleMessage.java +++ b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java @@ -14,6 +14,8 @@ public enum LocaleMessage { RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), + NICK_DELETED_BY_OTHER("nick.delete.by-other", "The nickname has been deleted from your saved nicknames by "), + NICK_DELETED_OTHER("nick.delete.other", "You have successfully deleted from 's saved nicknames"), NICK_WHO_HEADER("nick.who.header", "Users with the name : "), NICK_WHO_USER("nick.who.user", "\n- - Last Seen: "), ADMIN_NICK_LOOKUP_HEADER("nick.admin.lookup.header", "'s nickname info:"), diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index bc3f057..6759730 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -15,24 +15,15 @@ permissions: simplenick.admin: description: allows user to set and reset other players' nicknames default: op - children: - simplenick.nick: true - simplenick.nick.set: true simplenick.admin.reset: default: op description: Allows the user to clear another player's nickname - children: - simplenick.admin: true simplenick.admin.save: default: op description: Allows the user to save another player's nickname for future use - children: - simplenick.admin: true simplenick.admin.delete: default: op description: Allows the user to delete one of another player's saved nicknames - children: - simplenick.admin: true simplenick.reload: description: allows a user to reload the locale and config of this plugin default: op @@ -51,65 +42,36 @@ permissions: simplenick.nick.save: description: save your current nickname for future use, only works on 'FILE' save type default: op - children: - simplenick.nick: true simplenick.nick.delete: description: delete one of your previously saved nicknames default: op - children: - simplenick.nick: true simplenick.nick.set: description: allows usage of the /nick command default: op - children: - simplenick.nick: true simplenick.nick.reset: description: allows a user to reset their own nickname default: op - children: - simplenick.nick: true simplenick.nick.color: description: allows color codes to be used in a nickname default: op - children: - simplenick.nick: true simplenick.nick.gradient: description: allows gradients to be used in a nickname default: op - children: - simplenick.nick: true simplenick.nick.rainbow: description: allows the rainbow tag to be used in a nickname default: op - children: - simplenick.nick: true simplenick.nick.format.reset: description: allows the reset formatting tag to be used in a nickname default: op - children: - simplenick.nick: true - simplenick.nick.format: true simplenick.nick.format.italic: description: allows the italic formatting tag to be used in a nickname default: op - children: - simplenick.nick: true - simplenick.nick.format: true simplenick.nick.format.strikethrough: description: allows the strikethrough formatting tag to be used in a nickname default: op - children: - simplenick.nick: true - simplenick.nick.format: true simplenick.nick.format.bold: description: allows the bold format tag to be used in a nickname default: op - children: - simplenick.nick: true - simplenick.nick.format: true simplenick.nick.format.obfuscated: description: allows the obfuscated format tag to be used in a nickname default: op - children: - simplenick.nick: true - simplenick.nick.format: true \ No newline at end of file From 41451e04aabc4007c15df0671514e721e1e8c91d Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sun, 27 Jul 2025 18:00:01 -0700 Subject: [PATCH 31/40] I don't understand --- .../simplexity/simplenicks/SimpleNicks.java | 2 + .../simplenicks/listener/LoginListener.java | 4 +- .../simplenicks/saving/AbstractSaving.java | 22 ---- .../simplenicks/saving/PlayerPDC.java | 60 ----------- .../simplenicks/saving/SaveMigrator.java | 92 ++++++++++++++++ .../simplenicks/saving/YMLFile.java | 102 ------------------ 6 files changed, 97 insertions(+), 185 deletions(-) delete mode 100644 src/main/java/simplexity/simplenicks/saving/AbstractSaving.java delete mode 100644 src/main/java/simplexity/simplenicks/saving/PlayerPDC.java create mode 100644 src/main/java/simplexity/simplenicks/saving/SaveMigrator.java delete mode 100644 src/main/java/simplexity/simplenicks/saving/YMLFile.java diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index e24d90b..560b86a 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -9,6 +9,7 @@ import simplexity.simplenicks.hooks.SNExpansion; import simplexity.simplenicks.listener.LeaveListener; import simplexity.simplenicks.listener.LoginListener; +import simplexity.simplenicks.saving.SaveMigrator; import simplexity.simplenicks.saving.SqlHandler; import java.util.logging.Logger; @@ -43,6 +44,7 @@ public void onEnable() { configReload(); SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); + SaveMigrator.migrateFromYml(); this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { commands.registrar().register(NicknameCommand.createCommand().build()); }); diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index 47266b2..a9179ec 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -6,14 +6,16 @@ import org.bukkit.event.player.PlayerJoinEvent; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.logic.NickUtils; +import simplexity.simplenicks.saving.SaveMigrator; import simplexity.simplenicks.saving.SqlHandler; import java.util.UUID; public class LoginListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void onPlayerLogin(PlayerJoinEvent joinEvent) { + public void onPlayerJoin(PlayerJoinEvent joinEvent) { UUID playerUuid = joinEvent.getPlayer().getUniqueId(); + SaveMigrator.migratePdcNickname(joinEvent.getPlayer()); Cache.getInstance().loadCurrentNickname(playerUuid); Cache.getInstance().loadSavedNicknames(playerUuid); NickUtils.getInstance().refreshNickname(playerUuid); diff --git a/src/main/java/simplexity/simplenicks/saving/AbstractSaving.java b/src/main/java/simplexity/simplenicks/saving/AbstractSaving.java deleted file mode 100644 index 481ea6e..0000000 --- a/src/main/java/simplexity/simplenicks/saving/AbstractSaving.java +++ /dev/null @@ -1,22 +0,0 @@ -package simplexity.simplenicks.saving; - -import org.bukkit.OfflinePlayer; - -import java.util.List; - -public abstract class AbstractSaving { - - public abstract void init(); - - public abstract String getNickname(OfflinePlayer offlinePlayer); - - public abstract boolean setNickname(OfflinePlayer offlinePlayer, String nickname); - - public abstract boolean saveNickname(OfflinePlayer offlinePlayer, String nickname); - - public abstract boolean deleteNickname(OfflinePlayer offlinePlayer, String nickname); - - public abstract boolean resetNickname(OfflinePlayer offlinePlayer); - - public abstract List getSavedNicknames(OfflinePlayer offlinePlayer); -} diff --git a/src/main/java/simplexity/simplenicks/saving/PlayerPDC.java b/src/main/java/simplexity/simplenicks/saving/PlayerPDC.java deleted file mode 100644 index 5c392fc..0000000 --- a/src/main/java/simplexity/simplenicks/saving/PlayerPDC.java +++ /dev/null @@ -1,60 +0,0 @@ -package simplexity.simplenicks.saving; - -import org.bukkit.NamespacedKey; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import simplexity.simplenicks.SimpleNicks; - -import java.util.ArrayList; -import java.util.List; - -public class PlayerPDC extends AbstractSaving { - public static final NamespacedKey nickNameSave = new NamespacedKey(SimpleNicks.getInstance(), "nickname"); - - @Override - public void init() { - } - - @Override - public String getNickname(OfflinePlayer offlinePlayer) { - Player player = offlinePlayer.getPlayer(); - if (player == null) return null; - PersistentDataContainer pdc = offlinePlayer.getPlayer().getPersistentDataContainer(); - return pdc.get(nickNameSave, PersistentDataType.STRING); - } - - @Override - public boolean setNickname(OfflinePlayer offlinePlayer, String nickname) { - Player player = offlinePlayer.getPlayer(); - if (player == null) return false; - PersistentDataContainer pdc = offlinePlayer.getPlayer().getPersistentDataContainer(); - pdc.set(nickNameSave, PersistentDataType.STRING, nickname); - return true; - } - - @Override - public boolean saveNickname(OfflinePlayer offlinePlayer, String nickname) { - return false; - } - - @Override - public boolean deleteNickname(OfflinePlayer offlinePlayer, String nickname) { - return false; - } - - @Override - public boolean resetNickname(OfflinePlayer offlinePlayer) { - Player player = offlinePlayer.getPlayer(); - if (player == null) return false; - PersistentDataContainer pdc = offlinePlayer.getPlayer().getPersistentDataContainer(); - pdc.remove(nickNameSave); - return true; - } - - @Override - public List getSavedNicknames(OfflinePlayer offlinePlayer) { - return new ArrayList<>(); - } -} diff --git a/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java b/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java new file mode 100644 index 0000000..01f1897 --- /dev/null +++ b/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java @@ -0,0 +1,92 @@ +package simplexity.simplenicks.saving; + +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.slf4j.Logger; +import simplexity.simplenicks.SimpleNicks; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +public class SaveMigrator { + + private static final Logger logger = SimpleNicks.getInstance().getSLF4JLogger(); + public static final NamespacedKey nickNameSave = new NamespacedKey(SimpleNicks.getInstance(), "nickname"); + + + public static void migrateFromYml() { + File dataFile = new File(SimpleNicks.getInstance().getDataFolder(), "nickname_data.yml"); + if (!dataFile.exists()) return; + FileConfiguration nicknameData = new YamlConfiguration(); + try { + nicknameData.load(dataFile); + } catch (IOException | InvalidConfigurationException e) { + logger.warn("Unable to migrate nicknames from YML: {}", e.getMessage(), e); + } + int migratedUsers = 0; + for (String uuidString : nicknameData.getKeys(false)) { + UUID uuid; + try { + uuid = UUID.fromString(uuidString); + } catch (IllegalArgumentException e) { + logger.warn("Skipping invalid UUID key: {}", uuidString); + continue; + } + + ConfigurationSection section = nicknameData.getConfigurationSection(uuidString); + if (section == null) continue; + + String currentNick = section.getString("current", null); + List savedNicks = section.getStringList("saved"); + + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + String username = player.getName(); + if (username == null) username = "unknown"; + logger.info("Migrating nicknames for user: {} - (UUID:{})", username, uuidString); + if (currentNick != null && !currentNick.isEmpty()) { + boolean saved = Cache.getInstance().setActiveNickname(uuid, username, currentNick); + if (saved) { + logger.info("Active nickname: {}", currentNick); + } else { + logger.warn("Failed to save current nickname: {}", currentNick); + } + } + if (!savedNicks.isEmpty()) { + for (String nickname : savedNicks) { + if (nickname == null || nickname.isEmpty()) continue; + boolean saved = Cache.getInstance().saveNickname(uuid, username, nickname); + if (saved) { + logger.info("Saved nickname: {}", nickname); + } else { + logger.warn("Failed to save nickname: {}", nickname); + } + } + } + migratedUsers++; + } + logger.info("Save data migrated successfully! {} users' data migrated", migratedUsers); + } + + public static void migratePdcNickname(Player player) { + PersistentDataContainer pdc = player.getPersistentDataContainer(); + if (!pdc.has(nickNameSave)) return; + String currentNick = pdc.get(nickNameSave, PersistentDataType.STRING); + UUID uuid = player.getUniqueId(); + Cache.getInstance().setActiveNickname(uuid, player.getName(), currentNick); + pdc.remove(nickNameSave); + } + + private static String normalizeNick(String nick) { + return SimpleNicks.getMiniMessage().stripTags(nick); + } +} diff --git a/src/main/java/simplexity/simplenicks/saving/YMLFile.java b/src/main/java/simplexity/simplenicks/saving/YMLFile.java deleted file mode 100644 index 326c647..0000000 --- a/src/main/java/simplexity/simplenicks/saving/YMLFile.java +++ /dev/null @@ -1,102 +0,0 @@ -package simplexity.simplenicks.saving; - -import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import simplexity.simplenicks.SimpleNicks; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@SuppressWarnings({"UnusedReturnValue", "CallToPrintStackTrace", "ResultOfMethodCallIgnored"}) -public class YMLFile extends AbstractSaving { - private final File dataFile = new File(SimpleNicks.getInstance().getDataFolder(), "nickname_data.yml"); - private final FileConfiguration nicknameData = new YamlConfiguration(); - - @Override - public void init() { - if (!dataFile.exists()) { - dataFile.getParentFile().mkdirs(); - try { - nicknameData.save(dataFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - try { - nicknameData.load(dataFile); - } catch (IOException | InvalidConfigurationException e) { - e.printStackTrace(); - } - } - - @Override - public String getNickname(OfflinePlayer offlinePlayer) { - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) return null; - return section.getString("current", null); - } - - @Override - public boolean setNickname(OfflinePlayer offlinePlayer, String nickname) { - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) section = nicknameData.createSection(offlinePlayer.getUniqueId().toString()); - section.set("current", nickname); - saveData(); - return true; - } - - @Override - public boolean saveNickname(OfflinePlayer offlinePlayer, String nickname) { - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) section = nicknameData.createSection(offlinePlayer.getUniqueId().toString()); - List savedNicknames = section.getStringList("saved"); - if (savedNicknames.contains(nickname)) return true; - savedNicknames.add(nickname); - section.set("saved", savedNicknames); - saveData(); - return true; - } - - @Override - public boolean deleteNickname(OfflinePlayer offlinePlayer, String nickname) { - List nicknames = getSavedNicknames(offlinePlayer); - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) return false; - if (!nicknames.contains(nickname)) return false; - nicknames.remove(nickname); - section.set("saved", nicknames); - saveData(); - return true; - } - - @Override - public boolean resetNickname(OfflinePlayer offlinePlayer) { - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) section = nicknameData.createSection(offlinePlayer.getUniqueId().toString()); - section.set("current", null); - saveData(); - return true; - } - - @Override - public List getSavedNicknames(OfflinePlayer offlinePlayer) { - ConfigurationSection section = nicknameData.getConfigurationSection(offlinePlayer.getUniqueId().toString()); - if (section == null) return new ArrayList<>(); - return section.getStringList("saved"); - } - - private boolean saveData() { - try { - nicknameData.save(dataFile); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } -} From 1171fd73eeeba8b2906e4fe12dda8d4ea2b009bb Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Sun, 27 Jul 2025 18:22:59 -0700 Subject: [PATCH 32/40] This didn't fix it but I needed to move it anyways --- .../java/simplexity/simplenicks/listener/LoginListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index a9179ec..ddafacc 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -15,11 +15,11 @@ public class LoginListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerJoin(PlayerJoinEvent joinEvent) { UUID playerUuid = joinEvent.getPlayer().getUniqueId(); + String username = joinEvent.getPlayer().getName(); + SqlHandler.getInstance().savePlayerToPlayers(playerUuid, username).join(); SaveMigrator.migratePdcNickname(joinEvent.getPlayer()); Cache.getInstance().loadCurrentNickname(playerUuid); Cache.getInstance().loadSavedNicknames(playerUuid); NickUtils.getInstance().refreshNickname(playerUuid); - String username = joinEvent.getPlayer().getName(); - SqlHandler.getInstance().savePlayerToPlayers(playerUuid, username); } } From 2570134ab9ff37273340b91e41bf794c6eaa1e28 Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Tue, 29 Jul 2025 15:22:53 -0700 Subject: [PATCH 33/40] No longer deletes the data lets go --- .../commands/NicknameProcessor.java | 19 +++---- .../simplenicks/config/ConfigHandler.java | 7 ++- .../simplenicks/listener/LoginListener.java | 2 +- .../simplexity/simplenicks/saving/Cache.java | 13 +++++ .../simplenicks/saving/SaveMigrator.java | 11 ++-- .../simplenicks/saving/SqlHandler.java | 57 ++++++++++++++++--- src/main/resources/config.yml | 5 +- 7 files changed, 88 insertions(+), 26 deletions(-) diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index aded1e0..10dd768 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -43,39 +43,38 @@ public boolean setNickname(OfflinePlayer player, String nickname) { public boolean resetNickname(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); + boolean success = Cache.getInstance().clearCurrentNickname(playerUuid); + if (!success) return false; if (online) { - boolean success = Cache.getInstance().clearCurrentNickname(playerUuid); - if (!success) return false; NickUtils.getInstance().refreshNickname(playerUuid); return true; } - return SqlHandler.getInstance().clearActiveNickname(playerUuid).join(); + return true; } public boolean saveNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); String username = player.getName(); boolean online = player.isOnline(); + boolean success = Cache.getInstance().saveNickname(playerUuid, username, nickname); + if (!success) return false; if (online) { - boolean success = Cache.getInstance().saveNickname(playerUuid, username, nickname); - if (!success) return false; NickUtils.getInstance().refreshNickname(playerUuid); return true; } - String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().saveNickname(playerUuid, username, nickname, normalizedNick).join(); + return true; } public boolean deleteNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); + boolean success = Cache.getInstance().deleteSavedNickname(playerUuid, nickname); + if (!success) return false; if (online) { - boolean success = Cache.getInstance().deleteSavedNickname(playerUuid, nickname); - if (!success) return false; NickUtils.getInstance().refreshNickname(playerUuid); return true; } - return SqlHandler.getInstance().deleteNickname(playerUuid, nickname).join(); + return true; } public List getSavedNicknames(OfflinePlayer player) { diff --git a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java index d703e5d..997faf8 100644 --- a/src/main/java/simplexity/simplenicks/config/ConfigHandler.java +++ b/src/main/java/simplexity/simplenicks/config/ConfigHandler.java @@ -22,7 +22,7 @@ public String getNickPrefix() { private final Logger logger = SimpleNicks.getSimpleNicksLogger(); private Pattern regex; - private boolean mySql, tablistNick, onlineNickProtection, offlineNickProtection; + private boolean mySql, tablistNick, onlineNickProtection, offlineNickProtection, debugMode; private int maxLength, maxSaves; private String regexString, nickPrefix, mySqlIp, mySqlName, mySqlUsername, mySqlPassword; private long usernameProtectionTime, offlineNickProtectionTime = 0; @@ -48,6 +48,7 @@ public void reloadConfig() { } catch (PatternSyntaxException e) { logger.severe(LocaleMessage.ERROR_INVALID_CONFIG_REGEX.getMessage()); } + debugMode = config.getBoolean("debug-mode", false); mySql = config.getBoolean("mysql.enabled", false); mySqlIp = config.getString("mysql.ip", "localhost:3306"); mySqlName = config.getString("mysql.name", "simplenicks"); @@ -115,4 +116,8 @@ public boolean shouldOnlineNicksBeProtected() { public boolean shouldOfflineNicksBeProtected() { return offlineNickProtection; } + + public boolean isDebugMode() { + return debugMode; + } } diff --git a/src/main/java/simplexity/simplenicks/listener/LoginListener.java b/src/main/java/simplexity/simplenicks/listener/LoginListener.java index ddafacc..6786482 100644 --- a/src/main/java/simplexity/simplenicks/listener/LoginListener.java +++ b/src/main/java/simplexity/simplenicks/listener/LoginListener.java @@ -16,7 +16,7 @@ public class LoginListener implements Listener { public void onPlayerJoin(PlayerJoinEvent joinEvent) { UUID playerUuid = joinEvent.getPlayer().getUniqueId(); String username = joinEvent.getPlayer().getName(); - SqlHandler.getInstance().savePlayerToPlayers(playerUuid, username).join(); + SqlHandler.getInstance().updatePlayerTableSqlite(playerUuid, username).join(); SaveMigrator.migratePdcNickname(joinEvent.getPlayer()); Cache.getInstance().loadCurrentNickname(playerUuid); Cache.getInstance().loadSavedNicknames(playerUuid); diff --git a/src/main/java/simplexity/simplenicks/saving/Cache.java b/src/main/java/simplexity/simplenicks/saving/Cache.java index 3ae6a02..b68fe11 100644 --- a/src/main/java/simplexity/simplenicks/saving/Cache.java +++ b/src/main/java/simplexity/simplenicks/saving/Cache.java @@ -1,6 +1,8 @@ package simplexity.simplenicks.saving; import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import simplexity.simplenicks.SimpleNicks; import javax.annotation.Nullable; @@ -35,6 +37,7 @@ public static Cache getInstance() { public void loadCurrentNickname(UUID uuid) { Nickname currentNick = SqlHandler.getInstance().getCurrentNicknameForPlayer(uuid).join(); if (currentNick == null) return; + if (playerIsOffline(uuid)) return; activeNicknames.put(uuid, currentNick); } @@ -58,6 +61,7 @@ public Nickname getActiveNickname(UUID uuid) { public void loadSavedNicknames(UUID uuid) { List savedNames = SqlHandler.getInstance().getSavedNicknamesForPlayer(uuid).join(); if (savedNames == null || savedNames.isEmpty()) return; + if (playerIsOffline(uuid)) return; savedNicknames.put(uuid, savedNames); } @@ -84,6 +88,7 @@ public boolean setActiveNickname(UUID uuid, String username, String nickname) { Nickname nick = new Nickname(nickname, normalizedNick); boolean sqlActiveNameSet = SqlHandler.getInstance().setActiveNickname(uuid, username, nickname, normalizedNick).join(); if (!sqlActiveNameSet) return false; + if (playerIsOffline(uuid)) return true; activeNicknames.put(uuid, nick); return true; } @@ -94,6 +99,7 @@ public boolean deleteSavedNickname(UUID uuid, String nickname) { if (!savedNicknames.containsKey(uuid)) return false; List userSavedNicknames = savedNicknames.get(uuid); userSavedNicknames.removeIf(name -> name.getNickname().equals(nickname)); + if (playerIsOffline(uuid)) return true; savedNicknames.put(uuid, userSavedNicknames); return true; } @@ -101,6 +107,7 @@ public boolean deleteSavedNickname(UUID uuid, String nickname) { public boolean clearCurrentNickname(UUID uuid) { boolean sqlNickRemoved = SqlHandler.getInstance().clearActiveNickname(uuid).join(); if (!sqlNickRemoved) return false; + if (playerIsOffline(uuid)) return true; activeNicknames.remove(uuid); return true; } @@ -126,6 +133,7 @@ public boolean saveNickname(UUID uuid, String username, String nickname) { userSavedNicknames.add(nick); boolean savedToSql = SqlHandler.getInstance().saveNickname(uuid, username, nickname, strippedNick).join(); if (!savedToSql) return false; + if (playerIsOffline(uuid)) return true; savedNicknames.put(uuid, userSavedNicknames); return true; } @@ -144,5 +152,10 @@ public Map getOnlineNicknames(){ return Collections.unmodifiableMap(activeNicknames); } + private boolean playerIsOffline(UUID uuid){ + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + return player.isOnline(); + } + } diff --git a/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java b/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java index 01f1897..5004347 100644 --- a/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java +++ b/src/main/java/simplexity/simplenicks/saving/SaveMigrator.java @@ -75,6 +75,13 @@ public static void migrateFromYml() { migratedUsers++; } logger.info("Save data migrated successfully! {} users' data migrated", migratedUsers); + File backupFile = new File(SimpleNicks.getInstance().getDataFolder(), "MIGRATED_nickname_data.yml"); + boolean renamed = dataFile.renameTo(backupFile); + if (!renamed) { + logger.warn("Unable to rename 'nickname_data.yml' - if migration was successful, please remove or rename this file so as to not overwrite new save data."); + } else { + logger.info("Successfully renamed 'nickname_data.yml' - this migration process will no longer be attempted (unless you rename it back, for some reason, I wouldn't recommend that)"); + } } public static void migratePdcNickname(Player player) { @@ -85,8 +92,4 @@ public static void migratePdcNickname(Player player) { Cache.getInstance().setActiveNickname(uuid, player.getName(), currentNick); pdc.remove(nickNameSave); } - - private static String normalizeNick(String nick) { - return SimpleNicks.getMiniMessage().stripTags(nick); - } } diff --git a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java index 978f8dc..a2843f6 100644 --- a/src/main/java/simplexity/simplenicks/saving/SqlHandler.java +++ b/src/main/java/simplexity/simplenicks/saving/SqlHandler.java @@ -35,6 +35,7 @@ public static SqlHandler getInstance() { public void init() { try (Connection connection = getConnection()) { + debug("Creating players table..."); PreparedStatement parentStatement = connection.prepareStatement(""" CREATE TABLE IF NOT EXISTS players ( uuid VARCHAR(36) PRIMARY KEY NOT NULL, @@ -43,6 +44,7 @@ last_known_name VARCHAR(16) NOT NULL, ); """); parentStatement.execute(); + debug("Creating saved_nicknames table..."); PreparedStatement savedNickStatement = connection.prepareStatement(""" CREATE TABLE IF NOT EXISTS saved_nicknames ( uuid VARCHAR(36) NOT NULL, @@ -55,6 +57,7 @@ REFERENCES players(uuid) ); """); savedNickStatement.execute(); + debug("Creating current_nicknames table..."); PreparedStatement currentNickStatement = connection.prepareStatement(""" CREATE TABLE IF NOT EXISTS current_nicknames ( uuid VARCHAR(36) NOT NULL, @@ -75,6 +78,7 @@ REFERENCES players(uuid) public CompletableFuture> nickAlreadySavedTo(@Nullable UUID uuidToExclude, String normalizedName) { return CompletableFuture.supplyAsync(() -> { + debug("Checking if nickname '{}' is already in use (excluding UUID='{}')", normalizedName, uuidToExclude); String queryString = "SELECT uuid FROM current_nicknames WHERE nickname = ?"; List uuidsWithName = new ArrayList<>(); try (Connection connection = getConnection()) { @@ -85,6 +89,7 @@ public CompletableFuture> nickAlreadySavedTo(@Nullable UUID uuidToExc UUID uuid = UUID.fromString(resultSet.getString("uuid")); if (uuid.equals(uuidToExclude)) continue; uuidsWithName.add(uuid); + debug("Nickname found in use by UUID={}", uuid); } return uuidsWithName; } catch (SQLException e) { @@ -96,6 +101,7 @@ public CompletableFuture> nickAlreadySavedTo(@Nullable UUID uuidToExc public CompletableFuture> getSavedNicknamesForPlayer(UUID uuid) { return CompletableFuture.supplyAsync(() -> { + debug("Fetching saved nicknames for UUID={}", uuid); List savedNicknames = new ArrayList<>(); if (!playerSaveExists(uuid).join()) return savedNicknames; String queryString = "SELECT nickname, normalized FROM saved_nicknames WHERE uuid = ?"; @@ -107,6 +113,7 @@ public CompletableFuture> getSavedNicknamesForPlayer(UUID uuid) { String nicknameString = resultSet.getString("nickname"); String normalizedString = resultSet.getString("normalized"); Nickname nick = new Nickname(nicknameString, normalizedString); + debug("Found saved nickname: '{}' (normalized '{}')", nicknameString, normalizedString); savedNicknames.add(nick); } } catch (SQLException e) { @@ -119,6 +126,7 @@ public CompletableFuture> getSavedNicknamesForPlayer(UUID uuid) { public CompletableFuture userAlreadySavedThisName(UUID uuid, String nickname) { return CompletableFuture.supplyAsync(() -> { + debug("Checking if UUID={} already saved nickname='{}'", uuid, nickname); if (!playerSaveExists(uuid).join()) return false; String queryString = "SELECT nickname FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; try (Connection connection = getConnection()) { @@ -137,6 +145,7 @@ public CompletableFuture userAlreadySavedThisName(UUID uuid, String nic public CompletableFuture getCurrentNicknameForPlayer(UUID uuid) { return CompletableFuture.supplyAsync(() -> { + debug("Fetching current nickname for UUID={}", uuid); if (!playerSaveExists(uuid).join()) return null; String queryString = "SELECT nickname, normalized FROM current_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { @@ -146,6 +155,7 @@ public CompletableFuture getCurrentNicknameForPlayer(UUID uuid) { if (resultSet.next()) { String nickString = resultSet.getString("nickname"); String normalizedString = resultSet.getString("normalized"); + debug("Current nickname found: '{}' (normalized '{}')", nickString, normalizedString); return new Nickname(nickString, normalizedString); } return null; @@ -157,20 +167,23 @@ public CompletableFuture getCurrentNicknameForPlayer(UUID uuid) { } - public CompletableFuture> getUuidsOfNickname(String normalizeName) { + public CompletableFuture> getUuidsOfNickname(String normalizedName) { return CompletableFuture.supplyAsync(() -> { + debug("Looking up UUIDs using normalized nickname='{}'", normalizedName); String queryString = "SELECT uuid FROM current_nicknames WHERE normalized = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); - statement.setString(1, normalizeName); + statement.setString(1, normalizedName); ResultSet resultSet = statement.executeQuery(); List uuids = new ArrayList<>(); while (resultSet.next()) { - uuids.add(UUID.fromString(resultSet.getString("uuid"))); + UUID id = UUID.fromString(resultSet.getString("uuid")); + uuids.add(id); + debug("Found UUID={} for nickname", id); } return uuids; } catch (SQLException e) { - logger.warn("Failed to get UUID list from normalized nickname: {}", normalizeName, e); + logger.warn("Failed to get UUID list from normalized nickname: {}", normalizedName, e); return null; } }); @@ -178,9 +191,10 @@ public CompletableFuture> getUuidsOfNickname(String normalizeName) { public CompletableFuture saveNickname(UUID uuid, String username, String nickname, String normalizedNickname) { return CompletableFuture.supplyAsync(() -> { + debug("Saving nickname '{}' (normalized '{}') for UUID={}, username={}", nickname, normalizedNickname, uuid, username); String saveString = "REPLACE INTO saved_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; if (!playerSaveExists(uuid).join()) { - if (!savePlayerToPlayers(uuid, username).join()) return false; + if (!updatePlayerTableSqlite(uuid, username).join()) return false; } try (Connection connection = getConnection()) { PreparedStatement saveStatement = connection.prepareStatement(saveString); @@ -188,6 +202,7 @@ public CompletableFuture saveNickname(UUID uuid, String username, Strin saveStatement.setString(2, nickname); saveStatement.setString(3, normalizedNickname); int rowsChanged = saveStatement.executeUpdate(); + debug("Rows modified when saving nickname: {}", rowsChanged); return rowsChanged > 0; } catch (SQLException e) { logger.warn("Failed to save nickname '{}' for UUID '{}'. Normalized nickname: {}, Username: {} ", @@ -199,6 +214,7 @@ public CompletableFuture saveNickname(UUID uuid, String username, Strin public CompletableFuture deleteNickname(UUID uuid, String nickname) { return CompletableFuture.supplyAsync(() -> { + debug("Deleting nickname '{}' for UUID={}", nickname, uuid); if (!playerSaveExists(uuid).join()) return null; String deleteQuery = "DELETE FROM saved_nicknames WHERE uuid = ? AND nickname = ?"; try (Connection connection = getConnection()) { @@ -206,6 +222,7 @@ public CompletableFuture deleteNickname(UUID uuid, String nickname) { statement.setString(1, String.valueOf(uuid)); statement.setString(2, nickname); int rowsChanged = statement.executeUpdate(); + debug("Rows affected in delete: {}", rowsChanged); return rowsChanged > 0; } catch (SQLException e) { logger.warn("Failed to delete nickname '{}' for UUID '{}'", nickname, uuid, e); @@ -217,12 +234,14 @@ public CompletableFuture deleteNickname(UUID uuid, String nickname) { public CompletableFuture clearActiveNickname(UUID uuid) { return CompletableFuture.supplyAsync(() -> { + debug("Clearing current nickname for UUID={}", uuid); if (!playerSaveExists(uuid).join()) return false; String deleteQuery = "DELETE FROM current_nicknames WHERE uuid = ?"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(deleteQuery); statement.setString(1, String.valueOf(uuid)); int rowsAffected = statement.executeUpdate(); + debug("Rows affected in clear: {}", rowsAffected); return rowsAffected > 0; } catch (SQLException e) { logger.warn("Failed to clear active nickname for UUID '{}'", uuid, e); @@ -234,9 +253,10 @@ public CompletableFuture clearActiveNickname(UUID uuid) { public CompletableFuture setActiveNickname(UUID uuid, String username, String nicknameString, String normalizedString) { return CompletableFuture.supplyAsync(() -> { + debug("Setting active nickname '{}' (normalized '{}') for UUID={}, username={}", nicknameString, normalizedString, uuid, username); String setQuery = "REPLACE INTO current_nicknames (uuid, nickname, normalized) VALUES (?, ?, ?)"; if (!playerSaveExists(uuid).join()) { - if (!savePlayerToPlayers(uuid, username).join()) return false; + if (!updatePlayerTableSqlite(uuid, username).join()) return false; } try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(setQuery); @@ -244,6 +264,7 @@ public CompletableFuture setActiveNickname(UUID uuid, String username, statement.setString(2, nicknameString); statement.setString(3, normalizedString); int rowsModified = statement.executeUpdate(); + debug("Rows affected setting active nickname: {}", rowsModified); return rowsModified > 0; } catch (SQLException e) { logger.warn("Failed to set active nickname '{}' for UUID '{}'. Normalized name: {}, Username: {}", @@ -262,7 +283,9 @@ public CompletableFuture playerSaveExists(UUID uuid) { PreparedStatement statement = connection.prepareStatement(queryString); statement.setString(1, String.valueOf(uuid)); ResultSet resultSet = statement.executeQuery(); - return resultSet.next(); + boolean exists = resultSet.next(); + debug("Check if player UUID={} exists: {}", uuid, exists); + return exists; } catch (SQLException e) { logger.warn("Failed to check if player with UUID {} exists", uuid, e); e.printStackTrace(); @@ -273,6 +296,7 @@ public CompletableFuture playerSaveExists(UUID uuid) { public CompletableFuture lastLongOfUsername(String username, long expiryTime) { return CompletableFuture.supplyAsync(() -> { + debug("Fetching last login for username='{}', expiry={}", username, expiryTime); String queryString = "SELECT last_login FROM players WHERE last_known_name = ? AND (? < 0 OR last_login >= ?)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); @@ -292,6 +316,7 @@ public CompletableFuture lastLongOfUsername(String username, long expiryTi public CompletableFuture lastLongOfUuid(UUID uuid, long expiryTime) { return CompletableFuture.supplyAsync(() -> { + debug("Fetching last login for UUID='{}', expiry={}", uuid, expiryTime); String queryString = "SELECT last_login FROM players WHERE uuid = ? AND (? < 0 OR last_login >= ?)"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(queryString); @@ -309,14 +334,20 @@ public CompletableFuture lastLongOfUuid(UUID uuid, long expiryTime) { }); } - public CompletableFuture savePlayerToPlayers(UUID uuid, String username) { + public CompletableFuture updatePlayerTableSqlite(UUID uuid, String username) { return CompletableFuture.supplyAsync(() -> { - String insertQuery = "REPLACE INTO players (uuid, last_known_name, last_login) VALUES (?, ?, CURRENT_TIMESTAMP)"; + debug("Saving player to players table: UUID={}, username={}", uuid, username); + String insertQuery = "INSERT INTO players (uuid, last_known_name, last_login) " + + "VALUES (?, ?, CURRENT_TIMESTAMP)" + + "ON CONFLICT(uuid) DO UPDATE SET " + + "last_known_name = excluded.last_known_name," + + "last_login = CURRENT_TIMESTAMP"; try (Connection connection = getConnection()) { PreparedStatement statement = connection.prepareStatement(insertQuery); statement.setString(1, String.valueOf(uuid)); statement.setString(2, username.toLowerCase()); int rowsChanged = statement.executeUpdate(); + debug("Rows affected in savePlayerToPlayers: {}", rowsChanged); return rowsChanged > 0; } catch (SQLException e) { logger.warn("Failed to save player with UUID: {}, username: {}", uuid, username, e); @@ -329,17 +360,25 @@ public void setupConfig() { if (!ConfigHandler.getInstance().isMySql()) { hikariConfig.setJdbcUrl("jdbc:sqlite:" + SimpleNicks.getInstance().getDataFolder() + "/simplenicks.db?foreign_keys=on"); dataSource = new HikariDataSource(hikariConfig); + debug("Initialized SQLite connection."); return; } hikariConfig.setJdbcUrl("jdbc:mysql://" + ConfigHandler.getInstance().getMySqlIp() + "/" + ConfigHandler.getInstance().getMySqlName()); hikariConfig.setUsername(ConfigHandler.getInstance().getMySqlUsername()); hikariConfig.setPassword(ConfigHandler.getInstance().getMySqlPassword()); dataSource = new HikariDataSource(hikariConfig); + debug("Initialized MySQL connection to '{}'", hikariConfig.getJdbcUrl()); } private static Connection getConnection() throws SQLException { return dataSource.getConnection(); } + private void debug(String message, Object... args) { + if (ConfigHandler.getInstance().isDebugMode()) { + logger.info("[SQL DEBUG] {}, {}", message, args); + } + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 04a7665..182e770 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -42,4 +42,7 @@ nickname-protection: enabled: false offline: enabled: false - expires: 30 \ No newline at end of file + expires: 30 + +# Development option, this will flood your logs, discouraged from enabling unless asked +debug-mode: false From f7acfaad56d0942b226cf41b7362df38eca2177e Mon Sep 17 00:00:00 2001 From: Rhythmic System Date: Fri, 8 Aug 2025 15:07:03 -0700 Subject: [PATCH 34/40] Adjust SQL, move things to be properly async. --- pom.xml | 2 +- .../simplexity/simplenicks/SimpleNicks.java | 1 - .../commands/NicknameProcessor.java | 49 +- .../commands/subcommands/Exceptions.java | 35 +- .../admin/AdminDeleteSubCommand.java | 29 +- .../admin/AdminLookupSubCommand.java | 14 +- .../admin/AdminResetSubCommand.java | 24 +- .../subcommands/admin/AdminSetSubCommand.java | 22 +- .../subcommands/basic/DeleteSubCommand.java | 25 +- .../subcommands/basic/ReloadSubCommand.java | 4 +- .../subcommands/basic/ResetSubCommand.java | 16 +- .../subcommands/basic/SaveSubCommand.java | 18 +- .../subcommands/basic/SetSubCommand.java | 16 +- .../subcommands/basic/SubCommand.java | 22 +- .../subcommands/basic/WhoSubCommand.java | 56 +- .../simplenicks/config/LocaleMessage.java | 69 ++- .../simplenicks/config/MessageUtils.java | 63 ++- .../simplenicks/listener/LoginListener.java | 2 +- .../simplenicks/logic/NickUtils.java | 8 +- .../simplexity/simplenicks/saving/Cache.java | 142 ++++- .../simplenicks/saving/SqlHandler.java | 518 +++++++++--------- 21 files changed, 643 insertions(+), 492 deletions(-) diff --git a/pom.xml b/pom.xml index 996715d..70d5dab 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ simplexity SimpleNicks - 2.1.0 + 3.0.0 jar SimpleNicks diff --git a/src/main/java/simplexity/simplenicks/SimpleNicks.java b/src/main/java/simplexity/simplenicks/SimpleNicks.java index 560b86a..02003bb 100644 --- a/src/main/java/simplexity/simplenicks/SimpleNicks.java +++ b/src/main/java/simplexity/simplenicks/SimpleNicks.java @@ -42,7 +42,6 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new LoginListener(), this); getServer().getPluginManager().registerEvents(new LeaveListener(), this); configReload(); - SqlHandler.getInstance().setupConfig(); SqlHandler.getInstance().init(); SaveMigrator.migrateFromYml(); this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { diff --git a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java index 10dd768..bdc559b 100644 --- a/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java +++ b/src/main/java/simplexity/simplenicks/commands/NicknameProcessor.java @@ -1,9 +1,6 @@ package simplexity.simplenicks.commands; -import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.OfflinePlayer; -import simplexity.simplenicks.SimpleNicks; -import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Cache; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.saving.SqlHandler; @@ -25,63 +22,33 @@ public static NicknameProcessor getInstance() { return instance; } - private final MiniMessage miniMessage = SimpleNicks.getMiniMessage(); - public boolean setNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); String username = player.getName(); - boolean online = player.isOnline(); - if (online) { - boolean success = Cache.getInstance().setActiveNickname(playerUuid, username, nickname); - if (!success) return false; - NickUtils.getInstance().refreshNickname(playerUuid); - } - String normalizedNick = miniMessage.stripTags(nickname); - return SqlHandler.getInstance().setActiveNickname(playerUuid, username, nickname, normalizedNick).join(); + return Cache.getInstance().setActiveNickname(playerUuid, username, nickname); } public boolean resetNickname(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); - boolean online = player.isOnline(); - boolean success = Cache.getInstance().clearCurrentNickname(playerUuid); - if (!success) return false; - if (online) { - NickUtils.getInstance().refreshNickname(playerUuid); - return true; - } - return true; + return Cache.getInstance().clearCurrentNickname(playerUuid); } public boolean saveNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); String username = player.getName(); - boolean online = player.isOnline(); - boolean success = Cache.getInstance().saveNickname(playerUuid, username, nickname); - if (!success) return false; - if (online) { - NickUtils.getInstance().refreshNickname(playerUuid); - return true; - } - return true; + return Cache.getInstance().saveNickname(playerUuid, username, nickname); } public boolean deleteNickname(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); - boolean online = player.isOnline(); - boolean success = Cache.getInstance().deleteSavedNickname(playerUuid, nickname); - if (!success) return false; - if (online) { - NickUtils.getInstance().refreshNickname(playerUuid); - return true; - } - return true; + return Cache.getInstance().deleteSavedNickname(playerUuid, nickname); } public List getSavedNicknames(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getSavedNicknames(playerUuid); - List nicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid).join(); + List nicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); if (nicks == null) return new ArrayList<>(); return nicks; } @@ -91,14 +58,14 @@ public Nickname getCurrentNickname(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getActiveNickname(playerUuid); - return SqlHandler.getInstance().getCurrentNicknameForPlayer(playerUuid).join(); + return SqlHandler.getInstance().getCurrentNicknameForPlayer(playerUuid); } public int getCurrentSavedNickCount(OfflinePlayer player) { UUID playerUuid = player.getUniqueId(); boolean online = player.isOnline(); if (online) return Cache.getInstance().getSavedNickCount(playerUuid); - List savedNicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid).join(); + List savedNicks = SqlHandler.getInstance().getSavedNicknamesForPlayer(playerUuid); if (savedNicks == null || savedNicks.isEmpty()) return 0; return savedNicks.size(); } @@ -106,7 +73,7 @@ public int getCurrentSavedNickCount(OfflinePlayer player) { public boolean playerAlreadySavedThis(OfflinePlayer player, String nickname) { UUID playerUuid = player.getUniqueId(); - return SqlHandler.getInstance().userAlreadySavedThisName(playerUuid, nickname).join(); + return SqlHandler.getInstance().userAlreadySavedThisName(playerUuid, nickname); } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java index 390ac16..831750e 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/Exceptions.java @@ -17,8 +17,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_DELETE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_DELETE_FAILURE.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_DELETE_FAILURE.getMessage() ) ) ); @@ -26,8 +25,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_NICK_IS_NULL = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_NICK_IS_NULL.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_NICK_IS_NULL.getMessage() ) ) ); @@ -35,8 +33,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_EMPTY_NICK_AFTER_PARSE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_INVALID_NICK_EMPTY.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_INVALID_NICK_EMPTY.getMessage() ) ) ); @@ -44,8 +41,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_SAVE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_SAVE_FAILURE.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_SAVE_FAILURE.getMessage() ) ) ); @@ -54,8 +50,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_INVALID_COMMAND = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_INVALID_COMMAND.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_INVALID_COMMAND.getMessage() ) ) ); @@ -63,8 +58,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_CANNOT_ACCESS_PLAYERS_PERMISSIONS.getMessage() ) ) ); @@ -72,8 +66,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_UNABLE_TO_RESET_NICK = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_RESET_FAILURE.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_RESET_FAILURE.getMessage() ) ) ); @@ -81,8 +74,7 @@ public class Exceptions { public static final SimpleCommandExceptionType ERROR_SET_FAILURE = new SimpleCommandExceptionType( MessageComponentSerializer.message().serialize( miniMessage.deserialize( - LocaleMessage.ERROR_SET_FAILURE.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + LocaleMessage.ERROR_SET_FAILURE.getMessage() ) ) ); @@ -92,8 +84,7 @@ public class Exceptions { miniMessage.deserialize( LocaleMessage.ERROR_INVALID_NICK_LENGTH.getMessage(), Placeholder.unparsed("value", String.valueOf(ConfigHandler.getInstance().getMaxLength())), - Placeholder.unparsed("name", nickname.toString()), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + Placeholder.unparsed("name", nickname.toString()) ) ) ); @@ -102,8 +93,7 @@ public class Exceptions { nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( LocaleMessage.ERROR_INVALID_NICK.getMessage(), - Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + Placeholder.unparsed("regex", ConfigHandler.getInstance().getRegexString()) ) ) ); @@ -112,8 +102,7 @@ public class Exceptions { playerName -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( LocaleMessage.ERROR_INVALID_PLAYER.getMessage(), - Placeholder.unparsed("player_name", playerName.toString()), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()) + Placeholder.unparsed("player_name", playerName.toString()) ) ) ); @@ -122,7 +111,6 @@ public class Exceptions { nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( LocaleMessage.ERROR_OTHER_PLAYERS_USERNAME.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.unparsed("value", nickname.toString()) ) ) @@ -133,7 +121,6 @@ public class Exceptions { nickname -> MessageComponentSerializer.message().serialize( miniMessage.deserialize( LocaleMessage.ERROR_OTHER_PLAYERS_NICKNAME.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.unparsed("value", nickname.toString()) ) ) diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java index bc055d6..c22053f 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminDeleteSubCommand.java @@ -6,16 +6,18 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -39,16 +41,23 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); - OfflinePlayer targetPlayer = ctx.getArgument("player", OfflinePlayer.class); + OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); Nickname nickname = ctx.getArgument("nickname", Nickname.class); - boolean deleted = NicknameProcessor.getInstance().deleteNickname(targetPlayer, nickname.getNickname()); - if (deleted) { - sender.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_OTHER.getMessage(), nickname.getNickname(), sender, targetPlayer)); - if (targetPlayer instanceof Player player) - player.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_BY_OTHER.getMessage(), nickname.getNickname(), sender, targetPlayer)); - return Command.SINGLE_SUCCESS; - } - throw Exceptions.ERROR_CANNOT_DELETE.create(); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean success = NicknameProcessor.getInstance().deleteNickname(target, nickname.getNickname()); + if (success) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + if ((target instanceof Player onlineTarget)) { + NickUtils.getInstance().refreshNickname(target.getUniqueId()); + onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_BY_OTHER.getMessage(), nickname.getNickname(), sender, target)); + } + sender.sendMessage(parseAdminMessage(LocaleMessage.NICK_DELETED_OTHER.getMessage(), nickname.getNickname(), sender, target)); + }); + } else { + sender.sendRichMessage(LocaleMessage.ERROR_DELETE_FAILURE.getMessage()); + } + }); + return Command.SINGLE_SUCCESS; } @Override diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java index ecbe651..68385bd 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminLookupSubCommand.java @@ -9,13 +9,13 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.config.MessageUtils; @@ -46,9 +46,11 @@ public int execute(@NotNull CommandContext ctx) throws Comma CommandSender sender = ctx.getSource().getSender(); OfflinePlayer lookupTarget = ctx.getArgument("player", OfflinePlayer.class); String username = lookupTarget.getName(); - Nickname currentNickname = NicknameProcessor.getInstance().getCurrentNickname(lookupTarget); - List savedNicknames = NicknameProcessor.getInstance().getSavedNicknames(lookupTarget); - sender.sendMessage(lookupInfoComponent(username, currentNickname, savedNicknames)); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + Nickname currentNickname = NicknameProcessor.getInstance().getCurrentNickname(lookupTarget); + List savedNicknames = NicknameProcessor.getInstance().getSavedNicknames(lookupTarget); + sender.sendMessage(lookupInfoComponent(username, currentNickname, savedNicknames)); + }); return Command.SINGLE_SUCCESS; } @@ -58,9 +60,9 @@ public boolean canExecute(@NotNull CommandSourceStack css) { return sender.hasPermission(Constants.NICK_ADMIN_LOOKUP); } - public Component lookupInfoComponent(String username, Nickname currentNick, List savedNames) throws CommandSyntaxException { + public Component lookupInfoComponent(String username, Nickname currentNick, List savedNames) { if (currentNick == null && (savedNames == null || savedNames.isEmpty())) - throw Exceptions.ERROR_NO_NICKNAMES.create(); + return miniMessage.deserialize(LocaleMessage.ERROR_NO_PLAYERS_FOUND_BY_THIS_NAME.getMessage()); Component nickname; if (currentNick == null) { nickname = miniMessage.deserialize(LocaleMessage.INSERT_NONE.getMessage()); diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java index c5f56a9..d7bfb8c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminResetSubCommand.java @@ -7,15 +7,17 @@ import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -37,12 +39,20 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); OfflinePlayer target = ctx.getArgument("player", OfflinePlayer.class); - boolean resetNick = NicknameProcessor.getInstance().resetNickname(target); - if (!resetNick) throw Exceptions.ERROR_UNABLE_TO_RESET_NICK.create(); - sender.sendMessage(parseAdminMessage(LocaleMessage.RESET_OTHER.getMessage(), "", sender, target)); - if (target instanceof Player onlineTarget) { - onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.RESET_BY_OTHER.getMessage(), "", sender, target)); - } + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean success = NicknameProcessor.getInstance().resetNickname(target); + if (success) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + if ((target instanceof Player onlineTarget)) { + NickUtils.getInstance().refreshNickname(target.getUniqueId()); + onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.RESET_BY_OTHER.getMessage(), "", sender, target)); + } + sender.sendMessage(parseAdminMessage(LocaleMessage.RESET_OTHER.getMessage(), "", sender, target)); + }); + } else { + sender.sendRichMessage(LocaleMessage.ERROR_RESET_FAILURE.getMessage()); + } + }); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java index c5c5c07..c752438 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/admin/AdminSetSubCommand.java @@ -6,14 +6,15 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.arguments.OfflinePlayerArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.commands.subcommands.basic.SubCommand; import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.logic.NickUtils; @@ -50,11 +51,20 @@ public int execute(@NotNull CommandContext ctx) throws Comma String cleanedNick = NickUtils.getInstance().cleanNonPermittedTags(sender, nickname.getNickname()); nickname.setNickname(cleanedNick); NickUtils.getInstance().nicknameChecks(sender, nickname); - boolean setSuccessfully = NicknameProcessor.getInstance().setNickname(target, cleanedNick); - if (!setSuccessfully) throw Exceptions.ERROR_SET_FAILURE.create(); - sender.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_OTHER.getMessage(), cleanedNick, sender, target)); - if (target instanceof Player onlineTarget) - onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_BY_OTHER.getMessage(), cleanedNick, sender, target)); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean success = NicknameProcessor.getInstance().setNickname(target, cleanedNick); + if (success) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + if ((target instanceof Player onlineTarget)) { + NickUtils.getInstance().refreshNickname(target.getUniqueId()); + onlineTarget.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_BY_OTHER.getMessage(), cleanedNick, sender, target)); + } + sender.sendMessage(parseAdminMessage(LocaleMessage.CHANGED_OTHER.getMessage(), cleanedNick, sender, target)); + }); + } else { + sender.sendRichMessage(LocaleMessage.ERROR_SET_FAILURE.getMessage()); + } + }); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java index f03a113..d2926b1 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/DeleteSubCommand.java @@ -6,13 +6,14 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import org.bukkit.OfflinePlayer; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import simplexity.simplenicks.util.Constants; @@ -35,14 +36,20 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par @Override public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { - OfflinePlayer player = (OfflinePlayer) ctx.getSource().getSender(); + Player player = (Player) ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); - boolean deleted = NicknameProcessor.getInstance().deleteNickname(player, nickname.getNickname()); - if (deleted) { - if (player instanceof Player onlinePlayer) sendFeedback(onlinePlayer, LocaleMessage.DELETE_NICK, nickname); - return Command.SINGLE_SUCCESS; - } - throw Exceptions.ERROR_CANNOT_DELETE.create(); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean success = NicknameProcessor.getInstance().deleteNickname(player, nickname.getNickname()); + if (success) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + NickUtils.getInstance().refreshNickname(player.getUniqueId()); + sendFeedback(player, LocaleMessage.DELETE_NICK, nickname); + }); + } else { + sendFeedback(player, LocaleMessage.ERROR_DELETE_FAILURE, nickname); + } + }); + return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java index 536999a..b21c5df 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ReloadSubCommand.java @@ -6,7 +6,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.config.ConfigHandler; @@ -25,8 +24,7 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); ConfigHandler.getInstance().reloadConfig(); - sender.sendRichMessage(LocaleMessage.CONFIG_RELOADED.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage())); + sender.sendRichMessage(LocaleMessage.CONFIG_RELOADED.getMessage()); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java index 7e8f7a9..6cd685c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/ResetSubCommand.java @@ -5,10 +5,13 @@ import com.mojang.brigadier.context.CommandContext; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.util.Constants; @SuppressWarnings("UnstableApiUsage") @@ -24,8 +27,17 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par @Override public int execute(@NotNull CommandContext ctx) { Player player = (Player) ctx.getSource().getSender(); - NicknameProcessor.getInstance().resetNickname(player); - sendFeedback(player, LocaleMessage.RESET_SELF, null); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean success = NicknameProcessor.getInstance().resetNickname(player); + if (success) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + NickUtils.getInstance().refreshNickname(player.getUniqueId()); + sendFeedback(player, LocaleMessage.RESET_SELF, null); + }); + } else { + sendFeedback(player, LocaleMessage.ERROR_RESET_FAILURE, null); + } + }); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java index cbd093d..490751c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SaveSubCommand.java @@ -6,8 +6,10 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; @@ -41,11 +43,17 @@ public int execute(@NotNull CommandContext ctx) throws Comma if (nickname == null) { throw Exceptions.ERROR_CANNOT_SAVE.create(); } - boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.getNickname()); - if (!saved) { - throw Exceptions.ERROR_CANNOT_SAVE.create(); - } - sendFeedback(player, LocaleMessage.SAVE_NICK, nickname); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean saved = NicknameProcessor.getInstance().saveNickname(player, nickname.getNickname()); + if (saved) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + NickUtils.getInstance().refreshNickname(player.getUniqueId()); + sendFeedback(player, LocaleMessage.SAVE_NICK, nickname); + }); + } else { + sendFeedback(player, LocaleMessage.ERROR_SAVE_FAILURE, nickname); + } + }); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java index d4b621c..4f5b85e 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SetSubCommand.java @@ -6,9 +6,10 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import org.bukkit.OfflinePlayer; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.NicknameProcessor; import simplexity.simplenicks.commands.arguments.NicknameArgument; import simplexity.simplenicks.commands.subcommands.Exceptions; @@ -43,8 +44,17 @@ public int execute(@NotNull CommandContext ctx) throws Comma } Player player = (Player) ctx.getSource().getSender(); NickUtils.getInstance().nicknameChecks(player, nickname); - NicknameProcessor.getInstance().setNickname((OfflinePlayer) ctx.getSource().getSender(), nickname.getNickname()); - sendFeedback(player, LocaleMessage.CHANGED_SELF, nickname); + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + boolean succeeded = NicknameProcessor.getInstance().setNickname(player, nickname.getNickname()); + if (succeeded) { + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> { + refreshName(player); + sendFeedback(player, LocaleMessage.CHANGED_SELF, nickname); + }); + } else { + sendFeedback(player, LocaleMessage.ERROR_SET_FAILURE, nickname); + } + }); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java index 7151d79..102b9b6 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/SubCommand.java @@ -10,12 +10,14 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import org.apache.commons.lang3.NotImplementedException; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.config.LocaleMessage; +import simplexity.simplenicks.logic.NickUtils; import simplexity.simplenicks.saving.Nickname; import java.util.concurrent.CompletableFuture; @@ -51,25 +53,25 @@ public interface SubCommand { /** * Sends a feedback message to the player, confirming the command went through properly * - * @param player Player - * @param localeMessage Message - * @param nickname Nickname + * @param player Player + * @param localeMessage Message + * @param nickname Nickname */ default void sendFeedback(Player player, LocaleMessage localeMessage, Nickname nickname) { if (nickname == null) nickname = new Nickname("", ""); player.sendRichMessage( localeMessage.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", nickname.getNickname()) ); } /** * Parses a message for admin commands. - * @param message Message to parse - * @param value Placeholder value from message, usually nickname, sometimes something else like a config value + * + * @param message Message to parse + * @param value Placeholder value from message, usually nickname, sometimes something else like a config value * @param initiator CommandSender who initiated the command, the admin - * @param target OfflinePlayer who this command is being run on + * @param target OfflinePlayer who this command is being run on * @return Component parsed message */ default Component parseAdminMessage(String message, String value, CommandSender initiator, @NotNull OfflinePlayer target) { @@ -85,7 +87,6 @@ default Component parseAdminMessage(String message, String value, CommandSender initiatorName = miniMessage.deserialize(LocaleMessage.SERVER_DISPLAY_NAME.getMessage()); } return miniMessage.deserialize(message, - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), Placeholder.parsed("value", value), Placeholder.component("initiator", initiatorName), Placeholder.parsed("target", targetUserName) @@ -108,5 +109,8 @@ default Component parseAdminMessage(String message, String value, CommandSender throw new NotImplementedException("listSuggestions was used, but not implemented."); } - + default void refreshName(OfflinePlayer player) { + if (!player.isOnline()) return; + Bukkit.getScheduler().runTask(SimpleNicks.getInstance(), () -> NickUtils.getInstance().refreshNickname(player.getUniqueId())); + } } diff --git a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java index 7a36aac..615822c 100644 --- a/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java +++ b/src/main/java/simplexity/simplenicks/commands/subcommands/basic/WhoSubCommand.java @@ -9,12 +9,12 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import simplexity.simplenicks.SimpleNicks; import simplexity.simplenicks.commands.arguments.NicknameArgument; -import simplexity.simplenicks.commands.subcommands.Exceptions; import simplexity.simplenicks.config.LocaleMessage; import simplexity.simplenicks.config.MessageUtils; import simplexity.simplenicks.logic.NickUtils; @@ -42,34 +42,48 @@ public void subcommandTo(@NotNull LiteralArgumentBuilder par public int execute(@NotNull CommandContext ctx) throws CommandSyntaxException { CommandSender sender = ctx.getSource().getSender(); Nickname nickname = ctx.getArgument("nickname", Nickname.class); - List playersWithNick = NickUtils.getInstance().getOfflinePlayersByNickname(nickname.getNormalizedNickname()); - if (playersWithNick == null) throw Exceptions.ERROR_NICK_IS_NULL.create(); - Component messageComponent = miniMessage.deserialize(LocaleMessage.NICK_WHO_HEADER.getMessage(), - Placeholder.parsed("prefix", LocaleMessage.PLUGIN_PREFIX.getMessage()), + Bukkit.getScheduler().runTaskAsynchronously(SimpleNicks.getInstance(), () -> { + List playersWithNick = NickUtils.getInstance() + .getOfflinePlayersByNickname(nickname.getNormalizedNickname()); + + if (playersWithNick == null) { + sender.sendRichMessage(LocaleMessage.ERROR_NO_PLAYERS_FOUND_BY_THIS_NAME.getMessage()); + return; + } + + Component message = buildWhoMessage(nickname, playersWithNick); + sender.sendMessage(message); + }); + + return Command.SINGLE_SUCCESS; + } + + private Component buildWhoMessage(Nickname nickname, List players) { + Component header = miniMessage.deserialize(LocaleMessage.NICK_WHO_HEADER.getMessage(), Placeholder.parsed("value", nickname.getNormalizedNickname())); - if (playersWithNick.isEmpty()) { - messageComponent = messageComponent.append(miniMessage.deserialize( - LocaleMessage.INSERT_NONE.getMessage())); - sender.sendMessage(messageComponent); - return Command.SINGLE_SUCCESS; + + if (players.isEmpty()) { + return header.append(miniMessage.deserialize(LocaleMessage.INSERT_NONE.getMessage())); } - for (OfflinePlayer player : playersWithNick) { + + Component result = header; + long now = System.currentTimeMillis(); + + for (OfflinePlayer player : players) { String username = player.getName(); if (username == null) continue; - long lastSeen = player.getLastSeen(); - long currentTime = System.currentTimeMillis(); - long timeDiff = currentTime - lastSeen; - timeDiff = timeDiff / 1000; - messageComponent = messageComponent.append(miniMessage.deserialize( - LocaleMessage.NICK_WHO_USER.getMessage() + LocaleMessage.INSERT_TIME_FORMAT_AGO.getMessage(), - Placeholder.parsed("name", username), - MessageUtils.getTimeFormat(timeDiff))); + long timeDiffSeconds = (now - player.getLastSeen()) / 1000; + result = result.append(miniMessage.deserialize( + LocaleMessage.NICK_WHO_USER.getMessage(), + Placeholder.parsed("name", username), + MessageUtils.getTimeFormat(timeDiffSeconds) + )); } - sender.sendMessage(messageComponent); - return Command.SINGLE_SUCCESS; + return result; } + @Override public boolean canExecute(@NotNull CommandSourceStack css) { CommandSender sender = css.getSender(); diff --git a/src/main/java/simplexity/simplenicks/config/LocaleMessage.java b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java index e2ce769..b1a6ca7 100644 --- a/src/main/java/simplexity/simplenicks/config/LocaleMessage.java +++ b/src/main/java/simplexity/simplenicks/config/LocaleMessage.java @@ -1,23 +1,22 @@ package simplexity.simplenicks.config; public enum LocaleMessage { - PLUGIN_PREFIX("plugin.prefix", "SimpleNicks » "), - HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), - SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), - CONFIG_RELOADED("plugin.config-reloaded", "SimpleNicks config and locale reloaded"), + HELP_MESSAGE("plugin.help-message", "\n========================\n· Setting a nickname:\n/nick set \n· removing a nickname:\n/nick reset\n· Formatting:\nThis plugin uses minimessage formatting. You can find a format viewer here"), + SHOWN_HELP("plugin.shown-help", " has been shown the help screen"), + CONFIG_RELOADED("plugin.config-reloaded", "SimpleNicks config and locale reloaded"), SERVER_DISPLAY_NAME("plugin.server-display-name", "[Server]"), - CHANGED_SELF("nick.changed.self", "Changed your nickname to !"), - CHANGED_OTHER("nick.changed.other", "Changed 's nickname to "), - CHANGED_BY_OTHER("nick.changed.by-other", " changed your nickname to !"), - RESET_SELF("nick.reset.self", "Reset your nickname!"), - RESET_OTHER("nick.reset.other", "Reset 's nickname."), - RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), - SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), - DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), - NICK_DELETED_BY_OTHER("nick.delete.by-other", "The nickname has been deleted from your saved nicknames by "), - NICK_DELETED_OTHER("nick.delete.other", "You have successfully deleted from 's saved nicknames"), - NICK_WHO_HEADER("nick.who.header", "Users with the name : "), - NICK_WHO_USER("nick.who.user", "\n- - Last Seen: "), + CHANGED_SELF("nick.changed.self", "Changed your nickname to !"), + CHANGED_OTHER("nick.changed.other", "Changed 's nickname to "), + CHANGED_BY_OTHER("nick.changed.by-other", " changed your nickname to !"), + RESET_SELF("nick.reset.self", "Reset your nickname!"), + RESET_OTHER("nick.reset.other", "Reset 's nickname."), + RESET_BY_OTHER("nick.reset.reset-by-other", "Your nickname was reset by "), + SAVE_NICK("nick.save.self", "Success! The nickname has been saved for future use"), + DELETE_NICK("nick.delete.self", "The nickname has been successfully removed from your saved names"), + NICK_DELETED_BY_OTHER("nick.delete.by-other", "The nickname has been deleted from your saved nicknames by "), + NICK_DELETED_OTHER("nick.delete.other", "You have successfully deleted from 's saved nicknames"), + NICK_WHO_HEADER("nick.who.header", "Users with the name : "), + NICK_WHO_USER("nick.who.user", "\n- - Last Seen: