📄 serverdirector.java
字号:
try{
Runtime.getRuntime().removeShutdownHook(shutdownThread);
}catch(Exception e) {
return; // we couldn't remove the hook, it means the VM is already exiting
}
serverDirector.shutdown();
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** Run method for Thread.
*/
public void run(){
do{
// 1 - we wait the persistence period minus 2 minutes
synchronized( this ) {
try{
wait( serverProperties.getIntegerProperty("init.persistencePeriod")*1000*3600-1000*120 );
}catch(Exception e) {}
}
if(immediatePersistenceThreadStop)
return;
// 2 - Start persistence action
persistenceAction( !mustStopThread() );
}
while( !mustStopThread() );
// We shutdown the server
dataManager.shutdown(false);
serverManager.shutdown();
Tools.waitTime( 1000*10 ); // 10s
Debug.signal( Debug.NOTICE, null, "Leaving Persistence Thread..." );
Debug.exit();
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** Saves the world & players.
*
* @param maintenance if true we advertise clients with a "entering maintenance mode"
* message. If false we send a "server is shuting down" message.
*/
protected void persistenceAction( boolean maintenance ) {
// 1 - We warn all the clients that the server is going to enter
// maintenance mode for 2-3 minutes, in 2 minutes.
// If we are not in maintenance mode ( maintenance=false )
// the message is a "server shuting down" message.
serverManager.lockServers();
if( maintenance ) {
Debug.signal( Debug.NOTICE, null, "Server will enter maintenance mode in 2 minutes...");
serverManager.sendWarningMessage( "Your server will enter maintenance mode in 2 minutes.\n"
+"Please disconnect and reconnect in 5 minutes");
Tools.waitTime( 1000*120 ); // 2mn
Debug.signal( Debug.WARNING, null, "Server enters maintenance mode now... ("+Tools.getLexicalTime()+")");
}
else {
Debug.signal( Debug.NOTICE, null, "Sending warning messages to connected clients...");
serverManager.sendWarningMessage( "Your server is about to shutdown in 30s.\n"
+"Please disconnect and reconnect later.");
Tools.waitTime( 1000*30 ); // 30s
Debug.signal( Debug.NOTICE, null, "Saving world & player data... ("+Tools.getLexicalTime()+")");
}
// 2 - We close all remaining connections
// and save the data
serverManager.closeAllConnections();
dataManager.save();
// 3 - Leaving Maintenance Mode...
if( maintenance ) {
updateKeys(); // we update the keys...
serverManager.unlockServers();
Debug.signal( Debug.NOTICE, null, "Leaving maintenance mode... ("+Tools.getLexicalTime()+")" );
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** Must stop the persistence thread ?
*/
private synchronized boolean mustStopThread() {
return mustStop;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To shutdown the server director (stops the persistence thread ).
*/
private synchronized void shutdown() {
mustStop = true;
notify();
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get the server ID of this server.
*
* @return serverID
*/
public static int getServerID() {
return serverProperties.getIntegerProperty("init.serverID");
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get the URL where are stored the remote server configs. This URL can also contain
* a news.html file to display some news.
*
* @return remoteServerConfigHomeURL
*/
public static String getRemoteServerConfigHomeURL() {
return remoteServersProperties.getProperty("info.remoteServerHomeURL");
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get server properties.
* @return server properties
*/
public static Properties getServerProperties() {
return (Properties)serverProperties;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get remote servers properties.
* @return remote servers properties
*/
public static Properties getRemoteServersProperties() {
return (Properties)remoteServersProperties;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To change the keys used for special players & the bot's controlKey
*/
public static void updateKeys() {
int period = serverProperties.getIntegerProperty("init.persistencePeriod");
int nbIteration = 24/period;
if(period<24) {
if( (updateKeysPeriod%nbIteration)==0 )
updateKeysPeriod=1;
else {
updateKeysPeriod++;
return;
}
}
serverProperties.setProperty( "key.shaitan", Tools.keyGenerator(23, getServerID()+1) );
serverProperties.setProperty( "key.amyrlin", Tools.keyGenerator(23, getServerID()+2) );
serverProperties.setProperty( "key.chronicles", Tools.keyGenerator(23, getServerID()+3) );
serverProperties.setProperty( "key.mhael", Tools.keyGenerator(23, getServerID()+4) );
Debug.signal( Debug.NOTICE, null, "Generated new keys for special characters..." );
serverProperties.setProperty( "bots.controlKey", Tools.keyGenerator(23, getServerID()+5) );
Debug.signal( Debug.NOTICE, null, "Generated new control key for bots..." );
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** This method is called when the server network interface is down.
* @param itf the network interface we tried which is NOT available.
*/
public void serverInterfaceIsDown( String itf ) {
Debug.signal( Debug.NOTICE, null, "Network interface "+itf+" is down... we'll retry a connection in three minutes.");
serverEnabled = false;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** This method is called when the server network interface is Up.
* @param ipAddress currently used IP address
* @param stateChanged if true it means the interface has been re-created ( ip changed or
* serverSocket has just been created ). If false it means that the interface is Up
* and its state has not changed (since last check).
*/
public void serverInterfaceIsUp( String ipAddress, boolean stateChanged ) {
if(!stateChanged) {
if(!serverEnabled) {
serverEnabled = true;
Debug.signal( Debug.NOTICE, null, "Network interface "+ipAddress+" is up... IP has not changed.");
}
return;
}
Debug.signal( Debug.NOTICE, null, "Network interface "+ipAddress+" is up...");
// We save the new IP
if( !serverManager.getServerConfigManager().updateServerConfig(
null, ipAddress, serverManager.getServerConfig() ) ) {
Debug.signal( Debug.CRITICAL, this, "Failed to save new IP ("+ipAddress+") to the local server-"
+getServerID()+".cfg.adr file ! Please perform a manual update!"
+"Your server's IP has changed !" );
return;
}
else
Debug.signal( Debug.NOTICE, null, "IP saved to server-"+getServerID()+".cfg.adr file");
if( getServerID()==0 )
return; // local server
// Manual update ?
if( !serverProperties.getBooleanProperty("init.automaticUpdate") ) {
String publishAddress = serverProperties.getProperty("init.publishAddress");
if(publishAddress==null || publishAddress.length()==0)
Debug.signal( Debug.NOTICE, null, "Your server's IP has changed, you should do a manual update on the wotlas web server!"
+"Your server will be unreachable until then.");
else
Debug.signal( Debug.NOTICE, null, "Your server's local IP has changed, you should update your NAT table if you are using"
+"it. Your server will be unreachable until then.");
return;
}
// Automatic Update via a Thread (we don't want to make our server wait)
Thread updateThread = new Thread() {
public void run() {
// We get the login
String login = remoteServersProperties.getProperty("transfer.serverHomeLogin");
// We load the script we are about to modify with login & password.
String cmd = resourceManager.getExternalTransferScript();
File wDir = new File(resourceManager.getExternalScriptsDir());
String script = resourceManager.loadText( cmd );
boolean editScript = true;
if( script.indexOf("SET WEB_LOGIN")<0 || script.indexOf("SET WEB_PASSWORD")<0 )
editScript = false; // the script doesn't use any login & password, no need to edit it
// Did the user already entered the password ?
if(password==null && editScript) {
ALoginDialog dialog = new ALoginDialog( new Frame(), "File Transfer Login (asked once):", login, resourceManager );
if( dialog.okWasClicked() ) {
login = dialog.getLogin();
remoteServersProperties.setProperty("transfer.serverHomeLogin",login);
password = dialog.getPassword();
}
else {
Debug.signal( Debug.ERROR, null, "No password set. Transfer aborted");
return; // no transfer
}
}
// Runtime... we execute the transfert command
int result=1;
try{
cmd = new File( cmd ).getCanonicalPath();
}catch(Exception ex ) {
Debug.signal( Debug.ERROR, this, "Failed to find scripts ! Err: "+ex+" Cmd:"+cmd);
return;
}
// We replace the login & password values
if( script==null ) {
Debug.signal( Debug.ERROR, this, "Failed to load "+script+" !" );
return;
}
else if( editScript ) {
script = FileTools.updateProperty( "SET WEB_LOGIN", login, script );
script = FileTools.updateProperty( "SET WEB_PASSWORD", password, script );
if( !resourceManager.saveText( cmd, script ) ) {
Debug.signal( Debug.ERROR, this, "Failed to save "+script+" !" );
return;
}
}
// We run the script...
Debug.signal(Debug.NOTICE,null,"Launching transfer script...");
try{
Process pr = Runtime.getRuntime().exec( cmd, null, wDir );
result = pr.waitFor();
}
catch( Exception ex ) {
Debug.signal( Debug.ERROR, this, "Command Line Failed : "+ex.getMessage() );
return;
}
Debug.signal(Debug.NOTICE,null,"Transfer script ended.");
if( editScript ) {
// We clean what we have modified in the script
script = FileTools.updateProperty( "SET WEB_LOGIN", "You will be prompted for your login.", script );
script = FileTools.updateProperty( "SET WEB_PASSWORD", "You will be prompted for your passsword.", script );
if( !resourceManager.saveText( cmd, script ) ) {
Debug.signal( Debug.ERROR, this, "Failed to save "+script+" to clean entries !" );
return;
}
}
}
};
// We start the thread that will take care of the update
updateThread.start();
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get our resource manager.
* @return our resource manager.
*/
public static ResourceManager getResourceManager() {
return resourceManager;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get our server manager.
* @return our server manager.
*/
public static ServerManager getServerManager() {
return serverManager;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/** To get our data manager.
* @return our data manager.
*/
public static DataManager getDataManager() {
return dataManager;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
static synchronized public String GenUniqueKeyId() {
return System.currentTimeMillis()+""+genUniqueKeyId++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -