    001    package net.minecraft.server;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.awt.GraphicsEnvironment;
    006    import java.io.File;
    007    import java.io.IOException;
    008    import java.security.KeyPair;
    009    import java.text.SimpleDateFormat;
    010    import java.util.ArrayList;
    011    import java.util.Date;
    012    import java.util.Hashtable;
    013    import java.util.Iterator;
    014    import java.util.List;
    015    import java.util.logging.Level;
    016    import java.util.logging.Logger;
    017    import cpw.mods.fml.common.FMLCommonHandler;
    018    import cpw.mods.fml.relauncher.ArgsWrapper;
    019    import cpw.mods.fml.relauncher.FMLRelauncher;
    020    import net.minecraft.src.AnvilSaveConverter;
    021    import net.minecraft.src.AxisAlignedBB;
    022    import net.minecraft.src.BehaviorArrowDispense;
    023    import net.minecraft.src.BehaviorBucketEmptyDispense;
    024    import net.minecraft.src.BehaviorBucketFullDispense;
    025    import net.minecraft.src.BehaviorDispenseBoat;
    026    import net.minecraft.src.BehaviorDispenseFireball;
    027    import net.minecraft.src.BehaviorDispenseMinecart;
    028    import net.minecraft.src.BehaviorEggDispense;
    029    import net.minecraft.src.BehaviorExpBottleDispense;
    030    import net.minecraft.src.BehaviorMobEggDispense;
    031    import net.minecraft.src.BehaviorPotionDispense;
    032    import net.minecraft.src.BehaviorSnowballDispense;
    033    import net.minecraft.src.BlockDispenser;
    034    import net.minecraft.src.CallableIsServerModded;
    035    import net.minecraft.src.CallablePlayers;
    036    import net.minecraft.src.CallableServerMemoryStats;
    037    import net.minecraft.src.CallableServerProfiler;
    038    import net.minecraft.src.ChunkCoordinates;
    039    import net.minecraft.src.CommandBase;
    040    import net.minecraft.src.ConvertingProgressUpdate;
    041    import net.minecraft.src.CrashReport;
    042    import net.minecraft.src.DedicatedServer;
    043    import net.minecraft.src.DemoWorldServer;
    044    import net.minecraft.src.EnumGameType;
    045    import net.minecraft.src.ICommandManager;
    046    import net.minecraft.src.ICommandSender;
    047    import net.minecraft.src.IPlayerUsage;
    048    import net.minecraft.src.IProgressUpdate;
    049    import net.minecraft.src.ISaveFormat;
    050    import net.minecraft.src.ISaveHandler;
    051    import net.minecraft.src.IUpdatePlayerListBox;
    052    import net.minecraft.src.Item;
    053    import net.minecraft.src.MathHelper;
    054    import net.minecraft.src.MinecraftException;
    055    import net.minecraft.src.NetworkListenThread;
    056    import net.minecraft.src.Packet;
    057    import net.minecraft.src.Packet4UpdateTime;
    058    import net.minecraft.src.PlayerUsageSnooper;
    059    import net.minecraft.src.Profiler;
    060    import net.minecraft.src.RConConsoleSource;
    061    import net.minecraft.src.ReportedException;
    062    import net.minecraft.src.ServerCommandManager;
    063    import net.minecraft.src.ServerConfigurationManager;
    064    import net.minecraft.src.StatList;
    065    import net.minecraft.src.StringTranslate;
    066    import net.minecraft.src.StringUtils;
    067    import net.minecraft.src.ThreadDedicatedServer;
    068    import net.minecraft.src.ThreadMinecraftServer;
    069    import net.minecraft.src.WorldInfo;
    070    import net.minecraft.src.WorldManager;
    071    import net.minecraft.src.WorldServer;
    072    import net.minecraft.src.WorldServerMulti;
    073    import net.minecraft.src.WorldSettings;
    074    import net.minecraft.src.WorldType;
    075    import net.minecraftforge.common.DimensionManager;
    076    import net.minecraftforge.common.MinecraftForge;
    077    import net.minecraftforge.event.world.WorldEvent;
    078
    079    public abstract class MinecraftServer implements Runnable, IPlayerUsage, ICommandSender
    080    {
    081        /** The logging system. */
    082        public static Logger logger = Logger.getLogger("Minecraft");
    083
    084        /** Instance of Minecraft Server. */
    085        private static MinecraftServer mcServer = null;
    086        private final ISaveFormat anvilConverterForAnvilFile;
    087
    088        /** The PlayerUsageSnooper instance. */
    089        private final PlayerUsageSnooper usageSnooper = new PlayerUsageSnooper("server", this);
    090        private final File anvilFile;
    091
    092        /** List of names of players who are online. */
    093        private final List playersOnline = new ArrayList();
    094        private final ICommandManager commandManager;
    095        public final Profiler theProfiler = new Profiler();
    096
    097        /** The server's hostname. */
    098        private String hostname;
    099
    100        /** The server's port. */
    101        private int serverPort = -1;
    102
    103        /** The server world instances. */
    104        public WorldServer[] worldServers;
    105
    106        /** The ServerConfigurationManager instance. */
    107        private ServerConfigurationManager serverConfigManager;
    108
    109        /**
    110         * Indicates whether the server is running or not. Set to false to initiate a shutdown.
    111         */
    112        private boolean serverRunning = true;
    113
    114        /** Indicates to other classes that the server is safely stopped. */
    115        private boolean serverStopped = false;
    116
    117        /** Incremented every tick. */
    118        private int tickCounter = 0;
    119
    120        /**
    121         * The task the server is currently working on(and will output on outputPercentRemaining).
    122         */
    123        public String currentTask;
    124
    125        /** The percentage of the current task finished so far. */
    126        public int percentDone;
    127
    128        /** True if the server is in online mode. */
    129        private boolean onlineMode;
    130
    131        /** True if the server has animals turned on. */
    132        private boolean canSpawnAnimals;
    133        private boolean canSpawnNPCs;
    134
    135        /** Indicates whether PvP is active on the server or not. */
    136        private boolean pvpEnabled;
    137
    138        /** Determines if flight is allowed or not. */
    139        private boolean allowFlight;
    140
    141        /** The server MOTD string. */
    142        private String motd;
    143
    144        /** Maximum build height. */
    145        private int buildLimit;
    146        private long lastSentPacketID;
    147        private long lastSentPacketSize;
    148        private long lastReceivedID;
    149        private long lastReceivedSize;
    150        public final long[] sentPacketCountArray = new long[100];
    151        public final long[] sentPacketSizeArray = new long[100];
    152        public final long[] receivedPacketCountArray = new long[100];
    153        public final long[] receivedPacketSizeArray = new long[100];
    154        public final long[] tickTimeArray = new long[100];
    155
    156        /** Stats are [dimension][tick%100] system.nanoTime is stored. */
    157        //public long[][] timeOfLastDimensionTick;
    158        public Hashtable<Integer, long[]> worldTickTimes = new Hashtable<Integer, long[]>();
    159        private KeyPair serverKeyPair;
    160
    161        /** Username of the server owner (for integrated servers) */
    162        private String serverOwner;
    163        private String folderName;
    164        @SideOnly(Side.CLIENT)
    165        private String worldName;
    166        private boolean isDemo;
    167        private boolean enableBonusChest;
    168
    169        /**
    170         * If true, there is no need to save chunks or stop the server, because that is already being done.
    171         */
    172        private boolean worldIsBeingDeleted;
    173        private String texturePack = "";
    174        private boolean serverIsRunning = false;
    175
    176        /**
    177         * Set when warned for "Can't keep up", which triggers again after 15 seconds.
    178         */
    179        private long timeOfLastWarning;
    180        private String userMessage;
    181        private boolean startProfiling;
    182
    183        public MinecraftServer(File par1File)
    184        {
    185            mcServer = this;
    186            this.anvilFile = par1File;
    187            this.commandManager = new ServerCommandManager();
    188            this.anvilConverterForAnvilFile = new AnvilSaveConverter(par1File);
    189            this.func_82355_al();
    190        }
    191
    192        private void func_82355_al()
    193        {
    194            BlockDispenser.field_82527_a.func_82595_a(Item.arrow, new BehaviorArrowDispense(this));
    195            BlockDispenser.field_82527_a.func_82595_a(Item.egg, new BehaviorEggDispense(this));
    196            BlockDispenser.field_82527_a.func_82595_a(Item.snowball, new BehaviorSnowballDispense(this));
    197            BlockDispenser.field_82527_a.func_82595_a(Item.expBottle, new BehaviorExpBottleDispense(this));
    198            BlockDispenser.field_82527_a.func_82595_a(Item.potion, new BehaviorPotionDispense(this));
    199            BlockDispenser.field_82527_a.func_82595_a(Item.monsterPlacer, new BehaviorMobEggDispense(this));
    200            BlockDispenser.field_82527_a.func_82595_a(Item.fireballCharge, new BehaviorDispenseFireball(this));
    201            BehaviorDispenseMinecart var1 = new BehaviorDispenseMinecart(this);
    202            BlockDispenser.field_82527_a.func_82595_a(Item.minecartEmpty, var1);
    203            BlockDispenser.field_82527_a.func_82595_a(Item.minecartCrate, var1);
    204            BlockDispenser.field_82527_a.func_82595_a(Item.minecartPowered, var1);
    205            BlockDispenser.field_82527_a.func_82595_a(Item.boat, new BehaviorDispenseBoat(this));
    206            BehaviorBucketFullDispense var2 = new BehaviorBucketFullDispense(this);
    207            BlockDispenser.field_82527_a.func_82595_a(Item.bucketLava, var2);
    208            BlockDispenser.field_82527_a.func_82595_a(Item.bucketWater, var2);
    209            BlockDispenser.field_82527_a.func_82595_a(Item.bucketEmpty, new BehaviorBucketEmptyDispense(this));
    210        }
    211
    212        /**
    213         * Initialises the server and starts it.
    214         */
    215        protected abstract boolean startServer() throws IOException;
    216
    217        protected void convertMapIfNeeded(String par1Str)
    218        {
    219            if (this.getActiveAnvilConverter().isOldMapFormat(par1Str))
    220            {
    221                logger.info("Converting map!");
    222                this.setUserMessage("menu.convertingLevel");
    223                this.getActiveAnvilConverter().convertMapFormat(par1Str, new ConvertingProgressUpdate(this));
    224            }
    225        }
    226
    227        /**
    228         * Typically "menu.convertingLevel", "menu.loadingLevel" or others.
    229         */
    230        protected synchronized void setUserMessage(String par1Str)
    231        {
    232            this.userMessage = par1Str;
    233        }
    234
    235        @SideOnly(Side.CLIENT)
    236
    237        public synchronized String getUserMessage()
    238        {
    239            return this.userMessage;
    240        }
    241
    242        protected void loadAllWorlds(String par1Str, String par2Str, long par3, WorldType par5WorldType, String par6Str)
    243        {
    244            this.convertMapIfNeeded(par1Str);
    245            this.setUserMessage("menu.loadingLevel");
    246            ISaveHandler var7 = this.anvilConverterForAnvilFile.getSaveLoader(par1Str, true);
    247            WorldInfo var9 = var7.loadWorldInfo();
    248            WorldSettings var8;
    249
    250            if (var9 == null)
    251            {
    252                var8 = new WorldSettings(par3, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), par5WorldType);
    253                var8.func_82750_a(par6Str);
    254            }
    255            else
    256            {
    257                var8 = new WorldSettings(var9);
    258            }
    259
    260            if (this.enableBonusChest)
    261            {
    262                var8.enableBonusChest();
    263            }
    264
    265            WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, var7, par2Str, 0, theProfiler) : new WorldServer(this, var7, par2Str, 0, var8, theProfiler));
    266            for (int dim : DimensionManager.getStaticDimensionIDs())
    267            {
    268                WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, var7, par2Str, dim, var8, overWorld, theProfiler));
    269                world.addWorldAccess(new WorldManager(this, world));
    270
    271                if (!this.isSinglePlayer())
    272                {
    273                    world.getWorldInfo().setGameType(this.getGameType());
    274                }
    275
    276                this.serverConfigManager.setPlayerManager(this.worldServers);
    277
    278                MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
    279            }
    280
    281            this.serverConfigManager.setPlayerManager(new WorldServer[]{ overWorld });
    282            this.setDifficultyForAllWorlds(this.getDifficulty());
    283            this.initialWorldChunkLoad();
    284        }
    285
    286        protected void initialWorldChunkLoad()
    287        {
    288            int var5 = 0;
    289            this.setUserMessage("menu.generatingTerrain");
    290            byte var6 = 0;
    291            logger.info("Preparing start region for level " + var6);
    292            WorldServer var7 = this.worldServers[var6];
    293            ChunkCoordinates var8 = var7.getSpawnPoint();
    294            long var9 = System.currentTimeMillis();
    295
    296            for (int var11 = -192; var11 <= 192 && this.isServerRunning(); var11 += 16)
    297            {
    298                for (int var12 = -192; var12 <= 192 && this.isServerRunning(); var12 += 16)
    299                {
    300                    long var13 = System.currentTimeMillis();
    301
    302                    if (var13 - var9 > 1000L)
    303                    {
    304                        this.outputPercentRemaining("Preparing spawn area", var5 * 100 / 625);
    305                        var9 = var13;
    306                    }
    307
    308                    ++var5;
    309                    var7.theChunkProviderServer.loadChunk(var8.posX + var11 >> 4, var8.posZ + var12 >> 4);
    310                }
    311            }
    312
    313            this.clearCurrentTask();
    314        }
    315
    316        public abstract boolean canStructuresSpawn();
    317
    318        public abstract EnumGameType getGameType();
    319
    320        /**
    321         * Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on the client.
    322         */
    323        public abstract int getDifficulty();
    324
    325        /**
    326         * Defaults to false.
    327         */
    328        public abstract boolean isHardcore();
    329
    330        /**
    331         * Used to display a percent remaining given text and the percentage.
    332         */
    333        protected void outputPercentRemaining(String par1Str, int par2)
    334        {
    335            this.currentTask = par1Str;
    336            this.percentDone = par2;
    337            logger.info(par1Str + ": " + par2 + "%");
    338        }
    339
    340        /**
    341         * Set current task to null and set its percentage to 0.
    342         */
    343        protected void clearCurrentTask()
    344        {
    345            this.currentTask = null;
    346            this.percentDone = 0;
    347        }
    348
    349        /**
    350         * par1 indicates if a log message should be output.
    351         */
    352        protected void saveAllWorlds(boolean par1)
    353        {
    354            if (!this.worldIsBeingDeleted)
    355            {
    356                WorldServer[] var2 = this.worldServers;
    357                int var3 = var2.length;
    358
    359                for (int var4 = 0; var4 < var3; ++var4)
    360                {
    361                    WorldServer var5 = var2[var4];
    362
    363                    if (var5 != null)
    364                    {
    365                        if (!par1)
    366                        {
    367                            logger.info("Saving chunks for level \'" + var5.getWorldInfo().getWorldName() + "\'/" + var5.provider.getDimensionName());
    368                        }
    369
    370                        try
    371                        {
    372                            var5.saveAllChunks(true, (IProgressUpdate)null);
    373                        }
    374                        catch (MinecraftException var7)
    375                        {
    376                            logger.warning(var7.getMessage());
    377                        }
    378                    }
    379                }
    380            }
    381        }
    382
    383        /**
    384         * Saves all necessary data as preparation for stopping the server.
    385         */
    386        public void stopServer()
    387        {
    388            if (!this.worldIsBeingDeleted)
    389            {
    390                logger.info("Stopping server");
    391
    392                if (this.getNetworkThread() != null)
    393                {
    394                    this.getNetworkThread().stopListening();
    395                }
    396
    397                if (this.serverConfigManager != null)
    398                {
    399                    logger.info("Saving players");
    400                    this.serverConfigManager.saveAllPlayerData();
    401                    this.serverConfigManager.removeAllPlayers();
    402                }
    403
    404                logger.info("Saving worlds");
    405                this.saveAllWorlds(false);
    406                WorldServer[] var1 = this.worldServers;
    407                int var2 = var1.length;
    408
    409                for (int var3 = 0; var3 < var2; ++var3)
    410                {
    411                    WorldServer var4 = var1[var3];
    412                    MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var4));
    413                    var4.flush();
    414                    DimensionManager.setWorld(var4.provider.dimensionId, null);
    415                }
    416
    417                if (this.usageSnooper != null && this.usageSnooper.isSnooperRunning())
    418                {
    419                    this.usageSnooper.stopSnooper();
    420                }
    421            }
    422        }
    423
    424        /**
    425         * "getHostname" is already taken, but both return the hostname.
    426         */
    427        public String getServerHostname()
    428        {
    429            return this.hostname;
    430        }
    431
    432        public void setHostname(String par1Str)
    433        {
    434            this.hostname = par1Str;
    435        }
    436
    437        public boolean isServerRunning()
    438        {
    439            return this.serverRunning;
    440        }
    441
    442        /**
    443         * Sets the serverRunning variable to false, in order to get the server to shut down.
    444         */
    445        public void initiateShutdown()
    446        {
    447            this.serverRunning = false;
    448        }
    449
    450        public void run()
    451        {
    452            try
    453            {
    454                if (this.startServer())
    455                {
    456                    FMLCommonHandler.instance().handleServerStarted();
    457                    long var1 = System.currentTimeMillis();
    458
    459                    FMLCommonHandler.instance().onWorldLoadTick(worldServers);
    460
    461                    for (long var50 = 0L; this.serverRunning; this.serverIsRunning = true)
    462                    {
    463                        long var5 = System.currentTimeMillis();
    464                        long var7 = var5 - var1;
    465
    466                        if (var7 > 2000L && var1 - this.timeOfLastWarning >= 15000L)
    467                        {
    468                            logger.warning("Can\'t keep up! Did the system time change, or is the server overloaded?");
    469                            var7 = 2000L;
    470                            this.timeOfLastWarning = var1;
    471                        }
    472
    473                        if (var7 < 0L)
    474                        {
    475                            logger.warning("Time ran backwards! Did the system time change?");
    476                            var7 = 0L;
    477                        }
    478
    479                        var50 += var7;
    480                        var1 = var5;
    481
    482                        if (this.worldServers[0].areAllPlayersAsleep())
    483                        {
    484                            this.tick();
    485                            var50 = 0L;
    486                        }
    487                        else
    488                        {
    489                            while (var50 > 50L)
    490                            {
    491                                var50 -= 50L;
    492                                this.tick();
    493                            }
    494                        }
    495
    496                        Thread.sleep(1L);
    497                    }
    498                    FMLCommonHandler.instance().handleServerStopping();
    499                }
    500                else
    501                {
    502                    this.finalTick((CrashReport)null);
    503                }
    504            }
    505            catch (Throwable var48)
    506            {
    507                var48.printStackTrace();
    508                logger.log(Level.SEVERE, "Encountered an unexpected exception " + var48.getClass().getSimpleName(), var48);
    509                CrashReport var2 = null;
    510
    511                if (var48 instanceof ReportedException)
    512                {
    513                    var2 = this.addServerInfoToCrashReport(((ReportedException)var48).getTheReportedExceptionCrashReport());
    514                }
    515                else
    516                {
    517                    var2 = this.addServerInfoToCrashReport(new CrashReport("Exception in server tick loop", var48));
    518                }
    519
    520                File var3 = new File(new File(this.getDataDirectory(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
    521
    522                if (var2.saveToFile(var3))
    523                {
    524                    logger.severe("This crash report has been saved to: " + var3.getAbsolutePath());
    525                }
    526                else
    527                {
    528                    logger.severe("We were unable to save this crash report to disk.");
    529                }
    530
    531                this.finalTick(var2);
    532            }
    533            finally
    534            {
    535                try
    536                {
    537                    this.stopServer();
    538                    this.serverStopped = true;
    539                }
    540                catch (Throwable var46)
    541                {
    542                    var46.printStackTrace();
    543                }
    544                finally
    545                {
    546                    this.systemExitNow();
    547                }
    548            }
    549        }
    550
    551        protected File getDataDirectory()
    552        {
    553            return new File(".");
    554        }
    555
    556        /**
    557         * Called on exit from the main run() loop.
    558         */
    559        protected void finalTick(CrashReport par1CrashReport) {}
    560
    561        /**
    562         * Directly calls System.exit(0), instantly killing the program.
    563         */
    564        protected void systemExitNow() {}
    565
    566        /**
    567         * Main function called by run() every loop.
    568         */
    569        public void tick()
    570        {
    571            FMLCommonHandler.instance().rescheduleTicks(Side.SERVER);
    572            long var1 = System.nanoTime();
    573            AxisAlignedBB.getAABBPool().cleanPool();
    574            FMLCommonHandler.instance().onPreServerTick();
    575            ++this.tickCounter;
    576
    577            if (this.startProfiling)
    578            {
    579                this.startProfiling = false;
    580                this.theProfiler.profilingEnabled = true;
    581                this.theProfiler.clearProfiling();
    582            }
    583
    584            this.theProfiler.startSection("root");
    585            this.updateTimeLightAndEntities();
    586
    587            if (this.tickCounter % 900 == 0)
    588            {
    589                this.theProfiler.startSection("save");
    590                this.serverConfigManager.saveAllPlayerData();
    591                this.saveAllWorlds(true);
    592                this.theProfiler.endSection();
    593            }
    594
    595            this.theProfiler.startSection("tallying");
    596            this.tickTimeArray[this.tickCounter % 100] = System.nanoTime() - var1;
    597            this.sentPacketCountArray[this.tickCounter % 100] = Packet.sentID - this.lastSentPacketID;
    598            this.lastSentPacketID = Packet.sentID;
    599            this.sentPacketSizeArray[this.tickCounter % 100] = Packet.sentSize - this.lastSentPacketSize;
    600            this.lastSentPacketSize = Packet.sentSize;
    601            this.receivedPacketCountArray[this.tickCounter % 100] = Packet.receivedID - this.lastReceivedID;
    602            this.lastReceivedID = Packet.receivedID;
    603            this.receivedPacketSizeArray[this.tickCounter % 100] = Packet.receivedSize - this.lastReceivedSize;
    604            this.lastReceivedSize = Packet.receivedSize;
    605            this.theProfiler.endSection();
    606            this.theProfiler.startSection("snooper");
    607
    608            if (!this.usageSnooper.isSnooperRunning() && this.tickCounter > 100)
    609            {
    610                this.usageSnooper.startSnooper();
    611            }
    612
    613            if (this.tickCounter % 6000 == 0)
    614            {
    615                this.usageSnooper.addMemoryStatsToSnooper();
    616            }
    617
    618            this.theProfiler.endSection();
    619            this.theProfiler.endSection();
    620            FMLCommonHandler.instance().onPostServerTick();
    621        }
    622
    623        public void updateTimeLightAndEntities()
    624        {
    625            this.theProfiler.startSection("levels");
    626
    627            for (Integer id : DimensionManager.getIDs())
    628            {
    629                long var2 = System.nanoTime();
    630
    631                if (id == 0 || this.getAllowNether())
    632                {
    633                    WorldServer var4 = DimensionManager.getWorld(id);
    634                    this.theProfiler.startSection(var4.getWorldInfo().getWorldName());
    635                    this.theProfiler.startSection("pools");
    636                    var4.func_82732_R().clear();
    637                    this.theProfiler.endSection();
    638
    639                    if (this.tickCounter % 20 == 0)
    640                    {
    641                        this.theProfiler.startSection("timeSync");
    642                        this.serverConfigManager.sendPacketToAllPlayersInDimension(new Packet4UpdateTime(var4.func_82737_E(), var4.getWorldTime()), var4.provider.dimensionId);
    643                        this.theProfiler.endSection();
    644                    }
    645
    646                    this.theProfiler.startSection("tick");
    647                    FMLCommonHandler.instance().onPreWorldTick(var4);
    648                    var4.tick();
    649                    var4.updateEntities();
    650                    FMLCommonHandler.instance().onPostWorldTick(var4);
    651                    this.theProfiler.endSection();
    652                    this.theProfiler.startSection("tracker");
    653                    var4.getEntityTracker().updateTrackedEntities();
    654                    this.theProfiler.endSection();
    655                    this.theProfiler.endSection();
    656                }
    657
    658                worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - var2;
    659            }
    660
    661            this.theProfiler.endStartSection("dim_unloading");
    662            DimensionManager.unloadWorlds(worldTickTimes);
    663            this.theProfiler.endStartSection("connection");
    664            this.getNetworkThread().networkTick();
    665            this.theProfiler.endStartSection("players");
    666            this.serverConfigManager.sendPlayerInfoToAllPlayers();
    667            this.theProfiler.endStartSection("tickables");
    668            Iterator var5 = this.playersOnline.iterator();
    669
    670            while (var5.hasNext())
    671            {
    672                IUpdatePlayerListBox var6 = (IUpdatePlayerListBox)var5.next();
    673                var6.update();
    674            }
    675
    676            this.theProfiler.endSection();
    677        }
    678
    679        public boolean getAllowNether()
    680        {
    681            return true;
    682        }
    683
    684        public void startServerThread()
    685        {
    686            (new ThreadMinecraftServer(this, "Server thread")).start();
    687        }
    688
    689        /**
    690         * Returns a File object from the specified string.
    691         */
    692        public File getFile(String par1Str)
    693        {
    694            return new File(this.getDataDirectory(), par1Str);
    695        }
    696
    697        /**
    698         * Logs the message with a level of INFO.
    699         */
    700        public void logInfo(String par1Str)
    701        {
    702            logger.info(par1Str);
    703        }
    704
    705        /**
    706         * Logs the message with a level of WARN.
    707         */
    708        public void logWarning(String par1Str)
    709        {
    710            logger.warning(par1Str);
    711        }
    712
    713        /**
    714         * Gets the worldServer by the given dimension.
    715         */
    716        public WorldServer worldServerForDimension(int par1)
    717        {
    718            WorldServer ret = DimensionManager.getWorld(par1);
    719            if (ret == null)
    720            {
    721                DimensionManager.initDimension(par1);
    722                ret = DimensionManager.getWorld(par1);
    723            }
    724            return ret;
    725        }
    726
    727        @SideOnly(Side.SERVER)
    728        public void func_82010_a(IUpdatePlayerListBox par1IUpdatePlayerListBox)
    729        {
    730            this.playersOnline.add(par1IUpdatePlayerListBox);
    731        }
    732
    733        /**
    734         * Returns the server's hostname.
    735         */
    736        public String getHostname()
    737        {
    738            return this.hostname;
    739        }
    740
    741        /**
    742         * Never used, but "getServerPort" is already taken.
    743         */
    744        public int getPort()
    745        {
    746            return this.serverPort;
    747        }
    748
    749        /**
    750         * minecraftServer.getMOTD is used in 2 places instead (it is a non-virtual function which returns the same thing)
    751         */
    752        public String getServerMOTD()
    753        {
    754            return this.motd;
    755        }
    756
    757        /**
    758         * Returns the server's Minecraft version as string.
    759         */
    760        public String getMinecraftVersion()
    761        {
    762            return "1.4";
    763        }
    764
    765        /**
    766         * Returns the number of players currently on the server.
    767         */
    768        public int getCurrentPlayerCount()
    769        {
    770            return this.serverConfigManager.getCurrentPlayerCount();
    771        }
    772
    773        /**
    774         * Returns the maximum number of players allowed on the server.
    775         */
    776        public int getMaxPlayers()
    777        {
    778            return this.serverConfigManager.getMaxPlayers();
    779        }
    780
    781        /**
    782         * Returns an array of the usernames of all the connected players.
    783         */
    784        public String[] getAllUsernames()
    785        {
    786            return this.serverConfigManager.getAllUsernames();
    787        }
    788
    789        /**
    790         * Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3; AnotherPlugin 2.1; AndSoForth 1.0".
    791         */
    792        public String getPlugins()
    793        {
    794            return "";
    795        }
    796
    797        public String executeCommand(String par1Str)
    798        {
    799            RConConsoleSource.consoleBuffer.resetLog();
    800            this.commandManager.executeCommand(RConConsoleSource.consoleBuffer, par1Str);
    801            return RConConsoleSource.consoleBuffer.getChatBuffer();
    802        }
    803
    804        /**
    805         * Returns true if debugging is enabled, false otherwise.
    806         */
    807        public boolean isDebuggingEnabled()
    808        {
    809            return false;
    810        }
    811
    812        /**
    813         * Logs the error message with a level of SEVERE.
    814         */
    815        public void logSevere(String par1Str)
    816        {
    817            logger.log(Level.SEVERE, par1Str);
    818        }
    819
    820        /**
    821         * If isDebuggingEnabled(), logs the message with a level of INFO.
    822         */
    823        public void logDebug(String par1Str)
    824        {
    825            if (this.isDebuggingEnabled())
    826            {
    827                logger.log(Level.INFO, par1Str);
    828            }
    829        }
    830
    831        public String getServerModName()
    832        {
    833            return "forge,fml";
    834        }
    835
    836        /**
    837         * Adds the server info, including from theWorldServer, to the crash report.
    838         */
    839        public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport)
    840        {
    841            par1CrashReport.addCrashSectionCallable("Is Modded", new CallableIsServerModded(this));
    842            par1CrashReport.addCrashSectionCallable("Profiler Position", new CallableServerProfiler(this));
    843
    844            if (this.worldServers != null && this.worldServers.length > 0 && this.worldServers[0] != null)
    845            {
    846                par1CrashReport.addCrashSectionCallable("Vec3 Pool Size", new CallableServerMemoryStats(this));
    847            }
    848
    849            if (this.serverConfigManager != null)
    850            {
    851                par1CrashReport.addCrashSectionCallable("Player Count", new CallablePlayers(this));
    852            }
    853
    854            if (this.worldServers != null)
    855            {
    856                WorldServer[] var2 = this.worldServers;
    857                int var3 = var2.length;
    858
    859                for (int var4 = 0; var4 < var3; ++var4)
    860                {
    861                    WorldServer var5 = var2[var4];
    862
    863                    if (var5 != null)
    864                    {
    865                        var5.addWorldInfoToCrashReport(par1CrashReport);
    866                    }
    867                }
    868            }
    869
    870            return par1CrashReport;
    871        }
    872
    873        /**
    874         * If par2Str begins with /, then it searches for commands, otherwise it returns players.
    875         */
    876        public List getPossibleCompletions(ICommandSender par1ICommandSender, String par2Str)
    877        {
    878            ArrayList var3 = new ArrayList();
    879
    880            if (par2Str.startsWith("/"))
    881            {
    882                par2Str = par2Str.substring(1);
    883                boolean var10 = !par2Str.contains(" ");
    884                List var11 = this.commandManager.getPossibleCommands(par1ICommandSender, par2Str);
    885
    886                if (var11 != null)
    887                {
    888                    Iterator var12 = var11.iterator();
    889
    890                    while (var12.hasNext())
    891                    {
    892                        String var13 = (String)var12.next();
    893
    894                        if (var10)
    895                        {
    896                            var3.add("/" + var13);
    897                        }
    898                        else
    899                        {
    900                            var3.add(var13);
    901                        }
    902                    }
    903                }
    904
    905                return var3;
    906            }
    907            else
    908            {
    909                String[] var4 = par2Str.split(" ", -1);
    910                String var5 = var4[var4.length - 1];
    911                String[] var6 = this.serverConfigManager.getAllUsernames();
    912                int var7 = var6.length;
    913
    914                for (int var8 = 0; var8 < var7; ++var8)
    915                {
    916                    String var9 = var6[var8];
    917
    918                    if (CommandBase.doesStringStartWith(var5, var9))
    919                    {
    920                        var3.add(var9);
    921                    }
    922                }
    923
    924                return var3;
    925            }
    926        }
    927
    928        /**
    929         * Gets mcServer.
    930         */
    931        public static MinecraftServer getServer()
    932        {
    933            return mcServer;
    934        }
    935
    936        /**
    937         * Gets the name of this command sender (usually username, but possibly "Rcon")
    938         */
    939        public String getCommandSenderName()
    940        {
    941            return "Server";
    942        }
    943
    944        public void sendChatToPlayer(String par1Str)
    945        {
    946            logger.info(StringUtils.stripControlCodes(par1Str));
    947        }
    948
    949        /**
    950         * Returns true if the command sender is allowed to use the given command.
    951         */
    952        public boolean canCommandSenderUseCommand(int par1, String par2Str)
    953        {
    954            return true;
    955        }
    956
    957        /**
    958         * Translates and formats the given string key with the given arguments.
    959         */
    960        public String translateString(String par1Str, Object ... par2ArrayOfObj)
    961        {
    962            return StringTranslate.getInstance().translateKeyFormat(par1Str, par2ArrayOfObj);
    963        }
    964
    965        public ICommandManager getCommandManager()
    966        {
    967            return this.commandManager;
    968        }
    969
    970        /**
    971         * Gets KeyPair instanced in MinecraftServer.
    972         */
    973        public KeyPair getKeyPair()
    974        {
    975            return this.serverKeyPair;
    976        }
    977
    978        /**
    979         * Gets serverPort.
    980         */
    981        public int getServerPort()
    982        {
    983            return this.serverPort;
    984        }
    985
    986        public void setServerPort(int par1)
    987        {
    988            this.serverPort = par1;
    989        }
    990
    991        /**
    992         * Returns the username of the server owner (for integrated servers)
    993         */
    994        public String getServerOwner()
    995        {
    996            return this.serverOwner;
    997        }
    998
    999        /**
    1000         * Sets the username of the owner of this server (in the case of an integrated server)
    1001         */
    1002        public void setServerOwner(String par1Str)
    1003        {
    1004            this.serverOwner = par1Str;
    1005        }
    1006
    1007        public boolean isSinglePlayer()
    1008        {
    1009            return this.serverOwner != null;
    1010        }
    1011
    1012        public String getFolderName()
    1013        {
    1014            return this.folderName;
    1015        }
    1016
    1017        public void setFolderName(String par1Str)
    1018        {
    1019            this.folderName = par1Str;
    1020        }
    1021
    1022        @SideOnly(Side.CLIENT)
    1023        public void setWorldName(String par1Str)
    1024        {
    1025            this.worldName = par1Str;
    1026        }
    1027
    1028        @SideOnly(Side.CLIENT)
    1029        public String getWorldName()
    1030        {
    1031            return this.worldName;
    1032        }
    1033
    1034        public void setKeyPair(KeyPair par1KeyPair)
    1035        {
    1036            this.serverKeyPair = par1KeyPair;
    1037        }
    1038
    1039        public void setDifficultyForAllWorlds(int par1)
    1040        {
    1041            for (int var2 = 0; var2 < this.worldServers.length; ++var2)
    1042            {
    1043                WorldServer var3 = this.worldServers[var2];
    1044
    1045                if (var3 != null)
    1046                {
    1047                    if (var3.getWorldInfo().isHardcoreModeEnabled())
    1048                    {
    1049                        var3.difficultySetting = 3;
    1050                        var3.setAllowedSpawnTypes(true, true);
    1051                    }
    1052                    else if (this.isSinglePlayer())
    1053                    {
    1054                        var3.difficultySetting = par1;
    1055                        var3.setAllowedSpawnTypes(var3.difficultySetting > 0, true);
    1056                    }
    1057                    else
    1058                    {
    1059                        var3.difficultySetting = par1;
    1060                        var3.setAllowedSpawnTypes(this.allowSpawnMonsters(), this.canSpawnAnimals);
    1061                    }
    1062                }
    1063            }
    1064        }
    1065
    1066        protected boolean allowSpawnMonsters()
    1067        {
    1068            return true;
    1069        }
    1070
    1071        /**
    1072         * Gets whether this is a demo or not.
    1073         */
    1074        public boolean isDemo()
    1075        {
    1076            return this.isDemo;
    1077        }
    1078
    1079        /**
    1080         * Sets whether this is a demo or not.
    1081         */
    1082        public void setDemo(boolean par1)
    1083        {
    1084            this.isDemo = par1;
    1085        }
    1086
    1087        public void canCreateBonusChest(boolean par1)
    1088        {
    1089            this.enableBonusChest = par1;
    1090        }
    1091
    1092        public ISaveFormat getActiveAnvilConverter()
    1093        {
    1094            return this.anvilConverterForAnvilFile;
    1095        }
    1096
    1097        /**
    1098         * WARNING : directly calls
    1099         * getActiveAnvilConverter().deleteWorldDirectory(theWorldServer[0].getSaveHandler().getSaveDirectoryName());
    1100         */
    1101        public void deleteWorldAndStopServer()
    1102        {
    1103            this.worldIsBeingDeleted = true;
    1104            this.getActiveAnvilConverter().flushCache();
    1105
    1106            for (int var1 = 0; var1 < this.worldServers.length; ++var1)
    1107            {
    1108                WorldServer var2 = this.worldServers[var1];
    1109
    1110                if (var2 != null)
    1111                {
    1112                    MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(var2));
    1113                    var2.flush();
    1114                }
    1115            }
    1116
    1117            this.getActiveAnvilConverter().deleteWorldDirectory(this.worldServers[0].getSaveHandler().getSaveDirectoryName());
    1118            this.initiateShutdown();
    1119        }
    1120
    1121        public String getTexturePack()
    1122        {
    1123            return this.texturePack;
    1124        }
    1125
    1126        public void setTexturePack(String par1Str)
    1127        {
    1128            this.texturePack = par1Str;
    1129        }
    1130
    1131        public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper)
    1132        {
    1133            par1PlayerUsageSnooper.addData("whitelist_enabled", Boolean.valueOf(false));
    1134            par1PlayerUsageSnooper.addData("whitelist_count", Integer.valueOf(0));
    1135            par1PlayerUsageSnooper.addData("players_current", Integer.valueOf(this.getCurrentPlayerCount()));
    1136            par1PlayerUsageSnooper.addData("players_max", Integer.valueOf(this.getMaxPlayers()));
    1137            par1PlayerUsageSnooper.addData("players_seen", Integer.valueOf(this.serverConfigManager.getAvailablePlayerDat().length));
    1138            par1PlayerUsageSnooper.addData("uses_auth", Boolean.valueOf(this.onlineMode));
    1139            par1PlayerUsageSnooper.addData("gui_state", this.getGuiEnabled() ? "enabled" : "disabled");
    1140            par1PlayerUsageSnooper.addData("avg_tick_ms", Integer.valueOf((int)(MathHelper.average(this.tickTimeArray) * 1.0E-6D)));
    1141            par1PlayerUsageSnooper.addData("avg_sent_packet_count", Integer.valueOf((int)MathHelper.average(this.sentPacketCountArray)));
    1142            par1PlayerUsageSnooper.addData("avg_sent_packet_size", Integer.valueOf((int)MathHelper.average(this.sentPacketSizeArray)));
    1143            par1PlayerUsageSnooper.addData("avg_rec_packet_count", Integer.valueOf((int)MathHelper.average(this.receivedPacketCountArray)));
    1144            par1PlayerUsageSnooper.addData("avg_rec_packet_size", Integer.valueOf((int)MathHelper.average(this.receivedPacketSizeArray)));
    1145            int var2 = 0;
    1146
    1147            for (int var3 = 0; var3 < this.worldServers.length; ++var3)
    1148            {
    1149                if (this.worldServers[var3] != null)
    1150                {
    1151                    WorldServer var4 = this.worldServers[var3];
    1152                    WorldInfo var5 = var4.getWorldInfo();
    1153                    par1PlayerUsageSnooper.addData("world[" + var2 + "][dimension]", Integer.valueOf(var4.provider.dimensionId));
    1154                    par1PlayerUsageSnooper.addData("world[" + var2 + "][mode]", var5.getGameType());
    1155                    par1PlayerUsageSnooper.addData("world[" + var2 + "][difficulty]", Integer.valueOf(var4.difficultySetting));
    1156                    par1PlayerUsageSnooper.addData("world[" + var2 + "][hardcore]", Boolean.valueOf(var5.isHardcoreModeEnabled()));
    1157                    par1PlayerUsageSnooper.addData("world[" + var2 + "][generator_name]", var5.getTerrainType().getWorldTypeName());
    1158                    par1PlayerUsageSnooper.addData("world[" + var2 + "][generator_version]", Integer.valueOf(var5.getTerrainType().getGeneratorVersion()));
    1159                    par1PlayerUsageSnooper.addData("world[" + var2 + "][height]", Integer.valueOf(this.buildLimit));
    1160                    par1PlayerUsageSnooper.addData("world[" + var2 + "][chunks_loaded]", Integer.valueOf(var4.getChunkProvider().getLoadedChunkCount()));
    1161                    ++var2;
    1162                }
    1163            }
    1164
    1165            par1PlayerUsageSnooper.addData("worlds", Integer.valueOf(var2));
    1166        }
    1167
    1168        public void addServerTypeToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper)
    1169        {
    1170            par1PlayerUsageSnooper.addData("singleplayer", Boolean.valueOf(this.isSinglePlayer()));
    1171            par1PlayerUsageSnooper.addData("server_brand", this.getServerModName());
    1172            par1PlayerUsageSnooper.addData("gui_supported", GraphicsEnvironment.isHeadless() ? "headless" : "supported");
    1173            par1PlayerUsageSnooper.addData("dedicated", Boolean.valueOf(this.isDedicatedServer()));
    1174        }
    1175
    1176        /**
    1177         * Returns whether snooping is enabled or not.
    1178         */
    1179        public boolean isSnooperEnabled()
    1180        {
    1181            return true;
    1182        }
    1183
    1184        /**
    1185         * This is checked to be 16 upon receiving the packet, otherwise the packet is ignored.
    1186         */
    1187        public int textureSize()
    1188        {
    1189            return 16;
    1190        }
    1191
    1192        public abstract boolean isDedicatedServer();
    1193
    1194        public boolean isServerInOnlineMode()
    1195        {
    1196            return this.onlineMode;
    1197        }
    1198
    1199        public void setOnlineMode(boolean par1)
    1200        {
    1201            this.onlineMode = par1;
    1202        }
    1203
    1204        public boolean getCanSpawnAnimals()
    1205        {
    1206            return this.canSpawnAnimals;
    1207        }
    1208
    1209        public void setCanSpawnAnimals(boolean par1)
    1210        {
    1211            this.canSpawnAnimals = par1;
    1212        }
    1213
    1214        public boolean getCanSpawnNPCs()
    1215        {
    1216            return this.canSpawnNPCs;
    1217        }
    1218
    1219        public void setCanSpawnNPCs(boolean par1)
    1220        {
    1221            this.canSpawnNPCs = par1;
    1222        }
    1223
    1224        public boolean isPVPEnabled()
    1225        {
    1226            return this.pvpEnabled;
    1227        }
    1228
    1229        public void setAllowPvp(boolean par1)
    1230        {
    1231            this.pvpEnabled = par1;
    1232        }
    1233
    1234        public boolean isFlightAllowed()
    1235        {
    1236            return this.allowFlight;
    1237        }
    1238
    1239        public void setAllowFlight(boolean par1)
    1240        {
    1241            this.allowFlight = par1;
    1242        }
    1243
    1244        public abstract boolean func_82356_Z();
    1245
    1246        public String getMOTD()
    1247        {
    1248            return this.motd;
    1249        }
    1250
    1251        public void setMOTD(String par1Str)
    1252        {
    1253            this.motd = par1Str;
    1254        }
    1255
    1256        public int getBuildLimit()
    1257        {
    1258            return this.buildLimit;
    1259        }
    1260
    1261        public void setBuildLimit(int par1)
    1262        {
    1263            this.buildLimit = par1;
    1264        }
    1265
    1266        public boolean isServerStopped()
    1267        {
    1268            return this.serverStopped;
    1269        }
    1270
    1271        public ServerConfigurationManager getConfigurationManager()
    1272        {
    1273            return this.serverConfigManager;
    1274        }
    1275
    1276        public void setConfigurationManager(ServerConfigurationManager par1ServerConfigurationManager)
    1277        {
    1278            this.serverConfigManager = par1ServerConfigurationManager;
    1279        }
    1280
    1281        /**
    1282         * Sets the game type for all worlds.
    1283         */
    1284        public void setGameType(EnumGameType par1EnumGameType)
    1285        {
    1286            for (int var2 = 0; var2 < this.worldServers.length; ++var2)
    1287            {
    1288                getServer().worldServers[var2].getWorldInfo().setGameType(par1EnumGameType);
    1289            }
    1290        }
    1291
    1292        public abstract NetworkListenThread getNetworkThread();
    1293
    1294        @SideOnly(Side.CLIENT)
    1295        public boolean serverIsInRunLoop()
    1296        {
    1297            return this.serverIsRunning;
    1298        }
    1299
    1300        public boolean getGuiEnabled()
    1301        {
    1302            return false;
    1303        }
    1304
    1305        /**
    1306         * On dedicated does nothing. On integrated, sets commandsAllowedForAll, gameType and allows external connections.
    1307         */
    1308        public abstract String shareToLAN(EnumGameType var1, boolean var2);
    1309
    1310        public int getTickCounter()
    1311        {
    1312            return this.tickCounter;
    1313        }
    1314
    1315        public void enableProfiling()
    1316        {
    1317            this.startProfiling = true;
    1318        }
    1319
    1320        @SideOnly(Side.CLIENT)
    1321        public PlayerUsageSnooper getPlayerUsageSnooper()
    1322        {
    1323            return this.usageSnooper;
    1324        }
    1325
    1326        public ChunkCoordinates func_82114_b()
    1327        {
    1328            return new ChunkCoordinates(0, 0, 0);
    1329        }
    1330
    1331        public int func_82357_ak()
    1332        {
    1333            return 16;
    1334        }
    1335
    1336        /**
    1337         * Gets the current player count, maximum player count, and player entity list.
    1338         */
    1339        public static ServerConfigurationManager getServerConfigurationManager(MinecraftServer par0MinecraftServer)
    1340        {
    1341            return par0MinecraftServer.serverConfigManager;
    1342        }
    1343
    1344        @SideOnly(Side.SERVER)
    1345        public static void main(String[] par0ArrayOfStr)
    1346        {
    1347            FMLRelauncher.handleServerRelaunch(new ArgsWrapper(par0ArrayOfStr));
    1348        }
    1349        @SideOnly(Side.SERVER)
    1350        public static void fmlReentry(ArgsWrapper wrap)
    1351        {
    1352            String[] par0ArrayOfStr = wrap.args;
    1353            StatList.func_75919_a();
    1354
    1355            try
    1356            {
    1357                boolean var1 = !GraphicsEnvironment.isHeadless();
    1358                String var2 = null;
    1359                String var3 = ".";
    1360                String var4 = null;
    1361                boolean var5 = false;
    1362                boolean var6 = false;
    1363                int var7 = -1;
    1364
    1365                for (int var8 = 0; var8 < par0ArrayOfStr.length; ++var8)
    1366                {
    1367                    String var9 = par0ArrayOfStr[var8];
    1368                    String var10 = var8 == par0ArrayOfStr.length - 1 ? null : par0ArrayOfStr[var8 + 1];
    1369                    boolean var11 = false;
    1370
    1371                    if (!var9.equals("nogui") && !var9.equals("--nogui"))
    1372                    {
    1373                        if (var9.equals("--port") && var10 != null)
    1374                        {
    1375                            var11 = true;
    1376
    1377                            try
    1378                            {
    1379                                var7 = Integer.parseInt(var10);
    1380                            }
    1381                            catch (NumberFormatException var13)
    1382                            {
    1383                                ;
    1384                            }
    1385                        }
    1386                        else if (var9.equals("--singleplayer") && var10 != null)
    1387                        {
    1388                            var11 = true;
    1389                            var2 = var10;
    1390                        }
    1391                        else if (var9.equals("--universe") && var10 != null)
    1392                        {
    1393                            var11 = true;
    1394                            var3 = var10;
    1395                        }
    1396                        else if (var9.equals("--world") && var10 != null)
    1397                        {
    1398                            var11 = true;
    1399                            var4 = var10;
    1400                        }
    1401                        else if (var9.equals("--demo"))
    1402                        {
    1403                            var5 = true;
    1404                        }
    1405                        else if (var9.equals("--bonusChest"))
    1406                        {
    1407                            var6 = true;
    1408                        }
    1409                    }
    1410                    else
    1411                    {
    1412                        var1 = false;
    1413                    }
    1414
    1415                    if (var11)
    1416                    {
    1417                        ++var8;
    1418                    }
    1419                }
    1420
    1421                DedicatedServer var15 = new DedicatedServer(new File(var3));
    1422
    1423                if (var2 != null)
    1424                {
    1425                    var15.setServerOwner(var2);
    1426                }
    1427
    1428                if (var4 != null)
    1429                {
    1430                    var15.setFolderName(var4);
    1431                }
    1432
    1433                if (var7 >= 0)
    1434                {
    1435                    var15.setServerPort(var7);
    1436                }
    1437
    1438                if (var5)
    1439                {
    1440                    var15.setDemo(true);
    1441                }
    1442
    1443                if (var6)
    1444                {
    1445                    var15.canCreateBonusChest(true);
    1446                }
    1447
    1448                if (var1)
    1449                {
    1450                    var15.func_82011_an();
    1451                }
    1452
    1453                var15.startServerThread();
    1454                Runtime.getRuntime().addShutdownHook(new ThreadDedicatedServer(var15));
    1455            }
    1456            catch (Exception var14)
    1457            {
    1458                logger.log(Level.SEVERE, "Failed to start the minecraft server", var14);
    1459            }
    1460        }
    1461    }