2010-12-22 16:22:23 +01:00
package net.minecraft.server ;
2011-01-29 22:50:29 +01:00
import java.awt.GraphicsEnvironment ;
2010-12-22 16:22:23 +01:00
import java.io.File ;
2011-01-11 09:25:13 +01:00
import java.io.IOException ;
2010-12-22 16:22:23 +01:00
import java.net.InetAddress ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.HashMap ;
2010-12-28 20:52:24 +01:00
import java.util.Iterator ;
2010-12-22 16:22:23 +01:00
import java.util.List ;
2011-03-31 22:40:00 +02:00
import java.util.Random ;
2010-12-22 16:22:23 +01:00
import java.util.logging.Level ;
import java.util.logging.Logger ;
2010-12-28 20:52:24 +01:00
2011-01-11 09:25:13 +01:00
// CraftBukkit start
2011-02-23 13:56:36 +01:00
import java.io.PrintStream ;
2011-01-11 09:25:13 +01:00
import java.net.UnknownHostException ;
2011-02-25 17:12:38 +01:00
import jline.ConsoleReader ;
2011-01-11 09:25:13 +01:00
import joptsimple.OptionSet ;
2011-05-26 14:48:22 +02:00
import org.bukkit.World.Environment ;
2011-09-25 00:14:13 +02:00
import org.bukkit.command.ConsoleCommandSender ;
2011-12-07 07:01:05 +01:00
import org.bukkit.command.RemoteConsoleCommandSender ;
import org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender ;
2010-12-22 16:22:23 +01:00
import org.bukkit.craftbukkit.CraftServer ;
2011-02-20 02:53:06 +01:00
import org.bukkit.craftbukkit.LoggerOutputStream ;
2011-02-03 00:53:04 +01:00
import org.bukkit.craftbukkit.scheduler.CraftScheduler ;
2011-03-29 22:01:04 +02:00
import org.bukkit.craftbukkit.util.ServerShutdownThread ;
2011-12-07 07:01:05 +01:00
import org.bukkit.event.Event ;
2011-07-28 16:35:50 +02:00
import org.bukkit.event.server.ServerCommandEvent ;
2011-06-22 19:27:27 +02:00
import org.bukkit.event.world.WorldInitEvent ;
2011-06-22 19:33:23 +02:00
import org.bukkit.event.world.WorldLoadEvent ;
2011-03-26 23:20:35 +01:00
import org.bukkit.event.world.WorldSaveEvent ;
2011-06-22 19:27:27 +02:00
import org.bukkit.generator.ChunkGenerator ;
2011-11-06 00:58:13 +01:00
import org.bukkit.plugin.Plugin ;
2011-06-22 18:46:12 +02:00
import org.bukkit.plugin.PluginLoadOrder ;
2011-07-28 16:35:50 +02:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
2011-11-20 09:01:14 +01:00
public class MinecraftServer implements Runnable , ICommandListener , IMinecraftServer {
2010-12-22 16:22:23 +01:00
2011-04-20 19:05:14 +02:00
public static Logger log = Logger . getLogger ( " Minecraft " ) ;
2011-06-27 00:25:01 +02:00
public static HashMap trackerList = new HashMap ( ) ;
2012-01-12 23:10:13 +01:00
private String t ;
private int u ;
2011-04-20 19:05:14 +02:00
public NetworkListenThread networkListenThread ;
public PropertyManager propertyManager ;
2011-05-28 22:50:08 +02:00
// public WorldServer[] worldServer; // CraftBukkit - removed!
2011-11-20 09:01:14 +01:00
public long [ ] f = new long [ 100 ] ;
public long [ ] [ ] g ;
2011-04-20 19:05:14 +02:00
public ServerConfigurationManager serverConfigurationManager ;
public ConsoleCommandHandler consoleCommandHandler ; // CraftBukkit - made public
private boolean isRunning = true ;
public boolean isStopped = false ;
int ticks = 0 ;
2011-11-20 09:01:14 +01:00
public String k ;
public int l ;
2012-01-12 23:10:13 +01:00
private List x = new ArrayList ( ) ;
private List y = Collections . synchronizedList ( new ArrayList ( ) ) ;
2011-11-20 09:01:14 +01:00
// public EntityTracker[] tracker = new EntityTracker[3]; // CraftBukkit - removed!
2011-04-20 19:05:14 +02:00
public boolean onlineMode ;
public boolean spawnAnimals ;
2012-01-12 23:10:13 +01:00
public boolean spawnNPCs ;
2011-04-20 19:05:14 +02:00
public boolean pvpMode ;
2011-06-27 00:25:01 +02:00
public boolean allowFlight ;
2012-01-12 23:10:13 +01:00
public String s ;
private RemoteStatusListener z ;
private RemoteControlListener A ;
2010-12-28 20:52:24 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
2011-05-26 23:15:27 +02:00
public List < WorldServer > worlds = new ArrayList < WorldServer > ( ) ;
2011-01-29 22:50:29 +01:00
public CraftServer server ;
public OptionSet options ;
2011-09-25 00:14:13 +02:00
public ConsoleCommandSender console ;
2011-12-07 07:01:05 +01:00
public RemoteConsoleCommandSender remoteConsole ;
2011-02-25 17:12:38 +01:00
public ConsoleReader reader ;
2011-05-09 20:51:01 +02:00
public static int currentTick ;
2011-05-14 16:29:42 +02:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
2011-02-23 13:56:36 +01:00
public MinecraftServer ( OptionSet options ) { // CraftBukkit - adds argument OptionSet
2011-02-21 23:30:01 +01:00
new ThreadSleepForever ( this ) ;
2011-02-25 17:12:38 +01:00
2011-06-12 00:02:58 +02:00
// CraftBukkit start
2011-02-25 17:12:38 +01:00
this . options = options ;
try {
this . reader = new ConsoleReader ( ) ;
} catch ( IOException ex ) {
Logger . getLogger ( MinecraftServer . class . getName ( ) ) . log ( Level . SEVERE , null , ex ) ;
}
2011-03-29 22:01:04 +02:00
Runtime . getRuntime ( ) . addShutdownHook ( new ServerShutdownThread ( this ) ) ;
2011-02-25 17:12:38 +01:00
// CraftBukkit end
2011-02-21 23:30:01 +01:00
}
2011-04-20 19:05:14 +02:00
private boolean init ( ) throws UnknownHostException { // CraftBukkit - added throws UnknownHostException
this . consoleCommandHandler = new ConsoleCommandHandler ( this ) ;
2010-12-28 20:52:24 +01:00
ThreadCommandReader threadcommandreader = new ThreadCommandReader ( this ) ;
2010-12-22 16:22:23 +01:00
2011-01-29 22:50:29 +01:00
threadcommandreader . setDaemon ( true ) ;
threadcommandreader . start ( ) ;
2011-05-14 16:29:42 +02:00
ConsoleLogManager . init ( this ) ; // CraftBukkit
2011-02-20 02:53:06 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
2011-04-20 19:05:14 +02:00
System . setOut ( new PrintStream ( new LoggerOutputStream ( log , Level . INFO ) , true ) ) ;
System . setErr ( new PrintStream ( new LoggerOutputStream ( log , Level . SEVERE ) , true ) ) ;
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-02-20 02:53:06 +01:00
2011-12-01 22:43:54 +01:00
log . info ( " Starting minecraft server version 1.0.1 " ) ;
2010-12-22 16:22:23 +01:00
if ( Runtime . getRuntime ( ) . maxMemory ( ) / 1024L / 1024L < 512L ) {
2011-04-20 19:05:14 +02:00
log . warning ( " **** NOT ENOUGH RAM! " ) ;
log . warning ( " To start the server with more ram, launch it as \" java -Xmx1024M -Xms1024M -jar minecraft_server.jar \" " ) ;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
2011-04-20 19:05:14 +02:00
log . info ( " Loading properties " ) ;
2011-06-27 00:25:01 +02:00
this . propertyManager = new PropertyManager ( this . options ) ; // CraftBukkit - CLI argument support
2012-01-12 23:10:13 +01:00
this . t = this . propertyManager . getString ( " server-ip " , " " ) ;
2011-04-20 19:05:14 +02:00
this . onlineMode = this . propertyManager . getBoolean ( " online-mode " , true ) ;
this . spawnAnimals = this . propertyManager . getBoolean ( " spawn-animals " , true ) ;
2012-01-12 23:10:13 +01:00
this . spawnNPCs = this . propertyManager . getBoolean ( " spawn-npcs " , true ) ;
2011-04-20 19:05:14 +02:00
this . pvpMode = this . propertyManager . getBoolean ( " pvp " , true ) ;
2011-06-27 00:25:01 +02:00
this . allowFlight = this . propertyManager . getBoolean ( " allow-flight " , false ) ;
2012-01-12 23:10:13 +01:00
this . s = this . propertyManager . getString ( " motd " , " A Minecraft Server " ) ;
this . s . replace ( '\u00a7' , '$' ) ;
2010-12-28 20:52:24 +01:00
InetAddress inetaddress = null ;
2010-12-22 16:22:23 +01:00
2012-01-12 23:10:13 +01:00
if ( this . t . length ( ) > 0 ) {
inetaddress = InetAddress . getByName ( this . t ) ;
2010-12-22 16:22:23 +01:00
}
2012-01-12 23:10:13 +01:00
this . u = this . propertyManager . getInt ( " server-port " , 25565 ) ;
log . info ( " Starting Minecraft server on " + ( this . t . length ( ) = = 0 ? " * " : this . t ) + " : " + this . u ) ;
2011-01-29 22:50:29 +01:00
2010-12-22 16:22:23 +01:00
try {
2012-01-12 23:10:13 +01:00
this . networkListenThread = new NetworkListenThread ( this , inetaddress , this . u ) ;
2011-02-21 23:30:01 +01:00
} catch ( Throwable ioexception ) { // CraftBukkit - IOException -> Throwable
2011-04-20 19:05:14 +02:00
log . warning ( " **** FAILED TO BIND TO PORT! " ) ;
log . log ( Level . WARNING , " The exception was: " + ioexception . toString ( ) ) ;
log . warning ( " Perhaps a server is already running on that port? " ) ;
2010-12-22 16:22:23 +01:00
return false ;
}
2011-01-29 22:50:29 +01:00
2011-04-20 19:05:14 +02:00
if ( ! this . onlineMode ) {
log . warning ( " **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! " ) ;
log . warning ( " The server will make no attempt to authenticate usernames. Beware. " ) ;
log . warning ( " While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose. " ) ;
2011-11-26 02:09:04 +01:00
log . warning ( " To change this, set \" online-mode \" to \" true \" in the server.properties file. " ) ; // CraftBukkit - type. Seriously. :D
2010-12-22 16:22:23 +01:00
}
2010-12-26 03:20:29 +01:00
2011-04-20 19:05:14 +02:00
this . serverConfigurationManager = new ServerConfigurationManager ( this ) ;
2011-05-28 22:50:08 +02:00
// CraftBukkit - removed trackers
2011-11-20 09:01:14 +01:00
long i = System . nanoTime ( ) ;
String s = this . propertyManager . getString ( " level-name " , " world " ) ;
String s1 = this . propertyManager . getString ( " level-seed " , " " ) ;
2012-01-12 23:10:13 +01:00
String s2 = this . propertyManager . getString ( " level-type " , " DEFAULT " ) ;
2011-11-20 09:01:14 +01:00
long j = ( new Random ( ) ) . nextLong ( ) ;
2011-03-31 22:40:00 +02:00
2011-11-20 09:01:14 +01:00
if ( s1 . length ( ) > 0 ) {
2011-03-31 22:40:00 +02:00
try {
2011-11-20 09:01:14 +01:00
long k = Long . parseLong ( s1 ) ;
if ( k ! = 0L ) {
j = k ;
}
2011-03-31 22:40:00 +02:00
} catch ( NumberFormatException numberformatexception ) {
2011-11-20 09:01:14 +01:00
j = ( long ) s1 . hashCode ( ) ;
2011-03-31 22:40:00 +02:00
}
}
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
WorldType worldtype = WorldType . a ( s2 ) ;
if ( worldtype = = null ) {
worldtype = WorldType . NORMAL ;
}
2011-11-20 09:01:14 +01:00
log . info ( " Preparing level \" " + s + " \" " ) ;
2012-01-12 23:10:13 +01:00
this . a ( new WorldLoaderServer ( new File ( " . " ) ) , s , j , worldtype ) ;
2011-02-25 21:57:38 +01:00
2011-12-28 02:10:49 +01:00
// CraftBukkit start - display seconds for the completion time
2011-11-20 09:01:14 +01:00
long elapsed = System . nanoTime ( ) - i ;
2011-12-28 02:10:49 +01:00
String time = String . format ( " %.3fs " , elapsed / 1000000000 . 0D ) ;
2011-04-20 19:05:14 +02:00
log . info ( " Done ( " + time + " )! For help, type \" help \" or \" ? \" " ) ;
2011-12-28 02:10:49 +01:00
// CraftBukkit end
2011-02-25 21:57:38 +01:00
2011-11-20 09:01:14 +01:00
if ( this . propertyManager . getBoolean ( " enable-query " , false ) ) {
log . info ( " Starting GS4 status listener " ) ;
2012-01-12 23:10:13 +01:00
this . z = new RemoteStatusListener ( this ) ;
this . z . a ( ) ;
2011-11-20 09:01:14 +01:00
}
if ( this . propertyManager . getBoolean ( " enable-rcon " , false ) ) {
log . info ( " Starting remote control listener " ) ;
2012-01-12 23:10:13 +01:00
this . A = new RemoteControlListener ( this ) ;
this . A . a ( ) ;
2011-12-07 07:01:05 +01:00
this . remoteConsole = new CraftRemoteConsoleCommandSender ( ) ;
2011-11-20 09:01:14 +01:00
}
// CraftBukkit start
2011-06-17 05:49:58 +02:00
if ( this . propertyManager . properties . containsKey ( " spawn-protection " ) ) {
log . info ( " 'spawn-protection' in server.properties has been moved to 'settings.spawn-radius' in bukkit.yml. I will move your config for you. " ) ;
2011-06-27 00:25:01 +02:00
this . server . setSpawnRadius ( this . propertyManager . getInt ( " spawn-protection " , 16 ) ) ;
2011-06-17 05:49:58 +02:00
this . propertyManager . properties . remove ( " spawn-protection " ) ;
2011-06-27 00:25:01 +02:00
this . propertyManager . savePropertiesFile ( ) ;
2011-06-17 05:49:58 +02:00
}
2012-01-12 12:02:39 +01:00
// CraftBukkit end
2011-11-20 09:01:14 +01:00
2010-12-22 16:22:23 +01:00
return true ;
}
2012-01-12 23:10:13 +01:00
private void a ( Convertable convertable , String s , long i , WorldType worldtype ) {
2011-04-20 19:05:14 +02:00
if ( convertable . isConvertable ( s ) ) {
log . info ( " Converting map! " ) ;
convertable . convert ( s , new ConvertProgressUpdater ( this ) ) ;
2011-02-23 03:37:56 +01:00
}
2011-11-20 09:01:14 +01:00
// CraftBukkit - removed world and ticktime arrays
2011-09-15 02:23:52 +02:00
int j = this . propertyManager . getInt ( " gamemode " , 0 ) ;
j = WorldSettings . a ( j ) ;
log . info ( " Default game type: " + j ) ;
// CraftBukkit start (+ removed worldsettings and servernbtmanager)
2011-11-24 19:48:01 +01:00
int worldCount = 3 ;
2011-11-20 09:01:14 +01:00
for ( int k = 0 ; k < worldCount ; + + k ) {
2011-05-26 14:48:22 +02:00
WorldServer world ;
2011-11-20 09:01:14 +01:00
int dimension = 0 ;
if ( k = = 1 ) {
2011-11-24 19:48:01 +01:00
if ( this . propertyManager . getBoolean ( " allow-nether " , true ) ) {
dimension = - 1 ;
} else {
continue ;
}
2011-11-20 09:01:14 +01:00
}
if ( k = = 2 ) {
2012-01-12 19:43:34 +01:00
// CraftBukkit - (+ don't do this in server.properties, do it in bukkit.yml)
2011-12-09 18:55:36 +01:00
if ( this . server . getAllowEnd ( ) ) {
dimension = 1 ;
} else {
continue ;
}
2011-11-20 09:01:14 +01:00
}
2011-06-22 19:27:27 +02:00
String worldType = Environment . getEnvironment ( dimension ) . toString ( ) . toLowerCase ( ) ;
String name = ( dimension = = 0 ) ? s : s + " _ " + worldType ;
2011-06-27 00:25:01 +02:00
ChunkGenerator gen = this . server . getGenerator ( name ) ;
2012-01-12 23:10:13 +01:00
WorldSettings settings = new WorldSettings ( i , j , true , false , worldtype ) ;
2011-02-05 19:15:04 +01:00
2011-09-15 02:23:52 +02:00
if ( k = = 0 ) {
2011-10-12 05:24:41 +02:00
world = new WorldServer ( this , new ServerNBTManager ( server . getWorldContainer ( ) , s , true ) , s , dimension , settings , org . bukkit . World . Environment . getEnvironment ( dimension ) , gen ) ; // CraftBukkit
2011-05-26 14:48:22 +02:00
} else {
2011-12-19 17:26:11 +01:00
String dim = " DIM " + dimension ;
2011-06-16 22:41:01 +02:00
File newWorld = new File ( new File ( name ) , dim ) ;
File oldWorld = new File ( new File ( s ) , dim ) ;
2011-06-17 08:29:16 +02:00
2011-06-16 22:41:01 +02:00
if ( ( ! newWorld . isDirectory ( ) ) & & ( oldWorld . isDirectory ( ) ) ) {
log . info ( " ---- Migration of old " + worldType + " folder required ---- " ) ;
log . info ( " Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly. " ) ;
log . info ( " We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future. " ) ;
log . info ( " Attempting to move " + oldWorld + " to " + newWorld + " ... " ) ;
if ( newWorld . exists ( ) ) {
log . severe ( " A file or folder already exists at " + newWorld + " ! " ) ;
log . info ( " ---- Migration of old " + worldType + " folder failed ---- " ) ;
} else if ( newWorld . getParentFile ( ) . mkdirs ( ) ) {
if ( oldWorld . renameTo ( newWorld ) ) {
2011-12-19 17:26:11 +01:00
log . info ( " Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld ) ;
2011-06-16 22:41:01 +02:00
log . info ( " ---- Migration of old " + worldType + " folder complete ---- " ) ;
} else {
log . severe ( " Could not move folder " + oldWorld + " to " + newWorld + " ! " ) ;
log . info ( " ---- Migration of old " + worldType + " folder failed ---- " ) ;
}
} else {
log . severe ( " Could not create path for " + newWorld + " ! " ) ;
log . info ( " ---- Migration of old " + worldType + " folder failed ---- " ) ;
}
}
2011-10-12 05:24:41 +02:00
world = new SecondaryWorldServer ( this , new ServerNBTManager ( server . getWorldContainer ( ) , name , true ) , name , dimension , settings , this . worlds . get ( 0 ) , org . bukkit . World . Environment . getEnvironment ( dimension ) , gen ) ; // CraftBukkit
2011-06-22 19:27:27 +02:00
}
if ( gen ! = null ) {
world . getWorld ( ) . getPopulators ( ) . addAll ( gen . getDefaultPopulators ( world . getWorld ( ) ) ) ;
2011-05-26 14:48:22 +02:00
}
2011-06-27 00:25:01 +02:00
this . server . getPluginManager ( ) . callEvent ( new WorldInitEvent ( world . getWorld ( ) ) ) ;
2011-06-22 19:27:27 +02:00
2011-12-06 14:52:45 +01:00
world . tracker = new EntityTracker ( this , world ) ; // CraftBukkit
2011-05-26 14:48:22 +02:00
world . addIWorldAccess ( new WorldManager ( this , world ) ) ;
2011-09-24 23:03:31 +02:00
world . difficulty = this . propertyManager . getInt ( " difficulty " , 1 ) ;
2011-05-26 14:48:22 +02:00
world . setSpawnFlags ( this . propertyManager . getBoolean ( " spawn-monsters " , true ) , this . spawnAnimals ) ;
2011-11-30 00:17:43 +01:00
world . getWorldData ( ) . setGameType ( j ) ;
2011-06-27 00:25:01 +02:00
this . worlds . add ( world ) ;
this . serverConfigurationManager . setPlayerFileData ( this . worlds . toArray ( new WorldServer [ 0 ] ) ) ;
2011-05-26 14:48:22 +02:00
}
2011-05-28 22:50:08 +02:00
// CraftBukkit end
2011-02-05 19:15:04 +01:00
2011-01-29 22:50:29 +01:00
short short1 = 196 ;
2011-09-16 21:10:11 +02:00
long l = System . currentTimeMillis ( ) ;
2011-01-29 22:50:29 +01:00
2011-06-18 05:23:34 +02:00
// CraftBukkit start
2011-09-16 21:10:11 +02:00
for ( int i1 = 0 ; i1 < this . worlds . size ( ) ; + + i1 ) {
WorldServer worldserver = this . worlds . get ( i1 ) ;
log . info ( " Preparing start region for level " + i1 + " (Seed: " + worldserver . getSeed ( ) + " ) " ) ;
2012-01-12 23:10:13 +01:00
if ( ! worldserver . getWorld ( ) . getKeepSpawnInMemory ( ) ) {
continue ;
}
// CraftBukkit end
ChunkCoordinates chunkcoordinates = worldserver . getSpawn ( ) ;
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
for ( int j1 = - short1 ; j1 < = short1 & & this . isRunning ; j1 + = 16 ) {
for ( int k1 = - short1 ; k1 < = short1 & & this . isRunning ; k1 + = 16 ) {
long l1 = System . currentTimeMillis ( ) ;
2011-05-26 14:48:22 +02:00
2012-01-12 23:10:13 +01:00
if ( l1 < l ) {
l = l1 ;
}
2011-01-14 14:31:10 +01:00
2012-01-12 23:10:13 +01:00
if ( l1 > l + 1000L ) {
int i2 = ( short1 * 2 + 1 ) * ( short1 * 2 + 1 ) ;
int j2 = ( j1 + short1 ) * ( short1 * 2 + 1 ) + k1 + 1 ;
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
this . b ( " Preparing spawn area " , j2 * 100 / i2 ) ;
l = l1 ;
}
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
worldserver . chunkProviderServer . getChunkAt ( chunkcoordinates . x + j1 > > 4 , chunkcoordinates . z + k1 > > 4 ) ;
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
while ( worldserver . updateLights ( ) & & this . isRunning ) {
;
2011-02-05 19:15:04 +01:00
}
2010-12-22 16:22:23 +01:00
}
2012-01-12 23:10:13 +01:00
}
2010-12-22 16:22:23 +01:00
}
2010-12-28 20:52:24 +01:00
2011-06-27 00:25:01 +02:00
// CraftBukkit start
for ( World world : this . worlds ) {
this . server . getPluginManager ( ) . callEvent ( new WorldLoadEvent ( world . getWorld ( ) ) ) ;
2011-06-22 19:33:23 +02:00
}
2011-06-27 00:25:01 +02:00
// CraftBukkit end
2011-06-22 19:33:23 +02:00
2011-11-20 09:01:14 +01:00
this . t ( ) ;
2010-12-22 16:22:23 +01:00
}
2011-11-20 09:01:14 +01:00
private void b ( String s , int i ) {
this . k = s ;
this . l = i ;
2011-04-20 19:05:14 +02:00
log . info ( s + " : " + i + " % " ) ;
2010-12-22 16:22:23 +01:00
}
2011-11-20 09:01:14 +01:00
private void t ( ) {
this . k = null ;
this . l = 0 ;
2011-01-11 09:25:13 +01:00
2011-06-27 00:25:01 +02:00
this . server . enablePlugins ( PluginLoadOrder . POSTWORLD ) ; // CraftBukkit
2010-12-22 16:22:23 +01:00
}
2011-04-20 19:05:14 +02:00
void saveChunks ( ) { // CraftBukkit - private -> default
log . info ( " Saving chunks " ) ;
2011-02-05 19:15:04 +01:00
2011-05-28 22:50:08 +02:00
// CraftBukkit start
2011-05-26 14:48:22 +02:00
for ( int i = 0 ; i < this . worlds . size ( ) ; + + i ) {
WorldServer worldserver = this . worlds . get ( i ) ;
2011-02-19 21:29:51 +01:00
2011-05-26 14:48:22 +02:00
worldserver . save ( true , ( IProgressUpdate ) null ) ;
worldserver . saveLevel ( ) ;
WorldSaveEvent event = new WorldSaveEvent ( worldserver . getWorld ( ) ) ;
2011-06-27 00:25:01 +02:00
this . server . getPluginManager ( ) . callEvent ( event ) ;
2011-02-05 19:15:04 +01:00
}
2011-05-26 23:29:57 +02:00
2011-05-26 14:48:22 +02:00
WorldServer world = this . worlds . get ( 0 ) ;
2011-09-24 23:03:31 +02:00
if ( ! world . savingDisabled ) {
2011-05-16 23:29:57 +02:00
this . serverConfigurationManager . savePlayers ( ) ;
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
}
2011-05-14 16:29:42 +02:00
public void stop ( ) { // CraftBukkit - private -> public
2011-04-20 19:05:14 +02:00
log . info ( " Stopping server " ) ;
2011-02-21 23:30:01 +01:00
// CraftBukkit start
2011-06-27 00:25:01 +02:00
if ( this . server ! = null ) {
this . server . disablePlugins ( ) ;
2011-02-01 21:37:07 +01:00
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-02-02 00:32:18 +01:00
2011-04-20 19:05:14 +02:00
if ( this . serverConfigurationManager ! = null ) {
this . serverConfigurationManager . savePlayers ( ) ;
2011-01-27 22:15:41 +01:00
}
2012-01-12 23:10:13 +01:00
// for (int i = 0; i < this.worldServer.length; ++i) { // CraftBukkit - multiworld is handled in saveChunks() already.
WorldServer worldserver = this . worlds . get ( 0 ) ; // CraftBukkit
2011-05-26 14:48:22 +02:00
2012-01-12 23:10:13 +01:00
if ( worldserver ! = null ) {
this . saveChunks ( ) ;
}
// } // CraftBukkit
2010-12-22 16:22:23 +01:00
}
2011-09-24 23:03:31 +02:00
public void safeShutdown ( ) {
2011-04-20 19:05:14 +02:00
this . isRunning = false ;
2010-12-22 16:22:23 +01:00
}
public void run ( ) {
try {
2011-04-20 19:05:14 +02:00
if ( this . init ( ) ) {
2011-01-29 22:50:29 +01:00
long i = System . currentTimeMillis ( ) ;
2010-12-28 20:52:24 +01:00
2011-04-20 19:05:14 +02:00
for ( long j = 0L ; this . isRunning ; Thread . sleep ( 1L ) ) {
2011-01-29 22:50:29 +01:00
long k = System . currentTimeMillis ( ) ;
long l = k - i ;
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
if ( l > 2000L ) {
2011-04-20 19:05:14 +02:00
log . warning ( " Can \ 't keep up! Did the system time change, or is the server overloaded? " ) ;
2011-01-29 22:50:29 +01:00
l = 2000L ;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
if ( l < 0L ) {
2011-04-20 19:05:14 +02:00
log . warning ( " Time ran backwards! Did the system time change? " ) ;
2011-01-29 22:50:29 +01:00
l = 0L ;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
j + = l ;
i = k ;
2011-05-28 22:50:08 +02:00
if ( this . worlds . get ( 0 ) . everyoneDeeplySleeping ( ) ) { // CraftBukkit
2011-11-20 09:01:14 +01:00
this . w ( ) ;
2011-02-23 03:37:56 +01:00
j = 0L ;
} else {
while ( j > 50L ) {
2011-05-09 20:51:01 +02:00
MinecraftServer . currentTick = ( int ) ( System . currentTimeMillis ( ) / 50 ) ; // CraftBukkit
2011-02-23 03:37:56 +01:00
j - = 50L ;
2011-11-20 09:01:14 +01:00
this . w ( ) ;
2011-02-23 03:37:56 +01:00
}
2010-12-22 16:22:23 +01:00
}
}
} else {
2011-04-20 19:05:14 +02:00
while ( this . isRunning ) {
2011-01-29 22:50:29 +01:00
this . b ( ) ;
2010-12-22 16:22:23 +01:00
try {
Thread . sleep ( 10L ) ;
2010-12-28 20:52:24 +01:00
} catch ( InterruptedException interruptedexception ) {
interruptedexception . printStackTrace ( ) ;
2010-12-22 16:22:23 +01:00
}
}
}
2011-02-23 03:37:56 +01:00
} catch ( Throwable throwable ) {
throwable . printStackTrace ( ) ;
2011-04-20 19:05:14 +02:00
log . log ( Level . SEVERE , " Unexpected exception " , throwable ) ;
2011-01-29 22:50:29 +01:00
2011-04-20 19:05:14 +02:00
while ( this . isRunning ) {
2011-01-29 22:50:29 +01:00
this . b ( ) ;
2010-12-22 16:22:23 +01:00
try {
Thread . sleep ( 10L ) ;
2010-12-28 20:52:24 +01:00
} catch ( InterruptedException interruptedexception1 ) {
interruptedexception1 . printStackTrace ( ) ;
2010-12-22 16:22:23 +01:00
}
}
} finally {
2011-01-14 14:31:10 +01:00
try {
2011-04-20 19:05:14 +02:00
this . stop ( ) ;
this . isStopped = true ;
2011-02-23 03:37:56 +01:00
} catch ( Throwable throwable1 ) {
throwable1 . printStackTrace ( ) ;
2011-01-14 14:31:10 +01:00
} finally {
System . exit ( 0 ) ;
}
2010-12-22 16:22:23 +01:00
}
}
2011-11-20 09:01:14 +01:00
private void w ( ) {
long i = System . nanoTime ( ) ;
2011-01-11 09:25:13 +01:00
ArrayList arraylist = new ArrayList ( ) ;
2011-06-27 00:25:01 +02:00
Iterator iterator = trackerList . keySet ( ) . iterator ( ) ;
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
while ( iterator . hasNext ( ) ) {
2010-12-28 20:52:24 +01:00
String s = ( String ) iterator . next ( ) ;
2011-11-20 09:01:14 +01:00
int j = ( ( Integer ) trackerList . get ( s ) ) . intValue ( ) ;
2010-12-28 20:52:24 +01:00
2011-11-20 09:01:14 +01:00
if ( j > 0 ) {
trackerList . put ( s , Integer . valueOf ( j - 1 ) ) ;
2010-12-22 16:22:23 +01:00
} else {
2011-01-29 22:50:29 +01:00
arraylist . add ( s ) ;
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
2011-11-20 09:01:14 +01:00
int k ;
2011-01-29 22:50:29 +01:00
2011-11-20 09:01:14 +01:00
for ( k = 0 ; k < arraylist . size ( ) ; + + k ) {
trackerList . remove ( arraylist . get ( k ) ) ;
2010-12-22 16:22:23 +01:00
}
2010-12-26 03:20:29 +01:00
AxisAlignedBB . a ( ) ;
Vec3D . a ( ) ;
2011-04-20 19:05:14 +02:00
+ + this . ticks ;
2011-02-05 19:15:04 +01:00
2011-09-23 20:20:18 +02:00
// CraftBukkit start - only send timeupdates to the people in that world
2011-08-07 05:45:56 +02:00
2011-09-23 20:20:18 +02:00
( ( CraftScheduler ) this . server . getScheduler ( ) ) . mainThreadHeartbeat ( this . ticks ) ;
2011-02-07 02:59:06 +01:00
2011-09-23 20:20:18 +02:00
// Send timeupdates to everyone, it will get the right time from the world the player is in.
if ( this . ticks % 20 = = 0 ) {
2011-11-20 09:01:14 +01:00
for ( k = 0 ; k < this . serverConfigurationManager . players . size ( ) ; + + k ) {
EntityPlayer entityplayer = ( EntityPlayer ) this . serverConfigurationManager . players . get ( k ) ;
2011-09-23 20:20:18 +02:00
entityplayer . netServerHandler . sendPacket ( new Packet4UpdateTime ( entityplayer . getPlayerTime ( ) ) ) ; // Add support for per player time
}
}
2011-11-20 09:01:14 +01:00
for ( k = 0 ; k < this . worlds . size ( ) ; + + k ) {
long l = System . nanoTime ( ) ;
// if (k == 0 || this.propertyManager.getBoolean("allow-nether", true)) {
WorldServer worldserver = this . worlds . get ( k ) ;
2011-09-23 20:20:18 +02:00
/ * Drop global timeupdates
2011-05-28 22:50:08 +02:00
if ( this . ticks % 20 = = 0 ) {
2011-09-23 20:20:18 +02:00
this . serverConfigurationManager . a ( new Packet4UpdateTime ( worldserver . getTime ( ) ) , worldserver . worldProvider . dimension ) ;
2011-05-26 14:48:22 +02:00
}
2011-09-23 20:20:18 +02:00
// CraftBukkit end */
2011-02-19 21:29:51 +01:00
2011-05-28 22:50:08 +02:00
worldserver . doTick ( ) ;
2011-01-29 22:50:29 +01:00
2011-11-20 09:01:14 +01:00
while ( true ) {
2011-11-30 00:17:43 +01:00
if ( ! worldserver . updateLights ( ) ) {
2011-11-20 09:01:14 +01:00
worldserver . tickEntities ( ) ;
break ;
}
2011-05-28 22:50:08 +02:00
}
}
2011-11-20 09:01:14 +01:00
// this.g[k][this.ticks % 100] = System.nanoTime() - l; // CraftBukkit
2011-05-28 22:50:08 +02:00
// } // CraftBukkit
2011-05-26 14:48:22 +02:00
2011-04-20 19:05:14 +02:00
this . networkListenThread . a ( ) ;
2011-11-30 00:17:43 +01:00
this . serverConfigurationManager . tick ( ) ;
2011-05-26 14:48:22 +02:00
2011-05-28 22:50:08 +02:00
// CraftBukkit start
2011-11-20 09:01:14 +01:00
for ( k = 0 ; k < this . worlds . size ( ) ; + + k ) {
this . worlds . get ( k ) . tracker . updatePlayers ( ) ;
2011-05-26 14:48:22 +02:00
}
2011-05-28 22:50:08 +02:00
// CraftBukkit end
2011-01-29 22:50:29 +01:00
2012-01-12 23:10:13 +01:00
for ( k = 0 ; k < this . x . size ( ) ; + + k ) {
( ( IUpdatePlayerListBox ) this . x . get ( k ) ) . a ( ) ;
2010-12-28 20:52:24 +01:00
}
2010-12-22 16:22:23 +01:00
try {
2011-01-29 22:50:29 +01:00
this . b ( ) ;
2010-12-28 20:52:24 +01:00
} catch ( Exception exception ) {
2011-04-20 19:05:14 +02:00
log . log ( Level . WARNING , " Unexpected exception while parsing console command " , exception ) ;
2010-12-22 16:22:23 +01:00
}
2011-11-20 09:01:14 +01:00
this . f [ this . ticks % 100 ] = System . nanoTime ( ) - i ;
2010-12-22 16:22:23 +01:00
}
2011-04-20 19:05:14 +02:00
public void issueCommand ( String s , ICommandListener icommandlistener ) {
2012-01-12 23:10:13 +01:00
this . y . add ( new ServerCommand ( s , icommandlistener ) ) ;
2010-12-22 16:22:23 +01:00
}
public void b ( ) {
2012-01-12 23:10:13 +01:00
while ( this . y . size ( ) > 0 ) {
ServerCommand servercommand = ( ServerCommand ) this . y . remove ( 0 ) ;
2010-12-28 20:52:24 +01:00
2011-07-28 16:35:50 +02:00
// CraftBukkit start - ServerCommand for preprocessing
2011-12-07 07:01:05 +01:00
ServerCommandEvent event = new ServerCommandEvent ( Event . Type . SERVER_COMMAND , this . console , servercommand . command ) ;
2011-07-28 16:35:50 +02:00
this . server . getPluginManager ( ) . callEvent ( event ) ;
servercommand = new ServerCommand ( event . getCommand ( ) , servercommand . b ) ;
// CraftBukkit end
// this.consoleCommandHandler.handle(servercommand); // CraftBukkit - Removed its now called in server.dispatchCommand
2011-06-27 00:25:01 +02:00
this . server . dispatchCommand ( this . console , servercommand ) ; // CraftBukkit
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
public void a ( IUpdatePlayerListBox iupdateplayerlistbox ) {
2012-01-12 23:10:13 +01:00
this . x . add ( iupdateplayerlistbox ) ;
2010-12-22 16:22:23 +01:00
}
2011-02-23 13:56:36 +01:00
public static void main ( final OptionSet options ) { // CraftBukkit - replaces main(String args[])
2011-04-20 22:47:26 +02:00
StatisticList . a ( ) ;
2010-12-22 16:22:23 +01:00
try {
2011-06-12 00:02:58 +02:00
MinecraftServer minecraftserver = new MinecraftServer ( options ) ; // CraftBukkit - pass in the options
2011-01-29 22:50:29 +01:00
2011-01-11 09:25:13 +01:00
// CraftBukkit - remove gui
2010-12-22 16:22:23 +01:00
2010-12-28 20:52:24 +01:00
( new ThreadServerApplication ( " Server thread " , minecraftserver ) ) . start ( ) ;
} catch ( Exception exception ) {
2011-04-20 19:05:14 +02:00
log . log ( Level . SEVERE , " Failed to start the minecraft server " , exception ) ;
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
public File a ( String s ) {
return new File ( s ) ;
2010-12-22 16:22:23 +01:00
}
2011-04-20 19:05:14 +02:00
public void sendMessage ( String s ) {
log . info ( s ) ;
2010-12-22 16:22:23 +01:00
}
2011-11-20 09:01:14 +01:00
public void warning ( String s ) {
2011-04-20 19:05:14 +02:00
log . warning ( s ) ;
2011-03-31 22:40:00 +02:00
}
2011-04-20 19:05:14 +02:00
public String getName ( ) {
2010-12-22 16:22:23 +01:00
return " CONSOLE " ;
}
2010-12-28 20:52:24 +01:00
2011-06-27 00:25:01 +02:00
public WorldServer getWorldServer ( int i ) {
2011-05-28 22:50:08 +02:00
// CraftBukkit start
2011-06-27 00:25:01 +02:00
for ( WorldServer world : this . worlds ) {
2011-05-26 23:15:27 +02:00
if ( world . dimension = = i ) {
return world ;
}
}
2011-05-28 22:50:08 +02:00
2011-06-27 00:25:01 +02:00
return this . worlds . get ( 0 ) ;
2011-05-28 22:50:08 +02:00
// CraftBukkit end
2011-05-26 14:48:22 +02:00
}
2011-06-27 00:25:01 +02:00
public EntityTracker getTracker ( int i ) {
return this . getWorldServer ( i ) . tracker ; // CraftBukkit
2011-05-26 14:48:22 +02:00
}
2011-11-20 09:01:14 +01:00
public int getProperty ( String s , int i ) {
return this . propertyManager . getInt ( s , i ) ;
}
public String a ( String s , String s1 ) {
return this . propertyManager . getString ( s , s1 ) ;
}
public void a ( String s , Object object ) {
this . propertyManager . a ( s , object ) ;
}
public void c ( ) {
this . propertyManager . savePropertiesFile ( ) ;
}
public String getPropertiesFile ( ) {
File file1 = this . propertyManager . c ( ) ;
return file1 ! = null ? file1 . getAbsolutePath ( ) : " No settings file " ;
}
public String getMotd ( ) {
2012-01-12 23:10:13 +01:00
return this . t ;
2011-11-20 09:01:14 +01:00
}
public int getPort ( ) {
2012-01-12 23:10:13 +01:00
return this . u ;
2011-11-20 09:01:14 +01:00
}
public String getServerAddress ( ) {
2012-01-12 23:10:13 +01:00
return this . s ;
2011-11-20 09:01:14 +01:00
}
public String getVersion ( ) {
2012-01-12 23:10:13 +01:00
return " 1.1 " ;
2011-11-20 09:01:14 +01:00
}
public int getPlayerCount ( ) {
2011-11-30 00:17:43 +01:00
return this . serverConfigurationManager . getPlayerCount ( ) ;
2011-11-20 09:01:14 +01:00
}
public int getMaxPlayers ( ) {
2011-11-30 00:17:43 +01:00
return this . serverConfigurationManager . getMaxPlayers ( ) ;
2011-11-20 09:01:14 +01:00
}
public String [ ] getPlayers ( ) {
return this . serverConfigurationManager . d ( ) ;
}
public String getWorldName ( ) {
return this . propertyManager . getString ( " level-name " , " world " ) ;
}
public String getPlugins ( ) {
2011-11-06 00:58:13 +01:00
// CraftBukkit start - whole method
StringBuilder result = new StringBuilder ( ) ;
Plugin [ ] plugins = server . getPluginManager ( ) . getPlugins ( ) ;
result . append ( server . getName ( ) ) ;
result . append ( " on Bukkit " ) ;
result . append ( server . getBukkitVersion ( ) ) ;
if ( plugins . length > 0 ) {
result . append ( " : " ) ;
for ( int i = 0 ; i < plugins . length ; i + + ) {
if ( i > 0 ) {
result . append ( " ; " ) ;
}
result . append ( plugins [ i ] . getDescription ( ) . getName ( ) ) ;
result . append ( " " ) ;
result . append ( plugins [ i ] . getDescription ( ) . getVersion ( ) . replaceAll ( " ; " , " , " ) ) ;
}
}
return result . toString ( ) ;
// CraftBukkit end
2011-11-20 09:01:14 +01:00
}
public void o ( ) { }
public String d ( String s ) {
2012-01-12 16:27:39 +01:00
RemoteControlCommandListener . instance . a ( ) ;
2012-01-12 12:02:39 +01:00
// CraftBukkit start
2011-12-07 07:01:05 +01:00
ServerCommandEvent event = new ServerCommandEvent ( Event . Type . REMOTE_COMMAND , this . remoteConsole , s ) ;
this . server . getPluginManager ( ) . callEvent ( event ) ;
2012-01-12 16:27:39 +01:00
ServerCommand servercommand = new ServerCommand ( event . getCommand ( ) , RemoteControlCommandListener . instance ) ;
// this.consoleCommandHandler.handle(new ServerCommand(s, RemoteControlCommandListener.instance)); // CraftBukkit - removed
2011-12-07 07:01:05 +01:00
this . server . dispatchCommand ( this . remoteConsole , servercommand ) ; // CraftBukkit
// CraftBukkit end
2012-01-12 16:27:39 +01:00
return RemoteControlCommandListener . instance . b ( ) ;
2011-11-20 09:01:14 +01:00
}
public boolean isDebugging ( ) {
2011-11-06 00:58:13 +01:00
return this . propertyManager . getBoolean ( " debug " , false ) ; // CraftBukkit - don't hardcode
2011-11-20 09:01:14 +01:00
}
public void severe ( String s ) {
log . log ( Level . SEVERE , s ) ;
}
public void debug ( String s ) {
if ( this . isDebugging ( ) ) {
log . log ( Level . INFO , s ) ;
}
}
public String [ ] q ( ) {
2011-11-30 00:17:43 +01:00
return ( String [ ] ) this . serverConfigurationManager . getBannedAddresses ( ) . toArray ( new String [ 0 ] ) ;
2011-11-20 09:01:14 +01:00
}
public String [ ] r ( ) {
2011-11-30 00:17:43 +01:00
return ( String [ ] ) this . serverConfigurationManager . getBannedPlayers ( ) . toArray ( new String [ 0 ] ) ;
2011-11-20 09:01:14 +01:00
}
2011-04-20 19:05:14 +02:00
public static boolean isRunning ( MinecraftServer minecraftserver ) {
return minecraftserver . isRunning ;
2010-12-28 20:52:24 +01:00
}
2011-01-11 09:25:13 +01:00
}