Solved Restarting server automatically without editing batch file

Discussion in 'Plugin Development' started by Jxlly, Apr 19, 2021.

  1. Offline

    Jxlly

    So, what I'm trying to do the last days, was to make a plugin that restarts the server automatically per command after a specific time, but without editing the start batch file.

    I knew that there was a /restart command in the game. For me the /restart command works great. So what I did, was to combine the /restart command from the game with a timer.

    Now here is the problem:
    When the timer hits a specific value, the server performs:

    Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "restart");

    When I look into the console nothing happens. No error, no message, server is not frozen... (even wih try/catch)
    I only see my debug test messages before and after the code.

    By the way, if you know a better way, to restart the server without editing the batch file, just let me know.

    Thanks in advance, Jxlly.
     
  2. Offline

    pixelrider2000

    First, although I don't know if that's of any interest to you, there are a bunch of plugins that do exactly that (restart the server). But since I think this is not your problem because you rather wanna know how you can do that yourself here is my idea: Since the code that you posted should work perfectly fine I reckon that it has something to do with the console not being permitted to execute such a command in the same vein that a command block (at least on my server) can't execute the "/kick" command.
    When I tested the same code but with "stop" it worked perfectly fine for me. So my second idea would be that it has something to do with your code so could you please post your code.
     
  3. Offline

    Jxlly

    First off all, thanks for helping me.
    I'm gonna do question by question to make it more understandable.

    Why I want to do that:
    First, I'm not really into the plugins market, but I think there are no plugins that can restart automatically WITHOUT editing the batch file, correct me if I'm wrong.
    Secondly, I have a free server (not aternos) that stops after about 3-5 Minutes when there are 0 players online and I don't wanna accept that because it was only brought into the servers about a few days before. So what I want to do right now, is to restart the servers every 3 minutes so it's more or less the whole time online without me doing something.

    Depends on Console:
    This could actually be true, maybe the hosters have thought about this, but on my localhost server the plugin doesn't work either.

    Depends on Code:
    Here's my code:

    Quick explaination:
    -If a player leaves and no one's online, it starts the methode startCounter();
    -From there it checks, if the plugin is enabled.
    -If yes, then it starts a scheduler while it counts the seconds.
    -Now every second it checks if a player joins the server, then it would stop the counter.
    -If there are no players online, it restarts after 3 minutes.
    -And performs the dispatchCommand();

    Code:
    import de.jxlly.autorestart.AutoRestart;
    import org.bukkit.Bukkit;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class CounterManager {
    
        private final ScheduledExecutorService executorService;
        private int elapsedSeconds;
    
        public CounterManager() {
            this.executorService = Executors.newScheduledThreadPool(0);
        }
    
        public void startCounter() {
            if (AutoRestart.getPlugin().getAutoRestartManager().isPluginActivated()) {
    
                this.elapsedSeconds = 0;
                this.executorService.scheduleAtFixedRate(() -> {
    
                    if (Bukkit.getOnlinePlayers().size() == 0) {
                        this.elapsedSeconds++;
    
                        switch (this.elapsedSeconds) {
                            case 10:
                                System.out.println("Server is restarting in 3 minutes");
                                break;
                            case 70:
                                System.out.println("Server is restarting in 2 minutes");
                                break;
                            case 130:
                                System.out.println("Server is restarting in 1 minutes");
                                break;
                            case 190:
                                System.out.println("Server is restarting...");
                                Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "restart");
                                break;
                        }
                    } else {
                        endCounter();
                    }
                }, 0, 1, TimeUnit.SECONDS);
            }
        }
    
        private void endCounter() {
            try {
                executorService.shutdown();
            } catch (Exception e) {
            }
        }
    }
    
     
  4. Offline

    pixelrider2000

    I understand. I would like to know if the Sysout is being sent or not. Or in other words, can you find a "Server is restarting..." in your console? Because if you can see this message than you can be almost a 100% sure that the problem is with the Bukkit.dispatchCommand. Btw. have you tried to e.g. make a command that when you type it in executes this line of code "Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "restart");". 'Cause when you can execute this via command then you know that something is up with your Timer. So let me know if you can execute the code in any other way or if you can make the console execute different commands instead.
     
  5. Offline

    Jxlly

    Hi, so before I looked up the console I added a "hello world" via the "/say" command with the dispatchCommand and Sysout at the end of the code, now its like:

    Code:
    System.out.println("Server is restarting...");
    Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "say hello world!");
    Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "restart");
    System.out.println("Done");
    So I looked up the console and I can see the Sysout "Server restarting...".
    But from there I neither see the 2 dispatchCommand() nor the Sysout with "Done".
    Next thing was to make a command with the dispatchCommand(). I did that and the restart worked somehow perfectly fine.

    So my idea now is, that is has something to do with the ScheduledExecutorService or the Listener, I put the Listener here:

    Code:
    @EventHandler
        public void onQuit(PlayerQuitEvent event) {
            Bukkit.getScheduler().scheduleSyncDelayedTask(AutoRestart.getPlugin(), () -> {
                if (Bukkit.getOnlinePlayers().size() == 0) {
                    AutoRestart.getPlugin().getCounterManager().startCounter();
                }
            });
        }
    I think it maybe doesn't work because of the delay, that I had to put there because the Eventhandler is too fast for the player's disconnect, so when someone leaves it shows like the playercounter from before the disconnect. Let me know if you know it has something to do with the delay.

    Or it is the ScheduledExecutorService, that won't execute the dispatchCommand methode.

    UPDATE:
    While writing this message, I tried something:

    Code:
    import de.jxlly.autorestart.AutoRestart;
    import org.bukkit.Bukkit;
    
    public class CounterManager {
       
        private int elapsedSeconds;
        private int taskID;
    
        public void startCounter() {
            if (AutoRestart.getPlugin().getAutoRestartManager().isPluginActivated()) {
    
                taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(AutoRestart.getPlugin(), new Runnable() {
                    @Override
                    public void run() {
    
                        elapsedSeconds++;
    
                        switch (elapsedSeconds) {
                            case 10:
                                System.out.println("Server is restarting in 3 minutes");
                                break;
                            case 70:
                                System.out.println("Server is restarting in 2 minutes");
                                break;
                            case 130:
                                System.out.println("Server is restarting in 1 minutes");
                                break;
                            case 190:
                                System.out.println("Server is restarting...");
                                Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), "restart");
                                Bukkit.getScheduler().cancelTask(taskID);
                                break;
                        }
                    }
                }, 0, 20);
            }
        }
    }
    
    And for some reason it works now, I replaced the ScheduledExecutorService with the
    scheduleSyncRepeatingTask() from Bukkit.

    Thanks for your advice and the useful tips, next time I'll just try more on my own :)
     

Share This Page