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