/**
* @(#)Shutdown.java
*
*
* @author
* @version 1.00 2007/7/28
*/
package psjump.server;
import java.util.logging.Logger;
import java.sql.*;
import psjump.L1DatabaseFactory;
import psjump.server.model.*;
import psjump.server.templates.*;
/**
*
* This class provides the functions for shutting down and restarting the server
* It closes all open clientconnections and saves all data.
*
* @version $Revision: 1.2 $ $Date: 2004/11/18 15:43:30 $
*/
public class Shutdown extends Thread {
private static Logger _log = Logger.getLogger(Shutdown.class.getName());
private static Shutdown _instance;
private static Shutdown _counterInstance = null;
private int secondsShut;
private int shutdownMode;
public static final int SIGTERM = 0;
public static final int GM_SHUTDOWN = 1;
public static final int GM_RESTART = 2;
public static final int ABORT = 3;
private static String[] _modeText = {"SIGTERM", "shuting down", "restarting", "aborting"};
/**
* Default constucter is only used internal to create the shutdown-hook instance
*
*/
public Shutdown() {
secondsShut = -1;
shutdownMode = SIGTERM;
}
/**
* This creates a countdown instance of Shutdown.
*
* @param seconds how many seconds until shutdown
* @param restart true is the server shall restart after shutdown
*
*/
public Shutdown(int seconds, boolean restart) {
if (seconds < 0) {
seconds = 0;
}
secondsShut = seconds;
if (restart) {
shutdownMode = GM_RESTART;
} else {
shutdownMode = GM_SHUTDOWN;
}
}
/**
* get the shutdown-hook instance
* the shutdown-hook instance is created by the first call of this function,
* but it has to be registrered externaly.
*
* @return instance of Shutdown, to be used as shutdown hook
*/
public static Shutdown getInstance()
{
if (_instance == null)
{
_instance = new Shutdown();
}
return _instance;
}
/**
* this function is called, when a new thread starts
*
* if this thread is the thread of getInstance, then this is the shutdown hook
* and we save all data and disconnect all clients.
*
* after this thread ends, the server will completely exit
*
* if this is not the thread of getInstance, then this is a countdown thread.
* we start the countdown, and when we finished it, and it was not aborted,
* we tell the shutdown-hook why we call exit, and then call exit
*
* when the exit status of the server is 1, startServer.sh / startServer.bat
* will restart the server.
*
*/
public void run() {
if (this == _instance) {
// last byebye, save all data and quit this server
// logging doesnt work here :(
saveData();
// server will quit, when this function ends.
} else {
// gm shutdown: send warnings and then call exit to start shutdown sequence
countdown();
// last point where logging is operational :(
_log.warning("GM shutdown countdown is over. " + _modeText[shutdownMode] + " NOW!");
switch (shutdownMode) {
case GM_SHUTDOWN:
_instance.setMode(GM_SHUTDOWN);
System.exit(0);
break;
case GM_RESTART:
_instance.setMode(GM_RESTART);
System.exit(1);
break;
}
}
}
/**
* This functions starts a shutdown countdown
*
* @param activeChar GM who issued the shutdown command
* @param seconds seconds until shutdown
* @param restart true if the server will restart after shutdown
*/
public void startShutdown(L1PcInstance activeChar, int seconds, boolean restart) {
Announcements _an = Announcements.getInstance();
_log.warning("GM: "+activeChar.get_objectId()+" issued shutdown command. " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");
_an.announceToAll("Server is " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");
if (_counterInstance != null) {
_counterInstance._abort();
}
// the main instance should only run for shutdown hook, so we start a new instance
_counterInstance = new Shutdown(seconds, restart);
_counterInstance.start();
}
/**
* This function aborts a running countdown
*
* @param activeChar GM who issued the abort command
*/
public void abort(L1PcInstance activeChar) {
Announcements _an = Announcements.getInstance();
_log.warning("GM: "+activeChar.get_name()+" issued shutdown ABORT. ");
_an.announceToAll("Server aborts shutdown and continues normal operation!");
if (_counterInstance != null) {
_counterInstance._abort();
}
}
/**
* set the shutdown mode
* @param mode what mode shall be set
*/
private void setMode(int mode) {
shutdownMode = mode;
}
/**
* set the shutdown mode
* @param mode what mode shall be set
*/
int getMode() {
return shutdownMode;
}
/**
* set shutdown mode to ABORT
*
*/
private void _abort() {
shutdownMode = ABORT;
}
/**
* this counts the countdown and reports it to all players
* countdown is aborted if mode changes to ABORT
*/
private void countdown(){
Announcements _an = Announcements.getInstance();
try{
while (secondsShut > 0){
switch (secondsShut){
case 240:_an.announceToAll("The server will shutdown in 4 minutes.");break;
case 180:_an.announceToAll("The server will shutdown in 3 minutes.");break;
case 120:_an.announceToAll("The server will shutdown in 2 minutes.");break;
case 60:_an.announceToAll("The server will shutdown in 1 minute.");break;
case 30:_an.announceToAll("The server will shutdown in 30 seconds.");break;
case 10:_an.announceToAll("The server will shutdown in 10 seconds.");break;
case 5:_an.announceToAll("The server will shutdown in 5 seconds.");break;
case 4:_an.announceToAll("The server will shutdown in 4 seconds.");break;
case 3:_an.announceToAll("The server will shutdown in 3 seconds.");break;
case 2:_an.announceToAll("The server will shutdown in 2 seconds.");break;
case 1:_an.announceToAll("The server will shutdown in 1 second.");break;
}
secondsShut--;
int delay = 1000; //milliseconds
Thread.sleep(delay);
if(shutdownMode == ABORT) break;
}
} catch (InterruptedException e) {
//this will never happen
}
}
/**
* this sends a last byebye, disconnects all players and saves data
*
*/
private void saveData() {
switch (shutdownMode){
case SIGTERM:
System.err.println("[psjump] ¼¹ö °Á¦ Á¾·á.");
break;
case GM_SHUTDOWN:
System.err.println("[psjump] ¿î¿µÀÚÀÇ ±ÇÇÑÀ¸·Î ¼¹ö ´Ù¿î");
break;
case GM_RESTART:
System.err.println("[psjump] GM restart received. Restarting NOW!");
break;
}
GameServerSetting.getInstance().set_quit(false);
// ¸ðµçÇ÷¹ÀÌ¾î ¼¹ö¿Í ¿¬°á ²÷±â.
System.err.println("[psjump] ¸ðµçÇ÷¹ÀÌ¾î ¿¬°áÀ» Á¾·áÇÏ´Â ÁßÀÔ´Ï´Ù.");
disconnectAllCharacters();
//SaveAllName();
System.out.println("[Àӽ÷ΠDB Accounts Table ±â·Ï ÇÏ´Â°É ¸·ÀÚ!]");
IdFactory.getInstance().saveCurrentState();
GameServerSetting.getInstance().save();
System.err.println(" - ¿Ï·á");
}
public void SaveAllName(){
Connection con = null;
PreparedStatement statement = null;
try{
con = L1DatabaseFactory.getInstance().getConnection();
String[] name = ChaNameListTable.getInstance().getAllName();
try{
statement = con.prepareStatement("DELETE FROM cha_name_list");
statement.execute();
statement.close();
}catch (SQLException e){
System.out.println("");
System.out.println("[psjump] cha_name_list: ¿¡·¯ ¹ß»ý");
}
System.out.print("length: ");
System.out.println(ChaInfoListTable.getInstance().get_size());
for(int i=0 ; i<name.length ; ++i){
// for(int i=0 ; i<ChaInfoListTable.getInstance().get_size() ; ++i){
try{
statement = con.prepareStatement("INSERT INTO cha_name_list SET ¼ø¹ø=?,À̸§=?,·¹º§=?,Ç÷¸ÍID=?,¾Æµ¥³ª=?");
statement.setInt(1, i + 1);
statement.setString(2, name[i]);
statement.setInt(3, ChaInfoListTable.getInstance().getTemplate(name[i]).get_level());
statement.setInt(4, ChaInfoListTable.getInstance().getTemplate(name[i]).get_clanid());
statement.setInt(5, ChaInfoListTable.getInstance().getTemplate(name[i]).get_adena());
statement.execute();
statement.close();
}catch (SQLException e){
System.out.println("");
System.out.println("[psjump] cha_name_list: ¿¡·¯ ¹ß»ý");
}
}
con.close();
}catch (SQLException e){
System.out.println("");
System.out.println("[psjump] SaveAllName ¸Þ¼Òµå ¿¡·¯ ¹ß»ý");
}
}
/**
* ¸ðµçÇ÷¹ÀÌ¾î ¼¹ö¿Í ¿¬°á ²÷À¸¸é¼ ÀúÀåÇϱâ
*
*/
public void disconnectAllCharacters(){
L1PcInstance[] players = L1World.getInstance().getAllPlayers();
for(int i=0; i<players.length ;i++){
//Logout Character
try {
players[i].sendPackets(players[i].get_netConnection().bph().S_Disconnect(), true);
players[i].get_netConnection().close();
players[i].get_netConnection().saveCharToDisk(players[i]);
}catch (Exception e){}
}
}
public void startTelnetShutdown(String IP, int seconds, boolean restart)
{
Announcements _an = Announcements.getInstance();
_log.warning("IP: " + IP + " issued shutdown command. " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");
_an.announceToAll("Server is " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");
if (_counterInstance != null) {
_counterInstance._abort();
}
_counterInstance = new Shutdown(seconds, restart);
_counterInstance.start();
}
/**
* This function aborts a running countdown
*
* @param IP IP Which Issued shutdown command
*/
public void Telnetabort(String IP) {
Announcements _an = Announcements.getInstance();
_log.warning("IP: " + IP + " issued shutdown ABORT. " + _modeText[shutdownMode] + " has been stopped!");
_an.announceToAll("Server aborts " + _modeText[shutdownMode] + " and continues normal operation!");
if (_counterInstance != null) {
_counterInstance._abort();
}
}
}
----
errors:
--------------------Configuration: <Default>--------------------
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:15: cannot find symbol
symbol : class L1DatabaseFactory
location: package psjump
import psjump.L1DatabaseFactory;
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:16: package psjump.server.model does not exist
import psjump.server.model.*;
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:17: package psjump.server.templates does not exist
import psjump.server.templates.*;
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:131: cannot find symbol
symbol : class L1PcInstance
location: class psjump.server.Shutdown
public void startShutdown(L1PcInstance activeChar, int seconds, boolean restart) {
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:150: cannot find symbol
symbol : class L1PcInstance
location: class psjump.server.Shutdown
public void abort(L1PcInstance activeChar) {
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:132: cannot find symbol
symbol : class Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:132: cannot find symbol
symbol : variable Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:151: cannot find symbol
symbol : class Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:151: cannot find symbol
symbol : variable Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:189: cannot find symbol
symbol : class Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:189: cannot find symbol
symbol : variable Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:234: cannot find symbol
symbol : variable GameServerSetting
location: class psjump.server.Shutdown
GameServerSetting.getInstance().set_quit(false);
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:240: cannot find symbol
symbol : variable IdFactory
location: class psjump.server.Shutdown
IdFactory.getInstance().saveCurrentState();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:241: cannot find symbol
symbol : variable GameServerSetting
location: class psjump.server.Shutdown
GameServerSetting.getInstance().save();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:249: cannot find symbol
symbol : variable L1DatabaseFactory
location: class psjump.server.Shutdown
con = L1DatabaseFactory.getInstance().getConnection();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:250: cannot find symbol
symbol : variable ChaNameListTable
location: class psjump.server.Shutdown
String[] name = ChaNameListTable.getInstance().getAllName();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:260: cannot find symbol
symbol : variable ChaInfoListTable
location: class psjump.server.Shutdown
System.out.println(ChaInfoListTable.getInstance().get_size());
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:268: cannot find symbol
symbol : variable ChaInfoListTable
location: class psjump.server.Shutdown
statement.setInt(3, ChaInfoListTable.getInstance().getTemplate(name[i]).get_level());
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:269: cannot find symbol
symbol : variable ChaInfoListTable
location: class psjump.server.Shutdown
statement.setInt(4, ChaInfoListTable.getInstance().getTemplate(name[i]).get_clanid());
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:270: cannot find symbol
symbol : variable ChaInfoListTable
location: class psjump.server.Shutdown
statement.setInt(5, ChaInfoListTable.getInstance().getTemplate(name[i]).get_adena());
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:290: cannot find symbol
symbol : class L1PcInstance
location: class psjump.server.Shutdown
L1PcInstance[] players = L1World.getInstance().getAllPlayers();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:290: cannot find symbol
symbol : variable L1World
location: class psjump.server.Shutdown
L1PcInstance[] players = L1World.getInstance().getAllPlayers();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:303: cannot find symbol
symbol : class Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:303: cannot find symbol
symbol : variable Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:320: cannot find symbol
symbol : class Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
C:\Yeo\Copy of Yeo\psjump\server\Shutdown.java:320: cannot find symbol
symbol : variable Announcements
location: class psjump.server.Shutdown
Announcements _an = Announcements.getInstance();
^
26 errors
Process completed.