diff --git a/build.gradle b/build.gradle index 8e0f505..ad5c44a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id "io.freefair.lombok" version "5.0.1" + id "io.freefair.lombok" version "5.1.0" } group 'sh.okx' diff --git a/lombok.config b/lombok.config index cf350fc..6aa51d7 100644 --- a/lombok.config +++ b/lombok.config @@ -1,2 +1,2 @@ -# This file is generated by the 'io.freefair.lombok' Gradle plugin -config.stopBubbling = true +# This file is generated by the 'io.freefair.lombok' Gradle plugin +config.stopBubbling = true diff --git a/src/main/java/sh/okx/rankup/RankList.java b/src/main/java/sh/okx/rankup/RankList.java deleted file mode 100644 index 191e5b3..0000000 --- a/src/main/java/sh/okx/rankup/RankList.java +++ /dev/null @@ -1,130 +0,0 @@ -package sh.okx.rankup; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import lombok.Getter; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import sh.okx.rankup.ranks.Rank; - -public class RankList { - protected final RankupPlugin plugin; - @Getter - protected final FileConfiguration config; - protected final Collection ranks = new ArrayList<>(); - - public RankList(RankupPlugin plugin, FileConfiguration config, Function deserializer) { - this.plugin = plugin; - this.config = config; - for (Map.Entry entry : config.getValues(false).entrySet()) { - ConfigurationSection rankSection = (ConfigurationSection) entry.getValue(); - validateSection(rankSection); - T apply = deserializer.apply(rankSection); - if (apply != null) { - ranks.add(apply); - } - } - List ordered = getOrderedList(); - Set provisionalRanks = new HashSet<>(ordered); - this.ranks.clear(); - this.ranks.addAll(provisionalRanks); - } - - protected void validateSection(ConfigurationSection section) { - String name = "'" + section.getName() + "'"; - /*if (section.getConfigurationSection("requirements") != null) { - throw new IllegalArgumentException( - "Rankup/prestige section " + name + " is using the old requirements system.\n" + - "Instead of a configuration section, it is now a list of strings.\n" + - "For example, instead of \"requirements: money: 1000\" you should use \"requirements: - 'money 1000'\"."); - }*/ - Set keys = section.getKeys(false); - if (keys.size() == 1 && keys.iterator().next().equalsIgnoreCase("rank")) { - throw new IllegalArgumentException( - "Having a final rank (for example: \"Z: rank: 'Z'\") from 3.4.2 or earlier should no longer be used.\n" + - "It is safe to just delete the final rank " + name + ""); - } else if (!section.contains("requirements")) { - throw new IllegalArgumentException("Rank " + name + " does not have any requirements."); - } - } - - public T getFirst() { - OUTER: - for (T rank : ranks) { - // see if anything ranks up to this - for (T rank0 : ranks) { - if (rank0.getNext().equalsIgnoreCase(rank.getRank())) { - continue OUTER; - } - } - // nothing ranks up to this - return rank; - } - throw new IllegalArgumentException("Could not find a first rank. First ranks must not have anything that ranks up to them."); - } - - public List getOrderedList() { - List list = new ArrayList<>(); - T t = getFirst(); - while (t != null) { - for (T existing : list) { - if (existing.equals(t)) { - throw new IllegalArgumentException("Infinite rankup loop detected at rank " + t.getRank() + " to " + t.getNext() - + "\nMake sure no there are no rankups to previous ranks or to the same rank"); - } - } - list.add(t); - t = next(t); - } - return list; - } - - public T getByName(String name) { - if (name == null) { - return null; - } - for (T rank : ranks) { - if (name.equalsIgnoreCase(rank.getRank())) { - return rank; - } - } - return null; - } - - public T getByPlayer(Player player) { - List list = getOrderedList(); - Collections.reverse(list); - for (T t : list) { - if (t.isIn(player)) { - return t; - } - } - return null; - } - - public String getLast() { - List list = getOrderedList(); - return list.get(list.size() - 1).getNext(); - } - - public boolean isLast(Player player) { - String last = getLast(); - return plugin.getPermissions().inGroup(player.getUniqueId(), last); - } - - public T next(T rank) { - for (T nextRank : ranks) { - if (rank.getNext() != null && rank.getNext().equalsIgnoreCase(nextRank.getRank())) { - return nextRank; - } - } - return null; - } -} diff --git a/src/main/java/sh/okx/rankup/RankupHelper.java b/src/main/java/sh/okx/rankup/RankupHelper.java index 65c857d..1f16bb4 100644 --- a/src/main/java/sh/okx/rankup/RankupHelper.java +++ b/src/main/java/sh/okx/rankup/RankupHelper.java @@ -1,7 +1,5 @@ package sh.okx.rankup; -import java.util.HashMap; -import java.util.Map; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import sh.okx.rankup.hook.GroupProvider; @@ -10,8 +8,13 @@ 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. @@ -32,23 +35,23 @@ public class RankupHelper { this.permissions = plugin.getPermissions(); } - public void doRankup(Player player, Rank rank) { - rank.runCommands(player); + public void doRankup(Player player, RankElement rank) { + rank.getRank().runCommands(player); if (rank.getRank() != null) { - permissions.removeGroup(player.getUniqueId(), rank.getRank()); + permissions.removeGroup(player.getUniqueId(), rank.getRank().getRank()); } - permissions.addGroup(player.getUniqueId(), rank.getNext()); + permissions.addGroup(player.getUniqueId(), rank.getNext().getRank().getRank()); } - public void sendRankupMessages(Player player, Rank rank) { - plugin.getMessage(rank, Message.SUCCESS_PUBLIC) + public void sendRankupMessages(Player player, RankElement rank) { + plugin.getMessage(rank.getRank(), Message.SUCCESS_PUBLIC) .failIfEmpty() - .replaceRanks(player, rank, rank.getNext()) + .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) .broadcast(); - plugin.getMessage(rank, Message.SUCCESS_PRIVATE) + plugin.getMessage(rank.getRank(), Message.SUCCESS_PRIVATE) .failIfEmpty() - .replaceRanks(player, rank, rank.getNext()) + .replaceRanks(player, rank.getRank(), rank.getNext().getRank()) .send(player); } @@ -64,16 +67,19 @@ public class RankupHelper { permissions.addGroup(player.getUniqueId(), prestige.getNext()); } - public void sendPrestigeMessages(Player player, Prestige prestige) { - plugin.getMessage(prestige, Message.PRESTIGE_SUCCESS_PUBLIC) + 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, prestige.getNext()) - .replaceFromTo(prestige) + .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) + .replaceFromTo(prestige.getRank()) .broadcast(); - plugin.getMessage(prestige, Message.PRESTIGE_SUCCESS_PRIVATE) + plugin.getMessage(prestige.getRank(), Message.PRESTIGE_SUCCESS_PRIVATE) .failIfEmpty() - .replaceRanks(player, prestige, prestige.getNext()) - .replaceFromTo(prestige) + .replaceRanks(player, prestige.getRank(), prestige.getNext().getRank()) + .replaceFromTo(prestige.getRank()) .send(player); } @@ -112,12 +118,13 @@ public class RankupHelper { return; } - Rank rank = plugin.getRankups().getByPlayer(player); + RankElement rankElement = plugin.getRankups().getByPlayer(player); + Rank rank = rankElement.getRank(); rank.applyRequirements(player); applyCooldown(player); - doRankup(player, rank); - sendRankupMessages(player, rank); + doRankup(player, rankElement); + sendRankupMessages(player, rankElement); } public boolean checkRankup(Player player) { @@ -132,24 +139,26 @@ public class RankupHelper { */ public boolean checkRankup(Player player, boolean message) { Rankups rankups = plugin.getRankups(); - Rank rank = rankups.getByPlayer(player); - if (rankups.isLast(player)) { - Prestiges prestiges = plugin.getPrestiges(); - plugin.getMessage(prestiges == null || prestiges.isLast(player) ? Message.NO_RANKUP : Message.MUST_PRESTIGE) - .failIf(!message) - .replaceRanks(player, rankups.getLast()) - .send(player); - return false; - } else if (rank == null) { // check if in ladder + 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, rank.getNext()), player, rank) + .replaceRanks(player, rank, rankElement.getNext().getRank()), player, rank) .send(player); } return false; @@ -165,12 +174,13 @@ public class RankupHelper { return; } - Prestige prestige = plugin.getPrestiges().getByPlayer(player); + RankElement rankElement = plugin.getPrestiges().getByPlayer(player); + Prestige prestige = rankElement.getRank(); prestige.applyRequirements(player); applyCooldown(player); doPrestige(player, prestige); - sendPrestigeMessages(player, prestige); + sendPrestigeMessages(player, rankElement); } public boolean checkPrestige(Player player) { @@ -179,29 +189,29 @@ public class RankupHelper { public boolean checkPrestige(Player player, boolean message) { Prestiges prestiges = plugin.getPrestiges(); - Prestige prestige = prestiges.getByPlayer(player); - if (prestige == null || !prestige.isEligable(player)) { // check if in ladder + 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 (prestiges.isLast(player)) { // check if they are at the highest rank - plugin.getMessage(prestige, Message.PRESTIGE_NO_PRESTIGE) + } else if (!prestigeElement.hasNext()) { // check if they are at the highest rank + plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_NO_PRESTIGE) .failIf(!message) - .replaceRanks(player, prestige.getRank()) - .replaceFromTo(prestige) + .replaceRanks(player, prestigeElement.getRank().getRank()) + .replaceFromTo(prestigeElement.getRank()) .send(player); return false; - } else if (!prestige.hasRequirements(player)) { // check if they can afford it + } else if (!prestigeElement.getRank().hasRequirements(player)) { // check if they can afford it plugin.replaceMoneyRequirements( - plugin.getMessage(prestige, Message.PRESTIGE_REQUIREMENTS_NOT_MET) + plugin.getMessage(prestigeElement.getRank(), Message.PRESTIGE_REQUIREMENTS_NOT_MET) .failIf(!message) - .replaceRanks(player, prestige, prestiges.next(prestige).getRank()), player, prestige) - .replaceFromTo(prestige) + .replaceRanks(player, prestigeElement.getRank(), prestigeElement.getNext().getRank().getRank()), player, prestigeElement.getRank()) + .replaceFromTo(prestigeElement.getRank()) .send(player); return false; - } else if (checkCooldown(player, prestige)) { + } else if (checkCooldown(player, prestigeElement.getRank())) { return false; } diff --git a/src/main/java/sh/okx/rankup/RankupPlugin.java b/src/main/java/sh/okx/rankup/RankupPlugin.java index 9e6ce05..4ef966a 100644 --- a/src/main/java/sh/okx/rankup/RankupPlugin.java +++ b/src/main/java/sh/okx/rankup/RankupPlugin.java @@ -1,11 +1,5 @@ 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 net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; @@ -20,16 +14,11 @@ import org.bukkit.inventory.InventoryView; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; -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.commands.*; import sh.okx.rankup.gui.Gui; import sh.okx.rankup.gui.GuiListener; -import sh.okx.rankup.hook.PermissionManager; import sh.okx.rankup.hook.GroupProvider; +import sh.okx.rankup.hook.PermissionManager; import sh.okx.rankup.messages.Message; import sh.okx.rankup.messages.MessageBuilder; import sh.okx.rankup.messages.NullMessageBuilder; @@ -38,44 +27,32 @@ import sh.okx.rankup.placeholders.Placeholders; import sh.okx.rankup.prestige.Prestige; 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.requirements.Requirement; import sh.okx.rankup.requirements.RequirementRegistry; import sh.okx.rankup.requirements.XpLevelDeductibleRequirement; -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.TokensDeductibleRequirement; -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.XpLevelRequirement; +import sh.okx.rankup.requirements.requirement.*; 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.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.towny.*; 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 { @Getter @@ -227,7 +204,7 @@ public class RankupPlugin extends JavaPlugin { } private void addAll(Map map, RankList ranks) { - for (Rank rank : ranks.ranks) { + for (Rank rank : ranks.getTree()) { for (Requirement requirement : rank.getRequirements().getRequirements(null)) { String name = requirement.getName(); map.put(name, map.getOrDefault(name, 0) + 1); @@ -477,7 +454,7 @@ public class RankupPlugin extends JavaPlugin { } } - public MessageBuilder getMessage(CommandSender player, Message message, Rank oldRank, String rankName) { + public MessageBuilder getMessage(CommandSender player, Message message, Rank oldRank, Rank rankName) { String oldRankName; if (oldRank instanceof Prestige && oldRank.getRank() == null) { oldRankName = ((Prestige) oldRank).getFrom(); @@ -486,7 +463,7 @@ public class RankupPlugin extends JavaPlugin { } return replaceMoneyRequirements(getMessage(oldRank, message) - .replaceRanks(player, rankName) + .replaceRanks(player, rankName.getRank()) .replace(Variable.OLD_RANK, oldRankName), player, oldRank) .replaceFromTo(oldRank); } diff --git a/src/main/java/sh/okx/rankup/commands/InfoCommand.java b/src/main/java/sh/okx/rankup/commands/InfoCommand.java index c6de264..b1793ba 100644 --- a/src/main/java/sh/okx/rankup/commands/InfoCommand.java +++ b/src/main/java/sh/okx/rankup/commands/InfoCommand.java @@ -11,6 +11,7 @@ import sh.okx.rankup.RankupPlugin; 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 sh.okx.rankup.util.UpdateNotifier; @@ -46,19 +47,19 @@ public class InfoCommand implements CommandExecutor { } Rankups rankups = plugin.getRankups(); - if (rankups.isLast(player)) { + RankElement rankElement = rankups.getByPlayer(player); + if (rankElement == null) { + sender.sendMessage(ChatColor.YELLOW + "That player is not in any rankup groups."); + return true; + } else if (!rankElement.hasNext()) { sender.sendMessage(ChatColor.YELLOW + "That player is at the last rank."); return true; } - Rank rank = rankups.getByPlayer(player); - if (rank == null) { - sender.sendMessage(ChatColor.YELLOW + "That player is not in any rankup groups."); - return true; - } + Rank rank = rankElement.getRank(); - plugin.getHelper().doRankup(player, rank); - plugin.getHelper().sendRankupMessages(player, rank); + plugin.getHelper().doRankup(player, rankElement); + plugin.getHelper().sendRankupMessages(player, rankElement); sender.sendMessage(ChatColor.GREEN + "Successfully forced " + ChatColor.GOLD + player.getName() + ChatColor.GREEN + " to rankup from " + ChatColor.GOLD + rank.getRank() @@ -82,19 +83,20 @@ public class InfoCommand implements CommandExecutor { } Prestiges prestiges = plugin.getPrestiges(); - if (prestiges.isLast(player)) { + RankElement rankElement = prestiges.getByPlayer(player); + if (!rankElement.hasNext()) { sender.sendMessage(ChatColor.YELLOW + "That player is at the last prestige."); return true; } - Prestige prestige = prestiges.getByPlayer(player); + Prestige prestige = rankElement.getRank(); if (prestige == null) { sender.sendMessage(ChatColor.YELLOW + "That player is not in any prestige groups."); return true; } plugin.getHelper().doPrestige(player, prestige); - plugin.getHelper().sendPrestigeMessages(player, prestige); + plugin.getHelper().sendPrestigeMessages(player, rankElement); sender.sendMessage(ChatColor.GREEN + "Successfully forced " + ChatColor.GOLD + player.getName() + ChatColor.GREEN + " to prestige " diff --git a/src/main/java/sh/okx/rankup/commands/MaxRankupCommand.java b/src/main/java/sh/okx/rankup/commands/MaxRankupCommand.java index 1ed77af..cc3043e 100644 --- a/src/main/java/sh/okx/rankup/commands/MaxRankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/MaxRankupCommand.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.RankupHelper; import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; @RequiredArgsConstructor public class MaxRankupCommand implements CommandExecutor { @@ -27,8 +28,8 @@ public class MaxRankupCommand implements CommandExecutor { } do { - Rank rank = plugin.getRankups().getByPlayer(player); - rank.applyRequirements(player); + RankElement rank = plugin.getRankups().getByPlayer(player); + rank.getRank().applyRequirements(player); helper.doRankup(player, rank); diff --git a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java index ddf607d..67dda2e 100644 --- a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java +++ b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java @@ -11,6 +11,7 @@ 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; @@ -33,10 +34,11 @@ public class PrestigeCommand implements CommandExecutor { Player player = (Player) sender; Prestiges prestiges = plugin.getPrestiges(); - Prestige prestige = prestiges.getByPlayer(player); 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(); @@ -51,8 +53,8 @@ public class PrestigeCommand implements CommandExecutor { switch (confirmationType) { case "text": confirming.put(player, System.currentTimeMillis()); - Prestige next = prestiges.next(prestige); - String nextRank = next == null ? prestiges.getLast() : next.getRank(); + 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) @@ -60,7 +62,7 @@ public class PrestigeCommand implements CommandExecutor { .send(player); break; case "gui": - Gui.of(player, prestige, prestige.getNext(), plugin).open(player); + Gui.of(player, prestige, rankElement.getNext().getRank(), plugin).open(player); break; case "none": plugin.getHelper().prestige(player); diff --git a/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java index 5af691d..210bf64 100644 --- a/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java +++ b/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java @@ -9,6 +9,7 @@ import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.messages.Message; import sh.okx.rankup.prestige.Prestige; import sh.okx.rankup.prestige.Prestiges; +import sh.okx.rankup.ranks.RankElement; @RequiredArgsConstructor public class PrestigesCommand implements CommandExecutor { @@ -23,26 +24,26 @@ public class PrestigesCommand implements CommandExecutor { Prestiges prestiges = plugin.getPrestiges(); Prestige playerRank = null; if (sender instanceof Player) { - playerRank = prestiges.getByPlayer((Player) sender); + playerRank = prestiges.getRankByPlayer((Player) sender); } plugin.sendHeaderFooter(sender, playerRank, Message.PRESTIGES_HEADER); Message message = playerRank == null ? Message.PRESTIGES_INCOMPLETE : Message.PRESTIGES_COMPLETE; - Prestige prestige = prestiges.getFirst(); - String nextRank; - do { - nextRank = prestige.getNext(); - if (prestige.equals(playerRank)) { - plugin.getMessage(sender, Message.PRESTIGES_CURRENT, prestige, nextRank) + RankElement prestige = prestiges.getTree().getFirst(); + while (prestige.hasNext()) { + RankElement next = prestige.getNext(); + if (prestige.getRank().equals(playerRank)) { + plugin.getMessage(sender, Message.PRESTIGES_CURRENT, prestige.getRank(), next.getRank()) .send(sender); message = Message.PRESTIGES_INCOMPLETE; } else { - plugin.getMessage(sender, message, prestige, nextRank) - .replaceFirstPrestige(prestige, prestiges, prestige.getFrom()) + plugin.getMessage(sender, message, prestige.getRank(), next.getRank()) + .replaceFirstPrestige(prestige.getRank(), prestiges, prestige.getRank().getFrom()) .send(sender); } - } while((prestige = prestiges.getByName(nextRank)) != null); + prestige = next; + } plugin.sendHeaderFooter(sender, playerRank, Message.PRESTIGES_FOOTER); return true; diff --git a/src/main/java/sh/okx/rankup/commands/RanksCommand.java b/src/main/java/sh/okx/rankup/commands/RanksCommand.java index cdd2975..625575b 100644 --- a/src/main/java/sh/okx/rankup/commands/RanksCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RanksCommand.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.messages.Message; import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.ranks.RankElement; import sh.okx.rankup.ranks.Rankups; @RequiredArgsConstructor @@ -21,27 +22,29 @@ public class RanksCommand implements CommandExecutor { } Rankups rankups = plugin.getRankups(); - Rank playerRank = null; + RankElement playerRank = null; + Rank pRank = null; if (sender instanceof Player) { playerRank = rankups.getByPlayer((Player) sender); + pRank = playerRank == null ? null : playerRank.getRank(); } - plugin.sendHeaderFooter(sender, playerRank, Message.RANKS_HEADER); + plugin.sendHeaderFooter(sender, pRank, Message.RANKS_HEADER); - Message message = !(sender instanceof Player && rankups.isLast((Player) sender)) + Message message = !(sender instanceof Player && !(playerRank != null && playerRank.hasNext())) && playerRank == null ? Message.RANKS_INCOMPLETE : Message.RANKS_COMPLETE; - Rank rank = rankups.getFirst(); - while (rank != null) { - String name = rank.getNext(); - if (rank.equals(playerRank)) { - plugin.getMessage(sender, Message.RANKS_CURRENT, rank, name).failIfEmpty().send(sender); + RankElement rank = rankups.getTree().getFirst(); + while (rank.hasNext()) { + RankElement next = rank.getNext(); + if (rank.getRank().equals(pRank)) { + plugin.getMessage(sender, Message.RANKS_CURRENT, rank.getRank(), next.getRank()).failIfEmpty().send(sender); message = Message.RANKS_INCOMPLETE; } else { - plugin.getMessage(sender, message, rank, name).failIfEmpty().send(sender); + plugin.getMessage(sender, message, rank.getRank(), next.getRank()).failIfEmpty().send(sender); } - rank = rankups.getByName(name); + rank = next; } - plugin.sendHeaderFooter(sender, playerRank, Message.RANKS_FOOTER); + plugin.sendHeaderFooter(sender, pRank, Message.RANKS_FOOTER); 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 7c59699..9551e35 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -10,6 +10,7 @@ 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; @@ -35,10 +36,10 @@ public class RankupCommand implements CommandExecutor { Player player = (Player) sender; Rankups rankups = plugin.getRankups(); - Rank rank = rankups.getByPlayer(player); if (!plugin.getHelper().checkRankup(player)) { return true; } + RankElement rankElement = rankups.getByPlayer(player); /*Rank next = rankups.next(rank); if (next == null) { plugin.getLogger().severe("Rankup from " + rank.getRank() + " to " + rank.getNext() + @@ -46,7 +47,6 @@ public class RankupCommand implements CommandExecutor { plugin.getMessage(Message.INVALID_RANKUP).failIfEmpty().send(player); return true; }*/ - String next = rank.getNext(); FileConfiguration config = plugin.getConfig(); String confirmationType = config.getString("confirmation-type").toLowerCase(); @@ -63,12 +63,12 @@ public class RankupCommand implements CommandExecutor { switch (confirmationType) { case "text": confirming.put(player, System.currentTimeMillis()); - plugin.replaceMoneyRequirements(plugin.getMessage(rank, Message.CONFIRMATION) - .replaceRanks(player, rank, next), player, rank) + plugin.replaceMoneyRequirements(plugin.getMessage(rankElement.getRank(), Message.CONFIRMATION) + .replaceRanks(player, rankElement.getRank(), rankElement.getNext().getRank()), player, rankElement.getRank()) .send(player); break; case "gui": - Gui.of(player, rank, next, plugin).open(player); + Gui.of(player, rankElement.getRank(), rankElement.getNext().getRank(), plugin).open(player); break; case "none": plugin.getHelper().rankup(player); diff --git a/src/main/java/sh/okx/rankup/gui/Gui.java b/src/main/java/sh/okx/rankup/gui/Gui.java index e28d650..d1a6257 100644 --- a/src/main/java/sh/okx/rankup/gui/Gui.java +++ b/src/main/java/sh/okx/rankup/gui/Gui.java @@ -17,11 +17,11 @@ 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; -import sh.okx.rankup.util.ItemUtil; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class Gui implements InventoryHolder { @@ -34,7 +34,7 @@ public class Gui implements InventoryHolder { @Getter private boolean prestige; - public static Gui of(Player player, Rank oldRank, String rank, RankupPlugin plugin) { + public static Gui of(Player player, Rank oldRank, Rank rank, RankupPlugin plugin) { Gui gui = new Gui(); gui.prestige = oldRank instanceof Prestige; @@ -65,7 +65,7 @@ public class Gui implements InventoryHolder { } @SuppressWarnings("deprecation") - private static ItemStack getItem(RankupPlugin plugin, ConfigurationSection section, Player player, Rank oldRank, String rank) { + private static ItemStack getItem(RankupPlugin plugin, ConfigurationSection section, Player player, Rank oldRank, Rank rank) { String materialName = section.getString("material").toUpperCase(); ItemStack item; @@ -73,7 +73,7 @@ public class Gui implements InventoryHolder { Material material = Material.valueOf(materialName); item = new ItemStack(material); } else { - // handle default material correctly on older vesions + // handle default material correctly on older versions if (materialName.equals("BLACK_STAINED_GLASS_PANE")) { materialName = "STAINED_GLASS_PANE:15"; } @@ -103,7 +103,7 @@ public class Gui implements InventoryHolder { return item; } - private static String format(RankupPlugin plugin, String message, Player player, Rank oldRank, String rank) { + 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(); diff --git a/src/main/java/sh/okx/rankup/hook/GroupProvider.java b/src/main/java/sh/okx/rankup/hook/GroupProvider.java index 093d15d..93d2723 100644 --- a/src/main/java/sh/okx/rankup/hook/GroupProvider.java +++ b/src/main/java/sh/okx/rankup/hook/GroupProvider.java @@ -1,9 +1,9 @@ -package sh.okx.rankup.hook; - -import java.util.UUID; - -public interface GroupProvider { - boolean inGroup(UUID uuid, String group); - void addGroup(UUID uuid, String group); - void removeGroup(UUID uuid, String group); -} +package sh.okx.rankup.hook; + +import java.util.UUID; + +public interface GroupProvider { + boolean inGroup(UUID uuid, String group); + void addGroup(UUID uuid, String group); + void removeGroup(UUID uuid, String group); +} diff --git a/src/main/java/sh/okx/rankup/hook/PermissionGroupProvider.java b/src/main/java/sh/okx/rankup/hook/PermissionGroupProvider.java index 3990d30..b6dc5a4 100644 --- a/src/main/java/sh/okx/rankup/hook/PermissionGroupProvider.java +++ b/src/main/java/sh/okx/rankup/hook/PermissionGroupProvider.java @@ -1,32 +1,32 @@ -package sh.okx.rankup.hook; - -import java.util.UUID; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -public class PermissionGroupProvider implements GroupProvider { - - @Override - public boolean inGroup(UUID uuid, String group) { - Player player = getPlayer(uuid); - return player.hasPermission("rankup.rank." + group); - } - - @Override - public void addGroup(UUID uuid, String group) { - // no-op - } - - @Override - public void removeGroup(UUID uuid, String group) { - // no-op - } - - private Player getPlayer(UUID uuid) { - Player player = Bukkit.getPlayer(uuid); - if (player == null) { - throw new IllegalArgumentException("Player not online!"); - } - return player; - } -} +package sh.okx.rankup.hook; + +import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class PermissionGroupProvider implements GroupProvider { + + @Override + public boolean inGroup(UUID uuid, String group) { + Player player = getPlayer(uuid); + return player.hasPermission("rankup.rank." + group); + } + + @Override + public void addGroup(UUID uuid, String group) { + // no-op + } + + @Override + public void removeGroup(UUID uuid, String group) { + // no-op + } + + private Player getPlayer(UUID uuid) { + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + throw new IllegalArgumentException("Player not online!"); + } + return player; + } +} diff --git a/src/main/java/sh/okx/rankup/hook/VaultGroupProvider.java b/src/main/java/sh/okx/rankup/hook/VaultGroupProvider.java index 695b50b..068c427 100644 --- a/src/main/java/sh/okx/rankup/hook/VaultGroupProvider.java +++ b/src/main/java/sh/okx/rankup/hook/VaultGroupProvider.java @@ -1,44 +1,45 @@ -package sh.okx.rankup.hook; - -import java.util.Objects; -import java.util.UUID; -import net.milkbowl.vault.permission.Permission; -import org.bukkit.Bukkit; - -public class VaultGroupProvider implements GroupProvider { - private final Permission permission; - - public VaultGroupProvider(Permission permission) { - this.permission = permission; - } - - @Override - public boolean inGroup(UUID uuid, String group) { - Objects.requireNonNull(uuid); - Objects.requireNonNull(group); - - String[] playerGroups = permission.getPlayerGroups(null, Bukkit.getOfflinePlayer(uuid)); - for (String playerGroup : playerGroups) { - if (group.equalsIgnoreCase(playerGroup)) { - return true; - } - } - return false; - } - - @Override - public void addGroup(UUID uuid, String group) { - Objects.requireNonNull(uuid); - Objects.requireNonNull(group); - - permission.playerAddGroup(null, Bukkit.getOfflinePlayer(uuid), group); - } - - @Override - public void removeGroup(UUID uuid, String group) { - Objects.requireNonNull(uuid); - Objects.requireNonNull(group); - - permission.playerRemoveGroup(null, Bukkit.getOfflinePlayer(uuid), group); - } -} +package sh.okx.rankup.hook; + +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; + +import java.util.Objects; +import java.util.UUID; + +public class VaultGroupProvider implements GroupProvider { + private final Permission permission; + + public VaultGroupProvider(Permission permission) { + this.permission = permission; + } + + @Override + public boolean inGroup(UUID uuid, String group) { + Objects.requireNonNull(uuid); + Objects.requireNonNull(group); + + String[] playerGroups = permission.getPlayerGroups(null, Bukkit.getOfflinePlayer(uuid)); + for (String playerGroup : playerGroups) { + if (group.equalsIgnoreCase(playerGroup)) { + return true; + } + } + return false; + } + + @Override + public void addGroup(UUID uuid, String group) { + Objects.requireNonNull(uuid); + Objects.requireNonNull(group); + + permission.playerAddGroup(null, Bukkit.getOfflinePlayer(uuid), group); + } + + @Override + public void removeGroup(UUID uuid, String group) { + Objects.requireNonNull(uuid); + Objects.requireNonNull(group); + + permission.playerRemoveGroup(null, Bukkit.getOfflinePlayer(uuid), group); + } +} diff --git a/src/main/java/sh/okx/rankup/messages/MessageBuilder.java b/src/main/java/sh/okx/rankup/messages/MessageBuilder.java index 4bf8f6f..fcbb216 100644 --- a/src/main/java/sh/okx/rankup/messages/MessageBuilder.java +++ b/src/main/java/sh/okx/rankup/messages/MessageBuilder.java @@ -61,17 +61,34 @@ public class MessageBuilder { return this; } + public MessageBuilder replaceRanks(CommandSender player, Rank oldRank, Rank rank) { + replace(Variable.PLAYER, player.getName()); + replaceRanks(oldRank, rank); + return this; + } + public MessageBuilder replaceRanks(String rankName) { replace(Variable.RANK, rankName); return this; } + public MessageBuilder replaceRanks(Rank rank) { + replace(Variable.RANK, rank.getRank()); + return this; + } + public MessageBuilder replaceRanks(Rank oldRank, String rankName) { replaceRanks(rankName); replace(Variable.OLD_RANK, oldRank.getRank()); return this; } + public MessageBuilder replaceRanks(Rank oldRank, Rank rank) { + replaceRanks(rank); + replace(Variable.OLD_RANK, oldRank.getRank()); + return this; + } + public MessageBuilder replaceFromTo(Rank rank) { if (rank instanceof Prestige) { Prestige prestige = (Prestige) rank; diff --git a/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java b/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java index 57d0e24..bbf0d48 100644 --- a/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java +++ b/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java @@ -7,6 +7,7 @@ import sh.okx.rankup.RankupPlugin; 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 sh.okx.rankup.requirements.Requirement; @@ -30,12 +31,15 @@ public class RankupExpansion extends PlaceholderExpansion { params = params.toLowerCase(); Rankups rankups = plugin.getRankups(); - Rank rank = rankups.getByPlayer(player); + RankElement rankElement = rankups.getByPlayer(player); + Rank rank = rankElement == null ? null : rankElement.getRank(); Prestiges prestiges = plugin.getPrestiges(); + RankElement prestigeElement = null; Prestige prestige = null; if (prestiges != null) { - prestige = prestiges.getByPlayer(player); + prestigeElement = prestiges.getByPlayer(player); + prestige = prestigeElement == null ? null : prestigeElement.getRank(); } if (params.startsWith("requirement_")) { @@ -55,7 +59,7 @@ public class RankupExpansion extends PlaceholderExpansion { } return plugin.formatMoney(Math.max(0, amount)); } else if (params.startsWith("status_")) { - if (rankups.isLast(player) || rank.isIn(player)) { + if (rankElement != null && (!rankElement.hasNext() || rank.isIn(player))) { return getPlaceholder("status-complete"); } else { return getPlaceholder("status-incomplete"); @@ -65,16 +69,14 @@ public class RankupExpansion extends PlaceholderExpansion { switch (params) { case "current_prestige": requirePrestiging(prestiges, params); - if (prestiges.isLast(player)) { - return prestiges.getLast(); - } else if (prestige == null || prestige.getRank() == null) { + if (prestige == null || prestige.getRank() == null) { return getPlaceholder("no-prestige"); } else { return prestige.getRank(); } case "next_prestige": requirePrestiging(prestiges, params); - if (prestiges.isLast(player)) { + if (prestigeElement != null && !prestigeElement.hasNext()) { return getPlaceholder("highest-rank"); } return orElse(prestige, Prestige::getNext, prestiges.getFirst().getNext()); @@ -85,15 +87,13 @@ public class RankupExpansion extends PlaceholderExpansion { requirePrestiging(prestiges, params); return plugin.formatMoney(orElse(prestige, r -> r.isIn(player) ? r.getRequirement(player, "money").getValueDouble() : 0, 0D)); case "current_rank": - if (rankups.isLast(player)) { - return rankups.getLast(); - } else if (rank == null) { + if (rank == null) { return getPlaceholder("not-in-ladder"); } else { return rank.getRank(); } case "next_rank": - if (rankups.isLast(player)) { + if (rankElement != null && !rankElement.hasNext()) { return getPlaceholder("highest-rank"); } return orElsePlaceholder(rank, r -> orElsePlaceholder(rank, Rank::getNext, "highest-rank"), "not-in-ladder"); diff --git a/src/main/java/sh/okx/rankup/prestige/LastPrestige.java b/src/main/java/sh/okx/rankup/prestige/LastPrestige.java new file mode 100644 index 0000000..f3f4450 --- /dev/null +++ b/src/main/java/sh/okx/rankup/prestige/LastPrestige.java @@ -0,0 +1,43 @@ +package sh.okx.rankup.prestige; + +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.ranks.requirements.LastRankRequirements; +import sh.okx.rankup.requirements.NullRequirement; +import sh.okx.rankup.requirements.Requirement; + +import java.util.Collections; + +public class LastPrestige extends Prestige { + public LastPrestige(RankupPlugin plugin, String name) { + super(null, plugin, null, name, new LastRankRequirements(), Collections.emptyList(), null, null); + } + + @Override + public boolean isIn(Player player) { + return plugin.getPermissions().inGroup(player.getUniqueId(), rank); + } + + @Override + public boolean hasRequirements(Player player) { + return false; + } + + @Override + public Requirement getRequirement(Player player, String name) { + return new NullRequirement(); + } + + @Override + public void applyRequirements(Player player) { + } + + @Override + public void runCommands(Player player) { + } + + @Override + public boolean isEligible(Player player) { + return true; + } +} diff --git a/src/main/java/sh/okx/rankup/prestige/Prestige.java b/src/main/java/sh/okx/rankup/prestige/Prestige.java index a8401fa..f897e63 100644 --- a/src/main/java/sh/okx/rankup/prestige/Prestige.java +++ b/src/main/java/sh/okx/rankup/prestige/Prestige.java @@ -22,7 +22,7 @@ public class Prestige extends Rank { @Getter private final String to; - private Prestige(ConfigurationSection section, RankupPlugin plugin, String next, String rank, RankRequirements requirements, List commands, String from, String to) { + protected Prestige(ConfigurationSection section, RankupPlugin plugin, String next, String rank, RankRequirements requirements, List commands, String from, String to) { super(section, plugin, next, rank, requirements, commands); this.from = from; this.to = to; @@ -47,7 +47,7 @@ public class Prestige extends Rank { boolean inFrom = plugin.getPermissions().inGroup(player.getUniqueId(), from); if (rank == null && inFrom) { // not in any other prestiges - for (Prestige prestige : plugin.getPrestiges().getOrderedList()) { + for (Prestige prestige : plugin.getPrestiges().getTree()) { if (prestige != this && prestige.isIn(player)) { return false; } @@ -68,12 +68,7 @@ public class Prestige extends Rank { return false; } - public boolean isEligable(Player player) { + public boolean isEligible(Player player) { return plugin.getPermissions().inGroup(player.getUniqueId(), from); } - - @Override - public boolean isLast() { - return plugin.getPrestiges().getByName(next) == null; - } } diff --git a/src/main/java/sh/okx/rankup/prestige/Prestiges.java b/src/main/java/sh/okx/rankup/prestige/Prestiges.java index 1bc00dc..ce760e3 100644 --- a/src/main/java/sh/okx/rankup/prestige/Prestiges.java +++ b/src/main/java/sh/okx/rankup/prestige/Prestiges.java @@ -1,7 +1,8 @@ package sh.okx.rankup.prestige; import org.bukkit.configuration.file.FileConfiguration; -import sh.okx.rankup.RankList; +import sh.okx.rankup.ranks.RankElement; +import sh.okx.rankup.ranks.RankList; import sh.okx.rankup.RankupPlugin; public class Prestiges extends RankList { @@ -10,13 +11,9 @@ public class Prestiges extends RankList { } @Override - public Prestige getFirst() { - for (Prestige prestige : ranks) { - if (prestige.getRank() == null) { - return prestige; - } - } - throw new IllegalStateException("No prestige found for first prestige (first prestige is counted as a prestige without a rank set). " + - "Disable prestiges in config.yml if you don't want any."); + public void addLastRank(RankupPlugin plugin) { + RankElement last = getTree().last(); + last.setNext(new RankElement<>(new LastPrestige(plugin, last.getRank().getNext()), null)); } + } diff --git a/src/main/java/sh/okx/rankup/ranks/LastRank.java b/src/main/java/sh/okx/rankup/ranks/LastRank.java new file mode 100644 index 0000000..ecfa727 --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranks/LastRank.java @@ -0,0 +1,33 @@ +package sh.okx.rankup.ranks; + +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.ranks.requirements.LastRankRequirements; +import sh.okx.rankup.requirements.NullRequirement; +import sh.okx.rankup.requirements.Requirement; + +import java.util.Collections; + +public class LastRank extends Rank { + public LastRank(RankupPlugin plugin, String name) { + super(null, plugin, null, name, new LastRankRequirements(), Collections.emptyList()); + } + + @Override + public boolean hasRequirements(Player player) { + return false; + } + + @Override + public Requirement getRequirement(Player player, String name) { + return new NullRequirement(); + } + + @Override + public void applyRequirements(Player player) { + } + + @Override + public void runCommands(Player player) { + } +} diff --git a/src/main/java/sh/okx/rankup/ranks/Rank.java b/src/main/java/sh/okx/rankup/ranks/Rank.java index 88d09c7..83fa9b3 100644 --- a/src/main/java/sh/okx/rankup/ranks/Rank.java +++ b/src/main/java/sh/okx/rankup/ranks/Rank.java @@ -1,11 +1,9 @@ package sh.okx.rankup.ranks; -import java.util.List; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.ToString; import me.clip.placeholderapi.PlaceholderAPI; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; @@ -15,8 +13,9 @@ import sh.okx.rankup.messages.MessageBuilder; import sh.okx.rankup.ranks.requirements.RankRequirements; import sh.okx.rankup.requirements.Requirement; +import java.util.List; + @EqualsAndHashCode -@ToString @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class Rank { @Getter @@ -34,10 +33,6 @@ public class Rank { return plugin.getPermissions().inGroup(player.getUniqueId(), rank); } - public boolean isLast() { - return plugin.getRankups().getByName(next) == null; - } - public boolean hasRequirements(Player player) { return requirements.hasRequirements(player); } @@ -60,4 +55,13 @@ public class Rank { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), string); } } + + @Override + public String toString() { + return "Rank{" + + "next='" + next + '\'' + + ", rank='" + rank + '\'' + + ", commands=" + commands + + '}'; + } } diff --git a/src/main/java/sh/okx/rankup/ranks/RankElement.java b/src/main/java/sh/okx/rankup/ranks/RankElement.java new file mode 100644 index 0000000..571b586 --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranks/RankElement.java @@ -0,0 +1,31 @@ +package sh.okx.rankup.ranks; + +import lombok.Getter; + +import java.util.Objects; + +@Getter +public class RankElement { + private boolean rootNode = true; + private final T rank; + private RankElement next; + + public RankElement(T rank, RankElement next) { + Objects.requireNonNull(rank); + this.rank = rank; + this.next = next; + } + + public void setRootNode(boolean rootNode) { + this.rootNode = rootNode; + } + + public boolean hasNext() { + return next != null; + } + + public void setNext(RankElement next) { + this.next = next; + this.next.setRootNode(false); + } +} diff --git a/src/main/java/sh/okx/rankup/ranks/RankList.java b/src/main/java/sh/okx/rankup/ranks/RankList.java new file mode 100644 index 0000000..61478c1 --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranks/RankList.java @@ -0,0 +1,125 @@ +package sh.okx.rankup.ranks; + +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; + +import java.util.*; +import java.util.function.Function; + +public abstract class RankList { + + protected RankupPlugin plugin; + @Getter + protected FileConfiguration config; + @Getter + private RankTree tree; + + public RankList(RankupPlugin plugin, FileConfiguration config, + Function deserializer) { + this.plugin = plugin; + this.config = config; + List> rankElements = new ArrayList<>(); + for (Map.Entry entry : config.getValues(false).entrySet()) { + ConfigurationSection rankSection = (ConfigurationSection) entry.getValue(); + validateSection(rankSection); + T apply = deserializer.apply(rankSection); + if (apply != null) { + // find next + rankElements.add(findNext(apply, rankElements)); + } + } + + for (RankElement rankElement : rankElements) { + if (rankElement.isRootNode()) { + if (tree == null) { + tree = new RankTree<>(rankElement); + addLastRank(plugin); + } else { + plugin.getLogger().severe("Multiple root rankup nodes detected (a root rankup nodes is a rankup that does not have anything that ranks up to it). This may lead to inconsistent behaviour."); + plugin.getLogger().severe("Conflicting root node: " + rankElement.getRank() + ". Using root node: " + tree.getFirst().getRank()); + } + } + } + } + + public abstract void addLastRank(RankupPlugin plugin); + + private RankElement findNext(T rank, List> rankElements) { + Objects.requireNonNull(rank); + + RankElement currentElement = new RankElement<>(rank, null); + + for (RankElement rankElement : rankElements) { + T rank1 = rankElement.getRank(); + if (rank1.getRank() != null + && rank1.getRank().equalsIgnoreCase(rank.getNext())) { + // current rank element is the next rank + currentElement.setNext(rankElement); + } else if (rank1.getNext() != null + && rank1.getNext().equalsIgnoreCase(rank.getRank())) { + rankElement.setNext(currentElement); + } + } + return currentElement; + } + + protected void validateSection(ConfigurationSection section) { + String name = "'" + section.getName() + "'"; + /*if (section.getConfigurationSection("requirements") != null) { + throw new IllegalArgumentException( + "Rankup/prestige section " + name + " is using the old requirements system.\n" + + "Instead of a configuration section, it is now a list of strings.\n" + + "For example, instead of \"requirements: money: 1000\" you should use \"requirements: - 'money 1000'\"."); + }*/ + Set keys = section.getKeys(false); + if (keys.size() == 1 && keys.iterator().next().equalsIgnoreCase("rank")) { + throw new IllegalArgumentException( + "Having a final rank (for example: \"Z: rank: 'Z'\") from 3.4.2 or earlier should no longer be used.\n" + + + "It is safe to just delete the final rank " + name + ""); + } else if (!section.contains("requirements")) { + throw new IllegalArgumentException("Rank " + name + " does not have any requirements."); + } + } + + public T getFirst() { + return tree.getFirst().getRank(); + } + + public T getByName(String name) { + if (name == null) { + return null; + } + for (T rank : tree) { + if (name.equalsIgnoreCase(rank.getRank())) { + return rank; + } + } + return null; + } + + public RankElement getByPlayer(Player player) { + List> list = tree.asList(); + Collections.reverse(list); + for (RankElement t : list) { + if (t.getRank().isIn(player)) { + return t; + } + } + return null; + } + + public T getRankByPlayer(Player player) { + List> list = tree.asList(); + Collections.reverse(list); + for (RankElement t : list) { + if (t.getRank().isIn(player)) { + return t.getRank(); + } + } + return null; + } +} diff --git a/src/main/java/sh/okx/rankup/ranks/RankTree.java b/src/main/java/sh/okx/rankup/ranks/RankTree.java new file mode 100644 index 0000000..40f0885 --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranks/RankTree.java @@ -0,0 +1,65 @@ +package sh.okx.rankup.ranks; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class RankTree implements Iterable { + private final RankElement first; + + public RankTree(RankElement first) { + this.first = first; + } + + public RankElement getFirst() { + return first; + } + + public int length() { + int len = 0; + RankElement elem = first; + while (elem != null) { + len++; + elem = elem.getNext(); + } + return len; + } + + @NotNull + @Override + public Iterator iterator() { + return new Iterator() { + private RankElement element = first; + @Override + public boolean hasNext() { + return element.hasNext(); + } + + @Override + public T next() { + element = element.getNext(); + return element.getRank(); + } + }; + } + + public List> asList() { + List> ranks = new ArrayList<>(); + RankElement elem = first; + while (elem != null) { + ranks.add(elem); + elem = elem.getNext(); + } + return ranks; + } + + public RankElement last() { + RankElement elem = first; + while (elem.hasNext()) { + elem = elem.getNext(); + } + return elem; + } +} diff --git a/src/main/java/sh/okx/rankup/ranks/Rankup.java b/src/main/java/sh/okx/rankup/ranks/Rankup.java index ecd06df..129bfe3 100644 --- a/src/main/java/sh/okx/rankup/ranks/Rankup.java +++ b/src/main/java/sh/okx/rankup/ranks/Rankup.java @@ -1,13 +1,14 @@ package sh.okx.rankup.ranks; -import java.util.List; import org.bukkit.configuration.ConfigurationSection; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.ranks.requirements.RankRequirements; import sh.okx.rankup.ranks.requirements.RankRequirementsFactory; +import java.util.List; + public class Rankup extends Rank { - public static Rank deserialize(RankupPlugin plugin, ConfigurationSection section) { + public static Rankup deserialize(RankupPlugin plugin, ConfigurationSection section) { String next = section.getString("next"); String rank = section.getString("rank"); @@ -16,15 +17,15 @@ public class Rankup extends Rank { return null; } - return new Rank(section, plugin, + return new Rankup(section, + plugin, next, rank, RankRequirementsFactory.getRequirements(plugin, section), section.getStringList("commands")); } - protected Rankup(ConfigurationSection section, - RankupPlugin plugin, String next, String rank, + protected Rankup(ConfigurationSection section, RankupPlugin plugin, String next, String rank, RankRequirements requirements, List commands) { super(section, plugin, next, rank, requirements, commands); diff --git a/src/main/java/sh/okx/rankup/ranks/Rankups.java b/src/main/java/sh/okx/rankup/ranks/Rankups.java index 77c1424..8038eb8 100644 --- a/src/main/java/sh/okx/rankup/ranks/Rankups.java +++ b/src/main/java/sh/okx/rankup/ranks/Rankups.java @@ -1,11 +1,16 @@ package sh.okx.rankup.ranks; import org.bukkit.configuration.file.FileConfiguration; -import sh.okx.rankup.RankList; import sh.okx.rankup.RankupPlugin; public class Rankups extends RankList { public Rankups(RankupPlugin plugin, FileConfiguration config) { super(plugin, config, section -> Rankup.deserialize(plugin, section)); } + + @Override + public void addLastRank(RankupPlugin plugin) { + RankElement last = getTree().last(); + last.setNext(new RankElement<>(new LastRank(plugin, last.getRank().getNext()), null)); + } } diff --git a/src/main/java/sh/okx/rankup/ranks/requirements/LastRankRequirements.java b/src/main/java/sh/okx/rankup/ranks/requirements/LastRankRequirements.java new file mode 100644 index 0000000..c05f680 --- /dev/null +++ b/src/main/java/sh/okx/rankup/ranks/requirements/LastRankRequirements.java @@ -0,0 +1,29 @@ +package sh.okx.rankup.ranks.requirements; + +import java.util.Collections; +import java.util.Set; +import org.bukkit.entity.Player; +import sh.okx.rankup.requirements.Requirement; + +public class LastRankRequirements implements RankRequirements { + + @Override + public Set getRequirements(Player player) { + return Collections.emptySet(); + } + + @Override + public boolean hasRequirements(Player player) { + return false; + } + + @Override + public Requirement getRequirement(Player player, String name) { + return null; + } + + @Override + public void applyRequirements(Player player) { + + } +} 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 740c011..e1d198e 100644 --- a/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java +++ b/src/main/java/sh/okx/rankup/ranks/requirements/PrestigeListRankRequirements.java @@ -1,14 +1,15 @@ package sh.okx.rankup.ranks.requirements; -import java.util.Map; -import java.util.Objects; -import java.util.Set; 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; @@ -49,7 +50,7 @@ public class PrestigeListRankRequirements implements RankRequirements { return defaultRequirements; } - for (Prestige prestige : prestiges.getOrderedList()) { + for (Prestige prestige : prestiges.getTree()) { String next = prestige.getNext(); if(plugin.getPermissions().inGroup(player.getUniqueId(), next)) { RankRequirements rankRequirements = this.requirements.get(next.toLowerCase()); diff --git a/src/main/java/sh/okx/rankup/requirements/NullRequirement.java b/src/main/java/sh/okx/rankup/requirements/NullRequirement.java new file mode 100644 index 0000000..92be598 --- /dev/null +++ b/src/main/java/sh/okx/rankup/requirements/NullRequirement.java @@ -0,0 +1,24 @@ +package sh.okx.rankup.requirements; + +import org.bukkit.entity.Player; + +public class NullRequirement extends Requirement { + public NullRequirement() { + super(null, null); + } + + @Override + public boolean check(Player player) { + return false; + } + + @Override + public Requirement clone() { + return this; + } + + @Override + public double getTotal(Player player) { + return 0; + } +} diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/TokensDeductibleRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/tokenmanager/TokensDeductibleRequirement.java similarity index 81% rename from src/main/java/sh/okx/rankup/requirements/requirement/TokensDeductibleRequirement.java rename to src/main/java/sh/okx/rankup/requirements/requirement/tokenmanager/TokensDeductibleRequirement.java index 364526a..2b332c0 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/TokensDeductibleRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/tokenmanager/TokensDeductibleRequirement.java @@ -1,9 +1,8 @@ -package sh.okx.rankup.requirements.requirement; +package sh.okx.rankup.requirements.requirement.tokenmanager; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.requirements.DeductibleRequirement; -import sh.okx.rankup.requirements.requirement.tokenmanager.TokensRequirement; public class TokensDeductibleRequirement extends TokensRequirement implements DeductibleRequirement { public TokensDeductibleRequirement(RankupPlugin plugin, String name) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java index 5c5e0d0..721cf1d 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java @@ -1,32 +1,32 @@ -package sh.okx.rankup.requirements.requirement.votingplugin; - -import com.Ben12345rocks.VotingPlugin.Objects.User; -import com.Ben12345rocks.VotingPlugin.UserManager.UserManager; -import org.bukkit.entity.Player; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.requirements.DeductibleRequirement; -import sh.okx.rankup.requirements.Requirement; - -public class VotingPluginPointsDeductibleRequirement extends VotingPluginPointsRequirement implements DeductibleRequirement { - - public VotingPluginPointsDeductibleRequirement(RankupPlugin plugin, String name) { - super(plugin, name); - } - - protected VotingPluginPointsDeductibleRequirement(Requirement clone) { - super(clone); - } - - @Override - public void apply(Player player, double multiplier) { - User user = UserManager.getInstance().getVotingPluginUser(player); - if(!user.removePoints(getValueInt())) { - plugin.getLogger().warning("Unable to remove VotingPlugin points"); - } - } - - @Override - public Requirement clone() { - return new VotingPluginPointsDeductibleRequirement(this); - } -} +package sh.okx.rankup.requirements.requirement.votingplugin; + +import com.Ben12345rocks.VotingPlugin.Objects.User; +import com.Ben12345rocks.VotingPlugin.UserManager.UserManager; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.requirements.DeductibleRequirement; +import sh.okx.rankup.requirements.Requirement; + +public class VotingPluginPointsDeductibleRequirement extends VotingPluginPointsRequirement implements DeductibleRequirement { + + public VotingPluginPointsDeductibleRequirement(RankupPlugin plugin, String name) { + super(plugin, name); + } + + protected VotingPluginPointsDeductibleRequirement(Requirement clone) { + super(clone); + } + + @Override + public void apply(Player player, double multiplier) { + User user = UserManager.getInstance().getVotingPluginUser(player); + if(!user.removePoints(getValueInt())) { + plugin.getLogger().warning("Unable to remove VotingPlugin points"); + } + } + + @Override + public Requirement clone() { + return new VotingPluginPointsDeductibleRequirement(this); + } +} diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java index bd5aa33..6ffb45f 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java @@ -1,28 +1,28 @@ -package sh.okx.rankup.requirements.requirement.votingplugin; - -import com.Ben12345rocks.VotingPlugin.UserManager.UserManager; -import org.bukkit.entity.Player; -import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.requirements.ProgressiveRequirement; -import sh.okx.rankup.requirements.Requirement; - -public class VotingPluginPointsRequirement extends ProgressiveRequirement { - - public VotingPluginPointsRequirement(RankupPlugin plugin, String name) { - super(plugin, name); - } - - protected VotingPluginPointsRequirement(Requirement clone) { - super(clone); - } - - @Override - public double getProgress(Player player) { - return UserManager.getInstance().getVotingPluginUser(player).getPoints(); - } - - @Override - public Requirement clone() { - return new VotingPluginPointsRequirement(this); - } -} +package sh.okx.rankup.requirements.requirement.votingplugin; + +import com.Ben12345rocks.VotingPlugin.UserManager.UserManager; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankupPlugin; +import sh.okx.rankup.requirements.ProgressiveRequirement; +import sh.okx.rankup.requirements.Requirement; + +public class VotingPluginPointsRequirement extends ProgressiveRequirement { + + public VotingPluginPointsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); + } + + protected VotingPluginPointsRequirement(Requirement clone) { + super(clone); + } + + @Override + public double getProgress(Player player) { + return UserManager.getInstance().getVotingPluginUser(player).getPoints(); + } + + @Override + public Requirement clone() { + return new VotingPluginPointsRequirement(this); + } +}