diff --git a/build.gradle b/build.gradle index ed8cde6..efc04d6 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'sh.okx' -version '3.9.1' +version '3.10' repositories { mavenCentral() @@ -28,7 +28,7 @@ dependencies { testImplementation 'com.github.seeseemelk:MockBukkit-v1.15:0.3.0' compileOnly 'org.jetbrains:annotations:16.0.2' - implementation 'org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT' + implementation 'org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT' implementation('com.github.Realizedd:TokenManager:3.2.4') { transitive = false } diff --git a/src/main/java/sh/okx/rankup/RankupHelper.java b/src/main/java/sh/okx/rankup/RankupHelper.java index 625e3a7..26a9ce5 100644 --- a/src/main/java/sh/okx/rankup/RankupHelper.java +++ b/src/main/java/sh/okx/rankup/RankupHelper.java @@ -1,221 +1,221 @@ -package sh.okx.rankup; - -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import sh.okx.rankup.hook.GroupProvider; -import sh.okx.rankup.messages.Message; -import sh.okx.rankup.messages.Variable; -import sh.okx.rankup.prestige.Prestige; -import sh.okx.rankup.prestige.Prestiges; -import sh.okx.rankup.ranks.Rank; -import sh.okx.rankup.ranks.RankElement; -import sh.okx.rankup.ranks.Rankups; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Actually performs the ranking up and prestiging for the plugin and also manages the cooldowns - * between ranking up. - */ -public class RankupHelper { - - private final RankupPlugin plugin; - private final ConfigurationSection config; - private final GroupProvider permissions; - /** - * Players who cannot rankup/prestige for a certain amount of time. - */ - private final Map cooldowns = new HashMap<>(); - - public RankupHelper(RankupPlugin plugin) { - this.plugin = plugin; - this.config = plugin.getConfig(); - this.permissions = plugin.getPermissions(); - } - - public void doRankup(Player player, RankElement rank) { - rank.getRank().runCommands(player); - - if (rank.getRank() != null) { - permissions.removeGroup(player.getUniqueId(), rank.getRank().getRank()); - } - permissions.addGroup(player.getUniqueId(), rank.getNext().getRank().getRank()); - } - - public void sendRankupMessages(Player player, RankElement rank) { - plugin.getMessage(rank.getRank(), Message.SUCCESS_PUBLIC) - .failIfEmpty() - .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) - .broadcast(); - plugin.getMessage(rank.getRank(), Message.SUCCESS_PRIVATE) - .failIfEmpty() - .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) - .send(player); - } - - public void doPrestige(Player player, RankElement prestige) { - Prestige rank = prestige.getRank(); - rank.runCommands(player); - - permissions.removeGroup(player.getUniqueId(), rank.getFrom()); - permissions.addGroup(player.getUniqueId(), rank.getTo()); - - if (rank.getRank() != null) { - permissions.removeGroup(player.getUniqueId(), rank.getRank()); - } - permissions.addGroup(player.getUniqueId(), prestige.getNext().getRank().getRank()); - } - - public void sendPrestigeMessages(Player player, RankElement prestige) { - Objects.requireNonNull(prestige); - Objects.requireNonNull(prestige.getNext()); - - plugin.getMessage(prestige.getRank(), Message.PRESTIGE_SUCCESS_PUBLIC) - .failIfEmpty() - .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) - .replaceFromTo(prestige.getRank()) - .broadcast(); - plugin.getMessage(prestige.getRank(), Message.PRESTIGE_SUCCESS_PRIVATE) - .failIfEmpty() - .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) - .replaceFromTo(prestige.getRank()) - .send(player); - } - - private boolean checkCooldown(Player player, Rank rank) { - if (cooldowns.containsKey(player)) { - long time = System.currentTimeMillis() - cooldowns.get(player); - // if time passed is less than the cooldown - long cooldownSeconds = config.getInt("cooldown"); - long timeLeft = (cooldownSeconds * 1000) - time; - if (timeLeft > 0) { - long secondsLeft = (long) Math.ceil(timeLeft / 1000f); - plugin - .getMessage(rank, secondsLeft > 1 ? Message.COOLDOWN_PLURAL : Message.COOLDOWN_SINGULAR) - .failIfEmpty() - .replaceRanks(player, rank.getRank()) - .replaceFromTo(rank) - .replace(Variable.SECONDS, cooldownSeconds) - .replace(Variable.SECONDS_LEFT, secondsLeft) - .send(player); - return true; - } - // cooldown has expired so remove it - cooldowns.remove(player); - } - return false; - } - - private void applyCooldown(Player player) { - if (config.getInt("cooldown") > 0) { - cooldowns.put(player, System.currentTimeMillis()); - } - } - - public void rankup(Player player) { - if (!checkRankup(player)) { - return; - } - - RankElement rankElement = plugin.getRankups().getByPlayer(player); - Rank rank = rankElement.getRank(); - rank.applyRequirements(player); - applyCooldown(player); - - doRankup(player, rankElement); - sendRankupMessages(player, rankElement); - } - - public boolean checkRankup(Player player) { - return checkRankup(player, true); - } - - /** - * Checks if a player can rankup, and if they can't, sends the player a message and returns false - * - * @param player the player to check if they can rankup - * @return true if the player can rankup, false otherwise - */ - public boolean checkRankup(Player player, boolean message) { - Rankups rankups = plugin.getRankups(); - RankElement rankElement = rankups.getByPlayer(player); - if (rankElement == null) { // check if in ladder - plugin.getMessage(Message.NOT_IN_LADDER) - .failIf(!message) - .replace(Variable.PLAYER, player.getName()) - .send(player); - return false; - } - Rank rank = rankElement.getRank(); - if (!rankElement.hasNext()) { - Prestiges prestiges = plugin.getPrestiges(); - plugin.getMessage(prestiges == null || !prestiges.getByPlayer(player).hasNext() ? Message.NO_RANKUP : Message.MUST_PRESTIGE) - .failIf(!message) - .replaceRanks(player, rankups.getTree().last().getRank().getRank()) - .send(player); - return false; - } else if (!rank.hasRequirements(player)) { // check if they can afford it - if (message) { - plugin.replaceMoneyRequirements(plugin.getMessage(rank, Message.REQUIREMENTS_NOT_MET) - .replaceRanks(player, rank, rankElement.getNext().getRank()), player, rank) - .send(player); - } - return false; - } else if (message && checkCooldown(player, rank)) { - return false; - } - - return true; - } - - public void prestige(Player player) { - if (!checkPrestige(player)) { - return; - } - - RankElement rankElement = plugin.getPrestiges().getByPlayer(player); - Prestige prestige = rankElement.getRank(); - prestige.applyRequirements(player); - - applyCooldown(player); - doPrestige(player, rankElement); - sendPrestigeMessages(player, rankElement); - } - - public boolean checkPrestige(Player player) { - return checkPrestige(player, true); - } - - public boolean checkPrestige(Player player, boolean message) { - Prestiges prestiges = plugin.getPrestiges(); - RankElement prestigeElement = prestiges.getByPlayer(player); - if (prestigeElement == null || !prestigeElement.getRank().isEligible(player)) { // check if in ladder - plugin.getMessage(Message.NOT_HIGH_ENOUGH) - .failIf(!message) - .replace(Variable.PLAYER, player.getName()) - .send(player); - return false; - } else if (!prestigeElement.hasNext()) { // check if they are at the highest rank - plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_NO_PRESTIGE) - .failIf(!message) - .replaceRanks(player, prestigeElement.getRank().getRank()) - .replaceFromTo(prestigeElement.getRank()) - .send(player); - return false; - } else if (!prestigeElement.getRank().hasRequirements(player)) { // check if they can afford it - plugin.replaceMoneyRequirements( - plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_REQUIREMENTS_NOT_MET) - .failIf(!message) - .replaceRanks(player, prestigeElement.getRank(), prestigeElement.getNext().getRank().getRank()), player, prestigeElement.getRank()) - .replaceFromTo(prestigeElement.getRank()) - .send(player); - return false; - } else if (checkCooldown(player, prestigeElement.getRank())) { - return false; - } - - return true; - } -} +package sh.okx.rankup; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import sh.okx.rankup.hook.GroupProvider; +import sh.okx.rankup.messages.Message; +import sh.okx.rankup.messages.Variable; +import sh.okx.rankup.prestige.Prestige; +import sh.okx.rankup.prestige.Prestiges; +import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; +import sh.okx.rankup.ranks.Rankups; + +/** + * Actually performs the ranking up and prestiging for the plugin and also manages the cooldowns + * between ranking up. + */ +public class RankupHelper { + + private final RankupPlugin plugin; + private final ConfigurationSection config; + private final GroupProvider permissions; + /** + * Players who cannot rankup/prestige for a certain amount of time. + */ + private final Map cooldowns = new HashMap<>(); + + public RankupHelper(RankupPlugin plugin) { + this.plugin = plugin; + this.config = plugin.getConfig(); + this.permissions = plugin.getPermissions(); + } + + public void doRankup(Player player, RankElement rank) { + if (rank.getRank() != null) { + permissions.removeGroup(player.getUniqueId(), rank.getRank().getRank()); + } + permissions.addGroup(player.getUniqueId(), rank.getNext().getRank().getRank()); + + rank.getRank().runCommands(player); + } + + public void sendRankupMessages(Player player, RankElement rank) { + plugin.getMessage(rank.getRank(), Message.SUCCESS_PUBLIC) + .failIfEmpty() + .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) + .broadcast(); + plugin.getMessage(rank.getRank(), Message.SUCCESS_PRIVATE) + .failIfEmpty() + .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) + .send(player); + } + + public void doPrestige(Player player, RankElement prestige) { + Prestige rank = prestige.getRank(); + + permissions.removeGroup(player.getUniqueId(), rank.getFrom()); + permissions.addGroup(player.getUniqueId(), rank.getTo()); + + if (rank.getRank() != null) { + permissions.removeGroup(player.getUniqueId(), rank.getRank()); + } + permissions.addGroup(player.getUniqueId(), prestige.getNext().getRank().getRank()); + + rank.runCommands(player); + } + + public void sendPrestigeMessages(Player player, RankElement prestige) { + Objects.requireNonNull(prestige); + Objects.requireNonNull(prestige.getNext()); + + plugin.getMessage(prestige.getRank(), Message.PRESTIGE_SUCCESS_PUBLIC) + .failIfEmpty() + .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) + .replaceFromTo(prestige.getRank()) + .broadcast(); + plugin.getMessage(prestige.getRank(), Message.PRESTIGE_SUCCESS_PRIVATE) + .failIfEmpty() + .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) + .replaceFromTo(prestige.getRank()) + .send(player); + } + + private boolean checkCooldown(Player player, Rank rank) { + if (cooldowns.containsKey(player)) { + long time = System.currentTimeMillis() - cooldowns.get(player); + // if time passed is less than the cooldown + long cooldownSeconds = config.getInt("cooldown"); + long timeLeft = (cooldownSeconds * 1000) - time; + if (timeLeft > 0) { + long secondsLeft = (long) Math.ceil(timeLeft / 1000f); + plugin + .getMessage(rank, secondsLeft > 1 ? Message.COOLDOWN_PLURAL : Message.COOLDOWN_SINGULAR) + .failIfEmpty() + .replaceRanks(player, rank.getRank()) + .replaceFromTo(rank) + .replace(Variable.SECONDS, cooldownSeconds) + .replace(Variable.SECONDS_LEFT, secondsLeft) + .send(player); + return true; + } + // cooldown has expired so remove it + cooldowns.remove(player); + } + return false; + } + + private void applyCooldown(Player player) { + if (config.getInt("cooldown") > 0) { + cooldowns.put(player, System.currentTimeMillis()); + } + } + + public void rankup(Player player) { + if (!checkRankup(player)) { + return; + } + + RankElement rankElement = plugin.getRankups().getByPlayer(player); + Rank rank = rankElement.getRank(); + rank.applyRequirements(player); + applyCooldown(player); + + doRankup(player, rankElement); + sendRankupMessages(player, rankElement); + } + + public boolean checkRankup(Player player) { + return checkRankup(player, true); + } + + /** + * Checks if a player can rankup, and if they can't, sends the player a message and returns false + * + * @param player the player to check if they can rankup + * @return true if the player can rankup, false otherwise + */ + public boolean checkRankup(Player player, boolean message) { + Rankups rankups = plugin.getRankups(); + RankElement rankElement = rankups.getByPlayer(player); + if (rankElement == null) { // check if in ladder + plugin.getMessage(Message.NOT_IN_LADDER) + .failIf(!message) + .replace(Variable.PLAYER, player.getName()) + .send(player); + return false; + } + Rank rank = rankElement.getRank(); + if (!rankElement.hasNext()) { + Prestiges prestiges = plugin.getPrestiges(); + plugin.getMessage(prestiges == null || !prestiges.getByPlayer(player).hasNext() ? Message.NO_RANKUP : Message.MUST_PRESTIGE) + .failIf(!message) + .replaceRanks(player, rankups.getTree().last().getRank().getRank()) + .send(player); + return false; + } else if (!rank.hasRequirements(player)) { // check if they can afford it + if (message) { + plugin.replaceMoneyRequirements(plugin.getMessage(rank, Message.REQUIREMENTS_NOT_MET) + .replaceRanks(player, rank, rankElement.getNext().getRank()), player, rank) + .send(player); + } + return false; + } else if (message && checkCooldown(player, rank)) { + return false; + } + + return true; + } + + public void prestige(Player player) { + if (!checkPrestige(player)) { + return; + } + + RankElement rankElement = plugin.getPrestiges().getByPlayer(player); + Prestige prestige = rankElement.getRank(); + prestige.applyRequirements(player); + + applyCooldown(player); + doPrestige(player, rankElement); + sendPrestigeMessages(player, rankElement); + } + + public boolean checkPrestige(Player player) { + return checkPrestige(player, true); + } + + public boolean checkPrestige(Player player, boolean message) { + Prestiges prestiges = plugin.getPrestiges(); + RankElement prestigeElement = prestiges.getByPlayer(player); + if (prestigeElement == null || !prestigeElement.getRank().isEligible(player)) { // check if in ladder + plugin.getMessage(Message.NOT_HIGH_ENOUGH) + .failIf(!message) + .replace(Variable.PLAYER, player.getName()) + .send(player); + return false; + } else if (!prestigeElement.hasNext()) { // check if they are at the highest rank + plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_NO_PRESTIGE) + .failIf(!message) + .replaceRanks(player, prestigeElement.getRank().getRank()) + .replaceFromTo(prestigeElement.getRank()) + .send(player); + return false; + } else if (!prestigeElement.getRank().hasRequirements(player)) { // check if they can afford it + plugin.replaceMoneyRequirements( + plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_REQUIREMENTS_NOT_MET) + .failIf(!message) + .replaceRanks(player, prestigeElement.getRank(), prestigeElement.getNext().getRank().getRank()), player, prestigeElement.getRank()) + .replaceFromTo(prestigeElement.getRank()) + .send(player); + return false; + } else if (checkCooldown(player, prestigeElement.getRank())) { + return false; + } + + return true; + } +} diff --git a/src/main/java/sh/okx/rankup/RankupPlugin.java b/src/main/java/sh/okx/rankup/RankupPlugin.java index 9fcd9de..1c13095 100644 --- a/src/main/java/sh/okx/rankup/RankupPlugin.java +++ b/src/main/java/sh/okx/rankup/RankupPlugin.java @@ -1,5 +1,11 @@ package sh.okx.rankup; +import java.io.File; +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -14,7 +20,12 @@ import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import sh.okx.rankup.commands.*; +import sh.okx.rankup.commands.InfoCommand; +import sh.okx.rankup.commands.MaxRankupCommand; +import sh.okx.rankup.commands.PrestigeCommand; +import sh.okx.rankup.commands.PrestigesCommand; +import sh.okx.rankup.commands.RanksCommand; +import sh.okx.rankup.commands.RankupCommand; import sh.okx.rankup.economy.Economy; import sh.okx.rankup.economy.EconomyProvider; import sh.okx.rankup.economy.VaultEconomyProvider; @@ -33,30 +44,46 @@ import sh.okx.rankup.prestige.Prestiges; import sh.okx.rankup.ranks.Rank; import sh.okx.rankup.ranks.RankList; import sh.okx.rankup.ranks.Rankups; +import sh.okx.rankup.ranksgui.RanksGuiCommand; +import sh.okx.rankup.ranksgui.RanksGuiListener; import sh.okx.rankup.requirements.Requirement; import sh.okx.rankup.requirements.RequirementRegistry; +import sh.okx.rankup.requirements.requirement.AdvancementRequirement; +import sh.okx.rankup.requirements.requirement.BlockBreakRequirement; +import sh.okx.rankup.requirements.requirement.CraftItemRequirement; +import sh.okx.rankup.requirements.requirement.GroupRequirement; +import sh.okx.rankup.requirements.requirement.ItemDeductibleRequirement; +import sh.okx.rankup.requirements.requirement.ItemRequirement; +import sh.okx.rankup.requirements.requirement.MobKillsRequirement; +import sh.okx.rankup.requirements.requirement.MoneyDeductibleRequirement; +import sh.okx.rankup.requirements.requirement.MoneyRequirement; +import sh.okx.rankup.requirements.requirement.PermissionRequirement; +import sh.okx.rankup.requirements.requirement.PlaceholderRequirement; +import sh.okx.rankup.requirements.requirement.PlayerKillsRequirement; +import sh.okx.rankup.requirements.requirement.PlaytimeMinutesRequirement; +import sh.okx.rankup.requirements.requirement.TotalMobKillsRequirement; +import sh.okx.rankup.requirements.requirement.UseItemRequirement; +import sh.okx.rankup.requirements.requirement.WorldRequirement; import sh.okx.rankup.requirements.requirement.XpLevelDeductibleRequirement; -import sh.okx.rankup.requirements.requirement.*; +import sh.okx.rankup.requirements.requirement.XpLevelRequirement; import sh.okx.rankup.requirements.requirement.advancedachievements.AdvancedAchievementsAchievementRequirement; import sh.okx.rankup.requirements.requirement.advancedachievements.AdvancedAchievementsTotalRequirement; import sh.okx.rankup.requirements.requirement.mcmmo.McMMOPowerLevelRequirement; import sh.okx.rankup.requirements.requirement.mcmmo.McMMOSkillRequirement; import sh.okx.rankup.requirements.requirement.tokenmanager.TokensDeductibleRequirement; import sh.okx.rankup.requirements.requirement.tokenmanager.TokensRequirement; -import sh.okx.rankup.requirements.requirement.towny.*; +import sh.okx.rankup.requirements.requirement.towny.TownyKingNumberResidentsRequirement; +import sh.okx.rankup.requirements.requirement.towny.TownyKingNumberTownsRequirement; +import sh.okx.rankup.requirements.requirement.towny.TownyKingRequirement; +import sh.okx.rankup.requirements.requirement.towny.TownyMayorNumberResidentsRequirement; +import sh.okx.rankup.requirements.requirement.towny.TownyMayorRequirement; +import sh.okx.rankup.requirements.requirement.towny.TownyResidentRequirement; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginPointsDeductibleRequirement; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginPointsRequirement; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginVotesRequirement; import sh.okx.rankup.util.UpdateNotifier; import sh.okx.rankup.util.VersionChecker; -import java.io.File; -import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - public class RankupPlugin extends JavaPlugin { public static final int CONFIG_VERSION = 8; @@ -124,7 +151,13 @@ public class RankupPlugin extends JavaPlugin { } if (config.getBoolean("ranks")) { - getCommand("ranks").setExecutor(new RanksCommand(this)); + if (config.getBoolean("ranks-gui")) { + RanksGuiListener listener = new RanksGuiListener(); + getCommand("ranks").setExecutor(new RanksGuiCommand(this, listener)); + getServer().getPluginManager().registerEvents(listener, this); + } else { + getCommand("ranks").setExecutor(new RanksCommand(this)); + } } if (config.getBoolean("prestige")) { getCommand("prestige").setExecutor(new PrestigeCommand(this)); @@ -414,23 +447,27 @@ public class RankupPlugin extends JavaPlugin { public MessageBuilder replaceMoneyRequirements(MessageBuilder builder, CommandSender sender, Rank rank) { - if (builder instanceof NullMessageBuilder) { + if (builder instanceof NullMessageBuilder || rank == null) { return builder; } Requirement money = rank.getRequirement(sender instanceof Player ? (Player) sender : null, "money"); if (money != null) { Double amount = null; + Double total = null; if (sender instanceof Player && rank.isIn((Player) sender)) { if (economy != null) { amount = money.getRemaining((Player) sender); + total = money.getTotal((Player) sender); } } else { amount = money.getValueDouble(); + total = 0D; } if (amount != null && economy != null) { builder.replace(Variable.MONEY_NEEDED, formatMoney(amount)); builder.replace(Variable.MONEY, formatMoney(money.getValueDouble())); + builder.replace(Variable.MONEY_DONE, formatMoney(total)); } } if (sender instanceof Player) { diff --git a/src/main/java/sh/okx/rankup/commands/InfoCommand.java b/src/main/java/sh/okx/rankup/commands/InfoCommand.java index 07a360f..1db9b53 100644 --- a/src/main/java/sh/okx/rankup/commands/InfoCommand.java +++ b/src/main/java/sh/okx/rankup/commands/InfoCommand.java @@ -164,7 +164,6 @@ public class InfoCommand implements TabExecutor { } String[] placeholders = new String[] { - "prestige_money", "prestige_money_formatted", "prestige_percent_left_formatted", "prestige_percent_done_formatted", diff --git a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java index a675056..fd10161 100644 --- a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java +++ b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java @@ -1,81 +1,81 @@ -package sh.okx.rankup.commands; - -import lombok.RequiredArgsConstructor; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.gui.Gui; -import sh.okx.rankup.messages.Message; -import sh.okx.rankup.prestige.Prestige; -import sh.okx.rankup.prestige.Prestiges; -import sh.okx.rankup.ranks.RankElement; - -import java.util.Map; -import java.util.WeakHashMap; - -@RequiredArgsConstructor -public class PrestigeCommand implements CommandExecutor { - private final Map confirming = new WeakHashMap<>(); - private final RankupPlugin plugin; - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (plugin.error(sender)) { - return true; - } - - // check if player - if (!(sender instanceof Player)) { - return false; - } - Player player = (Player) sender; - - Prestiges prestiges = plugin.getPrestiges(); - if (!plugin.getHelper().checkPrestige(player)) { - return true; - } - RankElement rankElement = prestiges.getByPlayer(player); - Prestige prestige = rankElement.getRank(); - - FileConfiguration config = plugin.getConfig(); - String confirmationType = config.getString("confirmation-type").toLowerCase(); - if (confirmationType.equals("text") && confirming.containsKey(player)) { - long time = System.currentTimeMillis() - confirming.remove(player); - if (time < config.getInt("text.timeout") * 1000) { - plugin.getHelper().prestige(player); - return true; - } - } - - switch (confirmationType) { - case "text": - confirming.put(player, System.currentTimeMillis()); - Prestige next = rankElement.getNext().getRank(); - String nextRank = next == null ? prestiges.getTree().last().getRank().getRank() : next.getRank(); - - plugin.replaceMoneyRequirements(plugin.getMessage(prestige, Message.PRESTIGE_CONFIRMATION) - .replaceRanks(player, prestige, nextRank), player, prestige) - .replaceFromTo(prestige) - .send(player); - break; - case "gui": - Gui gui = Gui.of(player, prestige, rankElement.getNext().getRank(), plugin); - if (gui == null) { - player.sendMessage(ChatColor.RED + "GUI is not available. Check console for more informatiopn."); - return true; - } - gui.open(player); - break; - case "none": - plugin.getHelper().prestige(player); - break; - default: - throw new IllegalArgumentException("Invalid confirmation type " + confirmationType); - } - return true; - } -} +package sh.okx.rankup.commands; + +import lombok.RequiredArgsConstructor; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.gui.Gui; +import sh.okx.rankup.messages.Message; +import sh.okx.rankup.prestige.Prestige; +import sh.okx.rankup.prestige.Prestiges; +import sh.okx.rankup.ranks.RankElement; + +import java.util.Map; +import java.util.WeakHashMap; + +@RequiredArgsConstructor +public class PrestigeCommand implements CommandExecutor { + private final Map confirming = new WeakHashMap<>(); + private final RankupPlugin plugin; + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + + // check if player + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + + Prestiges prestiges = plugin.getPrestiges(); + if (!plugin.getHelper().checkPrestige(player)) { + return true; + } + RankElement rankElement = prestiges.getByPlayer(player); + Prestige prestige = rankElement.getRank(); + + FileConfiguration config = plugin.getConfig(); + String confirmationType = config.getString("confirmation-type").toLowerCase(); + if (confirmationType.equals("text") && confirming.containsKey(player)) { + long time = System.currentTimeMillis() - confirming.remove(player); + if (time < config.getInt("text.timeout") * 1000) { + plugin.getHelper().prestige(player); + return true; + } + } + + switch (confirmationType) { + case "text": + confirming.put(player, System.currentTimeMillis()); + Prestige next = rankElement.getNext().getRank(); + String nextRank = next == null ? prestiges.getTree().last().getRank().getRank() : next.getRank(); + + plugin.replaceMoneyRequirements(plugin.getMessage(prestige, Message.PRESTIGE_CONFIRMATION) + .replaceRanks(player, prestige, nextRank), player, prestige) + .replaceFromTo(prestige) + .send(player); + break; + case "gui": + Gui gui = Gui.of(player, prestige, rankElement.getNext().getRank(), plugin, false); + if (gui == null) { + player.sendMessage(ChatColor.RED + "GUI is not available. Check console for more informatiopn."); + return true; + } + gui.open(player); + break; + case "none": + plugin.getHelper().prestige(player); + break; + default: + throw new IllegalArgumentException("Invalid confirmation type " + confirmationType); + } + return true; + } +} diff --git a/src/main/java/sh/okx/rankup/commands/RankupCommand.java b/src/main/java/sh/okx/rankup/commands/RankupCommand.java index 855494f..18fbe37 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -1,80 +1,81 @@ -package sh.okx.rankup.commands; - -import lombok.RequiredArgsConstructor; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.gui.Gui; -import sh.okx.rankup.messages.Message; -import sh.okx.rankup.ranks.Rank; -import sh.okx.rankup.ranks.RankElement; -import sh.okx.rankup.ranks.Rankups; - -import java.util.Map; -import java.util.WeakHashMap; - -@RequiredArgsConstructor -public class RankupCommand implements CommandExecutor { - // weak hash maps so players going offline are automatically removed. - // otherwise there is a potential (albeit small) memory leak. - private final Map confirming = new WeakHashMap<>(); - private final RankupPlugin plugin; - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (plugin.error(sender)) { - return true; - } - - // check if player - if (!(sender instanceof Player)) { - return false; - } - Player player = (Player) sender; - - Rankups rankups = plugin.getRankups(); - if (!plugin.getHelper().checkRankup(player)) { - return true; - } - RankElement rankElement = rankups.getByPlayer(player); - - FileConfiguration config = plugin.getConfig(); - String confirmationType = config.getString("confirmation-type").toLowerCase(); - - // if they are on text confirming, rank them up - if (confirmationType.equals("text") && confirming.containsKey(player)) { - long time = System.currentTimeMillis() - confirming.remove(player); - if (time < config.getInt("text.timeout") * 1000) { - plugin.getHelper().rankup(player); - return true; - } - } - - switch (confirmationType) { - case "text": - confirming.put(player, System.currentTimeMillis()); - plugin.replaceMoneyRequirements(plugin.getMessage(rankElement.getRank(), Message.CONFIRMATION) - .replaceRanks(player, rankElement.getRank(), rankElement.getNext().getRank()), player, rankElement.getRank()) - .send(player); - break; - case "gui": - Gui gui = Gui.of(player, rankElement.getRank(), rankElement.getNext().getRank(), plugin); - if (gui == null) { - player.sendMessage(ChatColor.RED + "GUI is not available. Check console for more informatiopn."); - return true; - } - gui.open(player); - break; - case "none": - plugin.getHelper().rankup(player); - break; - default: - throw new IllegalArgumentException("Invalid confirmation type " + confirmationType); - } - return true; - } -} +package sh.okx.rankup.commands; + +import lombok.RequiredArgsConstructor; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.gui.Gui; +import sh.okx.rankup.messages.Message; +import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; +import sh.okx.rankup.ranks.Rankups; + +import java.util.Map; +import java.util.WeakHashMap; + +@RequiredArgsConstructor +public class RankupCommand implements CommandExecutor { + // weak hash maps so players going offline are automatically removed. + // otherwise there is a potential (albeit small) memory leak. + private final Map confirming = new WeakHashMap<>(); + private final RankupPlugin plugin; + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + + // check if player + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + + Rankups rankups = plugin.getRankups(); + if (!plugin.getHelper().checkRankup(player)) { + return true; + } + RankElement rankElement = rankups.getByPlayer(player); + + FileConfiguration config = plugin.getConfig(); + String confirmationType = config.getString("confirmation-type").toLowerCase(); + + // if they are on text confirming, rank them up + // clicking on the gui cannot confirm a rankup + if (confirmationType.equals("text") && confirming.containsKey(player) && !(args.length > 0 && args[0].equalsIgnoreCase("gui"))) { + long time = System.currentTimeMillis() - confirming.remove(player); + if (time < config.getInt("text.timeout") * 1000) { + plugin.getHelper().rankup(player); + return true; + } + } + + switch (confirmationType) { + case "text": + confirming.put(player, System.currentTimeMillis()); + plugin.replaceMoneyRequirements(plugin.getMessage(rankElement.getRank(), Message.CONFIRMATION) + .replaceRanks(player, rankElement.getRank(), rankElement.getNext().getRank()), player, rankElement.getRank()) + .send(player); + break; + case "gui": + Gui gui = Gui.of(player, rankElement.getRank(), rankElement.getNext().getRank(), plugin, args.length > 0 && args[0].equalsIgnoreCase("gui")); + if (gui == null) { + player.sendMessage(ChatColor.RED + "GUI is not available. Check console for more information."); + return true; + } + gui.open(player); + break; + case "none": + plugin.getHelper().rankup(player); + break; + default: + throw new IllegalArgumentException("Invalid confirmation type " + confirmationType); + } + return true; + } +} diff --git a/src/main/java/sh/okx/rankup/gui/Gui.java b/src/main/java/sh/okx/rankup/gui/Gui.java index 275e91c..59cd5d4 100644 --- a/src/main/java/sh/okx/rankup/gui/Gui.java +++ b/src/main/java/sh/okx/rankup/gui/Gui.java @@ -1,143 +1,158 @@ -package sh.okx.rankup.gui; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.messages.Message; -import sh.okx.rankup.messages.MessageBuilder; -import sh.okx.rankup.prestige.Prestige; -import sh.okx.rankup.ranks.Rank; -import sh.okx.rankup.util.ItemUtil; - -import java.util.Arrays; -import java.util.Objects; -import java.util.stream.Collectors; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class Gui implements InventoryHolder { - @Getter - private Inventory inventory; - @Getter - private ItemStack rankup; - @Getter - private ItemStack cancel; - @Getter - private boolean prestige; - - public static Gui of(Player player, Rank oldRank, Rank rank, RankupPlugin plugin) { - Gui gui = new Gui(); - gui.prestige = oldRank instanceof Prestige; - - String type = gui.prestige ? "prestige" : "rankup"; - String basePath = type + ".gui"; - ConfigurationSection config = plugin.getSection(oldRank, basePath); - if (config == null) { - plugin.getLogger().severe("You must update your config.yml and locale/en.yml to be able to use the GUI! Your configuration files are outdated."); - return null; - } - - ItemStack[] items = new ItemStack[config.getInt("rows", 1) * 9]; - - ItemStack fill = getItem(plugin, plugin.getSection(oldRank, basePath + ".fill"), player, oldRank, rank); - ItemStack cancel = getItem(plugin, plugin.getSection(oldRank, basePath + ".cancel"), player, oldRank, rank); - ItemStack rankup = getItem(plugin, plugin.getSection(oldRank, basePath + ".rankup"), player, oldRank, rank); - - addItem(items, plugin.getSection(oldRank, basePath + ".rankup"), rankup); - addItem(items, plugin.getSection(oldRank, basePath + ".cancel"), cancel); - addItem(items, plugin.getSection(oldRank, basePath + ".fill"), fill); - - gui.rankup = rankup; - gui.cancel = cancel; - - Inventory inventory = Bukkit.createInventory(gui, items.length, - plugin.replaceMoneyRequirements( - plugin.getMessage(oldRank, gui.prestige ? Message.PRESTIGE_TITLE : Message.TITLE) - .replaceRanks(player, oldRank, rank) - .replaceFromTo(oldRank), player, oldRank).toString()); - inventory.setContents(items); - gui.inventory = inventory; - return gui; - } - - @SuppressWarnings("deprecation") - private static ItemStack getItem(RankupPlugin plugin, ConfigurationSection section, Player player, Rank oldRank, Rank rank) { - String materialName = section.getString("material").toUpperCase(); - - ItemStack item; - if (ItemUtil.isServerFlattened()) { - Material material = Material.valueOf(materialName); - item = new ItemStack(material); - } else { - // handle default material correctly on older versions - if (materialName.equals("BLACK_STAINED_GLASS_PANE")) { - materialName = "STAINED_GLASS_PANE:15"; - } - - String[] parts = materialName.split(":"); - Material material = Material.valueOf(parts[0]); - - short type = parts.length > 1 ? Short.parseShort(parts[1]) : 0; - item = new ItemStack(material, 1, type); - } - - if (item.getType() == Material.AIR && section.getName().equalsIgnoreCase("fill")) { - return item; - } - - ItemMeta meta = item.getItemMeta(); - if (section.contains("lore")) { - meta.setLore(Arrays.stream(format(plugin, section.getString("lore"), player, oldRank, rank).split("\n")) - .map(string -> ChatColor.RESET + string) - .collect(Collectors.toList())); - } - if (section.contains("name")) { - meta.setDisplayName(ChatColor.RESET + format(plugin, section.getString("name"), player, oldRank, rank)); - } - item.setItemMeta(meta); - return item; - } - - private static String format(RankupPlugin plugin, String message, Player player, Rank oldRank, Rank rank) { - return plugin.replaceMoneyRequirements(new MessageBuilder(ChatColor.translateAlternateColorCodes('&', message)) - .replaceRanks(player, oldRank, rank), player, oldRank) - .toString(); - } - - private static void addItem(ItemStack[] items, ConfigurationSection section, ItemStack item) { - Objects.requireNonNull(section, "GUI configuration section not found"); - if (section.getName().equalsIgnoreCase("fill")) { - for (int i = 0; i < items.length; i++) { - if (items[i] == null) { - items[i] = item; - } - } - return; - } - - String[] locations = section.getString("index").split(" "); - for (String location : locations) { - String[] parts = location.split("-"); - if (parts.length == 1) { - items[Integer.parseInt(parts[0])] = item; - } else { - for (int i = Integer.parseInt(parts[0]); i <= Integer.parseInt(parts[1]); i++) { - items[i] = item; - } - } - } - } - - public void open(Player player) { - player.openInventory(inventory); - } -} +package sh.okx.rankup.gui; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.messages.Message; +import sh.okx.rankup.messages.MessageBuilder; +import sh.okx.rankup.prestige.Prestige; +import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; +import sh.okx.rankup.util.ItemUtil; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class Gui implements InventoryHolder { + @Getter + private final boolean returnToRanksGui; + @Getter + private Inventory inventory; + @Getter + private ItemStack rankup; + @Getter + private ItemStack cancel; + @Getter + private boolean prestige; + + public static Gui of(Player player, Rank oldRank, Rank rank, RankupPlugin plugin, boolean returnToRanksGui) { + Gui gui = new Gui(returnToRanksGui); + gui.prestige = oldRank instanceof Prestige; + + String type = gui.prestige ? "prestige" : "rankup"; + String basePath = type + ".gui"; + ConfigurationSection config = plugin.getSection(oldRank, basePath); + if (config == null) { + plugin.getLogger().severe("You must update your config.yml and locale/en.yml to be able to use the GUI! Your configuration files are outdated."); + return null; + } + + ItemStack[] items = new ItemStack[config.getInt("rows", 1) * 9]; + + ItemStack fill = getItem(plugin, plugin.getSection(oldRank, basePath + ".fill"), player, oldRank, rank); + ItemStack cancel = getItem(plugin, plugin.getSection(oldRank, basePath + ".cancel"), player, oldRank, rank); + ItemStack rankup = getItem(plugin, plugin.getSection(oldRank, basePath + ".rankup"), player, oldRank, rank); + + addItem(items, plugin.getSection(oldRank, basePath + ".rankup"), rankup); + addItem(items, plugin.getSection(oldRank, basePath + ".cancel"), cancel); + addItem(items, plugin.getSection(oldRank, basePath + ".fill"), fill); + + gui.rankup = rankup; + gui.cancel = cancel; + + Inventory inventory = Bukkit.createInventory(gui, items.length, + ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', plugin.replaceMoneyRequirements( + plugin.getMessage(oldRank, gui.prestige ? Message.PRESTIGE_TITLE : Message.TITLE) + .replaceRanks(player, oldRank, rank) + .replaceFromTo(oldRank), player, oldRank).toString()))); + inventory.setContents(items); + gui.inventory = inventory; + return gui; + } + + public static ItemStack getItem(RankupPlugin plugin, ConfigurationSection section, Player player, RankElement element) { + if (element == null) { + return getItem(plugin, section, player, null, null); + } else { + return getItem(plugin, section, player, element.getRank(), element.getNext().getRank()); + } + } + + @SuppressWarnings("deprecation") + public static ItemStack getItem(RankupPlugin plugin, ConfigurationSection section, Player player, Rank oldRank, Rank rank) { + if (section == null) { + return null; + } + String materialName = section.getString("material").toUpperCase(); + + ItemStack item; + if (ItemUtil.isServerFlattened()) { + Material material = Material.valueOf(materialName); + item = new ItemStack(material); + } else { + // handle default material correctly on older versions + if (materialName.equals("BLACK_STAINED_GLASS_PANE")) { + materialName = "STAINED_GLASS_PANE:15"; + } + + String[] parts = materialName.split(":"); + Material material = Material.valueOf(parts[0]); + + short type = parts.length > 1 ? Short.parseShort(parts[1]) : 0; + item = new ItemStack(material, 1, type); + } + + if (item.getType() == Material.AIR && section.getName().equalsIgnoreCase("fill")) { + return item; + } + + ItemMeta meta = item.getItemMeta(); + if (section.contains("lore")) { + meta.setLore(Arrays.stream(format(plugin, section.getString("lore"), player, oldRank, rank).split("\n")) + .map(string -> ChatColor.RESET + string) + .collect(Collectors.toList())); + } + if (section.contains("name")) { + meta.setDisplayName(ChatColor.RESET + format(plugin, section.getString("name"), player, oldRank, rank)); + } + item.setItemMeta(meta); + return item; + } + + private static String format(RankupPlugin plugin, String message, Player player, Rank oldRank, Rank rank) { + MessageBuilder builder = new MessageBuilder(message); + if (oldRank != null && rank != null) { + builder = builder.replaceRanks(player, oldRank, rank); + } + return ChatColor.translateAlternateColorCodes('&', plugin.replaceMoneyRequirements(builder, player, oldRank).toString()); + } + + private static void addItem(ItemStack[] items, ConfigurationSection section, ItemStack item) { + Objects.requireNonNull(section, "GUI configuration section not found"); + if (section.getName().equalsIgnoreCase("fill")) { + for (int i = 0; i < items.length; i++) { + if (items[i] == null) { + items[i] = item; + } + } + return; + } + + String[] locations = section.getString("index").split(" "); + for (String location : locations) { + String[] parts = location.split("-"); + if (parts.length == 1) { + items[Integer.parseInt(parts[0])] = item; + } else { + for (int i = Integer.parseInt(parts[0]); i <= Integer.parseInt(parts[1]); i++) { + items[i] = item; + } + } + } + } + + public void open(Player player) { + player.openInventory(inventory); + } +} diff --git a/src/main/java/sh/okx/rankup/gui/GuiListener.java b/src/main/java/sh/okx/rankup/gui/GuiListener.java index 7a1a01d..7e22446 100644 --- a/src/main/java/sh/okx/rankup/gui/GuiListener.java +++ b/src/main/java/sh/okx/rankup/gui/GuiListener.java @@ -1,40 +1,45 @@ -package sh.okx.rankup.gui; - -import lombok.RequiredArgsConstructor; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import sh.okx.rankup.RankupPlugin; - -@RequiredArgsConstructor -public class GuiListener implements Listener { - private final RankupPlugin plugin; - - @EventHandler - public void on(InventoryClickEvent e) { - Inventory inventory = e.getInventory(); - if (inventory == null - || !(inventory.getHolder() instanceof Gui) - || !inventory.equals(e.getClickedInventory())) { - return; - } - e.setCancelled(true); - - Player player = (Player) e.getWhoClicked(); - Gui gui = (Gui) inventory.getHolder(); - - if (gui.getRankup().isSimilar(e.getCurrentItem())) { - Bukkit.getScheduler().runTask(plugin, player::closeInventory); - if (gui.isPrestige()) { - plugin.getHelper().prestige(player); - } else { - plugin.getHelper().rankup(player); - } - } else if (gui.getCancel().isSimilar(e.getCurrentItem())) { - Bukkit.getScheduler().runTask(plugin, player::closeInventory); - } - } -} +package sh.okx.rankup.gui; + +import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import sh.okx.rankup.RankupPlugin; + +@RequiredArgsConstructor +public class GuiListener implements Listener { + private final RankupPlugin plugin; + + @EventHandler + public void on(InventoryClickEvent e) { + Inventory inventory = e.getInventory(); + if (inventory == null + || !(inventory.getHolder() instanceof Gui) + || !inventory.equals(e.getClickedInventory())) { + return; + } + e.setCancelled(true); + + Player player = (Player) e.getWhoClicked(); + Gui gui = (Gui) inventory.getHolder(); + + if (gui.getRankup().isSimilar(e.getCurrentItem())) { + Bukkit.getScheduler().runTask(plugin, player::closeInventory); + if (gui.isPrestige()) { + plugin.getHelper().prestige(player); + } else { + plugin.getHelper().rankup(player); + } + } else if (gui.getCancel().isSimilar(e.getCurrentItem())) { + Bukkit.getScheduler().runTask(plugin, () -> { + player.closeInventory(); + if (gui.isReturnToRanksGui()) { + Bukkit.dispatchCommand(player, "ranksgui"); + } + }); + } + } +} diff --git a/src/main/java/sh/okx/rankup/messages/Variable.java b/src/main/java/sh/okx/rankup/messages/Variable.java index 0fed4ce..bd3b99a 100644 --- a/src/main/java/sh/okx/rankup/messages/Variable.java +++ b/src/main/java/sh/okx/rankup/messages/Variable.java @@ -1,18 +1,19 @@ -package sh.okx.rankup.messages; - -public enum Variable { - PLAYER, - OLD_RANK, - RANK, - FROM, - TO, - MONEY, - MONEY_NEEDED, - AMOUNT, - AMOUNT_NEEDED, - AMOUNT_DONE, - PERCENT_DONE, - PERCENT_LEFT, - SECONDS, - SECONDS_LEFT -} +package sh.okx.rankup.messages; + +public enum Variable { + PLAYER, + OLD_RANK, + RANK, + FROM, + TO, + MONEY, + MONEY_NEEDED, + MONEY_DONE, + AMOUNT, + AMOUNT_NEEDED, + AMOUNT_DONE, + PERCENT_DONE, + PERCENT_LEFT, + SECONDS, + SECONDS_LEFT +} diff --git a/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java b/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java index e1d198e..a14b7ef 100644 --- a/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java +++ b/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java @@ -1,64 +1,64 @@ -package sh.okx.rankup.ranks.requirements; - -import org.bukkit.entity.Player; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.prestige.Prestige; -import sh.okx.rankup.prestige.Prestiges; -import sh.okx.rankup.requirements.Requirement; - -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -public class PrestigeListRankRequirements implements RankRequirements { - private final RankupPlugin plugin; - private final RankRequirements defaultRequirements; - private final Map requirements; - - public PrestigeListRankRequirements(RankupPlugin plugin, RankRequirements defaultRequirements, Map requirements) { - Objects.requireNonNull(plugin); - Objects.requireNonNull(defaultRequirements); - - this.plugin = plugin; - this.defaultRequirements = defaultRequirements; - this.requirements = requirements; - } - - @Override - public Set getRequirements(Player player) { - return getRankRequirements(player).getRequirements(player); - } - - @Override - public boolean hasRequirements(Player player) { - return getRankRequirements(player).hasRequirements(player); - } - - @Override - public Requirement getRequirement(Player player, String name) { - return getRankRequirements(player).getRequirement(player, name); - } - - @Override - public void applyRequirements(Player player) { - getRankRequirements(player).applyRequirements(player); - } - - private RankRequirements getRankRequirements(Player player) { - Prestiges prestiges = plugin.getPrestiges(); - if (player == null || prestiges == null) { - return defaultRequirements; - } - - for (Prestige prestige : prestiges.getTree()) { - String next = prestige.getNext(); - if(plugin.getPermissions().inGroup(player.getUniqueId(), next)) { - RankRequirements rankRequirements = this.requirements.get(next.toLowerCase()); - if (rankRequirements != null) { - return rankRequirements; - } - } - } - return defaultRequirements; - } -} +package sh.okx.rankup.ranks.requirements; + +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.prestige.Prestige; +import sh.okx.rankup.prestige.Prestiges; +import sh.okx.rankup.requirements.Requirement; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +public class PrestigeListRankRequirements implements RankRequirements { + private final RankupPlugin plugin; + private final RankRequirements defaultRequirements; + private final Map requirements; + + public PrestigeListRankRequirements(RankupPlugin plugin, RankRequirements defaultRequirements, Map requirements) { + Objects.requireNonNull(plugin); + Objects.requireNonNull(defaultRequirements); + + this.plugin = plugin; + this.defaultRequirements = defaultRequirements; + this.requirements = requirements; + } + + @Override + public Set getRequirements(Player player) { + return getRankRequirements(player).getRequirements(player); + } + + @Override + public boolean hasRequirements(Player player) { + return getRankRequirements(player).hasRequirements(player); + } + + @Override + public Requirement getRequirement(Player player, String name) { + return getRankRequirements(player).getRequirement(player, name); + } + + @Override + public void applyRequirements(Player player) { + getRankRequirements(player).applyRequirements(player); + } + + private RankRequirements getRankRequirements(Player player) { + Prestiges prestiges = plugin.getPrestiges(); + if (player == null || prestiges == null) { + return defaultRequirements; + } + + for (Prestige prestige : prestiges.getTree()) { + String next = prestige.getNext(); + if(next != null && plugin.getPermissions().inGroup(player.getUniqueId(), next)) { + RankRequirements rankRequirements = this.requirements.get(next.toLowerCase()); + if (rankRequirements != null) { + return rankRequirements; + } + } + } + return defaultRequirements; + } +} diff --git a/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java b/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java new file mode 100644 index 0000000..a0abb7b --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java @@ -0,0 +1,122 @@ +package sh.okx.rankup.ranksgui; + +import java.util.function.BiFunction; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.gui.Gui; +import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; + +public class RanksGui { + private final RankupPlugin plugin; + @Getter + private final Player player; + + private int rankupSlot; + + @Getter + private Inventory inventory; + + public RanksGui(RankupPlugin plugin, Player player) { + this.plugin = plugin; + this.player = player; + } + + public void open() { + RankElement playerRankElement = plugin.getRankups().getByPlayer(player); + ConfigurationSection playerPath = playerRankElement == null ? null : plugin.getSection(playerRankElement.getRank(), "rankup.ranksgui"); + ConfigurationSection basePath = plugin.getMessages().getConfigurationSection("rankup.ranksgui"); + + String title = get(ConfigurationSection::getString, "title", playerPath, basePath, "Ranks"); + int rows = get(ConfigurationSection::getInt, "rows", playerPath, basePath, 3); + int offset = get(ConfigurationSection::getInt, "offset", playerPath, basePath, 10); + int width = get(ConfigurationSection::getInt, "width", playerPath, basePath, 7); + + inventory = Bukkit.createInventory(null, rows * 9, title); + + ItemStack fill = get((section, path) -> Gui.getItem(plugin, section.getConfigurationSection(path), player, playerRankElement), "fill", playerPath, basePath, null); + + int index = offset; + int rowIndex = offset + width; + RankElement rankElement = plugin.getRankups().getTree().getFirst(); + boolean complete = playerRankElement != null; + while(rankElement.hasNext()) { + ConfigurationSection rankPath = plugin.getSection(rankElement.getRank(), "rankup.ranksgui"); + + String path; + if (rankElement == playerRankElement) { + path = "current"; + complete = false; + rankupSlot = index; + } else if (complete) { + path = "complete"; + } else { + path = "incomplete"; + } + + RankElement rankElement0 = rankElement; + ItemStack item = get((section, path0) -> Gui.getItem(plugin, section.getConfigurationSection(path0), player, rankElement0), path, rankPath, basePath, null); + + inventory.setItem(index++, item); + if (index == rowIndex) { + rowIndex += 9; + index += 9 - width; + } + if (index >= rows * 9) { + throw new IllegalArgumentException("Ranks GUI is too small for the number of ranks. Increase the number of rows on the ranks GUI."); + } + rankElement = rankElement.getNext(); + } + + if (fill != null) { + for (int i = 0; i < rows * 9; i++) { + ItemStack item = inventory.getItem(i); + if (item == null) { + inventory.setItem(i, fill); + } + } + } + + player.openInventory(inventory); + } + + private T get(BiFunction fun, String path, ConfigurationSection primary, ConfigurationSection secondary, T def) { + T get = null; + if (primary != null) { + get = fun.apply(primary, path); + } + if (get != null) { + return get; + } + if (secondary != null) { + get = fun.apply(secondary, path); + } + if (get != null) { + return get; + } + return def; + } + + public void click(InventoryClickEvent event) { + if (event.getClickedInventory() != event.getInventory()) { + return; + } + int slot = event.getRawSlot(); + if (slot == rankupSlot) { + Bukkit.getScheduler().runTask(plugin, () -> { + player.closeInventory(); + Bukkit.dispatchCommand(player, "rankup gui"); + }); + } + } + + public void close() { + + } +} diff --git a/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java new file mode 100644 index 0000000..e437efa --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java @@ -0,0 +1,26 @@ +package sh.okx.rankup.ranksgui; + +import lombok.RequiredArgsConstructor; +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 sh.okx.rankup.RankupPlugin; + +@RequiredArgsConstructor +public class RanksGuiCommand implements CommandExecutor { + private final RankupPlugin plugin; + private final RanksGuiListener listener; + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + + listener.open(new RanksGui(plugin, player)); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/sh/okx/rankup/ranksgui/RanksGuiListener.java b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiListener.java new file mode 100644 index 0000000..17a050c --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiListener.java @@ -0,0 +1,48 @@ +package sh.okx.rankup.ranksgui; + +import java.util.HashMap; +import java.util.Map; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; + +public class RanksGuiListener implements Listener { + + private final Map guiMap = new HashMap<>(); + + @EventHandler + public void on(InventoryCloseEvent event) { + if (!(event.getPlayer() instanceof Player)) { + return; + } + Player player = (Player) event.getPlayer(); + if (guiMap.containsKey(player)) { + RanksGui ranksGui = guiMap.get(player); + if (ranksGui.getInventory() != null + && ranksGui.getInventory() == event.getInventory()) { + guiMap.remove(player); + } + } + } + + @EventHandler + public void on(InventoryClickEvent event) { + if (!(event.getWhoClicked() instanceof Player)) { + return; + } + Player player = (Player) event.getWhoClicked(); + RanksGui ranksGui = guiMap.get(player); + if (ranksGui != null && event.getInventory() == ranksGui.getInventory()) { + event.setCancelled(true); + ranksGui.click(event); + } + } + + public void open(RanksGui gui) { + guiMap.put(gui.getPlayer(), gui); + gui.open(); + } +} + \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 53dfc2c..df673c8 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,105 +1,109 @@ -# this is used for letting you know that you need to update/change your config file -version: 8 - -# the locale to use for messages -# all messages can be customised but this allows you to -# choose messages that are already translated -# locales can be found in the locale/ folder -locale: en - -# interval (in minutes) to check to autorankup players -# ranking up manually wil always be enabled -# set to 0 to disable -autorankup-interval: 0 - -# whether /ranks and /prestiges should be enabled (true) or disabled (false) -# /rankup3 reload will not do anything if this is changed, -# you will have to restart your server. -ranks: true -# you can alternatively negate the permission rankup.prestiges -# this will also make the command not autocomplete in 1.13 -prestiges: true - -# whether or not /prestige and /prestiges should be enabled. -# when a player reaches the top rank, they can do /prestige to return to the first rank, -# but you will be able to grant them an additional "prestige" group or additional items. -# -# if you do not want this command to autocomplete, make sure -# you negate the permission rankup.prestige with your permissions plugin. -# if enabled, a prestiges.yml file will be generated with some example prestiges -# You must restart your server when you change this for it to work! -prestige: false - -# if true, players with the permission rankup.notify will receive notifications when they join -# to update if the server is on an older version of Rankup. -notify-update: true - -# if rankups and prestiges should be by permissions -# if false, players will be checked for if they have a group of the same name as in rankups.yml, -# and automatically added and taken away from those groups. -# if true, players will be checked for the permission rankup.rank.RANK, where RANK -# is the rankup in rankups.yml. Nothing will automatically happen on rankup, so you must -# use commands to change a player's group or permission. -permission-rankup: false - -# how people should confirm ranking up -# options are: gui, text or none -confirmation-type: 'gui' - -# how long, in seconds, people have to wait between a successful /rankup or /prestige -# set to 0 to disable. -cooldown: 1 - -# if enabled, players can run /maxrankup to rankup as many times as possible, -# before they fail the requirements for the next rank. -# the permission rankup.maxrankup is used for this command, but it is given by default. -# note that /maxrankup, if enabled, has no confirmation. -max-rankup: - # You must restart your server if you enable or disable /maxrankup! - enabled: false - # whether to send a message for each rankup a player does - # if set to true, the chat may be spammed for each rankup a player goes through with /maxrankup - # if set to false, only the last rankup will be shown (if a player starts on rank A, then does - # /maxrankup and ranks up to B and then C, it will just say "player has ranked up to C") - individual-messages: true - -# options when using the text rankup confirmation -text: - # the time in seconds for a player to - # confirm by typing /rankup again - timeout: 10 - -# placeholders: -# https://github.com/okx-code/Rankup3/wiki/PAPI-Placeholders -placeholders: - # format for money. for more information, see - # https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html - money-format: "#,##0.##" - percent-format: "0.##" - # the format used for requirements - simple-format: "#.##" - # used for current_rank and next_rank placeholders when a player is not in anything in rankups.yml - not-in-ladder: "None" - # used in the current_prestige placeholders when a player hasn't prestiged yet - no-prestige: "None" - # used in the next_rank and next_prestige placeholders when a player is at the highest rank or prestige - highest-rank: "None" - # used in the %rankup_status_[rank]% placeholders - status: - complete: "Complete" - current: "Current" - incomplete: "Incomplete" - -# what to shorten money by. -# ie 1000 -> 1k -# set to an empty list to disable -# for each entry here, it counts as increasing by a factor of 1,000 -# the first represents thousands (1,000) then millions (1,000,000) then billions (1,000,000,000) etc. -shorten: -- 'K' -- 'M' -- 'B' -- 'T' -- 'Q' -- 'Qu' +# this is used for letting you know that you need to update/change your config file +version: 9 + +# the locale to use for messages +# all messages can be customised but this allows you to +# choose messages that are already translated +# locales can be found in the locale/ folder +locale: en + +# interval (in minutes) to check to autorankup players +# ranking up manually will always be enabled +# set to 0 to disable +autorankup-interval: 0 + +# whether /ranks and /prestiges should be enabled (true) or disabled (false) +# /rankup3 reload will not do anything if this is changed, +# you will have to restart your server. +ranks: true +# you can alternatively negate the permission rankup.prestiges +# this will also make the command not autocomplete in 1.13 +prestiges: true + +# whether to enabable the /ranks GUI. +# will override the /ranks command +ranks-gui: false + +# whether or not /prestige and /prestiges should be enabled. +# when a player reaches the top rank, they can do /prestige to return to the first rank, +# but you will be able to grant them an additional "prestige" group or additional items. +# +# if you do not want this command to autocomplete, make sure +# you negate the permission rankup.prestige with your permissions plugin. +# if enabled, a prestiges.yml file will be generated with some example prestiges +# You must restart your server when you change this for it to work! +prestige: false + +# if true, players with the permission rankup.notify will receive notifications when they join +# to update if the server is on an older version of Rankup. +notify-update: true + +# if rankups and prestiges should be by permissions +# if false, players will be checked for if they have a group of the same name as in rankups.yml, +# and automatically added and taken away from those groups. +# if true, players will be checked for the permission rankup.rank.RANK, where RANK +# is the rankup in rankups.yml. Nothing will automatically happen on rankup, so you must +# use commands to change a player's group or permission. +permission-rankup: false + +# how people should confirm ranking up +# options are: gui, text or none +confirmation-type: 'gui' + +# how long, in seconds, people have to wait between a successful /rankup or /prestige +# set to 0 to disable. +cooldown: 1 + +# if enabled, players can run /maxrankup to rankup as many times as possible, +# before they fail the requirements for the next rank. +# the permission rankup.maxrankup is used for this command, but it is given by default. +# note that /maxrankup, if enabled, has no confirmation. +max-rankup: + # You must restart your server if you enable or disable /maxrankup! + enabled: false + # whether to send a message for each rankup a player does + # if set to true, the chat may be spammed for each rankup a player goes through with /maxrankup + # if set to false, only the last rankup will be shown (if a player starts on rank A, then does + # /maxrankup and ranks up to B and then C, it will just say "player has ranked up to C") + individual-messages: true + +# options when using the text rankup confirmation +text: + # the time in seconds for a player to + # confirm by typing /rankup again + timeout: 10 + +# placeholders: +# https://github.com/okx-code/Rankup3/wiki/PAPI-Placeholders +placeholders: + # format for money. for more information, see + # https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html + money-format: "#,##0.##" + percent-format: "0.##" + # the format used for requirements + simple-format: "#.##" + # used for current_rank and next_rank placeholders when a player is not in anything in rankups.yml + not-in-ladder: "None" + # used in the current_prestige placeholders when a player hasn't prestiged yet + no-prestige: "None" + # used in the next_rank and next_prestige placeholders when a player is at the highest rank or prestige + highest-rank: "None" + # used in the %rankup_status_[rank]% placeholders + status: + complete: "Complete" + current: "Current" + incomplete: "Incomplete" + +# what to shorten money by. +# ie 1000 -> 1k +# set to an empty list to disable +# for each entry here, it counts as increasing by a factor of 1,000 +# the first represents thousands (1,000) then millions (1,000,000) then billions (1,000,000,000) etc. +shorten: +- 'K' +- 'M' +- 'B' +- 'T' +- 'Q' +- 'Qu' - 'S' \ No newline at end of file diff --git a/src/main/resources/locale/en.yml b/src/main/resources/locale/en.yml index 51e7586..8900d05 100644 --- a/src/main/resources/locale/en.yml +++ b/src/main/resources/locale/en.yml @@ -1,104 +1,123 @@ -# the messages in this section can be customised for each rankup in rankups.yml. -rankup: - requirements-not-met: "&cYou need {MONEY} money to rankup." - no-rankup: "&eYou are at the highest rank." - # set to an empty string, ie: success-public: "" - # to hide that message. - success-public: "&a{PLAYER} &ehas ranked up to: &d{RANK}" - success-private: "&aYou have ranked up to: &d{RANK}" - # used for the text confirmation - confirmation: |- - &eAre you sure you want to rankup to &a{RANK}&e? - &eType &c/rankup &eagain to confirm. - # used for the GUI confirmation - title: "Rankup to {RANK}" - - must-prestige: "&cYou must prestige to /rankup further!" - - gui: - rows: 1 - title: "Rankup to {RANK}" - rankup: - material: EMERALD_BLOCK - # index can be separated by spaces to show in multiple groups - # for example: 0-3 9-12 18-21 - # you can also just use a single number instead of a range. - index: 0-3 - name: '&a&lConfirm' - # lore is optional - lore: '&6Rankup to &b{RANK}' - cancel: - material: REDSTONE_BLOCK - index: 5-8 - name: '&c&lCancel' - fill: - name: ' ' - # if you are using a 1.8-1.12 and you want to change this - # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 - # this works for both the rankup and cancel blocks as well - material: BLACK_STAINED_GLASS_PANE - - # you can (and probably should) you override these in rankups.yml - # to show the specific requirements for each rank. - # however if you are just using money or don't need to change the message per rank, you can use any combination of: - # {MONEY} {MONEY_NEEDED} {PERCENT_DONE } {PERCENT_LEFT } {AMOUNT } {AMOUNT_NEEDED } - # {MONEY} and {MONEY_NEEDED} are different from {AMOUNT money} and {AMOUNT_NEEDED money} in that they use a different format. - # here is an example of showing the requirements for just money: - #list: - # complete: "&7{OLD_RANK} &8\xbb &7{RANK} &efor &7${MONEY}" - # current: "&c{OLD_RANK} &e\xbb &c{RANK} &efor &a${MONEY} &e{PERCENT_DONE money}%" - # incomplete: "&r{OLD_RANK} &e\xbb &r{RANK} &efor &a${MONEY}" - list: - complete: "&7{OLD_RANK} &8\xbb &7{RANK}" - current: "&c{OLD_RANK} &e\xbb &c{RANK}" - incomplete: "&r{OLD_RANK} &e\xbb &r{RANK}" - # an empty string disables the header/footer - header: "" - footer: "" - # sent when a player tries to rankup when they are on cooldown - cooldown: - singular: "&cYou must wait {SECONDS_LEFT} more second to rankup again." - plural: "&cYou must wait {SECONDS_LEFT} more seconds to rankup again." -# prestige messages can also be customised -prestige: - requirements-not-met: "&cYou need {MONEY} money to prestige." - no-prestige: "&eYou are at the highest prestige." - - success-public: "&a{PLAYER} &ehas prestiged to: &d{RANK}" - success-private: "&aYou have prestiged to: &d{RANK}" - - confirmation: |- - &eAre you sure you want to prestige to &a{RANK}&e? - &eType &c/prestige &eagain to confirm. - - gui: - title: "Prestige to {RANK}" - rankup: - material: GOLD_BLOCK - index: 0-3 - name: '&a&lConfirm' - lore: '&6Prestige to &b{RANK}' - cancel: - material: REDSTONE_BLOCK - index: 5-8 - name: '&c&lCancel' - fill: - name: ' ' - # if you are using a 1.8-1.12 and you want to change this - # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 - # this works for both the rankup and cancel blocks as well - material: BLACK_STAINED_GLASS_PANE - - list: - complete: "&7{OLD_RANK} &8\xbb &7{RANK}" - current: "&c{OLD_RANK} &e\xbb &c{RANK}" - incomplete: "&r{OLD_RANK} &e\xbb &r{RANK}" - header: "" - footer: "" - cooldown: - singular: "&cYou must wait {SECONDS_LEFT} second to prestige again." - plural: "&cYou must wait {SECONDS_LEFT} more seconds to prestige again." - -not-high-enough: "&cYou cannot prestige at your rank!" -not-in-ladder: "&cSorry, but we could not find any rankups for the group(s) you are in. Use /ranks to list the rankups." +# the messages in this section can be customised for each rankup in rankups.yml. +rankup: + requirements-not-met: "&cYou need {MONEY} money to rankup." + no-rankup: "&eYou are at the highest rank." + # set to an empty string, ie: success-public: "" + # to hide that message. + success-public: "&a{PLAYER} &ehas ranked up to: &d{RANK}" + success-private: "&aYou have ranked up to: &d{RANK}" + # used for the text confirmation + confirmation: |- + &eAre you sure you want to rankup to &a{RANK}&e? + &eType &c/rankup &eagain to confirm. + # used for the GUI confirmation + title: "Rankup to {RANK}" + + must-prestige: "&cYou must prestige to /rankup further!" + + gui: + rows: 1 + title: "Rankup to {RANK}" + rankup: + material: EMERALD_BLOCK + # index can be separated by spaces to show in multiple groups + # for example: 0-3 9-12 18-21 + # you can also just use a single number instead of a range. + index: 0-3 + name: '&a&lConfirm' + # lore is optional + lore: '&6Rankup to &b{RANK}' + cancel: + material: REDSTONE_BLOCK + index: 5-8 + name: '&c&lCancel' + fill: + name: ' ' + # if you are using a 1.8-1.12 and you want to change this + # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 + # this works for both the rankup and cancel blocks as well + material: BLACK_STAINED_GLASS_PANE + + ranksgui: + title: "Ranks" + rows: 3 + offset: 10 + width: 7 + complete: + material: GREEN_STAINED_GLASS_PANE + name: "&aRank &7{RANK} &a(completed)" + current: + material: ORANGE_STAINED_GLASS_PANE + name: "&dRankup to &7{RANK}" + incomplete: + material: RED_STAINED_GLASS_PANE + name: "&cRank &7{RANK} &c(requires rankup)" + fill: + material: BLACK_STAINED_GLASS_PANE + name: ' ' + + + # you can (and probably should) you override these in rankups.yml + # to show the specific requirements for each rank. + # however if you are just using money or don't need to change the message per rank, you can use any combination of: + # {MONEY} {MONEY_NEEDED} {PERCENT_DONE } {PERCENT_LEFT } {AMOUNT } {AMOUNT_NEEDED } + # {MONEY} and {MONEY_NEEDED} are different from {AMOUNT money} and {AMOUNT_NEEDED money} in that they use a different format. + # here is an example of showing the requirements for just money: + #list: + # complete: "&7{OLD_RANK} &8\xbb &7{RANK} &efor &7${MONEY}" + # current: "&c{OLD_RANK} &e\xbb &c{RANK} &efor &a${MONEY} &e{PERCENT_DONE money}%" + # incomplete: "&r{OLD_RANK} &e\xbb &r{RANK} &efor &a${MONEY}" + list: + complete: "&7{OLD_RANK} &8\xbb &7{RANK}" + current: "&c{OLD_RANK} &e\xbb &c{RANK}" + incomplete: "&r{OLD_RANK} &e\xbb &r{RANK}" + # an empty string disables the header/footer + header: "" + footer: "" + # sent when a player tries to rankup when they are on cooldown + cooldown: + singular: "&cYou must wait {SECONDS_LEFT} more second to rankup again." + plural: "&cYou must wait {SECONDS_LEFT} more seconds to rankup again." +# prestige messages can also be customised +prestige: + requirements-not-met: "&cYou need {MONEY} money to prestige." + no-prestige: "&eYou are at the highest prestige." + + success-public: "&a{PLAYER} &ehas prestiged to: &d{RANK}" + success-private: "&aYou have prestiged to: &d{RANK}" + + confirmation: |- + &eAre you sure you want to prestige to &a{RANK}&e? + &eType &c/prestige &eagain to confirm. + + gui: + title: "Prestige to {RANK}" + rankup: + material: GOLD_BLOCK + index: 0-3 + name: '&a&lConfirm' + lore: '&6Prestige to &b{RANK}' + cancel: + material: REDSTONE_BLOCK + index: 5-8 + name: '&c&lCancel' + fill: + name: ' ' + # if you are using a 1.8-1.12 and you want to change this + # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 + # this works for both the rankup and cancel blocks as well + material: BLACK_STAINED_GLASS_PANE + + list: + complete: "&7{OLD_RANK} &8\xbb &7{RANK}" + current: "&c{OLD_RANK} &e\xbb &c{RANK}" + incomplete: "&r{OLD_RANK} &e\xbb &r{RANK}" + header: "" + footer: "" + cooldown: + singular: "&cYou must wait {SECONDS_LEFT} second to prestige again." + plural: "&cYou must wait {SECONDS_LEFT} more seconds to prestige again." + +not-high-enough: "&cYou cannot prestige at your rank!" +not-in-ladder: "&cSorry, but we could not find any rankups for the group(s) you are in. Use /ranks to list the rankups." invalid-rankup: "&cInvalid rankup defined in config, please check console." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7ed22d9..90a73ad 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,61 +1,61 @@ -name: Rankup -version: ${version} -main: sh.okx.rankup.RankupPlugin -author: Okx -depend: [Vault] -softdepend: [PlaceholderAPI, mcMMO, AdvancedAchievements, Towny] -api-version: 1.13 - -commands: - rankup: - permission: rankup.rankup - description: Rankup. - rankup3: - description: View Rankup version and perform some administrative commands. - # support the old command - aliases: [pru] - ranks: - permission: rankup.ranks - description: List all the ranks. - prestige: - permission: rankup.prestige - description: Prestige. - prestiges: - permission: rankup.prestiges - description: List all the prestiges. - maxrankup: - permission: rankup.maxrankup - description: Rankup as much as possible. -permissions: - rankup.*: - children: - rankup.rankup: true - rankup.admin: true - rankup.ranks: true - rankup.prestige: true - rankup.prestiges: true - rankup.auto: true - rankup.maxrankup: true - rankup.admin: - children: - # if a player can see if the plugin needs updating when they run /pru - rankup.checkversion: true - # if a player can run /pru reload - rankup.reload: true - # if a player can force rankup or prestige someone - rankup.force: true - # if a player receives notifications to update rankup when they log in. - rankup.notify: true - default: op - rankup.rankup: - default: true - rankup.ranks: - default: true - rankup.prestige: - default: true - rankup.prestiges: - default: true - rankup.auto: - default: true - rankup.maxrankup: +name: Rankup +version: ${version} +main: sh.okx.rankup.RankupPlugin +author: Okx +depend: [Vault] +softdepend: [PlaceholderAPI, mcMMO, AdvancedAchievements, Towny] +api-version: 1.13 + +commands: + rankup: + permission: rankup.rankup + description: Rankup. + rankup3: + description: View Rankup version and perform some administrative commands. + # support the old command + aliases: [pru] + ranks: + permission: rankup.ranks + description: List all the ranks. + prestige: + permission: rankup.prestige + description: Prestige. + prestiges: + permission: rankup.prestiges + description: List all the prestiges. + maxrankup: + permission: rankup.maxrankup + description: Rankup as much as possible. +permissions: + rankup.*: + children: + rankup.rankup: true + rankup.admin: true + rankup.ranks: true + rankup.prestige: true + rankup.prestiges: true + rankup.auto: true + rankup.maxrankup: true + rankup.admin: + children: + # if a player can see if the plugin needs updating when they run /pru + rankup.checkversion: true + # if a player can run /pru reload + rankup.reload: true + # if a player can force rankup or prestige someone + rankup.force: true + # if a player receives notifications to update rankup when they log in. + rankup.notify: true + default: op + rankup.rankup: + default: true + rankup.ranks: + default: true + rankup.prestige: + default: true + rankup.prestiges: + default: true + rankup.auto: + default: true + rankup.maxrankup: default: true \ No newline at end of file