Two times faster countdown

Discussion in 'Spigot Plugin Development' started by LavaCode, Apr 26, 2017.


  1. Hello I wrote a Doodlejump plugin. Actually, everything works except the countdown.
    He always counts twice as fast.
    Thus, not 60, 59, 58 ... but 60, 58, 56.
    It happens at the levels and during the chat.

    What have I done wrong?

    Code:

    Code (Text):
      @EventHandler
      public void onJoin(PlayerJoinEvent e)
     
      {
         
        if (Bukkit.getOnlinePlayers().size() == 2) {
          scheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable()
          {
            public void run() {
           
              for (Player all : Bukkit.getOnlinePlayers()) {
              if (Lobby.number <= 61) {
                Lobby.number -= 1;
                         all.setLevel(Lobby.number);
             
                if (Lobby.number == 60) {
                all.sendMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 30) {
                  all.sendMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 15) {
                  all.sendMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if ((Lobby.number <= 10) && (Lobby.number != 0) && (Lobby.number != 1)) {
                  all.sendMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 1) {
                  all.sendMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §eeiner §3Sekunde!");
                } else if (Lobby.number == 0) {
                  all.sendMessage("§7[§eDoodleJump§7] §3Lasset die Spiele beginnen!");
                  all.setLevel(0);
                  Lobby.this.teleportarena();
                  Bukkit.getScheduler().cancelTask(Lobby.scheduler);
                }
               
               }
             
           
             }


           }
          }, 0L, 20L);
        }
      }
     
     
  2. 1) I would recommaned switch-case statements instead of similar if-else's
    The probable reason is that multiple calling of the event makes your plugin generate numerous runnables each of which lowers the counter.
     
  3. I just do not understand how I should do it differently
    Could you perhaps send me an edited code?
     
  4. Don't make a runnable per player, create a runnable class object and have it check for players online, if they're in the waiting area or whatever then start the countdown.

    One runnable to support any amount of players, creating a runnable per player is a bad idea and could multiply your problem when you get 10 players online.

    There's no way to edit the code you have and make it work in that event you need your timer in its own class that will handle this countdown.


    Sent from my iPhone using Tapatalk
     
    • Agree Agree x 1
  5. I would recommend you to create some Singleton class to handle all timing operations which has it's Runnable which can't be duplicated.
     

  6. Ok I try to use with the cases
     
  7. WAS

    WAS

    Why not just set a lobby start time in the future (timestamp) and refer to the current time (timestamp)?

    For example, use executes lobby for 2 minute countdown. You set a current timestamp + 2 minutes.

    Removes all need for tasks, as before you let anything execute you make sure current (timestamp) isn't less than the set time. If it is, you remove the set time in future (not past) and let the program execute.

    Getting the difference in time to display to the users (that could be a task) can be as simple as

    Code (Text):
    timeDiff = TimeUnit.MILLISECONDS.toMinutes(timestampInFuture - System.currentTimeMillis())
    If it's less than a minute
    Code (Text):
    timeDiff = TimeUnit.MILLISECONDS.toSeconds(timestampInFuture - System.currentTimeMillis())
    Using a method like this also ensures you aren't slowed down by the TPS. For example, you set it to two minutes, but your TPS is 10, so it's really 4 minutes.
     
    #7 WAS, Apr 26, 2017
    Last edited: Apr 26, 2017
  8. I have now solved it quite simply:

    Code (Text):
      public static int number = 61;
     
      @EventHandler
      public void onJoin(PlayerJoinEvent e)
     
      {
         
        if (Bukkit.getOnlinePlayers().size() == 2) {
          scheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable()
          {
            public void run() {
           
             for(Player all : Bukkit.getOnlinePlayers()){
                 all.setLevel(Lobby.number - 1);
             }
               
               
              if (Lobby.number <= 61) {
                Lobby.number -= 1;
                         
                   

               
                }
                if (Lobby.number == 60) {
                Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 30) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 15) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if ((Lobby.number <= 10) && (Lobby.number != 0) && (Lobby.number != 1)) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 1) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §eeiner §3Sekunde!");
                } else if (Lobby.number == 0) {
                   
                    for(Player all : Bukkit.getOnlinePlayers()){
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Lasset die Spiele beginnen!");
                  all.setLevel(0);
                  Lobby.this.teleportarena();
                  Bukkit.getScheduler().cancelTask(Lobby.scheduler);
                  }
                 
                 
                 
                }
               
               
             
           
             }


           
          }, 0L, 20L);
        }
      }
     
    • Like Like x 1
  9. It's just a very stupid solution I would say. It's fixed to number 2 of players making it useless for other cases
     
  10. Sniped

    Yeah this just kind of bandaided the issue.

    What if one of the two players leaves? What if the game ends, the original two players are online and a third player joins? The code won't run because there's not exactly two players online.
     
    • Agree Agree x 1
  11. I have to agree with @dNiym here. Just make a scheduler class, and let that handle all of it.

    OP. Your way is poor and does not show that you understand the object orientated language well.
     
    • Agree Agree x 1

  12. This is not the completly code:


    Here
    Code (Text):
    package Lobby;

    import com.avaje.ebean.EbeanServer;
    import java.io.File;
    import java.io.InputStream;
    import java.util.List;
    import java.util.logging.Logger;
    import main.main;
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Server;
    import org.bukkit.World;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.server.ServerListPingEvent;
    import org.bukkit.generator.ChunkGenerator;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginLoader;

    public class Lobby
      implements Listener, Plugin
    {
      private static main plugin;
      public static int scheduler;

      public Lobby(main plugin)
      {
        Lobby.plugin = plugin;
      }

      public static int number = 61;

      @EventHandler
      public void onJoin(PlayerJoinEvent e)

      {
       
        if (Bukkit.getOnlinePlayers().size() == 2) {
          scheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable()
          {
            public void run() {
         
             for(Player all : Bukkit.getOnlinePlayers()){
                 all.setLevel(Lobby.number - 1);
             }
             
             
              if (Lobby.number <= 61) {
                Lobby.number -= 1;
                       
                 

             
                }
                if (Lobby.number == 60) {
                Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 30) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 15) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if ((Lobby.number <= 10) && (Lobby.number != 0) && (Lobby.number != 1)) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §e" + Lobby.number + " §3Sekunden!");
                } else if (Lobby.number == 1) {
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Das Spiel startet in §eeiner §3Sekunde!");
                } else if (Lobby.number == 0) {
                 
                    for(Player all : Bukkit.getOnlinePlayers()){
                  Bukkit.broadcastMessage("§7[§eDoodleJump§7] §3Lasset die Spiele beginnen!");
                  all.setLevel(0);
                  Lobby.this.teleportarena();
                  Bukkit.getScheduler().cancelTask(Lobby.scheduler);
                  }
               
               
               
                }
             
             
           
         
             }


         
          }, 0L, 20L);
        }
      }

      private void teleportarena()
      {
        for (Player p : Bukkit.getOnlinePlayers())
        {
          World w = Bukkit.getWorld("dj");
          if (w == null) {
            return;
          }
          double x = w.getSpawnLocation().getX();
          double y = w.getSpawnLocation().getY();
          double z = w.getSpawnLocation().getZ();
       
          Location l = new Location(w, x, y, z);
       
          p.teleport(l);
        }
      }

      public void onPing(ServerListPingEvent e)
      {
        if (Bukkit.getOnlinePlayers().size() == 0) {
          e.setMotd("§aLobby");
        } else if (Bukkit.getOnlinePlayers().size() == 1) {
          e.setMotd("§6Lobby");
        }
        if (number == 0) {
          e.setMotd("§cIngame");
        }
      }

      public List<String> onTabComplete(CommandSender arg0, Command arg1, String arg2, String[] arg3)
      {
        return null;
      }

      public boolean onCommand(CommandSender arg0, Command arg1, String arg2, String[] arg3)
      {
        return false;
      }

      public FileConfiguration getConfig()
      {
        return null;
      }

      public File getDataFolder()
      {
        return null;
      }

      public EbeanServer getDatabase()
      {
        return null;
      }

      public ChunkGenerator getDefaultWorldGenerator(String arg0, String arg1)
      {
        return null;
      }

      public PluginDescriptionFile getDescription()
      {
        return null;
      }

      public Logger getLogger()
      {
        return null;
      }

      public String getName()
      {
        return null;
      }

      public PluginLoader getPluginLoader()
      {
        return null;
      }

      public InputStream getResource(String arg0)
      {
        return null;
      }

      public Server getServer()
      {
        return null;
      }

      public boolean isEnabled()
      {
        return false;
      }

      public boolean isNaggable()
      {
        return false;
      }

      public void onDisable() {}

      public void onEnable() {}

      public void onLoad() {}

      public void reloadConfig() {}

      public void saveConfig() {}

      public void saveDefaultConfig() {}

      public void saveResource(String arg0, boolean arg1) {}

      public void setNaggable(boolean arg0) {}
    }
     
     
  13. Maybe... That you should study Java
     
  14. Yes I know. Genrell I think I have a bit of nice coden and not the whole time with if and else.
     
  15. There's still the problem of what if the mini game ends and two players are in the game. If a third one joins the countdown will never restart. You need to move that runnable to its own class or at least out of the player join event. You can have it trigger when a player joins but it should only start the runnable if one isn't already running!


    Sent from my iPhone using Tapatalk
     
    • Agree Agree x 1
  16. I was about to suggest exactly that, this is a great idea.


    Sent from my iPhone using Tapatalk