diff --git a/README.md b/README.md new file mode 100644 index 0000000..1b0fed2 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# MythicKeysPlugin +> Its just MythicKeysPlugin + Cool down + +Actually I'm a bit confusing about the code, but whatever it works! + +#### New Feature: You can set cool down for each key, and the command send to the player if it is cooling (also for each key) diff --git a/src/main/java/eu/asangarin/mythickeys/CoolDown.java b/src/main/java/eu/asangarin/mythickeys/CoolDown.java new file mode 100644 index 0000000..cea3d7d --- /dev/null +++ b/src/main/java/eu/asangarin/mythickeys/CoolDown.java @@ -0,0 +1,49 @@ +package eu.asangarin.mythickeys; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public class CoolDown { + + /** + * ConcurrentHashMap(UUID, Map()): UUID is player's uuid, Map↓
+ * Map(String, Long): String is KeyID, Long is whenever the cooldown ends. + */ + private static final ConcurrentHashMap> cdMap = new ConcurrentHashMap<>(); + + public static boolean isCooling(UUID playerUUID, String keyID) { + return getKeyMap(playerUUID).getOrDefault(keyID, 0L) >= now(); + } + + public static Long getCdLeft(UUID playerUUID, String keyID) { + return getCdEnd(playerUUID, keyID) - now(); + } + + /** + * @return The end time of cd in ms + */ + public static Long getCdEnd(UUID playerUUID, String keyID) { + return getKeyMap(playerUUID).getOrDefault(keyID, 0L); + } + + public static void setCdToMsLater(UUID playerUUID, String keyID, Long msLater) { + setCdToTimestamp(playerUUID, keyID, now() + msLater); + } + + public static void setCdToTimestamp(UUID playerUUID, String keyID, Long msTimestamp) { + Map keyMap = getKeyMap(playerUUID); + keyMap.put(keyID, msTimestamp); + cdMap.put(playerUUID, keyMap); + } + + private static Map getKeyMap(UUID playerUUID) { + return cdMap.computeIfAbsent(playerUUID, k -> new HashMap<>()); + } + + private static long now() { + return System.currentTimeMillis(); + } + +} diff --git a/src/main/java/eu/asangarin/mythickeys/MKListener.java b/src/main/java/eu/asangarin/mythickeys/MKListener.java index 11a1f3f..52072c1 100644 --- a/src/main/java/eu/asangarin/mythickeys/MKListener.java +++ b/src/main/java/eu/asangarin/mythickeys/MKListener.java @@ -33,9 +33,18 @@ public void receiveKeyPress(Player player, DataInputStream buf) { if (MythicKeysPlugin.get().getConf().getKeyInfoList().containsKey(id)) { MythicKeyInfo info = MythicKeysPlugin.get().getConf().getKeyInfoList().get(id); + boolean eventCmd = MythicKeysPlugin.get().getConf().isEventOnCommand(); if (firstPress) { + if (info.hasCd() && info.isCooling(player)) { + if (info.hasCdCmd()) { + info.runCdCmd(player); + } + return; + } else { + info.setCd(player); + } if (!info.runCommand(player) || eventCmd) Bukkit.getPluginManager().callEvent(new MythicKeyPressEvent(player, id, true)); info.mmSkill(player, true); return; diff --git a/src/main/java/eu/asangarin/mythickeys/config/MythicKeyInfo.java b/src/main/java/eu/asangarin/mythickeys/config/MythicKeyInfo.java index 106e14c..c7acebf 100644 --- a/src/main/java/eu/asangarin/mythickeys/config/MythicKeyInfo.java +++ b/src/main/java/eu/asangarin/mythickeys/config/MythicKeyInfo.java @@ -1,5 +1,6 @@ package eu.asangarin.mythickeys.config; +import eu.asangarin.mythickeys.CoolDown; import eu.asangarin.mythickeys.MythicKeysPlugin; import eu.asangarin.mythickeys.compat.MythicMobsCompat; import lombok.Getter; @@ -12,19 +13,22 @@ @Getter public class MythicKeyInfo { - private MythicKeyInfo(NamespacedKey id, String name, String category, int def, String command, String mythicPress, String mythicRelease) { + private MythicKeyInfo(NamespacedKey id, String name, String category, int def, String command, long cd, String cdCmd, String mythicPress, String mythicRelease) { this.id = id; this.name = name; this.category = category; this.def = def; this.command = command; + this.cd = cd; + this.cdCmd = cdCmd; this.mythicPress = mythicPress; this.mythicRelease = mythicRelease; } private final NamespacedKey id; - private final String name, category, command, mythicPress, mythicRelease; + private final String name, category, command, cdCmd, mythicPress, mythicRelease; private final int def; + private final long cd; // Using a static method to insert KeyInfo verification code. public static @Nullable MythicKeyInfo from(ConfigurationSection config) { @@ -33,11 +37,46 @@ private MythicKeyInfo(NamespacedKey id, String name, String category, int def, S if (key == null) return null; return new MythicKeyInfo(key, config.getString("Name"), config.getString("Category"), config.getInt("DefaultKey"), - config.getString("RunCommand", ""), config.getString("SkillPress", ""), config.getString("SkillRelease", "")); + config.getString("RunCommand", ""), config.getLong("CD"), config.getString("CdCommand"), config.getString("SkillPress", ""), config.getString("SkillRelease", "")); } return null; } + public boolean hasCd() { + return cd > 0; + } + + public boolean isCooling(Player player) { + return CoolDown.isCooling(player.getUniqueId(), id.getKey()); + } + + public void setCd(Player player) { + CoolDown.setCdToMsLater(player.getUniqueId(), id.getKey(), cd); + } + + public boolean hasCdCmd() { + return cdCmd != null && !cdCmd.isEmpty(); + } + + public void runCdCmd(Player player) { + if (!hasCdCmd()) return; + + final boolean isAdmin = cdCmd.startsWith("!"); + String cmd = (isAdmin ? cdCmd.substring(1) : cdCmd).replace("%player%", player.getName()); + if (cmd.contains("%s%")) { + Long cdLeft = CoolDown.getCdLeft(player.getUniqueId(), id.getKey()); + cmd = cmd.replaceAll("%s%", String.valueOf(cdLeft/1000)); + } + if (cmd.contains("%ms%")) { + Long cdLeft = CoolDown.getCdLeft(player.getUniqueId(), id.getKey()); + cmd = cmd.replaceAll("%ms%", String.valueOf(cdLeft)); + } + if (MythicKeysPlugin.get().papi) cmd = PlaceholderAPI.setPlaceholders(player, cmd); + + if (isAdmin) Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd); + else Bukkit.dispatchCommand(player, cmd); + } + public boolean runCommand(Player player) { if (command == null || command.isEmpty()) return false; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index fa75434..9bf8a72 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # MythicKeysPlugin # Made by Aria Sangarin -# Config Version 4 +# Config Version 5 # Whether or not the event should be fired # if a command was configured for the key ID. @@ -20,6 +20,13 @@ Keys: # There is also support for all PAPI placeholders. # If you don't want the key to run a command (for external plugin support), just leave it empty. + # You can remove [CD] and [CdCommand] if you don't want it + CD: 500 + # The Cooldown of this key (Millisecond) + CdCommand: "!msg %player% Cooling! (%s%)" + # If it is cooling, then send this. + # %s% for second, %ms% for millisecond + #SkillPress: "RunWhenKeyPressed" #SkillRelease: "RunWhenKeyReleased" # If you have MythicMobs installed, you can specify an MM skill to be ran when a key is pressed or released.