Solved Timer with real life date.

Discussion in 'Spigot Plugin Development' started by TxmyDevelopment, Jan 17, 2020.

  1. Hello everyone, i'm making a plugin for my UHC server and im doing the twitter post, and i could do this code that works perfectly but what happens is that the server registers the real time 3 seconds before it should.
    Here's the code:
    Code (Java):
        public static ZonedDateTime later;

        @Override
        public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
            if(sender instanceof Player) {
                if (sender.hasPermission("uhc.mod") || sender.hasPermission("uhc.admin")) {
                    Player player= (Player) sender;
                    if (args.length == 0 || args.length > 1) {
                        player.sendMessage(Formatter.format("&cThe command has two arguments: /post <time>"));
                        return false;
                    }
                    String time = args[0];
                    if (time.equalsIgnoreCase("help")) {
                        player.sendMessage(Formatter.format("&cPlease use /post &e<time>"));
                        return false;
                    }
                    String replaced = time.replace(":", "");
                    if (!isInt(replaced)) {
                        player.sendMessage(Formatter.format("&cPlease use /post &e<time>"));
                        return false;
                    }
                    ZonedDateTime now = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("America/Buenos_Aires"));
                    ZonedDateTime later = ZonedDateTime.of(now.getYear(), now.getMonthValue(), now.getDayOfMonth(), Integer.parseInt(time.split(":")[0]), Integer.parseInt(time.split(":")[1]), 0, now.getNano(), ZoneId.of("America/Buenos_Aires"));

                    if(later.getMinute() <= now.getMinute()){
                        player.sendMessage(Formatter.format("&cYou should enter a time that is greater that now."));
                        return false;
                    }
                    PostCommand.later = later;
                    int diff = later.getMinute() - now.getMinute();
                    StringBuilder str = new StringBuilder();
                    for (String string : UHC.get().getFileManager().getConfig().getStringList("TWEET")) {
                        str.append(string.replace("<time>", time)).append("\n");
                    }
                    player.chat("/tweet " + str.toString());
                    Bukkit.broadcastMessage(Formatter.format("&cUHC &f> &eThe game was posted to be opened at &b" + time));
                    UHC.get().getGame().setPosted(true);
                    UHC.get().getBoardManager().buildScoreboardPosted();
                    new AfterPostRunnable().runTaskTimer(UHC.get(), 0L, 20L);
                    Bukkit.getOnlinePlayers().forEach(p -> p.setScoreboard(UHC.get().getBoardManager().getLobbyScoreboardPosted()));
                } else sender.sendMessage(Formatter.format("&cYou don't have permission to do this."));
            }
            return true;
        }
     

    Code (Java):
        @Override
        public void run() {
            ZonedDateTime now = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("America/Buenos_Aires"));
            ZonedDateTime later = PostCommand.later;
            int hour = later.getHour();
            int minute = later.getMinute();
            int second = 0;
            if (now.getHour() == hour && now.getMinute() == minute && now.getSecond() == second) {
                cancel();
                pl.getWhitelist().setEnabled(false);
                pl.getGame().setGameState(GameState.STARTING);
                new ScatterRunnable().runTaskTimer(pl, 0L, 20L);
            } else {
                long o1 = ChronoUnit.HOURS.between(now, later);
                long o2 = ChronoUnit.MINUTES.between(now, later);
                long o3 = ChronoUnit.SECONDS.between(now, later);

                long diff = (o1 * 60) + (o2 * 60) + (o3);
                SimpleDateFormat formatter;
                if ((hour - now.getHour()) >= 1) {
                    formatter = new SimpleDateFormat("hh:mm:ss");
                } else {
                    formatter = new SimpleDateFormat("mm:ss");
                }

                Date date = new Date(diff * 1000);
                boardManager.getLobbyScoreboardPosted().getTeam("timer").setSuffix(formatter.format(date));
            }
        }
     

    In advanced, I know i could set the second to 3 and that would fix the problem, but i really want to make it work like this.

    Thanks to all.
     
  2. Are you using bukkit runnable for the timer? that means it will be delayed if tps of the server goes under 20
     
  3. How do you start your runnable?
     
  4. Yes, and I have noticed that when the runnable starts, it doesn't update the scoreboard at the moment, it takes those 3 seconds, but i don't know why delays, and i'm frequently checking the tps and there are not changes.
     
  5. Code (Text):
    new AfterPostRunnable().runTaskTimer(UHC.get(), 0L, 20L);
     
  6. It may be that some stuff the plugin do when the game starts is causing a lag spike like world generation/load. You can still use debug messages to spot the specific part of the code causing the delay.
     
  7. You should use runTaskTimerAsynchronously
     
  8. No you shouldn’t. That will potentially cause more problems than it solves based on the code OP has posted so far, namely causing race conditions with the whitelist and game state variables and the mutation of the scoreboard async.
     
    • Agree Agree x 1