diff options
author | Thinkofdeath <thinkofdeath@spigotmc.org> | 2014-11-26 08:32:16 +1100 |
---|---|---|
committer | md_5 <git@md-5.net> | 2014-11-28 17:16:30 +1100 |
commit | 24557bc2b37deb6a0edf497d547471832457b1dd (patch) | |
tree | c560572889a3b0b34964a0cddb35dc87fda3c914 /nms-patches/MinecraftServer.patch | |
parent | a4805dbd77da057cc1ea0bf344379bc6e53ca1f6 (diff) | |
download | craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.gz craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.lz craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.xz craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.zip |
Update to Minecraft 1.8
For more information please see http://www.spigotmc.org/
Diffstat (limited to 'nms-patches/MinecraftServer.patch')
-rw-r--r-- | nms-patches/MinecraftServer.patch | 726 |
1 files changed, 726 insertions, 0 deletions
diff --git a/nms-patches/MinecraftServer.patch b/nms-patches/MinecraftServer.patch new file mode 100644 index 00000000..22d7748f --- /dev/null +++ b/nms-patches/MinecraftServer.patch @@ -0,0 +1,726 @@ +--- ../work/decompile-bb26c12b/net/minecraft/server/MinecraftServer.java 2014-11-27 08:59:46.801421406 +1100 ++++ src/main/java/net/minecraft/server/MinecraftServer.java 2014-11-27 08:42:10.092851027 +1100 +@@ -37,6 +37,18 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.io.IOException; ++ ++import jline.console.ConsoleReader; ++import joptsimple.OptionSet; ++ ++import org.bukkit.craftbukkit.Main; ++import org.bukkit.World.Environment; ++import org.bukkit.craftbukkit.util.Waitable; ++import org.bukkit.event.server.RemoteServerCommandEvent; ++import org.bukkit.event.world.WorldSaveEvent; ++// CraftBukkit end + public abstract class MinecraftServer implements ICommandListener, Runnable, IAsyncTaskHandler, IMojangStatistics { + + private static final Logger LOGGER = LogManager.getLogger(); +@@ -93,24 +105,66 @@ + private Thread serverThread; + private long ab = ax(); + +- public MinecraftServer(File file, Proxy proxy, File file1) { ++ // CraftBukkit start ++ public List<WorldServer> worlds = new ArrayList<WorldServer>(); ++ public org.bukkit.craftbukkit.CraftServer server; ++ public OptionSet options; ++ public org.bukkit.command.ConsoleCommandSender console; ++ public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; ++ public ConsoleReader reader; ++ public static int currentTick = (int) (System.currentTimeMillis() / 50); ++ public final Thread primaryThread; ++ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>(); ++ public int autosavePeriod; ++ // CraftBukkit end ++ ++ public MinecraftServer(OptionSet options, Proxy proxy, File file1) { + this.d = proxy; + MinecraftServer.k = this; +- this.universe = file; ++ // this.universe = file; // CraftBukkit + this.q = new ServerConnection(this); + this.Z = new UserCache(this, file1); + this.p = this.h(); +- this.convertable = new WorldLoaderServer(file); ++ // this.convertable = new WorldLoaderServer(file); // CraftBukkit - moved to DedicatedServer.init + this.V = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString()); + this.W = this.V.createMinecraftSessionService(); + this.Y = this.V.createProfileRepository(); ++ // CraftBukkit start ++ this.options = options; ++ // Try to see if we're actually running in a terminal, disable jline if not ++ if (System.console() == null) { ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ Main.useJline = false; ++ } ++ ++ try { ++ reader = new ConsoleReader(System.in, System.out); ++ reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators ++ } catch (Throwable e) { ++ try { ++ // Try again with jline disabled for Windows users without C++ 2008 Redistributable ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ System.setProperty("user.language", "en"); ++ Main.useJline = false; ++ reader = new ConsoleReader(System.in, System.out); ++ reader.setExpandEvents(false); ++ } catch (IOException ex) { ++ LOGGER.warn((String) null, ex); ++ } ++ } ++ Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); ++ ++ this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main + } + ++ public abstract PropertyManager getPropertyManager(); ++ // CraftBukkit end ++ + protected CommandDispatcher h() { + return new CommandDispatcher(); + } + +- protected abstract boolean init(); ++ protected abstract boolean init() throws java.net.UnknownHostException; // CraftBukkit - throws UnknownHostException + + protected void a(String s) { + if (this.getConvertable().isConvertable(s)) { +@@ -129,6 +183,7 @@ + this.a(s); + this.b("menu.loadingLevel"); + this.worldServer = new WorldServer[3]; ++ /* CraftBukkit start - Remove ticktime arrays and worldsettings + this.h = new long[this.worldServer.length][100]; + IDataManager idatamanager = this.convertable.a(s, true); + +@@ -152,37 +207,110 @@ + worlddata.a(s1); + worldsettings = new WorldSettings(worlddata); + } ++ */ ++ int worldCount = 3; + +- for (int j = 0; j < this.worldServer.length; ++j) { +- byte b0 = 0; ++ for (int j = 0; j < worldCount; ++j) { ++ WorldServer world; ++ byte dimension = 0; + + if (j == 1) { +- b0 = -1; ++ if (getAllowNether()) { ++ dimension = -1; ++ } else { ++ continue; ++ } + } + + if (j == 2) { +- b0 = 1; ++ if (server.getAllowEnd()) { ++ dimension = 1; ++ } else { ++ continue; ++ } + } + ++ String worldType = org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(); ++ String name = (dimension == 0) ? s : s + "_" + worldType; ++ ++ org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name); ++ WorldSettings worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); ++ worldsettings.setGeneratorSettings(s2); ++ + if (j == 0) { ++ IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), s1, true); ++ WorldData worlddata = idatamanager.getWorldData(); ++ if (worlddata == null) { ++ worlddata = new WorldData(worldsettings, s1); ++ } + if (this.W()) { +- this.worldServer[j] = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, b0, this.methodProfiler)).b(); ++ world = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler)).b(); + } else { +- this.worldServer[j] = (WorldServer) (new WorldServer(this, idatamanager, worlddata, b0, this.methodProfiler)).b(); ++ world = (WorldServer) (new WorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler, org.bukkit.World.Environment.getEnvironment(dimension), gen)).b(); + } + +- this.worldServer[j].a(worldsettings); ++ world.a(worldsettings); ++ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard()); + } else { +- this.worldServer[j] = (WorldServer) (new SecondaryWorldServer(this, idatamanager, b0, this.worldServer[0], this.methodProfiler)).b(); ++ String dim = "DIM" + dimension; ++ ++ File newWorld = new File(new File(name), dim); ++ File oldWorld = new File(new File(s), dim); ++ ++ if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) { ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----"); ++ MinecraftServer.LOGGER.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly."); ++ MinecraftServer.LOGGER.info("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future."); ++ MinecraftServer.LOGGER.info("Attempting to move " + oldWorld + " to " + newWorld + "..."); ++ ++ if (newWorld.exists()) { ++ MinecraftServer.LOGGER.warn("A file or folder already exists at " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } else if (newWorld.getParentFile().mkdirs()) { ++ if (oldWorld.renameTo(newWorld)) { ++ MinecraftServer.LOGGER.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld); ++ // Migrate world data too. ++ try { ++ com.google.common.io.Files.copy(new File(new File(s), "level.dat"), new File(new File(name), "level.dat")); ++ } catch (IOException exception) { ++ MinecraftServer.LOGGER.warn("Unable to migrate world data."); ++ } ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder complete ----"); ++ } else { ++ MinecraftServer.LOGGER.warn("Could not move folder " + oldWorld + " to " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } ++ } else { ++ MinecraftServer.LOGGER.warn("Could not create path for " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } ++ } ++ ++ IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, true); ++ // world =, b0 to dimension, s1 to name, added Environment and gen ++ WorldData worlddata = idatamanager.getWorldData(); ++ if (worlddata == null) { ++ worlddata = new WorldData(worldsettings, name); ++ } ++ world = (WorldServer) new SecondaryWorldServer(this, idatamanager, dimension, this.worlds.get(0), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).b(); + } + +- this.worldServer[j].addIWorldAccess(new WorldManager(this, this.worldServer[j])); ++ if (gen != null) { ++ world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld())); ++ } ++ ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld())); ++ ++ world.addIWorldAccess(new WorldManager(this, world)); + if (!this.S()) { +- this.worldServer[j].getWorldData().setGameType(this.getGamemode()); ++ world.getWorldData().setGameType(this.getGamemode()); + } ++ ++ worlds.add(world); ++ getPlayerList().setPlayerFileData(worlds.toArray(new WorldServer[worlds.size()])); + } + +- this.v.setPlayerFileData(this.worldServer); ++ // CraftBukkit end + this.a(this.getDifficulty()); + this.k(); + } +@@ -197,25 +325,38 @@ + this.b("menu.generatingTerrain"); + byte b0 = 0; + +- MinecraftServer.LOGGER.info("Preparing start region for level " + b0); +- WorldServer worldserver = this.worldServer[b0]; +- BlockPosition blockposition = worldserver.getSpawn(); +- long j = ax(); +- +- for (int k = -192; k <= 192 && this.isRunning(); k += 16) { +- for (int l = -192; l <= 192 && this.isRunning(); l += 16) { +- long i1 = ax(); +- +- if (i1 - j > 1000L) { +- this.a_("Preparing spawn area", i * 100 / 625); +- j = i1; +- } ++ // CraftBukkit start - fire WorldLoadEvent and handle whether or not to keep the spawn in memory ++ for (int m = 0; m < worlds.size(); m++) { ++ WorldServer worldserver = this.worlds.get(m); ++ LOGGER.info("Preparing start region for level " + m + " (Seed: " + worldserver.getSeed() + ")"); ++ ++ if (!worldserver.getWorld().getKeepSpawnInMemory()) { ++ continue; ++ } ++ ++ BlockPosition blockposition = worldserver.getSpawn(); ++ long j = ax(); ++ i = 0; ++ ++ for (int k = -192; k <= 192 && this.isRunning(); k += 16) { ++ for (int l = -192; l <= 192 && this.isRunning(); l += 16) { ++ long i1 = ax(); ++ ++ if (i1 - j > 1000L) { ++ this.a_("Preparing spawn area", i * 100 / 625); ++ j = i1; ++ } + +- ++i; +- worldserver.chunkProviderServer.getChunkAt(blockposition.getX() + k >> 4, blockposition.getZ() + l >> 4); ++ ++i; ++ worldserver.chunkProviderServer.getChunkAt(blockposition.getX() + k >> 4, blockposition.getZ() + l >> 4); ++ } + } + } + ++ for (WorldServer world : this.worlds) { ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld())); ++ } ++ // CraftBukkit end + this.q(); + } + +@@ -247,35 +388,42 @@ + protected void q() { + this.e = null; + this.f = 0; ++ ++ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit + } + +- protected void saveChunks(boolean flag) { ++ protected void saveChunks(boolean flag) throws ExceptionWorldConflict { // CraftBukkit - added throws + if (!this.N) { +- WorldServer[] aworldserver = this.worldServer; +- int i = aworldserver.length; +- +- for (int j = 0; j < i; ++j) { +- WorldServer worldserver = aworldserver[j]; + ++ // CraftBukkit start ++ for (int j = 0; j < worlds.size(); ++j) { ++ WorldServer worldserver = worlds.get(j); ++ // CraftBukkit end + if (worldserver != null) { + if (!flag) { + MinecraftServer.LOGGER.info("Saving chunks for level \'" + worldserver.getWorldData().getName() + "\'/" + worldserver.worldProvider.getName()); + } + +- try { +- worldserver.save(true, (IProgressUpdate) null); +- } catch (ExceptionWorldConflict exceptionworldconflict) { +- MinecraftServer.LOGGER.warn(exceptionworldconflict.getMessage()); +- } ++ worldserver.save(true, (IProgressUpdate) null); ++ worldserver.saveLevel(); ++ ++ WorldSaveEvent event = new WorldSaveEvent(worldserver.getWorld()); ++ this.server.getPluginManager().callEvent(event); ++ // CraftBukkit end + } + } + + } + } + +- public void stop() { ++ public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws + if (!this.N) { + MinecraftServer.LOGGER.info("Stopping server"); ++ // CraftBukkit start ++ if (this.server != null) { ++ this.server.disablePlugins(); ++ } ++ // CraftBukkit end + if (this.ao() != null) { + this.ao().b(); + } +@@ -290,11 +438,13 @@ + MinecraftServer.LOGGER.info("Saving worlds"); + this.saveChunks(false); + ++ /* CraftBukkit start - Handled in saveChunks + for (int i = 0; i < this.worldServer.length; ++i) { + WorldServer worldserver = this.worldServer[i]; + + worldserver.saveLevel(); + } ++ // CraftBukkit end */ + } + + if (this.m.d()) { +@@ -335,6 +485,7 @@ + long k = j - this.ab; + + if (k > 2000L && this.ab - this.R >= 15000L) { ++ if (server.getWarnOnOverload()) // CraftBukkit + MinecraftServer.LOGGER.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] { Long.valueOf(k), Long.valueOf(k / 50L)}); + k = 2000L; + this.R = this.ab; +@@ -347,11 +498,12 @@ + + i += k; + this.ab = j; +- if (this.worldServer[0].everyoneDeeplySleeping()) { ++ if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit + this.y(); + i = 0L; + } else { + while (i > 50L) { ++ MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit + i -= 50L; + this.y(); + } +@@ -389,6 +541,12 @@ + } catch (Throwable throwable1) { + MinecraftServer.LOGGER.error("Exception stopping the server", throwable1); + } finally { ++ // CraftBukkit start - Restore terminal to original settings ++ try { ++ reader.getTerminal().restore(); ++ } catch (Exception ignored) { ++ } ++ // CraftBukkit end + this.x(); + } + +@@ -428,7 +586,7 @@ + + protected void x() {} + +- protected void y() { ++ protected void y() throws ExceptionWorldConflict { // CraftBukkit - added throws + long i = System.nanoTime(); + + ++this.ticks; +@@ -454,7 +612,7 @@ + this.r.b().a(agameprofile); + } + +- if (this.ticks % 900 == 0) { ++ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit + this.methodProfiler.a("save"); + this.v.savePlayers(); + this.saveChunks(true); +@@ -493,20 +651,40 @@ + + this.methodProfiler.c("levels"); + ++ // CraftBukkit start ++ this.server.getScheduler().mainThreadHeartbeat(this.ticks); ++ ++ // Run tasks that are waiting on processing ++ while (!processQueue.isEmpty()) { ++ processQueue.remove().run(); ++ } ++ ++ org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick(); ++ ++ // Send time updates to everyone, it will get the right time from the world the player is in. ++ if (this.ticks % 20 == 0) { ++ for (int i = 0; i < this.getPlayerList().players.size(); ++i) { ++ EntityPlayer entityplayer = (EntityPlayer) this.getPlayerList().players.get(i); ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time ++ } ++ } ++ + int i; + +- for (i = 0; i < this.worldServer.length; ++i) { ++ for (i = 0; i < this.worlds.size(); ++i) { + long j = System.nanoTime(); + +- if (i == 0 || this.getAllowNether()) { +- WorldServer worldserver = this.worldServer[i]; ++ // if (i == 0 || this.getAllowNether()) { ++ WorldServer worldserver = this.worlds.get(i); + + this.methodProfiler.a(worldserver.getWorldData().getName()); ++ /* Drop global time updates + if (this.ticks % 20 == 0) { + this.methodProfiler.a("timeSync"); + this.v.a(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.worldProvider.getDimension()); + this.methodProfiler.b(); + } ++ // CraftBukkit end */ + + this.methodProfiler.a("tick"); + +@@ -533,9 +711,9 @@ + worldserver.getTracker().updatePlayers(); + this.methodProfiler.b(); + this.methodProfiler.b(); +- } ++ // } // CraftBukkit + +- this.h[i][this.ticks % 100] = System.nanoTime() - j; ++ // this.h[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit + } + + this.methodProfiler.c("connection"); +@@ -559,10 +737,11 @@ + this.o.add(iupdateplayerlistbox); + } + +- public static void main(String[] astring) { ++ public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring) + DispenserRegistry.c(); + + try { ++ /* CraftBukkit start - Replace everything + boolean flag = true; + String s = null; + String s1 = "."; +@@ -636,6 +815,29 @@ + + dedicatedserver.B(); + Runtime.getRuntime().addShutdownHook(new ThreadShutdown("Server Shutdown Thread", dedicatedserver)); ++ */ ++ ++ DedicatedServer dedicatedserver = new DedicatedServer(options); ++ ++ if (options.has("port")) { ++ int port = (Integer) options.valueOf("port"); ++ if (port > 0) { ++ dedicatedserver.setPort(port); ++ } ++ } ++ ++ if (options.has("universe")) { ++ dedicatedserver.universe = (File) options.valueOf("universe"); ++ } else { ++ dedicatedserver.universe = new File("."); ++ } ++ ++ if (options.has("world")) { ++ dedicatedserver.setWorld((String) options.valueOf("world")); ++ } ++ ++ dedicatedserver.primaryThread.start(); ++ // CraftBukkit end + } catch (Exception exception) { + MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception); + } +@@ -643,8 +845,10 @@ + } + + public void B() { ++ /* CraftBukkit start - prevent abuse + this.serverThread = new Thread(this, "Server thread"); + this.serverThread.start(); ++ // CraftBukkit end */ + } + + public File d(String s) { +@@ -660,7 +864,14 @@ + } + + public WorldServer getWorldServer(int i) { +- return i == -1 ? this.worldServer[1] : (i == 1 ? this.worldServer[2] : this.worldServer[0]); ++ // CraftBukkit start ++ for (WorldServer world : worlds) { ++ if (world.dimension == i) { ++ return world; ++ } ++ } ++ return worlds.get(0); ++ // CraftBukkit end + } + + public String C() { +@@ -696,17 +907,62 @@ + } + + public String getPlugins() { +- return ""; +- } ++ // CraftBukkit start - Whole method ++ StringBuilder result = new StringBuilder(); ++ org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); ++ ++ result.append(server.getName()); ++ result.append(" on Bukkit "); ++ result.append(server.getBukkitVersion()); ++ ++ if (plugins.length > 0 && server.getQueryPlugins()) { ++ result.append(": "); ++ ++ for (int i = 0; i < plugins.length; i++) { ++ if (i > 0) { ++ result.append("; "); ++ } + +- public String executeRemoteCommand(String s) { +- RemoteControlCommandListener.getInstance().i(); +- this.p.a(RemoteControlCommandListener.getInstance(), s); +- return RemoteControlCommandListener.getInstance().j(); ++ result.append(plugins[i].getDescription().getName()); ++ result.append(" "); ++ result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); ++ } ++ } ++ ++ return result.toString(); ++ // CraftBukkit end ++ } ++ ++ // CraftBukkit start - fire RemoteServerCommandEvent ++ public String executeRemoteCommand(final String s) { ++ Waitable<String> waitable = new Waitable<String>() { ++ @Override ++ protected String evaluate() { ++ RemoteControlCommandListener.getInstance().i(); ++ // Event changes start ++ RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); ++ server.getPluginManager().callEvent(event); ++ // Event change end ++ ServerCommand serverCommand = new ServerCommand(event.getCommand(), RemoteControlCommandListener.getInstance()); ++ server.dispatchServerCommand(remoteConsole, serverCommand); ++ // this.p.a(RemoteControlCommandListener.getInstance(), s); ++ return RemoteControlCommandListener.getInstance().j(); ++ } ++ }; ++ processQueue.add(waitable); ++ try { ++ return waitable.get(); ++ } catch (java.util.concurrent.ExecutionException e) { ++ throw new RuntimeException("Exception processing rcon command " + s, e.getCause()); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); // Maintain interrupted state ++ throw new RuntimeException("Interrupted processing rcon command " + s, e); ++ } ++ // CraftBukkit end + } + + public boolean isDebugging() { +- return false; ++ return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode + } + + public void h(String s) { +@@ -721,7 +977,7 @@ + } + + public String getServerModName() { +- return "vanilla"; ++ return server.getName(); // CraftBukkit - cb > vanilla! + } + + public CrashReport b(CrashReport crashreport) { +@@ -734,6 +990,7 @@ + } + + public List tabCompleteCommand(ICommandListener icommandlistener, String s, BlockPosition blockposition) { ++ /* CraftBukkit start - Allow tab-completion of Bukkit commands + ArrayList arraylist = Lists.newArrayList(); + + if (s.startsWith("/")) { +@@ -772,6 +1029,9 @@ + + return arraylist; + } ++ */ ++ return server.tabComplete(icommandlistener, s); ++ // CraftBukkit end + } + + public static MinecraftServer getServer() { +@@ -835,8 +1095,10 @@ + } + + public void a(EnumDifficulty enumdifficulty) { +- for (int i = 0; i < this.worldServer.length; ++i) { +- WorldServer worldserver = this.worldServer[i]; ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ WorldServer worldserver = this.worlds.get(i); ++ // CraftBukkit end + + if (worldserver != null) { + if (worldserver.getWorldData().isHardcore()) { +@@ -878,15 +1140,17 @@ + this.N = true; + this.getConvertable().d(); + +- for (int i = 0; i < this.worldServer.length; ++i) { +- WorldServer worldserver = this.worldServer[i]; ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ WorldServer worldserver = this.worlds.get(i); ++ // CraftBukkit end + + if (worldserver != null) { + worldserver.saveLevel(); + } + } + +- this.getConvertable().e(this.worldServer[0].getDataManager().g()); ++ this.getConvertable().e(this.worlds.get(0).getDataManager().g()); // CraftBukkit + this.safeShutdown(); + } + +@@ -919,9 +1183,11 @@ + int i = 0; + + if (this.worldServer != null) { +- for (int j = 0; j < this.worldServer.length; ++j) { +- if (this.worldServer[j] != null) { +- WorldServer worldserver = this.worldServer[j]; ++ // CraftBukkit start ++ for (int j = 0; j < this.worlds.size(); ++j) { ++ WorldServer worldserver = this.worlds.get(j); ++ if (worldserver != null) { ++ // CraftBukkit end + WorldData worlddata = worldserver.getWorldData(); + + mojangstatisticsgenerator.a("world[" + i + "][dimension]", Integer.valueOf(worldserver.worldProvider.getDimension())); +@@ -954,7 +1220,7 @@ + public abstract boolean ad(); + + public boolean getOnlineMode() { +- return this.onlineMode; ++ return server.getOnlineMode(); // CraftBukkit + } + + public void setOnlineMode(boolean flag) { +@@ -1024,8 +1290,10 @@ + } + + public void setGamemode(EnumGamemode enumgamemode) { +- for (int i = 0; i < this.worldServer.length; ++i) { +- getServer().worldServer[i].getWorldData().setGameType(enumgamemode); ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ getServer().worlds.get(i).getWorldData().setGameType(enumgamemode); ++ // CraftBukkit end + } + + } +@@ -1057,7 +1325,7 @@ + } + + public World getWorld() { +- return this.worldServer[0]; ++ return this.worlds.get(0); // CraftBukkit + } + + public Entity f() { +@@ -1125,11 +1393,10 @@ + } + + public Entity a(UUID uuid) { +- WorldServer[] aworldserver = this.worldServer; +- int i = aworldserver.length; +- +- for (int j = 0; j < i; ++j) { +- WorldServer worldserver = aworldserver[j]; ++ // CraftBukkit start ++ for (int j = 0; j < worlds.size(); ++j) { ++ WorldServer worldserver = worlds.get(j); ++ // CraftBukkit end + + if (worldserver != null) { + Entity entity = worldserver.getEntity(uuid); +@@ -1144,7 +1411,7 @@ + } + + public boolean getSendCommandFeedback() { +- return getServer().worldServer[0].getGameRules().getBoolean("sendCommandFeedback"); ++ return getServer().worlds.get(0).getGameRules().getBoolean("sendCommandFeedback"); // CraftBukkit + } + + public void a(EnumCommandResult enumcommandresult, int i) {} |