package net.minecraft.server.integrated; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Iterator; import java.util.Queue; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import net.minecraft.client.ClientBrandRetriever; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ThreadLanServerPing; import net.minecraft.crash.CrashReport; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.profiler.PlayerUsageSnooper; import net.minecraft.server.MinecraftServer; import net.minecraft.util.CryptManager; import net.minecraft.util.HttpUtil; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.WorldManager; import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServerMulti; import net.minecraft.world.WorldSettings; import net.minecraft.world.WorldType; import net.minecraft.world.demo.DemoWorldServer; import net.minecraft.world.storage.ISaveHandler; import net.minecraft.world.storage.WorldInfo; public class IntegratedServer extends MinecraftServer { private static final Logger logger = LogManager.getLogger(); /** The Minecraft instance. */ private final Minecraft mc; private final WorldSettings theWorldSettings; private boolean isGamePaused; private boolean isPublic; private ThreadLanServerPing lanServerPing; private static final String __OBFID = "CL_00001129"; public IntegratedServer(final Minecraft mcIn) { super(mcIn.getProxy(), new File(mcIn.mcDataDir, USER_CACHE_FILE.getName())); this.mc = mcIn; this.theWorldSettings = null; } public IntegratedServer(final Minecraft mcIn, final String p_i1317_2_, final String p_i1317_3_, final WorldSettings p_i1317_4_) { super(new File(mcIn.mcDataDir, "saves"), mcIn.getProxy(), new File(mcIn.mcDataDir, USER_CACHE_FILE.getName())); this.setServerOwner(mcIn.getSession().getUsername()); this.setFolderName(p_i1317_2_); this.setWorldName(p_i1317_3_); this.setDemo(mcIn.isDemo()); this.canCreateBonusChest(p_i1317_4_.isBonusChestEnabled()); this.setBuildLimit(256); this.setConfigManager(new IntegratedPlayerList(this)); this.mc = mcIn; this.theWorldSettings = this.isDemo() ? DemoWorldServer.demoWorldSettings : p_i1317_4_; } @Override protected void loadAllWorlds(final String p_71247_1_, final String p_71247_2_, final long seed, final WorldType type, final String p_71247_6_) { this.convertMapIfNeeded(p_71247_1_); this.worldServers = new WorldServer[3]; this.timeOfLastDimensionTick = new long[this.worldServers.length][100]; final ISaveHandler var7 = this.getActiveAnvilConverter().getSaveLoader(p_71247_1_, true); this.setResourcePackFromWorld(this.getFolderName(), var7); WorldInfo var8 = var7.loadWorldInfo(); if (var8 == null) var8 = new WorldInfo(this.theWorldSettings, p_71247_2_); else var8.setWorldName(p_71247_2_); for (int var9 = 0; var9 < this.worldServers.length; ++var9) { byte var10 = 0; if (var9 == 1) var10 = -1; if (var9 == 2) var10 = 1; if (var9 == 0) { if (this.isDemo()) this.worldServers[var9] = (WorldServer) (new DemoWorldServer(this, var7, var8, var10, this.theProfiler)).init(); else this.worldServers[var9] = (WorldServer) (new WorldServer(this, var7, var8, var10, this.theProfiler)).init(); this.worldServers[var9].initialize(this.theWorldSettings); } else this.worldServers[var9] = (WorldServer) (new WorldServerMulti(this, var7, var10, this.worldServers[0], this.theProfiler)).init(); this.worldServers[var9].addWorldAccess(new WorldManager(this, this.worldServers[var9])); } this.getConfigurationManager().setPlayerManager(this.worldServers); if (this.worldServers[0].getWorldInfo().getDifficulty() == null) this.setDifficultyForAllWorlds(this.mc.gameSettings.difficulty); this.initialWorldChunkLoad(); } /** * Initialises the server and starts it. */ @Override protected boolean startServer() throws IOException { logger.info("Starting integrated minecraft server version 1.8"); this.setOnlineMode(true); this.setCanSpawnAnimals(true); this.setCanSpawnNPCs(true); this.setAllowPvp(true); this.setAllowFlight(true); logger.info("Generating keypair"); this.setKeyPair(CryptManager.generateKeyPair()); this.loadAllWorlds(this.getFolderName(), this.getWorldName(), this.theWorldSettings.getSeed(), this.theWorldSettings.getTerrainType(), this.theWorldSettings.getWorldName()); this.setMOTD(this.getServerOwner() + " - " + this.worldServers[0].getWorldInfo().getWorldName()); return true; } /** * Main function called by run() every loop. */ @Override public void tick() { final boolean var1 = this.isGamePaused; this.isGamePaused = Minecraft.getMinecraft().getNetHandler() != null && Minecraft.getMinecraft().isGamePaused(); if (!var1 && this.isGamePaused) { logger.info("Saving and pausing game..."); this.getConfigurationManager().saveAllPlayerData(); this.saveAllWorlds(false); } if (this.isGamePaused) { final Queue var2 = this.futureTaskQueue; synchronized (this.futureTaskQueue) { while (!this.futureTaskQueue.isEmpty()) try { ((FutureTask) this.futureTaskQueue.poll()).run(); } catch (final Throwable var8) { logger.fatal(var8); } } } else { super.tick(); if (this.mc.gameSettings.renderDistanceChunks != this.getConfigurationManager().getViewDistance()) { logger.info("Changing view distance to {}, from {}", new Object[] { Integer.valueOf(this.mc.gameSettings.renderDistanceChunks), Integer.valueOf(this.getConfigurationManager().getViewDistance()) }); this.getConfigurationManager().setViewDistance(this.mc.gameSettings.renderDistanceChunks); } if (this.mc.theWorld != null) { final WorldInfo var10 = this.worldServers[0].getWorldInfo(); final WorldInfo var3 = this.mc.theWorld.getWorldInfo(); if (!var10.isDifficultyLocked() && var3.getDifficulty() != var10.getDifficulty()) { logger.info("Changing difficulty to {}, from {}", var3.getDifficulty(), var10.getDifficulty()); this.setDifficultyForAllWorlds(var3.getDifficulty()); } else if (var3.isDifficultyLocked() && !var10.isDifficultyLocked()) { logger.info("Locking difficulty to {}", var3.getDifficulty()); final WorldServer[] var4 = this.worldServers; final int var5 = var4.length; for (int var6 = 0; var6 < var5; ++var6) { final WorldServer var7 = var4[var6]; if (var7 != null) var7.getWorldInfo().setDifficultyLocked(true); } } } } } @Override public boolean canStructuresSpawn() { return false; } @Override public WorldSettings.GameType getGameType() { return this.theWorldSettings.getGameType(); } /** * Get the server's difficulty */ @Override public EnumDifficulty getDifficulty() { return this.mc.theWorld.getWorldInfo().getDifficulty(); } /** * Defaults to false. */ @Override public boolean isHardcore() { return this.theWorldSettings.getHardcoreEnabled(); } @Override public File getDataDirectory() { return this.mc.mcDataDir; } @Override public boolean isDedicatedServer() { return false; } /** * Called on exit from the main run() loop. */ @Override protected void finalTick(final CrashReport report) { this.mc.crashed(report); } /** * Adds the server info, including from theWorldServer, to the crash report. */ @Override public CrashReport addServerInfoToCrashReport(CrashReport report) { report = super.addServerInfoToCrashReport(report); report.getCategory().addCrashSectionCallable("Type", new Callable() { private static final String __OBFID = "CL_00001130"; @Override public String call() { return "Integrated Server (map_client.txt)"; } }); report.getCategory().addCrashSectionCallable("Is Modded", new Callable() { private static final String __OBFID = "CL_00001131"; @Override public String call() { String var1 = ClientBrandRetriever.getClientModName(); if (!var1.equals("vanilla")) return "Definitely; Client brand changed to \'" + var1 + "\'"; else { var1 = IntegratedServer.this.getServerModName(); return !var1.equals("vanilla") ? "Definitely; Server brand changed to \'" + var1 + "\'" : (Minecraft.class.getSigners() == null ? "Very likely; Jar signature invalidated" : "Probably not. Jar signature remains and both client + server brands are untouched."); } } }); return report; } @Override public void setDifficultyForAllWorlds(final EnumDifficulty difficulty) { super.setDifficultyForAllWorlds(difficulty); if (this.mc.theWorld != null) this.mc.theWorld.getWorldInfo().setDifficulty(difficulty); } @Override public void addServerStatsToSnooper(final PlayerUsageSnooper playerSnooper) { super.addServerStatsToSnooper(playerSnooper); playerSnooper.addClientStat("snooper_partner", this.mc.getPlayerUsageSnooper().getUniqueID()); } /** * Returns whether snooping is enabled or not. */ @Override public boolean isSnooperEnabled() { return Minecraft.getMinecraft().isSnooperEnabled(); } /** * On dedicated does nothing. On integrated, sets commandsAllowedForAll, gameType and allows external connections. */ @Override public String shareToLAN(final WorldSettings.GameType type, final boolean allowCheats) { try { int var3 = -1; try { var3 = HttpUtil.getSuitableLanPort(); } catch (final IOException var5) { ; } if (var3 <= 0) var3 = 25564; this.getNetworkSystem().addLanEndpoint((InetAddress) null, var3); logger.info("Started on " + var3); this.isPublic = true; this.lanServerPing = new ThreadLanServerPing(this.getMOTD(), var3 + ""); this.lanServerPing.start(); this.getConfigurationManager().func_152604_a(type); this.getConfigurationManager().setCommandsAllowedForAll(allowCheats); return var3 + ""; } catch (final IOException var6) { return null; } } /** * Saves all necessary data as preparation for stopping the server. */ @Override public void stopServer() { super.stopServer(); if (this.lanServerPing != null) { this.lanServerPing.interrupt(); this.lanServerPing = null; } } /** * Sets the serverRunning variable to false, in order to get the server to shut down. */ @Override public void initiateShutdown() { Futures.getUnchecked(this.addScheduledTask(new Runnable() { private static final String __OBFID = "CL_00002380"; @Override public void run() { final ArrayList var1 = Lists.newArrayList(IntegratedServer.this.getConfigurationManager().playerEntityList); final Iterator var2 = var1.iterator(); while (var2.hasNext()) { final EntityPlayerMP var3 = (EntityPlayerMP) var2.next(); IntegratedServer.this.getConfigurationManager().playerLoggedOut(var3); } } })); super.initiateShutdown(); if (this.lanServerPing != null) { this.lanServerPing.interrupt(); this.lanServerPing = null; } } public void func_175592_a() { this.func_175585_v(); } /** * Returns true if this integrated server is open to LAN */ public boolean getPublic() { return this.isPublic; } /** * Sets the game type for all worlds. */ @Override public void setGameType(final WorldSettings.GameType gameMode) { this.getConfigurationManager().func_152604_a(gameMode); } /** * Return whether command blocks are enabled. */ @Override public boolean isCommandBlockEnabled() { return true; } @Override public int getOpPermissionLevel() { return 4; } }