forked from xjboss/KCauldronX
1219 lines
51 KiB
Diff
1219 lines
51 KiB
Diff
--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java
|
|
+++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java
|
|
@@ -16,6 +16,7 @@
|
|
import io.netty.buffer.ByteBufOutputStream;
|
|
import io.netty.buffer.Unpooled;
|
|
import io.netty.handler.codec.base64.Base64;
|
|
+
|
|
import java.awt.GraphicsEnvironment;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.File;
|
|
@@ -33,7 +34,10 @@
|
|
import java.util.Random;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.Callable;
|
|
+import java.util.logging.Level;
|
|
+
|
|
import javax.imageio.ImageIO;
|
|
+
|
|
import net.minecraft.command.CommandBase;
|
|
import net.minecraft.command.ICommandManager;
|
|
import net.minecraft.command.ICommandSender;
|
|
@@ -50,6 +54,7 @@
|
|
import net.minecraft.profiler.PlayerUsageSnooper;
|
|
import net.minecraft.profiler.Profiler;
|
|
import net.minecraft.server.dedicated.DedicatedServer;
|
|
+import net.minecraft.server.dedicated.PropertyManager;
|
|
import net.minecraft.server.gui.IUpdatePlayerListBox;
|
|
import net.minecraft.server.management.PlayerProfileCache;
|
|
import net.minecraft.server.management.ServerConfigurationManager;
|
|
@@ -72,6 +77,7 @@
|
|
import net.minecraft.world.storage.ISaveFormat;
|
|
import net.minecraft.world.storage.ISaveHandler;
|
|
import net.minecraft.world.storage.WorldInfo;
|
|
+
|
|
import org.apache.commons.lang3.Validate;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
@@ -80,18 +86,54 @@
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.event.world.WorldEvent;
|
|
|
|
+
|
|
+// CraftBukkit start
|
|
+import java.io.IOException;
|
|
+
|
|
+import jline.console.ConsoleReader;
|
|
+import joptsimple.OptionSet;
|
|
+import net.minecraft.world.chunk.storage.AnvilSaveHandler;
|
|
+
|
|
+import org.bukkit.World.Environment;
|
|
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
|
|
+import org.bukkit.craftbukkit.util.Waitable;
|
|
+import org.bukkit.event.server.RemoteServerCommandEvent;
|
|
+import org.bukkit.event.world.WorldSaveEvent;
|
|
+
|
|
+// CraftBukkit end
|
|
+// Cauldron start
|
|
+import java.util.Map;
|
|
+import java.lang.reflect.Constructor;
|
|
+
|
|
+import joptsimple.OptionParser;
|
|
+import kcauldron.KCauldronConfig;
|
|
+import cpw.mods.fml.common.asm.transformers.SideTransformer;
|
|
+import net.minecraft.command.ServerCommand;
|
|
+import net.minecraft.tileentity.TileEntity;
|
|
+import net.minecraft.world.WorldProvider;
|
|
+import net.minecraftforge.cauldron.CauldronUtils;
|
|
+import net.minecraftforge.cauldron.configuration.CauldronConfig;
|
|
+import net.minecraftforge.cauldron.configuration.TileEntityConfig;
|
|
+import net.minecraftforge.common.util.EnumHelper;
|
|
+
|
|
+import org.bukkit.configuration.ConfigurationSection;
|
|
+import org.bukkit.configuration.file.YamlConfiguration;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+import org.bukkit.craftbukkit.block.CraftBlock;
|
|
+// Cauldron end
|
|
+
|
|
public abstract class MinecraftServer implements ICommandSender, Runnable, IPlayerUsage
|
|
{
|
|
private static final Logger logger = LogManager.getLogger();
|
|
public static final File field_152367_a = new File("usercache.json");
|
|
private static MinecraftServer mcServer;
|
|
- private final ISaveFormat anvilConverterForAnvilFile;
|
|
+ public ISaveFormat anvilConverterForAnvilFile; // CraftBukkit - private final -> public
|
|
private final PlayerUsageSnooper usageSnooper = new PlayerUsageSnooper("server", this, getSystemTimeMillis());
|
|
- private final File anvilFile;
|
|
+ public File anvilFile; // CraftBukkit - private final -> public
|
|
private final List tickables = new ArrayList();
|
|
private final ICommandManager commandManager;
|
|
public final Profiler theProfiler = new Profiler();
|
|
- private final NetworkSystem field_147144_o;
|
|
+ private NetworkSystem field_147144_o; // Spigot
|
|
private final ServerStatusResponse field_147147_p = new ServerStatusResponse();
|
|
private final Random field_147146_q = new Random();
|
|
@SideOnly(Side.SERVER)
|
|
@@ -135,8 +177,40 @@
|
|
private long field_147142_T = 0L;
|
|
private final GameProfileRepository field_152365_W;
|
|
private final PlayerProfileCache field_152366_X;
|
|
+ // CraftBukkit start
|
|
+ public List<WorldServer> worlds = new ArrayList<WorldServer>();
|
|
+ public org.bukkit.craftbukkit.CraftServer server;
|
|
+ public static OptionSet options; // Cauldron
|
|
+ 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
|
|
+ // Spigot start
|
|
+ private static final int TPS = 20;
|
|
+ private static final int TICK_TIME = 1000000000 / TPS;
|
|
+ public final double[] recentTps = new double[ 3 ];
|
|
+ // Spigot end
|
|
+ // Cauldron start
|
|
+ public static CauldronConfig cauldronConfig;
|
|
+ public static KCauldronConfig kcauldronConfig;
|
|
+ public static TileEntityConfig tileEntityConfig;
|
|
+ public static YamlConfiguration configuration;
|
|
+ public static YamlConfiguration commandsConfiguration;
|
|
+ public static File configFile;
|
|
+ public static File commandFile;
|
|
+ public static double currentTps = 0;
|
|
+ public static boolean useJline = true;
|
|
+ public static boolean useConsole = true;
|
|
+ public static boolean callingForgeTick = false;
|
|
+ public static List<Class<? extends TileEntity>> bannedTileEntityUpdates = new ArrayList<Class<? extends TileEntity>>();
|
|
+ // Cauldron end
|
|
private static final String __OBFID = "CL_00001462";
|
|
|
|
+ // Cauldron start - IntegratedServer requires this
|
|
public MinecraftServer(File p_i45281_1_, Proxy p_i45281_2_)
|
|
{
|
|
this.field_152366_X = new PlayerProfileCache(this, field_152367_a);
|
|
@@ -149,10 +223,70 @@
|
|
this.field_152364_T = new YggdrasilAuthenticationService(p_i45281_2_, UUID.randomUUID().toString());
|
|
this.field_147143_S = this.field_152364_T.createMinecraftSessionService();
|
|
this.field_152365_W = this.field_152364_T.createProfileRepository();
|
|
+ this.primaryThread = new Thread(this, "Server thread"); // CraftBukkit
|
|
+ kcauldronConfig = new KCauldronConfig();
|
|
+ cauldronConfig = new CauldronConfig("cauldron.yml", "cauldron");
|
|
+ tileEntityConfig = new TileEntityConfig("tileentities.yml", "cauldron_te");
|
|
}
|
|
+ // Cauldron end
|
|
|
|
- protected abstract boolean startServer() throws IOException;
|
|
+ public MinecraftServer(OptionSet options, Proxy proxy) // CraftBukkit - signature file -> OptionSet
|
|
+ {
|
|
+ this.field_152366_X = new PlayerProfileCache(this, field_152367_a);
|
|
+ mcServer = this;
|
|
+ this.serverProxy = proxy;
|
|
+ // this.anvilFile = p_i45281_1_; // CraftBukkit
|
|
+ // this.field_147144_o = new NetworkSystem(this); // Spigot
|
|
+ this.commandManager = new ServerCommandManager();
|
|
+ // this.anvilConverterForAnvilFile = new AnvilSaveConverter(p_i45281_1_); // CraftBukkit - moved to DedicatedServer.init
|
|
+ this.field_152364_T = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString());
|
|
+ this.field_147143_S = this.field_152364_T.createMinecraftSessionService();
|
|
+ this.field_152365_W = this.field_152364_T.createProfileRepository();
|
|
+ // Cauldron start
|
|
+ kcauldronConfig = new KCauldronConfig();
|
|
+ cauldronConfig = new CauldronConfig("cauldron.yml", "cauldron");
|
|
+ tileEntityConfig = new TileEntityConfig("tileentities.yml", "cauldron_te");
|
|
+ // Cauldron end
|
|
+ // 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");
|
|
+ this.useJline = false; // Cauldron
|
|
+ }
|
|
|
|
+ try
|
|
+ {
|
|
+ this.reader = new ConsoleReader(System.in, System.out);
|
|
+ this.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");
|
|
+ this.useJline = false; // Cauldron
|
|
+ this.reader = new ConsoleReader(System.in, System.out);
|
|
+ this.reader.setExpandEvents(false);
|
|
+ }
|
|
+ catch (IOException ex)
|
|
+ {
|
|
+ logger.warn((String) null, ex);
|
|
+ }
|
|
+ }
|
|
+ net.minecraftforge.cauldron.CauldronHooks.enableThreadContentionMonitoring();
|
|
+ Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
|
|
+ primaryThread = new Thread(this, "Server thread"); // Moved from main
|
|
+ }
|
|
+
|
|
+ public abstract PropertyManager getPropertyManager();
|
|
+ // CraftBukkit end
|
|
+
|
|
+ protected abstract boolean startServer() throws java.net.UnknownHostException; // CraftBukkit - throws UnknownHostException
|
|
+
|
|
protected void convertMapIfNeeded(String p_71237_1_)
|
|
{
|
|
if (this.getActiveAnvilConverter().isOldMapFormat(p_71237_1_))
|
|
@@ -172,6 +306,7 @@
|
|
MinecraftServer.logger.info("Converting... " + p_73718_1_ + "%");
|
|
}
|
|
}
|
|
+
|
|
@SideOnly(Side.CLIENT)
|
|
public void resetProgressAndMessage(String p_73721_1_) {}
|
|
@SideOnly(Side.CLIENT)
|
|
@@ -195,10 +330,17 @@
|
|
|
|
protected void loadAllWorlds(String p_71247_1_, String p_71247_2_, long p_71247_3_, WorldType p_71247_5_, String p_71247_6_)
|
|
{
|
|
+ // Cauldron start - register vanilla server commands
|
|
+ ServerCommandManager vanillaCommandManager = (ServerCommandManager)this.getCommandManager();
|
|
+ vanillaCommandManager.registerVanillaCommands();
|
|
+ // Cauldron end
|
|
this.convertMapIfNeeded(p_71247_1_);
|
|
this.setUserMessage("menu.loadingLevel");
|
|
- ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(p_71247_1_, true);
|
|
- WorldInfo worldinfo = isavehandler.loadWorldInfo();
|
|
+ // Cauldron start - SaveHandler/WorldInfo below are not used and must be disabled to prevent FML receiving different handlers for overworld
|
|
+ //ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(p_71247_1_, true);
|
|
+ //WorldInfo worldinfo = isavehandler.loadWorldInfo();
|
|
+ // Cauldron end
|
|
+ /* CraftBukkit start - Removed worldsettings
|
|
WorldSettings worldsettings;
|
|
|
|
if (worldinfo == null)
|
|
@@ -215,11 +357,79 @@
|
|
{
|
|
worldsettings.enableBonusChest();
|
|
}
|
|
+ // */
|
|
|
|
- WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, isavehandler, p_71247_2_, 0, theProfiler) : new WorldServer(this, isavehandler, p_71247_2_, 0, worldsettings, theProfiler));
|
|
- for (int dim : DimensionManager.getStaticDimensionIDs())
|
|
+ WorldSettings worldsettings = new WorldSettings(p_71247_3_, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), p_71247_5_);
|
|
+ worldsettings.func_82750_a(p_71247_6_);
|
|
+ WorldServer world;
|
|
+
|
|
+ // Cauldron - overworld generator is handled in World after plugins load
|
|
+ WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, new AnvilSaveHandler(server.getWorldContainer(), p_71247_2_, true), p_71247_2_, 0, theProfiler) : new WorldServer(this, new AnvilSaveHandler(server.getWorldContainer(), p_71247_2_, true), p_71247_2_, 0, worldsettings, theProfiler, Environment.getEnvironment(0), null));
|
|
+
|
|
+ for (int dimension : DimensionManager.getStaticDimensionIDs())
|
|
{
|
|
- WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, isavehandler, p_71247_2_, dim, worldsettings, overWorld, theProfiler));
|
|
+ String worldType = "";
|
|
+ String name = "";
|
|
+ String oldName = "";
|
|
+ org.bukkit.generator.ChunkGenerator gen = null;
|
|
+ // Cauldron start
|
|
+ Environment env = Environment.getEnvironment(dimension);
|
|
+ if (dimension != 0)
|
|
+ {
|
|
+ if ((dimension == -1 && !this.getAllowNether()) || (dimension == 1 && !this.server.getAllowEnd()))
|
|
+ continue;
|
|
+
|
|
+ if (env == null)
|
|
+ {
|
|
+ WorldProvider provider = WorldProvider.getProviderForDimension(dimension);
|
|
+ worldType = provider.getClass().getSimpleName().toLowerCase();
|
|
+ worldType = worldType.replace("worldprovider", "");
|
|
+ oldName = "world_" + worldType.toLowerCase();
|
|
+ worldType = worldType.replace("provider", "");
|
|
+ env = Environment.getEnvironment(DimensionManager.getProviderType(provider.getClass()));
|
|
+ name = provider.getSaveFolder();
|
|
+ if (name == null) name = "DIM0";
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ worldType = env.toString().toLowerCase();
|
|
+ name = "DIM" + dimension;
|
|
+ oldName = p_71247_1_ + "_" + worldType;
|
|
+ oldName = oldName.replaceAll(" ", "_");
|
|
+ }
|
|
+
|
|
+ // check if the world is enabled or not
|
|
+ if (!configuration.isBoolean("world-settings." + worldType + ".enabled")) {
|
|
+ configuration.set("world-settings." + worldType + ".enabled", true);
|
|
+ }
|
|
+ boolean enabled = configuration.getBoolean("world-settings." + worldType + ".enabled");
|
|
+ try {
|
|
+ configuration.save(MinecraftServer.configFile);
|
|
+ } catch (IOException e) {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ if (!enabled)
|
|
+ continue;
|
|
+ // end world enabled check
|
|
+
|
|
+ gen = this.server.getGenerator(name);
|
|
+ worldsettings = new WorldSettings(p_71247_3_, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), p_71247_5_);
|
|
+ worldsettings.func_82750_a(p_71247_6_);
|
|
+
|
|
+ CauldronUtils.migrateWorlds(worldType, oldName, p_71247_1_, name);
|
|
+
|
|
+ this.setUserMessage(name);
|
|
+ }
|
|
+
|
|
+ world = (dimension == 0 ? overWorld : new WorldServerMulti(this, new AnvilSaveHandler(server.getWorldContainer(), name, true), name, dimension, worldsettings, overWorld, this.theProfiler, env, gen));
|
|
+ // Cauldron end
|
|
+ if (gen != null)
|
|
+ {
|
|
+ world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld()));
|
|
+ }
|
|
+
|
|
+ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard());
|
|
+ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
|
|
world.addWorldAccess(new WorldManager(this, world));
|
|
|
|
if (!this.isSinglePlayer())
|
|
@@ -227,12 +437,14 @@
|
|
world.getWorldInfo().setGameType(this.getGameType());
|
|
}
|
|
|
|
- MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
|
|
+ this.serverConfigManager.setPlayerManager(this.worlds.toArray(new WorldServer[this.worlds.size()]));
|
|
+ // CraftBukkit end
|
|
+ MinecraftForge.EVENT_BUS.post(new WorldEvent.Load((World)world)); // Forge
|
|
}
|
|
-
|
|
- this.serverConfigManager.setPlayerManager(new WorldServer[]{ overWorld });
|
|
this.func_147139_a(this.func_147135_j());
|
|
this.initialWorldChunkLoad();
|
|
+ CraftBlock.dumpMaterials();
|
|
+ // Cauldron end
|
|
}
|
|
|
|
protected void initialWorldChunkLoad()
|
|
@@ -244,9 +456,12 @@
|
|
int i = 0;
|
|
this.setUserMessage("menu.generatingTerrain");
|
|
byte b0 = 0;
|
|
+ // Cauldron start - we now handle CraftBukkit's keepSpawnInMemory logic in DimensionManager. Prevents crashes with mods such as DivineRPG and speeds up server startup time by a ton.
|
|
logger.info("Preparing start region for level " + b0);
|
|
WorldServer worldserver = this.worldServers[b0];
|
|
ChunkCoordinates chunkcoordinates = worldserver.getSpawnPoint();
|
|
+ boolean before = worldserver.theChunkProviderServer.loadChunkOnProvideRequest;
|
|
+ worldserver.theChunkProviderServer.loadChunkOnProvideRequest = true;
|
|
long j = getSystemTimeMillis();
|
|
|
|
for (int k = -192; k <= 192 && this.isServerRunning(); k += 16)
|
|
@@ -265,7 +480,8 @@
|
|
worldserver.theChunkProviderServer.loadChunk(chunkcoordinates.posX + k >> 4, chunkcoordinates.posZ + l >> 4);
|
|
}
|
|
}
|
|
-
|
|
+ worldserver.theChunkProviderServer.loadChunkOnProvideRequest = before;
|
|
+ // Cauldron end
|
|
this.clearCurrentTask();
|
|
}
|
|
|
|
@@ -292,19 +508,17 @@
|
|
{
|
|
this.currentTask = null;
|
|
this.percentDone = 0;
|
|
+ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit
|
|
}
|
|
|
|
- protected void saveAllWorlds(boolean p_71267_1_)
|
|
+ protected void saveAllWorlds(boolean p_71267_1_) throws MinecraftException // CraftBukkit - added throws
|
|
{
|
|
if (!this.worldIsBeingDeleted)
|
|
{
|
|
- WorldServer[] aworldserver = this.worldServers;
|
|
- if (aworldserver == null) return; //Forge: Just in case, NPE protection as it has been encountered.
|
|
- int i = aworldserver.length;
|
|
-
|
|
- for (int j = 0; j < i; ++j)
|
|
+ // CraftBukkit start
|
|
+ for (int j = 0; j < this.worlds.size(); ++j)
|
|
{
|
|
- WorldServer worldserver = aworldserver[j];
|
|
+ WorldServer worldserver = this.worlds.get(j);
|
|
|
|
if (worldserver != null)
|
|
{
|
|
@@ -313,25 +527,41 @@
|
|
logger.info("Saving chunks for level \'" + worldserver.getWorldInfo().getWorldName() + "\'/" + worldserver.provider.getDimensionName());
|
|
}
|
|
|
|
- try
|
|
+ worldserver.saveAllChunks(true, (IProgressUpdate) null);
|
|
+ worldserver.flush();
|
|
+ WorldSaveEvent event = new WorldSaveEvent(worldserver.getWorld());
|
|
+ this.server.getPluginManager().callEvent(event);
|
|
+ // Cauldron start - save world configs
|
|
+ if (worldserver.cauldronConfig != null)
|
|
{
|
|
- worldserver.saveAllChunks(true, (IProgressUpdate)null);
|
|
+ worldserver.cauldronConfig.save();
|
|
}
|
|
- catch (MinecraftException minecraftexception)
|
|
+ if (worldserver.tileentityConfig != null)
|
|
{
|
|
- logger.warn(minecraftexception.getMessage());
|
|
+ worldserver.tileentityConfig.save();
|
|
}
|
|
+ // Cauldron end
|
|
}
|
|
}
|
|
+
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
- public void stopServer()
|
|
+ public void stopServer() throws MinecraftException // CraftBukkit - added throws
|
|
{
|
|
if (!this.worldIsBeingDeleted && Loader.instance().hasReachedState(LoaderState.SERVER_STARTED) && !serverStopped) // make sure the save is valid and we don't save twice
|
|
{
|
|
logger.info("Stopping server");
|
|
|
|
+ // CraftBukkit start
|
|
+ if (this.server != null)
|
|
+ {
|
|
+ this.server.disablePlugins();
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
+
|
|
if (this.func_147137_ag() != null)
|
|
{
|
|
this.func_147137_ag().terminateEndpoints();
|
|
@@ -347,7 +577,14 @@
|
|
if (this.worldServers != null)
|
|
{
|
|
logger.info("Saving worlds");
|
|
- this.saveAllWorlds(false);
|
|
+ try
|
|
+ {
|
|
+ this.saveAllWorlds(false);
|
|
+ }
|
|
+ catch (MinecraftException e)
|
|
+ {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
|
|
for (int i = 0; i < this.worldServers.length; ++i)
|
|
{
|
|
@@ -380,6 +617,13 @@
|
|
this.serverRunning = false;
|
|
}
|
|
|
|
+ // Spigot Start
|
|
+ private static double calcTps(double avg, double exp, double tps)
|
|
+ {
|
|
+ return (avg * exp) + (tps * (1 - exp));
|
|
+ }
|
|
+ // Spigot End
|
|
+
|
|
public void run()
|
|
{
|
|
try
|
|
@@ -392,45 +636,41 @@
|
|
this.field_147147_p.func_151315_a(new ChatComponentText(this.motd));
|
|
this.field_147147_p.func_151321_a(new ServerStatusResponse.MinecraftProtocolVersionIdentifier("1.7.10", 5));
|
|
this.func_147138_a(this.field_147147_p);
|
|
+ DedicatedServer.allowPlayerLogins = true; // Cauldron - server is ready, allow player logins
|
|
+ // Spigot start
|
|
+ Arrays.fill(recentTps, 20);
|
|
+ long lastTick = 0, catchupTime = 0, curTime, wait;
|
|
|
|
while (this.serverRunning)
|
|
{
|
|
- long j = getSystemTimeMillis();
|
|
- long k = j - i;
|
|
+ curTime = System.nanoTime();
|
|
+ wait = TICK_TIME - (curTime - lastTick) - catchupTime;
|
|
|
|
- if (k > 2000L && i - this.timeOfLastWarning >= 15000L)
|
|
+ if (wait > 0)
|
|
{
|
|
- 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.timeOfLastWarning = i;
|
|
+ Thread.sleep(wait / 1000000);
|
|
+ catchupTime = 0;
|
|
+ continue;
|
|
}
|
|
-
|
|
- if (k < 0L)
|
|
+ else
|
|
{
|
|
- logger.warn("Time ran backwards! Did the system time change?");
|
|
- k = 0L;
|
|
+ catchupTime = Math.min(1000000000, Math.abs(wait));
|
|
}
|
|
|
|
- l += k;
|
|
- i = j;
|
|
-
|
|
- if (this.worldServers[0].areAllPlayersAsleep())
|
|
+ if (MinecraftServer.currentTick++ % 100 == 0)
|
|
{
|
|
- this.tick();
|
|
- l = 0L;
|
|
+ currentTps = 1E9 / (curTime - lastTick);
|
|
+ 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)
|
|
}
|
|
- else
|
|
- {
|
|
- while (l > 50L)
|
|
- {
|
|
- l -= 50L;
|
|
- this.tick();
|
|
- }
|
|
- }
|
|
|
|
- Thread.sleep(Math.max(1L, 50L - l));
|
|
+ lastTick = curTime;
|
|
+ this.tick();
|
|
this.serverIsRunning = true;
|
|
}
|
|
+
|
|
+ // Spigot end
|
|
FMLCommonHandler.instance().handleServerStopping();
|
|
FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
|
|
}
|
|
@@ -448,6 +688,14 @@
|
|
catch (Throwable throwable1)
|
|
{
|
|
logger.error("Encountered an unexpected exception", throwable1);
|
|
+
|
|
+ // Spigot Start
|
|
+ if (throwable1.getCause() != null)
|
|
+ {
|
|
+ logger.error("\tCause of unexpected exception was", throwable1.getCause());
|
|
+ }
|
|
+
|
|
+ // Spigot End
|
|
CrashReport crashreport = null;
|
|
|
|
if (throwable1 instanceof ReportedException)
|
|
@@ -477,6 +725,7 @@
|
|
{
|
|
try
|
|
{
|
|
+ org.spigotmc.WatchdogThread.doStop(); // Spigot
|
|
this.stopServer();
|
|
this.serverStopped = true;
|
|
}
|
|
@@ -486,6 +735,16 @@
|
|
}
|
|
finally
|
|
{
|
|
+ // CraftBukkit start - Restore terminal to original settings
|
|
+ try
|
|
+ {
|
|
+ this.reader.getTerminal().restore();
|
|
+ }
|
|
+ catch (Exception e)
|
|
+ {
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
FMLCommonHandler.instance().handleServerStopped();
|
|
this.serverStopped = true;
|
|
this.systemExitNow();
|
|
@@ -532,8 +791,11 @@
|
|
|
|
public void tick()
|
|
{
|
|
+ SpigotTimings.serverTickTimer.startTiming(); // Spigot
|
|
long i = System.nanoTime();
|
|
+ callingForgeTick = true; // Cauldron start - handle loadOnProviderRequests during forge tick event
|
|
FMLCommonHandler.instance().onPreServerTick();
|
|
+ callingForgeTick = false; // Cauldron end
|
|
++this.tickCounter;
|
|
|
|
if (this.startProfiling)
|
|
@@ -562,12 +824,21 @@
|
|
this.field_147147_p.func_151318_b().func_151330_a(agameprofile);
|
|
}
|
|
|
|
- if (this.tickCounter % 900 == 0)
|
|
+ if ((this.autosavePeriod > 0) && ((this.tickCounter % this.autosavePeriod) == 0)) // CraftBukkit
|
|
{
|
|
+ SpigotTimings.worldSaveTimer.startTiming(); // Spigot
|
|
this.theProfiler.startSection("save");
|
|
this.serverConfigManager.saveAllPlayerData();
|
|
- this.saveAllWorlds(true);
|
|
+ try
|
|
+ {
|
|
+ this.saveAllWorlds(true);
|
|
+ }
|
|
+ catch (MinecraftException e)
|
|
+ {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
this.theProfiler.endSection();
|
|
+ SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
|
|
}
|
|
|
|
this.theProfiler.startSection("tallying");
|
|
@@ -575,25 +846,57 @@
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.startSection("snooper");
|
|
|
|
- if (!this.usageSnooper.isSnooperRunning() && this.tickCounter > 100)
|
|
+ if (isSnooperEnabled() && !this.usageSnooper.isSnooperRunning() && this.tickCounter > 100) // Spigot
|
|
{
|
|
this.usageSnooper.startSnooper();
|
|
}
|
|
|
|
- if (this.tickCounter % 6000 == 0)
|
|
+ if (isSnooperEnabled() && this.tickCounter % 6000 == 0) // Spigot
|
|
{
|
|
this.usageSnooper.addMemoryStatsToSnooper();
|
|
}
|
|
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.endSection();
|
|
+ callingForgeTick = true; // Cauldron start - handle loadOnProviderRequests during forge tick event
|
|
FMLCommonHandler.instance().onPostServerTick();
|
|
+ callingForgeTick = false; // Cauldron end
|
|
+ SpigotTimings.serverTickTimer.stopTiming(); // Spigot
|
|
+ org.spigotmc.CustomTimingsHandler.tick(); // Spigot
|
|
}
|
|
|
|
public void updateTimeLightAndEntities()
|
|
{
|
|
this.theProfiler.startSection("levels");
|
|
+ SpigotTimings.schedulerTimer.startTiming(); // Spigot
|
|
+ // CraftBukkit start
|
|
+ this.server.getScheduler().mainThreadHeartbeat(this.tickCounter);
|
|
+ SpigotTimings.schedulerTimer.stopTiming(); // Spigot
|
|
+
|
|
+ // Run tasks that are waiting on processing
|
|
+ SpigotTimings.processQueueTimer.startTiming(); // Spigot
|
|
+ while (!processQueue.isEmpty())
|
|
+ {
|
|
+ processQueue.remove().run();
|
|
+ }
|
|
+ SpigotTimings.processQueueTimer.stopTiming(); // Spigot
|
|
+
|
|
+ SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot
|
|
net.minecraftforge.common.chunkio.ChunkIOExecutor.tick();
|
|
+ SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot
|
|
+
|
|
+ SpigotTimings.timeUpdateTimer.startTiming(); // Spigot
|
|
+ // 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.getConfigurationManager().playerEntityList.size(); ++i)
|
|
+ {
|
|
+ EntityPlayerMP entityplayermp = (EntityPlayerMP) this.getConfigurationManager().playerEntityList.get(i);
|
|
+ entityplayermp.playerNetServerHandler.sendPacket(new S03PacketTimeUpdate(entityplayermp.worldObj.getTotalWorldTime(), entityplayermp.getPlayerTime(), entityplayermp.worldObj.getGameRules().getGameRuleBooleanValue("doDaylightCycle"))); // Add support for per player time
|
|
+ }
|
|
+ }
|
|
+ SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot
|
|
+
|
|
int i;
|
|
|
|
Integer[] ids = DimensionManager.getIDs(this.tickCounter % 200 == 0);
|
|
@@ -602,19 +905,21 @@
|
|
int id = ids[x];
|
|
long j = System.nanoTime();
|
|
|
|
- if (id == 0 || this.getAllowNether())
|
|
- {
|
|
+ // CraftBukkit start
|
|
+ //if (id == 0 || this.getAllowNether())
|
|
+ //{
|
|
WorldServer worldserver = DimensionManager.getWorld(id);
|
|
this.theProfiler.startSection(worldserver.getWorldInfo().getWorldName());
|
|
this.theProfiler.startSection("pools");
|
|
this.theProfiler.endSection();
|
|
-
|
|
+ /* Drop global time updates
|
|
if (this.tickCounter % 20 == 0)
|
|
{
|
|
this.theProfiler.startSection("timeSync");
|
|
this.serverConfigManager.sendPacketToAllPlayersInDimension(new S03PacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getGameRuleBooleanValue("doDaylightCycle")), worldserver.provider.dimensionId);
|
|
this.theProfiler.endSection();
|
|
}
|
|
+ // CraftBukkit end */
|
|
|
|
this.theProfiler.startSection("tick");
|
|
FMLCommonHandler.instance().onPreWorldTick(worldserver);
|
|
@@ -622,22 +927,46 @@
|
|
|
|
try
|
|
{
|
|
+ worldserver.timings.doTick.startTiming(); // Spigot
|
|
worldserver.tick();
|
|
+ worldserver.timings.doTick.stopTiming(); // Spigot
|
|
}
|
|
catch (Throwable throwable1)
|
|
{
|
|
- crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world");
|
|
+ // Spigot Start
|
|
+ try
|
|
+ {
|
|
+ crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world");
|
|
+ }
|
|
+ catch (Throwable t)
|
|
+ {
|
|
+ throw new RuntimeException("Error generating crash report", t);
|
|
+ }
|
|
+
|
|
+ // Spigot End
|
|
worldserver.addWorldInfoToCrashReport(crashreport);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
|
|
try
|
|
{
|
|
+ worldserver.timings.tickEntities.startTiming(); // Spigot
|
|
worldserver.updateEntities();
|
|
+ worldserver.timings.tickEntities.stopTiming(); // Spigot
|
|
}
|
|
catch (Throwable throwable)
|
|
{
|
|
- crashreport = CrashReport.makeCrashReport(throwable, "Exception ticking world entities");
|
|
+ // Spigot Start
|
|
+ try
|
|
+ {
|
|
+ crashreport = CrashReport.makeCrashReport(throwable, "Exception ticking world entities");
|
|
+ }
|
|
+ catch (Throwable t)
|
|
+ {
|
|
+ throw new RuntimeException("Error generating crash report", t);
|
|
+ }
|
|
+
|
|
+ // Spigot End
|
|
worldserver.addWorldInfoToCrashReport(crashreport);
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
@@ -645,10 +974,12 @@
|
|
FMLCommonHandler.instance().onPostWorldTick(worldserver);
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.startSection("tracker");
|
|
+ worldserver.timings.tracker.startTiming(); // Spigot
|
|
worldserver.getEntityTracker().updateTrackedEntities();
|
|
+ worldserver.timings.tracker.stopTiming(); // Spigot
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.endSection();
|
|
- }
|
|
+ // } // CraftBukkit
|
|
|
|
worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - j;
|
|
}
|
|
@@ -656,15 +987,21 @@
|
|
this.theProfiler.endStartSection("dim_unloading");
|
|
DimensionManager.unloadWorlds(worldTickTimes);
|
|
this.theProfiler.endStartSection("connection");
|
|
+ SpigotTimings.connectionTimer.startTiming(); // Spigot
|
|
this.func_147137_ag().networkTick();
|
|
+ SpigotTimings.connectionTimer.stopTiming(); // Spigot
|
|
this.theProfiler.endStartSection("players");
|
|
+ SpigotTimings.playerListTimer.startTiming(); // Spigot
|
|
this.serverConfigManager.sendPlayerInfoToAllPlayers();
|
|
+ SpigotTimings.playerListTimer.stopTiming(); // Spigot
|
|
this.theProfiler.endStartSection("tickables");
|
|
|
|
+ SpigotTimings.tickablesTimer.startTiming(); // Spigot
|
|
for (i = 0; i < this.tickables.size(); ++i)
|
|
{
|
|
((IUpdatePlayerListBox)this.tickables.get(i)).update();
|
|
}
|
|
+ SpigotTimings.tickablesTimer.stopTiming(); // Spigot
|
|
|
|
this.theProfiler.endSection();
|
|
}
|
|
@@ -699,6 +1036,13 @@
|
|
|
|
public WorldServer worldServerForDimension(int p_71218_1_)
|
|
{
|
|
+ // Cauldron start - this is required for MystCraft agebooks to teleport correctly
|
|
+ // verify the nether or the end is allowed, and if not return overworld
|
|
+ if ((p_71218_1_ == -1 && !this.getAllowNether()) || (p_71218_1_ == 1 && !this.server.getAllowEnd()))
|
|
+ {
|
|
+ return DimensionManager.getWorld(0);
|
|
+ }
|
|
+ // Cauldron end
|
|
WorldServer ret = DimensionManager.getWorld(p_71218_1_);
|
|
if (ret == null)
|
|
{
|
|
@@ -784,13 +1128,14 @@
|
|
|
|
public List getPossibleCompletions(ICommandSender p_71248_1_, String p_71248_2_)
|
|
{
|
|
- ArrayList arraylist = new ArrayList();
|
|
+ // Cauldron start - add mod commands to list then pass to bukkit
|
|
+ java.util.HashSet arraylist = new java.util.HashSet(); // use a set here to avoid duplicates
|
|
|
|
if (p_71248_2_.startsWith("/"))
|
|
{
|
|
- p_71248_2_ = p_71248_2_.substring(1);
|
|
- boolean flag = !p_71248_2_.contains(" ");
|
|
- List list = this.commandManager.getPossibleCommands(p_71248_1_, p_71248_2_);
|
|
+ String char1 = p_71248_2_.substring(1); // rename var to avoid removing slash from passed message
|
|
+ boolean flag = !char1.contains(" ");
|
|
+ List list = this.commandManager.getPossibleCommands(p_71248_1_, char1);
|
|
|
|
if (list != null)
|
|
{
|
|
@@ -798,40 +1143,25 @@
|
|
|
|
while (iterator.hasNext())
|
|
{
|
|
- String s3 = (String)iterator.next();
|
|
+ String command = (String)iterator.next();
|
|
|
|
if (flag)
|
|
{
|
|
- arraylist.add("/" + s3);
|
|
+ arraylist.add("/" + command);
|
|
}
|
|
else
|
|
{
|
|
- arraylist.add(s3);
|
|
+ arraylist.add(command);
|
|
}
|
|
}
|
|
}
|
|
-
|
|
- return arraylist;
|
|
}
|
|
- else
|
|
- {
|
|
- String[] astring = p_71248_2_.split(" ", -1);
|
|
- String s1 = astring[astring.length - 1];
|
|
- String[] astring1 = this.serverConfigManager.getAllUsernames();
|
|
- int i = astring1.length;
|
|
|
|
- for (int j = 0; j < i; ++j)
|
|
- {
|
|
- String s2 = astring1[j];
|
|
-
|
|
- if (CommandBase.doesStringStartWith(s1, s2))
|
|
- {
|
|
- arraylist.add(s2);
|
|
- }
|
|
- }
|
|
-
|
|
- return arraylist;
|
|
- }
|
|
+ arraylist.addAll(this.server.tabComplete(p_71248_1_, p_71248_2_)); // add craftbukkit commands
|
|
+ ArrayList completions = new ArrayList(arraylist);
|
|
+ Collections.sort(completions); // sort the final list
|
|
+ return completions;
|
|
+ // Cauldron end
|
|
}
|
|
|
|
public static MinecraftServer getServer()
|
|
@@ -1034,7 +1364,7 @@
|
|
|
|
public boolean isServerInOnlineMode()
|
|
{
|
|
- return this.onlineMode;
|
|
+ return this.server.getOnlineMode(); // CraftBukkit
|
|
}
|
|
|
|
public void setOnlineMode(boolean p_71229_1_)
|
|
@@ -1124,7 +1454,7 @@
|
|
|
|
public NetworkSystem func_147137_ag()
|
|
{
|
|
- return this.field_147144_o;
|
|
+ return (this.field_147144_o) == null ? this.field_147144_o = new NetworkSystem(this) : this.field_147144_o; // Spigot
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
@@ -1259,8 +1589,11 @@
|
|
{
|
|
Bootstrap.func_151354_b();
|
|
|
|
+ OptionSet options = loadOptions(p_main_0_);
|
|
+
|
|
try
|
|
{
|
|
+ /* CraftBukkit start - Replace everything
|
|
boolean flag = true;
|
|
String s = null;
|
|
String s1 = ".";
|
|
@@ -1356,16 +1689,34 @@
|
|
{
|
|
dedicatedserver.setGuiEnabled();
|
|
}
|
|
+ // */
|
|
+ // CraftBukkit end
|
|
+ if (CauldronUtils.deobfuscatedEnvironment()) useJline = false; // Cauldron
|
|
+ DedicatedServer dedicatedserver = new DedicatedServer(options);
|
|
|
|
- dedicatedserver.startServerThread();
|
|
- Runtime.getRuntime().addShutdownHook(new Thread("Server Shutdown Thread")
|
|
+ if (options.has("port"))
|
|
{
|
|
- private static final String __OBFID = "CL_00001806";
|
|
- public void run()
|
|
+ int port = (Integer) options.valueOf("port");
|
|
+
|
|
+ if (port > 0)
|
|
{
|
|
- dedicatedserver.stopServer();
|
|
+ dedicatedserver.setServerPort(port);
|
|
}
|
|
- });
|
|
+ }
|
|
+
|
|
+ if (options.has("universe"))
|
|
+ {
|
|
+ dedicatedserver.anvilFile = (File) options.valueOf("universe");
|
|
+ }
|
|
+
|
|
+ if (options.has("world"))
|
|
+ {
|
|
+ dedicatedserver.setFolderName((String) options.valueOf("world"));
|
|
+ }
|
|
+
|
|
+ dedicatedserver.primaryThread.start();
|
|
+ // Runtime.getRuntime().addShutdownHook(new ThreadShutdown("Server Shutdown Thread", dedicatedserver));
|
|
+ // CraftBukkit end
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
@@ -1400,15 +1751,70 @@
|
|
@SideOnly(Side.SERVER)
|
|
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 && 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
|
|
}
|
|
|
|
@SideOnly(Side.SERVER)
|
|
- public String handleRConCommand(String p_71252_1_)
|
|
+ public String handleRConCommand(final String par1Str)
|
|
{
|
|
- RConConsoleSource.instance.resetLog();
|
|
- this.commandManager.executeCommand(RConConsoleSource.instance, p_71252_1_);
|
|
- return RConConsoleSource.instance.getLogContents();
|
|
+ Waitable<String> waitable = new Waitable<String>()
|
|
+ {
|
|
+ @Override
|
|
+ protected String evaluate()
|
|
+ {
|
|
+ RConConsoleSource.instance.resetLog();
|
|
+ // Event changes start
|
|
+ RemoteServerCommandEvent event = new RemoteServerCommandEvent(MinecraftServer.this.remoteConsole, par1Str);
|
|
+ MinecraftServer.this.server.getPluginManager().callEvent(event);
|
|
+ // Event changes end
|
|
+ ServerCommand servercommand = new ServerCommand(event.getCommand(), RConConsoleSource.instance);
|
|
+ MinecraftServer.this.server.dispatchServerCommand(MinecraftServer.this.remoteConsole, servercommand); // CraftBukkit
|
|
+ // this.n.a(RemoteControlCommandListener.instance, s);
|
|
+ return RConConsoleSource.instance.getLogContents();
|
|
+ }
|
|
+ };
|
|
+ processQueue.add(waitable);
|
|
+
|
|
+ try
|
|
+ {
|
|
+ return waitable.get();
|
|
+ }
|
|
+ catch (java.util.concurrent.ExecutionException e)
|
|
+ {
|
|
+ throw new RuntimeException("Exception processing rcon command " + par1Str, e.getCause());
|
|
+ }
|
|
+ catch (InterruptedException e)
|
|
+ {
|
|
+ Thread.currentThread().interrupt(); // Maintain interrupted state
|
|
+ throw new RuntimeException("Interrupted processing rcon command " + par1Str, e);
|
|
+ }
|
|
+
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
@SideOnly(Side.SERVER)
|
|
@@ -1455,9 +1861,213 @@
|
|
return this.serverStopped;
|
|
}
|
|
|
|
+ public static OptionSet loadOptions(String[] args) {
|
|
+ OptionParser parser = new OptionParser() {
|
|
+ {
|
|
+ acceptsAll(Arrays.asList("?", "help"), "Show the help");
|
|
+
|
|
+ acceptsAll(Arrays.asList("c", "config"), "Properties file to use")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("server.properties"))
|
|
+ .describedAs("Properties file");
|
|
+
|
|
+ acceptsAll(Arrays.asList("P", "plugins"), "Plugin directory to use")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("plugins"))
|
|
+ .describedAs("Plugin directory");
|
|
+
|
|
+ acceptsAll(Arrays.asList("h", "host", "server-ip"), "Host to listen on")
|
|
+ .withRequiredArg()
|
|
+ .ofType(String.class)
|
|
+ .describedAs("Hostname or IP");
|
|
+
|
|
+ acceptsAll(Arrays.asList("W", "world-dir", "universe", "world-container"), "World container")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .describedAs("Directory containing worlds");
|
|
+
|
|
+ acceptsAll(Arrays.asList("w", "world", "level-name"), "World name")
|
|
+ .withRequiredArg()
|
|
+ .ofType(String.class)
|
|
+ .describedAs("World name");
|
|
+
|
|
+ acceptsAll(Arrays.asList("p", "port", "server-port"), "Port to listen on")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Integer.class)
|
|
+ .describedAs("Port");
|
|
+
|
|
+ acceptsAll(Arrays.asList("o", "online-mode"), "Whether to use online authentication")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Boolean.class)
|
|
+ .describedAs("Authentication");
|
|
+
|
|
+ acceptsAll(Arrays.asList("s", "size", "max-players"), "Maximum amount of players")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Integer.class)
|
|
+ .describedAs("Server size");
|
|
+
|
|
+ acceptsAll(Arrays.asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
|
|
+ .withRequiredArg()
|
|
+ .ofType(SimpleDateFormat.class)
|
|
+ .describedAs("Log date format");
|
|
+
|
|
+ acceptsAll(Arrays.asList("log-pattern"), "Specfies the log filename pattern")
|
|
+ .withRequiredArg()
|
|
+ .ofType(String.class)
|
|
+ .defaultsTo("server.log")
|
|
+ .describedAs("Log filename");
|
|
+
|
|
+ acceptsAll(Arrays.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Integer.class)
|
|
+ .defaultsTo(0)
|
|
+ .describedAs("Max log size");
|
|
+
|
|
+ acceptsAll(Arrays.asList("log-count"), "Specified how many log files to cycle through")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Integer.class)
|
|
+ .defaultsTo(1)
|
|
+ .describedAs("Log count");
|
|
+
|
|
+ acceptsAll(Arrays.asList("log-append"), "Whether to append to the log file")
|
|
+ .withRequiredArg()
|
|
+ .ofType(Boolean.class)
|
|
+ .defaultsTo(true)
|
|
+ .describedAs("Log append");
|
|
+
|
|
+ acceptsAll(Arrays.asList("log-strip-color"), "Strips color codes from log file");
|
|
+
|
|
+ acceptsAll(Arrays.asList("b", "bukkit-settings"), "File for bukkit settings")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("bukkit.yml"))
|
|
+ .describedAs("Yml file");
|
|
+
|
|
+ acceptsAll(Arrays.asList("C", "commands-settings"), "File for command settings")
|
|
+ .withRequiredArg()
|
|
+ .ofType(File.class)
|
|
+ .defaultsTo(new File("commands.yml"))
|
|
+ .describedAs("Yml file");
|
|
+
|
|
+ acceptsAll(Arrays.asList("nojline"), "Disables jline and emulates the vanilla console");
|
|
+
|
|
+ acceptsAll(Arrays.asList("noconsole"), "Disables the console");
|
|
+
|
|
+ acceptsAll(Arrays.asList("v", "version"), "Show the CraftBukkit Version");
|
|
+
|
|
+ acceptsAll(Arrays.asList("demo"), "Demo mode");
|
|
+ }
|
|
+ };
|
|
+
|
|
+ OptionSet options = null;
|
|
+
|
|
+ try {
|
|
+ options = parser.parse(args);
|
|
+ } catch (joptsimple.OptionException ex) {
|
|
+ logger.log(org.apache.logging.log4j.Level.ERROR, ex.getLocalizedMessage());
|
|
+ }
|
|
+
|
|
+ if ((options == null) || (options.has("?"))) {
|
|
+ try {
|
|
+ parser.printHelpOn(System.out);
|
|
+ } catch (IOException ex) {
|
|
+ logger.log(org.apache.logging.log4j.Level.ERROR, ex);
|
|
+ }
|
|
+ } else {
|
|
+ try {
|
|
+ // This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals
|
|
+ String jline_UnsupportedTerminal = new String(new char[] {'j','l','i','n','e','.','U','n','s','u','p','p','o','r','t','e','d','T','e','r','m','i','n','a','l'});
|
|
+ String jline_terminal = new String(new char[] {'j','l','i','n','e','.','t','e','r','m','i','n','a','l'});
|
|
+
|
|
+ useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal));
|
|
+
|
|
+ if (options.has("nojline")) {
|
|
+ System.setProperty("user.language", "en");
|
|
+ useJline = false;
|
|
+ }
|
|
+
|
|
+ if (!useJline) {
|
|
+ // This ensures the terminal literal will always match the jline implementation
|
|
+ System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
|
|
+ }
|
|
+
|
|
+
|
|
+ if (options.has("noconsole")) {
|
|
+ useConsole = false;
|
|
+ }
|
|
+ // Cauldron start - initialize config
|
|
+ configFile = (File) options.valueOf("bukkit-settings");
|
|
+ commandFile = (File)options.valueOf("commands-settings");
|
|
+ configuration = YamlConfiguration.loadConfiguration(configFile);
|
|
+ configuration.options().copyDefaults(true);
|
|
+ configuration.setDefaults(YamlConfiguration.loadConfiguration(MinecraftServer.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml")));
|
|
+ ConfigurationSection legacyAlias = null;
|
|
+ if (!configuration.isString("aliases")) {
|
|
+ legacyAlias = configuration.getConfigurationSection("aliases");
|
|
+ configuration.set("aliases", "now-in-commands.yml");
|
|
+ }
|
|
+ try {
|
|
+ configuration.save(configFile);
|
|
+ } catch (IOException ex) {
|
|
+ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + configFile, ex);
|
|
+ }
|
|
+ if (commandFile.isFile()) {
|
|
+ legacyAlias = null;
|
|
+ }
|
|
+ commandsConfiguration = YamlConfiguration.loadConfiguration(commandFile);
|
|
+ commandsConfiguration.options().copyDefaults(true);
|
|
+ commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(MinecraftServer.class.getClassLoader().getResourceAsStream("configurations/commands.yml")));
|
|
+ try {
|
|
+ commandsConfiguration.save(commandFile);
|
|
+ } catch (IOException ex) {
|
|
+ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + commandFile, ex);
|
|
+ }
|
|
+
|
|
+ // Migrate aliases from old file and add previously implicit $1- to pass all arguments
|
|
+ if (legacyAlias != null) {
|
|
+ ConfigurationSection aliases = commandsConfiguration.createSection("aliases");
|
|
+ for (String key : legacyAlias.getKeys(false)) {
|
|
+ ArrayList<String> commands = new ArrayList<String>();
|
|
+
|
|
+ if (legacyAlias.isList(key)) {
|
|
+ for (String command : legacyAlias.getStringList(key)) {
|
|
+ commands.add(command + " $1-");
|
|
+ }
|
|
+ } else {
|
|
+ commands.add(legacyAlias.getString(key) + " $1-");
|
|
+ }
|
|
+
|
|
+ aliases.set(key, commands);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ commandsConfiguration.save(commandFile);
|
|
+ } catch (IOException ex) {
|
|
+ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + commandFile, ex);
|
|
+ }
|
|
+
|
|
+ return options;
|
|
+ // Cauldron end
|
|
+ } catch (Throwable t) {
|
|
+ t.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+ return null; // Cauldron
|
|
+ }
|
|
+
|
|
@SideOnly(Side.SERVER)
|
|
public void setForceGamemode(boolean p_104055_1_)
|
|
{
|
|
this.isGamemodeForced = p_104055_1_;
|
|
}
|
|
+
|
|
+ // CraftBukkit start
|
|
+ public static Logger getLogger()
|
|
+ {
|
|
+ return logger;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
}
|