/* * This file is part of aion-emu <aion-emu.com>. * * aion-emu is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * aion-emu is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with aion-emu. If not, see <http://www.gnu.org/licenses/>. */ package com.aionemu.gameserver; import java.util.Iterator; import org.apache.log4j.Logger; import com.aionemu.commons.utils.ExitCode; import com.aionemu.gameserver.configs.main.ShutdownConfig; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE; import com.aionemu.gameserver.network.loginserver.LoginServer; import com.aionemu.gameserver.services.PeriodicSaveService; import com.aionemu.gameserver.services.PlayerService; import com.aionemu.gameserver.utils.ThreadPoolManager; import com.aionemu.gameserver.utils.gametime.GameTimeManager; import com.aionemu.gameserver.world.World; import com.google.inject.Inject; /** * @author lord_rex * */ public class ShutdownHook extends Thread { private static final Logger log = Logger.getLogger(ShutdownHook.class); @Inject private World world; @Inject private PlayerService playerService; @Inject private LoginServer loginServer; @Inject private PeriodicSaveService playerUpdateService; @Override public void run() { if(ShutdownConfig.HOOK_MODE == 1) { shutdownHook(ShutdownConfig.HOOK_DELAY, ShutdownConfig.ANNOUNCE_INTERVAL, ShutdownMode.SHUTDOWN); } else if(ShutdownConfig.HOOK_MODE == 2) { shutdownHook(ShutdownConfig.HOOK_DELAY, ShutdownConfig.ANNOUNCE_INTERVAL, ShutdownMode.RESTART); } } public static enum ShutdownMode { NONE("terminating"), SHUTDOWN("shutting down"), RESTART("restarting"); private final String text; private ShutdownMode(String text) { this.text = text; } public String getText() { return text; } } private void sendShutdownMessage(int seconds) { try { Iterator<Player> onlinePlayers = world.getPlayersIterator(); if(!onlinePlayers.hasNext()) return; while(onlinePlayers.hasNext()) { Player player = onlinePlayers.next(); if(player != null && player.getClientConnection() != null) player.getClientConnection().sendPacket(SM_SYSTEM_MESSAGE.SERVER_SHUTDOWN(seconds)); } } catch(Exception e) { log.error(e.getMessage()); } } private void sendShutdownStatus(boolean status) { try { Iterator<Player> onlinePlayers = world.getPlayersIterator(); if(!onlinePlayers.hasNext()) return; while(onlinePlayers.hasNext()) { Player player = onlinePlayers.next(); if(player != null && player.getClientConnection() != null) player.getController().setInShutdownProgress(status); } } catch(Exception e) { log.error(e.getMessage()); } } private void shutdownHook(int duration, int interval, ShutdownMode mode) { for(int i = duration; i >= interval; i -= interval) { try { if(world.getPlayersIterator().hasNext()) { log.info("Runtime is " + mode.getText() + " in " + i + " seconds."); sendShutdownMessage(i); sendShutdownStatus(ShutdownConfig.SAFE_REBOOT); } else { log.info("Runtime is " + mode.getText() + " now ..."); break; // fast exit. } if(i > interval) { sleep(interval * 1000); } else { sleep(1000); } } catch(InterruptedException e) { return; } } // Disconnect login server from game. loginServer.gameServerDisconnected(); // Disconnect all players. Iterator<Player> onlinePlayers; onlinePlayers = world.getPlayersIterator(); while(onlinePlayers.hasNext()) { Player activePlayer = onlinePlayers.next(); try { playerService.playerLoggedOut(activePlayer); } catch(Exception e) { log.error("Error while saving player " + e.getMessage()); } } log.info("All players are disconnected..."); playerUpdateService.onShutdown(); // Save game time. GameTimeManager.saveTime(); // ThreadPoolManager shutdown ThreadPoolManager.getInstance().shutdown(); // Do system exit. if(mode == ShutdownMode.RESTART) Runtime.getRuntime().halt(ExitCode.CODE_RESTART); else Runtime.getRuntime().halt(ExitCode.CODE_NORMAL); log.info("Runtime is " + mode.getText() + " now..."); } /** * * @param delay * @param announceInterval * @param mode */ public void doShutdown(int delay, int announceInterval, ShutdownMode mode) { shutdownHook(delay, announceInterval, mode); } }