From 84bf373c55d394135657867c23e80e1de67f62a7 Mon Sep 17 00:00:00 2001 From: Erik Broes Date: Sat, 1 Jan 2011 11:47:24 +0100 Subject: Transition to Maven --- .../java/net/minecraft/server/BlockFlowing.java | 252 +++++++++ .../java/net/minecraft/server/MinecraftServer.java | 487 ++++++++++++++++++ .../net/minecraft/server/NetServerHandler.java | 567 +++++++++++++++++++++ .../server/ServerConfigurationManager.java | 369 ++++++++++++++ .../java/net/minecraft/server/WorldServer.java | 182 +++++++ .../java/org/bukkit/craftbukkit/CraftBlock.java | 152 ++++++ .../java/org/bukkit/craftbukkit/CraftChunk.java | 37 ++ .../java/org/bukkit/craftbukkit/CraftEntity.java | 72 +++ .../org/bukkit/craftbukkit/CraftHumanEntity.java | 41 ++ .../org/bukkit/craftbukkit/CraftLivingEntity.java | 42 ++ .../java/org/bukkit/craftbukkit/CraftPlayer.java | 67 +++ .../java/org/bukkit/craftbukkit/CraftServer.java | 80 +++ .../java/org/bukkit/craftbukkit/CraftWorld.java | 155 ++++++ src/main/java/org/bukkit/craftbukkit/Main.java | 16 + 14 files changed, 2519 insertions(+) create mode 100644 src/main/java/net/minecraft/server/BlockFlowing.java create mode 100644 src/main/java/net/minecraft/server/MinecraftServer.java create mode 100644 src/main/java/net/minecraft/server/NetServerHandler.java create mode 100644 src/main/java/net/minecraft/server/ServerConfigurationManager.java create mode 100644 src/main/java/net/minecraft/server/WorldServer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftBlock.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftChunk.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftPlayer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftServer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftWorld.java create mode 100644 src/main/java/org/bukkit/craftbukkit/Main.java (limited to 'src/main/java') diff --git a/src/main/java/net/minecraft/server/BlockFlowing.java b/src/main/java/net/minecraft/server/BlockFlowing.java new file mode 100644 index 00000000..86405a89 --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockFlowing.java @@ -0,0 +1,252 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.BlockFace; +import org.bukkit.craftbukkit.CraftBlock; +import org.bukkit.event.Event.Type; +import org.bukkit.event.block.BlockFromToEvent; + +public class BlockFlowing extends BlockFluids +{ + + protected BlockFlowing(int i1, Material material) + { + super(i1, material); + a = 0; + b = new boolean[4]; + c = new int[4]; + } + + private void i(World world, int i1, int j1, int k1) + { + int l1 = world.b(i1, j1, k1); + world.a(i1, j1, k1, bh + 1, l1); + world.b(i1, j1, k1, i1, j1, k1); + world.g(i1, j1, k1); + } + + public void a(World world, int i1, int j1, int k1, Random random) + { + int l1 = g(world, i1, j1, k1); + byte byte0 = 1; + if(bs == Material.g && !world.q.d) + byte0 = 2; + boolean flag = true; + if(l1 > 0) + { + int i2 = -100; + a = 0; + i2 = e(world, i1 - 1, j1, k1, i2); + i2 = e(world, i1 + 1, j1, k1, i2); + i2 = e(world, i1, j1, k1 - 1, i2); + i2 = e(world, i1, j1, k1 + 1, i2); + int j2 = i2 + byte0; + if(j2 >= 8 || i2 < 0) + j2 = -1; + if(g(world, i1, j1 + 1, k1) >= 0) + { + int l2 = g(world, i1, j1 + 1, k1); + if(l2 >= 8) + j2 = l2; + else + j2 = l2 + 8; + } + if(a >= 2 && bs == Material.f) + if(world.d(i1, j1 - 1, k1)) + j2 = 0; + else + if(world.c(i1, j1 - 1, k1) == bs && world.b(i1, j1, k1) == 0) + j2 = 0; + if(bs == Material.g && l1 < 8 && j2 < 8 && j2 > l1 && random.nextInt(4) != 0) + { + j2 = l1; + flag = false; + } + if(j2 != l1) + { + l1 = j2; + if(l1 < 0) + { + world.d(i1, j1, k1, 0); + } else + { + world.b(i1, j1, k1, l1); + world.h(i1, j1, k1, bh); + world.g(i1, j1, k1, bh); + } + } else + if(flag) + i(world, i1, j1, k1); + } else + { + i(world, i1, j1, k1); + } + + // Craftbukkit start + CraftBlock source = (CraftBlock) ((WorldServer) world).getWorld().getBlockAt(i1, j1, k1); + + if(l(world, i1, j1 - 1, k1)) + { + // Craftbucket send "down" to the server + BlockFromToEvent blockFlow = new BlockFromToEvent(Type.BLOCK_FLOW, source, BlockFace.Down); + ((WorldServer) world).getServer().getPluginManager().callEvent(blockFlow); + + if (!blockFlow.isCancelled()) { + if(l1 >= 8) + world.b(i1, j1 - 1, k1, bh, l1); + else + world.b(i1, j1 - 1, k1, bh, l1 + 8); + } + } else + if(l1 >= 0 && (l1 == 0 || k(world, i1, j1 - 1, k1))) + { + boolean aflag[] = j(world, i1, j1, k1); + int k2 = l1 + byte0; + if(l1 >= 8) + k2 = 1; + if(k2 >= 8) + return; + + // Craftbukkit start + BlockFace[] faces = new BlockFace[]{ BlockFace.North, BlockFace.South, BlockFace.East, BlockFace.West }; + for (BlockFace currentFace : faces) { + int index = 0; + if (aflag[index]) { + BlockFromToEvent event = new BlockFromToEvent(Type.BLOCK_FLOW, source, currentFace); + ((WorldServer) world).getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) + f(world, i1 + currentFace.getModX(), j1, k1 + currentFace.getModZ(), k2); + } + index++; + } + // Craftbukkit stop + } + } + + private void f(World world, int i1, int j1, int k1, int l1) + { + if(l(world, i1, j1, k1)) + { + int i2 = world.a(i1, j1, k1); + if(i2 > 0) + if(bs == Material.g) + h(world, i1, j1, k1); + else + Block.m[i2].a_(world, i1, j1, k1, world.b(i1, j1, k1)); + world.b(i1, j1, k1, bh, l1); + } + } + + private int a(World world, int i1, int j1, int k1, int l1, int i2) + { + int j2 = 1000; + for(int k2 = 0; k2 < 4; k2++) + { + if(k2 == 0 && i2 == 1 || k2 == 1 && i2 == 0 || k2 == 2 && i2 == 3 || k2 == 3 && i2 == 2) + continue; + int l2 = i1; + int i3 = j1; + int j3 = k1; + if(k2 == 0) + l2--; + if(k2 == 1) + l2++; + if(k2 == 2) + j3--; + if(k2 == 3) + j3++; + if(k(world, l2, i3, j3) || world.c(l2, i3, j3) == bs && world.b(l2, i3, j3) == 0) + continue; + if(!k(world, l2, i3 - 1, j3)) + return l1; + if(l1 >= 4) + continue; + int k3 = a(world, l2, i3, j3, l1 + 1, k2); + if(k3 < j2) + j2 = k3; + } + + return j2; + } + + private boolean[] j(World world, int i1, int j1, int k1) + { + for(int l1 = 0; l1 < 4; l1++) + { + c[l1] = 1000; + int j2 = i1; + int i3 = j1; + int j3 = k1; + if(l1 == 0) + j2--; + if(l1 == 1) + j2++; + if(l1 == 2) + j3--; + if(l1 == 3) + j3++; + if(k(world, j2, i3, j3) || world.c(j2, i3, j3) == bs && world.b(j2, i3, j3) == 0) + continue; + if(!k(world, j2, i3 - 1, j3)) + c[l1] = 0; + else + c[l1] = a(world, j2, i3, j3, 1, l1); + } + + int i2 = c[0]; + for(int k2 = 1; k2 < 4; k2++) + if(c[k2] < i2) + i2 = c[k2]; + + for(int l2 = 0; l2 < 4; l2++) + b[l2] = c[l2] == i2; + + return b; + } + + private boolean k(World world, int i1, int j1, int k1) + { + int l1 = world.a(i1, j1, k1); + if(l1 == Block.aE.bh || l1 == Block.aL.bh || l1 == Block.aD.bh || l1 == Block.aF.bh || l1 == Block.aX.bh) + return true; + if(l1 == 0) + return false; + Material material = Block.m[l1].bs; + return material.a(); + } + + protected int e(World world, int i1, int j1, int k1, int l1) + { + int i2 = g(world, i1, j1, k1); + if(i2 < 0) + return l1; + if(i2 == 0) + a++; + if(i2 >= 8) + i2 = 0; + return l1 >= 0 && i2 >= l1 ? l1 : i2; + } + + private boolean l(World world, int i1, int j1, int k1) + { + Material material = world.c(i1, j1, k1); + if(material == bs) + return false; + if(material == Material.g) + return false; + else + return !k(world, i1, j1, k1); + } + + public void e(World world, int i1, int j1, int k1) + { + super.e(world, i1, j1, k1); + if(world.a(i1, j1, k1) == bh) + world.h(i1, j1, k1, bh); + } + + int a; + boolean b[]; + int c[]; +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java new file mode 100644 index 00000000..8d49cfa6 --- /dev/null +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +1,487 @@ +package net.minecraft.server; + + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.craftbukkit.CraftServer; + + +public class MinecraftServer + implements ICommandListener, Runnable { + + public static Logger a = Logger.getLogger("Minecraft"); + public static HashMap b = new HashMap(); + public NetworkListenThread c; + public PropertyManager d; + public WorldServer e; + public ServerConfigurationManager f; + private boolean o; + public boolean g; + int h; + public String i; + public int j; + private List p; + private List q; + public EntityTracker k; + public boolean l; + public boolean m; + public boolean n; + + public CraftServer server; // CraftBukkit + + public MinecraftServer() { + o = true; + g = false; + h = 0; + p = new ArrayList(); + q = Collections.synchronizedList(new ArrayList()); + new ThreadSleepForever(this); + } + + // CraftBukkit: added throws UnknownHostException + private boolean d() throws UnknownHostException { + ThreadCommandReader threadcommandreader = new ThreadCommandReader(this); + + threadcommandreader.setDaemon(true); + threadcommandreader.start(); + ConsoleLogManager.a(); + a.info("Starting minecraft server version Beta 1.1_02"); + 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\""); + } + a.info("Loading properties"); + d = new PropertyManager(new File("server.properties")); + String s = d.a("server-ip", ""); + + l = d.a("online-mode", true); + m = d.a("spawn-animals", true); + n = d.a("pvp", true); + InetAddress inetaddress = null; + + if (s.length() > 0) { + inetaddress = InetAddress.getByName(s); + } + int i1 = d.a("server-port", 25565); + + a.info((new StringBuilder()).append("Starting Minecraft server on ").append(s.length() != 0 ? s : "*").append(":").append(i1).toString()); + try { + c = new NetworkListenThread(this, inetaddress, i1); + // CraftBukkit: Be more generic; IOException -> Throwable + } catch (Throwable ioexception) { + a.warning("**** FAILED TO BIND TO PORT!"); + a.log(Level.WARNING, (new StringBuilder()).append("The exception was: ").append(ioexception.toString()).toString()); + a.warning("Perhaps a server is already running on that port?"); + return false; + } + if (!l) { + 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."); + } + + server = new CraftServer(this, "1.1"); // CraftBukkit + + f = new ServerConfigurationManager(this); + k = new EntityTracker(this); + String s1 = d.a("level-name", "world"); + + a.info((new StringBuilder()).append("Preparing level \"").append(s1).append("\"").toString()); + c(s1); + a.info("Done! For help, type \"help\" or \"?\""); + return true; + } + + private void c(String s) { + a.info("Preparing start region"); + e = new WorldServer(this, new File("."), s, d.a("hellworld", false) ? -1 : 0); + e.a(new WorldManager(this)); + e.k = d.a("spawn-monsters", true) ? 1 : 0; + f.a(e); + byte byte0 = 10; + + for (int i1 = -byte0; i1 <= byte0; i1++) { + a("Preparing spawn area", ((i1 + byte0) * 100) / (byte0 + byte0 + 1)); + for (int j1 = -byte0; j1 <= byte0; j1++) { + if (!o) { + return; + } + e.A.d((e.m >> 4) + i1, (e.o >> 4) + j1); + } + + } + + e(); + } + + private void a(String s, int i1) { + i = s; + j = i1; + System.out.println((new StringBuilder()).append(s).append(": ").append(i1).append("%").toString()); + } + + private void e() { + i = null; + j = 0; + } + + private void f() { + a.info("Saving chunks"); + e.a(true, null); + } + + private void g() { + a.info("Stopping server"); + if (f != null) { + f.d(); + } + if (e != null) { + f(); + } + } + + public void a() { + o = false; + } + + public void run() { + try { + if (d()) { + long l1 = System.currentTimeMillis(); + long l2 = 0L; + + while (o) { + long l3 = System.currentTimeMillis(); + long l4 = l3 - l1; + + if (l4 > 2000L) { + a.warning("Can't keep up! Did the system time change, or is the server overloaded?"); + l4 = 2000L; + } + if (l4 < 0L) { + a.warning("Time ran backwards! Did the system time change?"); + l4 = 0L; + } + l2 += l4; + l1 = l3; + while (l2 > 50L) { + l2 -= 50L; + h(); + } + Thread.sleep(1L); + } + } else { + while (o) { + b(); + try { + Thread.sleep(10L); + } catch (InterruptedException interruptedexception) { + interruptedexception.printStackTrace(); + } + } + } + } catch (Exception exception) { + exception.printStackTrace(); + a.log(Level.SEVERE, "Unexpected exception", exception); + while (o) { + b(); + try { + Thread.sleep(10L); + } catch (InterruptedException interruptedexception1) { + interruptedexception1.printStackTrace(); + } + } + } finally { + g(); + g = true; + System.exit(0); + } + } + + private void h() { + ArrayList arraylist = new ArrayList(); + + for (Iterator iterator = b.keySet().iterator(); iterator.hasNext();) { + String s = (String) iterator.next(); + int k1 = ((Integer) b.get(s)).intValue(); + + if (k1 > 0) { + b.put(s, Integer.valueOf(k1 - 1)); + } else { + arraylist.add(s); + } + } + + for (int i1 = 0; i1 < arraylist.size(); i1++) { + b.remove(arraylist.get(i1)); + } + + AxisAlignedBB.a(); + Vec3D.a(); + h++; + if (h % 20 == 0) { + f.a(new Packet4UpdateTime(e.e)); + } + e.f(); + while (e.d()) { + ; + } + e.c(); + c.a(); + f.b(); + k.a(); + for (int j1 = 0; j1 < p.size(); j1++) { + ((IUpdatePlayerListBox) p.get(j1)).a(); + } + + try { + b(); + } catch (Exception exception) { + a.log(Level.WARNING, "Unexpected exception while parsing console command", exception); + } + } + + public void a(String s, ICommandListener icommandlistener) { + q.add(new ServerCommand(s, icommandlistener)); + } + + public void b() { + do { + if (q.size() <= 0) { + break; + } + ServerCommand servercommand = (ServerCommand) q.remove(0); + String s = servercommand.a; + ICommandListener icommandlistener = servercommand.b; + String s1 = icommandlistener.c(); + + if (s.toLowerCase().startsWith("help") || s.toLowerCase().startsWith("?")) { + icommandlistener.b("To run the server without a gui, start it like this:"); + icommandlistener.b(" java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui"); + icommandlistener.b("Console commands:"); + icommandlistener.b(" help or ? shows this message"); + icommandlistener.b(" kick removes a player from the server"); + icommandlistener.b(" ban bans a player from the server"); + icommandlistener.b(" pardon pardons a banned player so that they can connect again"); + icommandlistener.b(" ban-ip bans an IP address from the server"); + icommandlistener.b(" pardon-ip pardons a banned IP address so that they can connect again"); + icommandlistener.b(" op turns a player into an op"); + icommandlistener.b(" deop removes op status from a player"); + icommandlistener.b(" tp moves one player to the same location as another player"); + icommandlistener.b(" give [num] gives a player a resource"); + icommandlistener.b(" tell sends a private message to a player"); + icommandlistener.b(" stop gracefully stops the server"); + icommandlistener.b(" save-all forces a server-wide level save"); + icommandlistener.b(" save-off disables terrain saving (useful for backup scripts)"); + icommandlistener.b(" save-on re-enables terrain saving"); + icommandlistener.b(" list lists all currently connected players"); + icommandlistener.b(" say broadcasts a message to all players"); + } else if (s.toLowerCase().startsWith("list")) { + icommandlistener.b((new StringBuilder()).append("Connected players: ").append(f.c()).toString()); + } else if (s.toLowerCase().startsWith("stop")) { + a(s1, "Stopping the server.."); + o = false; + } else if (s.toLowerCase().startsWith("save-all")) { + a(s1, "Forcing save.."); + e.a(true, null); + a(s1, "Save complete."); + } else if (s.toLowerCase().startsWith("save-off")) { + a(s1, "Disabling level saving.."); + e.C = true; + } else if (s.toLowerCase().startsWith("save-on")) { + a(s1, "Enabling level saving.."); + e.C = false; + } else if (s.toLowerCase().startsWith("op ")) { + String s2 = s.substring(s.indexOf(" ")).trim(); + + f.e(s2); + a(s1, (new StringBuilder()).append("Opping ").append(s2).toString()); + f.a(s2, "\247eYou are now op!"); + } else if (s.toLowerCase().startsWith("deop ")) { + String s3 = s.substring(s.indexOf(" ")).trim(); + + f.f(s3); + f.a(s3, "\247eYou are no longer op!"); + a(s1, (new StringBuilder()).append("De-opping ").append(s3).toString()); + } else if (s.toLowerCase().startsWith("ban-ip ")) { + String s4 = s.substring(s.indexOf(" ")).trim(); + + f.c(s4); + a(s1, (new StringBuilder()).append("Banning ip ").append(s4).toString()); + } else if (s.toLowerCase().startsWith("pardon-ip ")) { + String s5 = s.substring(s.indexOf(" ")).trim(); + + f.d(s5); + a(s1, (new StringBuilder()).append("Pardoning ip ").append(s5).toString()); + } else if (s.toLowerCase().startsWith("ban ")) { + String s6 = s.substring(s.indexOf(" ")).trim(); + + f.a(s6); + a(s1, (new StringBuilder()).append("Banning ").append(s6).toString()); + EntityPlayerMP entityplayermp = f.h(s6); + + if (entityplayermp != null) { + entityplayermp.a.a("Banned by admin"); + } + } else if (s.toLowerCase().startsWith("pardon ")) { + String s7 = s.substring(s.indexOf(" ")).trim(); + + f.b(s7); + a(s1, (new StringBuilder()).append("Pardoning ").append(s7).toString()); + } else if (s.toLowerCase().startsWith("kick ")) { + String s8 = s.substring(s.indexOf(" ")).trim(); + EntityPlayerMP entityplayermp1 = null; + + for (int i1 = 0; i1 < f.b.size(); i1++) { + EntityPlayerMP entityplayermp5 = (EntityPlayerMP) f.b.get(i1); + + if (entityplayermp5.aw.equalsIgnoreCase(s8)) { + entityplayermp1 = entityplayermp5; + } + } + + if (entityplayermp1 != null) { + entityplayermp1.a.a("Kicked by admin"); + a(s1, (new StringBuilder()).append("Kicking ").append(entityplayermp1.aw).toString()); + } else { + icommandlistener.b((new StringBuilder()).append("Can't find user ").append(s8).append(". No kick.").toString()); + } + } else if (s.toLowerCase().startsWith("tp ")) { + String as[] = s.split(" "); + + if (as.length == 3) { + EntityPlayerMP entityplayermp2 = f.h(as[1]); + EntityPlayerMP entityplayermp3 = f.h(as[2]); + + if (entityplayermp2 == null) { + icommandlistener.b((new StringBuilder()).append("Can't find user ").append(as[1]).append(". No tp.").toString()); + } else if (entityplayermp3 == null) { + icommandlistener.b((new StringBuilder()).append("Can't find user ").append(as[2]).append(". No tp.").toString()); + } else { + entityplayermp2.a.a(entityplayermp3.p, entityplayermp3.q, entityplayermp3.r, entityplayermp3.v, entityplayermp3.w); + a(s1, (new StringBuilder()).append("Teleporting ").append(as[1]).append(" to ").append(as[2]).append(".").toString()); + } + } else { + icommandlistener.b("Syntax error, please provice a source and a target."); + } + } else if (s.toLowerCase().startsWith("give ")) { + String as1[] = s.split(" "); + + if (as1.length != 3 && as1.length != 4) { + return; + } + String s9 = as1[1]; + EntityPlayerMP entityplayermp4 = f.h(s9); + + if (entityplayermp4 != null) { + try { + int j1 = Integer.parseInt(as1[2]); + + if (Item.c[j1] != null) { + a(s1, (new StringBuilder()).append("Giving ").append(entityplayermp4.aw).append(" some ").append(j1).toString()); + int k1 = 1; + + if (as1.length > 3) { + k1 = b(as1[3], 1); + } + if (k1 < 1) { + k1 = 1; + } + if (k1 > 64) { + k1 = 64; + } + entityplayermp4.b(new ItemStack(j1, k1)); + } else { + icommandlistener.b((new StringBuilder()).append("There's no item with id ").append(j1).toString()); + } + } catch (NumberFormatException numberformatexception) { + icommandlistener.b((new StringBuilder()).append("There's no item with id ").append(as1[2]).toString()); + } + } else { + icommandlistener.b((new StringBuilder()).append("Can't find user ").append(s9).toString()); + } + } else if (s.toLowerCase().startsWith("say ")) { + s = s.substring(s.indexOf(" ")).trim(); + a.info((new StringBuilder()).append("[").append(s1).append("] ").append(s).toString()); + f.a(new Packet3Chat((new StringBuilder()).append("\247d[Server] ").append(s).toString())); + } else if (s.toLowerCase().startsWith("tell ")) { + String as2[] = s.split(" "); + + if (as2.length >= 3) { + s = s.substring(s.indexOf(" ")).trim(); + s = s.substring(s.indexOf(" ")).trim(); + a.info((new StringBuilder()).append("[").append(s1).append("->").append(as2[1]).append("] ").append(s).toString()); + s = (new StringBuilder()).append("\2477").append(s1).append(" whispers ").append(s).toString(); + a.info(s); + if (!f.a(as2[1], new Packet3Chat(s))) { + icommandlistener.b("There's no player by that name online."); + } + } + } else { + a.info("Unknown console command. Type \"help\" for help."); + } + } while (true); + } + + private void a(String s, String s1) { + String s2 = (new StringBuilder()).append(s).append(": ").append(s1).toString(); + + f.i((new StringBuilder()).append("\2477(").append(s2).append(")").toString()); + a.info(s2); + } + + private int b(String s, int i1) { + try { + return Integer.parseInt(s); + } catch (NumberFormatException numberformatexception) { + return i1; + } + } + + public void a(IUpdatePlayerListBox iupdateplayerlistbox) { + p.add(iupdateplayerlistbox); + } + + public static void main(String args[]) { + try { + MinecraftServer minecraftserver = new MinecraftServer(); + + if (!java.awt.GraphicsEnvironment.isHeadless() && (args.length <= 0 || !args[0].equals("nogui"))) { + ServerGUI.a(minecraftserver); + } + (new ThreadServerApplication("Server thread", minecraftserver)).start(); + } catch (Exception exception) { + a.log(Level.SEVERE, "Failed to start the minecraft server", exception); + } + } + + public File a(String s) { + return new File(s); + } + + public void b(String s) { + a.info(s); + } + + public String c() { + return "CONSOLE"; + } + + public static boolean a(MinecraftServer minecraftserver) { + return minecraftserver.o; + } + +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java new file mode 100644 index 00000000..1168a6df --- /dev/null +++ b/src/main/java/net/minecraft/server/NetServerHandler.java @@ -0,0 +1,567 @@ +package net.minecraft.server; + + +import java.io.PrintStream; +import java.util.*; +import java.util.logging.Logger; +import org.bukkit.Location; +import org.bukkit.Player; +import org.bukkit.craftbukkit.CraftPlayer; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.event.Event.Type; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerMoveEvent; + + +public class NetServerHandler extends NetHandler + implements ICommandListener { + + public static Logger a = Logger.getLogger("Minecraft"); + public NetworkManager b; + public boolean c; + private MinecraftServer d; + private EntityPlayerMP e; + private int f; + private double g; + private double h; + private double i; + private boolean j; + private Map k; + + // CraftBukkit - next 2 lines + private final CraftServer server; + private final CraftPlayer player; + + public NetServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayerMP entityplayermp) { + c = false; + f = 0; + j = true; + k = new HashMap(); + d = minecraftserver; + b = networkmanager; + networkmanager.a(this); + e = entityplayermp; + entityplayermp.a = this; + + // CraftBukkit - next 2 lines + server = minecraftserver.server; + player = new CraftPlayer(server, e); + } + + // CraftBukkit start + public CraftPlayer getPlayer() { + return player; + } + // CraftBukkit end + + public void a() { + b.a(); + if (f++ % 20 == 0) { + b.a(new Packet0KeepAlive()); + } + } + + public void a(String s) { + b.a(new Packet255KickDisconnect(s)); + b.c(); + d.f.a(new Packet3Chat((new StringBuilder()).append("\247e").append(e.aw).append(" left the game.").toString())); + d.f.c(e); + c = true; + } + + public void a(Packet10Flying packet10flying) { + if (!j) { + double d1 = packet10flying.b - h; + + if (packet10flying.a == g && d1 * d1 < 0.01D && packet10flying.c == i) { + j = true; + } + } + + // CraftBukkit start + Location from = new Location(player.getWorld(), g, h, i, e.v, e.w); + Location to = player.getLocation(); + if (!from.equals(to)) { + PlayerMoveEvent event = new PlayerMoveEvent(Type.PLAYER_MOVE, player, from, to); + server.getPluginManager().callEvent(event); + + from = event.getFrom(); + to = event.isCancelled() ? from : event.getTo(); + + e.p = to.getX(); + e.q = to.getY(); + e.r = to.getZ(); + e.v = to.getYaw(); + e.w = to.getPitch(); + } + // CraftBukkit end + + if (j) { + if (e.k != null) { + float f1 = e.v; + float f2 = e.w; + + e.k.A(); + double d3 = e.p; + double d5 = e.q; + double d7 = e.r; + double d9 = 0.0D; + double d10 = 0.0D; + + if (packet10flying.i) { + f1 = packet10flying.e; + f2 = packet10flying.f; + } + if (packet10flying.h && packet10flying.b == -999D && packet10flying.d == -999D) { + d9 = packet10flying.a; + d10 = packet10flying.c; + } + e.A = packet10flying.g; + e.F(); + e.c(d9, 0.0D, d10); + e.b(d3, d5, d7, f1, f2); + e.s = d9; + e.u = d10; + if (e.k != null) { + d.e.b(e.k, true); + } + if (e.k != null) { + e.k.A(); + } + d.f.b(e); + g = e.p; + h = e.q; + i = e.r; + d.e.f(e); + return; + } + double d2 = e.q; + + g = e.p; + h = e.q; + i = e.r; + double d4 = e.p; + double d6 = e.q; + double d8 = e.r; + float f3 = e.v; + float f4 = e.w; + + if (packet10flying.h && packet10flying.b == -999D && packet10flying.d == -999D) { + packet10flying.h = false; + } + if (packet10flying.h) { + d4 = packet10flying.a; + d6 = packet10flying.b; + d8 = packet10flying.c; + double d11 = packet10flying.d - packet10flying.b; + + if (d11 > 1.6499999999999999D || d11 < 0.10000000000000001D) { + a("Illegal stance"); + a.warning((new StringBuilder()).append(e.aw).append(" had an illegal stance: ").append(d11).toString()); + } + e.ak = packet10flying.d; + } + if (packet10flying.i) { + f3 = packet10flying.e; + f4 = packet10flying.f; + } + e.F(); + e.R = 0.0F; + e.b(g, h, i, f3, f4); + double d12 = d4 - e.p; + double d13 = d6 - e.q; + double d14 = d8 - e.r; + float f5 = 0.0625F; + boolean flag = d.e.a(e, e.z.b().e(f5, f5, f5)).size() == 0; + + e.c(d12, d13, d14); + d12 = d4 - e.p; + d13 = d6 - e.q; + if (d13 > -0.5D || d13 < 0.5D) { + d13 = 0.0D; + } + d14 = d8 - e.r; + double d15 = d12 * d12 + d13 * d13 + d14 * d14; + boolean flag1 = false; + + if (d15 > 0.0625D) { + flag1 = true; + a.warning((new StringBuilder()).append(e.aw).append(" moved wrongly!").toString()); + System.out.println((new StringBuilder()).append("Got position ").append(d4).append(", ").append(d6).append(", ").append(d8).toString()); + System.out.println((new StringBuilder()).append("Expected ").append(e.p).append(", ").append(e.q).append(", ").append(e.r).toString()); + } + e.b(d4, d6, d8, f3, f4); + boolean flag2 = d.e.a(e, e.z.b().e(f5, f5, f5)).size() == 0; + + if (flag && (flag1 || !flag2)) { + a(g, h, i, f3, f4); + return; + } + e.A = packet10flying.g; + d.f.b(e); + e.b(e.q - d2, packet10flying.g); + } + } + + public void a(double d1, double d2, double d3, float f1, + float f2) { + + // CraftBukkit start + Location from = player.getLocation(); + Location to = new Location(player.getWorld(), d1, d2, d3, f1, f2); + PlayerMoveEvent event = new PlayerMoveEvent(Type.PLAYER_TELEPORT, player, from, to); + server.getPluginManager().callEvent(event); + + from = event.getFrom(); + to = event.isCancelled() ? from : event.getTo(); + + d1 = to.getX(); + d2 = to.getY(); + d3 = to.getZ(); + f1 = to.getYaw(); + f2 = to.getPitch(); + // CraftBukkit end + + j = false; + g = d1; + h = d2; + i = d3; + e.b(d1, d2, d3, f1, f2); + e.a.b(new Packet13PlayerLookMove(d1, d2 + 1.6200000047683716D, d2, d3, f1, f2, false)); + } + + public void a(Packet14BlockDig packet14blockdig) { + if (packet14blockdig.e == 4) { + e.L(); + return; + } + boolean flag = d.e.B = d.f.g(e.aw); + boolean flag1 = false; + + if (packet14blockdig.e == 0) { + flag1 = true; + } + if (packet14blockdig.e == 1) { + flag1 = true; + } + int l = packet14blockdig.a; + int i1 = packet14blockdig.b; + int j1 = packet14blockdig.c; + + if (flag1) { + double d1 = e.p - ((double) l + 0.5D); + double d2 = e.q - ((double) i1 + 0.5D); + double d3 = e.r - ((double) j1 + 0.5D); + double d4 = d1 * d1 + d2 * d2 + d3 * d3; + + if (d4 > 36D) { + return; + } + double d5 = e.q; + + e.q = e.ak; + e.q = d5; + } + int k1 = packet14blockdig.d; + int l1 = (int) MathHelper.e(l - d.e.m); + int i2 = (int) MathHelper.e(j1 - d.e.o); + + if (l1 > i2) { + i2 = l1; + } + if (packet14blockdig.e == 0) { + if (i2 > 16 || flag) { + e.c.a(l, i1, j1); + } + } else if (packet14blockdig.e == 2) { + e.c.a(); + } else if (packet14blockdig.e == 1) { + if (i2 > 16 || flag) { + e.c.a(l, i1, j1, k1); + } + } else if (packet14blockdig.e == 3) { + double d6 = e.p - ((double) l + 0.5D); + double d7 = e.q - ((double) i1 + 0.5D); + double d8 = e.r - ((double) j1 + 0.5D); + double d9 = d6 * d6 + d7 * d7 + d8 * d8; + + if (d9 < 256D) { + e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); + } + } + d.e.B = false; + } + + public void a(Packet15Place packet15place) { + ItemStack itemstack = e.an.e(); + boolean flag = d.e.B = d.f.g(e.aw); + + if (packet15place.d == 255) { + if (itemstack == null) { + return; + } + e.c.a(e, d.e, itemstack); + } else { + int l = packet15place.a; + int i1 = packet15place.b; + int j1 = packet15place.c; + int k1 = packet15place.d; + int l1 = (int) MathHelper.e(l - d.e.m); + int i2 = (int) MathHelper.e(j1 - d.e.o); + + if (l1 > i2) { + i2 = l1; + } + if (i2 > 16 || flag) { + e.c.a(e, d.e, itemstack, l, i1, j1, k1); + } + e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); + if (k1 == 0) { + i1--; + } + if (k1 == 1) { + i1++; + } + if (k1 == 2) { + j1--; + } + if (k1 == 3) { + j1++; + } + if (k1 == 4) { + l--; + } + if (k1 == 5) { + l++; + } + e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); + } + if (itemstack != null && itemstack.a == 0) { + e.an.a[e.an.c] = null; + } + e.am = true; + e.an.a[e.an.c] = ItemStack.a(e.an.a[e.an.c]); + Slot slot = e.ap.a(e.an, e.an.c); + + e.ap.a(); + e.am = false; + if (!ItemStack.a(e.an.e(), packet15place.e)) { + b(new Packet103(e.ap.f, slot.c, e.an.e())); + } + d.e.B = false; + } + + public void a(String s, Object aobj[]) { + a.info((new StringBuilder()).append(e.aw).append(" lost connection: ").append(s).toString()); + d.f.a(new Packet3Chat((new StringBuilder()).append("\247e").append(e.aw).append(" left the game.").toString())); + d.f.c(e); + c = true; + } + + public void a(Packet packet) { + a.warning((new StringBuilder()).append(getClass()).append(" wasn't prepared to deal with a ").append(packet.getClass()).toString()); + a("Protocol error, unexpected packet"); + } + + public void b(Packet packet) { + b.a(packet); + } + + public void a(Packet16BlockItemSwitch packet16blockitemswitch) { + e.an.c = packet16blockitemswitch.a; + } + + public void a(Packet3Chat packet3chat) { + String s = packet3chat.a; + + if (s.length() > 100) { + a("Chat message too long"); + return; + } + s = s.trim(); + for (int l = 0; l < s.length(); l++) { + if (FontAllowedCharacters.a.indexOf(s.charAt(l)) < 0) { + a("Illegal characters in chat"); + return; + } + } + + if (s.startsWith("/")) { + c(s); + } else { + // CraftBukkit start + PlayerChatEvent event = new PlayerChatEvent(Type.PLAYER_CHAT, player, s); + server.getPluginManager().callEvent(event); + s = (new StringBuilder()).append("<").append(event.getPlayer().getName()).append("> ").append(event.getMessage()).toString(); + // CraftBukkit stop + + a.info(s); + d.f.a(new Packet3Chat(s)); + } + } + + private void c(String s) { + // CraftBukkit start + PlayerChatEvent event = new PlayerChatEvent(Type.PLAYER_COMMAND, player, s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) return; + s = event.getMessage(); + CraftPlayer player = (CraftPlayer)event.getPlayer(); + EntityPlayerMP e = player.getHandle(); + // CraftBukkit stop + + if (s.toLowerCase().startsWith("/me ")) { + s = (new StringBuilder()).append("* ").append(e.aw).append(" ").append(s.substring(s.indexOf(" ")).trim()).toString(); + a.info(s); + d.f.a(new Packet3Chat(s)); + } else if (s.toLowerCase().startsWith("/kill")) { + e.a(null, 1000); + } else if (s.toLowerCase().startsWith("/tell ")) { + String as[] = s.split(" "); + + if (as.length >= 3) { + s = s.substring(s.indexOf(" ")).trim(); + s = s.substring(s.indexOf(" ")).trim(); + s = (new StringBuilder()).append("\2477").append(e.aw).append(" whispers ").append(s).toString(); + a.info((new StringBuilder()).append(s).append(" to ").append(as[1]).toString()); + if (!d.f.a(as[1], new Packet3Chat(s))) { + b(new Packet3Chat("\247cThere's no player by that name online.")); + } + } + } else if (d.f.g(e.aw)) { + String s1 = s.substring(1); + + a.info((new StringBuilder()).append(e.aw).append(" issued server command: ").append(s1).toString()); + d.a(s1, this); + } else { + String s2 = s.substring(1); + + a.info((new StringBuilder()).append(e.aw).append(" tried command: ").append(s2).toString()); + } + } + + public void a(Packet18ArmAnimation packet18armanimation) { + if (packet18armanimation.b == 1) { + e.H(); + } else if (packet18armanimation.b == 104) { + e.al = true; + } else if (packet18armanimation.b == 105) { + e.al = false; + } + } + + public void a(Packet255KickDisconnect packet255kickdisconnect) { + b.a("disconnect.quitting", new Object[0]); + } + + public int b() { + return b.d(); + } + + public void b(String s) { + b(((Packet) (new Packet3Chat((new StringBuilder()).append("\2477").append(s).toString())))); + } + + public String c() { + return e.aw; + } + + public void a(Packet7 packet7) { + Entity entity = d.e.a(packet7.b); + + if (entity != null && e.i(entity)) { + if (packet7.c == 0) { + e.g(entity); + } else if (packet7.c == 1) { + e.h(entity); + } + } + } + + public void a(Packet9 packet9) { + if (e.ba > 0) { + return; + } else { + e = d.f.d(e); + player.setHandle(e); // CraftBukkit + return; + } + } + + public void a(Packet101 packet101) { + e.K(); + } + + public void a(Packet102 packet102) { + if (e.ap.f == packet102.a && e.ap.c(e)) { + ItemStack itemstack = e.ap.a(packet102.b, packet102.c, e); + + if (ItemStack.a(packet102.e, itemstack)) { + e.a.b(new Packet106(packet102.a, packet102.d, true)); + e.am = true; + e.ap.a(); + e.J(); + e.am = false; + } else { + k.put(Integer.valueOf(e.ap.f), Short.valueOf(packet102.d)); + e.a.b(new Packet106(packet102.a, packet102.d, false)); + e.ap.a(e, false); + ArrayList arraylist = new ArrayList(); + + for (int l = 0; l < e.ap.e.size(); l++) { + arraylist.add(((Slot) e.ap.e.get(l)).c()); + } + + e.a(e.ap, arraylist); + } + } + } + + public void a(Packet106 packet106) { + Short short1 = (Short) k.get(Integer.valueOf(e.ap.f)); + + if (short1 != null && packet106.b == short1.shortValue() && e.ap.f == packet106.a && !e.ap.c(e)) { + e.ap.a(e, true); + } + } + + public void a(Packet130 packet130) { + if (d.e.f(packet130.a, packet130.b, packet130.c)) { + TileEntity tileentity = d.e.l(packet130.a, packet130.b, packet130.c); + + for (int l = 0; l < 4; l++) { + boolean flag = true; + + if (packet130.d[l].length() > 15) { + flag = false; + } else { + for (int k1 = 0; k1 < packet130.d[l].length(); k1++) { + if (FontAllowedCharacters.a.indexOf(packet130.d[l].charAt(k1)) < 0) { + flag = false; + } + } + + } + if (!flag) { + packet130.d[l] = "!?"; + } + } + + if (tileentity instanceof TileEntitySign) { + int i1 = packet130.a; + int j1 = packet130.b; + int l1 = packet130.c; + TileEntitySign tileentitysign = (TileEntitySign) tileentity; + + for (int i2 = 0; i2 < 4; i2++) { + tileentitysign.e[i2] = packet130.d[i2]; + } + + tileentitysign.d(); + d.e.g(i1, j1, l1); + } + } + } + +} + diff --git a/src/main/java/net/minecraft/server/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/ServerConfigurationManager.java new file mode 100644 index 00000000..dac524b8 --- /dev/null +++ b/src/main/java/net/minecraft/server/ServerConfigurationManager.java @@ -0,0 +1,369 @@ +package net.minecraft.server; + +import java.io.*; +import java.util.*; +import java.util.logging.Logger; +import org.bukkit.craftbukkit.CraftPlayer; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.event.Event.Type; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerLoginEvent; + + +public class ServerConfigurationManager { + + public static Logger a = Logger.getLogger("Minecraft"); + public List b; + private MinecraftServer c; + private PlayerManager d; + private int e; + private Set f; + private Set g; + private Set h; + private File i; + private File j; + private File k; + private PlayerNBTManager l; + private CraftServer server; // Craftbukkit + + public ServerConfigurationManager(MinecraftServer minecraftserver) { + server = minecraftserver.server; // Craftbukkit + + b = new ArrayList(); + f = new HashSet(); + g = new HashSet(); + h = new HashSet(); + c = minecraftserver; + i = minecraftserver.a("banned-players.txt"); + j = minecraftserver.a("banned-ips.txt"); + k = minecraftserver.a("ops.txt"); + d = new PlayerManager(minecraftserver); + e = minecraftserver.d.a("max-players", 20); + e(); + g(); + i(); + f(); + h(); + j(); + } + + public void a(WorldServer worldserver) { + l = new PlayerNBTManager(new File(worldserver.t, "players")); + } + + public int a() { + return d.b(); + } + + public void a(EntityPlayerMP entityplayermp) { + b.add(entityplayermp); + l.b(entityplayermp); + c.e.A.d((int) entityplayermp.p >> 4, (int) entityplayermp.r >> 4); + for (; c.e.a(entityplayermp, entityplayermp.z).size() != 0; entityplayermp.a(entityplayermp.p, entityplayermp.q + 1.0D, entityplayermp.r)) { + ; + } + c.e.a(entityplayermp); + d.a(entityplayermp); + + // Craftbukkit + server.getPluginManager().callEvent(new PlayerEvent(PlayerEvent.Type.PLAYER_JOIN, server.getPlayer(entityplayermp))); + } + + public void b(EntityPlayerMP entityplayermp) { + d.c(entityplayermp); + } + + public void c(EntityPlayerMP entityplayermp) { + l.a(entityplayermp); + c.e.d(entityplayermp); + b.remove(entityplayermp); + d.b(entityplayermp); + + // Craftbukkit + server.getPluginManager().callEvent(new PlayerEvent(PlayerEvent.Type.PLAYER_QUIT, server.getPlayer(entityplayermp))); + } + + public EntityPlayerMP a(NetLoginHandler netloginhandler, String s, String s1) { + // Craftbukkit note: this entire method needs to be changed + // Instead of kicking then returning, we need to store the kick reason + // in the event, check with plugins to see if it's ok, and THEN kick + // depending on the outcome. + + EntityPlayerMP entity = new EntityPlayerMP(c, c.e, s, new ItemInWorldManager(c.e)); + PlayerLoginEvent event = new PlayerLoginEvent(Type.PLAYER_LOGIN, new CraftPlayer(server, entity)); + + String s2 = netloginhandler.b.b().toString(); + s2 = s2.substring(s2.indexOf("/") + 1); + s2 = s2.substring(0, s2.indexOf(":")); + + if (f.contains(s.trim().toLowerCase())) { + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, "You are banned from this server!"); + } else if (g.contains(s2)) { + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, "Your IP address is banned from this server!"); + } else if (b.size() >= e) { + event.disallow(PlayerLoginEvent.Result.KICK_FULL, "The server is full!"); + } + + server.getPluginManager().callEvent(event); + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + netloginhandler.a(event.getKickMessage()); + return null; + } + + for (int i1 = 0; i1 < b.size(); i1++) { + EntityPlayerMP entityplayermp = (EntityPlayerMP) b.get(i1); + + if (entityplayermp.aw.equalsIgnoreCase(s)) { + entityplayermp.a.a("You logged in from another location"); + } + } + + return entity; + } + + public EntityPlayerMP d(EntityPlayerMP entityplayermp) { + c.k.a(entityplayermp); + c.k.b(entityplayermp); + d.b(entityplayermp); + b.remove(entityplayermp); + c.e.e(entityplayermp); + EntityPlayerMP entityplayermp1 = new EntityPlayerMP(c, c.e, entityplayermp.aw, new ItemInWorldManager(c.e)); + + entityplayermp1.g = entityplayermp.g; + entityplayermp1.a = entityplayermp.a; + c.e.A.d((int) entityplayermp1.p >> 4, (int) entityplayermp1.r >> 4); + for (; c.e.a(entityplayermp1, entityplayermp1.z).size() != 0; entityplayermp1.a(entityplayermp1.p, entityplayermp1.q + 1.0D, entityplayermp1.r)) { + ; + } + entityplayermp1.a.b(new Packet9()); + entityplayermp1.a.a(entityplayermp1.p, entityplayermp1.q, entityplayermp1.r, entityplayermp1.v, entityplayermp1.w); + d.a(entityplayermp1); + c.e.a(entityplayermp1); + b.add(entityplayermp1); + entityplayermp1.k(); + return entityplayermp1; + } + + public void b() { + d.a(); + } + + public void a(int i1, int j1, int k1) { + d.a(i1, j1, k1); + } + + public void a(Packet packet) { + for (int i1 = 0; i1 < b.size(); i1++) { + EntityPlayerMP entityplayermp = (EntityPlayerMP) b.get(i1); + + entityplayermp.a.b(packet); + } + + } + + public String c() { + String s = ""; + + for (int i1 = 0; i1 < b.size(); i1++) { + if (i1 > 0) { + s = (new StringBuilder()).append(s).append(", ").toString(); + } + s = (new StringBuilder()).append(s).append(((EntityPlayerMP) b.get(i1)).aw).toString(); + } + + return s; + } + + public void a(String s) { + f.add(s.toLowerCase()); + f(); + } + + public void b(String s) { + f.remove(s.toLowerCase()); + f(); + } + + private void e() { + try { + f.clear(); + BufferedReader bufferedreader = new BufferedReader(new FileReader(i)); + + for (String s = ""; (s = bufferedreader.readLine()) != null;) { + f.add(s.trim().toLowerCase()); + } + + bufferedreader.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to load ban list: ").append(exception).toString()); + } + } + + private void f() { + try { + PrintWriter printwriter = new PrintWriter(new FileWriter(i, false)); + String s; + + for (Iterator iterator = f.iterator(); iterator.hasNext(); printwriter.println(s)) { + s = (String) iterator.next(); + } + + printwriter.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to save ban list: ").append(exception).toString()); + } + } + + public void c(String s) { + g.add(s.toLowerCase()); + h(); + } + + public void d(String s) { + g.remove(s.toLowerCase()); + h(); + } + + private void g() { + try { + g.clear(); + BufferedReader bufferedreader = new BufferedReader(new FileReader(j)); + + for (String s = ""; (s = bufferedreader.readLine()) != null;) { + g.add(s.trim().toLowerCase()); + } + + bufferedreader.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to load ip ban list: ").append(exception).toString()); + } + } + + private void h() { + try { + PrintWriter printwriter = new PrintWriter(new FileWriter(j, false)); + String s; + + for (Iterator iterator = g.iterator(); iterator.hasNext(); printwriter.println(s)) { + s = (String) iterator.next(); + } + + printwriter.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to save ip ban list: ").append(exception).toString()); + } + } + + public void e(String s) { + h.add(s.toLowerCase()); + j(); + } + + public void f(String s) { + h.remove(s.toLowerCase()); + j(); + } + + private void i() { + try { + h.clear(); + BufferedReader bufferedreader = new BufferedReader(new FileReader(k)); + + for (String s = ""; (s = bufferedreader.readLine()) != null;) { + h.add(s.trim().toLowerCase()); + } + + bufferedreader.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to load ip ban list: ").append(exception).toString()); + } + } + + private void j() { + try { + PrintWriter printwriter = new PrintWriter(new FileWriter(k, false)); + String s; + + for (Iterator iterator = h.iterator(); iterator.hasNext(); printwriter.println(s)) { + s = (String) iterator.next(); + } + + printwriter.close(); + } catch (Exception exception) { + a.warning((new StringBuilder()).append("Failed to save ip ban list: ").append(exception).toString()); + } + } + + public boolean g(String s) { + return h.contains(s.trim().toLowerCase()); + } + + public EntityPlayerMP h(String s) { + for (int i1 = 0; i1 < b.size(); i1++) { + EntityPlayerMP entityplayermp = (EntityPlayerMP) b.get(i1); + + if (entityplayermp.aw.equalsIgnoreCase(s)) { + return entityplayermp; + } + } + + return null; + } + + public void a(String s, String s1) { + EntityPlayerMP entityplayermp = h(s); + + if (entityplayermp != null) { + entityplayermp.a.b(new Packet3Chat(s1)); + } + } + + public void a(double d1, double d2, double d3, double d4, Packet packet) { + for (int i1 = 0; i1 < b.size(); i1++) { + EntityPlayerMP entityplayermp = (EntityPlayerMP) b.get(i1); + double d5 = d1 - entityplayermp.p; + double d6 = d2 - entityplayermp.q; + double d7 = d3 - entityplayermp.r; + + if (d5 * d5 + d6 * d6 + d7 * d7 < d4 * d4) { + entityplayermp.a.b(packet); + } + } + + } + + public void i(String s) { + Packet3Chat packet3chat = new Packet3Chat(s); + + for (int i1 = 0; i1 < b.size(); i1++) { + EntityPlayerMP entityplayermp = (EntityPlayerMP) b.get(i1); + + if (g(entityplayermp.aw)) { + entityplayermp.a.b(packet3chat); + } + } + + } + + public boolean a(String s, Packet packet) { + EntityPlayerMP entityplayermp = h(s); + + if (entityplayermp != null) { + entityplayermp.a.b(packet); + return true; + } else { + return false; + } + } + + public void d() { + for (int i1 = 0; i1 < b.size(); i1++) { + l.a((EntityPlayerMP) b.get(i1)); + } + + } + + public void a(int i1, int j1, int k1, TileEntity tileentity) {} + +} diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java new file mode 100644 index 00000000..431cb0ac --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -0,0 +1,182 @@ +package net.minecraft.server; + +import java.io.File; +import java.util.Random; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.Event; +import org.bukkit.event.Event.Type; +import org.bukkit.event.block.BlockCanBuildEvent; +import org.bukkit.event.block.BlockPhysicsEvent; + + +public class WorldServer extends World { + + public ChunkProviderServer A; + public boolean B; + public boolean C; + private MinecraftServer D; + private MCHashTable E; + private final CraftWorld world; // CraftBukkit + private final CraftServer server; // CraftBukkit + + public WorldServer(MinecraftServer minecraftserver, File file, String s, int i) { + super(file, s, (new Random()).nextLong(), WorldProvider.a(i)); + B = false; + E = new MCHashTable(); + D = minecraftserver; + world = new CraftWorld(this); // CraftBukkit + server = minecraftserver.server; // CraftBukkit + } + + // CraftBukkit start + @Override + public boolean c(int i1, int j1, int k1, int l1) { + boolean result = super.c(i1, j1, k1, l1); + world.updateBlock(i1, j1, k1); + return result; + } + + @Override + public boolean d(int i1, int j1, int k1, int l1) { + boolean result = super.d(i1, j1, k1, l1); + world.updateBlock(i1, j1, k1); + return result; + } + + public CraftWorld getWorld() { + return world; + } + + public CraftServer getServer() { + return server; + } + // CraftBukkit stop + + // CraftBukkit start - note: the following methods are straight from the + // World.java with tweaks as noted. KEEP THEM UPDATED! + @Override + public void g(int i1, int j1, int k1, int l1) { + k(i1 - 1, j1, k1, l1); + k(i1 + 1, j1, k1, l1); + k(i1, j1 - 1, k1, l1); + k(i1, j1 + 1, k1, l1); + k(i1, j1, k1 - 1, l1); + k(i1, j1, k1 + 1, l1); + } + + private void k(int i1, int j1, int k1, int l1) { + if (i || z) { + return; + } + Block block = Block.m[a(i1, j1, k1)]; + + if (block != null) { + // CraftBukkit start + BlockPhysicsEvent event = new BlockPhysicsEvent(Event.Type.BLOCK_PHYSICS, world.getBlockAt(i1, j1, k1), l1); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + // CraftBukkit stop + + block.b(this, i1, j1, k1, l1); + } + } + // CraftBukkit stop + + // CraftBukkit start + @Override + public boolean a(int i1, int j1, int k1, int l1, boolean flag) { + boolean superResult = super.a(i1, j1, k1, l1, flag); + + if (!flag) { + BlockCanBuildEvent event = new BlockCanBuildEvent(Type.BLOCK_CANBUILD, getWorld().getBlockAt(j1, k1, l1), i1, superResult); + server.getPluginManager().callEvent(event); + + return event.isBuildable(); + } else { + return superResult; + } + } + // CraftBukkit stop + + public void f() { + super.f(); + } + + public void a(Entity entity, boolean flag) { + if (!D.m && (entity instanceof EntityAnimals)) { + entity.l(); + } + if (entity.j == null || !(entity.j instanceof EntityPlayer)) { + super.a(entity, flag); + } + } + + public void b(Entity entity, boolean flag) { + super.a(entity, flag); + } + + protected IChunkProvider a(File file) { + A = new ChunkProviderServer(this, q.a(file), q.c()); + return A; + } + + public List d(int i, int j, int k, int l, int i1, int j1) { + ArrayList arraylist = new ArrayList(); + + for (int k1 = 0; k1 < c.size(); k1++) { + TileEntity tileentity = (TileEntity) c.get(k1); + + if (tileentity.b >= i && tileentity.c >= j && tileentity.d >= k && tileentity.b < l && tileentity.c < i1 && tileentity.d < j1) { + arraylist.add(tileentity); + } + } + + return arraylist; + } + + public boolean a(EntityPlayer entityplayer, int i, int j, int k) { + int l = (int) MathHelper.e(i - m); + int i1 = (int) MathHelper.e(k - o); + + if (l > i1) { + i1 = l; + } + return i1 > 16 || D.f.g(entityplayer.aw); + } + + protected void b(Entity entity) { + super.b(entity); + E.a(entity.g, entity); + } + + protected void c(Entity entity) { + super.c(entity); + E.d(entity.g); + } + + public Entity a(int i) { + return (Entity) E.a(i); + } + + public void a(Entity entity, byte byte0) { + Packet38 packet38 = new Packet38(entity.g, byte0); + + D.k.b(entity, packet38); + } + + public Explosion a(Entity entity, double d1, double d2, double d3, + float f1, boolean flag) { + Explosion explosion = super.a(entity, d1, d2, d3, f1, flag); + + D.f.a(d1, d2, d3, 64D, new Packet60(d1, d2, d3, f1, explosion.g)); + return explosion; + } +} + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/CraftBlock.java new file mode 100644 index 00000000..f67d14bf --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftBlock.java @@ -0,0 +1,152 @@ + +package org.bukkit.craftbukkit; + +import org.bukkit.*; + +public class CraftBlock implements Block { + private final CraftWorld world; + private final CraftChunk chunk; + private final int x; + private final int y; + private final int z; + protected int type; + protected byte data; + + protected CraftBlock(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) { + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.type = type; + this.data = data; + this.chunk = (CraftChunk)world.getChunkAt(x << 4, z << 4); + } + + /** + * Gets the world which contains this Block + * + * @return World containing this block + */ + public World getWorld() { + return world; + } + + /** + * Gets the x-coordinate of this block + * + * @return x-coordinate + */ + public int getX() { + return x; + } + + /** + * Gets the y-coordinate of this block + * + * @return y-coordinate + */ + public int getY() { + return y; + } + + /** + * Gets the z-coordinate of this block + * + * @return z-coordinate + */ + public int getZ() { + return z; + } + + /** + * Gets the chunk which contains this block + * + * @return Containing Chunk + */ + public Chunk getChunk() { + return chunk; + } + + /** + * Sets the metadata for this block + * + * @param data New block specific metadata + */ + public void setData(final byte data) { + this.data = data; + world.getHandle().c(x, y, z, data); + } + + /** + * Gets the metadata for this block + * + * @return block specific metadata + */ + public byte getData() { + return data; + } + + /** + * Sets the type of this block + * + * @param type Material to change this block to + */ + public void setType(final Material type) { + setTypeID(type.getID()); + } + + /** + * Sets the type-ID of this block + * + * @param type Type-ID to change this block to + */ + public void setTypeID(final int type) { + this.type = type; + world.getHandle().d(x, y, z, type); + } + + /** + * Gets the type of this block + * + * @return block type + */ + public Material getType() { + return Material.getMaterial(getTypeID()); + } + + /** + * Gets the type-ID of this block + * + * @return block type-ID + */ + public int getTypeID() { + return type; + } + + /** + * Gets the block at the given face + * + * @param face Face of this block to return + * @return Block at the given face + */ + public Block getFace(final BlockFace face) { + return getRelative(face.getModX(), face.getModY(), face.getModZ()); + } + + /** + * Gets the block at the given offsets + * + * @param modX X-coordinate offset + * @param modY Y-coordinate offset + * @param modZ Z-coordinate offset + * @return Block at the given offsets + */ + public Block getRelative(final int modX, final int modY, final int modZ) { + return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ); + } + + @Override + public String toString() { + return "CraftBlock{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "type=" + type + "data=" + data + '}'; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java new file mode 100644 index 00000000..003ee0f4 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -0,0 +1,37 @@ + +package org.bukkit.craftbukkit; + +import org.bukkit.Chunk; + +public class CraftChunk implements Chunk { + private final int x; + private final int z; + + protected CraftChunk(final int x, final int z) { + this.x = x; + this.z = z; + } + + /** + * Gets the X-coordinate of this chunk + * + * @return X-coordinate + */ + public int getX() { + return x; + } + + /** + * Gets the Z-coordinate of this chunk + * + * @return Z-coordinate + */ + public int getZ() { + return z; + } + + @Override + public String toString() { + return "CraftChunk{" + "x=" + x + "z=" + z + '}'; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/CraftEntity.java new file mode 100644 index 00000000..efbb7f28 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftEntity.java @@ -0,0 +1,72 @@ + +package org.bukkit.craftbukkit; + +import net.minecraft.server.Entity; +import net.minecraft.server.WorldServer; +import org.bukkit.Location; +import org.bukkit.World; + +public class CraftEntity implements org.bukkit.Entity { + protected final CraftServer server; + private Entity entity; + + public CraftEntity(final CraftServer server, final Entity entity) { + this.server = server; + this.entity = entity; + } + + public Location getLocation() { + return new Location(getWorld(), entity.p, entity.q, entity.r, entity.v, entity.w); + } + + public World getWorld() { + return ((WorldServer)entity.l).getWorld(); + } + + public void teleportTo(Location location) { + entity.b(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } + + public int getEntityID() { + return entity.g; + } + + public Entity getHandle() { + return entity; + } + + public void setHandle(final Entity entity) { + this.entity = entity; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftEntity other = (CraftEntity) obj; + if (this.server != other.server && (this.server == null || !this.server.equals(other.server))) { + return false; + } + if (this.entity != other.entity && (this.entity == null || !this.entity.equals(other.entity))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + (this.server != null ? this.server.hashCode() : 0); + hash = 89 * hash + (this.entity != null ? this.entity.hashCode() : 0); + return hash; + } + + @Override + public String toString() { + return "CraftEntity{" + "id=" + getEntityID() + '}'; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java new file mode 100644 index 00000000..b03f0967 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java @@ -0,0 +1,41 @@ + +package org.bukkit.craftbukkit; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.InventoryPlayer; +import org.bukkit.HumanEntity; +import org.bukkit.ItemStack; + +public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + private EntityPlayer entity; + + public CraftHumanEntity(final CraftServer server, final EntityPlayer entity) { + super(server, entity); + this.entity = entity; + } + + public ItemStack getSelectedItem() { + // TODO: Implement inventories + final InventoryPlayer inventory = entity.an; + return new ItemStack(inventory.e().c, inventory.e().a); + } + + public String getName() { + return entity.aw; + } + + @Override + public EntityPlayer getHandle() { + return entity; + } + + public void setHandle(final EntityPlayer entity) { + super.setHandle((EntityPlayer)entity); + this.entity = entity; + } + + @Override + public String toString() { + return "CraftHumanEntity{" + "id=" + getEntityID() + "name=" + getName() + '}'; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java new file mode 100644 index 00000000..8f753386 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java @@ -0,0 +1,42 @@ + +package org.bukkit.craftbukkit; + +import net.minecraft.server.Entity; +import net.minecraft.server.EntityLiving; +import org.bukkit.LivingEntity; + +public class CraftLivingEntity extends CraftEntity implements LivingEntity { + private EntityLiving entity; + + public CraftLivingEntity(final CraftServer server, final EntityLiving entity) { + super(server, entity); + this.entity = entity; + } + + public int getHealth() { + return entity.ba; + } + + public void setHealth(int health) { + if ((health < 0) || (health > 20)) { + throw new IllegalArgumentException("Health must be between 0 and 20"); + } + + entity.ba = health; + } + + @Override + public EntityLiving getHandle() { + return entity; + } + + public void setHandle(final EntityLiving entity) { + super.setHandle((Entity)entity); + this.entity = entity; + } + + @Override + public String toString() { + return "CraftLivingEntity{" + "id=" + getEntityID() + '}'; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java new file mode 100644 index 00000000..a8a368dc --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java @@ -0,0 +1,67 @@ + +package org.bukkit.craftbukkit; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EntityPlayerMP; +import net.minecraft.server.Packet3Chat; +import org.bukkit.Location; +import org.bukkit.Player; + +public class CraftPlayer extends CraftHumanEntity implements Player { + private EntityPlayerMP entity; + + public CraftPlayer(CraftServer server, EntityPlayerMP entity) { + super(server, entity); + this.entity = entity; + } + + public boolean isOnline() { + return server.getHandle().g(getName()); + } + + @Override + public EntityPlayerMP getHandle() { + return entity; + } + + public void setHandle(final EntityPlayerMP entity) { + super.setHandle((EntityPlayer)entity); + this.entity = entity; + } + + public void sendMessage(String message) { + entity.a.b(new Packet3Chat(message)); + } + + @Override + public void teleportTo(Location location) { + entity.a.a(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } + + @Override + public String toString() { + return "CraftPlayer{" + "name=" + getName() + '}'; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftPlayer other = (CraftPlayer) obj; + if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 97 * hash + (this.getName() != null ? this.getName().hashCode() : 0); + return hash; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java new file mode 100644 index 00000000..1fe1ee44 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -0,0 +1,80 @@ + +package org.bukkit.craftbukkit; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerConfigurationManager; +import net.minecraft.server.WorldServer; +import org.bukkit.*; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.SimplePluginManager; +import org.bukkit.plugin.java.JavaPluginLoader; + +public final class CraftServer implements Server { + private final String serverName = "Craftbukkit"; + private final String serverVersion; + private final PluginManager pluginManager = new SimplePluginManager(this); + + protected final MinecraftServer console; + protected final ServerConfigurationManager server; + + public CraftServer(MinecraftServer instance, String ver) { + serverVersion = ver; + + console = instance; + server = console.f; + + pluginManager.RegisterInterface(JavaPluginLoader.class); + + File pluginFolder = new File("plugins"); + if (pluginFolder.exists()) { + try { + pluginManager.loadPlugins(pluginFolder); + } catch (Throwable ex) { + Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, "(Did you extract the lib folder?)", ex); + } + } else { + pluginFolder.mkdir(); + } + } + + public String getName() { + return serverName; + } + + public String getVersion() { + return serverVersion; + } + + public Player[] getOnlinePlayers() { + List online = server.b; + Player[] players = new Player[online.size()]; + + for (int i = 0; i < players.length; i++) { + players[i] = online.get(i).a.getPlayer(); + } + + return players; + } + + public Player getPlayer(final EntityPlayerMP entity) { + return entity.a.getPlayer(); + } + + public PluginManager getPluginManager() { + return pluginManager; + } + + public World[] getWorlds() { + return new World[] { console.e.getWorld() }; + } + + public ServerConfigurationManager getHandle() { + return server; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java new file mode 100644 index 00000000..5e6d20d7 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +1,155 @@ + +package org.bukkit.craftbukkit; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.WorldServer; +import org.bukkit.Block; +import org.bukkit.Chunk; +import org.bukkit.World; + +public class CraftWorld implements World { + private final Map chunkCache = new HashMap(); + private final Map blockCache = new HashMap(); + private final WorldServer world; + + public CraftWorld(WorldServer world) { + this.world = world; + } + + public Block getBlockAt(int x, int y, int z) { + BlockCoordinate loc = new BlockCoordinate(x, y, z); + Block block = blockCache.get(loc); + + if (block == null) { + block = new CraftBlock(this, x, y, z, world.a(x, y, z), (byte)world.b(x, y, z)); + blockCache.put(loc, block); + } + + return block; + } + + public Chunk getChunkAt(int x, int z) { + ChunkCoordinate loc = new ChunkCoordinate(x, z); + Chunk chunk = chunkCache.get(loc); + + if (chunk == null) { + chunk = new CraftChunk(x, z); + chunkCache.put(loc, chunk); + } + + return chunk; + } + + public Chunk getChunkAt(Block block) { + return getChunkAt(block.getX() << 4, block.getZ() << 4); + } + + public boolean isChunkLoaded() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Block updateBlock(int x, int y, int z) { + BlockCoordinate loc = new BlockCoordinate(x, y, z); + CraftBlock block = (CraftBlock)blockCache.get(loc); + final int type = world.a(x, y, z); + final byte data = (byte)world.b(x, y, z); + + if (block == null) { + block = new CraftBlock(this, x, y, z, type, data); + blockCache.put(loc, block); + } else { + block.type = type; + block.data = data; + } + + return block; + } + + public WorldServer getHandle() { + return world; + } + + @Override + public String toString() { + return "CraftWorld"; + } + + private final class ChunkCoordinate { + public final int x; + public final int z; + + public ChunkCoordinate(final int x, final int z) { + this.x = x; + this.z = z; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ChunkCoordinate other = (ChunkCoordinate) obj; + if (this.x != other.x) { + return false; + } + if (this.z != other.z) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 53 * hash + this.x; + hash = 53 * hash + this.z; + return hash; + } + } + + private final class BlockCoordinate { + public final int x; + public final int y; + public final int z; + + public BlockCoordinate(final int x, final int y, final int z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final BlockCoordinate other = (BlockCoordinate) obj; + if (this.x != other.x) { + return false; + } + if (this.y != other.y) { + return false; + } + if (this.z != other.z) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 37 * hash + this.x; + hash = 37 * hash + this.y; + hash = 37 * hash + this.z; + return hash; + } + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java new file mode 100644 index 00000000..d2543b5e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +1,16 @@ + +package org.bukkit.craftbukkit; + +import net.minecraft.server.MinecraftServer; + +public class Main { + public static void main(String[] args) { + // Todo: Installation script + + try { + MinecraftServer.main(args); + } catch (Throwable t) { + t.printStackTrace(); + } + } +} -- cgit v1.2.3