Paper/src/main/java/net/minecraft/server/MinecraftServer.java

1288 Zeilen
42 KiB
Java

2010-12-22 16:22:23 +01:00
package net.minecraft.server;
2012-07-29 09:33:13 +02:00
import java.awt.GraphicsEnvironment;
2013-11-04 14:07:38 +01:00
import java.awt.image.BufferedImage;
2010-12-22 16:22:23 +01:00
import java.io.File;
2013-07-01 13:03:00 +02:00
import java.net.Proxy;
2012-07-29 09:33:13 +02:00
import java.security.KeyPair;
import java.text.SimpleDateFormat;
2010-12-22 16:22:23 +01:00
import java.util.ArrayList;
2013-11-04 14:07:38 +01:00
import java.util.Arrays;
import java.util.Collections;
2012-07-29 09:33:13 +02:00
import java.util.Date;
2010-12-28 20:52:24 +01:00
import java.util.Iterator;
2010-12-22 16:22:23 +01:00
import java.util.List;
2013-11-04 14:07:38 +01:00
import java.util.Random;
import java.util.UUID;
2012-07-29 09:33:13 +02:00
import java.util.concurrent.Callable;
2013-11-04 14:07:38 +01:00
import javax.imageio.ImageIO;
import net.minecraft.util.com.google.common.base.Charsets;
import net.minecraft.util.com.mojang.authlib.GameProfile;
import net.minecraft.util.com.mojang.authlib.minecraft.MinecraftSessionService;
import net.minecraft.util.com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.buffer.ByteBufOutputStream;
import net.minecraft.util.io.netty.buffer.Unpooled;
import net.minecraft.util.io.netty.handler.codec.base64.Base64;
import net.minecraft.util.org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
2010-12-28 20:52:24 +01:00
// CraftBukkit start
import java.io.IOException;
import jline.console.ConsoleReader;
import joptsimple.OptionSet;
2011-05-26 14:48:22 +02:00
import org.bukkit.World.Environment;
import org.bukkit.craftbukkit.util.Waitable;
2012-01-30 21:51:53 +01:00
import org.bukkit.event.server.RemoteServerCommandEvent;
import org.bukkit.event.world.WorldSaveEvent;
// CraftBukkit end
2010-12-22 16:22:23 +01:00
2012-11-06 13:05:28 +01:00
public abstract class MinecraftServer implements ICommandListener, Runnable, IMojangStatistics {
2010-12-22 16:22:23 +01:00
2013-11-04 14:07:38 +01:00
private static final Logger h = LogManager.getLogger();
private static MinecraftServer i;
2012-07-29 09:33:13 +02:00
public Convertable convertable; // CraftBukkit - private final -> public
2013-11-04 14:07:38 +01:00
private final MojangStatisticsGenerator k = new MojangStatisticsGenerator("server", this, ap());
2012-07-29 09:33:13 +02:00
public File universe; // CraftBukkit - private final -> public
2013-11-04 14:07:38 +01:00
private final List m = new ArrayList();
private final ICommandHandler n;
2012-07-29 09:33:13 +02:00
public final MethodProfiler methodProfiler = new MethodProfiler();
2013-11-04 14:07:38 +01:00
private final ServerConnection o;
private final ServerPing p = new ServerPing();
private final Random q = new Random();
2012-07-29 09:33:13 +02:00
private String serverIp;
2013-07-01 13:03:00 +02:00
private int s = -1;
2013-03-13 23:33:27 +01:00
public WorldServer[] worldServer;
2013-07-01 13:03:00 +02:00
private PlayerList t;
private boolean isRunning = true;
2013-07-01 13:03:00 +02:00
private boolean isStopped;
private int ticks;
2013-11-04 14:07:38 +01:00
protected final Proxy c;
2013-07-01 13:03:00 +02:00
public String d;
public int e;
2012-07-29 09:33:13 +02:00
private boolean onlineMode;
private boolean spawnAnimals;
private boolean spawnNPCs;
private boolean pvpMode;
private boolean allowFlight;
private String motd;
2013-07-01 13:03:00 +02:00
private int D;
2013-11-04 14:07:38 +01:00
private int E = 0;
public final long[] f = new long[100];
public long[][] g;
private KeyPair F;
private String G;
private String H;
2012-07-29 09:33:13 +02:00
private boolean demoMode;
2013-11-04 14:07:38 +01:00
private boolean K;
private boolean L;
private String M = "";
private boolean N;
private long O;
private String P;
private boolean Q;
2013-09-19 20:25:08 +02:00
private boolean R;
2013-11-04 14:07:38 +01:00
private final MinecraftSessionService S;
private long T = 0L;
2010-12-28 20:52:24 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
public List<WorldServer> worlds = new ArrayList<WorldServer>();
public org.bukkit.craftbukkit.CraftServer server;
2011-01-29 22:50:29 +01:00
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;
2011-05-14 16:29:42 +02:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
2013-11-04 14:07:38 +01:00
public MinecraftServer(OptionSet options, Proxy proxy) { // CraftBukkit - signature file -> OptionSet
i = this;
this.c = proxy;
2012-07-29 09:33:13 +02:00
// this.universe = file1; // CraftBukkit
2013-11-04 14:07:38 +01:00
this.o = new ServerConnection(this);
this.n = new CommandDispatcher();
// this.convertable = new WorldLoaderServer(file1); // CraftBukkit - moved to DedicatedServer.init
this.S = (new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString())).createMinecraftSessionService();
2011-06-12 00:02:58 +02:00
// CraftBukkit start
this.options = options;
try {
this.reader = new ConsoleReader(System.in, System.out);
this.reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators
} catch (Exception 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");
org.bukkit.craftbukkit.Main.useJline = false;
this.reader = new ConsoleReader(System.in, System.out);
this.reader.setExpandEvents(false);
2013-03-25 05:22:32 +01:00
} catch (IOException ex) {
2013-11-04 14:07:38 +01:00
h.warn((String) null, ex);
}
}
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
2012-07-29 09:33:13 +02:00
primaryThread = new ThreadServerApplication(this, "Server thread"); // Moved from main
}
public abstract PropertyManager getPropertyManager();
2012-07-29 09:33:13 +02:00
// CraftBukkit end
2011-11-20 09:01:14 +01:00
2012-07-29 09:33:13 +02:00
protected abstract boolean init() throws java.net.UnknownHostException; // CraftBukkit - throws UnknownHostException
2011-11-20 09:01:14 +01:00
2013-07-01 13:03:00 +02:00
protected void a(String s) {
2012-07-29 09:33:13 +02:00
if (this.getConvertable().isConvertable(s)) {
2013-11-04 14:07:38 +01:00
h.info("Converting map!");
2013-07-01 13:03:00 +02:00
this.b("menu.convertingLevel");
2012-07-29 09:33:13 +02:00
this.getConvertable().convert(s, new ConvertProgressUpdater(this));
}
2010-12-22 16:22:23 +01:00
}
2013-07-01 13:03:00 +02:00
protected synchronized void b(String s) {
2013-11-04 14:07:38 +01:00
this.P = s;
2012-07-29 09:33:13 +02:00
}
2011-02-23 03:37:56 +01:00
protected void a(String s, String s1, long i, WorldType worldtype, String s2) {
2013-07-01 13:03:00 +02:00
this.a(s);
this.b("menu.loadingLevel");
2013-03-13 23:33:27 +01:00
this.worldServer = new WorldServer[3];
2013-11-04 14:07:38 +01:00
// this.g = new long[this.worldServer.length][100]; // CraftBukkit - Removed ticktime arrays
// IDataManager idatamanager = this.convertable.a(s, true);
// WorldData worlddata = idatamanager.getWorldData();
/* CraftBukkit start - Removed worldsettings
WorldSettings worldsettings;
if (worlddata == null) {
worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype);
worldsettings.a(s2);
} else {
worldsettings = new WorldSettings(worlddata);
}
if (this.K) {
worldsettings.a();
}
// */
2011-11-24 19:48:01 +01:00
int worldCount = 3;
2011-11-20 09:01:14 +01:00
2012-07-29 09:33:13 +02:00
for (int j = 0; j < worldCount; ++j) {
2011-05-26 14:48:22 +02:00
WorldServer world;
2011-11-20 09:01:14 +01:00
int dimension = 0;
2012-07-29 09:33:13 +02:00
if (j == 1) {
if (this.getAllowNether()) {
2011-11-24 19:48:01 +01:00
dimension = -1;
} else {
continue;
}
2011-11-20 09:01:14 +01:00
}
2012-07-29 09:33:13 +02:00
if (j == 2) {
if (this.server.getAllowEnd()) {
dimension = 1;
} else {
continue;
}
2011-11-20 09:01:14 +01:00
}
String worldType = 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.a(s2);
2012-07-29 09:33:13 +02:00
if (j == 0) {
2013-11-04 14:07:38 +01:00
IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), s1, true);
if (this.P()) {
world = new DemoWorldServer(this, idatamanager, s1, dimension, this.methodProfiler);
2012-07-29 09:33:13 +02:00
} else {
2013-11-04 14:07:38 +01:00
// world =, b0 to dimension, added Environment and gen
world = new WorldServer(this, idatamanager, s1, dimension, worldsettings, this.methodProfiler, Environment.getEnvironment(dimension), gen);
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard());
2011-05-26 14:48:22 +02:00
} else {
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())) {
2013-11-04 14:07:38 +01:00
h.info("---- Migration of old " + worldType + " folder required ----");
h.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.");
h.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.");
h.info("Attempting to move " + oldWorld + " to " + newWorld + "...");
if (newWorld.exists()) {
2013-11-04 14:07:38 +01:00
h.warn("A file or folder already exists at " + newWorld + "!");
h.info("---- Migration of old " + worldType + " folder failed ----");
} else if (newWorld.getParentFile().mkdirs()) {
if (oldWorld.renameTo(newWorld)) {
2013-11-04 14:07:38 +01:00
h.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld);
// Migrate world data too.
try {
2013-03-25 05:22:32 +01:00
com.google.common.io.Files.copy(new File(new File(s), "level.dat"), new File(new File(name), "level.dat"));
} catch (IOException exception) {
2013-11-04 14:07:38 +01:00
h.warn("Unable to migrate world data.");
}
2013-11-04 14:07:38 +01:00
h.info("---- Migration of old " + worldType + " folder complete ----");
} else {
2013-11-04 14:07:38 +01:00
h.warn("Could not move folder " + oldWorld + " to " + newWorld + "!");
h.info("---- Migration of old " + worldType + " folder failed ----");
}
} else {
2013-11-04 14:07:38 +01:00
h.warn("Could not create path for " + newWorld + "!");
h.info("---- Migration of old " + worldType + " folder failed ----");
}
}
2013-11-04 14:07:38 +01:00
IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, true);
// world =, b0 to dimension, s1 to name, added Environment and gen
world = new SecondaryWorldServer(this, idatamanager, name, dimension, worldsettings, this.worlds.get(0), this.methodProfiler, Environment.getEnvironment(dimension), gen);
}
if (gen != null) {
world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld()));
2011-05-26 14:48:22 +02:00
}
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
2011-05-26 14:48:22 +02:00
world.addIWorldAccess(new WorldManager(this, world));
2013-11-04 14:07:38 +01:00
if (!this.L()) {
2012-07-29 09:33:13 +02:00
world.getWorldData().setGameType(this.getGamemode());
}
2013-11-04 14:07:38 +01:00
this.worlds.add(world);
2013-07-01 13:03:00 +02:00
this.t.setPlayerFileData(this.worlds.toArray(new WorldServer[this.worlds.size()]));
2012-07-29 09:33:13 +02:00
// CraftBukkit end
2011-05-26 14:48:22 +02:00
}
2013-11-04 14:07:38 +01:00
this.a(this.getDifficulty());
this.g();
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
protected void g() {
2013-07-01 13:03:00 +02:00
boolean flag = true;
boolean flag1 = true;
boolean flag2 = true;
boolean flag3 = true;
int i = 0;
2012-07-29 09:33:13 +02:00
2013-07-01 13:03:00 +02:00
this.b("menu.generatingTerrain");
byte b0 = 0;
2011-01-29 22:50:29 +01:00
// CraftBukkit start
2013-07-01 13:03:00 +02:00
for (int m = 0; m < this.worlds.size(); ++m) {
WorldServer worldserver = this.worlds.get(m);
2013-11-04 14:07:38 +01:00
h.info("Preparing start region for level " + m + " (Seed: " + worldserver.getSeed() + ")");
2012-01-12 23:10:13 +01:00
if (!worldserver.getWorld().getKeepSpawnInMemory()) {
continue;
}
2013-03-13 23:33:27 +01:00
2012-01-12 23:10:13 +01:00
ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
2013-11-04 14:07:38 +01:00
long j = ap();
i = 0;
2011-01-29 22:50:29 +01:00
2013-03-13 23:33:27 +01:00
for (int k = -192; k <= 192 && this.isRunning(); k += 16) {
for (int l = -192; l <= 192 && this.isRunning(); l += 16) {
2013-11-04 14:07:38 +01:00
long i1 = ap();
2011-01-14 14:31:10 +01:00
2013-07-01 13:03:00 +02:00
if (i1 - j > 1000L) {
this.a_("Preparing spawn area", i * 100 / 625);
j = i1;
2012-01-12 23:10:13 +01:00
}
2011-01-29 22:50:29 +01:00
2013-07-01 13:03:00 +02:00
++i;
2012-07-29 09:33:13 +02:00
worldserver.chunkProviderServer.getChunkAt(chunkcoordinates.x + k >> 4, chunkcoordinates.z + l >> 4);
2010-12-22 16:22:23 +01:00
}
2012-01-12 23:10:13 +01:00
}
2010-12-22 16:22:23 +01:00
}
2013-03-13 23:33:27 +01:00
// CraftBukkit end
2013-11-04 14:07:38 +01:00
this.m();
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
public abstract boolean getGenerateStructures();
public abstract EnumGamemode getGamemode();
2013-11-04 14:07:38 +01:00
public abstract EnumDifficulty getDifficulty();
2012-07-29 09:33:13 +02:00
public abstract boolean isHardcore();
2013-11-04 14:07:38 +01:00
public abstract int l();
2013-07-01 13:03:00 +02:00
2012-07-29 09:33:13 +02:00
protected void a_(String s, int i) {
2013-07-01 13:03:00 +02:00
this.d = s;
this.e = i;
2013-11-04 14:07:38 +01:00
h.info(s + ": " + i + "%");
2010-12-22 16:22:23 +01:00
}
2013-11-04 14:07:38 +01:00
protected void m() {
2013-07-01 13:03:00 +02:00
this.d = null;
this.e = 0;
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
protected void saveChunks(boolean flag) throws ExceptionWorldConflict { // CraftBukkit - added throws
2013-11-04 14:07:38 +01:00
if (!this.L) {
2012-07-29 09:33:13 +02:00
// CraftBukkit start
2013-11-04 14:07:38 +01:00
// WorldServer[] aworldserver = this.worldServer;
int i = this.worlds.size();
for (int j = 0; j < i; ++j) {
2012-07-29 09:33:13 +02:00
WorldServer worldserver = this.worlds.get(j);
2012-07-29 09:33:13 +02:00
if (worldserver != null) {
if (!flag) {
2013-11-04 14:07:38 +01:00
h.info("Saving chunks for level \'" + worldserver.getWorldData().getName() + "\'/" + worldserver.worldProvider.getName());
2012-07-29 09:33:13 +02:00
}
worldserver.save(true, (IProgressUpdate) null);
2012-07-29 09:33:13 +02:00
worldserver.saveLevel();
2011-05-26 14:48:22 +02:00
2012-07-29 09:33:13 +02:00
WorldSaveEvent event = new WorldSaveEvent(worldserver.getWorld());
this.server.getPluginManager().callEvent(event);
2013-11-04 14:07:38 +01:00
// CraftBukkit end
2012-07-29 09:33:13 +02:00
}
}
}
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws
2013-11-04 14:07:38 +01:00
if (!this.L) {
h.info("Stopping server");
2012-07-29 09:33:13 +02:00
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
}
// CraftBukkit end
2011-02-02 00:32:18 +01:00
2013-07-01 13:03:00 +02:00
if (this.ag() != null) {
2013-11-04 14:07:38 +01:00
this.ag().b();
2012-07-29 09:33:13 +02:00
}
2011-01-27 22:15:41 +01:00
2013-07-01 13:03:00 +02:00
if (this.t != null) {
2013-11-04 14:07:38 +01:00
h.info("Saving players");
2013-07-01 13:03:00 +02:00
this.t.savePlayers();
this.t.r();
2012-07-29 09:33:13 +02:00
}
2011-05-26 14:48:22 +02:00
2013-11-04 14:07:38 +01:00
h.info("Saving worlds");
2012-07-29 09:33:13 +02:00
this.saveChunks(false);
2013-03-25 05:22:32 +01:00
/* CraftBukkit start - Handled in saveChunks
2012-11-06 13:05:28 +01:00
for (int i = 0; i < this.worldServer.length; ++i) {
WorldServer worldserver = this.worldServer[i];
2012-07-29 09:33:13 +02:00
worldserver.saveLevel();
}
// CraftBukkit end */
2013-11-04 14:07:38 +01:00
if (this.k.d()) {
this.k.e();
2012-01-12 23:10:13 +01:00
}
2012-07-29 09:33:13 +02:00
}
}
public String getServerIp() {
return this.serverIp;
}
2013-07-01 13:03:00 +02:00
public void c(String s) {
2012-07-29 09:33:13 +02:00
this.serverIp = s;
}
public boolean isRunning() {
return this.isRunning;
2010-12-22 16:22:23 +01:00
}
public void safeShutdown() {
this.isRunning = false;
2010-12-22 16:22:23 +01:00
}
public void run() {
try {
if (this.init()) {
2013-11-04 14:07:38 +01:00
long i = ap();
long j = 0L;
this.p.setMOTD(new ChatComponentText(this.motd));
this.p.setServerInfo(new ServerPingServerData("1.7.2", 4));
this.a(this.p);
2010-12-28 20:52:24 +01:00
2013-11-04 14:07:38 +01:00
while (this.isRunning) {
long k = ap();
2011-01-29 22:50:29 +01:00
long l = k - i;
2010-12-28 20:52:24 +01:00
2013-11-04 14:07:38 +01:00
if (l > 2000L && i - this.O >= 15000L) {
2012-07-29 09:33:13 +02:00
if (this.server.getWarnOnOverload()) // CraftBukkit - Added option to suppress warning messages
2013-11-04 14:07:38 +01:00
h.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(l), Long.valueOf(l / 50L)});
2011-01-29 22:50:29 +01:00
l = 2000L;
2013-11-04 14:07:38 +01:00
this.O = i;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
if (l < 0L) {
2013-11-04 14:07:38 +01:00
h.warn("Time ran backwards! Did the system time change?");
2011-01-29 22:50:29 +01:00
l = 0L;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
j += l;
i = k;
2011-05-28 22:50:08 +02:00
if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit
2013-11-04 14:07:38 +01:00
this.t();
2011-02-23 03:37:56 +01:00
j = 0L;
} else {
while (j > 50L) {
MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
2011-02-23 03:37:56 +01:00
j -= 50L;
2013-11-04 14:07:38 +01:00
this.t();
2011-02-23 03:37:56 +01:00
}
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
2012-07-29 09:33:13 +02:00
Thread.sleep(1L);
2013-11-04 14:07:38 +01:00
this.N = true;
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
} else {
this.a((CrashReport) null);
2010-12-22 16:22:23 +01:00
}
2011-02-23 03:37:56 +01:00
} catch (Throwable throwable) {
2013-11-04 14:07:38 +01:00
h.error("Encountered an unexpected exception", throwable);
2012-07-29 09:33:13 +02:00
CrashReport crashreport = null;
if (throwable instanceof ReportedException) {
crashreport = this.b(((ReportedException) throwable).a());
} else {
crashreport = this.b(new CrashReport("Exception in server tick loop", throwable));
}
2011-01-29 22:50:29 +01:00
2013-11-04 14:07:38 +01:00
File file1 = new File(new File(this.r(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
2011-01-29 22:50:29 +01:00
2013-11-04 14:07:38 +01:00
if (crashreport.a(file1)) {
h.error("This crash report has been saved to: " + file1.getAbsolutePath());
2012-07-29 09:33:13 +02:00
} else {
2013-11-04 14:07:38 +01:00
h.error("We were unable to save this crash report to disk.");
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
this.a(crashreport);
2010-12-22 16:22:23 +01:00
} finally {
2011-01-14 14:31:10 +01:00
try {
this.stop();
this.isStopped = true;
2012-07-29 09:33:13 +02:00
} catch (Throwable throwable1) {
2013-11-04 14:07:38 +01:00
h.error("Exception stopping the server", throwable1);
2012-07-29 09:33:13 +02:00
} finally {
2013-03-25 05:22:32 +01:00
// CraftBukkit start - Restore terminal to original settings
try {
this.reader.getTerminal().restore();
} catch (Exception e) {
}
// CraftBukkit end
2013-11-04 14:07:38 +01:00
this.s();
}
}
}
private void a(ServerPing serverping) {
File file1 = this.d("server-icon.png");
if (file1.isFile()) {
ByteBuf bytebuf = Unpooled.buffer();
try {
BufferedImage bufferedimage = ImageIO.read(file1);
Validate.validState(bufferedimage.getWidth() == 64, "Must be 64 pixels wide", new Object[0]);
Validate.validState(bufferedimage.getHeight() == 64, "Must be 64 pixels high", new Object[0]);
ImageIO.write(bufferedimage, "PNG", new ByteBufOutputStream(bytebuf));
ByteBuf bytebuf1 = Base64.encode(bytebuf);
serverping.setFavicon("data:image/png;base64," + bytebuf1.toString(Charsets.UTF_8));
} catch (Exception exception) {
h.error("Couldn\'t load server icon", exception);
2011-01-14 14:31:10 +01:00
}
2010-12-22 16:22:23 +01:00
}
}
2013-11-04 14:07:38 +01:00
protected File r() {
2012-07-29 09:33:13 +02:00
return new File(".");
}
protected void a(CrashReport crashreport) {}
2013-11-04 14:07:38 +01:00
protected void s() {}
2012-07-29 09:33:13 +02:00
2013-11-04 14:07:38 +01:00
protected void t() throws ExceptionWorldConflict { // CraftBukkit - added throws
2011-11-20 09:01:14 +01:00
long i = System.nanoTime();
2010-12-28 20:52:24 +01:00
2012-07-29 09:33:13 +02:00
AxisAlignedBB.a().a();
++this.ticks;
2013-11-04 14:07:38 +01:00
if (this.Q) {
this.Q = false;
2012-09-10 06:19:28 +02:00
this.methodProfiler.a = true;
this.methodProfiler.a();
2012-07-29 09:33:13 +02:00
}
2010-12-28 20:52:24 +01:00
2012-09-10 06:19:28 +02:00
this.methodProfiler.a("root");
2013-11-04 14:07:38 +01:00
this.u();
if (i - this.T >= 5000000000L) {
this.T = i;
this.p.setPlayerSample(new ServerPingPlayerSample(this.C(), this.B()));
GameProfile[] agameprofile = new GameProfile[Math.min(this.B(), 12)];
int j = MathHelper.nextInt(this.q, 0, this.B() - agameprofile.length);
for (int k = 0; k < agameprofile.length; ++k) {
agameprofile[k] = ((EntityPlayer) this.t.players.get(j + k)).getProfile();
}
Collections.shuffle(Arrays.asList(agameprofile));
this.p.b().a(agameprofile);
}
if ((this.autosavePeriod > 0) && ((this.ticks % this.autosavePeriod) == 0)) { // CraftBukkit
2012-09-10 06:19:28 +02:00
this.methodProfiler.a("save");
2013-07-01 13:03:00 +02:00
this.t.savePlayers();
2012-07-29 09:33:13 +02:00
this.saveChunks(true);
2012-09-10 06:19:28 +02:00
this.methodProfiler.b();
2010-12-22 16:22:23 +01:00
}
2010-12-28 20:52:24 +01:00
2012-09-10 06:19:28 +02:00
this.methodProfiler.a("tallying");
2013-11-04 14:07:38 +01:00
this.f[this.ticks % 100] = System.nanoTime() - i;
2012-09-10 06:19:28 +02:00
this.methodProfiler.b();
this.methodProfiler.a("snooper");
2013-11-04 14:07:38 +01:00
if (!this.k.d() && this.ticks > 100) {
this.k.a();
2012-07-29 09:33:13 +02:00
}
2011-01-29 22:50:29 +01:00
2012-07-29 09:33:13 +02:00
if (this.ticks % 6000 == 0) {
2013-11-04 14:07:38 +01:00
this.k.b();
2010-12-22 16:22:23 +01:00
}
2012-09-10 06:19:28 +02:00
this.methodProfiler.b();
this.methodProfiler.b();
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public void u() {
2012-09-10 06:19:28 +02:00
this.methodProfiler.a("levels");
2011-08-07 05:45:56 +02:00
2013-03-25 05:22:32 +01:00
// CraftBukkit start
2012-07-29 09:33:13 +02:00
this.server.getScheduler().mainThreadHeartbeat(this.ticks);
// Run tasks that are waiting on processing
while (!processQueue.isEmpty()) {
processQueue.remove().run();
}
Load chunks asynchronously for players. When a player triggers a chunk load via walking around or teleporting there is no need to stop everything and get this chunk on the main thread. The client is used to having to wait some time for this chunk and the server doesn't immediately do anything with it except send it to the player. At the same time chunk loading is the last major source of file IO that still runs on the main thread. These two facts make it possible to offload chunks loaded for this reason to another thread. However, not all parts of chunk loading can happen off the main thread. For this we use the new AsynchronousExecutor system to split chunk loading in to three pieces. The first is loading data from disk, decompressing it, and parsing it in to an NBT structure. The second piece is creating entities and tile entities in the chunk and adding them to the world, this is still done on the main thread. The third piece is informing everyone who requested a chunk load that the load is finished. For this we register callbacks and then run them on the main thread once the previous two stages are finished. There are still cases where a chunk is needed immediately and these will still trigger chunk loading entirely on the main thread. The most obvious case is plugins using the API to request a chunk load. We also must load the chunk immediately when something in the world tries to access it. In these cases we ignore any possibly pending or in progress chunk loading that is happening asynchronously as we will have the chunk loaded by the time they are finished. The hope is that overall this system will result in less CPU time and pauses due to blocking file IO on the main thread thus giving more consistent performance. Testing so far has shown that this also speeds up chunk loading client side although some of this is likely to be because we are sending less chunks at once for the client to process. Thanks for @ammaraskar for help with the implementation of this feature.
2012-11-30 09:49:19 +01:00
org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick();
2013-03-25 05:22:32 +01:00
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
2012-12-20 05:03:52 +01:00
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
EntityPlayer entityplayer = (EntityPlayer) this.getPlayerList().players.get(i);
2013-11-04 14:07:38 +01:00
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time
}
}
2012-11-06 13:05:28 +01:00
int i;
for (i = 0; i < this.worlds.size(); ++i) {
2012-07-29 09:33:13 +02:00
long j = System.nanoTime();
// if (i == 0 || this.getAllowNether()) {
WorldServer worldserver = this.worlds.get(i);
this.methodProfiler.a(worldserver.getWorldData().getName());
this.methodProfiler.a("pools");
worldserver.getVec3DPool().a();
this.methodProfiler.b();
/* Drop global time updates
2011-05-28 22:50:08 +02:00
if (this.ticks % 20 == 0) {
this.methodProfiler.a("timeSync");
2013-11-04 14:07:38 +01:00
this.t.a(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.worldProvider.dimension);
this.methodProfiler.b();
2011-05-26 14:48:22 +02:00
}
// CraftBukkit end */
2012-09-10 06:19:28 +02:00
this.methodProfiler.a("tick");
2012-11-06 13:05:28 +01:00
CrashReport crashreport;
try {
worldserver.doTick();
} catch (Throwable throwable) {
crashreport = CrashReport.a(throwable, "Exception ticking world");
worldserver.a(crashreport);
throw new ReportedException(crashreport);
}
try {
worldserver.tickEntities();
} catch (Throwable throwable1) {
crashreport = CrashReport.a(throwable1, "Exception ticking world entities");
worldserver.a(crashreport);
throw new ReportedException(crashreport);
}
this.methodProfiler.b();
this.methodProfiler.a("tracker");
worldserver.getTracker().updatePlayers();
this.methodProfiler.b();
this.methodProfiler.b();
2012-07-29 09:33:13 +02:00
// } // CraftBukkit
2011-05-26 14:48:22 +02:00
2013-11-04 14:07:38 +01:00
// this.g[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit
2011-05-26 14:48:22 +02:00
}
2011-01-29 22:50:29 +01:00
2012-09-10 06:19:28 +02:00
this.methodProfiler.c("connection");
2013-11-04 14:07:38 +01:00
this.ag().c();
2012-09-10 06:19:28 +02:00
this.methodProfiler.c("players");
2013-07-01 13:03:00 +02:00
this.t.tick();
2012-09-10 06:19:28 +02:00
this.methodProfiler.c("tickables");
2011-11-20 09:01:14 +01:00
2013-11-04 14:07:38 +01:00
for (i = 0; i < this.m.size(); ++i) {
((IUpdatePlayerListBox) this.m.get(i)).a();
2012-07-29 09:33:13 +02:00
}
2010-12-22 16:22:23 +01:00
2012-09-10 06:19:28 +02:00
this.methodProfiler.b();
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
public boolean getAllowNether() {
return true;
2010-12-22 16:22:23 +01:00
}
2010-12-28 20:52:24 +01:00
public void a(IUpdatePlayerListBox iupdateplayerlistbox) {
2013-11-04 14:07:38 +01:00
this.m.add(iupdateplayerlistbox);
2010-12-22 16:22:23 +01:00
}
2012-07-29 09:33:13 +02:00
public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring)
2013-11-04 14:07:38 +01:00
DispenserRegistry.b();
2011-04-20 22:47:26 +02:00
2010-12-22 16:22:23 +01:00
try {
2013-03-25 05:22:32 +01:00
/* CraftBukkit start - Replace everything
2013-07-01 13:03:00 +02:00
boolean flag = !GraphicsEnvironment.isHeadless();
2012-07-29 09:33:13 +02:00
String s = null;
String s1 = ".";
String s2 = null;
boolean flag1 = false;
boolean flag2 = false;
int i = -1;
for (int j = 0; j < astring.length; ++j) {
String s3 = astring[j];
String s4 = j == astring.length - 1 ? null : astring[j + 1];
boolean flag3 = false;
if (!s3.equals("nogui") && !s3.equals("--nogui")) {
if (s3.equals("--port") && s4 != null) {
flag3 = true;
try {
i = Integer.parseInt(s4);
} catch (NumberFormatException numberformatexception) {
;
}
} else if (s3.equals("--singleplayer") && s4 != null) {
flag3 = true;
s = s4;
} else if (s3.equals("--universe") && s4 != null) {
flag3 = true;
s1 = s4;
} else if (s3.equals("--world") && s4 != null) {
flag3 = true;
s2 = s4;
} else if (s3.equals("--demo")) {
flag1 = true;
} else if (s3.equals("--bonusChest")) {
flag2 = true;
}
} else {
flag = false;
}
if (flag3) {
++j;
}
}
2011-01-29 22:50:29 +01:00
2013-11-04 14:07:38 +01:00
DedicatedServer dedicatedserver = new DedicatedServer(new File(s1));
2012-07-29 09:33:13 +02:00
if (s != null) {
2013-07-01 13:03:00 +02:00
dedicatedserver.j(s);
2012-07-29 09:33:13 +02:00
}
if (s2 != null) {
2013-07-01 13:03:00 +02:00
dedicatedserver.k(s2);
2012-07-29 09:33:13 +02:00
}
2010-12-22 16:22:23 +01:00
2012-07-29 09:33:13 +02:00
if (i >= 0) {
dedicatedserver.setPort(i);
}
if (flag1) {
dedicatedserver.b(true);
}
if (flag2) {
dedicatedserver.c(true);
}
if (flag) {
2013-11-04 14:07:38 +01:00
dedicatedserver.ay();
}
// */
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");
}
if (options.has("world")) {
dedicatedserver.k((String) options.valueOf("world"));
2012-07-29 09:33:13 +02:00
}
dedicatedserver.primaryThread.start();
2013-11-04 14:07:38 +01:00
// Runtime.getRuntime().addShutdownHook(new ThreadShutdown("Server Shutdown Thread", dedicatedserver));
2012-07-29 09:33:13 +02:00
// CraftBukkit end
2010-12-28 20:52:24 +01:00
} catch (Exception exception) {
2013-11-04 14:07:38 +01:00
h.fatal("Failed to start the minecraft server", exception);
2010-12-22 16:22:23 +01:00
}
}
2013-11-04 14:07:38 +01:00
public void w() {
2012-07-29 09:33:13 +02:00
// (new ThreadServerApplication(this, "Server thread")).start(); // CraftBukkit - prevent abuse
2010-12-22 16:22:23 +01:00
}
2013-07-01 13:03:00 +02:00
public File d(String s) {
2013-11-04 14:07:38 +01:00
return new File(this.r(), s);
2012-07-29 09:33:13 +02:00
}
public void info(String s) {
2013-11-04 14:07:38 +01:00
h.info(s);
2010-12-22 16:22:23 +01:00
}
2011-11-20 09:01:14 +01:00
public void warning(String s) {
2013-11-04 14:07:38 +01:00
h.warn(s);
2011-03-31 22:40:00 +02:00
}
public WorldServer getWorldServer(int i) {
2011-05-28 22:50:08 +02:00
// CraftBukkit start
for (WorldServer world : this.worlds) {
if (world.dimension == i) {
return world;
}
}
2011-05-28 22:50:08 +02:00
return this.worlds.get(0);
2011-05-28 22:50:08 +02:00
// CraftBukkit end
2011-05-26 14:48:22 +02:00
}
2013-11-04 14:07:38 +01:00
public String x() {
2012-07-29 09:33:13 +02:00
return this.serverIp;
2011-11-20 09:01:14 +01:00
}
2013-11-04 14:07:38 +01:00
public int y() {
2013-07-01 13:03:00 +02:00
return this.s;
2011-11-20 09:01:14 +01:00
}
2013-11-04 14:07:38 +01:00
public String z() {
return this.motd;
2011-11-20 09:01:14 +01:00
}
public String getVersion() {
2013-11-04 14:07:38 +01:00
return "1.7.2";
2011-11-20 09:01:14 +01:00
}
2013-11-04 14:07:38 +01:00
public int B() {
2013-07-01 13:03:00 +02:00
return this.t.getPlayerCount();
2011-11-20 09:01:14 +01:00
}
2013-11-04 14:07:38 +01:00
public int C() {
2013-07-01 13:03:00 +02:00
return this.t.getMaxPlayers();
2011-11-20 09:01:14 +01:00
}
public String[] getPlayers() {
2013-07-01 13:03:00 +02:00
return this.t.d();
2011-11-20 09:01:14 +01:00
}
public String getPlugins() {
2013-03-25 05:22:32 +01:00
// 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 && this.server.getQueryPlugins()) {
result.append(": ");
for (int i = 0; i < plugins.length; i++) {
if (i > 0) {
result.append("; ");
}
result.append(plugins[i].getDescription().getName());
result.append(" ");
result.append(plugins[i].getDescription().getVersion().replaceAll(";", ","));
}
}
return result.toString();
// CraftBukkit end
2011-11-20 09:01:14 +01:00
}
// CraftBukkit start
2013-11-04 14:07:38 +01:00
public String g(final String s) { // final parameter
Waitable<String> waitable = new Waitable<String>() {
@Override
protected String evaluate() {
2013-11-04 14:07:38 +01:00
RemoteControlCommandListener.instance.e();
// Event changes start
RemoteServerCommandEvent event = new RemoteServerCommandEvent(MinecraftServer.this.remoteConsole, s);
MinecraftServer.this.server.getPluginManager().callEvent(event);
// Event changes end
ServerCommand servercommand = new ServerCommand(event.getCommand(), RemoteControlCommandListener.instance);
MinecraftServer.this.server.dispatchServerCommand(MinecraftServer.this.remoteConsole, servercommand); // CraftBukkit
2013-11-04 14:07:38 +01:00
// this.n.a(RemoteControlCommandListener.instance, s);
return RemoteControlCommandListener.instance.f();
}};
processQueue.add(waitable);
try {
return waitable.get();
2013-03-25 05:22:32 +01:00
} 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
2011-11-20 09:01:14 +01:00
}
public boolean isDebugging() {
2012-07-29 09:33:13 +02:00
return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode
2011-11-20 09:01:14 +01:00
}
2013-07-01 13:03:00 +02:00
public void h(String s) {
2013-11-04 14:07:38 +01:00
h.error(s);
2011-11-20 09:01:14 +01:00
}
2013-07-01 13:03:00 +02:00
public void i(String s) {
2011-11-20 09:01:14 +01:00
if (this.isDebugging()) {
2013-11-04 14:07:38 +01:00
h.info(s);
2011-11-20 09:01:14 +01:00
}
}
2012-07-29 09:33:13 +02:00
public String getServerModName() {
return "craftbukkit"; // CraftBukkit - cb > vanilla!
}
public CrashReport b(CrashReport crashreport) {
2012-11-06 13:05:28 +01:00
crashreport.g().a("Profiler Position", (Callable) (new CrashReportProfilerPosition(this)));
2013-07-01 13:03:00 +02:00
if (this.worlds != null && this.worlds.size() > 0 && this.worlds.get(0) != null) { // CraftBukkit
2012-11-06 13:05:28 +01:00
crashreport.g().a("Vec3 Pool Size", (Callable) (new CrashReportVec3DPoolSize(this)));
2012-07-29 09:33:13 +02:00
}
2013-07-01 13:03:00 +02:00
if (this.t != null) {
2012-11-06 13:05:28 +01:00
crashreport.g().a("Player Count", (Callable) (new CrashReportPlayerCount(this)));
2012-07-29 09:33:13 +02:00
}
return crashreport;
}
public List a(ICommandListener icommandlistener, String s) {
// CraftBukkit start - Allow tab-completion of Bukkit commands
/*
2012-07-29 09:33:13 +02:00
ArrayList arraylist = new ArrayList();
if (s.startsWith("/")) {
s = s.substring(1);
boolean flag = !s.contains(" ");
2013-11-04 14:07:38 +01:00
List list = this.n.b(icommandlistener, s);
2012-07-29 09:33:13 +02:00
if (list != null) {
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String s1 = (String) iterator.next();
if (flag) {
arraylist.add("/" + s1);
} else {
arraylist.add(s1);
}
}
}
return arraylist;
} else {
String[] astring = s.split(" ", -1);
String s2 = astring[astring.length - 1];
2013-11-04 14:07:38 +01:00
String[] astring1 = this.t.d();
2012-07-29 09:33:13 +02:00
int i = astring1.length;
for (int j = 0; j < i; ++j) {
String s3 = astring1[j];
if (CommandAbstract.a(s2, s3)) {
arraylist.add(s3);
}
}
return arraylist;
}
*/
return this.server.tabComplete(icommandlistener, s);
// CraftBukkit end
2011-11-20 09:01:14 +01:00
}
2012-07-29 09:33:13 +02:00
public static MinecraftServer getServer() {
2013-11-04 14:07:38 +01:00
return i;
2011-11-20 09:01:14 +01:00
}
2012-07-29 09:33:13 +02:00
public String getName() {
return "Server";
}
2013-11-04 14:07:38 +01:00
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
h.info(ichatbasecomponent.c());
2012-07-29 09:33:13 +02:00
}
public boolean a(int i, String s) {
2012-07-29 09:33:13 +02:00
return true;
}
public ICommandHandler getCommandHandler() {
2013-11-04 14:07:38 +01:00
return this.n;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public KeyPair I() {
return this.F;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public int J() {
2013-07-01 13:03:00 +02:00
return this.s;
2012-07-29 09:33:13 +02:00
}
public void setPort(int i) {
2013-07-01 13:03:00 +02:00
this.s = i;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public String K() {
return this.G;
2012-07-29 09:33:13 +02:00
}
2013-07-01 13:03:00 +02:00
public void j(String s) {
2013-11-04 14:07:38 +01:00
this.G = s;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public boolean L() {
return this.G != null;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public String M() {
return this.H;
2012-07-29 09:33:13 +02:00
}
2013-07-01 13:03:00 +02:00
public void k(String s) {
2013-11-04 14:07:38 +01:00
this.H = s;
2012-07-29 09:33:13 +02:00
}
public void a(KeyPair keypair) {
2013-11-04 14:07:38 +01:00
this.F = keypair;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public void a(EnumDifficulty enumdifficulty) {
2012-07-29 09:33:13 +02:00
// CraftBukkit start
for (int j = 0; j < this.worlds.size(); ++j) {
WorldServer worldserver = this.worlds.get(j);
// CraftBukkit end
if (worldserver != null) {
if (worldserver.getWorldData().isHardcore()) {
2013-11-04 14:07:38 +01:00
worldserver.difficulty = EnumDifficulty.HARD;
2012-07-29 09:33:13 +02:00
worldserver.setSpawnFlags(true, true);
2013-11-04 14:07:38 +01:00
} else if (this.L()) {
worldserver.difficulty = enumdifficulty;
worldserver.setSpawnFlags(worldserver.difficulty != EnumDifficulty.PEACEFUL, true);
2012-07-29 09:33:13 +02:00
} else {
2013-11-04 14:07:38 +01:00
worldserver.difficulty = enumdifficulty;
2012-07-29 09:33:13 +02:00
worldserver.setSpawnFlags(this.getSpawnMonsters(), this.spawnAnimals);
}
}
}
}
protected boolean getSpawnMonsters() {
return true;
}
2013-11-04 14:07:38 +01:00
public boolean P() {
2012-07-29 09:33:13 +02:00
return this.demoMode;
}
public void b(boolean flag) {
this.demoMode = flag;
}
public void c(boolean flag) {
2013-11-04 14:07:38 +01:00
this.K = flag;
2012-07-29 09:33:13 +02:00
}
public Convertable getConvertable() {
return this.convertable;
}
2013-11-04 14:07:38 +01:00
public void S() {
this.L = true;
2012-07-29 09:33:13 +02:00
this.getConvertable().d();
2013-11-04 14:07:38 +01:00
// CraftBukkit start
2012-07-29 09:33:13 +02:00
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.worlds.get(0).getDataManager().g()); // CraftBukkit
2012-07-29 09:33:13 +02:00
this.safeShutdown();
}
2013-11-04 14:07:38 +01:00
public String getResourcePack() {
return this.M;
2012-07-29 09:33:13 +02:00
}
public void setTexturePack(String s) {
2013-11-04 14:07:38 +01:00
this.M = s;
2012-07-29 09:33:13 +02:00
}
public void a(MojangStatisticsGenerator mojangstatisticsgenerator) {
mojangstatisticsgenerator.a("whitelist_enabled", Boolean.valueOf(false));
mojangstatisticsgenerator.a("whitelist_count", Integer.valueOf(0));
2013-11-04 14:07:38 +01:00
mojangstatisticsgenerator.a("players_current", Integer.valueOf(this.B()));
mojangstatisticsgenerator.a("players_max", Integer.valueOf(this.C()));
2013-07-01 13:03:00 +02:00
mojangstatisticsgenerator.a("players_seen", Integer.valueOf(this.t.getSeenPlayers().length));
2012-07-29 09:33:13 +02:00
mojangstatisticsgenerator.a("uses_auth", Boolean.valueOf(this.onlineMode));
2013-07-01 13:03:00 +02:00
mojangstatisticsgenerator.a("gui_state", this.ai() ? "enabled" : "disabled");
2013-11-04 14:07:38 +01:00
mojangstatisticsgenerator.a("run_time", Long.valueOf((ap() - mojangstatisticsgenerator.g()) / 60L * 1000L));
mojangstatisticsgenerator.a("avg_tick_ms", Integer.valueOf((int) (MathHelper.a(this.f) * 1.0E-6D)));
2012-07-29 09:33:13 +02:00
int i = 0;
// CraftBukkit start
for (int j = 0; j < this.worlds.size(); ++j) {
2013-11-04 14:07:38 +01:00
WorldServer worldserver = this.worlds.get(j);
if (worldServer != null) {
2012-07-29 09:33:13 +02:00
// CraftBukkit end
WorldData worlddata = worldserver.getWorldData();
mojangstatisticsgenerator.a("world[" + i + "][dimension]", Integer.valueOf(worldserver.worldProvider.dimension));
mojangstatisticsgenerator.a("world[" + i + "][mode]", worlddata.getGameType());
2013-11-04 14:07:38 +01:00
mojangstatisticsgenerator.a("world[" + i + "][difficulty]", worldserver.difficulty);
2012-07-29 09:33:13 +02:00
mojangstatisticsgenerator.a("world[" + i + "][hardcore]", Boolean.valueOf(worlddata.isHardcore()));
mojangstatisticsgenerator.a("world[" + i + "][generator_name]", worlddata.getType().name());
mojangstatisticsgenerator.a("world[" + i + "][generator_version]", Integer.valueOf(worlddata.getType().getVersion()));
2013-07-01 13:03:00 +02:00
mojangstatisticsgenerator.a("world[" + i + "][height]", Integer.valueOf(this.D));
2013-11-04 14:07:38 +01:00
mojangstatisticsgenerator.a("world[" + i + "][chunks_loaded]", Integer.valueOf(worldserver.K().getLoadedChunks()));
2012-07-29 09:33:13 +02:00
++i;
2013-11-04 14:07:38 +01:00
}
2012-07-29 09:33:13 +02:00
}
mojangstatisticsgenerator.a("worlds", Integer.valueOf(i));
}
public void b(MojangStatisticsGenerator mojangstatisticsgenerator) {
2013-11-04 14:07:38 +01:00
mojangstatisticsgenerator.a("singleplayer", Boolean.valueOf(this.L()));
2012-07-29 09:33:13 +02:00
mojangstatisticsgenerator.a("server_brand", this.getServerModName());
mojangstatisticsgenerator.a("gui_supported", GraphicsEnvironment.isHeadless() ? "headless" : "supported");
2013-07-01 13:03:00 +02:00
mojangstatisticsgenerator.a("dedicated", Boolean.valueOf(this.V()));
2012-07-29 09:33:13 +02:00
}
public boolean getSnooperEnabled() {
return true;
}
2013-07-01 13:03:00 +02:00
public abstract boolean V();
2012-07-29 09:33:13 +02:00
public boolean getOnlineMode() {
2012-12-20 05:03:52 +01:00
return this.server.getOnlineMode(); // CraftBukkit
2012-07-29 09:33:13 +02:00
}
public void setOnlineMode(boolean flag) {
this.onlineMode = flag;
}
public boolean getSpawnAnimals() {
return this.spawnAnimals;
}
public void setSpawnAnimals(boolean flag) {
this.spawnAnimals = flag;
}
public boolean getSpawnNPCs() {
return this.spawnNPCs;
}
public void setSpawnNPCs(boolean flag) {
this.spawnNPCs = flag;
}
public boolean getPvP() {
return this.pvpMode;
}
public void setPvP(boolean flag) {
this.pvpMode = flag;
}
public boolean getAllowFlight() {
return this.allowFlight;
}
public void setAllowFlight(boolean flag) {
this.allowFlight = flag;
}
public abstract boolean getEnableCommandBlock();
2012-07-29 09:33:13 +02:00
public String getMotd() {
return this.motd;
}
public void setMotd(String s) {
this.motd = s;
}
public int getMaxBuildHeight() {
2013-07-01 13:03:00 +02:00
return this.D;
2012-07-29 09:33:13 +02:00
}
2013-11-04 14:07:38 +01:00
public void c(int i) {
2013-07-01 13:03:00 +02:00
this.D = i;
2012-07-29 09:33:13 +02:00
}
public boolean isStopped() {
return this.isStopped;
}
2012-12-20 05:03:52 +01:00
public PlayerList getPlayerList() {
2013-07-01 13:03:00 +02:00
return this.t;
2012-07-29 09:33:13 +02:00
}
2012-12-20 05:03:52 +01:00
public void a(PlayerList playerlist) {
2013-07-01 13:03:00 +02:00
this.t = playerlist;
2012-07-29 09:33:13 +02:00
}
public void a(EnumGamemode enumgamemode) {
// CraftBukkit start
for (int i = 0; i < this.worlds.size(); ++i) {
getServer().worlds.get(i).getWorldData().setGameType(enumgamemode);
// CraftBukkit end
}
}
2013-11-04 14:07:38 +01:00
public ServerConnection ag() {
return this.o;
}
2012-07-29 09:33:13 +02:00
2013-07-01 13:03:00 +02:00
public boolean ai() {
2012-07-29 09:33:13 +02:00
return false;
}
public abstract String a(EnumGamemode enumgamemode, boolean flag);
2013-07-01 13:03:00 +02:00
public int aj() {
2012-07-29 09:33:13 +02:00
return this.ticks;
}
2013-07-01 13:03:00 +02:00
public void ak() {
2013-11-04 14:07:38 +01:00
this.Q = true;
2012-03-30 23:33:51 +02:00
}
2011-11-20 09:01:14 +01:00
2013-11-04 14:07:38 +01:00
public ChunkCoordinates getChunkCoordinates() {
return new ChunkCoordinates(0, 0, 0);
}
2013-11-04 14:07:38 +01:00
public World getWorld() {
2013-07-01 13:03:00 +02:00
return this.worlds.get(0); // CraftBukkit
}
public int getSpawnProtection() {
return 16;
}
2013-03-13 23:33:27 +01:00
public boolean a(World world, int i, int j, int k, EntityHuman entityhuman) {
return false;
}
2013-04-27 11:40:05 +02:00
public void setForceGamemode(boolean flag) {
2013-11-04 14:07:38 +01:00
this.R = flag;
2013-04-27 11:40:05 +02:00
}
public boolean getForceGamemode() {
2013-11-04 14:07:38 +01:00
return this.R;
2013-07-01 13:03:00 +02:00
}
2013-11-04 14:07:38 +01:00
public Proxy ao() {
2013-07-01 13:03:00 +02:00
return this.c;
}
2013-11-04 14:07:38 +01:00
public static long ap() {
2013-07-01 13:03:00 +02:00
return System.currentTimeMillis();
2013-04-27 11:40:05 +02:00
}
2013-11-04 14:07:38 +01:00
public int aq() {
2013-09-19 20:25:08 +02:00
return this.E;
}
2013-11-04 14:07:38 +01:00
public void d(int i) {
2013-09-19 20:25:08 +02:00
this.E = i;
}
2013-11-04 14:07:38 +01:00
public IChatBaseComponent getScoreboardDisplayName() {
return new ChatComponentText(this.getName());
}
public boolean ar() {
return true;
}
public MinecraftSessionService as() {
return this.S;
}
public ServerPing at() {
return this.p;
}
public void au() {
this.T = 0L;
}
public static Logger av() {
return h;
}
2012-12-20 05:03:52 +01:00
public static PlayerList a(MinecraftServer minecraftserver) {
2013-07-01 13:03:00 +02:00
return minecraftserver.t;
2010-12-28 20:52:24 +01:00
}
}