summaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
authorErik Broes <erikbroes@grum.nl>2011-01-01 11:23:14 +0100
committerErik Broes <erikbroes@grum.nl>2011-01-01 11:23:14 +0100
commitddff384203acf9ded5861e0036c7415f8cc451de (patch)
tree68230230aad11bb70273b2431af4559b90fab862 /src/main/java
parent7b6539422b350dffb230a9934f803eb83ace1086 (diff)
downloadbukkit-ddff384203acf9ded5861e0036c7415f8cc451de.tar
bukkit-ddff384203acf9ded5861e0036c7415f8cc451de.tar.gz
bukkit-ddff384203acf9ded5861e0036c7415f8cc451de.tar.lz
bukkit-ddff384203acf9ded5861e0036c7415f8cc451de.tar.xz
bukkit-ddff384203acf9ded5861e0036c7415f8cc451de.zip
Transition to Maven
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/bukkit/Block.java102
-rw-r--r--src/main/java/org/bukkit/BlockFace.java48
-rw-r--r--src/main/java/org/bukkit/Chunk.java23
-rw-r--r--src/main/java/org/bukkit/Entity.java35
-rw-r--r--src/main/java/org/bukkit/HumanEntity.java22
-rw-r--r--src/main/java/org/bukkit/ItemStack.java81
-rw-r--r--src/main/java/org/bukkit/LivingEntity.java21
-rw-r--r--src/main/java/org/bukkit/Location.java187
-rw-r--r--src/main/java/org/bukkit/Material.java205
-rw-r--r--src/main/java/org/bukkit/Player.java22
-rw-r--r--src/main/java/org/bukkit/Server.java44
-rw-r--r--src/main/java/org/bukkit/World.java18
-rw-r--r--src/main/java/org/bukkit/event/Cancellable.java6
-rw-r--r--src/main/java/org/bukkit/event/Event.java140
-rw-r--r--src/main/java/org/bukkit/event/EventException.java48
-rw-r--r--src/main/java/org/bukkit/event/Listener.java9
-rw-r--r--src/main/java/org/bukkit/event/block/BlockBrokenEvent.java13
-rw-r--r--src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java47
-rw-r--r--src/main/java/org/bukkit/event/block/BlockEvent.java24
-rw-r--r--src/main/java/org/bukkit/event/block/BlockFromToEvent.java50
-rw-r--r--src/main/java/org/bukkit/event/block/BlockIgniteEvent.java19
-rw-r--r--src/main/java/org/bukkit/event/block/BlockListener.java81
-rw-r--r--src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java59
-rw-r--r--src/main/java/org/bukkit/event/block/BlockPlacedEvent.java32
-rw-r--r--src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java53
-rw-r--r--src/main/java/org/bukkit/event/player/PlayerChatEvent.java66
-rw-r--r--src/main/java/org/bukkit/event/player/PlayerEvent.java25
-rw-r--r--src/main/java/org/bukkit/event/player/PlayerListener.java68
-rw-r--r--src/main/java/org/bukkit/event/player/PlayerLoginEvent.java104
-rw-r--r--src/main/java/org/bukkit/event/player/PlayerMoveEvent.java86
-rw-r--r--src/main/java/org/bukkit/plugin/InvalidDescriptionException.java36
-rw-r--r--src/main/java/org/bukkit/plugin/InvalidPluginException.java36
-rw-r--r--src/main/java/org/bukkit/plugin/Plugin.java47
-rw-r--r--src/main/java/org/bukkit/plugin/PluginDescriptionFile.java87
-rw-r--r--src/main/java/org/bukkit/plugin/PluginLoader.java37
-rw-r--r--src/main/java/org/bukkit/plugin/PluginManager.java87
-rw-r--r--src/main/java/org/bukkit/plugin/RegisteredListener.java44
-rw-r--r--src/main/java/org/bukkit/plugin/SimplePluginManager.java216
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPlugin.java91
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java123
40 files changed, 2542 insertions, 0 deletions
diff --git a/src/main/java/org/bukkit/Block.java b/src/main/java/org/bukkit/Block.java
new file mode 100644
index 00000000..0c32c321
--- /dev/null
+++ b/src/main/java/org/bukkit/Block.java
@@ -0,0 +1,102 @@
+
+package org.bukkit;
+
+/**
+ * Represents a block
+ */
+public interface Block {
+ /**
+ * Gets the metadata for this block
+ *
+ * @return block specific metadata
+ */
+ byte getData();
+
+ /**
+ * Gets the block at the given face
+ *
+ * @param face Face of this block to return
+ * @return Block at the given face
+ */
+ Block getFace(BlockFace face);
+
+ /**
+ * 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
+ */
+ Block getRelative(int modX, int modY, int modZ);
+
+ /**
+ * Gets the type of this block
+ *
+ * @return block type
+ */
+ Material getType();
+
+ /**
+ * Gets the type-ID of this block
+ *
+ * @return block type-ID
+ */
+ int getTypeID();
+
+ /**
+ * Gets the world which contains this Block
+ *
+ * @return World containing this block
+ */
+ World getWorld();
+
+ /**
+ * Gets the x-coordinate of this block
+ *
+ * @return x-coordinate
+ */
+ int getX();
+
+ /**
+ * Gets the y-coordinate of this block
+ *
+ * @return y-coordinate
+ */
+ int getY();
+
+ /**
+ * Gets the z-coordinate of this block
+ *
+ * @return z-coordinate
+ */
+ int getZ();
+
+ /**
+ * Gets the chunk which contains this block
+ *
+ * @return Containing Chunk
+ */
+ Chunk getChunk();
+
+ /**
+ * Sets the metadata for this block
+ *
+ * @param data New block specific metadata
+ */
+ void setData(byte data);
+
+ /**
+ * Sets the type of this block
+ *
+ * @param type Material to change this block to
+ */
+ void setType(Material type);
+
+ /**
+ * Sets the type-ID of this block
+ *
+ * @param type Type-ID to change this block to
+ */
+ void setTypeID(int type);
+}
diff --git a/src/main/java/org/bukkit/BlockFace.java b/src/main/java/org/bukkit/BlockFace.java
new file mode 100644
index 00000000..aba16cbf
--- /dev/null
+++ b/src/main/java/org/bukkit/BlockFace.java
@@ -0,0 +1,48 @@
+package org.bukkit;
+
+/**
+ * Represents the face of a block
+ */
+public enum BlockFace {
+ North(-1, 0, 0),
+ East(0, 0, -1),
+ South(1, 0, 0),
+ West(0, 0, 1),
+ Up(0, 1, 0),
+ Down(0, -1, 0),
+ Self(0, 0, 0);
+
+ private final int modX;
+ private final int modY;
+ private final int modZ;
+
+ private BlockFace(final int modX, final int modY, final int modZ) {
+ this.modX = modX;
+ this.modY = modY;
+ this.modZ = modZ;
+ }
+
+ /**
+ * Get the amount of X-coordinates to modify to get the represented block
+ * @return Amount of X-coordinates to modify
+ */
+ public int getModX() {
+ return modX;
+ }
+
+ /**
+ * Get the amount of Y-coordinates to modify to get the represented block
+ * @return Amount of Y-coordinates to modify
+ */
+ public int getModY() {
+ return modY;
+ }
+
+ /**
+ * Get the amount of Z-coordinates to modify to get the represented block
+ * @return Amount of Z-coordinates to modify
+ */
+ public int getModZ() {
+ return modZ;
+ }
+}
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
new file mode 100644
index 00000000..4bb9431f
--- /dev/null
+++ b/src/main/java/org/bukkit/Chunk.java
@@ -0,0 +1,23 @@
+
+package org.bukkit;
+
+/**
+ * Represents a chunk of blocks
+ */
+public interface Chunk {
+
+ /**
+ * Gets the X-coordinate of this chunk
+ *
+ * @return X-coordinate
+ */
+ int getX();
+
+ /**
+ * Gets the Z-coordinate of this chunk
+ *
+ * @return Z-coordinate
+ */
+ int getZ();
+
+}
diff --git a/src/main/java/org/bukkit/Entity.java b/src/main/java/org/bukkit/Entity.java
new file mode 100644
index 00000000..849bdd2d
--- /dev/null
+++ b/src/main/java/org/bukkit/Entity.java
@@ -0,0 +1,35 @@
+
+package org.bukkit;
+
+/**
+ * Represents a base entity in the world
+ */
+public interface Entity {
+ /**
+ * Gets the entitys current position
+ *
+ * @return Location containing the position of this entity
+ */
+ public Location getLocation();
+
+ /**
+ * Gets the current world this entity resides in
+ *
+ * @return World
+ */
+ public World getWorld();
+
+ /**
+ * Teleports this entity to the given location
+ *
+ * @param location New location to teleport this entity to
+ */
+ public void teleportTo(Location location);
+
+ /**
+ * Returns a unique ID for this entity
+ *
+ * @return Entity ID
+ */
+ public int getEntityID();
+}
diff --git a/src/main/java/org/bukkit/HumanEntity.java b/src/main/java/org/bukkit/HumanEntity.java
new file mode 100644
index 00000000..349251d7
--- /dev/null
+++ b/src/main/java/org/bukkit/HumanEntity.java
@@ -0,0 +1,22 @@
+
+package org.bukkit;
+
+/**
+ * Represents a human entity, such as an NPC or a player
+ */
+public interface HumanEntity extends LivingEntity {
+ /**
+ * Returns the name of this player
+ *
+ * @return Player name
+ */
+ public String getName();
+
+ /**
+ * Gets the item this entity has currently selected, which will be shown in
+ * their hand
+ *
+ * @return ItemStack containing details on the item this entity has selected
+ */
+ public ItemStack getSelectedItem();
+}
diff --git a/src/main/java/org/bukkit/ItemStack.java b/src/main/java/org/bukkit/ItemStack.java
new file mode 100644
index 00000000..2ca42274
--- /dev/null
+++ b/src/main/java/org/bukkit/ItemStack.java
@@ -0,0 +1,81 @@
+
+package org.bukkit;
+
+/**
+ * Represents a stack of items
+ */
+public class ItemStack {
+ private int type;
+ private int amount = 0;
+
+ public ItemStack(final int type) {
+ this.type = type;
+ }
+
+ public ItemStack(final Material type) {
+ this(type.getID());
+ }
+
+ public ItemStack(final int type, final int amount) {
+ this.type = type;
+ this.amount = amount;
+ }
+
+ public ItemStack(final Material type, final int amount) {
+ this(type.getID(), amount);
+ }
+
+ /**
+ * Gets the type of this item
+ *
+ * @return Type of the items in this stack
+ */
+ public Material getType() {
+ return Material.getMaterial(type);
+ }
+
+ /**
+ * Sets the type of this item
+ *
+ * @param type New type to set the items in this stack to
+ */
+ public void setType(Material type) {
+ this.type = type.getID();
+ }
+
+ /**
+ * Gets the type ID of this item
+ *
+ * @return Type ID of the items in this stack
+ */
+ public int getTypeID() {
+ return type;
+ }
+
+ /**
+ * Sets the type ID of this item
+ *
+ * @param type New type ID to set the items in this stack to
+ */
+ public void setTypeID(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the amount of items in this stack
+ *
+ * @return Amount of items in this stick
+ */
+ public int getAmount() {
+ return amount;
+ }
+
+ /**
+ * Sets the amount of items in this stack
+ *
+ * @param amount New amount of items in this stack
+ */
+ public void setAmount(int amount) {
+ this.amount = amount;
+ }
+}
diff --git a/src/main/java/org/bukkit/LivingEntity.java b/src/main/java/org/bukkit/LivingEntity.java
new file mode 100644
index 00000000..1fd153c9
--- /dev/null
+++ b/src/main/java/org/bukkit/LivingEntity.java
@@ -0,0 +1,21 @@
+
+package org.bukkit;
+
+/**
+ * Represents a living entity, such as a monster or player
+ */
+public interface LivingEntity extends Entity {
+ /**
+ * Gets the entitys health from 0-20, where 0 is dead and 20 is full
+ *
+ * @return Health represented from 0-20
+ */
+ public int getHealth();
+
+ /**
+ * Sets the entitys health from 0-20, where 0 is dead and 20 is full
+ *
+ * @param health New health represented from 0-20
+ */
+ public void setHealth(int health);
+}
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
new file mode 100644
index 00000000..69329cd3
--- /dev/null
+++ b/src/main/java/org/bukkit/Location.java
@@ -0,0 +1,187 @@
+
+package org.bukkit;
+
+/**
+ * Represents a 3-dimensional position in a world
+ */
+public class Location implements Cloneable {
+ private World world;
+ private double x;
+ private double y;
+ private double z;
+ private float pitch;
+ private float yaw;
+
+ public Location(final World world, final double x, final double y, final double z) {
+ this(world, x, y, z, 0, 0);
+ }
+
+ public Location(final World world, final double x, final double y, final double z, final float yaw, final float pitch) {
+ this.world = world;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.pitch = pitch;
+ this.yaw = yaw;
+ }
+
+ /**
+ * Sets the world that this location resides in
+ *
+ * @param world New world that this location resides in
+ */
+ public void setWorld(World world) {
+ this.world = world;
+ }
+
+ /**
+ * Gets the world that this location resides in
+ *
+ * @return World that contains this location
+ */
+ public World getWorld() {
+ return world;
+ }
+
+ /**
+ * Sets the x-coordinate of this location
+ *
+ * @param x X-coordinate
+ */
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ /**
+ * Gets the x-coordinate of this location
+ *
+ * @return x-coordinate
+ */
+ public double getX() {
+ return x;
+ }
+
+ /**
+ * Sets the y-coordinate of this location
+ *
+ * @param y y-coordinate
+ */
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ /**
+ * Gets the y-coordinate of this location
+ *
+ * @return y-coordinate
+ */
+ public double getY() {
+ return y;
+ }
+
+ /**
+ * Sets the z-coordinate of this location
+ *
+ * @param z z-coordinate
+ */
+ public void setZ(double z) {
+ this.z = z;
+ }
+
+ /**
+ * Gets the z-coordinate of this location
+ *
+ * @return z-coordinate
+ */
+ public double getZ() {
+ return z;
+ }
+
+ /**
+ * Sets the yaw of this location
+ *
+ * @param yaw New yaw
+ */
+ public void setYaw(float yaw) {
+ this.yaw = yaw;
+ }
+
+ /**
+ * Gets the yaw of this location
+ *
+ * @return Yaw
+ */
+ public float getYaw() {
+ return yaw;
+ }
+
+ /**
+ * Sets the pitch of this location
+ *
+ * @param pitch New pitch
+ */
+ public void setPitch(float pitch) {
+ this.pitch = pitch;
+ }
+
+ /**
+ * Gets the pitch of this location
+ *
+ * @return Pitch
+ */
+ public float getPitch() {
+ return pitch;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Location other = (Location) obj;
+ if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) {
+ return false;
+ }
+ if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) {
+ return false;
+ }
+ if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) {
+ return false;
+ }
+ if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) {
+ return false;
+ }
+ if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) {
+ return false;
+ }
+ if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 19 * hash + (this.world != null ? this.world.hashCode() : 0);
+ hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
+ hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
+ hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
+ hash = 19 * hash + Float.floatToIntBits(this.pitch);
+ hash = 19 * hash + Float.floatToIntBits(this.yaw);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return "Location{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "pitch=" + pitch + "yaw=" + yaw + '}';
+ }
+
+ @Override
+ protected Location clone() {
+ return new Location(world, x, y, z, yaw, pitch);
+ }
+}
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
new file mode 100644
index 00000000..1b6323d7
--- /dev/null
+++ b/src/main/java/org/bukkit/Material.java
@@ -0,0 +1,205 @@
+package org.bukkit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An enum of all material IDs accepted by the official server + client
+ */
+public enum Material {
+ Air(0),
+ Stone(1),
+ Grass(2),
+ Dirt(3),
+ Cobblestone(4),
+ Wood(5),
+ Sapling(6),
+ Bedrock(7),
+ Water(8),
+ StationaryWater(9),
+ Lava(10),
+ StationaryLava(11),
+ Sand(12),
+ Gravel(13),
+ GoldOre(14),
+ IronOre(15),
+ CoalOre(16),
+ Log(17),
+ Leaves(18),
+ Sponge(19),
+ Glass(20),
+ Cloth(35),
+ YellowFlower(37),
+ RedRose(38),
+ BrownMushroom(39),
+ RedMushroom(40),
+ GoldBlock(41),
+ IronBlock(42),
+ DoubleStep(43),
+ Step(44),
+ Brick(45),
+ TNT(46),
+ BookShelf(47),
+ MossyCobblestone(48),
+ Obsidian(49),
+ Torch(50),
+ Fire(51),
+ MobSpawner(52),
+ WoodStairs(53),
+ Chest(54),
+ RedstoneWire(55),
+ DiamondOre(56),
+ DiamondBlock(57),
+ Workbench(58),
+ Crops(59),
+ Soil(60),
+ Furnace(61),
+ BurningFurnace(62),
+ SignPost(63),
+ WoodenDoor(64),
+ Ladder(65),
+ Rails(66),
+ CobblestoneStairs(67),
+ WallSign(68),
+ Lever(69),
+ StonePlate(70),
+ IronDoorBlock(71),
+ WoodPlate(72),
+ RedstoneOre(73),
+ GlowingRedstoneOre(74),
+ RedstoneTorchOff(75),
+ RedstoneTorchOn(76),
+ StoneButton(77),
+ Snow(78),
+ Ice(79),
+ SnowBlock(80),
+ Cactus(81),
+ Clay(82),
+ ReedBlock(83),
+ Jukebox(84),
+ Fence(85),
+ Pumpkin(86),
+ Netherstone(87),
+ SlowSand(88),
+ LightStone(89),
+ Portal(90),
+ JackOLantern(91),
+ IronSpade(256),
+ IronPickaxe(257),
+ IronAxe(258),
+ FlintAndSteel(259),
+ Apple(260),
+ Bow(261),
+ Arrow(262),
+ Coal(263),
+ Diamond(264),
+ IronIngot(265),
+ GoldIngot(266),
+ IronSword(267),
+ WoodSword(268),
+ WoodSpade(269),
+ WoodPickaxe(270),
+ WoodAxe(271),
+ StoneSword(272),
+ StoneSpade(273),
+ StonePickaxe(274),
+ StoneAxe(275),
+ DiamondSword(276),
+ DiamondSpade(277),
+ DiamondPickaxe(278),
+ DiamondAxe(279),
+ Stick(280),
+ Bowl(281),
+ MushroomSoup(282),
+ GoldSword(283),
+ GoldSpade(284),
+ GoldPickaxe(285),
+ GoldAxe(286),
+ String(287),
+ Feather(288),
+ Gunpowder(289),
+ WoodHoe(290),
+ StoneHoe(291),
+ IronHoe(292),
+ DiamondHoe(293),
+ GoldHoe(294),
+ Seeds(295),
+ Wheat(296),
+ Bread(297),
+ LeatherHelmet(298),
+ LeatherChestplate(299),
+ LeatherLeggings(300),
+ LeatherBoots(301),
+ ChainmailHelmet(302),
+ ChainmailChestplate(303),
+ ChainmailLeggings(304),
+ ChainmailBoots(305),
+ IronHelmet(306),
+ IronChestplate(307),
+ IronLeggings(308),
+ IronBoots(309),
+ DiamondHelmet(310),
+ DiamondChestplate(311),
+ DiamondLeggings(312),
+ DiamondBoots(313),
+ GoldHelmet(314),
+ GoldChestplate(315),
+ GoldLeggings(316),
+ GoldBoots(317),
+ Flint(318),
+ Pork(319),
+ GrilledPork(320),
+ Painting(321),
+ GoldenApple(322),
+ Sign(323),
+ WoodDoor(324),
+ Bucket(325),
+ WaterBucket(326),
+ LavaBucket(327),
+ Minecart(328),
+ Saddle(329),
+ IronDoor(330),
+ RedStone(331),
+ SnowBall(332),
+ Boat(333),
+ Leather(334),
+ MilkBucket(335),
+ ClayBrick(336),
+ ClayBall(337),
+ Reed(338),
+ Paper(339),
+ Book(340),
+ SlimeBall(341),
+ StorageMinecart(342),
+ PoweredMinecart(343),
+ Egg(344),
+ Compass(345),
+ FishingRod(346),
+ Watch(347),
+ LightstoneDust(348),
+ RawFish(349),
+ CookedFish(350),
+ GoldRecord(2256),
+ GreenRecord(2257);
+
+ private final int id;
+ private static final Map<Integer, Material> lookup = new HashMap<Integer, Material>();
+
+ private Material(final int id) {
+ this.id = id;
+ }
+
+ public int getID() {
+ return id;
+ }
+
+ public static Material getMaterial(final int id) {
+ return lookup.get(id);
+ }
+
+ static {
+ for (Material material : values()) {
+ lookup.put(material.getID(), material);
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/Player.java b/src/main/java/org/bukkit/Player.java
new file mode 100644
index 00000000..7d4c5ed7
--- /dev/null
+++ b/src/main/java/org/bukkit/Player.java
@@ -0,0 +1,22 @@
+
+package org.bukkit;
+
+/**
+ * Represents a player, connected or not
+ *
+ */
+public interface Player extends HumanEntity {
+ /**
+ * Checks if this player is currently online
+ *
+ * @return true if they are online
+ */
+ public boolean isOnline();
+
+ /**
+ * Sends this player a message, which will be displayed in their chat
+ *
+ * @param message Message to be displayed
+ */
+ public void sendMessage(String message);
+}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
new file mode 100644
index 00000000..1019423f
--- /dev/null
+++ b/src/main/java/org/bukkit/Server.java
@@ -0,0 +1,44 @@
+
+package org.bukkit;
+
+import org.bukkit.plugin.PluginManager;
+
+/**
+ * Represents a server implementation
+ */
+public interface Server {
+ /**
+ * Gets the name of this server implementation
+ *
+ * @return name of this server implementation
+ */
+ public String getName();
+
+ /**
+ * Gets the version string of this server implementation.
+ *
+ * @return version of this server implementation
+ */
+ public String getVersion();
+
+ /**
+ * Gets a list of all currently logged in players
+ *
+ * @return An array of Players that are currently online
+ */
+ public Player[] getOnlinePlayers();
+
+ /**
+ * Gets the PluginManager for interfacing with plugins
+ *
+ * @return PluginManager for this Server instance
+ */
+ public PluginManager getPluginManager();
+
+ /**
+ * Gets a list of all worlds on this server
+ *
+ * @return An array of worlds
+ */
+ public World[] getWorlds();
+}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
new file mode 100644
index 00000000..1ff0d7b3
--- /dev/null
+++ b/src/main/java/org/bukkit/World.java
@@ -0,0 +1,18 @@
+
+package org.bukkit;
+
+/**
+ * Represents a world.
+ *
+ * Currently there is only one world in the default Minecraft spec, but this
+ * may change with the addition of a functional Nether world
+ */
+public interface World {
+ public Block getBlockAt(int x, int y, int z);
+
+ public Chunk getChunkAt(int x, int z);
+
+ public Chunk getChunkAt(Block block);
+
+ public boolean isChunkLoaded();
+}
diff --git a/src/main/java/org/bukkit/event/Cancellable.java b/src/main/java/org/bukkit/event/Cancellable.java
new file mode 100644
index 00000000..985dc1de
--- /dev/null
+++ b/src/main/java/org/bukkit/event/Cancellable.java
@@ -0,0 +1,6 @@
+package org.bukkit.event;
+
+public interface Cancellable {
+ public boolean isCancelled();
+ public void setCancelled(boolean cancel);
+}
diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java
new file mode 100644
index 00000000..2362a31d
--- /dev/null
+++ b/src/main/java/org/bukkit/event/Event.java
@@ -0,0 +1,140 @@
+
+package org.bukkit.event;
+
+/**
+ * Represents an event
+ */
+public abstract class Event {
+ private final Type type;
+
+ protected Event(final Type type) {
+ this.type = type;
+ }
+
+ /**
+ * Gets the Type of this event
+ * @return Server which this event was triggered on
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * Represents an events priority
+ */
+ public enum Priority {
+ /**
+ * Event is critical and must be called near-first
+ */
+ Highest,
+
+ /**
+ * Event is of high importance
+ */
+ High,
+
+ /**
+ * Event is neither important or unimportant, and may be ran normally
+ */
+ Normal,
+
+ /**
+ * Event is of low importance
+ */
+ Low,
+
+ /**
+ * Event is of extremely low importance, most likely just to monitor events, and must be run near-last
+ */
+ Lowest
+ }
+
+ public enum Category {
+ PLAYER,
+ BLOCK,
+ ITEM,
+ ENVIRONMENT,
+ ENTITY,
+ VEHICLE,
+ INVENTORY,
+ SIGN,
+ CUSTOM;
+ }
+
+ public enum Type {
+ /**
+ * Player Events
+ */
+ PLAYER_JOIN (Category.PLAYER),
+ PLAYER_LOGIN (Category.PLAYER),
+ PLAYER_CHAT (Category.PLAYER),
+ PLAYER_COMMAND (Category.PLAYER),
+ PLAYER_QUIT (Category.PLAYER),
+ PLAYER_MOVE (Category.PLAYER),
+ //PLAYER_ANIMATION (Category.PLAYER),
+ PLAYER_TELEPORT (Category.PLAYER),
+ /**
+ * Block Events
+ */
+ BLOCK_BROKEN (Category.BLOCK),
+ BLOCK_CANBUILD (Category.BLOCK),
+ BLOCK_FLOW (Category.BLOCK),
+ BLOCK_IGNITE (Category.BLOCK),
+ BLOCK_PHYSICS (Category.BLOCK),
+ BLOCK_PLACED (Category.BLOCK),
+ BLOCK_RIGHTCLICKED (Category.BLOCK),
+ REDSTONE_CHANGE (Category.BLOCK);
+
+
+ /**
+ * Item Events
+
+ ITEM_DROP (Category.ITEM),
+ ITEM_PICK_UP (Category.ITEM),
+ ITEM_USE (Category.ITEM),
+ /**
+ * Environment Events
+
+ IGNITE (Category.ENVIRONMENT),
+ FLOW (Category.ENVIRONMENT),
+ EXPLODE (Category.ENVIRONMENT),
+ LIQUID_DESTROY (Category.ENVIRONMENT),
+ /**
+ * Non-player Entity Events
+
+ MOB_SPAWN (Category.ENTITY),
+ DAMAGE (Category.ENTITY),
+ HEALTH_CHANGE (Category.ENTITY),
+ ATTACK (Category.ENTITY), // Need to look into this category more
+ /**
+ * Vehicle Events
+
+ VEHICLE_CREATE (Category.VEHICLE),
+ VEHICLE_UPDATE (Category.VEHICLE),
+ VEHICLE_DAMAGE (Category.VEHICLE),
+ VEHICLE_COLLISION (Category.VEHICLE),
+ VEHICLE_DESTROYED (Category.VEHICLE),
+ VEHICLE_ENTERED (Category.VEHICLE),
+ VEHICLE_POSITIONCHANGE (Category.VEHICLE),
+ /**
+ * Inventory Events
+
+ OPEN_INVENTORY (Category.INVENTORY),
+ /**
+ * Sign Events (Item events??)
+
+ SIGN_SHOW (Category.SIGN),
+ SIGN_CHANGE (Category.SIGN);
+ */
+
+ private Category category;
+
+ private Type(Category category) {
+ this.category = category;
+ }
+
+ public Category getCategory() {
+ return category;
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/event/EventException.java b/src/main/java/org/bukkit/event/EventException.java
new file mode 100644
index 00000000..2abd7d94
--- /dev/null
+++ b/src/main/java/org/bukkit/event/EventException.java
@@ -0,0 +1,48 @@
+package org.bukkit.event;
+
+public class EventException extends Exception {
+ private static final long serialVersionUID = 3532808232324183999L;
+ private final Throwable cause;
+
+ /**
+ * Constructs a new EventException based on the given Exception
+ *
+ * @param throwable Exception that triggered this Exception
+ */
+ public EventException(Throwable throwable) {
+ cause = throwable;
+ }
+
+ /**
+ * Constructs a new EventException
+ */
+ public EventException() {
+ cause = null;
+ }
+
+ /**
+ * Constructs a new EventException with the given message
+ */
+ public EventException(Throwable cause, String message) {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Constructs a new EventException with the given message
+ */
+ public EventException(String message) {
+ super(message);
+ cause = null;
+ }
+
+ /**
+ * If applicable, returns the Exception that triggered this Exception
+ *
+ * @return Inner exception, or null if one does not exist
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/Listener.java b/src/main/java/org/bukkit/event/Listener.java
new file mode 100644
index 00000000..004d18ed
--- /dev/null
+++ b/src/main/java/org/bukkit/event/Listener.java
@@ -0,0 +1,9 @@
+
+package org.bukkit.event;
+
+/**
+ * Simple interface for tagging all EventListeners
+ */
+public interface Listener {
+
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockBrokenEvent.java b/src/main/java/org/bukkit/event/block/BlockBrokenEvent.java
new file mode 100644
index 00000000..800b84d8
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockBrokenEvent.java
@@ -0,0 +1,13 @@
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+
+/**
+ * Not implemented yet
+ */
+public class BlockBrokenEvent extends BlockEvent {
+
+ public BlockBrokenEvent(Type type, Block block ) {
+ super(type, block);
+ }
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java
new file mode 100644
index 00000000..9853164f
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java
@@ -0,0 +1,47 @@
+/**
+ *
+ */
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.Material;
+import org.bukkit.event.Cancellable;
+
+/**
+ * @author durron597
+ */
+public class BlockCanBuildEvent extends BlockEvent {
+ protected boolean buildable;
+ protected int material;
+
+ public BlockCanBuildEvent(Type type, Block block, int id, boolean canBuild) {
+ super(type, block);
+ buildable = canBuild;
+ material = id;
+ }
+
+ /**
+ * Returns whether or not the block can be built here. By default, returns
+ * Minecraft's answer on whether the block can be built
+ *
+ * @return boolean whether or not the block can be built
+ */
+ public boolean isBuildable() {
+ return buildable;
+ }
+
+ /**
+ * Set whether the block can be built here.
+ */
+ public void setBuildable(boolean cancel) {
+ this.buildable = cancel;
+ }
+
+ public Material getMaterial() {
+ return Material.getMaterial(material);
+ }
+
+ public int getMaterialID() {
+ return material;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockEvent.java b/src/main/java/org/bukkit/event/block/BlockEvent.java
new file mode 100644
index 00000000..6e50caed
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockEvent.java
@@ -0,0 +1,24 @@
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.event.Event;
+
+/**
+ * Represents a block related event
+ */
+public class BlockEvent extends Event {
+ protected Block block;
+
+ public BlockEvent(final Event.Type type, final Block theBlock) {
+ super(type);
+ block = theBlock;
+ }
+
+ /**
+ * Returns the block involved in this event
+ * @return Block which block is involved in this event
+ */
+ public final Block getBlock() {
+ return block;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockFromToEvent.java b/src/main/java/org/bukkit/event/block/BlockFromToEvent.java
new file mode 100644
index 00000000..eb2846f9
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockFromToEvent.java
@@ -0,0 +1,50 @@
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.BlockFace;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+
+/**
+ * Holds information for events with a source block and a destination block
+ */
+public class BlockFromToEvent extends BlockEvent implements Cancellable {
+ protected Block from;
+ protected BlockFace face;
+ protected boolean cancel;
+
+ public BlockFromToEvent(final Event.Type type, final Block block, final BlockFace face) {
+ super(type, block);
+ this.face = face;
+ this.from = block.getRelative(face.getModX(), face.getModY(), face.getModZ());
+ this.cancel = false;
+ }
+
+ /**
+ * Gets the location this player moved to
+ *
+ * @return Block the block is event originated from
+ */
+ public BlockFace getFace() {
+ return face;
+ }
+
+ /**
+ * Convenience method for getting the faced block
+ *
+ * @return Block the faced block
+ */
+ public Block getFromBlock() {
+ return from;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java b/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java
new file mode 100644
index 00000000..90347096
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java
@@ -0,0 +1,19 @@
+package org.bukkit.event.block;
+
+import org.bukkit.event.Event;
+
+/**
+ * @author durron597
+ *
+ */
+public class BlockIgniteEvent extends Event {
+
+ /**
+ * @param type
+ */
+ public BlockIgniteEvent(Type type) {
+ super(type);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockListener.java b/src/main/java/org/bukkit/event/block/BlockListener.java
new file mode 100644
index 00000000..cef040c3
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockListener.java
@@ -0,0 +1,81 @@
+package org.bukkit.event.block;
+
+import org.bukkit.event.Listener;
+
+/**
+ * Handles all events thrown in relation to Blocks
+ *
+ * @author durron597
+ */
+public class BlockListener implements Listener {
+ /**
+ * Default Constructor
+ */
+ public BlockListener() {
+ }
+
+ /**
+ * Called when a block is broken (or destroyed)
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockBroken(BlockBrokenEvent event) {
+ }
+
+ /**
+ * Called when we try to place a block, to see if we can build it
+ */
+ public void onBlockCanBuild(BlockCanBuildEvent event) {
+ }
+
+ /**
+ * Called when a block flows (water/lava)
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockFlow(BlockFromToEvent event) {
+ }
+
+ /**
+ * Called when a block gets ignited
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockIgnite(BlockIgniteEvent event) {
+ }
+
+ /**
+ * Called when block physics occurs
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockPhysics(BlockPhysicsEvent event) {
+ }
+
+ /**
+ * Called when a player places a block
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockPlaced(BlockPlacedEvent event) {
+ }
+
+ /**
+ * Called when redstone changes
+ * From: the source of the redstone change
+ * To: The redstone dust that changed
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockRedstoneChange(BlockFromToEvent event) {
+ }
+
+ /**
+ * Called when a player right clicks a block
+ *
+ * @param event Relevant event details
+ */
+ public void onBlockRightClicked(BlockRightClickedEvent event) {
+ }
+
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java b/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java
new file mode 100644
index 00000000..addb6b18
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java
@@ -0,0 +1,59 @@
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.ItemStack;
+import org.bukkit.Material;
+import org.bukkit.event.Event;
+
+/**
+ * Thrown when a block physics check is called
+ *
+ * @author Dinnerbone
+ */
+public class BlockPhysicsEvent extends BlockEvent {
+ private final int changed;
+ private boolean cancel = false;
+
+ public BlockPhysicsEvent(final Event.Type type, final Block block, final int changed) {
+ super(type, block);
+ this.changed = changed;
+ }
+
+ /**
+ * Gets the type of block that changed, causing this event
+ *
+ * @return Changed block's type ID
+ */
+ public int getChangedTypeID() {
+ return changed;
+ }
+
+ /**
+ * Gets the type of block that changed, causing this event
+ *
+ * @return Changed block's type
+ */
+ public Material getChangedType() {
+ return Material.getMaterial(changed);
+ }
+
+ /**
+ * Gets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * @return true if this event is cancelled
+ */
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ /**
+ * Sets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * @param cancel true if you wish to cancel this event
+ */
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java b/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java
new file mode 100644
index 00000000..de5d9427
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java
@@ -0,0 +1,32 @@
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.event.Cancellable;
+
+/**
+ * Not implemented yet
+ */
+public class BlockPlacedEvent extends BlockEvent implements Cancellable {
+ private boolean cancel;
+
+ /**
+ * @param type
+ * @param theBlock
+ */
+ public BlockPlacedEvent(Type type, Block theBlock) {
+ super(type, theBlock);
+ cancel = false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ // TODO Auto-generated method stub
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+}
diff --git a/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java b/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java
new file mode 100644
index 00000000..4f43492c
--- /dev/null
+++ b/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java
@@ -0,0 +1,53 @@
+/**
+ *
+ */
+package org.bukkit.event.block;
+
+import org.bukkit.Block;
+import org.bukkit.BlockFace;
+import org.bukkit.ItemStack;
+import org.bukkit.Player;
+
+/**
+ * @author durron597
+ */
+public class BlockRightClickedEvent extends BlockEvent {
+ protected Player clicker;
+ protected BlockFace direction;
+ protected ItemStack clickedWith;
+
+ /**
+ * @param type The type of event this is
+ * @param theBlock The clicked block
+ * @param direction The face we clicked from
+ * @param clicker The player who clicked a block
+ * @param clickedWith Item in player's hand
+ */
+ public BlockRightClickedEvent(Type type, Block theBlock, BlockFace direction, Player clicker, ItemStack clickedWith) {
+ super(type, theBlock);
+ this.direction = direction;
+ this.clicker = clicker;
+ this.clickedWith = clickedWith;
+ }
+
+ /**
+ * @return the clicker
+ */
+ public Player getClicker() {
+ return clicker;
+ }
+
+ /**
+ * @return the direction
+ */
+ public BlockFace getDirection() {
+ return direction;
+ }
+
+ /**
+ * @return the clickedWith
+ */
+ public ItemStack getClickedWith() {
+ return clickedWith;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerChatEvent.java b/src/main/java/org/bukkit/event/player/PlayerChatEvent.java
new file mode 100644
index 00000000..f67ebd86
--- /dev/null
+++ b/src/main/java/org/bukkit/event/player/PlayerChatEvent.java
@@ -0,0 +1,66 @@
+
+package org.bukkit.event.player;
+
+import org.bukkit.Player;
+import org.bukkit.event.Cancellable;
+
+/**
+ * Holds information for player chat and commands
+ */
+public class PlayerChatEvent extends PlayerEvent implements Cancellable {
+ private boolean cancel = false;
+ private String message;
+
+ public PlayerChatEvent(final Type type, final Player player, final String message) {
+ super(type, player);
+ this.message = message;
+ }
+
+ /**
+ * Gets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * @return true if this event is cancelled
+ */
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ /**
+ * Sets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * @param cancel true if you wish to cancel this event
+ */
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ /**
+ * Gets the message that the player is attempting to send
+ *
+ * @return Message the player is attempting to send
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Sets the message that the player will send
+ *
+ * @param message New message that the player will send
+ */
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ /**
+ * Sets the player that this message will display as, or command will be
+ * executed as
+ *
+ * @param player New player which this event will execute as
+ */
+ public void setPlayer(final Player player) {
+ this.player = player;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerEvent.java b/src/main/java/org/bukkit/event/player/PlayerEvent.java
new file mode 100644
index 00000000..2e4ea068
--- /dev/null
+++ b/src/main/java/org/bukkit/event/player/PlayerEvent.java
@@ -0,0 +1,25 @@
+
+package org.bukkit.event.player;
+
+import org.bukkit.Player;
+import org.bukkit.event.Event;
+
+/**
+ * Represents a player related event
+ */
+public class PlayerEvent extends Event {
+ protected Player player;
+
+ public PlayerEvent(final Event.Type type, final Player who) {
+ super(type);
+ player = who;
+ }
+
+ /**
+ * Returns the player involved in this event
+ * @return Player who is involved in this event
+ */
+ public final Player getPlayer() {
+ return player;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerListener.java b/src/main/java/org/bukkit/event/player/PlayerListener.java
new file mode 100644
index 00000000..0c6817e2
--- /dev/null
+++ b/src/main/java/org/bukkit/event/player/PlayerListener.java
@@ -0,0 +1,68 @@
+
+package org.bukkit.event.player;
+
+import org.bukkit.event.Listener;
+
+/**
+ * Handles all events thrown in relation to a Player
+ */
+public class PlayerListener implements Listener {
+ public PlayerListener() {
+ }
+
+ /**
+ * Called when a player joins a server
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerJoin(PlayerEvent event) {
+ }
+
+ /**
+ * Called when a player leaves a server
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerQuit(PlayerEvent event) {
+ }
+
+ /**
+ * Called when a player sends a chat message
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerChat(PlayerChatEvent event) {
+ }
+
+ /**
+ * Called when a player attempts to use a command
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerCommand(PlayerChatEvent event) {
+ }
+
+ /**
+ * Called when a player attempts to move location in a world
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerMove(PlayerMoveEvent event) {
+ }
+
+ /**
+ * Called when a player attempts to teleport to a new location in a world
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerTeleport(PlayerMoveEvent event) {
+ }
+
+ /**
+ * Called when a player attempts to log in to the server
+ *
+ * @param event Relevant event details
+ */
+ public void onPlayerLogin(PlayerLoginEvent event) {
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
new file mode 100644
index 00000000..e19475a9
--- /dev/null
+++ b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
@@ -0,0 +1,104 @@
+
+package org.bukkit.event.player;
+
+import org.bukkit.Player;
+
+/**
+ * Stores details for players attempting to log in
+ */
+public class PlayerLoginEvent extends PlayerEvent {
+ private Result result;
+ private String message;
+
+ public PlayerLoginEvent(final Type type, final Player player) {
+ super(type, player);
+ this.result = Result.ALLOWED;
+ this.message = "";
+ }
+
+ public PlayerLoginEvent(final Type type, final Player player, final Result result, final String message) {
+ super(type, player);
+ this.result = result;
+ this.message = message;
+ }
+
+ /**
+ * Gets the current result of the login, as an enum
+ *
+ * @return Current Result of the login
+ */
+ public Result getResult() {
+ return result;
+ }
+
+ /**
+ * Sets the new result of the login, as an enum
+ *
+ * @param result New result to set
+ */
+ public void setResult(final Result result) {
+ this.result = result;
+ }
+
+ /**
+ * Gets the current kick message that will be used if getResult() != Result.ALLOWED
+ *
+ * @return Current kick message
+ */
+ public String getKickMessage() {
+ return message;
+ }
+
+ /**
+ * Sets the kick message to display if getResult() != Result.ALLOWED
+ *
+ * @param message New kick message
+ */
+ public void setKickMessage(final String message) {
+ this.message = message;
+ }
+
+ /**
+ * Allows the player to log in
+ */
+ public void allow() {
+ result = Result.ALLOWED;
+ message = "";
+ }
+
+ /**
+ * Disallows the player from logging in, with the given reason
+ *
+ * @param result New result for disallowing the player
+ * @param message Kick message to display to the user
+ */
+ public void disallow(final Result result, final String message) {
+ this.result = result;
+ this.message = message;
+ }
+
+ /**
+ * Basic kick reasons for communicating to plugins
+ */
+ public enum Result {
+ /**
+ * The player is allowed to log in
+ */
+ ALLOWED,
+
+ /**
+ * The player is not allowed to log in, due to the server being full
+ */
+ KICK_FULL,
+
+ /**
+ * The player is not allowed to log in, due to them being banned
+ */
+ KICK_BANNED,
+
+ /**
+ * The player is not allowed to log in, for reasons undefined
+ */
+ KICK_OTHER
+ }
+}
diff --git a/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java b/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
new file mode 100644
index 00000000..24b31b59
--- /dev/null
+++ b/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
@@ -0,0 +1,86 @@
+
+package org.bukkit.event.player;
+
+import org.bukkit.Location;
+import org.bukkit.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+
+/**
+ * Holds information for player movement and teleportation events
+ */
+public class PlayerMoveEvent extends PlayerEvent implements Cancellable {
+ private boolean cancel = false;
+ private Location from;
+ private Location to;
+
+ public PlayerMoveEvent(final Event.Type type, final Player player, final Location from, final Location to) {
+ super(type, player);
+ this.from = from;
+ this.to = to;
+ }
+
+ /**
+ * Gets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * If a move or teleport event is cancelled, the player will be moved or
+ * teleported back to the Location as defined by getFrom(). This will not
+ * fire an event
+ *
+ * @return true if this event is cancelled
+ */
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ /**
+ * Sets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins
+ *
+ * If a move or teleport event is cancelled, the player will be moved or
+ * teleported back to the Location as defined by getFrom(). This will not
+ * fire an event
+ *
+ * @param cancel true if you wish to cancel this event
+ */
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ /**
+ * Gets the location this player moved from
+ *
+ * @return Location the player moved from
+ */
+ public Location getFrom() {
+ return from;
+ }
+
+ /**
+ * Sets the location to mark as where the player moved from
+ *
+ * @param from New location to mark as the players previous location
+ */
+ public void setFrom(Location from) {
+ this.from = from;
+ }
+
+ /**
+ * Gets the location this player moved to
+ *
+ * @return Location the player moved to
+ */
+ public Location getTo() {
+ return to;
+ }
+
+ /**
+ * Sets the location that this player will move to
+ *
+ * @param to New Location this player will move to
+ */
+ public void setTo(Location to) {
+ this.to = to;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java b/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java
new file mode 100644
index 00000000..e6f03892
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java
@@ -0,0 +1,36 @@
+
+package org.bukkit.plugin;
+
+/**
+ * Thrown when attempting to load an invalid PluginDescriptionFile
+ */
+public class InvalidDescriptionException extends Exception {
+ private static final long serialVersionUID = 5721389122281775894L;
+ private final Throwable cause;
+
+ /**
+ * Constructs a new InvalidDescriptionException based on the given Exception
+ *
+ * @param throwable Exception that triggered this Exception
+ */
+ public InvalidDescriptionException(Throwable throwable) {
+ cause = throwable;
+ }
+
+ /**
+ * Constructs a new InvalidDescriptionException
+ */
+ public InvalidDescriptionException() {
+ cause = null;
+ }
+
+ /**
+ * If applicable, returns the Exception that triggered this Exception
+ *
+ * @return Inner exception, or null if one does not exist
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/InvalidPluginException.java b/src/main/java/org/bukkit/plugin/InvalidPluginException.java
new file mode 100644
index 00000000..4155723a
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/InvalidPluginException.java
@@ -0,0 +1,36 @@
+
+package org.bukkit.plugin;
+
+/**
+ * Thrown when attempting to load an invalid Plugin file
+ */
+public class InvalidPluginException extends Exception {
+ private static final long serialVersionUID = -8242141640709409542L;
+ private final Throwable cause;
+
+ /**
+ * Constructs a new InvalidPluginException based on the given Exception
+ *
+ * @param throwable Exception that triggered this Exception
+ */
+ public InvalidPluginException(Throwable throwable) {
+ cause = throwable;
+ }
+
+ /**
+ * Constructs a new InvalidPluginException
+ */
+ public InvalidPluginException() {
+ cause = null;
+ }
+
+ /**
+ * If applicable, returns the Exception that triggered this Exception
+ *
+ * @return Inner exception, or null if one does not exist
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java
new file mode 100644
index 00000000..e9097cdb
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/Plugin.java
@@ -0,0 +1,47 @@
+
+package org.bukkit.plugin;
+
+import org.bukkit.Server;
+
+/**
+ * Represents a Plugin
+ */
+public interface Plugin {
+ /**
+ * Returns the plugin.yaml file containing the details for this plugin
+ *
+ * @return Contents of the plugin.yaml file
+ */
+ public PluginDescriptionFile getDescription();
+
+ /**
+ * Gets the associated PluginLoader responsible for this plugin
+ *
+ * @return PluginLoader that controls this plugin
+ */
+ public PluginLoader getPluginLoader();
+
+ /**
+ * Returns the Server instance currently running this plugin
+ *
+ * @return Server running this plugin
+ */
+ public Server getServer();
+
+ /**
+ * Returns a value indicating whether or not this plugin is currently enabled
+ *
+ * @return true if this plugin is enabled, otherwise false
+ */
+ public boolean isEnabled();
+
+ /**
+ * Called when this plugin is disabled
+ */
+ public void onDisable();
+
+ /**
+ * Called when this plugin is enabled
+ */
+ public void onEnable();
+}
diff --git a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
new file mode 100644
index 00000000..9387d253
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
@@ -0,0 +1,87 @@
+
+package org.bukkit.plugin;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.SafeConstructor;
+
+/**
+ * Provides access to a Plugins description file, plugin.yaml
+ */
+public final class PluginDescriptionFile {
+ private static final Yaml yaml = new Yaml(new SafeConstructor());
+ private String name = null;
+ private String main = null;
+
+ public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
+ try {
+ loadMap((Map<String, Object>)yaml.load(stream));
+ } catch (ClassCastException ex) {
+ throw new InvalidDescriptionException(ex);
+ }
+ }
+
+ /**
+ * Loads a PluginDescriptionFile from the specified reader
+ * @param reader
+ */
+ public PluginDescriptionFile(final Reader reader) {
+ loadMap((Map<String, Object>)yaml.load(reader));
+ }
+
+ /**
+ * Creates a new PluginDescriptionFile with the given detailed
+ *
+ * @param pluginName Name of this plugin
+ * @param mainClass Full location of the main class of this plugin
+ */
+ public PluginDescriptionFile(final String pluginName, final String mainClass) {
+ name = pluginName;
+ main = mainClass;
+ }
+
+ /**
+ * Saves this PluginDescriptionFile to the given writer
+ *
+ * @param writer Writer to output this file to
+ */
+ public void save(Writer writer) {
+ yaml.dump(saveMap(), writer);
+ }
+
+ /**
+ * Returns the name of a plugin
+ *
+ * @return String name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the main class for a plugin
+ *
+ * @return Java classpath
+ */
+ public String getMain() {
+ return main;
+ }
+
+ private void loadMap(Map<String, Object> map) throws ClassCastException {
+ name = (String)map.get("name");
+ main = (String)map.get("main");
+ }
+
+ private Map<String, Object> saveMap() {
+ Map<String, Object> map = new HashMap<String, Object>();
+
+ map.put("name", name);
+ map.put("main", main);
+
+ return map;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java
new file mode 100644
index 00000000..7d75f577
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
@@ -0,0 +1,37 @@
+
+package org.bukkit.plugin;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+import org.bukkit.event.Event;
+
+/**
+ * Represents a plugin loader, which handles direct access to specific types
+ * of plugins
+ */
+public interface PluginLoader {
+ /**
+ * Loads the plugin contained in the specified file
+ *
+ * @param file File to attempt to load
+ * @return Plugin that was contained in the specified file, or null if
+ * unsuccessful
+ * @throws InvalidPluginException Thrown when the specified file is not a plugin
+ */
+ public Plugin loadPlugin(File file) throws InvalidPluginException;
+
+ /**
+ * Returns a list of all filename filters expected by this PluginLoader
+ */
+ public Pattern[] getPluginFileFilters();
+
+ /**
+ * Calls a player related event with the given details
+ *
+ * @param registration Registered information on the plugin to call about this event
+ * @param type Type of player related event to call
+ * @param event Event details
+ */
+ public void callEvent(RegisteredListener registration, Event event);
+}
diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java
new file mode 100644
index 00000000..a2f88cb1
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
@@ -0,0 +1,87 @@
+
+package org.bukkit.plugin;
+
+import java.io.File;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.Event.Priority;
+import org.bukkit.event.Listener;
+
+/**
+ * Handles all plugin management from the Server
+ */
+public interface PluginManager {
+
+ /**
+ * Registers the specified plugin loader
+ *
+ * @param loader Class name of the PluginLoader to register
+ * @throws IllegalArgumentException Thrown when the given Class is not a valid PluginLoader
+ */
+ public void RegisterInterface(Class loader) throws IllegalArgumentException;
+
+ /**
+ * Checks if the given plugin is loaded and returns it when applicable
+ *
+ * Please note that the name of the plugin is case-sensitive
+ *
+ * @param name Name of the plugin to check
+ * @return Plugin if it exists, otherwise null
+ */
+ public Plugin getPlugin(String name);
+
+ /**
+ * Checks if the given plugin is enabled or not
+ *
+ * Please note that the name of the plugin is case-sensitive.
+ *
+ * @param name Name of the plugin to check
+ * @return true if the plugin is enabled, otherwise false
+ */
+ public boolean isPluginEnabled(String name);
+
+ /**
+ * Checks if the given plugin is enabled or not
+ *
+ * @param plugin Plugin to check
+ * @return true if the plugin is enabled, otherwise false
+ */
+ public boolean isPluginEnabled(Plugin plugin);
+
+ /**
+ * Loads the plugin in the specified file
+ *
+ * File must be valid according to the current enabled Plugin interfaces
+ *
+ * @param file File containing the plugin to load
+ * @return The Plugin loaded, or null if it was invalid
+ * @throws InvalidPluginException Thrown when the specified file is not a valid plugin
+ */
+ public Plugin loadPlugin(File file) throws InvalidPluginException;
+
+ /**
+ * Loads the plugins contained within the specified directory
+ *
+ * @param directory Directory to check for plugins
+ * @return A list of all plugins loaded
+ */
+ public Plugin[] loadPlugins(File directory);
+
+ /**
+ * Calls a player related event with the given details
+ *
+ * @param type Type of player related event to call
+ * @param event Event details
+ */
+ public void callEvent(Event event);
+
+ /**
+ * Registers the given event to the specified listener
+ *
+ * @param type EventType to register
+ * @param listener Listener to register
+ * @param priority Priority of this event
+ * @param plugin Plugin to register
+ */
+ public void registerEvent(Event.Type type, Listener listener, Priority priority, Plugin plugin);
+}
diff --git a/src/main/java/org/bukkit/plugin/RegisteredListener.java b/src/main/java/org/bukkit/plugin/RegisteredListener.java
new file mode 100644
index 00000000..1ee5a1c7
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/RegisteredListener.java
@@ -0,0 +1,44 @@
+
+package org.bukkit.plugin;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.Listener;
+
+/**
+ * Stores relevant information for plugin listeners
+ */
+public class RegisteredListener {
+ private final Listener listener;
+ private final Event.Priority priority;
+ private final Plugin plugin;
+
+ public RegisteredListener(final Listener pluginListener, final Event.Priority eventPriority, final Plugin registeredPlugin) {
+ listener = pluginListener;
+ priority = eventPriority;
+ plugin = registeredPlugin;
+ }
+
+ /**
+ * Gets the listener for this registration
+ * @return Registered Listener
+ */
+ public Listener getListener() {
+ return listener;
+ }
+
+ /**
+ * Gets the plugin for this registration
+ * @return Registered Plugin
+ */
+ public Plugin getPlugin() {
+ return plugin;
+ }
+
+ /**
+ * Gets the priority for this registration
+ * @return Registered Priority
+ */
+ public Event.Priority getPriority() {
+ return priority;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
new file mode 100644
index 00000000..d2c4b770
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -0,0 +1,216 @@
+
+package org.bukkit.plugin;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import org.bukkit.Server;
+import java.util.regex.Pattern;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.Event.Priority;
+import org.bukkit.event.Listener;
+
+/**
+ * Handles all plugin management from the Server
+ */
+public final class SimplePluginManager implements PluginManager {
+ private final Server server;
+ private final Map<Pattern, PluginLoader> fileAssociations = new HashMap<Pattern, PluginLoader>();
+ private final List<Plugin> plugins = new ArrayList<Plugin>();
+ private final Map<String, Plugin> lookupNames = new HashMap<String, Plugin>();
+ private final Map<Event.Type, List<RegisteredListener>> listeners = new EnumMap<Event.Type, List<RegisteredListener>>(Event.Type.class);
+
+ public SimplePluginManager(Server instance) {
+ server = instance;
+ }
+
+ /**
+ * Registers the specified plugin loader
+ *
+ * @param loader Class name of the PluginLoader to register
+ * @throws IllegalArgumentException Thrown when the given Class is not a valid PluginLoader
+ */
+ public void RegisterInterface(Class loader) throws IllegalArgumentException {
+ PluginLoader instance;
+
+ if (PluginLoader.class.isAssignableFrom(loader)) {
+ Constructor constructor;
+ try {
+ constructor = loader.getConstructor(Server.class);
+ instance = (PluginLoader) constructor.newInstance(server);
+ } catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException(String.format("Class %s does not have a public %s(Server) constructor", loader.getName()), ex);
+ } catch (Exception ex) {
+ throw new IllegalArgumentException(String.format("Unexpected exception %s while attempting to construct a new instance of %s", ex.getClass().getName(), loader.getName()), ex);
+ }
+ } else {
+ throw new IllegalArgumentException(String.format("Class %s does not implement interface PluginLoader", loader.getName()));
+ }
+
+ Pattern[] patterns = instance.getPluginFileFilters();
+
+ for (Pattern pattern : patterns) {
+ fileAssociations.put(pattern, instance);
+ }
+ }
+
+ /**
+ * Loads the plugins contained within the specified directory
+ *
+ * @param directory Directory to check for plugins
+ * @return A list of all plugins loaded
+ */
+ public Plugin[] loadPlugins(File directory) {
+ List<Plugin> result = new ArrayList<Plugin>();
+ File[] files = directory.listFiles();
+
+ for (File file : files) {
+ Plugin plugin = null;
+
+ try {
+ plugin = loadPlugin(file);
+ } catch (InvalidPluginException ex) {
+ Logger.getLogger(SimplePluginManager.class.getName()).log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath(), ex);
+ }
+
+ if (plugin != null) {
+ result.add(plugin);
+ }
+ }
+
+ return result.toArray(new Plugin[result.size()]);
+ }
+
+ /**
+ * Loads the plugin in the specified file
+ *
+ * File must be valid according to the current enabled Plugin interfaces
+ *
+ * @param file File containing the plugin to load
+ * @return The Plugin loaded, or null if it was invalid
+ * @throws InvalidPluginException Thrown when the specified file is not a valid plugin
+ */
+ public Plugin loadPlugin(File file) throws InvalidPluginException {
+ Set<Pattern> filters = fileAssociations.keySet();
+ Plugin result = null;
+
+ for (Pattern filter : filters) {
+ String name = file.getName();
+ Matcher match = filter.matcher(name);
+
+ if (match.find()) {
+ PluginLoader loader = fileAssociations.get(filter);
+ result = loader.loadPlugin(file);
+ }
+ }
+
+ if (result != null) {
+ plugins.add(result);
+ lookupNames.put(result.getDescription().getName(), result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Checks if the given plugin is loaded and returns it when applicable
+ *
+ * Please note that the name of the plugin is case-sensitive
+ *
+ * @param name Name of the plugin to check
+ * @return Plugin if it exists, otherwise null
+ */
+ public Plugin getPlugin(String name) {
+ return lookupNames.get(name);
+ }
+
+ /**
+ * Checks if the given plugin is enabled or not
+ *
+ * Please note that the name of the plugin is case-sensitive.
+ *
+ * @param name Name of the plugin to check
+ * @return true if the plugin is enabled, otherwise false
+ */
+ public boolean isPluginEnabled(String name) {
+ Plugin plugin = getPlugin(name);
+
+ return isPluginEnabled(plugin);
+ }
+
+ /**
+ * Checks if the given plugin is enabled or not
+ *
+ * @param plugin Plugin to check
+ * @return true if the plugin is enabled, otherwise false
+ */
+ public boolean isPluginEnabled(Plugin plugin) {
+ if ((plugin != null) && (plugins.contains(plugin))) {
+ return plugin.isEnabled();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Calls a player related event with the given details
+ *
+ * @param type Type of player related event to call
+ * @param event Event details
+ */
+ public void callEvent(Event event) {
+ List<RegisteredListener> eventListeners = listeners.get(event.getType());
+
+ if (eventListeners != null) {
+ for (RegisteredListener registration : eventListeners) {
+ Plugin plugin = registration.getPlugin();
+ PluginLoader loader = plugin.getPluginLoader();
+
+ if (plugin.isEnabled()) {
+ try {
+ loader.callEvent(registration, event);
+ } catch (Throwable ex) {
+ Logger.getLogger(SimplePluginManager.class.getName()).log(Level.SEVERE, "Could not pass event " + event.getType() + " to " + plugin.getDescription().getName(), ex);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Registers the given event to the specified listener
+ *
+ * @param type EventType to register
+ * @param listener PlayerListener to register
+ * @param priority Priority of this event
+ * @param plugin Plugin to register
+ */
+ public void registerEvent(Event.Type type, Listener listener, Priority priority, Plugin plugin) {
+ List<RegisteredListener> eventListeners = listeners.get(type);
+ int position = 0;
+
+ if (eventListeners != null) {
+ for (RegisteredListener registration : eventListeners) {
+ if (registration.getPriority().compareTo(priority) < 0) {
+ break;
+ }
+
+ position++;
+ }
+ } else {
+ eventListeners = new ArrayList<RegisteredListener>();
+ listeners.put(type, eventListeners);
+ }
+
+ eventListeners.add(position, new RegisteredListener(listener, priority, plugin));
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
new file mode 100644
index 00000000..7692e3d5
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
@@ -0,0 +1,91 @@
+
+package org.bukkit.plugin.java;
+
+import java.io.File;
+import org.bukkit.Server;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.plugin.PluginLoader;
+
+/**
+ * Represents a Java plugin
+ */
+public abstract class JavaPlugin implements Plugin {
+ private boolean isEnabled = true;
+ private final PluginLoader loader;
+ private final Server server;
+ private final File file;
+ private final PluginDescriptionFile description;
+ private final ClassLoader classLoader;
+
+ /**
+ * Constructs a new Java plugin instance
+ *
+ * @param pluginLoader PluginLoader that is responsible for this plugin
+ * @param instance Server instance that is running this plugin
+ * @param desc PluginDescriptionFile containing metadata on this plugin
+ * @param plugin File containing this plugin
+ * @param cLoader ClassLoader which holds this plugin
+ */
+ public JavaPlugin(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File plugin, ClassLoader cLoader) {
+ loader = pluginLoader;
+ server = instance;
+ file = plugin;
+ description = desc;
+ classLoader = cLoader;
+ }
+
+ /**
+ * Gets the associated PluginLoader responsible for this plugin
+ *
+ * @return PluginLoader that controls this plugin
+ */
+ public final PluginLoader getPluginLoader() {
+ return loader;
+ }
+
+ /**
+ * Returns the Server instance currently running this plugin
+ *
+ * @return Server running this plugin
+ */
+ public final Server getServer() {
+ return server;
+ }
+
+ /**
+ * Returns a value indicating whether or not this plugin is currently enabled
+ *
+ * @return true if this plugin is enabled, otherwise false
+ */
+ public final boolean isEnabled() {
+ return isEnabled;
+ }
+
+ /**
+ * Returns the file which contains this plugin
+ *
+ * @return File containing this plugin
+ */
+ protected File getFile() {
+ return file;
+ }
+
+ /**
+ * Returns the plugin.yaml file containing the details for this plugin
+ *
+ * @return Contents of the plugin.yaml file
+ */
+ public PluginDescriptionFile getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the ClassLoader which holds this plugin
+ *
+ * @return ClassLoader holding this plugin
+ */
+ protected ClassLoader getClassLoader() {
+ return classLoader;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
new file mode 100644
index 00000000..40753b02
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -0,0 +1,123 @@
+
+package org.bukkit.plugin.java;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+import org.bukkit.Server;
+import org.bukkit.event.Event;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.*;
+import org.bukkit.event.player.*;
+import org.bukkit.plugin.*;
+
+/**
+ * Represents a Java plugin loader, allowing plugins in the form of .jar
+ */
+public final class JavaPluginLoader implements PluginLoader {
+ private final Server server;
+ private final Pattern[] fileFilters = new Pattern[] {
+ Pattern.compile("\\.jar$"),
+ };
+
+ public JavaPluginLoader(Server instance) {
+ server = instance;
+ }
+
+ public Plugin loadPlugin(File file) throws InvalidPluginException {
+ JavaPlugin result = null;
+ PluginDescriptionFile description = null;
+
+ if (!file.exists()) {
+ throw new InvalidPluginException(new FileNotFoundException(String.format("%s does not exist", file.getPath())));
+ }
+ try {
+ JarFile jar = new JarFile(file);
+ JarEntry entry = jar.getJarEntry("plugin.yml");
+
+ if (entry == null) {
+ throw new InvalidPluginException(new FileNotFoundException("Jar does not contain plugin.yml"));
+ }
+
+ InputStream stream = jar.getInputStream(entry);
+ description = new PluginDescriptionFile(stream);
+
+ stream.close();
+ jar.close();
+ } catch (IOException ex) {
+ throw new InvalidPluginException(ex);
+ } catch (InvalidDescriptionException ex) {
+ throw new InvalidPluginException(ex);
+ }
+
+ try {
+ ClassLoader loader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, getClass().getClassLoader());
+ Class<?> jarClass = Class.forName(description.getMain(), true, loader);
+ Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
+ Constructor<? extends JavaPlugin> constructor = plugin.getConstructor(PluginLoader.class, Server.class, PluginDescriptionFile.class, File.class, ClassLoader.class);
+
+ result = constructor.newInstance(this, server, description, file, loader);
+ } catch (Throwable ex) {
+ throw new InvalidPluginException(ex);
+ }
+
+ return (Plugin)result;
+ }
+
+ public Pattern[] getPluginFileFilters() {
+ return fileFilters;
+ }
+
+ public void callEvent(RegisteredListener registration, Event event) {
+ Listener listener = registration.getListener();
+
+ if (listener instanceof PlayerListener) {
+ PlayerListener trueListener = (PlayerListener)listener;
+
+ switch (event.getType()) {
+ case PLAYER_JOIN:
+ trueListener.onPlayerJoin((PlayerEvent)event);
+ break;
+ case PLAYER_QUIT:
+ trueListener.onPlayerQuit((PlayerEvent)event);
+ break;
+ case PLAYER_COMMAND:
+ trueListener.onPlayerCommand((PlayerChatEvent)event);
+ break;
+ case PLAYER_CHAT:
+ trueListener.onPlayerChat((PlayerChatEvent)event);
+ break;
+ case PLAYER_MOVE:
+ trueListener.onPlayerMove((PlayerMoveEvent)event);
+ break;
+ case PLAYER_TELEPORT:
+ trueListener.onPlayerTeleport((PlayerMoveEvent)event);
+ break;
+ case PLAYER_LOGIN:
+ trueListener.onPlayerLogin((PlayerLoginEvent)event);
+ break;
+ }
+ } else if (listener instanceof BlockListener) {
+ BlockListener trueListener = (BlockListener)listener;
+
+ switch (event.getType()) {
+ case BLOCK_PHYSICS:
+ trueListener.onBlockPhysics((BlockPhysicsEvent)event);
+ break;
+ case BLOCK_CANBUILD:
+ trueListener.onBlockCanBuild((BlockCanBuildEvent)event);
+ break;
+ case BLOCK_FLOW:
+ trueListener.onBlockFlow((BlockFromToEvent)event);
+ break;
+ }
+ }
+ }
+}