1248 lines
33 KiB
Java
1248 lines
33 KiB
Java
package net.minecraft.server;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.net.Proxy;
|
|
import java.security.KeyPair;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import net.minecraft.src.AxisAlignedBB;
|
|
import net.minecraft.src.ChunkCoordinates;
|
|
import net.minecraft.src.CommandBase;
|
|
import net.minecraft.src.ConvertingProgressUpdate;
|
|
import net.minecraft.src.CrashReport;
|
|
import net.minecraft.src.DispenserBehaviors;
|
|
import net.minecraft.src.EntityPlayer;
|
|
import net.minecraft.src.EnumGameType;
|
|
import net.minecraft.src.ICommandManager;
|
|
import net.minecraft.src.ICommandSender;
|
|
import net.minecraft.src.ILogAgent;
|
|
import net.minecraft.src.IProgressUpdate;
|
|
import net.minecraft.src.ISaveFormat;
|
|
import net.minecraft.src.ISaveHandler;
|
|
import net.minecraft.src.IUpdatePlayerListBox;
|
|
import net.minecraft.src.MathHelper;
|
|
import net.minecraft.src.MinecraftException;
|
|
import net.minecraft.src.Packet;
|
|
import net.minecraft.src.Packet4UpdateTime;
|
|
import net.minecraft.src.Profiler;
|
|
import net.minecraft.src.RConConsoleSource;
|
|
import net.minecraft.src.ReportedException;
|
|
import net.minecraft.src.ServerCommandManager;
|
|
import net.minecraft.src.ServerConfigurationManager;
|
|
import net.minecraft.src.World;
|
|
import net.minecraft.src.WorldInfo;
|
|
import net.minecraft.src.WorldManager;
|
|
import net.minecraft.src.WorldServer;
|
|
import net.minecraft.src.WorldServerMulti;
|
|
import net.minecraft.src.WorldSettings;
|
|
import net.minecraft.src.WorldType;
|
|
|
|
public abstract class MinecraftServer implements ICommandSender, Runnable
|
|
{
|
|
/** Instance of Minecraft Server. */
|
|
private static MinecraftServer mcServer;
|
|
//private final ISaveFormat anvilConverterForAnvilFile;
|
|
|
|
/** The PlayerUsageSnooper instance. */
|
|
private final File anvilFile;
|
|
|
|
/**
|
|
* Collection of objects to update every tick. Type: List<IUpdatePlayerListBox>
|
|
*/
|
|
private final List tickables = new ArrayList();
|
|
private final ICommandManager commandManager;
|
|
public final Profiler theProfiler = new Profiler();
|
|
|
|
/** The server's hostname. */
|
|
private String hostname;
|
|
|
|
/** The server's port. */
|
|
private int serverPort = -1;
|
|
|
|
/** The server world instances. */
|
|
public WorldServer[] worldServers;
|
|
|
|
/** The ServerConfigurationManager instance. */
|
|
private ServerConfigurationManager serverConfigManager;
|
|
|
|
/**
|
|
* Indicates whether the server is running or not. Set to false to initiate a shutdown.
|
|
*/
|
|
private boolean serverRunning = true;
|
|
|
|
/** Indicates to other classes that the server is safely stopped. */
|
|
private boolean serverStopped;
|
|
|
|
/** Incremented every tick. */
|
|
private int tickCounter;
|
|
protected Proxy serverProxy;
|
|
|
|
/**
|
|
* The task the server is currently working on(and will output on outputPercentRemaining).
|
|
*/
|
|
public String currentTask;
|
|
|
|
/** The percentage of the current task finished so far. */
|
|
public int percentDone;
|
|
|
|
/** True if the server is in online mode. */
|
|
private boolean onlineMode;
|
|
|
|
/** True if the server has animals turned on. */
|
|
private boolean canSpawnAnimals;
|
|
private boolean canSpawnNPCs;
|
|
|
|
/** Indicates whether PvP is active on the server or not. */
|
|
private boolean pvpEnabled;
|
|
|
|
/** Determines if flight is allowed or not. */
|
|
private boolean allowFlight;
|
|
|
|
/** The server MOTD string. */
|
|
private String motd;
|
|
|
|
/** Maximum build height. */
|
|
private int buildLimit;
|
|
private int field_143008_E;
|
|
private long lastSentPacketID;
|
|
private long lastSentPacketSize;
|
|
private long lastReceivedID;
|
|
private long lastReceivedSize;
|
|
public final long[] sentPacketCountArray;
|
|
public final long[] sentPacketSizeArray;
|
|
public final long[] receivedPacketCountArray;
|
|
public final long[] receivedPacketSizeArray;
|
|
public final long[] tickTimeArray;
|
|
|
|
/** Stats are [dimension][tick%100] system.nanoTime is stored. */
|
|
public long[][] timeOfLastDimensionTick;
|
|
private KeyPair serverKeyPair;
|
|
|
|
/** Username of the server owner (for integrated servers) */
|
|
private String serverOwner;
|
|
private String folderName;
|
|
private String worldName;
|
|
private boolean isDemo;
|
|
private boolean enableBonusChest;
|
|
|
|
/**
|
|
* If true, there is no need to save chunks or stop the server, because that is already being done.
|
|
*/
|
|
private boolean worldIsBeingDeleted;
|
|
private String texturePack;
|
|
private boolean serverIsRunning;
|
|
|
|
/**
|
|
* Set when warned for "Can't keep up", which triggers again after 15 seconds.
|
|
*/
|
|
private long timeOfLastWarning;
|
|
private String userMessage;
|
|
private boolean startProfiling;
|
|
private boolean isGamemodeForced;
|
|
|
|
public MinecraftServer(File par1File)
|
|
{
|
|
this.serverProxy = Proxy.NO_PROXY;
|
|
this.field_143008_E = 0;
|
|
this.sentPacketCountArray = new long[100];
|
|
this.sentPacketSizeArray = new long[100];
|
|
this.receivedPacketCountArray = new long[100];
|
|
this.receivedPacketSizeArray = new long[100];
|
|
this.tickTimeArray = new long[100];
|
|
this.texturePack = "";
|
|
mcServer = this;
|
|
this.anvilFile = par1File;
|
|
this.commandManager = new ServerCommandManager();
|
|
//this.anvilConverterForAnvilFile = new AnvilSaveConverter(par1File);
|
|
this.registerDispenseBehaviors();
|
|
}
|
|
|
|
/**
|
|
* Register all dispense behaviors.
|
|
*/
|
|
private void registerDispenseBehaviors()
|
|
{
|
|
DispenserBehaviors.registerDispenserBehaviours();
|
|
}
|
|
|
|
/**
|
|
* Initialises the server and starts it.
|
|
*/
|
|
protected abstract boolean startServer() throws IOException;
|
|
|
|
protected void convertMapIfNeeded(String par1Str)
|
|
{
|
|
if (this.getActiveAnvilConverter().isOldMapFormat(par1Str))
|
|
{
|
|
this.getLogAgent().logInfo("Converting map!");
|
|
this.setUserMessage("menu.convertingLevel");
|
|
this.getActiveAnvilConverter().convertMapFormat(par1Str, new ConvertingProgressUpdate(this));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Typically "menu.convertingLevel", "menu.loadingLevel" or others.
|
|
*/
|
|
protected synchronized void setUserMessage(String par1Str)
|
|
{
|
|
this.userMessage = par1Str;
|
|
}
|
|
|
|
public synchronized String getUserMessage()
|
|
{
|
|
return this.userMessage;
|
|
}
|
|
|
|
protected void loadAllWorlds(String par1Str, String par2Str, long par3, WorldType par5WorldType, String par6Str)
|
|
{
|
|
this.convertMapIfNeeded(par1Str);
|
|
this.setUserMessage("menu.loadingLevel");
|
|
this.worldServers = new WorldServer[3];
|
|
this.timeOfLastDimensionTick = new long[this.worldServers.length][100];
|
|
ISaveHandler var7 = null;
|
|
WorldInfo var9 = var7.loadWorldInfo();
|
|
WorldSettings var8;
|
|
|
|
if (var9 == null)
|
|
{
|
|
var8 = new WorldSettings(par3, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), par5WorldType);
|
|
var8.func_82750_a(par6Str);
|
|
}
|
|
else
|
|
{
|
|
var8 = new WorldSettings(var9);
|
|
}
|
|
|
|
if (this.enableBonusChest)
|
|
{
|
|
var8.enableBonusChest();
|
|
}
|
|
|
|
for (int var10 = 0; var10 < this.worldServers.length; ++var10)
|
|
{
|
|
byte var11 = 0;
|
|
|
|
if (var10 == 1)
|
|
{
|
|
var11 = -1;
|
|
}
|
|
|
|
if (var10 == 2)
|
|
{
|
|
var11 = 1;
|
|
}
|
|
|
|
if (var10 == 0)
|
|
{
|
|
this.worldServers[var10] = new WorldServer(this, var7, par2Str, var11, var8, this.theProfiler, this.getLogAgent());
|
|
|
|
}
|
|
else
|
|
{
|
|
this.worldServers[var10] = new WorldServerMulti(this, var7, par2Str, var11, var8, this.worldServers[0], this.theProfiler, this.getLogAgent());
|
|
}
|
|
|
|
this.worldServers[var10].addWorldAccess(new WorldManager(this, this.worldServers[var10]));
|
|
|
|
if (!this.isSinglePlayer())
|
|
{
|
|
this.worldServers[var10].getWorldInfo().setGameType(this.getGameType());
|
|
}
|
|
|
|
this.serverConfigManager.setPlayerManager(this.worldServers);
|
|
}
|
|
|
|
this.setDifficultyForAllWorlds(this.getDifficulty());
|
|
this.initialWorldChunkLoad();
|
|
}
|
|
|
|
protected void initialWorldChunkLoad()
|
|
{
|
|
boolean var1 = true;
|
|
boolean var2 = true;
|
|
boolean var3 = true;
|
|
boolean var4 = true;
|
|
int var5 = 0;
|
|
this.setUserMessage("menu.generatingTerrain");
|
|
byte var6 = 0;
|
|
this.getLogAgent().logInfo("Preparing start region for level " + var6);
|
|
WorldServer var7 = this.worldServers[var6];
|
|
ChunkCoordinates var8 = var7.getSpawnPoint();
|
|
long var9 = getSystemTimeMillis();
|
|
|
|
for (int var11 = -192; var11 <= 192 && this.isServerRunning(); var11 += 16)
|
|
{
|
|
for (int var12 = -192; var12 <= 192 && this.isServerRunning(); var12 += 16)
|
|
{
|
|
long var13 = getSystemTimeMillis();
|
|
|
|
if (var13 - var9 > 1000L)
|
|
{
|
|
this.outputPercentRemaining("Preparing spawn area", var5 * 100 / 625);
|
|
var9 = var13;
|
|
}
|
|
|
|
++var5;
|
|
var7.theChunkProviderServer.loadChunk(var8.posX + var11 >> 4, var8.posZ + var12 >> 4);
|
|
}
|
|
}
|
|
|
|
this.clearCurrentTask();
|
|
}
|
|
|
|
public abstract boolean canStructuresSpawn();
|
|
|
|
public abstract EnumGameType getGameType();
|
|
|
|
/**
|
|
* Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on the client.
|
|
*/
|
|
public abstract int getDifficulty();
|
|
|
|
/**
|
|
* Defaults to false.
|
|
*/
|
|
public abstract boolean isHardcore();
|
|
|
|
public abstract int func_110455_j();
|
|
|
|
/**
|
|
* Used to display a percent remaining given text and the percentage.
|
|
*/
|
|
protected void outputPercentRemaining(String par1Str, int par2)
|
|
{
|
|
this.currentTask = par1Str;
|
|
this.percentDone = par2;
|
|
this.getLogAgent().logInfo(par1Str + ": " + par2 + "%");
|
|
}
|
|
|
|
/**
|
|
* Set current task to null and set its percentage to 0.
|
|
*/
|
|
protected void clearCurrentTask()
|
|
{
|
|
this.currentTask = null;
|
|
this.percentDone = 0;
|
|
}
|
|
|
|
/**
|
|
* par1 indicates if a log message should be output.
|
|
*/
|
|
protected void saveAllWorlds(boolean par1)
|
|
{
|
|
if (!this.worldIsBeingDeleted)
|
|
{
|
|
WorldServer[] var2 = this.worldServers;
|
|
int var3 = var2.length;
|
|
|
|
for (int var4 = 0; var4 < var3; ++var4)
|
|
{
|
|
WorldServer var5 = var2[var4];
|
|
|
|
if (var5 != null)
|
|
{
|
|
if (!par1)
|
|
{
|
|
this.getLogAgent().logInfo("Saving chunks for level \'" + var5.getWorldInfo().getWorldName() + "\'/" + var5.provider.getDimensionName());
|
|
}
|
|
|
|
try
|
|
{
|
|
var5.saveAllChunks(true, (IProgressUpdate)null);
|
|
}
|
|
catch (MinecraftException var7)
|
|
{
|
|
this.getLogAgent().logWarning(var7.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves all necessary data as preparation for stopping the server.
|
|
*/
|
|
public void stopServer()
|
|
{
|
|
if (!this.worldIsBeingDeleted)
|
|
{
|
|
this.getLogAgent().logInfo("Stopping server");
|
|
|
|
if (this.serverConfigManager != null)
|
|
{
|
|
this.getLogAgent().logInfo("Saving players");
|
|
this.serverConfigManager.saveAllPlayerData();
|
|
this.serverConfigManager.removeAllPlayers();
|
|
}
|
|
|
|
this.getLogAgent().logInfo("Saving worlds");
|
|
this.saveAllWorlds(false);
|
|
|
|
for (int var1 = 0; var1 < this.worldServers.length; ++var1)
|
|
{
|
|
WorldServer var2 = this.worldServers[var1];
|
|
var2.flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* "getHostname" is already taken, but both return the hostname.
|
|
*/
|
|
public String getServerHostname()
|
|
{
|
|
return this.hostname;
|
|
}
|
|
|
|
public void setHostname(String par1Str)
|
|
{
|
|
this.hostname = par1Str;
|
|
}
|
|
|
|
public boolean isServerRunning()
|
|
{
|
|
return this.serverRunning;
|
|
}
|
|
|
|
/**
|
|
* Sets the serverRunning variable to false, in order to get the server to shut down.
|
|
*/
|
|
public void initiateShutdown()
|
|
{
|
|
this.serverRunning = false;
|
|
}
|
|
|
|
public void run()
|
|
{
|
|
try
|
|
{
|
|
if (this.startServer())
|
|
{
|
|
long var1 = getSystemTimeMillis();
|
|
|
|
for (long var50 = 0L; this.serverRunning; this.serverIsRunning = true)
|
|
{
|
|
long var5 = getSystemTimeMillis();
|
|
long var7 = var5 - var1;
|
|
|
|
if (var7 > 2000L && var1 - this.timeOfLastWarning >= 15000L)
|
|
{
|
|
this.getLogAgent().logWarning("Can\'t keep up! Did the system time change, or is the server overloaded?");
|
|
var7 = 2000L;
|
|
this.timeOfLastWarning = var1;
|
|
}
|
|
|
|
if (var7 < 0L)
|
|
{
|
|
this.getLogAgent().logWarning("Time ran backwards! Did the system time change?");
|
|
var7 = 0L;
|
|
}
|
|
|
|
var50 += var7;
|
|
var1 = var5;
|
|
|
|
if (this.worldServers[0].areAllPlayersAsleep())
|
|
{
|
|
this.tick();
|
|
var50 = 0L;
|
|
}
|
|
else
|
|
{
|
|
while (var50 > 50L)
|
|
{
|
|
var50 -= 50L;
|
|
this.tick();
|
|
}
|
|
}
|
|
|
|
Thread.sleep(1L);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.finalTick((CrashReport)null);
|
|
}
|
|
}
|
|
catch (Throwable var48)
|
|
{
|
|
var48.printStackTrace();
|
|
this.getLogAgent().logSevereException("Encountered an unexpected exception " + var48.getClass().getSimpleName(), var48);
|
|
CrashReport var2 = null;
|
|
|
|
if (var48 instanceof ReportedException)
|
|
{
|
|
var2 = this.addServerInfoToCrashReport(((ReportedException)var48).getCrashReport());
|
|
}
|
|
else
|
|
{
|
|
var2 = this.addServerInfoToCrashReport(new CrashReport("Exception in server tick loop", var48));
|
|
}
|
|
|
|
File var3 = new File(new File(this.getDataDirectory(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
|
|
|
|
if (var2.saveToFile(var3, this.getLogAgent()))
|
|
{
|
|
this.getLogAgent().logSevere("This crash report has been saved to: " + var3.getAbsolutePath());
|
|
}
|
|
else
|
|
{
|
|
this.getLogAgent().logSevere("We were unable to save this crash report to disk.");
|
|
}
|
|
|
|
this.finalTick(var2);
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
this.stopServer();
|
|
this.serverStopped = true;
|
|
}
|
|
catch (Throwable var46)
|
|
{
|
|
var46.printStackTrace();
|
|
}
|
|
finally
|
|
{
|
|
this.systemExitNow();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected File getDataDirectory()
|
|
{
|
|
return new File(".");
|
|
}
|
|
|
|
/**
|
|
* Called on exit from the main run() loop.
|
|
*/
|
|
protected void finalTick(CrashReport par1CrashReport) {}
|
|
|
|
/**
|
|
* Directly calls System.exit(0), instantly killing the program.
|
|
*/
|
|
protected void systemExitNow() {}
|
|
|
|
/**
|
|
* Main function called by run() every loop.
|
|
*/
|
|
public void tick()
|
|
{
|
|
long var1 = System.nanoTime();
|
|
AxisAlignedBB.getAABBPool().cleanPool();
|
|
++this.tickCounter;
|
|
|
|
if (this.startProfiling)
|
|
{
|
|
this.startProfiling = false;
|
|
this.theProfiler.profilingEnabled = false;
|
|
this.theProfiler.clearProfiling();
|
|
}
|
|
|
|
this.theProfiler.startSection("root");
|
|
this.updateTimeLightAndEntities();
|
|
|
|
if (this.tickCounter % 900 == 0)
|
|
{
|
|
this.theProfiler.startSection("save");
|
|
this.serverConfigManager.saveAllPlayerData();
|
|
this.saveAllWorlds(true);
|
|
this.theProfiler.endSection();
|
|
}
|
|
|
|
this.theProfiler.startSection("tallying");
|
|
this.tickTimeArray[this.tickCounter % 100] = System.nanoTime() - var1;
|
|
this.sentPacketCountArray[this.tickCounter % 100] = Packet.sentID - this.lastSentPacketID;
|
|
this.lastSentPacketID = Packet.sentID;
|
|
this.sentPacketSizeArray[this.tickCounter % 100] = Packet.sentSize - this.lastSentPacketSize;
|
|
this.lastSentPacketSize = Packet.sentSize;
|
|
this.receivedPacketCountArray[this.tickCounter % 100] = Packet.receivedID - this.lastReceivedID;
|
|
this.lastReceivedID = Packet.receivedID;
|
|
this.receivedPacketSizeArray[this.tickCounter % 100] = Packet.receivedSize - this.lastReceivedSize;
|
|
this.lastReceivedSize = Packet.receivedSize;
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.endSection();
|
|
}
|
|
|
|
public void updateTimeLightAndEntities()
|
|
{
|
|
this.theProfiler.startSection("levels");
|
|
int var1;
|
|
|
|
for (var1 = 0; var1 < this.worldServers.length; ++var1)
|
|
{
|
|
long var2 = System.nanoTime();
|
|
|
|
if (var1 == 0 || this.getAllowNether())
|
|
{
|
|
WorldServer var4 = this.worldServers[var1];
|
|
this.theProfiler.startSection(var4.getWorldInfo().getWorldName());
|
|
this.theProfiler.startSection("pools");
|
|
var4.getWorldVec3Pool().clear();
|
|
this.theProfiler.endSection();
|
|
|
|
if (this.tickCounter % 20 == 0)
|
|
{
|
|
this.theProfiler.startSection("timeSync");
|
|
this.serverConfigManager.sendPacketToAllPlayersInDimension(new Packet4UpdateTime(var4.getTotalWorldTime(), var4.getWorldTime(), var4.getGameRules().getGameRuleBooleanValue("doDaylightCycle")), var4.provider.dimensionId);
|
|
this.theProfiler.endSection();
|
|
}
|
|
|
|
this.theProfiler.startSection("tick");
|
|
CrashReport var6;
|
|
|
|
try
|
|
{
|
|
var4.tick();
|
|
}
|
|
catch (Throwable var8)
|
|
{
|
|
var6 = CrashReport.makeCrashReport(var8, "Exception ticking world");
|
|
var4.addWorldInfoToCrashReport(var6);
|
|
throw new ReportedException(var6);
|
|
}
|
|
|
|
try
|
|
{
|
|
var4.updateEntities();
|
|
}
|
|
catch (Throwable var7)
|
|
{
|
|
var6 = CrashReport.makeCrashReport(var7, "Exception ticking world entities");
|
|
var4.addWorldInfoToCrashReport(var6);
|
|
throw new ReportedException(var6);
|
|
}
|
|
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.startSection("tracker");
|
|
var4.getEntityTracker().updateTrackedEntities();
|
|
this.theProfiler.endSection();
|
|
this.theProfiler.endSection();
|
|
}
|
|
|
|
this.timeOfLastDimensionTick[var1][this.tickCounter % 100] = System.nanoTime() - var2;
|
|
}
|
|
|
|
this.theProfiler.endStartSection("connection");
|
|
this.theProfiler.endStartSection("players");
|
|
this.serverConfigManager.sendPlayerInfoToAllPlayers();
|
|
this.theProfiler.endStartSection("tickables");
|
|
|
|
for (var1 = 0; var1 < this.tickables.size(); ++var1)
|
|
{
|
|
((IUpdatePlayerListBox)this.tickables.get(var1)).update();
|
|
}
|
|
|
|
this.theProfiler.endSection();
|
|
}
|
|
|
|
public boolean getAllowNether()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns a File object from the specified string.
|
|
*/
|
|
public File getFile(String par1Str)
|
|
{
|
|
return new File(this.getDataDirectory(), par1Str);
|
|
}
|
|
|
|
/**
|
|
* Logs the message with a level of INFO.
|
|
*/
|
|
public void logInfo(String par1Str)
|
|
{
|
|
this.getLogAgent().logInfo(par1Str);
|
|
}
|
|
|
|
/**
|
|
* Logs the message with a level of WARN.
|
|
*/
|
|
public void logWarning(String par1Str)
|
|
{
|
|
this.getLogAgent().logWarning(par1Str);
|
|
}
|
|
|
|
/**
|
|
* Gets the worldServer by the given dimension.
|
|
*/
|
|
public WorldServer worldServerForDimension(int par1)
|
|
{
|
|
return par1 == -1 ? this.worldServers[1] : (par1 == 1 ? this.worldServers[2] : this.worldServers[0]);
|
|
}
|
|
|
|
/**
|
|
* Returns the server's hostname.
|
|
*/
|
|
public String getHostname()
|
|
{
|
|
return this.hostname;
|
|
}
|
|
|
|
/**
|
|
* Never used, but "getServerPort" is already taken.
|
|
*/
|
|
public int getPort()
|
|
{
|
|
return this.serverPort;
|
|
}
|
|
|
|
/**
|
|
* Returns the server message of the day
|
|
*/
|
|
public String getServerMOTD()
|
|
{
|
|
return this.motd;
|
|
}
|
|
|
|
/**
|
|
* Returns the server's Minecraft version as string.
|
|
*/
|
|
public String getMinecraftVersion()
|
|
{
|
|
return "1.6.4";
|
|
}
|
|
|
|
/**
|
|
* Returns the number of players currently on the server.
|
|
*/
|
|
public int getCurrentPlayerCount()
|
|
{
|
|
return this.serverConfigManager.getCurrentPlayerCount();
|
|
}
|
|
|
|
/**
|
|
* Returns the maximum number of players allowed on the server.
|
|
*/
|
|
public int getMaxPlayers()
|
|
{
|
|
return this.serverConfigManager.getMaxPlayers();
|
|
}
|
|
|
|
/**
|
|
* Returns an array of the usernames of all the connected players.
|
|
*/
|
|
public String[] getAllUsernames()
|
|
{
|
|
return this.serverConfigManager.getAllUsernames();
|
|
}
|
|
|
|
/**
|
|
* Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3; AnotherPlugin 2.1; AndSoForth 1.0".
|
|
*/
|
|
public String getPlugins()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public String executeCommand(String par1Str)
|
|
{
|
|
RConConsoleSource.consoleBuffer.resetLog();
|
|
this.commandManager.executeCommand(RConConsoleSource.consoleBuffer, par1Str);
|
|
return RConConsoleSource.consoleBuffer.getChatBuffer();
|
|
}
|
|
|
|
/**
|
|
* Returns true if debugging is enabled, false otherwise.
|
|
*/
|
|
public boolean isDebuggingEnabled()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Logs the error message with a level of SEVERE.
|
|
*/
|
|
public void logSevere(String par1Str)
|
|
{
|
|
this.getLogAgent().logSevere(par1Str);
|
|
}
|
|
|
|
/**
|
|
* If isDebuggingEnabled(), logs the message with a level of INFO.
|
|
*/
|
|
public void logDebug(String par1Str)
|
|
{
|
|
if (this.isDebuggingEnabled())
|
|
{
|
|
this.getLogAgent().logInfo(par1Str);
|
|
}
|
|
}
|
|
|
|
public String getServerModName()
|
|
{
|
|
return "vanilla";
|
|
}
|
|
|
|
/**
|
|
* Adds the server info, including from theWorldServer, to the crash report.
|
|
*/
|
|
public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport)
|
|
{
|
|
return par1CrashReport;
|
|
}
|
|
|
|
/**
|
|
* If par2Str begins with /, then it searches for commands, otherwise it returns players.
|
|
*/
|
|
public List getPossibleCompletions(ICommandSender par1ICommandSender, String par2Str)
|
|
{
|
|
ArrayList var3 = new ArrayList();
|
|
|
|
if (par2Str.startsWith("/"))
|
|
{
|
|
par2Str = par2Str.substring(1);
|
|
boolean var10 = !par2Str.contains(" ");
|
|
List var11 = this.commandManager.getPossibleCommands(par1ICommandSender, par2Str);
|
|
|
|
if (var11 != null)
|
|
{
|
|
Iterator var12 = var11.iterator();
|
|
|
|
while (var12.hasNext())
|
|
{
|
|
String var13 = (String)var12.next();
|
|
|
|
if (var10)
|
|
{
|
|
var3.add("/" + var13);
|
|
}
|
|
else
|
|
{
|
|
var3.add(var13);
|
|
}
|
|
}
|
|
}
|
|
|
|
return var3;
|
|
}
|
|
else
|
|
{
|
|
String[] var4 = par2Str.split(" ", -1);
|
|
String var5 = var4[var4.length - 1];
|
|
String[] var6 = this.serverConfigManager.getAllUsernames();
|
|
int var7 = var6.length;
|
|
|
|
for (int var8 = 0; var8 < var7; ++var8)
|
|
{
|
|
String var9 = var6[var8];
|
|
|
|
if (CommandBase.doesStringStartWith(var5, var9))
|
|
{
|
|
var3.add(var9);
|
|
}
|
|
}
|
|
|
|
return var3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets mcServer.
|
|
*/
|
|
public static MinecraftServer getServer()
|
|
{
|
|
return mcServer;
|
|
}
|
|
|
|
/**
|
|
* Gets the name of this command sender (usually username, but possibly "Rcon")
|
|
*/
|
|
public String getCommandSenderName()
|
|
{
|
|
return "Server";
|
|
}
|
|
|
|
public void sendChatToPlayer(String par1ChatMessageComponent)
|
|
{
|
|
this.getLogAgent().logInfo(par1ChatMessageComponent);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the command sender is allowed to use the given command.
|
|
*/
|
|
public boolean canCommandSenderUseCommand(int par1, String par2Str)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public ICommandManager getCommandManager()
|
|
{
|
|
return this.commandManager;
|
|
}
|
|
|
|
/**
|
|
* Gets KeyPair instanced in MinecraftServer.
|
|
*/
|
|
public KeyPair getKeyPair()
|
|
{
|
|
return this.serverKeyPair;
|
|
}
|
|
|
|
/**
|
|
* Gets serverPort.
|
|
*/
|
|
public int getServerPort()
|
|
{
|
|
return this.serverPort;
|
|
}
|
|
|
|
public void setServerPort(int par1)
|
|
{
|
|
this.serverPort = par1;
|
|
}
|
|
|
|
/**
|
|
* Returns the username of the server owner (for integrated servers)
|
|
*/
|
|
public String getServerOwner()
|
|
{
|
|
return this.serverOwner;
|
|
}
|
|
|
|
/**
|
|
* Sets the username of the owner of this server (in the case of an integrated server)
|
|
*/
|
|
public void setServerOwner(String par1Str)
|
|
{
|
|
this.serverOwner = par1Str;
|
|
}
|
|
|
|
public boolean isSinglePlayer()
|
|
{
|
|
return this.serverOwner != null;
|
|
}
|
|
|
|
public String getFolderName()
|
|
{
|
|
return this.folderName;
|
|
}
|
|
|
|
public void setFolderName(String par1Str)
|
|
{
|
|
this.folderName = par1Str;
|
|
}
|
|
|
|
public void setWorldName(String par1Str)
|
|
{
|
|
this.worldName = par1Str;
|
|
}
|
|
|
|
public String getWorldName()
|
|
{
|
|
return this.worldName;
|
|
}
|
|
|
|
public void setKeyPair(KeyPair par1KeyPair)
|
|
{
|
|
this.serverKeyPair = par1KeyPair;
|
|
}
|
|
|
|
public void setDifficultyForAllWorlds(int par1)
|
|
{
|
|
for (int var2 = 0; var2 < this.worldServers.length; ++var2)
|
|
{
|
|
WorldServer var3 = this.worldServers[var2];
|
|
|
|
if (var3 != null)
|
|
{
|
|
if (var3.getWorldInfo().isHardcoreModeEnabled())
|
|
{
|
|
var3.difficultySetting = 3;
|
|
var3.setAllowedSpawnTypes(true, true);
|
|
}
|
|
else if (this.isSinglePlayer())
|
|
{
|
|
var3.difficultySetting = par1;
|
|
var3.setAllowedSpawnTypes(var3.difficultySetting > 0, true);
|
|
}
|
|
else
|
|
{
|
|
var3.difficultySetting = par1;
|
|
var3.setAllowedSpawnTypes(this.allowSpawnMonsters(), this.canSpawnAnimals);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected boolean allowSpawnMonsters()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Gets whether this is a demo or not.
|
|
*/
|
|
public boolean isDemo()
|
|
{
|
|
return this.isDemo;
|
|
}
|
|
|
|
/**
|
|
* Sets whether this is a demo or not.
|
|
*/
|
|
public void setDemo(boolean par1)
|
|
{
|
|
this.isDemo = par1;
|
|
}
|
|
|
|
public void canCreateBonusChest(boolean par1)
|
|
{
|
|
this.enableBonusChest = par1;
|
|
}
|
|
|
|
public ISaveFormat getActiveAnvilConverter()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* WARNING : directly calls
|
|
* getActiveAnvilConverter().deleteWorldDirectory(theWorldServer[0].getSaveHandler().getWorldDirectoryName());
|
|
*/
|
|
public void deleteWorldAndStopServer()
|
|
{
|
|
this.worldIsBeingDeleted = true;
|
|
this.getActiveAnvilConverter().flushCache();
|
|
|
|
for (int var1 = 0; var1 < this.worldServers.length; ++var1)
|
|
{
|
|
WorldServer var2 = this.worldServers[var1];
|
|
|
|
if (var2 != null)
|
|
{
|
|
var2.flush();
|
|
}
|
|
}
|
|
|
|
this.getActiveAnvilConverter().deleteWorldDirectory(this.worldServers[0].getSaveHandler().getWorldDirectoryName());
|
|
this.initiateShutdown();
|
|
}
|
|
|
|
public String getTexturePack()
|
|
{
|
|
return this.texturePack;
|
|
}
|
|
|
|
public void setTexturePack(String par1Str)
|
|
{
|
|
this.texturePack = par1Str;
|
|
}
|
|
|
|
/**
|
|
* This is checked to be 16 upon receiving the packet, otherwise the packet is ignored.
|
|
*/
|
|
public int textureSize()
|
|
{
|
|
return 16;
|
|
}
|
|
|
|
public abstract boolean isDedicatedServer();
|
|
|
|
public boolean isServerInOnlineMode()
|
|
{
|
|
return this.onlineMode;
|
|
}
|
|
|
|
public void setOnlineMode(boolean par1)
|
|
{
|
|
this.onlineMode = par1;
|
|
}
|
|
|
|
public boolean getCanSpawnAnimals()
|
|
{
|
|
return this.canSpawnAnimals;
|
|
}
|
|
|
|
public void setCanSpawnAnimals(boolean par1)
|
|
{
|
|
this.canSpawnAnimals = par1;
|
|
}
|
|
|
|
public boolean getCanSpawnNPCs()
|
|
{
|
|
return this.canSpawnNPCs;
|
|
}
|
|
|
|
public void setCanSpawnNPCs(boolean par1)
|
|
{
|
|
this.canSpawnNPCs = par1;
|
|
}
|
|
|
|
public boolean isPVPEnabled()
|
|
{
|
|
return this.pvpEnabled;
|
|
}
|
|
|
|
public void setAllowPvp(boolean par1)
|
|
{
|
|
this.pvpEnabled = par1;
|
|
}
|
|
|
|
public boolean isFlightAllowed()
|
|
{
|
|
return this.allowFlight;
|
|
}
|
|
|
|
public void setAllowFlight(boolean par1)
|
|
{
|
|
this.allowFlight = par1;
|
|
}
|
|
|
|
/**
|
|
* Return whether command blocks are enabled.
|
|
*/
|
|
public abstract boolean isCommandBlockEnabled();
|
|
|
|
public String getMOTD()
|
|
{
|
|
return this.motd;
|
|
}
|
|
|
|
public void setMOTD(String par1Str)
|
|
{
|
|
this.motd = par1Str;
|
|
}
|
|
|
|
public int getBuildLimit()
|
|
{
|
|
return this.buildLimit;
|
|
}
|
|
|
|
public void setBuildLimit(int par1)
|
|
{
|
|
this.buildLimit = par1;
|
|
}
|
|
|
|
public boolean isServerStopped()
|
|
{
|
|
return this.serverStopped;
|
|
}
|
|
|
|
public ServerConfigurationManager getConfigurationManager()
|
|
{
|
|
return this.serverConfigManager;
|
|
}
|
|
|
|
public void setConfigurationManager(ServerConfigurationManager par1ServerConfigurationManager)
|
|
{
|
|
this.serverConfigManager = par1ServerConfigurationManager;
|
|
}
|
|
|
|
/**
|
|
* Sets the game type for all worlds.
|
|
*/
|
|
public void setGameType(EnumGameType par1EnumGameType)
|
|
{
|
|
for (int var2 = 0; var2 < this.worldServers.length; ++var2)
|
|
{
|
|
getServer().worldServers[var2].getWorldInfo().setGameType(par1EnumGameType);
|
|
}
|
|
}
|
|
|
|
|
|
public boolean serverIsInRunLoop()
|
|
{
|
|
return this.serverIsRunning;
|
|
}
|
|
|
|
public boolean getGuiEnabled()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* On dedicated does nothing. On integrated, sets commandsAllowedForAll, gameType and allows external connections.
|
|
*/
|
|
public abstract String shareToLAN(EnumGameType var1, boolean var2);
|
|
|
|
public int getTickCounter()
|
|
{
|
|
return this.tickCounter;
|
|
}
|
|
|
|
public void enableProfiling()
|
|
{
|
|
this.startProfiling = true;
|
|
}
|
|
/**
|
|
* Return the position for this command sender.
|
|
*/
|
|
public ChunkCoordinates getPlayerCoordinates()
|
|
{
|
|
return new ChunkCoordinates(0, 0, 0);
|
|
}
|
|
|
|
public World getEntityWorld()
|
|
{
|
|
return this.worldServers[0];
|
|
}
|
|
|
|
/**
|
|
* Return the spawn protection area's size.
|
|
*/
|
|
public int getSpawnProtectionSize()
|
|
{
|
|
return 16;
|
|
}
|
|
|
|
/**
|
|
* Returns true if a player does not have permission to edit the block at the given coordinates.
|
|
*/
|
|
public boolean isBlockProtected(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public abstract ILogAgent getLogAgent();
|
|
|
|
public void setForceGamemode(boolean par1)
|
|
{
|
|
this.isGamemodeForced = par1;
|
|
}
|
|
|
|
public boolean getForceGamemode()
|
|
{
|
|
return this.isGamemodeForced;
|
|
}
|
|
|
|
public Proxy getServerProxy()
|
|
{
|
|
return this.serverProxy;
|
|
}
|
|
|
|
/**
|
|
* returns the difference, measured in milliseconds, between the current system time and midnight, January 1, 1970
|
|
* UTC.
|
|
*/
|
|
public static long getSystemTimeMillis()
|
|
{
|
|
return System.currentTimeMillis();
|
|
}
|
|
|
|
public int func_143007_ar()
|
|
{
|
|
return this.field_143008_E;
|
|
}
|
|
|
|
public void func_143006_e(int par1)
|
|
{
|
|
this.field_143008_E = par1;
|
|
}
|
|
|
|
/**
|
|
* Gets the current player count, maximum player count, and player entity list.
|
|
*/
|
|
public static ServerConfigurationManager getServerConfigurationManager(MinecraftServer par0MinecraftServer)
|
|
{
|
|
return par0MinecraftServer.serverConfigManager;
|
|
}
|
|
}
|