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