v1.0.0 Release - Added Rank Commands. Currently rank data is only stored locally in a rank_data.json file. Will implement MySQL/SQLite support at some point!

This commit is contained in:
WildInterloper 2024-03-13 23:28:50 -04:00
parent b74236c275
commit 7745ca2d93
10 changed files with 537 additions and 7 deletions

View File

@ -30,6 +30,8 @@ public class PlayerSpawn implements Listener {
if (joinedPlayer.hasPermission("nvus.prisoner") && configManager.getConfig("config.yml").getBoolean("PrisonerArmor", true)) {
equipPrisonerArmor(joinedPlayer);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)

View File

@ -10,6 +10,9 @@ import me.nvus.nvus_prison_setup.Listeners.PlayerSpawn;
import me.nvus.nvus_prison_setup.Listeners.BlockListener;
import me.nvus.nvus_prison_setup.Listeners.ToolSwitchListener;
import me.nvus.nvus_prison_setup.Placeholders.GangPlaceholders;
import me.nvus.nvus_prison_setup.Ranks.RankCommands;
import me.nvus.nvus_prison_setup.Ranks.RankListener;
import me.nvus.nvus_prison_setup.Ranks.RankManager;
import me.nvus.nvus_prison_setup.Updater.UpdateChecker;
import me.nvus.nvus_prison_setup.Listeners.ToolDamageListener;
import me.nvus.nvus_prison_setup.TreeFarm.TreeFarmListener;
@ -42,7 +45,9 @@ public final class PrisonSetup extends JavaPlugin {
private ConfigManager configManager;
private DatabaseManager dbManager;
private GangManager gangManager; // Added reference to GangManager
private GangManager gangManager;
private RankManager rankManager;
private static Economy econ = null; // Vault / Economy
@ -52,8 +57,15 @@ public final class PrisonSetup extends JavaPlugin {
// Initialize the ConfigManager
configManager = new ConfigManager(this);
// Save the default configs, if they don't exist
configManager.saveDefaultConfig("config.yml");
configManager.saveDefaultConfig("banned_items.yml");
configManager.saveDefaultConfig("auto_switch.yml");
configManager.saveDefaultConfig("item_prices.yml");
configManager.saveDefaultConfig("ranks.yml");
// Initialize the DatabaseManager with ConfigManager
dbManager = new DatabaseManager(configManager); // Correctly assign to the class field
dbManager = new DatabaseManager(configManager); // Correctly assign to the configManager
// Initialize the GangManager with the DatabaseManager
gangManager = new GangManager(dbManager); // Use the corrected dbManager
@ -67,11 +79,6 @@ public final class PrisonSetup extends JavaPlugin {
getLogger().info("SQLite database already exists.");
}
// Save the default configs, if they don't exist
configManager.saveDefaultConfig("config.yml");
configManager.saveDefaultConfig("banned_items.yml");
configManager.saveDefaultConfig("auto_switch.yml");
configManager.saveDefaultConfig("item_prices.yml");
configManager.loadItemPricesConfig(this.getDataFolder());
@ -130,9 +137,24 @@ public final class PrisonSetup extends JavaPlugin {
getServer().getPluginManager().registerEvents(new TreeFarmListener(this), this);
}
// Ranks Manager
boolean prisonerRanksEnabled = configManager.getConfig("config.yml").getBoolean("PrisonerRanks", true);
if (prisonerRanksEnabled) {
// Initialize RankManager and other initializations
rankManager = new RankManager(this);
// Register RankListener
getServer().getPluginManager().registerEvents(new RankListener(rankManager), this);
// Register commands
this.getCommand("rankup").setExecutor(new RankCommands(this));
this.getCommand("ranks").setExecutor(new RankCommands(this));
}
// Successful Startup/Enable
getLogger().info(ChatColor.translateAlternateColorCodes('&',"&a&lNVus Prison Setup has been successfully enabled!"));
// UPDATE CHECKER
new UpdateChecker(this, 12345).getVersion(version -> {
if (!this.getDescription().getVersion().equals(version)) {
@ -194,6 +216,10 @@ public final class PrisonSetup extends JavaPlugin {
return econ;
}
public RankManager getRankManager() {
return rankManager;
}
public ConfigManager getConfigManager() {
return configManager;
}

View File

@ -0,0 +1,31 @@
package me.nvus.nvus_prison_setup.Ranks;
import java.util.UUID;
public class PlayerRankData {
private UUID uuid;
private String username;
private String rankName;
public PlayerRankData(UUID uuid, String username, String rankName) {
this.uuid = uuid;
this.username = username;
this.rankName = rankName;
}
// Getters
public UUID getUuid() {
return uuid;
}
public String getUsername() {
return username;
}
public String getRankName() {
return rankName;
}
}

View File

@ -0,0 +1,30 @@
package me.nvus.nvus_prison_setup.Ranks;
import java.util.List;
public class Rank {
private String name;
private double cost;
private List<String> commands;
public Rank(String name, double cost, List<String> commands) {
this.name = name;
this.cost = cost;
this.commands = commands;
}
// Getters
public String getName() {
return name;
}
public double getCost() {
return cost;
}
public List<String> getCommands() {
return commands;
}
// Setters and other methods as necessary
}

View File

@ -0,0 +1,58 @@
package me.nvus.nvus_prison_setup.Ranks;
import me.nvus.nvus_prison_setup.PrisonSetup;
import me.nvus.nvus_prison_setup.Ranks.RankManager;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class RankCommands implements CommandExecutor {
private final RankManager rankManager;
public RankCommands(PrisonSetup plugin) {
this.rankManager = plugin.getRankManager();
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command can only be used by players.");
return true;
}
Player player = (Player) sender;
switch (label.toLowerCase()) {
case "rankup":
return handleRankUpCommand(player);
case "ranks":
return handleRanksCommand(player);
default:
return false;
}
}
private boolean handleRankUpCommand(Player player) {
// Check if the player has a rank, assign the default rank if not
Rank currentRank = rankManager.getCurrentRank(player);
if (currentRank == null) {
rankManager.assignDefaultRank(player);
player.sendMessage(ChatColor.YELLOW + "We couldn't find you in the ranks database. Assigning default rank now!");
return true;
}
boolean success = rankManager.rankUp(player);
if (!success) {
player.sendMessage(ChatColor.RED + "Unable to rank up. Please check your rank and balance using /ranks");
}
return true;
}
private boolean handleRanksCommand(Player player) {
String ranksMessage = rankManager.getRanksDisplay(player);
player.sendMessage(ranksMessage);
return true;
}
}

View File

@ -0,0 +1,32 @@
package me.nvus.nvus_prison_setup.Ranks;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.entity.Player;
public class RankListener implements Listener {
private RankManager rankManager;
public RankListener(RankManager rankManager) {
this.rankManager = rankManager;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
handleNewPlayer(player);
// if (rankManager.getCurrentRank(player) == null) {
// // Assign to the default rank
// rankManager.assignDefaultRank(player);
// }
}
private void handleNewPlayer(Player player) {
Rank currentRank = rankManager.getCurrentRank(player);
if (currentRank == null) {
rankManager.assignDefaultRank(player);
}
}
}

View File

@ -0,0 +1,317 @@
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<Rank> ranks = new ArrayList<>();
private Map<UUID, String> 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<String> rankKeys = ranksConfig.getConfigurationSection("Ranks").getKeys(false);
List<Rank> ranks = rankKeys.stream().map(rankKey -> {
String path = "Ranks." + rankKey;
String name = rankKey;
double cost = ranksConfig.getDouble(path + ".Cost");
List<String> commands = ranksConfig.getStringList(path + ".Commands");
return new Rank(name, cost, commands);
}).collect(Collectors.toList());
Map<String, Object> 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<Map<String, Object>>() {}.getType();
Map<String, Object> rankDataMap = gson.fromJson(reader, type);
List<Map<String, Object>> ranksList = (List<Map<String, Object>>) rankDataMap.get("ranks");
if (ranksList != null) {
this.ranks.clear(); // Clear existing ranks before loading new ones
for (Map<String, Object> rankMap : ranksList) {
String name = (String) rankMap.get("name");
double cost = ((Number) rankMap.get("cost")).doubleValue();
List<String> commands = (List<String>) 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<String> 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<String, Object> existingData = new HashMap<>();
try (Reader reader = new FileReader(rankDataFile)) {
Type type = new TypeToken<Map<String, Object>>() {}.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<Map<String, Object>> serializedRanks = ranks.stream().map(rank -> {
Map<String, Object> 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<Map<String, Object>> serializedPlayerRanks = playerRanks.entrySet().stream().map(entry -> {
Map<String, Object> 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<Map<String, List<PlayerRankData>>>() {}.getType();
Map<String, List<PlayerRankData>> data = new Gson().fromJson(reader, type);
List<PlayerRankData> playerRankDataList = data.get("players");
if (playerRankDataList != null) {
playerRankDataList.forEach(playerRankData -> playerRanks.put(playerRankData.getUuid(), playerRankData.getRankName()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -64,6 +64,14 @@ ToolDamage: false
# It will then place down a sapling in the same spot where the tree base was destroyed.
TreeFarm: true
########################################################################################
# PRISONER RANKS FEATURE #
########################################################################################
# Do you want to use the built-in /rankup and /maxrankup commands to rank prisoners up?
# Can configure the ranks in the ranks.yml file!
PrisonerRanks: true
########################################################################################
# DATABASE SETTINGS #
########################################################################################

View File

@ -60,6 +60,16 @@ commands:
usage: |
/setprice <price> - Set the price of the block being held in item_prices.yml.
aliases: [ setblockprice ]
rankup:
description: Rank up to the next rank.
usage: |
/rankup - Rank up to the next rank.
aliases: [ nextrank ]
ranks:
description: Display all available ranks, their cost and your current rank and balance.
usage: |
/ranks - Rank up to the max rank.
aliases: [ allranks ]
permissions:
nvus.admin:

View File

@ -0,0 +1,16 @@
#======================================================================================#
# NVus PRISON GOLD EDITION #
# by never2nv #
# www.FNGnation.net #
# Discord: FNGnation.net/discord #
#======================================================================================#
Ranks:
Default: # DO NOT CHANGE THE NAME 'Default' or this will break the plugin! This is the first/default rank!
Cost: 100
Commands:
- broadcast %player% has been processed as a new inmate!
Tier2:
Cost: 200
Commands:
- broadcast %player% has been promoted to Tier 2!
- lp user %player% permission set nvus.gang.create true