About Bukkit.getServer().shutdown();

Discussion in 'Plugin Development' started by Kiwz, Dec 27, 2012.

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

    Kiwz

    I make a new thread with a runnable, in this runnable I have a while loop, at the end of the while loop I use "Bukkit.getServer().shutdown();
    This method is my own way of auto-restarting my bukkit server, and here is how I get the server to auto start again:
    This code is my start.bat file:

    @ECHO OFF
    :start
    cls
    java -Xmx12288M -Xms512M -jar "craftbukkit.jar" -log-strip-color
    CHOICE /C YN /N /T 6 /D N /M "Press 'Y' to exit!"
    If Errorlevel 2 Goto start
    If Errorlevel 1 Goto end
    :end

    Hope you could understand what I am trying to achive.

    Here is a pastebin of all the classes for this task.
    http://pastebin.com/YV6SzXMN
    http://pastebin.com/RUWuhGAE
    http://pastebin.com/Qt1WMiGm
    http://pastebin.com/ysn290yf

    Here is my plugin on GitHub:
    https://github.com/Kiwz/LarvikGaming

    So for my issue.
    Every now and then when this thing kicks in my server freezes, giving me "[INFO] Read timed out".
    To get it up again I need to kill java from task manager.
     
  2. Offline

    RainoBoy97

    Is the restart automatic?

    (pssst: jeg er også norsk)
     
  3. Offline

    Kiwz

    Yes it is
     
  4. For god's sake, PLEASE stop using threads when you don't know how synchronization works, and even more importantly don't use them with the Bukkit API, and even less for timed things like that!
    Bukkit has a scheduler, that lets you delay and repeat stuff on the main thread, and this is the only place where you are allowed to do anything.
    http://wiki.bukkit.org/Scheduler_Programming

    Stopping the server from an async thread is probably the maddest thing you could possibly do.
    Imagine you are sitting in the office, happily serving some phone calls and minding your own business, when suddenly someone walks up to you, punches you in the face and kicks you off your chair. How happy do you think your customer would be, now? ;)
    No, to properly end your work, YOU need to properly end your phone call, save the documents you were working on, etc..

    Granted, it's not that severe, because shutdown() only sets a flag, but that's bad enough.
     
  5. Offline

    fireblast709

    Nice metaphor, but absolutely true
     
  6. Offline

    Kiwz

    Thank you Bone008.
    I will read up on the bukkit scheduler and see how I can use that instead of my own thread.

    But can I use my own threads if it is not calling anything from the bukkit Api?
    Like some file copy stuff?

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

    william9518

    why not use bukkit? Bukkit.getServer().getScheduler().
     
  8. Offline

    tommycake50

    so i guess your asking how to start a batch file.
    well i can say one of two ways(might not work :/ but if it doesnt then theres a long way around it)
    first way
    Code:java
    1. ProcessBuilder pb = new ProcessBuilder("cmd.exe @ECHO OFF\n:start\ncls\njava -Xmx12288M -Xms512M -jar craftbukkit.jar -log-strip-color\nCHOICE /C YN /N /T 6 /D N /M Press 'Y' to exit!\nIf Errorlevel 2 Goto start\nIf Errorlevel 1 Goto end\n:end")
    2. Process p = pb.start();
    3.  

    second way
    Code:java
    1. Runtime r = Runtime.getRuntime();
    2. r.exec("java -Xmx12288M -Xms512M -jar craftbukkit.jar -log-strip-color");
    3.  
     
  9. Offline

    Kiwz

    Nope, my batch file is working perfectly, I was asking how to run a scheduled Bukkit.getServer().shutdown();
    I was aparantly doing it all wrong, and I am now gonna look into the Bukkit.getServer().getScheduler();

    Yeah, why not, I am just not familiar with that, but I need to learn it now.

    Okay, so I made this test-version of my plugin.
    It would be cool to get any comments about this way of shutting down a bukkit server.

    Code:
    package net.kiwz.larvikgaming;
     
    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class LarvikGaming extends JavaPlugin {
     
        public static String name = "[LarvikGaming] ";
        private Logger log = Logger.getLogger("Minecraft");
       
        public void onEnable() {
            Commands cmds = new Commands();
            getCommand("restart").setExecutor(cmds);
           
            Schedules sche = new Schedules();
            sche.StopServer();
            sche.StopServerMessage();
           
            log.info(name + "ENABLED!");
        }
     
        public void onDisable() {
            log.info(name + "DISABLED!");
        }
    }
    Code:
    package net.kiwz.larvikgaming;
     
    import net.kiwz.larvikgaming.utils.StopServer;
     
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
     
    public class Commands implements CommandExecutor {
       
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
           
            if (cmd.getName().equalsIgnoreCase("restart") && sender.hasPermission("larvikgaming.restart")) {
                StopServer ss = new StopServer();
                ss.stopServer();
                return true;
            }
            return false;
        }
    }
    Code:
    package net.kiwz.larvikgaming.utils;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Server;
    import org.bukkit.entity.Player;
     
    public class StopServer {
       
        public void stopServer() {
            Server server = Bukkit.getServer();
            Player[] players = server.getOnlinePlayers();
            for (Player player : players) {
                player.kickPlayer("Dont worry! It's just a restart. Come back in a few minutes");
            }
            server.shutdown();
        }
    }
    Code:
    package net.kiwz.larvikgaming.tasks;
     
    import net.kiwz.larvikgaming.utils.StopServer;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Server;
    import org.bukkit.plugin.Plugin;
     
    public class Schedules {
        static Server server = Bukkit.getServer();
        static Plugin larvikGaming = server.getPluginManager().getPlugin("LarvikGaming");
        int restartTime = 600 * 20;    //should be the same as 10 minutes!
       
        public void StopServer() {
            larvikGaming.getServer().getScheduler().scheduleSyncDelayedTask(larvikGaming, new Runnable() {
                @Override
                public void run() {
                    StopServer ss = new StopServer();
                    ss.stopServer();
                }
            }, restartTime);
        }
       
        public void StopServerMessage() {
            larvikGaming.getServer().getScheduler().scheduleSyncDelayedTask(larvikGaming, new Runnable() {
                @Override
                public void run() {
                    server.broadcastMessage(ChatColor.DARK_PURPLE + "**Server-Restart in 2min**");
                }
            }, restartTime - 2400);
        }
    }
    See the changes @github:
    https://github.com/Kiwz/LarvikGaming/commit/11d9b9b42a37cc20857e42106214d04ee8bdccb5

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

    fireblast709

    Kiwz well a lot of code for a small thing, but at least you warn your players. +1 for user-friendliness
     
  11. Offline

    Kiwz

    Hehe, thank you.
    And since you didnt complain about anything (except for "a lot of code") I guess this should be okay to run on an online server?
     
  12. Offline

    fireblast709

    Obviously try it out first. But yea, if you are sure it works flawlessly, try it out
     
  13. Offline

    Kiwz

    I did test it on an empty server, and it did work as intendent.
    I just hope it dosent freeze my online server like the last one did.

    With this code I hope I dont punches the office dude in the face and kicks him off his chair.

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

    fireblast709

    No in this code the office dude will just do his job and leave like intended
     
    Kiwz likes this.
  15. Offline

    Kiwz

    Big thanks to fireblast709 and Bone008 for helping me with this issue :D
     
  16. Hehe, nope, now you only kindly tell him to end his work because cake is waiting for him, and he will happily say good-bye to his customers :D

    Actually, assuming our office guy is the server thread, it's actually a bit different: He asks you if you have anything to say (executes the scheduled task), then you tell him "yo dawg, time for a break" and then he's like "sure thing, Johnny, give me a sec!" and he still has the opportunity to end his work properly ;)
     
    Kiwz likes this.
  17. Offline

    Kiwz

    Cool, love the way you explain it :D
    Could I ask how I can cancel all my scheduled tasks?
    I think I will need to do this or else they will stack (atleast the repeating one).
    In case of a /reload.
    Could I add this in my onDisable method:
    Bukkit.getScheduler().cancelTasks(Bukkit.getServer().getPluginManager().getPlugin("LarvikGaming"));
     
  18. Offline

    fireblast709

    Bukkit.getScheduler().cancelTasks(this) ;D
     
Thread Status:
Not open for further replies.

Share This Page