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