📄 serverdirector.java
字号:
/*
* Light And Shadow. A Persistent Universe based on Robert Jordan's Wheel of Time Books.
* Copyright (C) 2001-2002 WOTLAS Team
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package wotlas.server;
import wotlas.server.setup.ServerAdminGUI;
import wotlas.utils.Debug;
import wotlas.utils.Tools;
import wotlas.utils.FileTools;
import wotlas.libs.log.*;
import wotlas.libs.net.*;
import wotlas.libs.sound.SoundLibrary;
import wotlas.common.*;
import wotlas.common.RemoteServersPropertiesFile;
import wotlas.libs.aswing.ALoginDialog;
import wotlas.common.environment.*;
import wotlas.common.universe.*;
import wotlas.common.action.*;
import java.awt.Frame;
import java.io.File;
import java.util.Properties;
import java.net.*;
/** The MAIN server class. It starts the PersistenceManager, the ServerManager
* and the DataManager. So got it ? yeah, it's the boss on the server side...
*
* @author Aldiss
* @see wotlas.server.GameServer
* @see wotlas.server.PersistenceManager
*/
public class ServerDirector implements Runnable, NetServerListener {
/*------------------------------------------------------------------------------------*/
/** Server Command Line Help
*/
public final static String SERVER_COMMAND_LINE_HELP =
"Usage: ServerDirector -[debug|admin|erroronly|daemon|help] -[base <path>]\n\n"
+"Examples : \n"
+" ServerDirector -admin : will display the admin GUI only.\n"
+" ServerDirector -daemon : the server will display nothing.\n"
+" ServerDirector -erroronly : the server will only print errors.\n"
+" ServerDirector -base ../base : sets the data location.\n\n"
+"If the -base option is not set we search for data in "
+ResourceManager.DEFAULT_BASE_PATH
+"\n\n";
/** Format of the server log name.
*/
public final static String SERVER_LOG_PREFIX = "wot-server-";
public final static String SERVER_LOG_SUFFIX = ".log";
/*------------------------------------------------------------------------------------*/
/** Our server properties.
*/
private static ServerPropertiesFile serverProperties;
/** Our remote server properties.
*/
private static RemoteServersPropertiesFile remoteServersProperties;
/** Our resource manager
*/
private static ResourceManager resourceManager;
/*------------------------------------------------------------------------------------*/
/** Our Server Manager.
*/
private static ServerManager serverManager;
/** Our Data Manager.
*/
private static DataManager dataManager;
/** Our default ServerDirector (Peristence Thread).
*/
private static ServerDirector serverDirector;
/*------------------------------------------------------------------------------------*/
/** Shutdown Thread.
*/
public static Thread shutdownThread;
/** Period for changing the keys.
*/
public static byte updateKeysPeriod =0;
/** Immediate stop of persistence thread ?
*/
public static boolean immediatePersistenceThreadStop = false;
/** Default password for transfer
*/
private static String password;
/** To stop the persistence thread.
*/
private boolean mustStop = false;
/** To tell if the server is enabled or not (network interfaces available).
*/
private boolean serverEnabled = true;
/** Show debug information ?
*/
public static boolean SHOW_DEBUG = false;
static private long genUniqueKeyId;
/*------------------------------------------------------------------------------------*/
/** Main Class. Starts the Wotlas Server.
* @param argv enter -help to get some help info.
*/
public static void main( String argv[] ) {
/* first of all Manage the Preloader for WorldGenerator*/
WorldManager.PRELOADER_STATUS = PreloaderEnabled.LOAD_SERVER_DATA;
UserAction.InitAllActions();
// STEP 0 - We parse the command line options
boolean isDaemon = false;
boolean displayAdminGUI = false;
String basePath = ResourceManager.DEFAULT_BASE_PATH;
Debug.displayExceptionStack( false );
for( int i=0; i<argv.length; i++ ) {
if( !argv[i].startsWith("-") )
continue;
if (argv[i].equals("-debug")) { // -- TO SET THE DEBUG MODE --
if(isDaemon) {
System.out.println("Incompatible options.");
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
System.out.println("mode DEBUG on");
SHOW_DEBUG = true;
Debug.displayExceptionStack( true );
}
else if (argv[i].equals("-erroronly")) { // -- TO ONLY DISPLAY ERRORS --
if(SHOW_DEBUG) {
System.out.println("Incompatible options.");
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
Debug.displayExceptionStack( false );
Debug.setLevel(Debug.ERROR);
}
else if (argv[i].equals("-admin")) { // -- TO ONLY DISPLAY THE ADMIN GUI --
if(isDaemon) {
System.out.println("Incompatible options.");
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
displayAdminGUI = true;
}
else if (argv[i].equals("-daemon")) { // -- DAEMON MODE --
if(SHOW_DEBUG) {
System.out.println("Incompatible options.");
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
isDaemon = true;
Debug.displayExceptionStack( true );
Debug.setLevel(Debug.NOTICE);
}
else if(argv[i].equals("-base")) { // -- TO SET THE CONFIG FILES LOCATION --
if(i==argv.length-1) {
System.out.println("Location missing.");
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
basePath = argv[i+1];
}
else if(argv[i].equals("-help")) { // -- TO DISPLAY THE HELP --
System.out.println(SERVER_COMMAND_LINE_HELP);
return;
}
}
// STEP 1 - Creation of the ResourceManager
resourceManager = new ResourceManager();
if( !resourceManager.inJar() )
resourceManager.setBasePath(basePath);
// STEP 2 - We create a LogStream to save our Debug messages to disk.
try{
if(isDaemon) {
// We don't print the Debug messages on System.err
Debug.setPrintStream( new DaemonLogStream( resourceManager.getExternalLogsDir()
+SERVER_LOG_PREFIX+System.currentTimeMillis()+SERVER_LOG_SUFFIX ) );
}
else if(displayAdminGUI) {
Debug.setPrintStream( new JLogStream( new javax.swing.JFrame(),
resourceManager.getExternalLogsDir()+"server-setup.log",
"log-title-dark.jpg", resourceManager ) );
}
else{
// We also print the Debug messages on System.err
Debug.setPrintStream( new ServerLogStream( resourceManager.getExternalLogsDir()
+SERVER_LOG_PREFIX+System.currentTimeMillis()+SERVER_LOG_SUFFIX ) );
}
}
catch( java.io.FileNotFoundException e ) {
e.printStackTrace();
return;
}
// STEP 3 - We control the VM version and load our vital config files.
if( !Tools.javaVersionHigherThan( "1.3.0" ) )
Debug.exit();
Debug.signal( Debug.NOTICE, null, "*----------------------------------------*" );
Debug.signal( Debug.NOTICE, null, "| Wheel Of Time - Light & Shadow |" );
Debug.signal( Debug.NOTICE, null, "| Copyright (C) 2001-2003 WOTLAS Team |" );
Debug.signal( Debug.NOTICE, null, "*---------------------------------------*\n");
Debug.signal( Debug.NOTICE, null, "| ver 2.0 is an alpha: |" );
Debug.signal( Debug.NOTICE, null, "| |" );
Debug.signal( Debug.NOTICE, null, "| Every times a new comes up u need |" );
Debug.signal( Debug.NOTICE, null, "| to delete universe and home directory |" );
Debug.signal( Debug.NOTICE, null, "| and reload server-world-generator |" );
Debug.signal( Debug.NOTICE, null, "| Diego |" );
Debug.signal( Debug.NOTICE, null, "*---------------------------------------*" );
Debug.signal( Debug.NOTICE, null, "Code version : "+resourceManager.WOTLAS_VERSION );
if( !resourceManager.inJar() )
Debug.signal( Debug.NOTICE, null, "Data directory : "+basePath );
else
Debug.signal( Debug.NOTICE, null, "Data directory : JAR File" );
serverProperties = new ServerPropertiesFile(resourceManager);
remoteServersProperties = new RemoteServersPropertiesFile(resourceManager);
if(displayAdminGUI) {
ServerAdminGUI.create();
return; // we just display the admin GUI, we don't start the server.
}
// STEP 4 - We ask the ServerManager to get ready
serverManager = new ServerManager(resourceManager);
Debug.signal( Debug.NOTICE, null, "Server Manager created..." );
// STEP 5 - We ask the DataManager to load the worlds & client accounts
dataManager = new DataManager(resourceManager);
dataManager.init( serverProperties );
// STEP 6 - Sound Library for alerts... (we only create a sound player)
SoundLibrary.createSoundLibrary( serverProperties, null, resourceManager );
// STEP 7 - Start of the GameServer, AccountServer & GatewayServer !
Debug.signal( Debug.NOTICE, null, "Starting Game server, Account server & Gateway server..." );
serverDirector = new ServerDirector();
serverManager.getGameServer().addServerListener( serverDirector );
serverManager.start();
// STEP 8 - We generate new keys for special characters
updateKeys();
// STEP 9 - Adding Shutdown Hook
shutdownThread = new Thread() {
public void run() {
immediatePersistenceThreadStop = true;
Debug.signal(Debug.CRITICAL,null,"Received VM Shutdown Signal.");
// 1 - Lock servers...
serverManager.lockServers();
// 2 - We warn connected clients
serverManager.sendWarningMessage( "Your server has been stopped.\n"
+"Try to reconnect in a few minutes.");
// 3 - We close all remaining connections & save the data
serverManager.closeAllConnections();
dataManager.shutdown(true);
serverManager.shutdown();
SoundLibrary.clear();
Debug.signal(Debug.CRITICAL,null,"Data Saved. Exiting.");
Debug.flushPrintStream();
}
};
Runtime.getRuntime().addShutdownHook(shutdownThread);
// STEP 10 - Everything is ok ! we enter the persistence loop
Debug.signal( Debug.NOTICE, null, "Starting persistence thread..." );
Thread persistenceThread = new Thread( serverDirector );
persistenceThread.start();
// showing environment type
Debug.signal( Debug.NOTICE, null, "Server environment name : "+EnvironmentManager.getEnvironmentName()+" ." );
EnvironmentManager.getEnvironmentHour();
// If we are in "daemon" mode the only way to stop the server is via signals.
// Otherwise we wait 2s and wait for a key to be pressed to shutdown...
if( !isDaemon ) {
Tools.waitTime( 2000 ); // 2s
Debug.signal( Debug.NOTICE, null, "Press <ENTER> if you want to shutdown this server." );
try{
System.in.read();
}catch( Exception e ) {
e.printStackTrace();
}
Debug.signal( Debug.NOTICE, null, "Leaving in 30s..." );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -