Minigame Scheduler Help

Discussion in 'Plugin Development' started by jcbjoe, Jul 18, 2014.

Thread Status:
Not open for further replies.
  1. Hello,
    I'm creating a minigame for a friend and I have a scheduler setup for when people join the game. However i was wondering how i can make it so that multiple schedulers can run at the same time.

    This is my current code:
    Code:java
    1. task = Bukkit.getScheduler().scheduleSyncRepeatingTask(
    2. plugin, new Runnable() {
    3.  
    4. @Override
    5. public void run() {
    6. countdown--;
    7. if(countdown == 590){
    8. for(Player player : islandnumber.keySet()){
    9. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 10 Seconds!");
    10. }
    11. }
    12. if(countdown == 585){
    13. for(Player player : islandnumber.keySet()){
    14. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 5 Seconds!");
    15. }
    16. }
    17. if(countdown == 584){
    18. for(Player player : islandnumber.keySet()){
    19. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 4 Seconds!");
    20. }
    21. }
    22. if(countdown == 583){
    23. for(Player player : islandnumber.keySet()){
    24. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 3 Seconds!");
    25. }
    26. }
    27. if(countdown == 582){
    28. for(Player player : islandnumber.keySet()){
    29. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 2 Seconds!");
    30. }
    31. }
    32. if(countdown == 581){
    33. for(Player player : islandnumber.keySet()){
    34. player.sendMessage(ChatColor.DARK_RED+"Game Starting In 1 Seconds!");
    35. }
    36. }
    37. if(countdown == 580){
    38. if(peoplejoined.get(args[1]).equals(1)){
    39.  
    40. Player player = (Player)sender;
    41. player.getInventory().clear();
    42. player.getInventory().setArmorContents(null);
    43.  
    44. player.getInventory().setContents(inv.get(player.getName()));
    45. player.getInventory().setArmorContents(armor.get(player.getName()));
    46.  
    47. inv.remove(player.getName());
    48. armor.remove(player.getName());
    49. sender.sendMessage(ChatColor.DARK_RED+"There are not enough players to start the game!");
    50. arena.remove(args[1]);
    51. islandnumber.remove(player);
    52. peoplejoined.remove(args[1]);
    53. Location endpoint = new Location(Bukkit.getWorld(plugin.getConfig().getString("Islands."+arena.get(player)+".end.world")),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.x"),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.y"),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.z"));
    54. player.teleport(endpoint);
    55. Bukkit.getScheduler().cancelTask(
    56. task);
    57. plugin.getConfig()
    58. .set("Islands." + args[1] + ".Status",
    59. "Not-Running");
    60. plugin.saveConfig();
    61. countdown = 600;
    62. return;
    63. }else{
    64. for(Player player : islandnumber.keySet()){
    65. if(arena.get(player).equals(args[1])){
    66. score.put(player, 0);
    67. player.sendMessage(ChatColor.DARK_RED+"Game Starting!");
    68. int island = islandnumber.get(player);
    69. Location islandspawn = new Location(Bukkit.getWorld(plugin.getConfig().getString("Islands."+arena.get(player)+".playerspawns."+island+".world")),plugin.getConfig().getInt("Islands."+arena.get(player)+".playerspawns."+island+".x"),plugin.getConfig().getInt("Islands."+arena.get(player)+".playerspawns."+island+".y"),plugin.getConfig().getInt("Islands."+arena.get(player)+".playerspawns."+island+".z"));
    70. player.teleport(islandspawn);
    71. plugin.getConfig()
    72. .set("Islands." + args[1] + ".Status",
    73. "Running");
    74. plugin.saveConfig();
    75. }
    76.  
    77. }
    78. }
    79. }if(countdown == 2){
    80. for(Player player : islandnumber.keySet()){
    81. if(arena.get(player).equals(args[1])){
    82. int score2 = score.get(player);
    83. if(score2 > topscore){
    84. topscore = score2;
    85. }
    86. }
    87. }
    88. }
    89. if(countdown == 1){
    90. for(Player player : islandnumber.keySet()){
    91. if(arena.get(player).equals(args[1])){
    92. if(score.get(player)==topscore){
    93. Bukkit.broadcastMessage(ChatColor.RED+player.getName()+" has won islandwars on: "+arena.get(player)+"!");
    94. }
    95. player.getInventory().clear();
    96. player.getInventory().setArmorContents(null);
    97.  
    98. player.getInventory().setContents(inv.get(player.getName()));
    99. player.getInventory().setArmorContents(armor.get(player.getName()));
    100.  
    101. inv.remove(player.getName());
    102. armor.remove(player.getName());
    103. arena.remove(args[1]);
    104. islandnumber.remove(player);
    105. peoplejoined.remove(args[1]);
    106. Location endpoint = new Location(Bukkit.getWorld(plugin.getConfig().getString("Islands."+arena.get(player)+".end.world")),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.x"),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.y"),plugin.getConfig().getInt("Islands."+arena.get(player)+".end.z"));
    107. player.teleport(endpoint);
    108. }
    109. }
    110. sender.sendMessage(ChatColor.DARK_RED+"The game has ended!");
    111.  
    112. plugin.getConfig()
    113. .set("Islands." + args[1] + ".Status",
    114. "Not-Running");
    115. plugin.saveConfig();
    116. Bukkit.getScheduler().cancelTask(
    117. task);
    118.  
    119. }
    120.  
    121.  
    122.  
    123.  
    124. }
    125. }, 0L, 20L);


    So, as you can see at the end it does the code: Bukkit.getScheduler().cancelTask(task); which stops the minigames running. This mean if you have 2 running when the first one is stoped so will the second one. Please could you help me find a solution for this

    Thanks in advance
    Joe
     
  2. Offline

    Tux2

    Use a concurrent hash map to store the tasks per arena:
    Code:java
    1. ConcurrentHashMap<String, BukkitTask> runningarenas = new ConcurrentHashMap();
    2.  
    3. Then, when creating it:
    4. BukkitTask temptask = Bukkit.getScheduler().runTaskTimer(plugin, runnable, timetilfirstrun, delay);
    5. runningarenas.put(arenaname, temptask);


    Then you stop it outside of it.

    However, what you're trying to do is cancel it when you're done with the count down. So what you're going to need to do is not use an anonymous inner class, as that isn't going to work for you. Create a new class that implements runnable and put all of the stuff in the run function in there. You'll also want to pass the arena that it belongs to in it's constructor. Once you get the BukkitTask have a function in the class where you can pass the task id, which it then saves inside the class:
    Code:java
    1. public void setTask(BukkitTask thetask) {
    2. task = thetask;
    3.  
    4. }
     
    Devil Boy and FabeGabeMC like this.
  3. Offline

    xTrollxDudex

    Tux2
    You shouldn't use Concurrent collections for sync tasks.
     
  4. Offline

    Tux2

    xTrollxDudex I use ConcurrentHashMaps as a basis of all my HashMap arrays as a general practice. Why? Using a ConcurrentHashMap for a sync task is far less dangerous than using a HashMap on an async task. I'll take the extremely small performance hit for greater coding flexibility.
     
  5. Offline

    fireblast709

    Tux2 ConcurrentHashMaps are pretty costly, and not needed when it is only used in one thread in your case
     
  6. Offline

    Tux2

    fireblast709 costly how? I decided to run a controlled test on both a ConcurrentHashMap as well as a HashMap, same variables, same queries, the only difference being the type of hash map. Here's the results on both (in milliseconds) for the result of 10 million insertions, queries and removals:
    ConcurrentHashMap insertion time: 9228
    ConcurrentHashMap retrieval time: 1184
    ConcurrentHashMap removal time: 2051
    HashMap insertion time: 6363
    HashMap retrieval time: 1034
    HashMap removal time: 1521

    The only differences is the insertion and removal times which is only 2.7 seconds longer using the Concurrent one on 10 million queries, or 0.0002865 milliseconds longer per insertion. Since I don't think he will be changing the table much I'd have to say the difference is quite negligible and only makes any sort of difference when you're constantly adding variables. Even the removal time is comparable with only half a second difference.

    I'm going to have to say that costly doesn't really describe the performance difference in these in a low volume application, especially one where Bukkit may just decide to make commands async one day and he'll have to terminate his thread using an async thread. Future proof it, so that way you don't have to worry.
     
    Devil Boy likes this.
Thread Status:
Not open for further replies.

Share This Page