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