From 923cc8918c791495390cf71c6c798a93e09e0183 Mon Sep 17 00:00:00 2001 From: okx-code Date: Tue, 28 Aug 2018 20:42:26 +0100 Subject: [PATCH] add /rankup cooldown --- build.gradle | 2 +- src/main/java/sh/okx/rankup/Rankup.java | 37 +++++++++++++++++-- .../sh/okx/rankup/commands/RankupCommand.java | 4 +- .../rankup/messages/EmptyMessageBuilder.java | 3 ++ .../java/sh/okx/rankup/messages/Message.java | 4 +- .../okx/rankup/messages/MessageBuilder.java | 9 ++--- .../java/sh/okx/rankup/messages/Variable.java | 3 +- src/main/resources/config.yml | 7 +++- src/main/resources/messages.yml | 4 ++ src/main/resources/plugin.yml | 2 +- 10 files changed, 59 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 9e587ce..35d597a 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'sh.okx' -version '3.0-alpha.12' +version '3.0-alpha.13' sourceCompatibility = 1.8 diff --git a/src/main/java/sh/okx/rankup/Rankup.java b/src/main/java/sh/okx/rankup/Rankup.java index 36d6897..809bc37 100644 --- a/src/main/java/sh/okx/rankup/Rankup.java +++ b/src/main/java/sh/okx/rankup/Rankup.java @@ -33,6 +33,8 @@ import sh.okx.rankup.ranks.requirements.XpLevelRequirement; import java.io.File; import java.text.DecimalFormat; import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; import java.util.function.Supplier; public class Rankup extends JavaPlugin { @@ -54,6 +56,11 @@ public class Rankup extends JavaPlugin { @Getter private Placeholders placeholders; + /** + * Players who cannot rankup for a certain amount of time. + */ + private Map cooldowns; + @Override public void onEnable() { registerRequirements(); @@ -69,7 +76,7 @@ public class Rankup extends JavaPlugin { } }); - if(config.getBoolean("ranks")) { + if (config.getBoolean("ranks")) { getCommand("ranks").setExecutor(new RankListCommand(this)); } getCommand("rankup").setExecutor(new RankupCommand(this)); @@ -85,6 +92,7 @@ public class Rankup extends JavaPlugin { } public void reload() { + cooldowns = new WeakHashMap<>(); closeInventories(); loadConfigs(); if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { @@ -204,6 +212,11 @@ public class Rankup extends JavaPlugin { .send(player); oldRank.runCommands(player, rank); + + // apply cooldown last + if(config.getInt("cooldown") > 0) { + cooldowns.put(player, System.currentTimeMillis()); + } } /** @@ -239,22 +252,38 @@ public class Rankup extends JavaPlugin { replaceRequirements(player, builder, rank); builder.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(rank, secondsLeft > 1 ? Message.COOLDOWN_PLURAL : Message.COOLDOWN_SINGULAR) + .failIfEmpty() + .replaceAll(player, rank) + .replace(Variable.SECONDS, secondsLeft) + .send(player); + return false; + } + // cooldown has expired so remove it + cooldowns.remove(player); } + return true; } public void replaceRequirements(Player player, MessageBuilder builder, Rank rank) { DecimalFormat simpleFormat = placeholders.getSimpleFormat(); DecimalFormat percentFormat = placeholders.getPercentFormat(); - for(Requirement requirement : rank.getRequirements()) { + for (Requirement requirement : rank.getRequirements()) { replaceRequirements(builder, Variable.AMOUNT, requirement, () -> simpleFormat.format(requirement.getAmount())); replaceRequirements(builder, Variable.AMOUNT_NEEDED, requirement, () -> simpleFormat.format(requirement.getRemaining(player))); replaceRequirements(builder, Variable.PERCENT_LEFT, requirement, () -> percentFormat.format(Math.max(0, (requirement.getRemaining(player) / requirement.getAmount()) * 100))); - replaceRequirements(builder, Variable.PERCENT_DONE, requirement, () -> percentFormat.format(Math.min(100, (1-(requirement.getRemaining(player) / requirement.getAmount())) * 100))); + replaceRequirements(builder, Variable.PERCENT_DONE, requirement, () -> percentFormat.format(Math.min(100, (1 - (requirement.getRemaining(player) / requirement.getAmount())) * 100))); } } private void replaceRequirements(MessageBuilder builder, Variable variable, Requirement requirement, Supplier value) { - builder.replace(variable + " " + requirement.getName(), value.get()); + builder.replace(variable + " " + requirement.getName(), value.get()); } } diff --git a/src/main/java/sh/okx/rankup/commands/RankupCommand.java b/src/main/java/sh/okx/rankup/commands/RankupCommand.java index 4a57811..0d8282a 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -8,7 +8,6 @@ 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.messages.Variable; import sh.okx.rankup.ranks.Rank; import sh.okx.rankup.ranks.Rankups; @@ -16,7 +15,10 @@ import java.util.Map; import java.util.WeakHashMap; public class RankupCommand implements CommandExecutor { + // weak hash maps so players going offline are automatically removed. + // otherwise there is a potential (but small) memory leak. private final Map confirming = new WeakHashMap<>(); + private final Rankup plugin; public RankupCommand(Rankup plugin) { diff --git a/src/main/java/sh/okx/rankup/messages/EmptyMessageBuilder.java b/src/main/java/sh/okx/rankup/messages/EmptyMessageBuilder.java index 9039317..6537717 100644 --- a/src/main/java/sh/okx/rankup/messages/EmptyMessageBuilder.java +++ b/src/main/java/sh/okx/rankup/messages/EmptyMessageBuilder.java @@ -7,6 +7,9 @@ class EmptyMessageBuilder extends MessageBuilder { super(null); } + /** + * what are you doing failing if empty when it has already failed? + */ @Override public MessageBuilder failIfEmpty() { throw new UnsupportedOperationException(); diff --git a/src/main/java/sh/okx/rankup/messages/Message.java b/src/main/java/sh/okx/rankup/messages/Message.java index 0fcb916..a6b2134 100644 --- a/src/main/java/sh/okx/rankup/messages/Message.java +++ b/src/main/java/sh/okx/rankup/messages/Message.java @@ -14,7 +14,9 @@ public enum Message { RANKS_FOOTER("rankup.ranks.footer"), RANKS_COMPLETE("rankup.ranks.complete"), RANKS_CURRENT("rankup.ranks.current"), - RANKS_INCOMPLETE("rankup.ranks.incomplete"); + RANKS_INCOMPLETE("rankup.ranks.incomplete"), + COOLDOWN_SINGULAR("rankup.cooldown.singular"), + COOLDOWN_PLURAL("rankup.cooldown.plural"); @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 ede00b7..bc39931 100644 --- a/src/main/java/sh/okx/rankup/messages/MessageBuilder.java +++ b/src/main/java/sh/okx/rankup/messages/MessageBuilder.java @@ -1,16 +1,12 @@ package sh.okx.rankup.messages; -import lombok.AllArgsConstructor; -import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import sh.okx.rankup.ranks.Rank; -import sh.okx.rankup.ranks.requirements.Requirement; -import java.text.DecimalFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -65,10 +61,11 @@ public class MessageBuilder { /** * Fails the MessageBuilder if the message is empty. * if this fails, all subsequent calls to that MessageBuilder will do nothing + * * @return an EmptyMessageBuilder if the message is empty, itself otherwise */ public MessageBuilder failIfEmpty() { - if(message.isEmpty()) { + if (message.isEmpty()) { return new EmptyMessageBuilder(); } else { return this; @@ -84,7 +81,7 @@ public class MessageBuilder { * ie, calls MessageBuilder#send(Player) for all players online, and sends the message in the console. */ public void broadcast() { - for(Player player : Bukkit.getOnlinePlayers()) { + for (Player player : Bukkit.getOnlinePlayers()) { send(player); } send(Bukkit.getConsoleSender()); diff --git a/src/main/java/sh/okx/rankup/messages/Variable.java b/src/main/java/sh/okx/rankup/messages/Variable.java index 0faed6b..4fb9b52 100644 --- a/src/main/java/sh/okx/rankup/messages/Variable.java +++ b/src/main/java/sh/okx/rankup/messages/Variable.java @@ -14,7 +14,8 @@ public enum Variable { AMOUNT, AMOUNT_NEEDED, PERCENT_DONE, - PERCENT_LEFT; + PERCENT_LEFT, + SECONDS; public String replace(String message, String value, String type) { Pattern pattern = Pattern.compile("\\{" + type + "_" + this + "}", Pattern.CASE_INSENSITIVE); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5fbba0b..44f2cff 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -10,6 +10,11 @@ ranks: true # 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. +# set to 0 to disable. +cooldown: 1 + gui: rows: 1 rankup: @@ -34,7 +39,7 @@ gui: text: # the time in seconds for a player to - # confirm ranking up by typing the command again + # confirm by typing /rankup again timeout: 10 placeholders: diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index cce81fd..4dc3415 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -32,5 +32,9 @@ rankup: # an empty string disables the header/footer header: '' footer: '' + # sent when a player tries to rankup when they are on cooldown + cooldown: + singular: '&cYou must wait {SECONDS} more second to rankup again.' + plural: '&cYou must wait {SECONDS} more seconds to rankup again.' not-in-ladder: "&cSorry, but we could not find any rankups for the group(s) you are in." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 350fd96..fc79030 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Rankup -version: 3.0-alpha.12 +version: 3.0-alpha.13 main: sh.okx.rankup.Rankup author: Okx depend: [Vault]