Files
CatServer/patches/net/minecraft/server/MinecraftServer.java.patch

881 lines
36 KiB
Diff

--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java
+++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java
@@ -16,19 +16,14 @@
import io.netty.handler.codec.base64.Base64;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
+import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Proxy;
import java.security.KeyPair;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Queue;
-import java.util.Random;
-import java.util.UUID;
+import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
@@ -52,6 +47,7 @@
import net.minecraft.profiler.Profiler;
import net.minecraft.profiler.Snooper;
import net.minecraft.server.dedicated.DedicatedServer;
+import net.minecraft.server.dedicated.PropertyManager;
import net.minecraft.server.management.PlayerList;
import net.minecraft.server.management.PlayerProfileCache;
import net.minecraft.util.IProgressUpdate;
@@ -66,33 +62,41 @@
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
-import net.minecraft.world.EnumDifficulty;
-import net.minecraft.world.GameType;
-import net.minecraft.world.MinecraftException;
-import net.minecraft.world.ServerWorldEventHandler;
-import net.minecraft.world.World;
-import net.minecraft.world.WorldServer;
-import net.minecraft.world.WorldServerMulti;
-import net.minecraft.world.WorldSettings;
-import net.minecraft.world.WorldType;
+import net.minecraft.world.*;
import net.minecraft.world.chunk.storage.AnvilSaveConverter;
+import net.minecraft.world.chunk.storage.AnvilSaveHandler;
import net.minecraft.world.demo.DemoWorldServer;
import net.minecraft.world.storage.ISaveFormat;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.WorldInfo;
+import net.minecraftforge.common.DimensionManager;
+import net.minecraftforge.fml.common.Loader;
+import net.minecraftforge.fml.common.LoaderState;
+import net.minecraftforge.fml.common.registry.GameData;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+//CraftBukkit start
+import jline.console.ConsoleReader;
+import joptsimple.OptionSet;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.*;
+import org.bukkit.craftbukkit.command.ColouredConsoleSender;
+import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager;
+import org.bukkit.event.world.*;
+// CraftBukkit end
+
public abstract class MinecraftServer implements Runnable, ICommandSender, IThreadListener, ISnooperInfo
{
- private static final Logger LOG = LogManager.getLogger();
+ public static final Logger LOG = LogManager.getLogger();
public static final File USER_CACHE_FILE = new File("usercache.json");
- private final ISaveFormat anvilConverterForAnvilFile;
+ public ISaveFormat anvilConverterForAnvilFile;
private final Snooper usageSnooper = new Snooper("server", this, getCurrentTimeMillis());
- private final File anvilFile;
+ public File anvilFile;
+ public static File serverConfigDir=new File("./");
private final List<ITickable> tickables = Lists.<ITickable>newArrayList();
public final ICommandManager commandManager;
public final Profiler theProfiler = new Profiler();
@@ -141,26 +145,71 @@
private final GameProfileRepository profileRepo;
private final PlayerProfileCache profileCache;
private long nanoTimeSinceStatusRefresh;
- public final Queue < FutureTask<? >> futureTaskQueue = Queues. < FutureTask<? >> newArrayDeque();
+ public final Queue < FutureTask<? >> futureTaskQueue = new java.util.concurrent.ConcurrentLinkedQueue<FutureTask<?>>(); // Spigot, PAIL: Rename
private Thread serverThread;
private long currentTime = getCurrentTimeMillis();
@SideOnly(Side.CLIENT)
private boolean worldIconSet;
+ // 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;
+ private static final int TPS = 20;
+ private static final int TICK_TIME = 1000000000 / TPS;
+ private static final int SAMPLE_INTERVAL = 100;
+ public final double[] recentTps = new double[ 3 ];
+ // CraftBukkit end
- public MinecraftServer(File anvilFileIn, Proxy proxyIn, DataFixer dataFixerIn, YggdrasilAuthenticationService authServiceIn, MinecraftSessionService sessionServiceIn, GameProfileRepository profileRepoIn, PlayerProfileCache profileCacheIn)
+ public MinecraftServer(OptionSet options, Proxy proxyIn, DataFixer dataFixerIn, YggdrasilAuthenticationService authServiceIn, MinecraftSessionService sessionServiceIn, GameProfileRepository profileRepoIn, PlayerProfileCache profileCacheIn)
{
this.serverProxy = proxyIn;
this.authService = authServiceIn;
this.sessionService = sessionServiceIn;
this.profileRepo = profileRepoIn;
this.profileCache = profileCacheIn;
- this.anvilFile = anvilFileIn;
+ //this.anvilFile = anvilFileIn; // CraftBukkit
this.networkSystem = new NetworkSystem(this);
this.commandManager = this.createNewCommandManager();
- this.anvilConverterForAnvilFile = new AnvilSaveConverter(anvilFileIn, dataFixerIn);
+ //this.anvilConverterForAnvilFile = new AnvilSaveConverter(anvilFileIn, dataFixerIn); // CraftBukkit - moved to DedicatedServer.init
this.dataFixer = dataFixerIn;
+ // 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.getProperty("jline.terminal") == 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) {
+ LOG.warn((String) null, ex);
+ }
+ }
+ ColouredConsoleSender.setTerminal(reader.getTerminal());
+ 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
+
public ServerCommandManager createNewCommandManager()
{
return new ServerCommandManager(this);
@@ -217,43 +266,58 @@
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, String generatorOptions)
{
+ // Cauldron start - register vanilla server commands
+ ServerCommandManager vanillaCommandManager = (ServerCommandManager)this.getCommandManager();
+ vanillaCommandManager.registerVanillaCommands();
+ // Cauldron end
this.convertMapIfNeeded(saveName);
this.setUserMessage("menu.loadingLevel");
- ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(saveName, true);
- this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
- WorldInfo worldinfo = isavehandler.loadWorldInfo();
- WorldSettings worldsettings;
+ ISaveHandler iSaveHandler = new AnvilSaveHandler(server.getWorldContainer(),worldNameIn,true, this.dataFixer);
+ this.setResourcePackFromWorld(this.getFolderName(), iSaveHandler);
+ WorldInfo worldinfo = iSaveHandler.loadWorldInfo();
+ // CatServer start
+ if (!GameData.initializedBukkit) { // CatServer - inject bukkit materials before plugins load
+ GameData.injectBlockBukkitMaterials();
+ GameData.injectItemBukkitMaterials();
+ GameData.initializedBukkit = true;
+ }
+ server.loadPlugins();
+ server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
+ // CatServer end
+ WorldSettings worldsettings = new WorldSettings(seed,this.getGameType(),this.canStructuresSpawn(),this.isHardcore(),type);
+ worldsettings.setGeneratorOptions(generatorOptions);
+ if(worldinfo == null){
+ worldinfo = new WorldInfo(worldsettings,worldNameIn);
+ }
+ worldinfo.checkName(worldNameIn);
+ WorldServer overWorld = (WorldServer)(isDemo() ? new DemoWorldServer(this, iSaveHandler, worldinfo, 0, theProfiler).init() : new WorldServer(this, iSaveHandler, worldinfo, 0, theProfiler, org.bukkit.World.Environment.getEnvironment(0), this.server.getGenerator(worldNameIn)).init());
+ this.server.scoreboardManager = new CraftScoreboardManager(this, overWorld.getScoreboard());
- if (worldinfo == null)
+ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs())
{
- if (this.isDemo())
- {
- worldsettings = DemoWorldServer.DEMO_WORLD_SETTINGS;
- }
- else
- {
- worldsettings = new WorldSettings(seed, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), type);
- worldsettings.setGeneratorOptions(generatorOptions);
+ String worldType = "";
+ String name = "";
- if (this.enableBonusChest)
- {
- worldsettings.enableBonusChest();
+ WorldServer world = overWorld;
+ org.bukkit.generator.ChunkGenerator gen = null;
+ org.bukkit.World.Environment env = org.bukkit.World.Environment.getEnvironment(dim);
+ if(dim != 0) {
+ if ((dim == -1) && !this.getAllowNether() || (dim == 1 && !this.server.getAllowEnd())) continue;
+ worldType = env.toString().toLowerCase();
+ name = "DIM" + dim;
+ gen = this.server.getGenerator(name);
+ this.setUserMessage(name);
+ ISaveHandler worldServerMulti = new AnvilSaveHandler(server.getWorldContainer(), name, true, dataFixer);
+ worldinfo = worldServerMulti.loadWorldInfo();
+ if(worldinfo == null){
+ worldinfo = new WorldInfo(worldsettings,name);
}
+ worldinfo.checkName(name);
+ world=new WorldServerMulti(this, worldServerMulti, dim, overWorld, this.theProfiler, worldinfo, env, gen);
}
+ world.initialize(worldsettings);
- worldinfo = new WorldInfo(worldsettings, worldNameIn);
- }
- else
- {
- worldinfo.setWorldName(worldNameIn);
- worldsettings = new WorldSettings(worldinfo);
- }
-
- WorldServer overWorld = (WorldServer)(isDemo() ? new DemoWorldServer(this, isavehandler, worldinfo, 0, theProfiler).init() : new WorldServer(this, isavehandler, worldinfo, 0, theProfiler).init());
- overWorld.initialize(worldsettings);
- for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs())
- {
- WorldServer world = (dim == 0 ? overWorld : (WorldServer)new WorldServerMulti(this, isavehandler, dim, overWorld, theProfiler).init());
+ this.server.getPluginManager().callEvent(new WorldInitEvent(world.getWorld()));
world.addEventListener(new ServerWorldEventHandler(this, world));
if (!this.isSinglePlayer())
@@ -261,44 +325,52 @@
world.getWorldInfo().setGameType(this.getGameType());
}
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world));
- }
+ this.server.getPluginManager().callEvent(new WorldInitEvent(world.getWorld()));
+ getPlayerList().setPlayerManager(worlds.toArray(new WorldServer[worlds.size()]));
- this.playerList.setPlayerManager(new WorldServer[]{ overWorld });
+ }
+ this.playerList.setPlayerManager(this.worldServers);
this.setDifficultyForAllWorlds(this.getDifficulty());
this.initialWorldChunkLoad();
}
public void initialWorldChunkLoad()
{
- int i = 16;
- int j = 4;
- int k = 192;
- int l = 625;
+ //int i = 16;
+ //int j = 4;
+ //int k = 192;
+ //int l = 625;
int i1 = 0;
this.setUserMessage("menu.generatingTerrain");
- int j1 = 0;
- LOG.info("Preparing start region for level 0");
- WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(j1);
- BlockPos blockpos = worldserver.getSpawnPoint();
- long k1 = getCurrentTimeMillis();
-
- for (int l1 = -192; l1 <= 192 && this.isServerRunning(); l1 += 16)
- {
- for (int i2 = -192; i2 <= 192 && this.isServerRunning(); i2 += 16)
+ for(int m = 0; m < worldServers.length; m++){
+ WorldServer worldserver = this.worldServers[m];
+ LOG.info("Preparing start region for level " + m + " (Seed: " + worldserver.getSeed() + ")");
+ if(!worldserver.getWorld().getKeepSpawnInMemory()){
+ continue;
+ }
+ BlockPos blockpos = worldserver.getSpawnPoint();
+ long k1 = getCurrentTimeMillis();
+ i1 = 0;
+ for (int l1 = -192; l1 <= 192 && this.isServerRunning(); l1 += 16)
{
- long j2 = getCurrentTimeMillis();
-
- if (j2 - k1 > 1000L)
+ for (int i2 = -192; i2 <= 192 && this.isServerRunning(); i2 += 16)
{
- this.outputPercentRemaining("Preparing spawn area", i1 * 100 / 625);
- k1 = j2;
- }
+ long j2 = getCurrentTimeMillis();
- ++i1;
- worldserver.getChunkProvider().provideChunk(blockpos.getX() + l1 >> 4, blockpos.getZ() + i2 >> 4);
+ if (j2 - k1 > 1000L)
+ {
+ this.outputPercentRemaining("Preparing spawn area", i1 * 100 / 625);
+ k1 = j2;
+ }
+
+ ++i1;
+ worldserver.getChunkProvider().loadChunk(blockpos.getX() + l1 >> 4, blockpos.getZ() + i2 >> 4);
+ }
}
}
-
+ for(WorldServer worldServer : this.worldServers){
+ this.server.getPluginManager().callEvent(new WorldLoadEvent(worldServer.getWorld()));
+ }
this.clearCurrentTask();
}
@@ -337,81 +409,104 @@
{
this.currentTask = null;
this.percentDone = 0;
+ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit
}
- public void saveAllWorlds(boolean isSilent)
+ public void saveAllWorlds(boolean isSilent) throws MinecraftException
{
- for (WorldServer worldserver : this.worldServers)
- {
+
+ for(int m = 0; m < worlds.size(); m++){
+ WorldServer worldserver = this.worlds.get(m);
if (worldserver != null)
{
if (!isSilent)
{
LOG.info("Saving chunks for level \'{}\'/{}", new Object[] {worldserver.getWorldInfo().getWorldName(), worldserver.provider.getDimensionType().getName()});
}
-
- try
- {
+ try {
worldserver.saveAllChunks(true, (IProgressUpdate)null);
+ worldserver.saveLevel();
+ worldserver.flush();
+ } catch (MinecraftException e){
+
}
- catch (MinecraftException minecraftexception)
- {
- LOG.warn(minecraftexception.getMessage());
- }
+
+ WorldSaveEvent event = new WorldSaveEvent(worldserver.getWorld());
+ this.server.getPluginManager().callEvent(event);
+
}
}
}
- public void stopServer()
+ public void stopServer() throws MinecraftException
{
- LOG.info("Stopping server");
+ if(Loader.instance().hasReachedState(LoaderState.SERVER_STARTED) && !serverStopped){
+ LOG.info("Stopping server");
- if (this.getNetworkSystem() != null)
- {
- this.getNetworkSystem().terminateEndpoints();
- }
+ // CraftBukkit start
+ if (this.server != null)
+ {
+ this.server.disablePlugins();
+ }
+ // CraftBukkit end
+ if (this.getNetworkSystem() != null)
+ {
+ this.getNetworkSystem().terminateEndpoints();
+ }
- if (this.playerList != null)
- {
- LOG.info("Saving players");
- this.playerList.saveAllPlayerData();
- this.playerList.removeAllPlayers();
- }
-
- if (this.worldServers != null)
- {
- LOG.info("Saving worlds");
-
- for (WorldServer worldserver : this.worldServers)
+ if (this.playerList != null)
{
- if (worldserver != null)
+ LOG.info("Saving players");
+ this.playerList.saveAllPlayerData();
+ this.playerList.removeAllPlayers();
+ }
+ try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
+ if (this.worldServers != null)
+ {
+ LOG.info("Saving worlds");
+
+ for (WorldServer worldserver : this.worldServers)
{
- worldserver.disableLevelSaving = false;
+ if (worldserver != null)
+ {
+ worldserver.disableLevelSaving = false;
+ }
}
- }
- this.saveAllWorlds(false);
+ try {
+ this.saveAllWorlds(false);
+ } catch (MinecraftException e) {
+ e.printStackTrace();
+ }
- for (WorldServer worldserver1 : this.worldServers)
- {
- if (worldserver1 != null)
+ for (WorldServer worldserver1 : this.worldServers)
{
- net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver1));
- worldserver1.flush();
+ if (worldserver1 != null)
+ {
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver1));
+ worldserver1.flush();
+ }
}
+
+ WorldServer[] tmp = worldServers;
+ for (WorldServer world : tmp)
+ {
+ net.minecraftforge.common.DimensionManager.setWorld(world.provider.getDimension(), null, this);
+ }
}
- WorldServer[] tmp = worldServers;
- for (WorldServer world : tmp)
+ if (this.usageSnooper.isSnooperRunning())
{
- net.minecraftforge.common.DimensionManager.setWorld(world.provider.getDimension(), null, this);
+ this.usageSnooper.stopSnooper();
}
}
- if (this.usageSnooper.isSnooperRunning())
- {
- this.usageSnooper.stopSnooper();
+ // Spigot start
+ if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
+ LOG.info("Saving usercache.json");
+ this.profileCache.save();
}
+ // Spigot end
}
public boolean isServerRunning()
@@ -436,43 +531,34 @@
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.10.2", 210));
this.applyServerIconToResponse(this.statusResponse);
+ DedicatedServer.allowPlayerLogins = true;
+ Arrays.fill( recentTps, 20 );
+ long lastTick = System.nanoTime(), catchupTime = 0, curTime, wait, tickSection = lastTick;
while (this.serverRunning)
{
long k = getCurrentTimeMillis();
long j = k - this.currentTime;
+ curTime = System.nanoTime();
+ wait = TICK_TIME - (curTime - lastTick) - catchupTime;
- if (j > 2000L && this.currentTime - this.timeOfLastWarning >= 15000L)
- {
- LOG.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(j), Long.valueOf(j / 50L)});
- j = 2000L;
- this.timeOfLastWarning = this.currentTime;
+ if (wait > 0) {
+ Thread.sleep(wait / 1000000);
+ catchupTime = 0;
+ continue;
+ } else {
+ catchupTime = Math.min(1000000000, Math.abs(wait));
}
-
- if (j < 0L)
+ if ( MinecraftServer.currentTick++ % SAMPLE_INTERVAL == 0 )
{
- LOG.warn("Time ran backwards! Did the system time change?");
- j = 0L;
+ double currentTps = 1E9 / ( curTime - tickSection ) * SAMPLE_INTERVAL;
+ recentTps[0] = calcTps( recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min)
+ recentTps[1] = calcTps( recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min)
+ recentTps[2] = calcTps( recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min)
+ tickSection = curTime;
}
-
- i += j;
- this.currentTime = k;
-
- if (this.worldServers[0].areAllPlayersAsleep())
- {
- this.tick();
- i = 0L;
- }
- else
- {
- while (i > 50L)
- {
- i -= 50L;
- this.tick();
- }
- }
-
- Thread.sleep(Math.max(1L, 50L - i));
+ lastTick = curTime;
+ this.tick();
this.serverIsRunning = true;
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopping();
@@ -521,6 +607,7 @@
{
try
{
+ org.spigotmc.WatchdogThread.doStop();
this.stopServer();
this.serverStopped = true;
}
@@ -537,6 +624,10 @@
}
}
+ private double calcTps(double avg, double exp, double tps) {
+ return (avg * exp) + (tps * (1 - exp));
+ }
+
public void applyServerIconToResponse(ServerStatusResponse response)
{
File file1 = this.getFile("server-icon.png");
@@ -596,8 +687,9 @@
{
}
- public void tick()
+ public void tick() throws MinecraftException
{
+ SpigotTimings.serverTickTimer.startTiming();
long i = System.nanoTime();
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreServerTick();
++this.tickCounter;
@@ -629,12 +721,18 @@
this.statusResponse.invalidateJson();
}
- if (this.tickCounter % 900 == 0)
+ if ((autosavePeriod > 0) && ((this.tickCounter % autosavePeriod) == 0)) //CatServer
{
+ SpigotTimings.worldSaveTimer.startTiming();
this.theProfiler.startSection("save");
this.playerList.saveAllPlayerData();
- this.saveAllWorlds(true);
+ try {
+ this.saveAllWorlds(true);
+ } catch (MinecraftException e) {
+ e.printStackTrace();
+ }
this.theProfiler.endSection();
+ SpigotTimings.worldSaveTimer.stopTiming();
}
this.theProfiler.startSection("tallying");
@@ -655,23 +753,55 @@
this.theProfiler.endSection();
this.theProfiler.endSection();
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostServerTick();
+ org.spigotmc.WatchdogThread.tick(); // Spigot
+ SpigotTimings.serverTickTimer.stopTiming();
+ org.spigotmc.CustomTimingsHandler.tick();
}
public void updateTimeLightAndEntities()
{
+ SpigotTimings.schedulerTimer.startTiming();
+ this.server.getScheduler().mainThreadHeartbeat(this.tickCounter);
+ SpigotTimings.schedulerTimer.stopTiming();
this.theProfiler.startSection("jobs");
- synchronized (this.futureTaskQueue)
- {
- while (!this.futureTaskQueue.isEmpty())
- {
- Util.runTask((FutureTask)this.futureTaskQueue.poll(), LOG);
- }
+ // Spigot start
+ FutureTask<?> entry;
+ int count = this.futureTaskQueue.size();
+ while (count-- > 0 && (entry = this.futureTaskQueue.poll()) != null) {
+ Util.runTask(entry, MinecraftServer.LOG);
}
+ // Spigot end
this.theProfiler.endStartSection("levels");
+
net.minecraftforge.common.chunkio.ChunkIOExecutor.tick();
+ // CraftBukkit start
+ SpigotTimings.processQueueTimer.startTiming();
+ // Run tasks that are waiting on processing
+ while (!processQueue.isEmpty()) {
+ processQueue.remove().run();
+ }
+ SpigotTimings.processQueueTimer.stopTiming();
+
+ SpigotTimings.chunkIOTickTimer.startTiming();
+ org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick();
+ SpigotTimings.chunkIOTickTimer.stopTiming();
+ // CraftBukkit end
+
+ SpigotTimings.timeUpdateTimer.startTiming();
+ // Send time updates to everyone, it will get the right time from the world the player is in.
+ if (this.tickCounter % 20 == 0)
+ {
+ for (int i = 0; i < this.getPlayerList().playerEntityList.size(); i++)
+ {
+ EntityPlayerMP entityplayer = (EntityPlayerMP) this.getPlayerList().playerEntityList.get(i);
+ entityplayer.connection.sendPacket(new SPacketTimeUpdate(entityplayer.worldObj.getTotalWorldTime(), entityplayer.getPlayerTime(), entityplayer.worldObj.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time
+ }
+ }
+ SpigotTimings.timeUpdateTimer.stopTiming();
+
Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.tickCounter % 200 == 0);
for (int x = 0; x < ids.length; x++)
{
@@ -682,20 +812,22 @@
{
WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
this.theProfiler.startSection(worldserver.getWorldInfo().getWorldName());
-
+ /* Drop global time updates
if (this.tickCounter % 20 == 0)
{
this.theProfiler.startSection("timeSync");
this.playerList.sendPacketToAllPlayersInDimension(new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.provider.getDimension());
this.theProfiler.endSection();
}
-
+ // CraftBukkit end */
this.theProfiler.startSection("tick");
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreWorldTick(worldserver);
try
{
+ worldserver.timings.doTick.startTiming();
worldserver.tick();
+ worldserver.timings.doTick.stopTiming();
}
catch (Throwable throwable1)
{
@@ -706,7 +838,9 @@
try
{
+ worldserver.timings.tickEntities.startTiming();
worldserver.updateEntities();
+ worldserver.timings.tickEntities.stopTiming();
}
catch (Throwable throwable)
{
@@ -718,7 +852,9 @@
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostWorldTick(worldserver);
this.theProfiler.endSection();
this.theProfiler.startSection("tracker");
+ worldserver.timings.tracker.startTiming();
worldserver.getEntityTracker().updateTrackedEntities();
+ worldserver.timings.tracker.stopTiming();
this.theProfiler.endSection();
this.theProfiler.endSection();
}
@@ -729,15 +865,21 @@
this.theProfiler.endStartSection("dim_unloading");
net.minecraftforge.common.DimensionManager.unloadWorlds(worldTickTimes);
this.theProfiler.endStartSection("connection");
+ SpigotTimings.connectionTimer.startTiming();
this.getNetworkSystem().networkTick();
+ SpigotTimings.connectionTimer.stopTiming();
this.theProfiler.endStartSection("players");
+ SpigotTimings.playerListTimer.startTiming();
this.playerList.onTick();
+ SpigotTimings.playerListTimer.stopTiming();
this.theProfiler.endStartSection("tickables");
+ SpigotTimings.tickablesTimer.startTiming();
for (int k = 0; k < this.tickables.size(); ++k)
{
((ITickable)this.tickables.get(k)).update();
}
+ SpigotTimings.tickablesTimer.stopTiming();
this.theProfiler.endSection();
}
@@ -831,56 +973,12 @@
public List<String> getTabCompletions(ICommandSender sender, String input, @Nullable BlockPos pos, boolean hasTargetBlock)
{
- List<String> list = Lists.<String>newArrayList();
- boolean flag = input.startsWith("/");
-
- if (flag)
- {
- input = input.substring(1);
- }
-
- if (!flag && !hasTargetBlock)
- {
- String[] astring = input.split(" ", -1);
- String s2 = astring[astring.length - 1];
-
- for (String s1 : this.playerList.getAllUsernames())
- {
- if (CommandBase.doesStringStartWith(s2, s1))
- {
- list.add(s1);
- }
- }
-
- return list;
- }
- else
- {
- boolean flag1 = !input.contains(" ");
- List<String> list1 = this.commandManager.getTabCompletionOptions(sender, input, pos);
-
- if (!list1.isEmpty())
- {
- for (String s : list1)
- {
- if (flag1)
- {
- list.add("/" + s);
- }
- else
- {
- list.add(s);
- }
- }
- }
-
- return list;
- }
+ return server.tabComplete(sender, input, pos);
}
public boolean isAnvilFileSet()
{
- return this.anvilFile != null;
+ return true; // CraftBukkit
}
public String getName()
@@ -1320,6 +1418,13 @@
{
return this;
}
+
+ // CraftBukkit start
+ @Deprecated
+ public static MinecraftServer getServerInst() {
+ return (Bukkit.getServer() instanceof CraftServer) ? ((CraftServer) Bukkit.getServer()).getServer() : null;
+ }
+ // CraftBukkit end
public int getMaxWorldSize()
{
@@ -1334,11 +1439,10 @@
{
ListenableFutureTask<V> listenablefuturetask = ListenableFutureTask.<V>create(callable);
- synchronized (this.futureTaskQueue)
- {
- this.futureTaskQueue.add(listenablefuturetask);
- return listenablefuturetask;
- }
+ // Spigot start
+ this.futureTaskQueue.add(listenablefuturetask);
+ return listenablefuturetask;
+ // Spigot end
}
else
{
@@ -1400,10 +1504,14 @@
@SideOnly(Side.SERVER)
public static void main(String[] p_main_0_)
{
+ OptionSet options = org.bukkit.craftbukkit.Main.main(p_main_0_);
+ if(options == null)
+ return;
Bootstrap.register();
try
{
+ /*
boolean flag = true;
String s = null;
String s1 = ".";
@@ -1466,14 +1574,19 @@
{
++j;
}
+ }*/
+
+ if (options.has("server-config-dir")) {
+ MinecraftServer.serverConfigDir = (File) options.valueOf("server-config-dir");
}
-
YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
- PlayerProfileCache playerprofilecache = new PlayerProfileCache(gameprofilerepository, new File(s1, USER_CACHE_FILE.getName()));
- final DedicatedServer dedicatedserver = new DedicatedServer(new File(s1), DataFixesManager.createFixer(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, playerprofilecache);
+ PlayerProfileCache playerprofilecache = new PlayerProfileCache(gameprofilerepository, new File(MinecraftServer.serverConfigDir, USER_CACHE_FILE.getName()));
+ //final DedicatedServer dedicatedserver = new DedicatedServer(new File(s1), DataFixesManager.createFixer(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, playerprofilecache);
+ final DedicatedServer dedicatedserver = new DedicatedServer(options, DataFixesManager.createFixer(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, playerprofilecache);
+ /*
if (s != null)
{
dedicatedserver.setServerOwner(s);
@@ -1512,6 +1625,24 @@
dedicatedserver.stopServer();
}
});
+ */
+ if (options.has("port")) {
+ int port = (Integer) options.valueOf("port");
+ if (port > 0) {
+ dedicatedserver.setServerPort(port);
+ }
+ }
+
+ if (options.has("universe")) {
+ dedicatedserver.anvilFile = (File) options.valueOf("universe");
+ }
+
+ if (options.has("world")) {
+ dedicatedserver.setWorldName((String) options.valueOf("world"));
+ }
+
+ dedicatedserver.primaryThread.start();
+ // CraftBukkit end
}
catch (Exception exception)
{
@@ -1528,7 +1659,8 @@
@SideOnly(Side.SERVER)
public boolean isDebuggingEnabled()
{
- return false;
+ //return false;
+ return this.getPropertyManager().getBooleanProperty("debug", false); // CraftBukkit - don't hardcode
}
@SideOnly(Side.SERVER)