From 82078dd31badaf4eb2430b6741373c454ef58dad Mon Sep 17 00:00:00 2001 From: okx-code Date: Sun, 2 Sep 2018 15:36:08 +0100 Subject: [PATCH] add /prestige --- build.gradle | 2 +- src/main/java/sh/okx/rankup/RankList.java | 71 ++++++++++ src/main/java/sh/okx/rankup/Rankup.java | 133 +++++++++++++++--- .../okx/rankup/commands/PrestigeCommand.java | 69 +++++++++ ...RankListCommand.java => RanksCommand.java} | 16 +-- .../sh/okx/rankup/commands/RankupCommand.java | 6 +- src/main/java/sh/okx/rankup/gui/Gui.java | 22 ++- .../java/sh/okx/rankup/gui/GuiListener.java | 6 +- .../java/sh/okx/rankup/messages/Message.java | 4 +- .../okx/rankup/messages/MessageBuilder.java | 22 +-- .../java/sh/okx/rankup/messages/Variable.java | 2 + .../okx/rankup/placeholders/Placeholders.java | 8 +- .../java/sh/okx/rankup/prestige/Prestige.java | 63 ++++++++- .../sh/okx/rankup/prestige/Prestiges.java | 20 +++ .../java/sh/okx/rankup/ranks/Prestige.java | 4 - src/main/java/sh/okx/rankup/ranks/Rank.java | 54 +++---- .../java/sh/okx/rankup/ranks/Rankups.java | 75 +--------- .../requirements/OperationRegistry.java | 5 +- .../requirements/RequirementRegistry.java | 28 ++++ src/main/resources/config.yml | 7 +- src/main/resources/messages.yml | 5 +- src/main/resources/plugin.yml | 8 +- src/main/resources/prestiges.yml | 20 +-- 23 files changed, 469 insertions(+), 181 deletions(-) create mode 100644 src/main/java/sh/okx/rankup/RankList.java create mode 100644 src/main/java/sh/okx/rankup/commands/PrestigeCommand.java rename src/main/java/sh/okx/rankup/commands/{RankListCommand.java => RanksCommand.java} (83%) create mode 100644 src/main/java/sh/okx/rankup/prestige/Prestiges.java delete mode 100644 src/main/java/sh/okx/rankup/ranks/Prestige.java diff --git a/build.gradle b/build.gradle index 9d88d8d..7405ad1 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'sh.okx' -version '3.0-alpha.19' +version '3.0-alpha.20' sourceCompatibility = 1.8 diff --git a/src/main/java/sh/okx/rankup/RankList.java b/src/main/java/sh/okx/rankup/RankList.java new file mode 100644 index 0000000..a12c16a --- /dev/null +++ b/src/main/java/sh/okx/rankup/RankList.java @@ -0,0 +1,71 @@ +package sh.okx.rankup; + +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; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +public class RankList { + @Getter + protected final FileConfiguration config; + protected final Set ranks = new HashSet<>(); + + public RankList(Rankup plugin, FileConfiguration config, Function deserializer) { + this.config = config; + for (Map.Entry entry : config.getValues(false).entrySet()) { + ConfigurationSection rankSection = (ConfigurationSection) entry.getValue(); + ranks.add(deserializer.apply(rankSection)); + } + } + + public T getFirst() { + OUTER: + for (T rank : ranks) { + // see if anything ranks up to this + for (T rank0 : ranks) { + if (!rank0.isLast() && rank0.getNext().equals(rank.getName())) { + continue OUTER; + } + } + // nothing ranks up to this + return rank; + } + return null; + } + + public T getByName(String name) { + for (T rank : ranks) { + if (rank.getName().equalsIgnoreCase(name)) { + return rank; + } + } + return null; + } + + public T getByPlayer(Player player) { + return ranks.stream() + .filter(rank -> rank.isIn(player)) + .findFirst() + .orElse(null); + } + + public T next(T rank) { + if (rank.isLast()) { + return null; + } + + for (T nextRank : ranks) { + if (rank.getNext().equalsIgnoreCase(nextRank.getName())) { + return nextRank; + } + } + // this shouldn't happen but whatever + return null; + } +} diff --git a/src/main/java/sh/okx/rankup/Rankup.java b/src/main/java/sh/okx/rankup/Rankup.java index 2351fc3..8e320bc 100644 --- a/src/main/java/sh/okx/rankup/Rankup.java +++ b/src/main/java/sh/okx/rankup/Rankup.java @@ -15,7 +15,8 @@ import org.bukkit.inventory.InventoryView; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; import sh.okx.rankup.commands.InfoCommand; -import sh.okx.rankup.commands.RankListCommand; +import sh.okx.rankup.commands.PrestigeCommand; +import sh.okx.rankup.commands.RanksCommand; import sh.okx.rankup.commands.RankupCommand; import sh.okx.rankup.gui.Gui; import sh.okx.rankup.gui.GuiListener; @@ -23,6 +24,8 @@ import sh.okx.rankup.messages.Message; import sh.okx.rankup.messages.MessageBuilder; import sh.okx.rankup.messages.Variable; 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.Rankups; import sh.okx.rankup.requirements.OperationRegistry; @@ -63,9 +66,11 @@ public class Rankup extends JavaPlugin { @Getter private Rankups rankups; @Getter + private Prestiges prestiges; + @Getter private Placeholders placeholders; /** - * Players who cannot rankup for a certain amount of time. + * Players who cannot rankup/prestige for a certain amount of time. */ private Map cooldowns; @@ -85,8 +90,12 @@ public class Rankup extends JavaPlugin { }); if (config.getBoolean("ranks")) { - getCommand("ranks").setExecutor(new RankListCommand(this)); + getCommand("ranks").setExecutor(new RanksCommand(this)); } + if(prestiges != null) { + getCommand("prestige").setExecutor(new PrestigeCommand(this)); + } + getCommand("rankup").setExecutor(new RankupCommand(this)); getCommand("rankup3").setExecutor(new InfoCommand(this)); getServer().getPluginManager().registerEvents(new GuiListener(this), this); @@ -138,6 +147,9 @@ public class Rankup extends JavaPlugin { messages = loadConfig("messages.yml"); config = loadConfig("config.yml"); rankups = new Rankups(this, loadConfig("rankups.yml")); + if(config.getBoolean("prestige")) { + prestiges = new Prestiges(this, loadConfig("prestiges.yml")); + } } private FileConfiguration loadConfig(String name) { @@ -203,13 +215,19 @@ public class Rankup extends JavaPlugin { return MessageBuilder.of(messages, message); } + private void applyCooldown(Player player) { + if (config.getInt("cooldown") > 0) { + cooldowns.put(player, System.currentTimeMillis()); + } + } + public void rankup(Player player) { if (!checkRankup(player)) { return; } - Rank oldRank = rankups.getRank(player); - Rank rank = rankups.nextRank(oldRank); + Rank oldRank = rankups.getByPlayer(player); + Rank rank = rankups.next(oldRank); oldRank.applyRequirements(player); @@ -218,19 +236,15 @@ public class Rankup extends JavaPlugin { getMessage(oldRank, Message.SUCCESS_PUBLIC) .failIfEmpty() - .replaceAll(player, oldRank, rank) + .replaceRanks(player, oldRank, rank) .broadcast(); getMessage(oldRank, Message.SUCCESS_PRIVATE) .failIfEmpty() - .replaceAll(player, oldRank, rank) + .replaceRanks(player, oldRank, rank) .send(player); oldRank.runCommands(player, rank); - - // apply cooldown last - if (config.getInt("cooldown") > 0) { - cooldowns.put(player, System.currentTimeMillis()); - } + applyCooldown(player); } /** @@ -241,20 +255,27 @@ public class Rankup extends JavaPlugin { * @return true if the player can rankup, false otherwise */ public boolean checkRankup(Player player) { - Rank rank = rankups.getRank(player); + Rank rank = rankups.getByPlayer(player); if (rank == null) { // check if in ladder getMessage(Message.NOT_IN_LADDER) .replace(Variable.PLAYER, player.getName()) .send(player); return false; - } else if (rank.isLastRank()) { // check if they are at the highest rank - getMessage(rank, Message.NO_RANKUP) - .replaceAll(player, rank) + } else if (rank.isLast()) { // check if they are at the highest rank + if(prestiges != null) { + Prestige prestige = prestiges.getByPlayer(player); + if(prestige.isLast()) { + getMessage(rank, Message.NO_RANKUP); + } + } + getMessage(rank, prestiges == null ? Message.NO_RANKUP : + prestiges.getByPlayer(player).isLast() ? Message.NO_RANKUP : Message.MUST_PRESTIGE) + .replaceRanks(player, rank) .send(player); return false; - } else if (!rank.checkRequirements(player)) { // check if they can afford it + } else if (!rank.hasRequirements(player)) { // check if they can afford it replaceMoneyRequirements(getMessage(rank, Message.REQUIREMENTS_NOT_MET) - .replaceAll(player, rank, rankups.nextRank(rank)), player, rank) + .replaceRanks(player, rank, rankups.next(rank)), player, rank) .send(player); return false; } else if (cooldowns.containsKey(player)) { @@ -265,7 +286,79 @@ public class Rankup extends JavaPlugin { long secondsLeft = (long) Math.ceil(timeLeft / 1000f); getMessage(rank, secondsLeft > 1 ? Message.COOLDOWN_PLURAL : Message.COOLDOWN_SINGULAR) .failIfEmpty() - .replaceAll(player, rank) + .replaceRanks(player, rank) + .replace(Variable.SECONDS, secondsLeft) + .send(player); + return false; + } + // cooldown has expired so remove it + cooldowns.remove(player); + } + + return true; + } + + public void prestige(Player player) { + if (!checkPrestige(player)) { + return; + } + + Prestige oldPrestige = prestiges.getByPlayer(player); + Prestige prestige = prestiges.next(oldPrestige); + + oldPrestige.applyRequirements(player); + + permissions.playerRemoveGroup(null, player, oldPrestige.getFrom()); + permissions.playerAddGroup(null, player, oldPrestige.getTo()); + if(oldPrestige.getRank() != null) { + permissions.playerRemoveGroup(null, player, oldPrestige.getRank()); + } + permissions.playerAddGroup(null, player, prestige.getRank()); + + getMessage(oldPrestige, Message.SUCCESS_PUBLIC) + .failIfEmpty() + .replaceRanks(player, oldPrestige, prestige) + .replaceFromTo(oldPrestige) + .broadcast(); + getMessage(oldPrestige, Message.SUCCESS_PRIVATE) + .failIfEmpty() + .replaceRanks(player, oldPrestige, prestige) + .replaceFromTo(oldPrestige) + .send(player); + + oldPrestige.runCommands(player, prestige); + applyCooldown(player); + } + + public boolean checkPrestige(Player player) { + Prestige prestige = prestiges.getByPlayer(player); + if (!prestige.isEligable(player)) { // check if in ladder + getMessage(Message.NOT_HIGH_ENOUGH) + .replace(Variable.PLAYER, player.getName()) + .send(player); + return false; + } else if (prestige.isLast()) { // check if they are at the highest rank + getMessage(prestige, Message.NO_RANKUP) + .replaceRanks(player, prestige) + .replaceFromTo(prestige) + .send(player); + return false; + } else if (!prestige.hasRequirements(player)) { // check if they can afford it + replaceMoneyRequirements(getMessage(prestige, Message.REQUIREMENTS_NOT_MET) + .replaceRanks(player, prestige, prestiges.next(prestige)), player, prestige) + .replaceFromTo(prestige) + .send(player); + return false; + } else if (cooldowns.containsKey(player)) { + long time = System.currentTimeMillis() - cooldowns.get(player); + // if time passed is less than the cooldown + long timeLeft = (config.getInt("cooldown") * 1000) - time; + if (timeLeft > 0) { + long secondsLeft = (long) Math.ceil(timeLeft / 1000f); + getMessage(prestige, secondsLeft > 1 ? Message.COOLDOWN_PLURAL : Message.COOLDOWN_SINGULAR) + .failIfEmpty() + .replaceRanks(player, prestige) + .replaceFromTo(prestige) .replace(Variable.SECONDS, secondsLeft) .send(player); return false; @@ -280,7 +373,7 @@ public class Rankup extends JavaPlugin { public MessageBuilder replaceMoneyRequirements(MessageBuilder builder, CommandSender sender, Rank rank) { Requirement money = rank.getRequirement("money"); Double amount = null; - if (sender instanceof Player && rank.isInRank((Player) sender)) { + if (sender instanceof Player && rank.isIn((Player) sender)) { if (money != null && economy != null) { amount = money.getRemaining((Player) sender); } diff --git a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java new file mode 100644 index 0000000..0e37fbf --- /dev/null +++ b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java @@ -0,0 +1,69 @@ +package sh.okx.rankup.commands; + +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.Rankup; +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 java.util.Map; +import java.util.WeakHashMap; + +public class PrestigeCommand implements CommandExecutor { + private final Map confirming = new WeakHashMap<>(); + + private final Rankup plugin; + + public PrestigeCommand(Rankup plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + // check if player + if (!(sender instanceof Player)) { + return false; + } + Player player = (Player) sender; + + Prestiges prestiges = plugin.getPrestiges(); + Prestige prestige = prestiges.getByPlayer(player); + if (!plugin.checkPrestige(player)) { + return true; + } + + 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.prestige(player); + return true; + } + } + + switch (confirmationType) { + case "text": + confirming.put(player, System.currentTimeMillis()); + plugin.replaceMoneyRequirements(plugin.getMessage(prestige, Message.CONFIRMATION) + .replaceRanks(player, prestige, prestiges.next(prestige)), player, prestige) + .replaceFromTo(prestige) + .send(player); + break; + case "gui": + Gui.of(player, prestige, prestiges.next(prestige), plugin).open(player); + break; + case "none": + plugin.prestige(player); + break; + default: + throw new IllegalArgumentException("Invalid confirmation type " + confirmationType); + } + return true; + } +} diff --git a/src/main/java/sh/okx/rankup/commands/RankListCommand.java b/src/main/java/sh/okx/rankup/commands/RanksCommand.java similarity index 83% rename from src/main/java/sh/okx/rankup/commands/RankListCommand.java rename to src/main/java/sh/okx/rankup/commands/RanksCommand.java index a0267fc..6d4e74b 100644 --- a/src/main/java/sh/okx/rankup/commands/RankListCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RanksCommand.java @@ -6,14 +6,14 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import sh.okx.rankup.Rankup; +import sh.okx.rankup.ranks.Rankups; import sh.okx.rankup.messages.Message; import sh.okx.rankup.messages.MessageBuilder; import sh.okx.rankup.messages.Variable; import sh.okx.rankup.ranks.Rank; -import sh.okx.rankup.ranks.Rankups; @RequiredArgsConstructor -public class RankListCommand implements CommandExecutor { +public class RanksCommand implements CommandExecutor { private final Rankup plugin; @Override @@ -21,15 +21,15 @@ public class RankListCommand implements CommandExecutor { Rankups rankups = plugin.getRankups(); Rank playerRank = null; if (sender instanceof Player) { - playerRank = rankups.getRank((Player) sender); + playerRank = rankups.getByPlayer((Player) sender); } sendHeaderFooter(sender, playerRank, Message.RANKS_HEADER); Message message = playerRank == null ? Message.RANKS_INCOMPLETE : Message.RANKS_COMPLETE; - Rank rank = rankups.getFirstRank(); + Rank rank = rankups.getFirst(); do { - Rank next = rankups.nextRank(rank); + Rank next = rankups.next(rank); if (rank.equals(playerRank)) { sendMessage(sender, Message.RANKS_CURRENT, rank, next); message = Message.RANKS_INCOMPLETE; @@ -37,7 +37,7 @@ public class RankListCommand implements CommandExecutor { sendMessage(sender, message, rank, next); } rank = next; - } while (!rank.isLastRank()); + } while (!rank.isLast()); sendHeaderFooter(sender, playerRank, Message.RANKS_FOOTER); return true; @@ -49,14 +49,14 @@ public class RankListCommand implements CommandExecutor { if (rank == null) { builder.replace(Variable.PLAYER, sender.getName()); } else { - builder.replaceAll(sender, rank); + builder.replaceRanks(sender, rank); } builder.send(sender); } private void sendMessage(CommandSender player, Message message, Rank oldRank, Rank rank) { plugin.replaceMoneyRequirements(plugin.getMessage(oldRank, message) - .replaceAll(player, oldRank, rank), player, oldRank) + .replaceRanks(player, oldRank, rank), player, oldRank) .send(player); } } diff --git a/src/main/java/sh/okx/rankup/commands/RankupCommand.java b/src/main/java/sh/okx/rankup/commands/RankupCommand.java index afe73f0..e375554 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -34,7 +34,7 @@ public class RankupCommand implements CommandExecutor { Player player = (Player) sender; Rankups rankups = plugin.getRankups(); - Rank rank = rankups.getRank(player); + Rank rank = rankups.getByPlayer(player); if (!plugin.checkRankup(player)) { return true; } @@ -55,11 +55,11 @@ public class RankupCommand implements CommandExecutor { case "text": confirming.put(player, System.currentTimeMillis()); plugin.replaceMoneyRequirements(plugin.getMessage(rank, Message.CONFIRMATION) - .replaceAll(player, rank, rankups.nextRank(rank)), player, rank) + .replaceRanks(player, rank, rankups.next(rank)), player, rank) .send(player); break; case "gui": - Gui.of(player, rank, rankups.nextRank(rank), plugin).open(player); + Gui.of(player, rank, rankups.next(rank), plugin).open(player); break; case "none": plugin.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 3a3d167..5c351b6 100644 --- a/src/main/java/sh/okx/rankup/gui/Gui.java +++ b/src/main/java/sh/okx/rankup/gui/Gui.java @@ -15,6 +15,7 @@ import org.bukkit.inventory.meta.ItemMeta; import sh.okx.rankup.Rankup; 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 java.util.Arrays; @@ -28,6 +29,8 @@ public class Gui implements InventoryHolder { private ItemStack rankup; @Getter private ItemStack cancel; + @Getter + private boolean prestige; public static Gui of(Player player, Rank oldRank, Rank rank, Rankup plugin) { ConfigurationSection config = plugin.getConfig().getConfigurationSection("gui"); @@ -39,11 +42,18 @@ public class Gui implements InventoryHolder { Gui gui = new Gui(); gui.rankup = getItem(config.getConfigurationSection("rankup"), player, oldRank, rank); gui.cancel = getItem(config.getConfigurationSection("cancel"), player, oldRank, rank); - Inventory inventory = Bukkit.createInventory(gui, - items.length, - plugin.getMessage(rank, Message.TITLE) - .replaceAll(player, oldRank, rank) - .toString()); + + MessageBuilder builder = plugin.getMessage(rank, Message.TITLE) + .replaceRanks(player, oldRank, rank); + if(oldRank instanceof Prestige) { + gui.prestige = true; + builder.replaceFromTo((Prestige) oldRank); + } else { + gui.prestige = false; + } + + + Inventory inventory = Bukkit.createInventory(gui, items.length, builder.toString()); inventory.setContents(items); gui.inventory = inventory; return gui; @@ -90,7 +100,7 @@ public class Gui implements InventoryHolder { private static String format(String message, Player player, Rank oldRank, Rank rank) { return new MessageBuilder(ChatColor.translateAlternateColorCodes('&', message)) - .replaceAll(player, oldRank, rank) + .replaceRanks(player, oldRank, rank) .toString(); } diff --git a/src/main/java/sh/okx/rankup/gui/GuiListener.java b/src/main/java/sh/okx/rankup/gui/GuiListener.java index e4897b3..c6d398e 100644 --- a/src/main/java/sh/okx/rankup/gui/GuiListener.java +++ b/src/main/java/sh/okx/rankup/gui/GuiListener.java @@ -28,7 +28,11 @@ public class GuiListener implements Listener { if (gui.getRankup().isSimilar(e.getCurrentItem())) { Bukkit.getScheduler().runTask(plugin, player::closeInventory); - plugin.rankup(player); + if(gui.isPrestige()) { + plugin.prestige(player); + } else { + plugin.rankup(player); + } } else if (gui.getCancel().isSimilar(e.getCurrentItem())) { Bukkit.getScheduler().runTask(plugin, player::closeInventory); } diff --git a/src/main/java/sh/okx/rankup/messages/Message.java b/src/main/java/sh/okx/rankup/messages/Message.java index a6b2134..d902bef 100644 --- a/src/main/java/sh/okx/rankup/messages/Message.java +++ b/src/main/java/sh/okx/rankup/messages/Message.java @@ -16,7 +16,9 @@ public enum Message { RANKS_CURRENT("rankup.ranks.current"), RANKS_INCOMPLETE("rankup.ranks.incomplete"), COOLDOWN_SINGULAR("rankup.cooldown.singular"), - COOLDOWN_PLURAL("rankup.cooldown.plural"); + COOLDOWN_PLURAL("rankup.cooldown.plural"), + NOT_HIGH_ENOUGH("rankup.not-high-enough"), + MUST_PRESTIGE("rankup.must-prestige"); @Getter private final String name; diff --git a/src/main/java/sh/okx/rankup/messages/MessageBuilder.java b/src/main/java/sh/okx/rankup/messages/MessageBuilder.java index bc39931..b1dd208 100644 --- a/src/main/java/sh/okx/rankup/messages/MessageBuilder.java +++ b/src/main/java/sh/okx/rankup/messages/MessageBuilder.java @@ -5,6 +5,7 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; +import sh.okx.rankup.prestige.Prestige; import sh.okx.rankup.ranks.Rank; import java.util.regex.Matcher; @@ -32,32 +33,37 @@ public class MessageBuilder { return this; } - public MessageBuilder replaceAll(CommandSender player, Rank rank) { + public MessageBuilder replaceRanks(CommandSender player, Rank rank) { replace(Variable.PLAYER, player.getName()); - replaceAll(rank); + replaceRanks(rank); return this; } - public MessageBuilder replaceAll(CommandSender player, Rank oldRank, Rank rank) { + public MessageBuilder replaceRanks(CommandSender player, Rank oldRank, Rank rank) { replace(Variable.PLAYER, player.getName()); - replaceAll(oldRank, rank); + replaceRanks(oldRank, rank); return this; } - public MessageBuilder replaceAll(Rank rank) { + public MessageBuilder replaceRanks(Rank rank) { replace(Variable.RANK, rank.getRank()); replace(Variable.RANK_NAME, rank.getName()); return this; } - public MessageBuilder replaceAll(Rank oldRank, Rank rank) { - replace(Variable.RANK, rank.getRank()); - replace(Variable.RANK_NAME, rank.getName()); + public MessageBuilder replaceRanks(Rank oldRank, Rank rank) { + replaceRanks(rank); replace(Variable.OLD_RANK, oldRank.getRank()); replace(Variable.OLD_RANK_NAME, oldRank.getName()); return this; } + public MessageBuilder replaceFromTo(Prestige prestige) { + replace(Variable.FROM, prestige.getFrom()); + replace(Variable.TO, prestige.getTo()); + return this; + } + /** * Fails the MessageBuilder if the message is empty. * if this fails, all subsequent calls to that MessageBuilder will do nothing diff --git a/src/main/java/sh/okx/rankup/messages/Variable.java b/src/main/java/sh/okx/rankup/messages/Variable.java index 4fb9b52..cbdcc3e 100644 --- a/src/main/java/sh/okx/rankup/messages/Variable.java +++ b/src/main/java/sh/okx/rankup/messages/Variable.java @@ -9,6 +9,8 @@ public enum Variable { OLD_RANK_NAME, RANK, RANK_NAME, + FROM, + TO, MONEY, MONEY_NEEDED, AMOUNT, diff --git a/src/main/java/sh/okx/rankup/placeholders/Placeholders.java b/src/main/java/sh/okx/rankup/placeholders/Placeholders.java index 063640f..0152134 100644 --- a/src/main/java/sh/okx/rankup/placeholders/Placeholders.java +++ b/src/main/java/sh/okx/rankup/placeholders/Placeholders.java @@ -35,8 +35,8 @@ public class Placeholders extends PlaceholderExpansion { params = params.toLowerCase(); Rankups rankups = plugin.getRankups(); - Rank rank = rankups.getRank(player); - Rank next = rank == null ? null : rankups.nextRank(rank); + Rank rank = rankups.getByPlayer(player); + Rank next = rank == null ? null : rankups.next(rank); if (params.startsWith("requirement_")) { String[] parts = params.split("_", 3); @@ -44,10 +44,10 @@ public class Placeholders extends PlaceholderExpansion { parts[1], parts.length > 2 ? parts[2] : ""); } else if (params.startsWith("rank_requirement_")) { String[] parts = params.split("_", 4); - return simpleFormat.format(orElse(rankups.getRank(parts[2]).getRequirement(parts[3]), Requirement::getValueDouble, 0)); + return simpleFormat.format(orElse(rankups.getByName(parts[2]).getRequirement(parts[3]), Requirement::getValueDouble, 0)); } else if (params.startsWith("rank_money_")) { String[] parts = params.split("_", 3); - return plugin.formatMoney(rankups.getRank(parts[2]).getRequirement("money").getValueDouble()); + return plugin.formatMoney(rankups.getByName(parts[2]).getRequirement("money").getValueDouble()); } switch (params) { diff --git a/src/main/java/sh/okx/rankup/prestige/Prestige.java b/src/main/java/sh/okx/rankup/prestige/Prestige.java index 9e67fa5..630a73d 100644 --- a/src/main/java/sh/okx/rankup/prestige/Prestige.java +++ b/src/main/java/sh/okx/rankup/prestige/Prestige.java @@ -1,4 +1,65 @@ package sh.okx.rankup.prestige; -public class Prestige { +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import sh.okx.rankup.Rankup; +import sh.okx.rankup.ranks.Rank; +import sh.okx.rankup.requirements.Operation; +import sh.okx.rankup.requirements.Requirement; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Prestige extends Rank { + @Getter + private final String from; + @Getter + private final String to; + + private Prestige(Rankup plugin, String name, String next, String rank, Set requirements, Operation operation, List commands, String from, String to) { + super(plugin, name, next, rank, requirements, operation, commands); + this.from = from; + this.to = to; + } + + public static Prestige deserialize(Rankup plugin, ConfigurationSection section) { + Set requirements = new HashSet<>(); + Operation operation = null; + ConfigurationSection requirementsSection = section.getConfigurationSection("requirements"); + + if (requirementsSection != null) { + requirements = plugin.getRequirementRegistry().getRequirements(requirementsSection); + operation = plugin.getOperationRegistry().getOperation(section.getString("operation")); + } + + return new Prestige(plugin, + section.getName(), + section.getString("next"), + section.getString("rank"), + requirements, + operation, + section.getStringList("commands"), + section.getString("from"), + section.getString("to")); + } + + public boolean isEligable(Player player) { + String[] groups = plugin.getPermissions().getPlayerGroups(player); + for (String group : groups) { + if (group.equalsIgnoreCase(from)) { + return true; + } + } + return false; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Prestige)) { + return false; + } + return ((Prestige) o).name.equals(name); + } } diff --git a/src/main/java/sh/okx/rankup/prestige/Prestiges.java b/src/main/java/sh/okx/rankup/prestige/Prestiges.java new file mode 100644 index 0000000..b92d916 --- /dev/null +++ b/src/main/java/sh/okx/rankup/prestige/Prestiges.java @@ -0,0 +1,20 @@ +package sh.okx.rankup.prestige; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import sh.okx.rankup.RankList; +import sh.okx.rankup.Rankup; + +public class Prestiges extends RankList { + public Prestiges(Rankup plugin, FileConfiguration config) { + super(plugin, config, section -> Prestige.deserialize(plugin, section)); + } + + @Override + public Prestige getByPlayer(Player player) { + return ranks.stream() + .filter(rank -> rank.isIn(player)) + .findFirst() + .orElseGet(this::getFirst); + } +} diff --git a/src/main/java/sh/okx/rankup/ranks/Prestige.java b/src/main/java/sh/okx/rankup/ranks/Prestige.java deleted file mode 100644 index fe006cb..0000000 --- a/src/main/java/sh/okx/rankup/ranks/Prestige.java +++ /dev/null @@ -1,4 +0,0 @@ -package sh.okx.rankup.ranks; - -public class Prestige { -} diff --git a/src/main/java/sh/okx/rankup/ranks/Rank.java b/src/main/java/sh/okx/rankup/ranks/Rank.java index 0efbdb9..da20a12 100644 --- a/src/main/java/sh/okx/rankup/ranks/Rank.java +++ b/src/main/java/sh/okx/rankup/ranks/Rank.java @@ -8,70 +8,55 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import sh.okx.rankup.Rankup; import sh.okx.rankup.messages.MessageBuilder; -import sh.okx.rankup.messages.Variable; import sh.okx.rankup.requirements.DeductibleRequirement; import sh.okx.rankup.requirements.Operation; import sh.okx.rankup.requirements.Requirement; import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class Rank { - private final Rankup plugin; + protected final Rankup plugin; @Getter - private final String name; + protected final String name; @Getter - private final String next; + protected final String next; @Getter - private final String rank; + protected final String rank; @Getter - private final Set requirements; - private final Operation operation; - private final List commands; + protected final Set requirements; + protected final Operation operation; + protected final List commands; public static Rank deserialize(Rankup plugin, ConfigurationSection section) { - String rank = section.getString("rank"); - Set requirements = new HashSet<>(); Operation operation = null; ConfigurationSection requirementsSection = section.getConfigurationSection("requirements"); - if (requirementsSection != null) { - for (Map.Entry entry : requirementsSection.getValues(false).entrySet()) { - String name = entry.getKey(); - String value = String.valueOf(entry.getValue()); - Requirement requirement = plugin.getRequirementRegistry().newRequirement(name, value); - if (requirement == null) { - plugin.getLogger().warning("Unknown requirement " + name); - } else { - requirements.add(requirement); - } - } - String operationName = Optional.ofNullable(section.getString("operation")).orElse("all"); - operation = plugin.getOperationRegistry().getOperation(operationName); + if (requirementsSection != null) { + requirements = plugin.getRequirementRegistry().getRequirements(requirementsSection); + operation = plugin.getOperationRegistry().getOperation(section.getString("operation")); } return new Rank(plugin, section.getName(), section.getString("next"), - rank, + section.getString("rank"), requirements, operation, section.getStringList("commands")); } - public boolean checkRequirements(Player player) { + public boolean hasRequirements(Player player) { return operation.check(requirements.stream() .map(requirement -> requirement.check(player)) .collect(Collectors.toList())); } - public boolean isInRank(Player player) { + public boolean isIn(Player player) { String[] groups = plugin.getPermissions().getPlayerGroups(player); for (String group : groups) { if (group.equalsIgnoreCase(rank)) { @@ -81,7 +66,7 @@ public class Rank { return false; } - public boolean isLastRank() { + public boolean isLast() { return next == null; } @@ -104,13 +89,8 @@ public class Rank { public void runCommands(Player player, Rank nextRank) { for (String command : commands) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), new MessageBuilder(command) - .replace(Variable.PLAYER, player.getName()) - .replace(Variable.OLD_RANK, rank) - .replace(Variable.OLD_RANK_NAME, name) - .replace(Variable.RANK, nextRank.rank) - .replace(Variable.RANK_NAME, nextRank.name) - .toString()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), + new MessageBuilder(command).replaceRanks(player, this, nextRank).toString()); } } diff --git a/src/main/java/sh/okx/rankup/ranks/Rankups.java b/src/main/java/sh/okx/rankup/ranks/Rankups.java index 0b63f59..3a27661 100644 --- a/src/main/java/sh/okx/rankup/ranks/Rankups.java +++ b/src/main/java/sh/okx/rankup/ranks/Rankups.java @@ -1,80 +1,11 @@ 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.RankList; import sh.okx.rankup.Rankup; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class Rankups { - @Getter - private final FileConfiguration config; - private final Set ranks = new HashSet<>(); - +public class Rankups extends RankList { public Rankups(Rankup plugin, FileConfiguration config) { - this.config = config; - for (Map.Entry entry : config.getValues(false).entrySet()) { - ConfigurationSection rankSection = (ConfigurationSection) entry.getValue(); - ranks.add(Rank.deserialize(plugin, rankSection)); - } + super(plugin, config, section -> Rank.deserialize(plugin, section)); } - - public Rank getFirstRank() { - OUTER: - for (Rank rank : ranks) { - // see if anything ranks up to this - for (Rank rank0 : ranks) { - if (!rank0.isLastRank() && rank0.getNext().equals(rank.getName())) { - continue OUTER; - } - } - // nothing ranks up to this - return rank; - } - return null; - } - - public Rank getRank(String name) { - for (Rank rank : ranks) { - if (rank.getName().equalsIgnoreCase(name)) { - return rank; - } - } - return null; - } - - public Rank getRank(Player player) { - return ranks.stream() - .filter(rank -> rank.isInRank(player)) - .findFirst() - .orElse(null); - } - - public Rank nextRank(Rank rank) { - if (rank.isLastRank()) { - return null; - } - - for (Rank nextRank : ranks) { - if (rank.getNext().equalsIgnoreCase(nextRank.getName())) { - return nextRank; - } - } - // this shouldn't happen but whatever - return null; - } - -// public boolean hasNext(Rank start, Rank rank) { -// while(!start.isLastRank()) { -// start = nextRank(rank); -// if(start.equals(rank)) { -// return true; -// } -// } -// return false; -// } } diff --git a/src/main/java/sh/okx/rankup/requirements/OperationRegistry.java b/src/main/java/sh/okx/rankup/requirements/OperationRegistry.java index 2df6b65..2e05bb2 100644 --- a/src/main/java/sh/okx/rankup/requirements/OperationRegistry.java +++ b/src/main/java/sh/okx/rankup/requirements/OperationRegistry.java @@ -1,15 +1,16 @@ package sh.okx.rankup.requirements; +import java.util.HashMap; import java.util.Map; public class OperationRegistry { - private Map operations; + private Map operations = new HashMap<>(); public void addOperation(String name, Operation operation) { operations.put(name.toLowerCase(), operation); } public Operation getOperation(String name) { - return operations.get(name.toLowerCase()); + return operations.get(name == null ? "all" : name.toLowerCase()); } } diff --git a/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java b/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java index 81331e1..a9a6f89 100644 --- a/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java +++ b/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java @@ -1,6 +1,10 @@ package sh.okx.rankup.requirements; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + import java.util.HashSet; +import java.util.Map; import java.util.Set; public class RequirementRegistry { @@ -20,4 +24,28 @@ public class RequirementRegistry { } return null; } + + public Set getRequirements(ConfigurationSection section) { + Set requirements = new HashSet<>(); + + for (Map.Entry entry : section.getValues(false).entrySet()) { + String name = entry.getKey(); + String value = String.valueOf(entry.getValue()); + Requirement requirement = newRequirement(name, value); + if (requirement == null) { + System.err.println("Unknown requirement: " + name); + } else { + requirements.add(requirement); + } + } + return requirements; + } + + public void apply(Player player, Set requirements) { + for (Requirement requirement : requirements) { + if (requirement instanceof DeductibleRequirement) { + ((DeductibleRequirement) requirement).apply(player); + } + } + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index efb012a..18f4c29 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -6,12 +6,15 @@ version: 0 # you will have to restart your server. ranks: true +# whether or not prestiging should be enabled. +prestige: true + # 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 /rankup -# only successful rankups start the cooldown. +# how long in seconds people have to wait between a /rankup and a /prestige +# only successful rankups and prestiges start the cooldown. # set to 0 to disable. cooldown: 1 diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 4dc3415..cba9d0c 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -1,7 +1,5 @@ # the messages in this section can be customised for each rankup in rankups.yml. rankup: - # NOTE: if you are using requirements for your ranks that are NOT money, - # you will want to change this for each rank! 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: "" @@ -15,6 +13,9 @@ rankup: # used for the GUI confirmation title: "Rankup to {RANK}" + not-high-enough: "&cYou cannot prestige at your rank!" + must-prestige: "&cYou must prestige to /rankup further!" + # 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: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1e29070..faff6f3 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Rankup -version: 3.0-alpha.19 +version: 3.0-alpha.20 main: sh.okx.rankup.Rankup author: Okx depend: [Vault] @@ -18,6 +18,9 @@ commands: ranks: permission: rankup.ranks description: List all the ranks. + prestige: + permission: rankup.prestige + description: Prestige. permissions: rankup.*: children: @@ -27,6 +30,7 @@ permissions: rankup.ranks: true rankup.reload: true rankup.ranks: true + rankup.prestige: true rankup.info: default: true rankup.rankup: @@ -38,4 +42,6 @@ permissions: rankup.reload: default: op rankup.ranks: + default: true + rankup.prestige: default: true \ No newline at end of file diff --git a/src/main/resources/prestiges.yml b/src/main/resources/prestiges.yml index f772a4e..2f41a16 100644 --- a/src/main/resources/prestiges.yml +++ b/src/main/resources/prestiges.yml @@ -1,20 +1,24 @@ -P1example: +first: # the rank people must be to use this prestige from: 'D' # the rank to change it to to: 'A' - # the rank to also add - rank: 'P1' - # requirements are the same as in rankups.yml + next: 'P2example' + # see rankups.yml for more information on requirements, operations, commands and messages requirements: money: 10000 - # optional + # optional, defaults to all operation: all - # commands & prestige messages can be added as per rankups.yml too. P1example: from: 'D' to: 'A' - rank: 'P2' + # the rank add to indicate this prestige + rank: 'P1' + next: 'P2example' requirements: money: 20000 - xp-level: 5 \ No newline at end of file + xp-level: 5 +P2example: + from: 'D' + to: 'A' + rank: 'P2' \ No newline at end of file