    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.io.File;
    006    import java.io.IOException;
    007
    008    import cpw.mods.fml.common.FMLCommonHandler;
    009    import net.minecraft.client.Minecraft;
    010    import net.minecraft.server.MinecraftServer;
    011    import net.minecraftforge.common.DimensionManager;
    012    import net.minecraftforge.common.MinecraftForge;
    013    import net.minecraftforge.event.world.WorldEvent;
    014
    015    @SideOnly(Side.CLIENT)
    016    public class IntegratedServer extends MinecraftServer
    017    {
    018        /** The Minecraft instance. */
    019        private final Minecraft mc;
    020        private final WorldSettings theWorldSettings;
    021
    022        /** Instance of IntegratedServerListenThread. */
    023        private IntegratedServerListenThread theServerListeningThread;
    024        private boolean field_71348_o = false;
    025        private boolean isPublic;
    026        private ThreadLanServerPing lanServerPing;
    027
    028        public IntegratedServer(Minecraft par1Minecraft, String par2Str, String par3Str, WorldSettings par4WorldSettings)
    029        {
    030            super(new File(Minecraft.getMinecraftDir(), "saves"));
    031            this.setServerOwner(par1Minecraft.session.username);
    032            this.setFolderName(par2Str);
    033            this.setWorldName(par3Str);
    034            this.setDemo(par1Minecraft.isDemo());
    035            this.canCreateBonusChest(par4WorldSettings.isBonusChestEnabled());
    036            this.setBuildLimit(256);
    037            this.setConfigurationManager(new IntegratedPlayerList(this));
    038            this.mc = par1Minecraft;
    039            this.theWorldSettings = par4WorldSettings;
    040
    041            try
    042            {
    043                this.theServerListeningThread = new IntegratedServerListenThread(this);
    044            }
    045            catch (IOException var6)
    046            {
    047                throw new Error();
    048            }
    049        }
    050
    051        protected void loadAllWorlds(String par1Str, String par2Str, long par3, WorldType par5WorldType, String par6Str)
    052        {
    053            this.convertMapIfNeeded(par1Str);
    054            ISaveHandler var7 = this.getActiveAnvilConverter().getSaveLoader(par1Str, true);
    055
    056            WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, var7, par2Str, 0, theProfiler) : new WorldServer(this, var7, par2Str, 0, theWorldSettings, theProfiler));
    057            for (int dim : DimensionManager.getStaticDimensionIDs())
    058            {
    059                WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, var7, par2Str, dim, theWorldSettings, overWorld, theProfiler));
    060                world.addWorldAccess(new WorldManager(this, world));
    061                if (!this.isSinglePlayer())
    062                {
    063                    world.getWorldInfo().setGameType(this.getGameType());
    064                }
    065
    066                MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
    067            }
    068
    069            this.getConfigurationManager().setPlayerManager(new WorldServer[]{ overWorld });
    070            this.setDifficultyForAllWorlds(this.getDifficulty());
    071            this.initialWorldChunkLoad();
    072        }
    073
    074        /**
    075         * Initialises the server and starts it.
    076         */
    077        protected boolean startServer() throws IOException
    078        {
    079            logger.info("Starting integrated minecraft server version 1.4");
    080            this.setOnlineMode(false);
    081            this.setCanSpawnAnimals(true);
    082            this.setCanSpawnNPCs(true);
    083            this.setAllowPvp(true);
    084            this.setAllowFlight(true);
    085            logger.info("Generating keypair");
    086            this.setKeyPair(CryptManager.createNewKeyPair());
    087            this.loadAllWorlds(this.getFolderName(), this.getWorldName(), this.theWorldSettings.getSeed(), this.theWorldSettings.getTerrainType(), this.theWorldSettings.func_82749_j());
    088            this.setMOTD(this.getServerOwner() + " - " + this.worldServers[0].getWorldInfo().getWorldName());
    089            FMLCommonHandler.instance().handleServerStarting(this);
    090            return true;
    091        }
    092
    093        /**
    094         * Main function called by run() every loop.
    095         */
    096        public void tick()
    097        {
    098            boolean var1 = this.field_71348_o;
    099            this.field_71348_o = this.theServerListeningThread.func_71752_f();
    100
    101            if (!var1 && this.field_71348_o)
    102            {
    103                logger.info("Saving and pausing game...");
    104                this.getConfigurationManager().saveAllPlayerData();
    105                this.saveAllWorlds(false);
    106            }
    107
    108            if (!this.field_71348_o)
    109            {
    110                super.tick();
    111            }
    112        }
    113
    114        public boolean canStructuresSpawn()
    115        {
    116            return false;
    117        }
    118
    119        public EnumGameType getGameType()
    120        {
    121            return this.theWorldSettings.getGameType();
    122        }
    123
    124        /**
    125         * Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on the client.
    126         */
    127        public int getDifficulty()
    128        {
    129            return this.mc.gameSettings.difficulty;
    130        }
    131
    132        /**
    133         * Defaults to false.
    134         */
    135        public boolean isHardcore()
    136        {
    137            return this.theWorldSettings.getHardcoreEnabled();
    138        }
    139
    140        protected File getDataDirectory()
    141        {
    142            return this.mc.mcDataDir;
    143        }
    144
    145        public boolean isDedicatedServer()
    146        {
    147            return false;
    148        }
    149
    150        /**
    151         * Gets the IntergratedServerListenThread.
    152         */
    153        public IntegratedServerListenThread getServerListeningThread()
    154        {
    155            return this.theServerListeningThread;
    156        }
    157
    158        /**
    159         * Called on exit from the main run() loop.
    160         */
    161        protected void finalTick(CrashReport par1CrashReport)
    162        {
    163            this.mc.crashed(par1CrashReport);
    164        }
    165
    166        /**
    167         * Adds the server info, including from theWorldServer, to the crash report.
    168         */
    169        public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport)
    170        {
    171            par1CrashReport = super.addServerInfoToCrashReport(par1CrashReport);
    172            par1CrashReport.addCrashSectionCallable("Type", new CallableType3(this));
    173            par1CrashReport.addCrashSectionCallable("Is Modded", new CallableIsModded(this));
    174            return par1CrashReport;
    175        }
    176
    177        public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper)
    178        {
    179            super.addServerStatsToSnooper(par1PlayerUsageSnooper);
    180            par1PlayerUsageSnooper.addData("snooper_partner", this.mc.getPlayerUsageSnooper().getUniqueID());
    181        }
    182
    183        /**
    184         * Returns whether snooping is enabled or not.
    185         */
    186        public boolean isSnooperEnabled()
    187        {
    188            return Minecraft.getMinecraft().isSnooperEnabled();
    189        }
    190
    191        /**
    192         * On dedicated does nothing. On integrated, sets commandsAllowedForAll, gameType and allows external connections.
    193         */
    194        public String shareToLAN(EnumGameType par1EnumGameType, boolean par2)
    195        {
    196            try
    197            {
    198                String var3 = this.theServerListeningThread.func_71755_c();
    199                System.out.println("Started on " + var3);
    200                this.isPublic = true;
    201                this.lanServerPing = new ThreadLanServerPing(this.getMOTD(), var3);
    202                this.lanServerPing.start();
    203                this.getConfigurationManager().setGameType(par1EnumGameType);
    204                this.getConfigurationManager().setCommandsAllowedForAll(par2);
    205                return var3;
    206            }
    207            catch (IOException var4)
    208            {
    209                return null;
    210            }
    211        }
    212
    213        /**
    214         * Saves all necessary data as preparation for stopping the server.
    215         */
    216        public void stopServer()
    217        {
    218            super.stopServer();
    219
    220            if (this.lanServerPing != null)
    221            {
    222                this.lanServerPing.interrupt();
    223                this.lanServerPing = null;
    224            }
    225        }
    226
    227        /**
    228         * Sets the serverRunning variable to false, in order to get the server to shut down.
    229         */
    230        public void initiateShutdown()
    231        {
    232            super.initiateShutdown();
    233
    234            if (this.lanServerPing != null)
    235            {
    236                this.lanServerPing.interrupt();
    237                this.lanServerPing = null;
    238            }
    239        }
    240
    241        /**
    242         * Returns true if this integrated server is open to LAN
    243         */
    244        public boolean getPublic()
    245        {
    246            return this.isPublic;
    247        }
    248
    249        /**
    250         * Sets the game type for all worlds.
    251         */
    252        public void setGameType(EnumGameType par1EnumGameType)
    253        {
    254            this.getConfigurationManager().setGameType(par1EnumGameType);
    255        }
    256
    257        public boolean func_82356_Z()
    258        {
    259            return true;
    260        }
    261
    262        public NetworkListenThread getNetworkThread()
    263        {
    264            return this.getServerListeningThread();
    265        }
    266    }