package net.minecraft.server.dedicated; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; import net.minecraft.command.ICommandSender; import net.minecraft.command.ServerCommand; import net.minecraft.crash.CrashReport; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.logging.ILogAgent; import net.minecraft.logging.LogAgent; import net.minecraft.network.NetworkListenThread; import net.minecraft.network.rcon.IServer; import net.minecraft.network.rcon.RConThreadMain; import net.minecraft.network.rcon.RConThreadQuery; import net.minecraft.profiler.PlayerUsageSnooper; import net.minecraft.server.MinecraftServer; import net.minecraft.server.gui.ServerGUI; import net.minecraft.server.management.ServerConfigurationManager; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.CryptManager; import net.minecraft.util.MathHelper; import net.minecraft.world.EnumGameType; import net.minecraft.world.World; import net.minecraft.world.WorldSettings; import net.minecraft.world.WorldType; public class DedicatedServer extends MinecraftServer implements IServer { private final List pendingCommandList = Collections.synchronizedList(new ArrayList()); private final ILogAgent field_98131_l; private RConThreadQuery theRConThreadQuery; private RConThreadMain theRConThreadMain; private PropertyManager settings; private boolean canSpawnStructures; private EnumGameType gameType; private NetworkListenThread networkThread; private boolean guiIsEnabled = false; public DedicatedServer(File par1File) { super(par1File); this.field_98131_l = new LogAgent("Minecraft-Server", (String)null, (new File(par1File, "server.log")).getAbsolutePath()); new DedicatedServerSleepThread(this); } /** * Initialises the server and starts it. */ protected boolean startServer() throws IOException { DedicatedServerCommandThread dedicatedservercommandthread = new DedicatedServerCommandThread(this); dedicatedservercommandthread.setDaemon(true); dedicatedservercommandthread.start(); this.getLogAgent().logInfo("Starting minecraft server version 1.5.2"); if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { this.getLogAgent().logWarning("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } FMLCommonHandler.instance().onServerStart(this); this.getLogAgent().logInfo("Loading properties"); this.settings = new PropertyManager(new File("server.properties"), this.getLogAgent()); if (this.isSinglePlayer()) { this.setHostname("127.0.0.1"); } else { this.setOnlineMode(this.settings.getBooleanProperty("online-mode", true)); this.setHostname(this.settings.getProperty("server-ip", "")); } this.setCanSpawnAnimals(this.settings.getBooleanProperty("spawn-animals", true)); this.setCanSpawnNPCs(this.settings.getBooleanProperty("spawn-npcs", true)); this.setAllowPvp(this.settings.getBooleanProperty("pvp", true)); this.setAllowFlight(this.settings.getBooleanProperty("allow-flight", false)); this.setTexturePack(this.settings.getProperty("texture-pack", "")); this.setMOTD(this.settings.getProperty("motd", "A Minecraft Server")); this.func_104055_i(this.settings.getBooleanProperty("force-gamemode", false)); if (this.settings.getIntProperty("difficulty", 1) < 0) { this.settings.setProperty("difficulty", Integer.valueOf(0)); } else if (this.settings.getIntProperty("difficulty", 1) > 3) { this.settings.setProperty("difficulty", Integer.valueOf(3)); } this.canSpawnStructures = this.settings.getBooleanProperty("generate-structures", true); int i = this.settings.getIntProperty("gamemode", EnumGameType.SURVIVAL.getID()); this.gameType = WorldSettings.getGameTypeById(i); this.getLogAgent().logInfo("Default game type: " + this.gameType); InetAddress inetaddress = null; if (this.getServerHostname().length() > 0) { inetaddress = InetAddress.getByName(this.getServerHostname()); } if (this.getServerPort() < 0) { this.setServerPort(this.settings.getIntProperty("server-port", 25565)); } this.getLogAgent().logInfo("Generating keypair"); this.setKeyPair(CryptManager.createNewKeyPair()); this.getLogAgent().logInfo("Starting Minecraft server on " + (this.getServerHostname().length() == 0 ? "*" : this.getServerHostname()) + ":" + this.getServerPort()); try { this.networkThread = new DedicatedServerListenThread(this, inetaddress, this.getServerPort()); } catch (IOException ioexception) { this.getLogAgent().logWarning("**** FAILED TO BIND TO PORT!"); this.getLogAgent().logWarningFormatted("The exception was: {0}", new Object[] {ioexception.toString()}); this.getLogAgent().logWarning("Perhaps a server is already running on that port?"); return false; } if (!this.isServerInOnlineMode()) { this.getLogAgent().logWarning("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); this.getLogAgent().logWarning("The server will make no attempt to authenticate usernames. Beware."); this.getLogAgent().logWarning("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); this.getLogAgent().logWarning("To change this, set \"online-mode\" to \"true\" in the server.properties file."); } FMLCommonHandler.instance().onServerStarted(); this.setConfigurationManager(new DedicatedPlayerList(this)); long j = System.nanoTime(); if (this.getFolderName() == null) { this.setFolderName(this.settings.getProperty("level-name", "world")); } String s = this.settings.getProperty("level-seed", ""); String s1 = this.settings.getProperty("level-type", "DEFAULT"); String s2 = this.settings.getProperty("generator-settings", ""); long k = (new Random()).nextLong(); if (s.length() > 0) { try { long l = Long.parseLong(s); if (l != 0L) { k = l; } } catch (NumberFormatException numberformatexception) { k = (long)s.hashCode(); } } WorldType worldtype = WorldType.parseWorldType(s1); if (worldtype == null) { worldtype = WorldType.DEFAULT; } this.setBuildLimit(this.settings.getIntProperty("max-build-height", 256)); this.setBuildLimit((this.getBuildLimit() + 8) / 16 * 16); this.setBuildLimit(MathHelper.clamp_int(this.getBuildLimit(), 64, 256)); this.settings.setProperty("max-build-height", Integer.valueOf(this.getBuildLimit())); if (!FMLCommonHandler.instance().handleServerAboutToStart(this)) { return false; } this.getLogAgent().logInfo("Preparing level \"" + this.getFolderName() + "\""); this.loadAllWorlds(this.getFolderName(), this.getFolderName(), k, worldtype, s2); long i1 = System.nanoTime() - j; String s3 = String.format("%.3fs", new Object[] {Double.valueOf((double)i1 / 1.0E9D)}); this.getLogAgent().logInfo("Done (" + s3 + ")! For help, type \"help\" or \"?\""); if (this.settings.getBooleanProperty("enable-query", false)) { this.getLogAgent().logInfo("Starting GS4 status listener"); this.theRConThreadQuery = new RConThreadQuery(this); this.theRConThreadQuery.startThread(); } if (this.settings.getBooleanProperty("enable-rcon", false)) { this.getLogAgent().logInfo("Starting remote control listener"); this.theRConThreadMain = new RConThreadMain(this); this.theRConThreadMain.startThread(); } return FMLCommonHandler.instance().handleServerStarting(this); } public boolean canStructuresSpawn() { return this.canSpawnStructures; } public EnumGameType getGameType() { return this.gameType; } /** * Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on the client. */ public int getDifficulty() { return this.settings.getIntProperty("difficulty", 1); } /** * Defaults to false. */ public boolean isHardcore() { return this.settings.getBooleanProperty("hardcore", false); } /** * Called on exit from the main run() loop. */ protected void finalTick(CrashReport par1CrashReport) { while (this.isServerRunning()) { this.executePendingCommands(); try { Thread.sleep(10L); } catch (InterruptedException interruptedexception) { interruptedexception.printStackTrace(); } } } /** * Adds the server info, including from theWorldServer, to the crash report. */ public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport) { par1CrashReport = super.addServerInfoToCrashReport(par1CrashReport); par1CrashReport.func_85056_g().addCrashSectionCallable("Is Modded", new CallableType(this)); par1CrashReport.func_85056_g().addCrashSectionCallable("Type", new CallableServerType(this)); return par1CrashReport; } /** * Directly calls System.exit(0), instantly killing the program. */ protected void systemExitNow() { System.exit(0); } public void updateTimeLightAndEntities() { super.updateTimeLightAndEntities(); this.executePendingCommands(); } public boolean getAllowNether() { return this.settings.getBooleanProperty("allow-nether", true); } public boolean allowSpawnMonsters() { return this.settings.getBooleanProperty("spawn-monsters", true); } public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper) { par1PlayerUsageSnooper.addData("whitelist_enabled", Boolean.valueOf(this.getDedicatedPlayerList().isWhiteListEnabled())); par1PlayerUsageSnooper.addData("whitelist_count", Integer.valueOf(this.getDedicatedPlayerList().getWhiteListedPlayers().size())); super.addServerStatsToSnooper(par1PlayerUsageSnooper); } /** * Returns whether snooping is enabled or not. */ public boolean isSnooperEnabled() { return this.settings.getBooleanProperty("snooper-enabled", true); } public void addPendingCommand(String par1Str, ICommandSender par2ICommandSender) { this.pendingCommandList.add(new ServerCommand(par1Str, par2ICommandSender)); } public void executePendingCommands() { while (!this.pendingCommandList.isEmpty()) { ServerCommand servercommand = (ServerCommand)this.pendingCommandList.remove(0); this.getCommandManager().executeCommand(servercommand.sender, servercommand.command); } } public boolean isDedicatedServer() { return true; } public DedicatedPlayerList getDedicatedPlayerList() { return (DedicatedPlayerList)super.getConfigurationManager(); } public NetworkListenThread getNetworkThread() { return this.networkThread; } /** * Gets an integer property. If it does not exist, set it to the specified value. */ public int getIntProperty(String par1Str, int par2) { return this.settings.getIntProperty(par1Str, par2); } /** * Gets a string property. If it does not exist, set it to the specified value. */ public String getStringProperty(String par1Str, String par2Str) { return this.settings.getProperty(par1Str, par2Str); } /** * Gets a boolean property. If it does not exist, set it to the specified value. */ public boolean getBooleanProperty(String par1Str, boolean par2) { return this.settings.getBooleanProperty(par1Str, par2); } /** * Saves an Object with the given property name. */ public void setProperty(String par1Str, Object par2Obj) { this.settings.setProperty(par1Str, par2Obj); } /** * Saves all of the server properties to the properties file. */ public void saveProperties() { this.settings.saveProperties(); } /** * Returns the filename where server properties are stored */ public String getSettingsFilename() { File file1 = this.settings.getPropertiesFile(); return file1 != null ? file1.getAbsolutePath() : "No settings file"; } public boolean getGuiEnabled() { return this.guiIsEnabled; } /** * On dedicated does nothing. On integrated, sets commandsAllowedForAll, gameType and allows external connections. */ public String shareToLAN(EnumGameType par1EnumGameType, boolean par2) { return ""; } /** * Return whether command blocks are enabled. */ public boolean isCommandBlockEnabled() { return this.settings.getBooleanProperty("enable-command-block", false); } /** * Return the spawn protection area's size. */ public int getSpawnProtectionSize() { return this.settings.getIntProperty("spawn-protection", super.getSpawnProtectionSize()); } public boolean func_96290_a(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { if (par1World.provider.dimensionId != 0) { return false; } else if (this.getDedicatedPlayerList().getOps().isEmpty()) { return false; } else if (this.getDedicatedPlayerList().areCommandsAllowed(par5EntityPlayer.username)) { return false; } else if (this.getSpawnProtectionSize() <= 0) { return false; } else { ChunkCoordinates chunkcoordinates = par1World.getSpawnPoint(); int l = MathHelper.abs_int(par2 - chunkcoordinates.posX); int i1 = MathHelper.abs_int(par4 - chunkcoordinates.posZ); int j1 = Math.max(l, i1); return j1 <= this.getSpawnProtectionSize(); } } public ILogAgent getLogAgent() { return this.field_98131_l; } public ServerConfigurationManager getConfigurationManager() { return this.getDedicatedPlayerList(); } @SideOnly(Side.SERVER) public void enableGui() { ServerGUI.initGUI(this); this.guiIsEnabled = true; } }