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

422 Zeilen
13 KiB
Java

2010-12-22 16:22:23 +01:00
package net.minecraft.server;
2011-01-29 22:50:29 +01:00
import java.awt.GraphicsEnvironment;
2010-12-22 16:22:23 +01:00
import java.io.File;
import java.io.IOException;
2010-12-22 16:22:23 +01:00
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
2010-12-28 20:52:24 +01:00
import java.util.Iterator;
2010-12-22 16:22:23 +01:00
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
2010-12-28 20:52:24 +01:00
// CraftBukkit start
2011-02-23 13:56:36 +01:00
import java.io.PrintStream;
import java.net.UnknownHostException;
import jline.ConsoleReader;
import joptsimple.OptionSet;
import org.bukkit.command.ConsoleCommandSender;
2010-12-22 16:22:23 +01:00
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.LoggerOutputStream;
import org.bukkit.craftbukkit.command.ColouredConsoleSender;
2011-02-03 00:53:04 +01:00
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
import org.bukkit.event.Event;
import org.bukkit.event.world.WorldEvent;
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
2011-02-23 03:37:56 +01:00
public class MinecraftServer implements Runnable, ICommandListener {
2010-12-22 16:22:23 +01:00
public static Logger a = Logger.getLogger("Minecraft");
public static HashMap b = new HashMap();
2010-12-26 03:20:29 +01:00
public NetworkListenThread c;
public PropertyManager d;
2011-02-23 13:56:36 +01:00
// public WorldServer e; // CraftBukkit - removed
2010-12-26 03:20:29 +01:00
public ServerConfigurationManager f;
2011-02-23 03:37:56 +01:00
private ConsoleCommandHandler o;
private boolean p = true;
2011-01-29 22:50:29 +01:00
public boolean g = false;
int h = 0;
2010-12-22 16:22:23 +01:00
public String i;
public int j;
2011-02-23 03:37:56 +01:00
private List q = new ArrayList();
private List r = Collections.synchronizedList(new ArrayList());
2010-12-26 03:20:29 +01:00
public EntityTracker k;
2010-12-22 16:22:23 +01:00
public boolean l;
public boolean m;
public boolean n;
2010-12-28 20:52:24 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
public int spawnProtection;
public List<WorldServer> worlds = new ArrayList<WorldServer>();
2011-01-29 22:50:29 +01:00
public CraftServer server;
public OptionSet options;
public ColouredConsoleSender console;
public ConsoleReader reader;
// Craftbukkit end
2010-12-22 16:22:23 +01:00
2011-02-23 13:56:36 +01:00
public MinecraftServer(OptionSet options) { // CraftBukkit - adds argument OptionSet
new ThreadSleepForever(this);
// CraftBukkit start
this.options = options;
try {
this.reader = new ConsoleReader();
} catch (IOException ex) {
Logger.getLogger(MinecraftServer.class.getName()).log(Level.SEVERE, null, ex);
}
// CraftBukkit end
}
private boolean d() throws UnknownHostException { // CraftBukkit - added throws UnknownHostException
2011-02-23 03:37:56 +01:00
this.o = new ConsoleCommandHandler(this);
2010-12-28 20:52:24 +01:00
ThreadCommandReader threadcommandreader = new ThreadCommandReader(this);
2010-12-22 16:22:23 +01:00
2011-01-29 22:50:29 +01:00
threadcommandreader.setDaemon(true);
threadcommandreader.start();
ConsoleLogManager.a(reader); // Craftbukkit
2011-02-23 13:56:36 +01:00
// CraftBukkit start
System.setOut(new PrintStream(new LoggerOutputStream(a, Level.INFO), true));
System.setErr(new PrintStream(new LoggerOutputStream(a, Level.SEVERE), true));
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-02-23 03:37:56 +01:00
a.info("Starting minecraft server version Beta 1.3");
2010-12-22 16:22:23 +01:00
if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
a.warning("**** NOT ENOUGH RAM!");
a.warning("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
}
2011-01-29 22:50:29 +01:00
2010-12-22 16:22:23 +01:00
a.info("Loading properties");
2011-02-23 13:56:36 +01:00
this.d = new PropertyManager(options); // CraftBukkit
2011-01-29 22:50:29 +01:00
String s = this.d.a("server-ip", "");
2010-12-22 16:22:23 +01:00
2011-01-29 22:50:29 +01:00
this.l = this.d.a("online-mode", true);
this.m = this.d.a("spawn-animals", true);
this.n = this.d.a("pvp", true);
this.spawnProtection = this.d.a("spawn-protection", 16); // CraftBukkit Configurable spawn protection start
2010-12-28 20:52:24 +01:00
InetAddress inetaddress = null;
2010-12-22 16:22:23 +01:00
2010-12-28 20:52:24 +01:00
if (s.length() > 0) {
inetaddress = InetAddress.getByName(s);
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
int i = this.d.a("server-port", 25565);
a.info("Starting Minecraft server on " + (s.length() == 0 ? "*" : s) + ":" + i);
2010-12-22 16:22:23 +01:00
try {
2011-01-29 22:50:29 +01:00
this.c = new NetworkListenThread(this, inetaddress, i);
} catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable
2010-12-22 16:22:23 +01:00
a.warning("**** FAILED TO BIND TO PORT!");
2011-01-29 22:50:29 +01:00
a.log(Level.WARNING, "The exception was: " + ioexception.toString());
2010-12-22 16:22:23 +01:00
a.warning("Perhaps a server is already running on that port?");
return false;
}
2011-01-29 22:50:29 +01:00
if (!this.l) {
2010-12-22 16:22:23 +01:00
a.warning("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
a.warning("The server will make no attempt to authenticate usernames. Beware.");
a.warning("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose.");
a.warning("To change this, set \"online-mode\" to \"true\" in the server.settings file.");
}
2010-12-26 03:20:29 +01:00
2011-01-29 22:50:29 +01:00
this.f = new ServerConfigurationManager(this);
this.k = new EntityTracker(this);
2011-02-23 03:37:56 +01:00
long j = System.nanoTime();
2011-01-29 22:50:29 +01:00
String s1 = this.d.a("level-name", "world");
a.info("Preparing level \"" + s1 + "\"");
2011-02-23 03:37:56 +01:00
this.a((Convertable) (new WorldLoaderServer(new File("."))), s1);
// CraftBukkit start
long elapsed = System.nanoTime() - j;
String time = String.format( "%.3fs", elapsed / 10000000000.0D );
a.info("Done (" + time + ")! For help, type \"help\" or \"?\"");
// CraftBukkit end
2010-12-22 16:22:23 +01:00
return true;
}
2011-02-23 03:37:56 +01:00
private void a(Convertable convertable, String s) {
if (convertable.a(s)) {
a.info("Converting map!");
convertable.a(s, new ConvertProgressUpdater(this));
}
2010-12-22 16:22:23 +01:00
a.info("Preparing start region");
2011-02-23 13:56:36 +01:00
// CraftBukkit start
2011-02-23 03:37:56 +01:00
WorldServer world = new WorldServer(this, new ServerNBTManager(new File("."), s, true), s, this.d.a("hellworld", false) ? -1 : 0);
world.a(new WorldManager(this, world));
2011-02-23 03:37:56 +01:00
world.j = this.d.a("spawn-monsters", true) ? 1 : 0;
world.a(this.d.a("spawn-monsters", true), this.m);
this.f.a(world);
worlds.add(world);
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-01-29 22:50:29 +01:00
short short1 = 196;
long i = System.currentTimeMillis();
2011-02-23 13:56:36 +01:00
ChunkCoordinates chunkcoordinates = worlds.get(0).l(); // CraftBukkit
2011-01-29 22:50:29 +01:00
2011-02-23 03:37:56 +01:00
for (int j = -short1; j <= short1 && this.p; j += 16) {
for (int k = -short1; k <= short1 && this.p; k += 16) {
2011-01-29 22:50:29 +01:00
long l = System.currentTimeMillis();
if (l < i) {
i = l;
2011-01-14 14:31:10 +01:00
}
2011-01-29 22:50:29 +01:00
if (l > i + 1000L) {
int i1 = (short1 * 2 + 1) * (short1 * 2 + 1);
int j1 = (j + short1) * (short1 * 2 + 1) + k + 1;
this.a("Preparing spawn area", j1 * 100 / i1);
i = l;
2011-01-14 14:31:10 +01:00
}
2011-01-29 22:50:29 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
for (WorldServer worldserver: worlds) {
2011-02-23 03:37:56 +01:00
world.u.d(chunkcoordinates.a + j >> 4, chunkcoordinates.c + k >> 4);
2011-01-29 22:50:29 +01:00
2011-02-23 03:37:56 +01:00
while (world.e() && this.p) {
;
}
2010-12-22 16:22:23 +01:00
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
this.e();
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
private void a(String s, int i) {
this.i = s;
this.j = i;
a.info(s + ": " + i + "%");
2010-12-22 16:22:23 +01:00
}
private void e() {
2011-01-29 22:50:29 +01:00
this.i = null;
this.j = 0;
server.loadPlugins(); // CraftBukkit
2010-12-22 16:22:23 +01:00
}
void f() { //CraftBukkit - private -> default
2010-12-22 16:22:23 +01:00
a.info("Saving chunks");
2011-02-23 13:56:36 +01:00
// CraftBukkit start
for (WorldServer world: worlds) {
world.a(true, (IProgressUpdate) null);
2011-02-23 03:37:56 +01:00
world.r();
2011-02-23 13:56:36 +01:00
WorldEvent event = new WorldEvent( Event.Type.WORLD_SAVED, world.getWorld() );
server.getPluginManager().callEvent( event );
}
this.f.d(); // CraftBukkit - player data should be saved whenever a save happens.
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2010-12-22 16:22:23 +01:00
}
private void g() {
a.info("Stopping server");
// CraftBukkit start
2011-02-23 13:56:36 +01:00
if (server != null) {
server.disablePlugins();
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-02-02 00:32:18 +01:00
2011-01-29 22:50:29 +01:00
if (this.f != null) {
this.f.d();
2011-01-27 22:15:41 +01:00
}
2011-02-23 13:56:36 +01:00
if (this.worlds.size() > 0) { // CraftBukkit
2011-01-29 22:50:29 +01:00
this.f();
2010-12-22 16:22:23 +01:00
}
}
public void a() {
2011-02-23 03:37:56 +01:00
this.p = false;
2010-12-22 16:22:23 +01:00
}
public void run() {
try {
2011-01-29 22:50:29 +01:00
if (this.d()) {
long i = System.currentTimeMillis();
2010-12-28 20:52:24 +01:00
2011-02-23 03:37:56 +01:00
for (long j = 0L; this.p; Thread.sleep(1L)) {
2011-01-29 22:50:29 +01:00
long k = System.currentTimeMillis();
long l = k - i;
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
if (l > 2000L) {
a.warning("Can\'t keep up! Did the system time change, or is the server overloaded?");
l = 2000L;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
if (l < 0L) {
2010-12-22 16:22:23 +01:00
a.warning("Time ran backwards! Did the system time change?");
2011-01-29 22:50:29 +01:00
l = 0L;
2010-12-22 16:22:23 +01:00
}
2011-01-29 22:50:29 +01:00
j += l;
i = k;
2011-02-23 13:56:36 +01:00
// CraftBukkit - TODO - Replace with loop?
if (this.worlds.size() > 0 && this.worlds.get(0).q()) {
2011-01-29 22:50:29 +01:00
this.h();
2011-02-23 03:37:56 +01:00
j = 0L;
} else {
while (j > 50L) {
j -= 50L;
this.h();
}
2010-12-22 16:22:23 +01:00
}
}
} else {
2011-02-23 03:37:56 +01:00
while (this.p) {
2011-01-29 22:50:29 +01:00
this.b();
2010-12-22 16:22:23 +01:00
try {
Thread.sleep(10L);
2010-12-28 20:52:24 +01:00
} catch (InterruptedException interruptedexception) {
interruptedexception.printStackTrace();
2010-12-22 16:22:23 +01:00
}
}
}
2011-02-23 03:37:56 +01:00
} catch (Throwable throwable) {
throwable.printStackTrace();
a.log(Level.SEVERE, "Unexpected exception", throwable);
2011-01-29 22:50:29 +01:00
2011-02-23 03:37:56 +01:00
while (this.p) {
2011-01-29 22:50:29 +01:00
this.b();
2010-12-22 16:22:23 +01:00
try {
Thread.sleep(10L);
2010-12-28 20:52:24 +01:00
} catch (InterruptedException interruptedexception1) {
interruptedexception1.printStackTrace();
2010-12-22 16:22:23 +01:00
}
}
} finally {
2011-01-14 14:31:10 +01:00
try {
2011-01-29 22:50:29 +01:00
this.g();
this.g = true;
2011-02-23 03:37:56 +01:00
} catch (Throwable throwable1) {
throwable1.printStackTrace();
2011-01-14 14:31:10 +01:00
} finally {
System.exit(0);
}
2010-12-22 16:22:23 +01:00
}
}
private void h() {
ArrayList arraylist = new ArrayList();
2011-01-29 22:50:29 +01:00
Iterator iterator = b.keySet().iterator();
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
while (iterator.hasNext()) {
2010-12-28 20:52:24 +01:00
String s = (String) iterator.next();
2011-01-29 22:50:29 +01:00
int i = ((Integer) b.get(s)).intValue();
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
if (i > 0) {
b.put(s, Integer.valueOf(i - 1));
2010-12-22 16:22:23 +01:00
} else {
2011-01-29 22:50:29 +01:00
arraylist.add(s);
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
2011-01-29 22:50:29 +01:00
int j;
for (j = 0; j < arraylist.size(); ++j) {
b.remove(arraylist.get(j));
2010-12-22 16:22:23 +01:00
}
2010-12-26 03:20:29 +01:00
AxisAlignedBB.a();
Vec3D.a();
2011-01-29 22:50:29 +01:00
++this.h;
2011-02-23 13:56:36 +01:00
// CraftBukkit start
2011-01-29 22:50:29 +01:00
if (this.h % 20 == 0) {
for (int i = 0; i < this.f.b.size(); ++i) {
EntityPlayer entityplayer = (EntityPlayer) this.f.b.get(i);
2011-02-23 03:37:56 +01:00
entityplayer.a.b((Packet) (new Packet4UpdateTime(entityplayer.world.k())));
}
2010-12-22 16:22:23 +01:00
}
((CraftScheduler) server.getScheduler()).mainThreadHeartbeat(this.h);
2011-02-23 13:56:36 +01:00
for (WorldServer world: worlds) {
2011-02-23 03:37:56 +01:00
world.g();
2011-01-29 22:50:29 +01:00
2011-02-23 03:37:56 +01:00
while (world.e()) {
;
}
2011-02-23 03:37:56 +01:00
world.d();
2010-12-22 16:22:23 +01:00
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-01-29 22:50:29 +01:00
this.c.a();
this.f.b();
this.k.a();
2011-02-23 03:37:56 +01:00
for (j = 0; j < this.q.size(); ++j) {
((IUpdatePlayerListBox) this.q.get(j)).a();
2010-12-28 20:52:24 +01:00
}
2010-12-22 16:22:23 +01:00
try {
2011-01-29 22:50:29 +01:00
this.b();
2010-12-28 20:52:24 +01:00
} catch (Exception exception) {
2011-01-29 22:50:29 +01:00
a.log(Level.WARNING, "Unexpected exception while parsing console command", exception);
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
public void a(String s, ICommandListener icommandlistener) {
2011-02-23 03:37:56 +01:00
this.r.add(new ServerCommand(s, icommandlistener));
2010-12-22 16:22:23 +01:00
}
public void b() {
2011-02-23 03:37:56 +01:00
while (this.r.size() > 0) {
ServerCommand servercommand = (ServerCommand) this.r.remove(0);
2010-12-28 20:52:24 +01:00
2011-02-23 13:56:36 +01:00
// CraftBukkit start
2011-02-23 03:37:56 +01:00
if (server.dispatchCommand(console, servercommand.a)) {
continue;
}
2011-02-23 13:56:36 +01:00
// CraftBukkit end
2011-02-23 03:37:56 +01:00
this.o.a(servercommand);
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
public void a(IUpdatePlayerListBox iupdateplayerlistbox) {
2011-02-23 03:37:56 +01:00
this.q.add(iupdateplayerlistbox);
2010-12-22 16:22:23 +01:00
}
2011-02-23 13:56:36 +01:00
public static void main(final OptionSet options) { // CraftBukkit - replaces main(String args[])
2010-12-22 16:22:23 +01:00
try {
2011-01-30 13:51:20 +01:00
MinecraftServer minecraftserver = new MinecraftServer(options);
2011-01-29 22:50:29 +01:00
// CraftBukkit - remove gui
2010-12-22 16:22:23 +01:00
2010-12-28 20:52:24 +01:00
(new ThreadServerApplication("Server thread", minecraftserver)).start();
} catch (Exception exception) {
2011-01-29 22:50:29 +01:00
a.log(Level.SEVERE, "Failed to start the minecraft server", exception);
2010-12-22 16:22:23 +01:00
}
}
2010-12-28 20:52:24 +01:00
public File a(String s) {
return new File(s);
2010-12-22 16:22:23 +01:00
}
2010-12-28 20:52:24 +01:00
public void b(String s) {
a.info(s);
2010-12-22 16:22:23 +01:00
}
public String c() {
return "CONSOLE";
}
2010-12-28 20:52:24 +01:00
public static boolean a(MinecraftServer minecraftserver) {
2011-02-23 03:37:56 +01:00
return minecraftserver.p;
2010-12-28 20:52:24 +01:00
}
}