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.