Plugin cooldown

Discussion in 'Plugin Development' started by tg95, Nov 13, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    tg95

    hi, i have a problem with my java code, i wanted to put cooldown, so when they pressed on the paper, if they pressed it again they had to wait 5 seconds, i'm still a newbie in java programs, can someone help me? thanks for your attencion

    Best regards!


    my code;

    Code:java
    1. package com.tg95.svgui;
    2.  
    3. import java.io.ByteArrayOutputStream;
    4. import java.io.DataOutputStream;
    5. import java.io.IOException;
    6. import java.util.Arrays;
    7. import java.util.List;
    8.  
    9. import org.bukkit.Bukkit;
    10. import org.bukkit.Material;
    11. import org.bukkit.entity.Player;
    12. import org.bukkit.event.EventHandler;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.event.block.Action;
    15. import org.bukkit.event.inventory.InventoryClickEvent;
    16. import org.bukkit.event.player.PlayerInteractEvent;
    17. import org.bukkit.event.player.PlayerJoinEvent;
    18. import org.bukkit.inventory.Inventory;
    19. import org.bukkit.inventory.ItemStack;
    20. import org.bukkit.inventory.meta.BookMeta;
    21. import org.bukkit.inventory.meta.ItemMeta;
    22. import org.bukkit.plugin.java.JavaPlugin;
    23.  
    24. public class tg95svgui extends JavaPlugin
    25. implements Listener {
    26.  
    27.  
    28. @Override
    29. public void onEnable() {
    30. Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
    31. getServer().getPluginManager().registerEvents(this, this);
    32. }
    33.  
    34.  
    35. @EventHandler
    36. public void onplayerjoin(PlayerJoinEvent e) {
    37. Player p = e.getPlayer();
    38. p.performCommand("spawn");
    39. // P//
    40. p.getInventory().remove(Material.PAPER);
    41. //P//
    42. ItemStack gv = new ItemStack(Material.PAPER);
    43. ItemMeta tempgv = gv.getItemMeta();
    44. tempgv.setDisplayName("§a§l\u2714 §4§lNSP§9§lServers §a§l\u2714");
    45. List<String> lorefree1 = Arrays.asList("§bCarrega aqui para escolheres um servidor !");
    46. tempgv.setLore(lorefree1);
    47. gv.setItemMeta(tempgv);
    48. p.getInventory().setItem(0, gv);
    49.  
    50. }
    51.  
    52. @EventHandler
    53. public void onPlayerInteract (PlayerInteractEvent event)
    54. {
    55.  
    56. Action a = event.getAction();
    57. ItemStack is = event.getItem();
    58. if ((a == Action.PHYSICAL) || (is == null) || (is.getType() == Material.AIR)) {
    59. return;
    60.  
    61. }
    62. if (is.getType() == Material.PAPER) {
    63. Player p = event.getPlayer();
    64. Inventory inv = Bukkit.getServer().createInventory(p, 9, "§4§lNSP§3§lServidores");
    65.  
    66. //Survival//
    67. ItemStack free1 = new ItemStack(Material.DIAMOND_PICKAXE);
    68. ItemMeta tempfree1 = free1.getItemMeta();
    69. tempfree1.setDisplayName("§6§l\u2733 §a§lSurvival §6§l\u2733");
    70. List<String> lorefree1 = Arrays.asList("§5Carrega aqui para ires até", "§5ao nosso servidor §6§l\u2733 §a§lSurvival §6§l\u2733");
    71. tempfree1.setLore(lorefree1);
    72. free1.setItemMeta(tempfree1);
    73. inv.setItem(2, free1);
    74.  
    75. //Prison//
    76. ItemStack free2 = new ItemStack(Material.IRON_FENCE);
    77. ItemMeta tempfree2 = free2.getItemMeta();
    78. tempfree2.setDisplayName("§2§l\u27F6 §4§lPrison §2§l\u27F5");
    79. List<String> lorefree2 = Arrays.asList("§5Carrega aqui para ires até", "§5ao nosso servidor §2§l\u27F6 §4§lPrison §2§l\u27F5");
    80. tempfree2.setLore(lorefree2);
    81. free2.setItemMeta(tempfree2);
    82. inv.setItem(4, free2);
    83.  
    84. //MINIGAMES//
    85. ItemStack free3 = new ItemStack(Material.WATCH);
    86. ItemMeta tempfree3 = free3.getItemMeta();
    87. tempfree3.setDisplayName("§4§l\u25A7 §b§lMiniGames §4§l\u25A7");
    88. List<String> lorefree3 = Arrays.asList("§5Carrega aqui para ires até", "§5ao nosso servidor §4§l\u25A7 §b§lMiniGames §4§l\u25A7");
    89. tempfree3.setLore(lorefree3);
    90. free3.setItemMeta(tempfree3);
    91. inv.setItem(6, free3);
    92.  
    93.  
    94. //END//
    95. p.openInventory(inv);
    96. }
    97.  
    98. }
    99.  
    100.  
    101.  
    102. @EventHandler
    103. public void invclick(InventoryClickEvent e) {
    104.  
    105. try {
    106. if(e.getInventory().getName().equalsIgnoreCase("§4§lNSP§3§lServidores")) {
    107. ItemStack itemclicked = e.getCurrentItem();
    108. Player p = (Player) e.getWhoClicked();
    109. e.setCancelled(true);
    110.  
    111. // SURVIVAL //
    112. if(itemclicked.getType().equals(Material.DIAMOND_PICKAXE)) {
    113. p.closeInventory();
    114. if (!(p instanceof Player)) return;
    115. try {
    116. out.writeUTF("Connect");
    117. out.writeUTF("Principal");
    118. } catch (IOException e2) {
    119. }
    120. p.sendPluginMessage(this, "BungeeCord", b.toByteArray());
    121.  
    122. }
    123.  
    124. // Prison //
    125. if(itemclicked.getType().equals(Material.IRON_FENCE)) {
    126. p.closeInventory();
    127. if (!(p instanceof Player)) return;
    128. try {
    129. out.writeUTF("Connect");
    130. out.writeUTF("Prison");
    131. } catch (IOException e2) {
    132. }
    133. p.sendPluginMessage(this, "BungeeCord", b.toByteArray());
    134.  
    135. }
    136.  
    137. // MINIGAMES //
    138. if(itemclicked.getType().equals(Material.WATCH)) {
    139. p.closeInventory();
    140. if (!(p instanceof Player)) return;
    141. try {
    142. out.writeUTF("Connect");
    143. out.writeUTF("Minigames");
    144. } catch (IOException e2) {
    145. }
    146. p.sendPluginMessage(this, "BungeeCord", b.toByteArray());
    147.  
    148. }
    149. }
    150. }catch (Exception e2) {}
    151. }
    152.  
    153. }
     
  2. Offline

    JordyPwner

    You can use a ArrayList with a scheduler (thats how i do it :p
     
  3. Offline

    The Fancy Whale

    I personally am more of a fan of assigning a player's uuid to an integer in a hashmap and every second subtracting from all keys in the hashmap. This also allows for the developer to display the time left.
     
  4. Offline

    FerusGrim

    Assuming that you don't care about actively showing the user the cooldown (such as sending a message to the player, when time nears 0), you could use something commonly referred to as a Delayed Task.

    If this isn't what you want to do, stop reading, and listen to the suggestion by The Fancy Whale. (Or, continue reading, and learn something new, anyways!)

    Delayed Task, meaning that the task or function is only used when it's needed, rather than on time. For instance, ask yourself - Do you need the task to activate immediately after the cooldown is resolved? Or could it wait until the cooldown is queried again? In most cases where you don't actively display the cooldown, a Delayed Task works much better, because the user doesn't need to see whether or not they have or don't have a cooldown until they use the command/function again.

    So, if this works for you, it's worth noting that the major advantage is not having to use a Runnable.

    I'll display this in steps, and then give an example.
    1) Create a HashMap with the Player UUID as the key, and the System#currentTimeMillis as the key. This key won't change, as you don't need to update it - just check against it.
    2) When the player uses the command/function (we'll just say command, from now on), check if they're in this map.
    3a) If they ARE in the Map, check how much time has elapsed by doing another System#currentTimeMillis and deducting the stored value from the HashMap. If the result is equal to or larger than the amount of time you want for the coolown, let them do the command. If not, tell them how much time they have left.
    3b) If they are NOT in the Map, allow them to do the command and add their UUID and the System#currentTimeMillis to the Map.

    Example:

    Code:java
    1. private final Map<UUID, Long> cooldownMap = new HashMap<UUID, Long>();
    2. private final long cooldownTime = 10000; // 10 seconds
    3.  
    4. @Override
    5. public void onCommand(Command cmd, blah blah, CommandSender sender) {
    6. if (!(sender instanceof Player)) {
    7. return; // For the purposes of this tutorial, I'm going to discount standard responses to this.
    8. }
    9.  
    10. final Player player = (Player) sender;
    11. final UUID uuid = player.getUniqueId();
    12. final long elapsedTime = System.currentTimeMillis() - cooldownMap.get(uuid);
    13. if (elapsedTime >= cooldownTime) {
    14. cooldownMap.put(uuid, System.currentTimeMillis()); // This will override the previous value. No need to remove them from the Map first.
    15. runCommand(); // You'll probably want to send something like the command arguments / Player object.
    16. } else {
    17. final int timeInSeconds = (cooldownTime - elapsedTime) / 1000;
    18. player.sendMessage("You need to wait " + timeInSeconds + " before using this command!");
    19. }
    20. }
    21.  
    22. public void runCommand() {
    23. // do stuff
    24. }


    EDIT:

    I'm double posting on purpose because I can't be arsed to fix formatting in the example code above.

    Just wanted to note that the above code might not (probably) be copy/pasteable. It was written without an IDE, and I probably screwed something up.

    Also, Dragonphase has created a more in-depth tutorial on using Delayed Tasks that you can find here. (It's really good)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  5. Offline

    Gnat008

    tg95
    Used with permission from @ColonelHedgehog:

    Should I use Runnable cooldowns?

    Nope. It's redundant. There's no point and it can cause problems. Use "lazy data". Instead of storing an ArrayList with the player's UUID, make a HashMap storing his UUID as well as the System.currentTimeInMilis() as the value. For a command cool down, for example, add the player's UUID and the current time to the HashMap. When he tries to use the command again, check and see the current time and compare it to the HashMap's time. If it has been long enough since he first used the command, remove him from the HashMap and allow him to use it. No need for a runnable at all! In fact, this gives you more flexibility. You can compare the times to send a message to the player telling him exactly how much time must elapse before he can use the command again. Otherwise, you could potentially cause lag. No fun at all.
     
  6. Offline

    tg95

    Thanks for all help me, but, want i want is for them to not do spam on paper whitch time they want to use the delay 5 seconds , again thanks for all the help
     
Thread Status:
Not open for further replies.

Share This Page