Help with countdown

Discussion in 'Plugin Development' started by JimsHD, Nov 22, 2013.

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

    JimsHD

    So I'm coding an OITC plugin for my server(One in the chamber) And I'd like to have a countdown when a player runs the command start. I'm not sure how to make a countdown. If you guys could help that'd be awesome!
     
  2. Offline

    Aperx

  3. Offline

    JimsHD

    Aperx Not a scoreboard countdown, a regular countdown where it announces things and then stops
     
  4. Offline

    Mikaelrk2

    That code Aperx gives u is wrong
    this is a code i made:

    import java.util.logging.Logger;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Countdown extends JavaPlugin{

    public final Logger logger = Logger.getLogger("Minecraft");
    public static Countdown plugin;
    int startCount = 0;

    @Override
    public void onDisable() {

    PluginDescriptionFile pdfFile = this.getDescription();
    this.logger.info(pdfFile.getName() + " has been Disabled.");


    }

    @Override
    public void onEnable() {

    PluginDescriptionFile pdfFile = this.getDescription();
    this.logger.info(pdfFile.getName() + " has been Enabled.");
    }


    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {


    Player player = (Player)sender;
    if(player.hasPermission("count.allow"));
    if (commandLabel.equalsIgnoreCase("countdown")) {

    if (args.length == 0) {

    player.sendMessage(ChatColor.DARK_RED + "Usage: /countdown <seconds>");

    }else{

    startCount = Integer.parseInt(args[0]);

    Bukkit.broadcastMessage(ChatColor.AQUA + " Started a countdown from ");
    while (startCount != 0) {

    Bukkit.broadcastMessage(ChatColor.GOLD + " " + startCount);
    startCount--;
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    if (startCount == 0) {

    Bukkit.broadcastMessage(ChatColor.AQUA + "Starting round 1!");
    sender.sendMessage(ChatColor.GREEN + "Go!");

    }

    }

    }
    return false;

    }

    }

    Like mine one?

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

    JimsHD

    Mikaelrk2 Your's doesn't work, next time put it in code brackets :3
     
  6. Offline

    Mikaelrk2

    I hade them my pl works fine u need to put use the command /countdown how long :p
    PS: i hade brakets
     
  7. Offline

    geNAZt

    Dont use this code. It will block your mine craft thread causing huge amounts of lag and disconnects
     
  8. Offline

    JimsHD

  9. Offline

    Aperx

    JimsHD he uses
    Code:java
    1. Thread.sleep(1000);

    Thus, causing what geNAZt said
     
  10. Offline

    geNAZt

    To get this right you must understand how the Minecraft Server and his event loop works. To make this a bit easier i made this picture:

    [​IMG]
    What you see here is what Bukkit/Minecraft does within ONE tick (Dont hit me if the order is wrong or i missed some steps inside the loop). For Minecraft not to lag you need > 17-18 of those Ticks (maximum Limit is 20 which is the best score you can get). If you block the Event Loop (which is run in the same Thread as the event you get [as long as its not an async event]) the Minecraft server will halt for the time you Block. For example you have a PlayerJoinEvent listener which gets called from the Network Handle code. Normaly the whole Tick has a execution time of: 1000/20 = 50ms per Tick. Now you go andget the Event and block on it for 1000ms.

    So you have a Tick timing for this Tick of 1050ms. You have a TPS under 1 and the Minecraft Server will drop you of or even crash (Cant keep up! Has the time changed?).

    So NEVER Thread.sleep() inside any events. You can use Threads or runTaskAsync and block in there because it doesnt affect any Minecraft Event Loop things (as long you dont try to syncronize these Loops [but i never saw one doing this :D])

    So for your example this would mean that you Block every second for one second if a command is entered which would lead to a disconnect instantly.

    You should use the Bukkit sheduler for these kind of works.

    Code:java
    1. import org.bukkit.Bukkit;
    2. import org.bukkit.ChatColor;
    3. import org.bukkit.command.Command;
    4. import org.bukkit.command.CommandSender;
    5. import org.bukkit.entity.Player;
    6. import org.bukkit.plugin.java.JavaPlugin;
    7. import org.bukkit.scheduler.BukkitRunnable;
    8.  
    9. public class Plugin extends JavaPlugin {
    10. private class CountdownRunnable extends BukkitRunnable {
    11. private Integer startCountdown = 0;
    12.  
    13. public CountdownRunnable(Integer start) {
    14. this.startCountdown = start;
    15. }
    16.  
    17. @Override
    18. public void run() {
    19. Bukkit.broadcastMessage(ChatColor.GOLD + " " + startCountdown);
    20. startCountdown--;
    21.  
    22. if(startCountdown == 0) {
    23. Bukkit.broadcastMessage(ChatColor.GOLD + " Countdown finished");
    24. Bukkit.getScheduler().cancelTask(this.getTaskId());
    25. }
    26. }
    27. }
    28.  
    29. public void onEnable() {
    30. //Tell Bukkit which CommandExecutor should be used for the "countdown" command
    31. getCommand("countdown").setExecutor(this);
    32. }
    33.  
    34. public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    35. //Always check if the sender is a player, it also can be the console!
    36. if(!(sender instanceof Player)) {
    37. sender.sendMessage("This command can only be used by players");
    38. return true;
    39. }
    40.  
    41. //Cast the sender into a Player Object
    42. Player player = (Player)sender;
    43.  
    44. //Check if the Player has the Permission to access t
    45. if(!player.hasPermission("count.allow")) {
    46. player.sendMessage("You dont have the permission to do this.");
    47. return true;
    48. }
    49.  
    50. //Check if the argument is given
    51. if(args.length == 0) {
    52. player.sendMessage(ChatColor.DARK_RED + "Usage: /countdown <seconds>");
    53. } else {
    54. //This could throw a NumberFormatException
    55. final Integer startCount = Integer.parseInt(args[0]);
    56.  
    57. Bukkit.broadcastMessage(ChatColor.AQUA + " Started a countdown from ");
    58. Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new CountdownRunnable(startCount), 0, 20);
    59. }
    60.  
    61. return true;
    62.  
    63. }
    64. }
    65.  


    Please care this is not tested but it should work. Also here is a example plugin.yml:

    Code:
    name: Countdown
    main: your.name.space.in.java.Plugin
    description: Simple Countdown
    version: 0.1.0
    commands:
        countdown:
           description: Start the countdown
           usage: /countdown <seconds>
           permission: count.allow
           permission-message: You cant start a countdown
    permissions:
      count.allow:
        description: Allows to start a new Countdown
    
    If you have any further questions please thag me i dont watch threads. Thanks
     
  11. Offline

    Mikaelrk2

    My Thread.sleep(1000)
    Is how fast & how slow the countdown is :p

    It can make a bit of server connection bad but it works fine.

    I tested the plugin & it did begin and count from 10 and look now:

    View attachment 15972
    Maybe my code wasnt so bad :p

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

    1Rogue


    Learn about threading and general task handling before making a statement like that. Sleeping the main thread will stop the server for that same amount of time. Instead you should be working with ScheduledFuture<> and just using a task that runs every second counting down.


    You're still insinuating that it's perfectly fine to sleep the main thread...

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

    Mikaelrk2

    I ment the -1 -2 -3 Counter.png

    K help the guy dont whant to have a fight here ..
    So c ya
    Sorry if my pl is like it im gonna fix it

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

    geNAZt

    Well thanks that you havent read my Posting about the Event Loop within minecraft. It says why its bad to sleep inside Minecraft and that my code is untested.

    I <3 this Community :(
     
Thread Status:
Not open for further replies.

Share This Page