From b48bcb7688fa56bea792812ac13ed42e91c01c41 Mon Sep 17 00:00:00 2001 From: WildInterloper <156627888+WildInterloper@users.noreply.github.com> Date: Thu, 14 Mar 2024 03:16:32 -0400 Subject: [PATCH] v1.0.1 - Re-wrote rank commands and set them up to use MySQL/SQLite!!!! --- pom.xml | 2 +- .../Database/DatabaseManager.java | 331 ++++++++- .../Listeners/CommandListener.java | 39 ++ .../nvus/nvus_prison_setup/PrisonSetup.java | 9 +- .../nvus_prison_setup/Ranks/RankManager.java | 631 ++++++++++-------- src/main/resources/plugin.yml | 4 + src/main/resources/ranks.yml | 2 +- 7 files changed, 745 insertions(+), 273 deletions(-) diff --git a/pom.xml b/pom.xml index cc61a14..95a7b6b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.NVus NVus_Prison - 1.0.0 + 1.0.1 jar NVus_PrisonSetup diff --git a/src/main/java/me/nvus/nvus_prison_setup/Database/DatabaseManager.java b/src/main/java/me/nvus/nvus_prison_setup/Database/DatabaseManager.java index 481cc98..7f0efd0 100644 --- a/src/main/java/me/nvus/nvus_prison_setup/Database/DatabaseManager.java +++ b/src/main/java/me/nvus/nvus_prison_setup/Database/DatabaseManager.java @@ -6,12 +6,19 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.UUID; import java.io.File; import me.nvus.nvus_prison_setup.Gangs.GangInfo; +import me.nvus.nvus_prison_setup.Ranks.Rank; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import me.nvus.nvus_prison_setup.Configs.ConfigManager; +import org.bukkit.entity.Player; + import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -42,8 +49,10 @@ public class DatabaseManager { } else { this.url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?user=" + username + "&password=" + password; } - - initializeDatabase(); + // Init Gangs Database + initializeGangDatabase(); + // Init Ranks Database + initializeRanksDatabase(); } @@ -51,7 +60,317 @@ public class DatabaseManager { return DriverManager.getConnection(url); } - private void initializeDatabase() { + + + + // Public Accessor to initialize the database + public void initGangDatabase() { + initializeGangDatabase(); + } + public void initRanksDatabase() { + initializeRanksDatabase(); + } + + +/* ================================================================================================================ + RANKS RELATED METHODS +==================================================================================================================*/ + + private void initializeRanksDatabase() { + String sqlRanks = "CREATE TABLE IF NOT EXISTS nvus_ranks (" + + "rank_name VARCHAR(255) NOT NULL PRIMARY KEY," + + "cost DOUBLE NOT NULL," + + "commands TEXT NOT NULL" + + ");"; + + String sqlRanksPlayers = "CREATE TABLE IF NOT EXISTS nvus_ranks_players (" + + "uuid VARCHAR(36) NOT NULL," + + "username VARCHAR(255) NOT NULL," + + "rank_name VARCHAR(255) NOT NULL," + + "FOREIGN KEY (rank_name) REFERENCES nvus_ranks(rank_name) ON DELETE CASCADE ON UPDATE CASCADE" + + ");"; + + try (Connection conn = connect(); Statement stmt = conn.createStatement()) { + stmt.execute(sqlRanks); + stmt.execute(sqlRanksPlayers); + } catch (SQLException e) { + System.out.println("Error initializing Ranks database: " + e.getMessage()); + } + + } + + + + private void loadRanksFromConfig(FileConfiguration ranksConfig) { + ConfigurationSection ranksSection = ranksConfig.getConfigurationSection("Ranks"); + if (ranksSection != null) { + for (String rankKey : ranksSection.getKeys(false)) { + String rankName = rankKey; + double cost = ranksSection.getDouble(rankKey + ".Cost"); + List commandsList = ranksSection.getStringList(rankKey + ".Commands"); + // Join the commands list into a single string with ";" as the delimiter + String commands = String.join(";", commandsList); + + // Insert or update the ranks in the database with the commands as a single string + upsertRankInDatabase(rankName, cost, commands); + } + } + } + + + public void syncRanks() { + FileConfiguration ranksConfig = configManager.getConfig("ranks.yml"); + // Assuming you've moved loadRanksFromConfig method logic directly here or keep it separated as below + loadRanksFromConfig(ranksConfig); + } + + private void upsertRankInDatabase(String rankName, double cost, String commandsAsString) { + // This method will check if the rank exists and update or insert accordingly + String selectQuery = "SELECT COUNT(*) FROM nvus_ranks WHERE rank_name = ?"; + String insertQuery = "INSERT INTO nvus_ranks (rank_name, cost, commands) VALUES (?, ?, ?)"; + String updateQuery = "UPDATE nvus_ranks SET cost = ?, commands = ? WHERE rank_name = ?"; + + try (Connection conn = connect(); + PreparedStatement selectStmt = conn.prepareStatement(selectQuery); + PreparedStatement insertStmt = conn.prepareStatement(insertQuery); + PreparedStatement updateStmt = conn.prepareStatement(updateQuery)) { + + // Check if rank exists + selectStmt.setString(1, rankName); + ResultSet rs = selectStmt.executeQuery(); + if (rs.next() && rs.getInt(1) > 0) { + // Rank exists, update it + updateStmt.setDouble(1, cost); + updateStmt.setString(2, commandsAsString); + updateStmt.setString(3, rankName); + updateStmt.executeUpdate(); + } else { + // Rank doesn't exist, insert it + insertStmt.setString(1, rankName); + insertStmt.setDouble(2, cost); + insertStmt.setString(3, commandsAsString); + insertStmt.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Error upserting rank: " + e.getMessage()); + } + } + + public void initializeAndSyncRanks() { + // Initialize the database (tables creation) + initializeRanksDatabase(); + + // Load ranks from the ranks.yml config and sync them with the database + syncRanks(); + } + + + + public void reloadRanks() { + syncRanks(); + } + + // Now it's a onstructor to re-build string comments from DB with ; as delimeter to a LIST/ARRAY :P + public Rank getCurrentRank(Player player) { + String playerRankSql = "SELECT rank_name FROM nvus_ranks_players WHERE uuid = ?"; + String rankDetailsSql = "SELECT * FROM nvus_ranks WHERE rank_name = ?"; + + try (Connection conn = connect(); + PreparedStatement pstmtPlayerRank = conn.prepareStatement(playerRankSql)) { + + pstmtPlayerRank.setString(1, player.getUniqueId().toString()); + ResultSet rsPlayerRank = pstmtPlayerRank.executeQuery(); + + if (rsPlayerRank.next()) { + String rankName = rsPlayerRank.getString("rank_name"); + + try (PreparedStatement pstmtRankDetails = conn.prepareStatement(rankDetailsSql)) { + pstmtRankDetails.setString(1, rankName); + ResultSet rsRankDetails = pstmtRankDetails.executeQuery(); + + if (rsRankDetails.next()) { + double cost = rsRankDetails.getDouble("cost"); + String commandsAsString = rsRankDetails.getString("commands"); + List commands = new ArrayList<>(); + if (commandsAsString != null && !commandsAsString.isEmpty()) { + commands = Arrays.asList(commandsAsString.split(";")); + } + return new Rank(rankName, cost, commands); + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public Rank getCurrentPlayerRank(Player player) { + return getCurrentRank(player); + } + + + + private Rank getNextRank(Player player) { + Rank currentRank = getCurrentRank(player); + if (currentRank == null) { + return null; // Player has no current rank, handle as needed + } + + final String query = "SELECT * FROM nvus_ranks WHERE cost > ? ORDER BY cost ASC LIMIT 1"; + + try (Connection conn = connect(); + PreparedStatement pstmt = conn.prepareStatement(query)) { + + pstmt.setDouble(1, currentRank.getCost()); + ResultSet rs = pstmt.executeQuery(); + + if (rs.next()) { + String rankName = rs.getString("rank_name"); + double cost = rs.getDouble("cost"); + String commandsAsString = rs.getString("commands"); + List commands = new ArrayList<>(); + if (commandsAsString != null && !commandsAsString.isEmpty()) { + commands = Arrays.asList(commandsAsString.split(";")); + } + return new Rank(rankName, cost, commands); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; // Player is at the highest rank or an error occurred + } + + + public Rank getPlayerNextRank(Player player) { + return getNextRank(player); + } + + private void updatePlayerRank(UUID uuid, String username, String newRankName) { + // SQL query to update the player's rank + String updateSql = "UPDATE nvus_ranks_players SET rank_name = ?, username = ? WHERE uuid = ?;"; + + // SQL query to insert a new row if the player does not exist in the table + String insertSql = "INSERT INTO nvus_ranks_players (uuid, username, rank_name) SELECT ?, ?, ? WHERE NOT EXISTS (SELECT 1 FROM nvus_ranks_players WHERE uuid = ?);"; + + try (Connection conn = connect(); + PreparedStatement updateStmt = conn.prepareStatement(updateSql); + PreparedStatement insertStmt = conn.prepareStatement(insertSql)) { + + // First, try to update the player's rank + updateStmt.setString(1, newRankName); + updateStmt.setString(2, username); + updateStmt.setString(3, uuid.toString()); + int rowsAffected = updateStmt.executeUpdate(); + + // If the player was not already in the table, insert a new row + if (rowsAffected == 0) { + insertStmt.setString(1, uuid.toString()); + insertStmt.setString(2, username); + insertStmt.setString(3, newRankName); + insertStmt.setString(4, uuid.toString()); + insertStmt.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Error updating player rank: " + e.getMessage()); + } + } + + + public void updatePlayerRankData(Player player, Rank nextRank) { + // Extract UUID and username from the Player object + UUID playerUUID = player.getUniqueId(); + String username = player.getName(); + + // Extract the new rank name from the Rank object + String newRankName = nextRank.getName(); + + // Update the player's rank in the database + updatePlayerRank(playerUUID, username, newRankName); + } + + public List getAllRanksSorted() { + List sortedRanks = new ArrayList<>(); + final String query = "SELECT * FROM nvus_ranks ORDER BY cost ASC"; + + try (Connection conn = connect(); + PreparedStatement pstmt = conn.prepareStatement(query); + ResultSet rs = pstmt.executeQuery()) { + + while (rs.next()) { + String rankName = rs.getString("rank_name"); + double cost = rs.getDouble("cost"); + String commandsAsString = rs.getString("commands"); + List commands = new ArrayList<>(); + if (commandsAsString != null && !commandsAsString.isEmpty()) { + commands = Arrays.asList(commandsAsString.split(";")); + } + Rank rank = new Rank(rankName, cost, commands); + sortedRanks.add(rank); + } + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Error retrieving all ranks sorted: " + e.getMessage()); + } + return sortedRanks; + } + + + + private void setPlayerDefaultRank(UUID playerUuid, String playerName) { + final String defaultRankQuery = "SELECT * FROM nvus_ranks ORDER BY cost ASC LIMIT 1"; + final String insertOrUpdatePlayerRankSql = "INSERT INTO nvus_ranks_players (uuid, username, rank_name) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE rank_name = VALUES(rank_name), username = VALUES(username)"; + + try (Connection conn = connect(); + PreparedStatement defaultRankStmt = conn.prepareStatement(defaultRankQuery); + ResultSet rsDefaultRank = defaultRankStmt.executeQuery()) { + + if (rsDefaultRank.next()) { + String defaultRankName = rsDefaultRank.getString("rank_name"); + + try (PreparedStatement insertOrUpdateStmt = conn.prepareStatement(insertOrUpdatePlayerRankSql)) { + insertOrUpdateStmt.setString(1, playerUuid.toString()); + insertOrUpdateStmt.setString(2, playerName); + insertOrUpdateStmt.setString(3, defaultRankName); + insertOrUpdateStmt.executeUpdate(); + } + } + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("Error setting default rank for player: " + e.getMessage()); + } + } + + public void assignPlayerToDefaultRank(Player player) { + setPlayerDefaultRank(player.getUniqueId(), player.getName()); + } + + + + + + + + + + + + + + + + + + + + + /* ================================================================================================================ + GANG RELATED METHODS + ==================================================================================================================*/ + + private void initializeGangDatabase() { String sqlGangs = "CREATE TABLE IF NOT EXISTS nvus_gangs (" + "id INTEGER PRIMARY KEY " + (databaseType.equalsIgnoreCase("SQLite") ? "AUTOINCREMENT" : "AUTO_INCREMENT") + "," + "name TEXT NOT NULL," @@ -76,12 +395,6 @@ public class DatabaseManager { - - // Public Accessor to initialize the database - public void initDatabase() { - initializeDatabase(); - } - public void createGang(String name, String ownerUuid, String ownerName) { String insertGangSQL = "INSERT INTO nvus_gangs(name, owner_uuid) VALUES(?,?)"; String insertMemberSQL = "INSERT INTO nvus_gangs_members(uuid, username, gang_id, rank) VALUES(?,?,(SELECT id FROM nvus_gangs WHERE owner_uuid = ?),'Owner')"; diff --git a/src/main/java/me/nvus/nvus_prison_setup/Listeners/CommandListener.java b/src/main/java/me/nvus/nvus_prison_setup/Listeners/CommandListener.java index 7127790..3f42f13 100644 --- a/src/main/java/me/nvus/nvus_prison_setup/Listeners/CommandListener.java +++ b/src/main/java/me/nvus/nvus_prison_setup/Listeners/CommandListener.java @@ -10,6 +10,11 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + public class CommandListener implements CommandExecutor { private final JavaPlugin plugin; private final ConfigManager configManager; @@ -60,6 +65,9 @@ public class CommandListener implements CommandExecutor { case "version": handleVersionCommand(sender); break; + case "id": + handleIdCommand(sender); + break; case "menu": if (!(sender instanceof Player)) { sender.sendMessage(ChatColor.RED + "This command can only be used by players."); @@ -145,6 +153,36 @@ public class CommandListener implements CommandExecutor { sender.sendMessage(ChatColor.GREEN + "Plugin version: " + plugin.getDescription().getVersion()); } + public void handleIdCommand(CommandSender sender) { + // Check if the sender is a player + if (sender instanceof Player) { + Player player = (Player) sender; + + // Your existing logic here + // For example, sending the player their username and UUID in a simple message + player.sendMessage("Your username: " + player.getName()); + player.sendMessage("Your UUID: " + player.getUniqueId().toString()); + + // Now send the clickable UUID message + sendClickableUUID(player); + } else { + // If the command sender is not a player (e.g., console), handle appropriately + sender.sendMessage("This command can only be used by a player."); + } + } + + public void sendClickableUUID(Player player) { + String uuid = player.getUniqueId().toString(); + + TextComponent message = new TextComponent("Click here to copy your UUID"); + message.setColor(net.md_5.bungee.api.ChatColor.GOLD); + message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, uuid)); + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click to copy your UUID").color(net.md_5.bungee.api.ChatColor.YELLOW).create())); + + player.spigot().sendMessage(message); + } + + private void handleToggleConfigCommand(CommandSender sender, String key, String value) { boolean boolValue = Boolean.parseBoolean(value); FileConfiguration config = configManager.getConfig("config.yml"); @@ -153,4 +191,5 @@ public class CommandListener implements CommandExecutor { sender.sendMessage(ChatColor.GREEN + key + " set to " + boolValue + "."); } + } diff --git a/src/main/java/me/nvus/nvus_prison_setup/PrisonSetup.java b/src/main/java/me/nvus/nvus_prison_setup/PrisonSetup.java index 1bd3030..2a81359 100644 --- a/src/main/java/me/nvus/nvus_prison_setup/PrisonSetup.java +++ b/src/main/java/me/nvus/nvus_prison_setup/PrisonSetup.java @@ -73,7 +73,8 @@ public final class PrisonSetup extends JavaPlugin { // Check if SQLite DB Exists, if not init it File databaseFile = new File(getDataFolder(), "nvus_prison.db"); if (!databaseFile.exists()) { - dbManager.initDatabase(); // Correct use of dbManager after initialization + dbManager.initGangDatabase(); // Correct use of dbManager after initialization + dbManager.initRanksDatabase(); // Correct use of dbManager after initialization getLogger().info("Database initialized successfully."); } else { getLogger().info("SQLite database already exists."); @@ -140,8 +141,11 @@ public final class PrisonSetup extends JavaPlugin { // Ranks Manager boolean prisonerRanksEnabled = configManager.getConfig("config.yml").getBoolean("PrisonerRanks", true); if (prisonerRanksEnabled) { + // Init & Sync Ranks with Database + dbManager.initializeAndSyncRanks(); + // Initialize RankManager and other initializations - rankManager = new RankManager(this); + rankManager = new RankManager(dbManager,econ); // Use the corrected dbManager // Register RankListener getServer().getPluginManager().registerEvents(new RankListener(rankManager), this); @@ -149,6 +153,7 @@ public final class PrisonSetup extends JavaPlugin { // Register commands this.getCommand("rankup").setExecutor(new RankCommands(this)); this.getCommand("ranks").setExecutor(new RankCommands(this)); + } // Successful Startup/Enable diff --git a/src/main/java/me/nvus/nvus_prison_setup/Ranks/RankManager.java b/src/main/java/me/nvus/nvus_prison_setup/Ranks/RankManager.java index 67d3197..6a37dd1 100644 --- a/src/main/java/me/nvus/nvus_prison_setup/Ranks/RankManager.java +++ b/src/main/java/me/nvus/nvus_prison_setup/Ranks/RankManager.java @@ -1,317 +1,428 @@ package me.nvus.nvus_prison_setup.Ranks; -import com.google.gson.Gson; -import me.nvus.nvus_prison_setup.PrisonSetup; +import me.nvus.nvus_prison_setup.Database.DatabaseManager; import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.EconomyResponse; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; -import java.io.FileReader; -import java.io.FileWriter; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.List; public class RankManager { - private JavaPlugin plugin; - private List ranks = new ArrayList<>(); - private Map playerRanks = new HashMap<>(); + private final DatabaseManager dbManager; + private final Economy economy; // Assuming you have a method to get the Economy service - - public RankManager(JavaPlugin plugin) { - this.plugin = plugin; - ensureRankDataFile(); - loadRanksFromConfig(); - loadPlayerRanks(); - loadRanksFromRankDataFile(); + public RankManager(DatabaseManager dbManager, Economy economy) { + this.dbManager = dbManager; + this.economy = economy; + syncRanksWithDatabase(); } - private void ensureRankDataFile() { - File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); - if (!rankDataFile.exists()) { - try { - plugin.saveResource("ranks.yml", false); - File ranksYmlFile = new File(plugin.getDataFolder(), "ranks.yml"); - FileConfiguration ranksConfig = YamlConfiguration.loadConfiguration(ranksYmlFile); - updateRankDataFromYml(ranksConfig, rankDataFile); - } catch (Exception e) { - e.printStackTrace(); - } - } + public void syncRanksWithDatabase() { + dbManager.syncRanks(); } - private void updateRankDataFromYml(FileConfiguration ranksConfig, File rankDataFile) { - try { - Set rankKeys = ranksConfig.getConfigurationSection("Ranks").getKeys(false); - List ranks = rankKeys.stream().map(rankKey -> { - String path = "Ranks." + rankKey; - String name = rankKey; - double cost = ranksConfig.getDouble(path + ".Cost"); - List commands = ranksConfig.getStringList(path + ".Commands"); - return new Rank(name, cost, commands); - }).collect(Collectors.toList()); - - Map rankData = new HashMap<>(); - rankData.put("ranks", ranks); - // Add a dummy player data for demonstration. Replace with actual player data logic. - rankData.put("players", Collections.singletonList(new PlayerRankData(UUID.randomUUID(), "DummyPlayer", "Default"))); - - try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(rankDataFile), StandardCharsets.UTF_8))) { - new Gson().toJson(rankData, writer); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void loadRanksFromConfig() { - File ranksYmlFile = new File(plugin.getDataFolder(), "ranks.yml"); - if (ranksYmlFile.exists()) { - FileConfiguration ranksConfig = YamlConfiguration.loadConfiguration(ranksYmlFile); - File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); - updateRankDataFromYml(ranksConfig, rankDataFile); - // Debug log to check ranks loading - System.out.println("Loaded ranks: " + ranks.size()); - ranks.forEach(rank -> System.out.println(rank.getName() + ": $" + rank.getCost())); - } - } - - private void loadRanksFromRankDataFile() { - File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); - if (rankDataFile.exists()) { - try (Reader reader = new FileReader(rankDataFile)) { - Gson gson = new Gson(); - Type type = new TypeToken>() {}.getType(); - Map rankDataMap = gson.fromJson(reader, type); - - List> ranksList = (List>) rankDataMap.get("ranks"); - if (ranksList != null) { - this.ranks.clear(); // Clear existing ranks before loading new ones - for (Map rankMap : ranksList) { - String name = (String) rankMap.get("name"); - double cost = ((Number) rankMap.get("cost")).doubleValue(); - List commands = (List) rankMap.get("commands"); - Rank rank = new Rank(name, cost, commands); - this.ranks.add(rank); - } - } - System.out.println("Loaded ranks from rank_data.json: " + ranks.size()); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public Rank getCurrentRank(Player player) { - String currentRankName = playerRanks.get(player.getUniqueId()); - if (currentRankName == null) { - // Reload ranks from config to ensure they are up to date - loadRanksFromConfig(); - loadPlayerRanks(); - - // Assign default rank if the player has no current rank - assignDefaultRank(player); - currentRankName = playerRanks.get(player.getUniqueId()); - } - - // Use a final variable for the lambda expression - final String rankNameForLambda = currentRankName; - - return ranks.stream() - .filter(rank -> rank.getName().equals(rankNameForLambda)) - .findFirst() - .orElse(null); // Consider handling the default rank if not found. + return dbManager.getCurrentPlayerRank(player); } - public Rank getNextRank(Player player) { - Rank currentRank = getCurrentRank(player); - if (currentRank == null) { - return null; // Handle appropriately, maybe return the first rank if implementing a default catch-up mechanism. - } - int currentIndex = ranks.indexOf(currentRank); - if (currentIndex < ranks.size() - 1) { - return ranks.get(currentIndex + 1); - } - return null; // Player is at the highest rank. + return dbManager.getPlayerNextRank(player); } public boolean rankUp(Player player) { - // Directly retrieve the next rank using the player object Rank nextRank = getNextRank(player); - if (nextRank == null) { player.sendMessage(ChatColor.RED + "You are already at the highest rank!"); return false; } - Economy economy = PrisonSetup.getEconomy(); // Assuming this static method access is correct double balance = economy.getBalance(player); - - if (balance < nextRank.getCost()) { - player.sendMessage(ChatColor.RED + "You cannot afford to rank up. You have " + balance + ", but need " + nextRank.getCost() + "."); + if (balance >= nextRank.getCost()) { + EconomyResponse response = economy.withdrawPlayer(player, nextRank.getCost()); + if (response.transactionSuccess()) { + dbManager.updatePlayerRankData(player, nextRank); + executeRankCommands(player, nextRank.getCommands()); + //player.sendMessage(ChatColor.GREEN + "Congratulations! You've been ranked up to " + nextRank.getName() + "."); + return true; + } else { + player.sendMessage(ChatColor.RED + "Transaction failed: " + response.errorMessage); + return false; + } + } else { + player.sendMessage(ChatColor.RED + "You cannot afford to rank up. You need $" + nextRank.getCost() + ", but you only have $" + balance + "."); return false; } - - EconomyResponse response = economy.withdrawPlayer(player, nextRank.getCost()); - if (!response.transactionSuccess()) { - player.sendMessage(ChatColor.RED + "Transaction failed: " + response.errorMessage); - return false; - } - - // Update the player's rank in memory and any persistent storage - playerRanks.put(player.getUniqueId(), nextRank.getName()); - saveRankData(); // Ensure to implement this method to persist changes to 'rank_data.json' - - // Execute rank-up commands - executeRankCommands(player, nextRank.getCommands()); - - player.sendMessage(ChatColor.GREEN + "You've been ranked up to " + nextRank.getName() + "!"); - return true; } - - private void updatePlayerRank(Player player, Rank nextRank) { - // Update the player's current rank in memory (if you're keeping a cache) - playerRanks.put(player.getUniqueId(), nextRank.getName()); - // Save the player's current rank to persistent storage - saveRankData(); - } - - - private void executeRankCommands(Player player, List commands) { if (commands == null || commands.isEmpty()) return; - String playerName = player.getName(); - commands.forEach(command -> - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%player%", playerName)) - ); - } - - - private void saveRankData() { - File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - // Load existing rank data to merge with updates - Map existingData = new HashMap<>(); - try (Reader reader = new FileReader(rankDataFile)) { - Type type = new TypeToken>() {}.getType(); - existingData = gson.fromJson(reader, type); - } catch (Exception e) { - e.printStackTrace(); - } - - // If there's no existing data or it's the first time, initialize structures - if (existingData == null) { - existingData = new HashMap<>(); - } - - // Prepare rank data to be saved - List> serializedRanks = ranks.stream().map(rank -> { - Map rankMap = new HashMap<>(); - rankMap.put("name", rank.getName()); - rankMap.put("cost", rank.getCost()); - rankMap.put("commands", rank.getCommands()); - return rankMap; - }).collect(Collectors.toList()); - - // Prepare player rank data to be saved - List> serializedPlayerRanks = playerRanks.entrySet().stream().map(entry -> { - Map playerRankMap = new HashMap<>(); - playerRankMap.put("uuid", entry.getKey().toString()); - playerRankMap.put("rankName", entry.getValue()); - return playerRankMap; - }).collect(Collectors.toList()); - - // Update the existing data map - existingData.put("ranks", serializedRanks); - existingData.put("players", serializedPlayerRanks); - - // Save the updated data back to the file - try (Writer writer = new FileWriter(rankDataFile)) { - gson.toJson(existingData, writer); - } catch (Exception e) { - e.printStackTrace(); + for (String command : commands) { + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%player%", player.getName())); } } public String getRanksDisplay(Player player) { StringBuilder ranksMessage = new StringBuilder(ChatColor.GOLD + "Available Ranks:\n"); - for (Rank rank : ranks) { + Rank currentRank = getCurrentRank(player); + // Assuming you have a method to get all ranks sorted by cost + List allRanks = dbManager.getAllRanksSorted(); + for (Rank rank : allRanks) { ranksMessage.append(ChatColor.YELLOW).append(rank.getName()) .append(ChatColor.WHITE).append(" - $") .append(ChatColor.GREEN).append(rank.getCost()).append("\n"); } - - // Fetch the player's current rank from the stored data - String currentRankName = playerRanks.getOrDefault(player.getUniqueId(), "Unranked"); - // Using Vault to get the player's balance - Economy economy = PrisonSetup.getEconomy(); + ranksMessage.append(ChatColor.GOLD + "\nYour current rank: " + ChatColor.YELLOW + currentRank.getName()); double balance = economy.getBalance(player); - - // Append the player's current rank and balance to the message - ranksMessage.append(ChatColor.GOLD + "\nYour current rank: " + ChatColor.YELLOW + currentRankName); ranksMessage.append(ChatColor.GOLD + "\nYour balance: " + ChatColor.GREEN + "$" + balance); - return ranksMessage.toString(); } + public void assignDefaultRank(Player player) { - if (!playerRanks.containsKey(player.getUniqueId())) { - // Ensure this method successfully finds and assigns the default rank - Rank defaultRank = ranks.stream().filter(r -> r.getName().equalsIgnoreCase("Default")).findFirst().orElse(null); - if (defaultRank != null) { - playerRanks.put(player.getUniqueId(), defaultRank.getName()); - // Debug log - System.out.println("Assigning default rank to " + player.getName()); - saveRankData(); - player.sendMessage(ChatColor.GREEN + "You've been assigned the default rank: " + defaultRank.getName()); - } else { - System.out.println("Default rank not found in loaded ranks."); - } - } + dbManager.assignPlayerToDefaultRank(player); + // You might want to log this action or send a message to the player + player.sendMessage(ChatColor.GREEN + "You have been assigned the default rank."); } - private void loadPlayerRanks() { - File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); - if (rankDataFile.exists()) { - try (Reader reader = new FileReader(rankDataFile)) { - Type type = new TypeToken>>() {}.getType(); - Map> data = new Gson().fromJson(reader, type); - List playerRankDataList = data.get("players"); - if (playerRankDataList != null) { - playerRankDataList.forEach(playerRankData -> playerRanks.put(playerRankData.getUuid(), playerRankData.getRankName())); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - - - - - - } + + + + + + + + + + + + + + + + + +//package me.nvus.nvus_prison_setup.Ranks; +// +//import com.google.gson.Gson; +//import me.nvus.nvus_prison_setup.PrisonSetup; +//import net.milkbowl.vault.economy.Economy; +//import net.milkbowl.vault.economy.EconomyResponse; +//import org.bukkit.Bukkit; +//import org.bukkit.ChatColor; +//import org.bukkit.configuration.file.FileConfiguration; +//import org.bukkit.configuration.file.YamlConfiguration; +//import org.bukkit.plugin.java.JavaPlugin; +//import org.bukkit.entity.Player; +// +//import java.io.*; +//import java.nio.charset.StandardCharsets; +//import java.nio.file.Files; +//import java.nio.file.Paths; +//import java.util.*; +//import java.util.stream.Collectors; +//import com.google.gson.GsonBuilder; +//import com.google.gson.reflect.TypeToken; +//import java.io.FileReader; +//import java.io.FileWriter; +//import java.lang.reflect.Type; +//import java.util.HashMap; +//import java.util.Map; +//import java.util.UUID; +// +//public class RankManager { +// +// private JavaPlugin plugin; +// private List ranks = new ArrayList<>(); +// private Map playerRanks = new HashMap<>(); +// +// +// public RankManager(JavaPlugin plugin) { +// this.plugin = plugin; +// ensureRankDataFile(); +// loadRanksFromConfig(); +// loadPlayerRanks(); +// loadRanksFromRankDataFile(); +// } +// +// private void ensureRankDataFile() { +// File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); +// if (!rankDataFile.exists()) { +// try { +// plugin.saveResource("ranks.yml", false); +// File ranksYmlFile = new File(plugin.getDataFolder(), "ranks.yml"); +// FileConfiguration ranksConfig = YamlConfiguration.loadConfiguration(ranksYmlFile); +// updateRankDataFromYml(ranksConfig, rankDataFile); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// +// private void updateRankDataFromYml(FileConfiguration ranksConfig, File rankDataFile) { +// try { +// Set rankKeys = ranksConfig.getConfigurationSection("Ranks").getKeys(false); +// List ranks = rankKeys.stream().map(rankKey -> { +// String path = "Ranks." + rankKey; +// String name = rankKey; +// double cost = ranksConfig.getDouble(path + ".Cost"); +// List commands = ranksConfig.getStringList(path + ".Commands"); +// return new Rank(name, cost, commands); +// }).collect(Collectors.toList()); +// +// Map rankData = new HashMap<>(); +// rankData.put("ranks", ranks); +// // Add a dummy player data for demonstration. Replace with actual player data logic. +// rankData.put("players", Collections.singletonList(new PlayerRankData(UUID.randomUUID(), "DummyPlayer", "Default"))); +// +// try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(rankDataFile), StandardCharsets.UTF_8))) { +// new Gson().toJson(rankData, writer); +// } +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// public void loadRanksFromConfig() { +// File ranksYmlFile = new File(plugin.getDataFolder(), "ranks.yml"); +// if (ranksYmlFile.exists()) { +// FileConfiguration ranksConfig = YamlConfiguration.loadConfiguration(ranksYmlFile); +// File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); +// updateRankDataFromYml(ranksConfig, rankDataFile); +// // Debug log to check ranks loading +// System.out.println("Loaded ranks: " + ranks.size()); +// ranks.forEach(rank -> System.out.println(rank.getName() + ": $" + rank.getCost())); +// } +// } +// +// private void loadRanksFromRankDataFile() { +// File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); +// if (rankDataFile.exists()) { +// try (Reader reader = new FileReader(rankDataFile)) { +// Gson gson = new Gson(); +// Type type = new TypeToken>() {}.getType(); +// Map rankDataMap = gson.fromJson(reader, type); +// +// List> ranksList = (List>) rankDataMap.get("ranks"); +// if (ranksList != null) { +// this.ranks.clear(); // Clear existing ranks before loading new ones +// for (Map rankMap : ranksList) { +// String name = (String) rankMap.get("name"); +// double cost = ((Number) rankMap.get("cost")).doubleValue(); +// List commands = (List) rankMap.get("commands"); +// Rank rank = new Rank(name, cost, commands); +// this.ranks.add(rank); +// } +// } +// System.out.println("Loaded ranks from rank_data.json: " + ranks.size()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// +// +// public Rank getCurrentRank(Player player) { +// String currentRankName = playerRanks.get(player.getUniqueId()); +// if (currentRankName == null) { +// // Reload ranks from config to ensure they are up to date +// loadRanksFromConfig(); +// loadPlayerRanks(); +// +// // Assign default rank if the player has no current rank +// assignDefaultRank(player); +// currentRankName = playerRanks.get(player.getUniqueId()); +// } +// +// // Use a final variable for the lambda expression +// final String rankNameForLambda = currentRankName; +// +// return ranks.stream() +// .filter(rank -> rank.getName().equals(rankNameForLambda)) +// .findFirst() +// .orElse(null); // Consider handling the default rank if not found. +// } +// +// +// public Rank getNextRank(Player player) { +// Rank currentRank = getCurrentRank(player); +// if (currentRank == null) { +// return null; // Handle appropriately, maybe return the first rank if implementing a default catch-up mechanism. +// } +// int currentIndex = ranks.indexOf(currentRank); +// if (currentIndex < ranks.size() - 1) { +// return ranks.get(currentIndex + 1); +// } +// return null; // Player is at the highest rank. +// } +// +// public boolean rankUp(Player player) { +// // Directly retrieve the next rank using the player object +// Rank nextRank = getNextRank(player); +// +// if (nextRank == null) { +// player.sendMessage(ChatColor.RED + "You are already at the highest rank!"); +// return false; +// } +// +// Economy economy = PrisonSetup.getEconomy(); // Assuming this static method access is correct +// double balance = economy.getBalance(player); +// +// if (balance < nextRank.getCost()) { +// player.sendMessage(ChatColor.RED + "You cannot afford to rank up. You have " + balance + ", but need " + nextRank.getCost() + "."); +// return false; +// } +// +// EconomyResponse response = economy.withdrawPlayer(player, nextRank.getCost()); +// if (!response.transactionSuccess()) { +// player.sendMessage(ChatColor.RED + "Transaction failed: " + response.errorMessage); +// return false; +// } +// +// // Update the player's rank in memory and any persistent storage +// playerRanks.put(player.getUniqueId(), nextRank.getName()); +// saveRankData(); // Ensure to implement this method to persist changes to 'rank_data.json' +// +// // Execute rank-up commands +// executeRankCommands(player, nextRank.getCommands()); +// +// player.sendMessage(ChatColor.GREEN + "You've been ranked up to " + nextRank.getName() + "!"); +// return true; +// } +// +// +// private void updatePlayerRank(Player player, Rank nextRank) { +// // Update the player's current rank in memory (if you're keeping a cache) +// playerRanks.put(player.getUniqueId(), nextRank.getName()); +// // Save the player's current rank to persistent storage +// saveRankData(); +// } +// +// +// +// private void executeRankCommands(Player player, List commands) { +// if (commands == null || commands.isEmpty()) return; +// String playerName = player.getName(); +// commands.forEach(command -> +// Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%player%", playerName)) +// ); +// } +// +// +// private void saveRankData() { +// File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); +// Gson gson = new GsonBuilder().setPrettyPrinting().create(); +// +// // Load existing rank data to merge with updates +// Map existingData = new HashMap<>(); +// try (Reader reader = new FileReader(rankDataFile)) { +// Type type = new TypeToken>() {}.getType(); +// existingData = gson.fromJson(reader, type); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// // If there's no existing data or it's the first time, initialize structures +// if (existingData == null) { +// existingData = new HashMap<>(); +// } +// +// // Prepare rank data to be saved +// List> serializedRanks = ranks.stream().map(rank -> { +// Map rankMap = new HashMap<>(); +// rankMap.put("name", rank.getName()); +// rankMap.put("cost", rank.getCost()); +// rankMap.put("commands", rank.getCommands()); +// return rankMap; +// }).collect(Collectors.toList()); +// +// // Prepare player rank data to be saved +// List> serializedPlayerRanks = playerRanks.entrySet().stream().map(entry -> { +// Map playerRankMap = new HashMap<>(); +// playerRankMap.put("uuid", entry.getKey().toString()); +// playerRankMap.put("rankName", entry.getValue()); +// return playerRankMap; +// }).collect(Collectors.toList()); +// +// // Update the existing data map +// existingData.put("ranks", serializedRanks); +// existingData.put("players", serializedPlayerRanks); +// +// // Save the updated data back to the file +// try (Writer writer = new FileWriter(rankDataFile)) { +// gson.toJson(existingData, writer); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// public String getRanksDisplay(Player player) { +// StringBuilder ranksMessage = new StringBuilder(ChatColor.GOLD + "Available Ranks:\n"); +// for (Rank rank : ranks) { +// ranksMessage.append(ChatColor.YELLOW).append(rank.getName()) +// .append(ChatColor.WHITE).append(" - $") +// .append(ChatColor.GREEN).append(rank.getCost()).append("\n"); +// } +// +// // Fetch the player's current rank from the stored data +// String currentRankName = playerRanks.getOrDefault(player.getUniqueId(), "Unranked"); +// // Using Vault to get the player's balance +// Economy economy = PrisonSetup.getEconomy(); +// double balance = economy.getBalance(player); +// +// // Append the player's current rank and balance to the message +// ranksMessage.append(ChatColor.GOLD + "\nYour current rank: " + ChatColor.YELLOW + currentRankName); +// ranksMessage.append(ChatColor.GOLD + "\nYour balance: " + ChatColor.GREEN + "$" + balance); +// +// return ranksMessage.toString(); +// } +// +// public void assignDefaultRank(Player player) { +// if (!playerRanks.containsKey(player.getUniqueId())) { +// // Ensure this method successfully finds and assigns the default rank +// Rank defaultRank = ranks.stream().filter(r -> r.getName().equalsIgnoreCase("Default")).findFirst().orElse(null); +// if (defaultRank != null) { +// playerRanks.put(player.getUniqueId(), defaultRank.getName()); +// // Debug log +// System.out.println("Assigning default rank to " + player.getName()); +// saveRankData(); +// player.sendMessage(ChatColor.GREEN + "You've been assigned the default rank: " + defaultRank.getName()); +// } else { +// System.out.println("Default rank not found in loaded ranks."); +// } +// } +// } +// +// +// private void loadPlayerRanks() { +// File rankDataFile = new File(plugin.getDataFolder(), "rank_data.json"); +// if (rankDataFile.exists()) { +// try (Reader reader = new FileReader(rankDataFile)) { +// Type type = new TypeToken>>() {}.getType(); +// Map> data = new Gson().fromJson(reader, type); +// List playerRankDataList = data.get("players"); +// if (playerRankDataList != null) { +// playerRankDataList.forEach(playerRankData -> playerRanks.put(playerRankData.getUuid(), playerRankData.getRankName())); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// +// +// +// +// +// +// +// +// +//} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index bba07cc..8290d3a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -21,14 +21,18 @@ commands: usage: | /nvus reload - Reloads all configuration files. /nvus version - Shows the plugin version. + /nvus id - Display your username, UUID and send a clickable UUID. /nvus menu - Opens the settings menu. /nvus autopickup - Toggles the auto item pickup feature. /nvus autoswitch - Toggles the auto tool switch feature. /nvus prisonerarmor - Toggles giving prisoners armor on join. /nvus restrictarmor - Toggles the restriction on changing prisoner armor. /nvus tooldamage - Toggle if prisoner tools receive damage. FALSE = No Damage. + /nvus treefarm - Toggle the TreeFarm feature for prisoners. + /nvus prisonerranks - Toggle if prisoners can use the /rankup and /ranks commands. /nvus autosell - Toggle if prisoners can auto toggle auto selling of items as they are mined. /nvus sellall - Toggle if prisoners can use /sellall to manually sell items form inventory. + aliases: [prison] gang: diff --git a/src/main/resources/ranks.yml b/src/main/resources/ranks.yml index b386fe3..20d5639 100644 --- a/src/main/resources/ranks.yml +++ b/src/main/resources/ranks.yml @@ -6,7 +6,7 @@ #======================================================================================# Ranks: Default: # DO NOT CHANGE THE NAME 'Default' or this will break the plugin! This is the first/default rank! - Cost: 100 + Cost: 0 # This should always be free, as it's the default rank! Commands: - broadcast %player% has been processed as a new inmate! Tier2: