diff --git a/paper-api/src/main/java/org/bukkit/Block.java b/paper-api/src/main/java/org/bukkit/Block.java index 8909de4d9d..d2719be28a 100644 --- a/paper-api/src/main/java/org/bukkit/Block.java +++ b/paper-api/src/main/java/org/bukkit/Block.java @@ -1,7 +1,12 @@ package org.bukkit; +import org.bukkit.block.BlockState; + /** - * Represents a block + * Represents a block. This is a live object, and only one Block may exist for + * any given location in a world. The state of the block may change concurrently + * to your own handling of it; use block.getState() to get a snapshot state of a + * block which will not be modified. */ public interface Block { /** @@ -12,13 +17,33 @@ public interface Block { byte getData(); /** - * Gets the block at the given face + * Gets the block at the given face
+ *
+ * This method is equal to getFace(face, 1) * * @param face Face of this block to return * @return Block at the given face + * @see Block.getFace(BlockFace face, int distance); */ Block getFace(BlockFace face); + /** + * Gets the block at the given distance of the given face
+ *
+ * For example, the following method places water at 100,102,100; two blocks + * above 100,100,100. + *
+     * Block block = world.getBlockAt(100,100,100);
+     * Block shower = block.getFace(BlockFace.Up, 2);
+     * shower.setType(Material.WATER);
+     * 
+ * + * @param face Face of this block to return + * @param distance Distance to get the block at + * @return Block at the given face + */ + Block getFace(BlockFace face, int distance); + /** * Gets the block at the given offsets * @@ -105,4 +130,33 @@ public interface Block { * @param type Type-ID to change this block to */ void setTypeID(int type); + + /** + * Gets the face relation of this block compared to the given block
+ *
+ * For example: + *
+     * Block current = world.getBlockAt(100, 100, 100);
+     * Block target = world.getBlockAt(100, 101, 100);
+     *
+     * current.getFace(target) == BlockFace.Up;
+     * 
+ *
+ * If the given block is not connected to this block, null may be returned + * + * @param block Block to compare against this block + * @return BlockFace of this block which has the requested block, or null + */ + BlockFace getFace(Block block); + + /** + * Captures the current state of this block. You may then cast that state + * into any accepted type, such as Furnace or Sign. + * + * The returned object will never be updated, and you are not guaranteed that + * (for example) a sign is still a sign after you capture its state. + * + * @return BlockState with the current state of this block. + */ + BlockState getState(); } diff --git a/paper-api/src/main/java/org/bukkit/BlockFace.java b/paper-api/src/main/java/org/bukkit/BlockFace.java index aba16cbf6f..12eb2c54d3 100644 --- a/paper-api/src/main/java/org/bukkit/BlockFace.java +++ b/paper-api/src/main/java/org/bukkit/BlockFace.java @@ -10,6 +10,10 @@ public enum BlockFace { West(0, 0, 1), Up(0, 1, 0), Down(0, -1, 0), + NorthEast(North, East), + NorthWest(North, West), + SouthEast(South, East), + SouthWest(South, West), Self(0, 0, 0); private final int modX; @@ -22,6 +26,12 @@ public enum BlockFace { this.modZ = modZ; } + private BlockFace(final BlockFace face1, final BlockFace face2) { + this.modX = face1.getModX() + face2.getModX(); + this.modY = face1.getModY() + face2.getModY(); + this.modZ = face1.getModZ() + face2.getModZ(); + } + /** * Get the amount of X-coordinates to modify to get the represented block * @return Amount of X-coordinates to modify diff --git a/paper-api/src/main/java/org/bukkit/Chunk.java b/paper-api/src/main/java/org/bukkit/Chunk.java index 4bb9431fff..3f158f5b72 100644 --- a/paper-api/src/main/java/org/bukkit/Chunk.java +++ b/paper-api/src/main/java/org/bukkit/Chunk.java @@ -20,4 +20,10 @@ public interface Chunk { */ int getZ(); + /** + * Gets the world containing this chunk + * + * @return Parent World + */ + World getWorld(); } diff --git a/paper-api/src/main/java/org/bukkit/Inventory.java b/paper-api/src/main/java/org/bukkit/Inventory.java new file mode 100644 index 0000000000..7378903e57 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/Inventory.java @@ -0,0 +1,65 @@ +package org.bukkit; + +import java.util.Collection; + +/** + * Interface to the various inventories + */ +public interface Inventory { + /** + * Returns the size of the inventory + * + * @return The inventory size + */ + public int getSize(); + + /** + * Return the name of the inventory + * + * @return The inventory name + */ + public String getName(); + + /** + * TODO Set the name of the inventory + * + * @param name The new name of the inventory + public void setName(String name); + */ + + /** TODO: Appears minecraft has different ideas for slots! + * Get the slot at a specific index of an inventory + * + * @param index The index of the slot to get + * @return The Slot found at the index + public Slot getSlot(int index); + */ + + /** + * Get the ItemStack found in the slot at the given index + * + * @param index The index of the Slot's ItemStack to return + * @return The ItemStack in the slot + */ + public ItemStack getItem(int index); + + /** + * Get all ItemStacks from the inventory + * + * @return All the ItemStacks from all slots + */ + public Collection getContents(); + + /* + * TODO public boolean contains(int materialId); public boolean + * contains(Material material); public boolean contains(ItemStack item); + * + * public Collection all(int materialId); public Collection + * all(Material material); public Collection all(ItemStack item); + * + * public Slot first(int materialId); public Slot first(Material material); + * public Slot first(ItemStack item); + * + * public int firstEmptyIndex(); + */ +} \ No newline at end of file diff --git a/paper-api/src/main/java/org/bukkit/ItemStack.java b/paper-api/src/main/java/org/bukkit/ItemStack.java index 2ca42274ab..f235062134 100644 --- a/paper-api/src/main/java/org/bukkit/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/ItemStack.java @@ -1,81 +1,118 @@ - -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; - } -} + +package org.bukkit; + +/** + * Represents a stack of items + */ +public class ItemStack { + private int type; + private int amount = 0; + private byte damage = 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); + } + + public ItemStack(final int type, final int amount, final byte damage) { + this.type = type; + this.amount = amount; + this.damage = damage; + } + + public ItemStack(final Material type, final int amount, final byte damage) { + this(type.getID(), amount, damage); + } + + /** + * 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) { + setTypeID(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; + } + + /** + * Sets the damage of this item

+ * + * 0x00 represents an item which cannot be damaged
+ * 0x01 represents an item at maximum health
+ * 0x32 represents an item with no health left + * + * @param damage Damage of this item + */ + public void setDamage(final byte damage) { + this.damage = damage; + } + + /** + * Gets the damage of this item

+ * + * 0x00 represents an item which cannot be damaged
+ * 0x01 represents an item at maximum health
+ * 0x32 represents an item with no health left + * + * @return Damage of this item + */ + public byte getDamage() { + return damage; + } +} diff --git a/paper-api/src/main/java/org/bukkit/Material.java b/paper-api/src/main/java/org/bukkit/Material.java index d114d042d0..3d0d680650 100644 --- a/paper-api/src/main/java/org/bukkit/Material.java +++ b/paper-api/src/main/java/org/bukkit/Material.java @@ -193,10 +193,14 @@ public enum Material { return id; } + public boolean isBlock() { + return id < 256; + } + public static Material getMaterial(final int id) { return lookup.get(id); } - + static { for (Material material : values()) { lookup.put(material.getID(), material); diff --git a/paper-api/src/main/java/org/bukkit/Player.java b/paper-api/src/main/java/org/bukkit/Player.java index 7d4c5ed722..ffa03eb8e5 100644 --- a/paper-api/src/main/java/org/bukkit/Player.java +++ b/paper-api/src/main/java/org/bukkit/Player.java @@ -19,4 +19,24 @@ public interface Player extends HumanEntity { * @param message Message to be displayed */ public void sendMessage(String message); + + /** + * Gets the "friendly" name to display of this player. This may include color. + * + * Note that this name will not be displayed in game, only in chat and places + * defined by plugins + * + * @return String containing a color formatted name to display for this player + */ + public String getDisplayName(); + + /** + * Sets the "friendly" name to display of this player. This may include color. + * + * Note that this name will not be displayed in game, only in chat and places + * defined by plugins + * + * @return String containing a color formatted name to display for this player + */ + public void setDisplayName(String name); } diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index 503901cd9f..f355692239 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -1,6 +1,7 @@ package org.bukkit; +import java.util.List; import org.bukkit.plugin.PluginManager; /** @@ -38,6 +39,18 @@ public interface Server { */ public Player getPlayer(String name); + /** + * Attempts to match any players with the given name, and returns a list + * of all possibly matches + * + * This list is not sorted in any particular order. If an exact match is found, + * the returned list will only contain a single result. + * + * @param name Name to match + * @return List of all possible players + */ + public List matchPlayer(String name); + /** * Gets the PluginManager for interfacing with plugins * @@ -51,4 +64,18 @@ public interface Server { * @return An array of worlds */ public World[] getWorlds(); + + /** + * Gets the in-game time on the server (in hours*1000) + * + * @return The current time in hours*1000 + */ + public long getTime(); + + /** + * Sets the in-game time on the server (in hours*1000) + * + * @param time The time to set the in-game time to (in hours*1000) + */ + public void setTime(long time); } diff --git a/paper-api/src/main/java/org/bukkit/Slot.java b/paper-api/src/main/java/org/bukkit/Slot.java new file mode 100644 index 0000000000..3ead03998f --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/Slot.java @@ -0,0 +1,41 @@ +package org.bukkit; + +/** + * Represents a slot in an inventory + */ +public class Slot { + private Inventory inventory; + private int index; + + public Slot(Inventory inventory, int index) { + this.inventory = inventory; + this.index = index; + } + + /** + * Gets the inventory this slot belongs to + * + * @return The inventory + */ + public Inventory getInventory() { + return inventory; + } + + /** + * Get the index this slot belongs to + * + * @return Index of the slot + */ + public int getIndex() { + return index; + } + + /** + * Get the item from the slot. + * + * @return ItemStack in the slot. + */ + public ItemStack getItem() { + return inventory.getItem(index); + } +} diff --git a/paper-api/src/main/java/org/bukkit/StorageMinecart.java b/paper-api/src/main/java/org/bukkit/StorageMinecart.java index 2d4a4afbdd..bd7b1b02e0 100644 --- a/paper-api/src/main/java/org/bukkit/StorageMinecart.java +++ b/paper-api/src/main/java/org/bukkit/StorageMinecart.java @@ -5,5 +5,5 @@ package org.bukkit; * * @author sk89q */ -public interface StorageMinecart extends Minecart { +public interface StorageMinecart extends Minecart, Inventory { } diff --git a/paper-api/src/main/java/org/bukkit/block/BlockState.java b/paper-api/src/main/java/org/bukkit/block/BlockState.java new file mode 100644 index 0000000000..cb124fc790 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/block/BlockState.java @@ -0,0 +1,138 @@ + +package org.bukkit.block; + +import org.bukkit.Block; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; + +/** + * Represents a captured state of a block, which will not change automatically. + * + * Unlike Block, which only one object can exist per coordinate, BlockState can + * exist multiple times for any given Block. Note that another plugin may change + * the state of the block and you will not know, or they may change the block to + * another type entirely, causing your BlockState to become invalid. + */ +public interface BlockState { + /** + * Gets the block represented by this BlockState + * + * @return Block that this BlockState represents + */ + Block getBlock(); + + /** + * Gets the metadata for this block + * + * @return block specific metadata + */ + byte getData(); + + /** + * 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 light level between 0-15 + * + * @return light level + */ + byte getLightLevel(); + + /** + * 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); + + /** + * Attempts to update the block represented by this state, setting it to the + * new values as defined by this state.
+ *
+ * This has the same effect as calling update(false). That is to say, + * this will not modify the state of a block if it is no longer the same + * type as it was when this state was taken. It will return false in this + * eventuality. + * + * @return true if the update was successful, otherwise false + * @see BlockState.update(boolean force) + */ + boolean update(); + + /** + * Attempts to update the block represented by this state, setting it to the + * new values as defined by this state.
+ *
+ * Unless force is true, this will not modify the state of a block if it is + * no longer the same type as it was when this state was taken. It will return + * false in this eventuality.
+ *
+ * If force is true, it will set the type of the block to match the new state, + * set the state data and then return true. + * + * @param force true to forcefully set the state + * @return true if the update was successful, otherwise false + */ + boolean update(boolean force); +} diff --git a/paper-api/src/main/java/org/bukkit/block/Sign.java b/paper-api/src/main/java/org/bukkit/block/Sign.java new file mode 100644 index 0000000000..8731f6c279 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/block/Sign.java @@ -0,0 +1,37 @@ + +package org.bukkit.block; + +/** + * Represents either a SignPost or a WallSign + */ +public interface Sign extends BlockState { + /** + * Gets all the lines of text currently on this sign. + * + * @return Array of Strings containing each line of text + */ + public String[] getLines(); + + /** + * Gets the line of text at the specified index. + * + * For example, getLine(0) will return the first line of text. + * + * @param index Line number to get the text from, starting at 0 + * @throws IndexOutOfBoundsException Thrown when the line does not exist + * @return Text on the given line + */ + public String getLine(int index) throws IndexOutOfBoundsException; + + /** + * Sets the line of text at the specified index. + * + * For example, setLine(0, "Line One") will set the first line of text to + * "Line One". + * + * @param index Line number to set the text at, starting from 0 + * @param line New text to set at the specified index + * @throws IndexOutOfBoundsException + */ + public void setLine(int index, String line) throws IndexOutOfBoundsException; +} diff --git a/paper-api/src/main/java/org/bukkit/event/Event.java b/paper-api/src/main/java/org/bukkit/event/Event.java index fe1d69207a..f6bf423607 100644 --- a/paper-api/src/main/java/org/bukkit/event/Event.java +++ b/paper-api/src/main/java/org/bukkit/event/Event.java @@ -170,6 +170,33 @@ public abstract class Event { */ PLAYER_ANIMATION (Category.PLAYER), + /** + * Always called when a player uses an item while pointing at a block + * Sometimes, cancelling this event doesn't do anything. + * + * This is the event that is called on block placement. Cancel this + * to prevent block placement. This will ALWAYS be called, even if + * universe physics prevents the block from being placed. This allows + * you to add functionality to rightclicking with block items even + * if the universe won't allow them to get placed. Use BLOCK_CANBUILD + * to override notch's block placement rules. + * + * Example: This event is also called, for example when redstone is + * placed, when a sign is placed, when minecarts are placed on a track, + * when boats are placed (in both water and air) + */ + PLAYER_BLOCKITEM (Category.PLAYER), + + /** + * Called when a player uses an item while pointing at the air + * This can also be additionally called while pointing at the ground + * + * Example: all food will also call this event while pointing at the + * ground, bows/snowballs/eggs will all call this while pointing at + * the ground, buckets call this event. + */ + PLAYER_ITEM (Category.PLAYER), + /** * Called when a player teleports from one position to another */ @@ -185,7 +212,8 @@ public abstract class Event { BLOCK_DAMAGED (Category.BLOCK), /** - * Called when a block is undergoing a check on whether it can be built + * Called when a block is undergoing a universe physics + * check on whether it can be built * * For example, cacti cannot be built on grass unless overridden here */ @@ -210,16 +238,16 @@ public abstract class Event { * type */ BLOCK_PHYSICS (Category.BLOCK), - + /** * Called when a player is attempting to place a block */ BLOCK_PLACED (Category.BLOCK), /** - * Called when a specific block is being sent to a player + * Called when leaves are decaying naturally */ - BLOCK_SENT (Category.BLOCK), + LEAVES_DECAY (Category.BLOCK), /** * Called when a liquid attempts to flow into a block which already diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockListener.java b/paper-api/src/main/java/org/bukkit/event/block/BlockListener.java index c760758849..a26c42c23b 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockListener.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockListener.java @@ -1,81 +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) { - } - -} +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 leaves are decaying naturally + * + * @param event Relevant event details + */ + public void onLeavesDecay(LeavesDecayEvent event) { + } + +} diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java index 030a2dd92a..6bc1896877 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockPlacedEvent.java @@ -11,24 +11,36 @@ public class BlockPlacedEvent extends BlockEvent implements Cancellable { private boolean cancel; private Player player; - /** - * @param type - * @param theBlock - */ public BlockPlacedEvent(Type type, Block theBlock) { super(type, theBlock); cancel = false; } - + + /** + * Gets the player who placed this block + * + * @return Player who placed the block + */ public Player getPlayer() { return player; } + /** + * 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() { - // TODO Auto-generated method stub 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/paper-api/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java deleted file mode 100644 index ba5b6bb3c3..0000000000 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockRightClickedEvent.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * - */ -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/paper-api/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java b/paper-api/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java new file mode 100644 index 0000000000..1ee2f4039c --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java @@ -0,0 +1,36 @@ + +package org.bukkit.event.block; + +import org.bukkit.Block; +import org.bukkit.event.Cancellable; + +/** + * Called on leaves decaying + */ +public class LeavesDecayEvent extends BlockEvent implements Cancellable { + private boolean cancel = false; + + public LeavesDecayEvent(final Type type, final Block block) { + super(type, block); + } + + /** + * 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/paper-api/src/main/java/org/bukkit/event/player/PlayerBlockItemEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerBlockItemEvent.java new file mode 100644 index 0000000000..766296e3ef --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerBlockItemEvent.java @@ -0,0 +1,85 @@ +package org.bukkit.event.player; + +import org.bukkit.Block; +import org.bukkit.BlockFace; +import org.bukkit.ItemStack; +import org.bukkit.Player; +import org.bukkit.event.Cancellable; + +/** + * Represents an event that a block was clicked with an item. + * + * Note: while this is the event that is thrown on block placement, there is no + * BlockPlaced associated with this event. This is because the event is thrown + * before the block is written to the universe, so the returned block would not + * be the new placed block. In hMod, BlockPlaced worked by UNDOING the block + * placement; in Bukkit, we catch the event before it even gets written to the + * universe, so the concept of a placed block is meaningless. + * + * To get the type of block that's being placed, use the method getItem (for + * the item in your hand). + * + * @author durron597 + */ +public class PlayerBlockItemEvent extends PlayerItemEvent implements Cancellable { + protected Block blockClicked; + protected BlockFace direction; + protected boolean canBuild; + + public PlayerBlockItemEvent(Type type, Player who, ItemStack item, Block blockClicked, BlockFace direction, boolean canBuild) { + super(type, who, item); + this.blockClicked = blockClicked; + this.canBuild = canBuild; + } + + /** + * Convenience method to inform the user whether this was a block placement + * event. + * + * @return boolean true if the item in hand was a block + */ + public boolean isBlock() { + if (item == null) return false; + + return item.getType().isBlock(); + } + + /** + * Returns the clicked block + * + * @return Block returns the block clicked with this item. + */ + public Block getBlockClicked() { + return blockClicked; + } + + /** + * Returns the face of the block that was clicked + * + * @return BlockFace returns the face of the block that was clicked + */ + public BlockFace getBlockFace() { + return direction; + } + + /** + * Gets the value whether the player would be allowed to build here. + * Defaults to spawn if the server was going to stop them (such as, the + * player is in Spawn). Note that this is an entirely different check + * than BLOCK_CANBUILD, as this refers to a player, not universe-physics + * rule like cactus on dirt. + * + * @return boolean whether the server would allow a player to build here + */ + public boolean canBuild() { + return this.canBuild; + } + + /** + * Sets the canBuild state of this event. Set to true if you want the + * player to be able to build. + */ + public void setBuild(boolean canBuild) { + this.canBuild = canBuild; + } +} diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerChatEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerChatEvent.java index f67ebd8627..b97ac5a6a9 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerChatEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerChatEvent.java @@ -10,6 +10,7 @@ import org.bukkit.event.Cancellable; public class PlayerChatEvent extends PlayerEvent implements Cancellable { private boolean cancel = false; private String message; + private String format = "<%1$s> %2$s"; public PlayerChatEvent(final Type type, final Player player, final String message) { super(type, player); @@ -63,4 +64,22 @@ public class PlayerChatEvent extends PlayerEvent implements Cancellable { public void setPlayer(final Player player) { this.player = player; } + + /** + * Gets the format to use to display this chat message + * + * @return String.Format compatible format string + */ + public String getFormat() { + return format; + } + + /** + * Sets the format to use to display this chat message + * + * @param format String.Format compatible format string + */ + public void setFormat(final String format) { + this.format = format; + } } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemEvent.java new file mode 100644 index 0000000000..842a0eb0e5 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemEvent.java @@ -0,0 +1,67 @@ +package org.bukkit.event.player; + +import org.bukkit.ItemStack; +import org.bukkit.Material; +import org.bukkit.Player; +import org.bukkit.event.Cancellable; + +/** + * + * @author durron597 + * + */ +public class PlayerItemEvent extends PlayerEvent implements Cancellable { + protected ItemStack item; + protected boolean cancel; + + public PlayerItemEvent(Type type, Player who, ItemStack item) { + super(type, who); + this.item = item; + cancel = false; + } + + /** + * Gets the cancellation state of this event. Set to true if you + * want to prevent buckets from placing water and so forth + * + * @return boolean cancellation state + */ + 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 + * + * Cancelling this event will prevent use of food (player won't lose the + * food item), prevent bows/snowballs/eggs from firing, etc. (player won't + * lose the ammo) + * + * @param cancel true if you wish to cancel this event + */ + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Returns the item in hand represented by this event + * + * @return ItemStack the item used + */ + public ItemStack getItem() { + return this.item; + } + + /** + * Convenience method. Returns the material of the item represented by this + * event + * + * @return Material the material of the item used + */ + public Material getMaterial() { + if (this.item == null) return Material.Air; + + return item.getType(); + } +} diff --git a/paper-api/src/main/java/org/bukkit/event/world/ChunkLoadedEvent.java b/paper-api/src/main/java/org/bukkit/event/world/ChunkLoadedEvent.java new file mode 100644 index 0000000000..f91b7aebe6 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/world/ChunkLoadedEvent.java @@ -0,0 +1,26 @@ + +package org.bukkit.event.world; + +import org.bukkit.Chunk; + +/** + * Called when a chunk is loaded + */ +public class ChunkLoadedEvent extends WorldEvent { + private final Chunk chunk; + + public ChunkLoadedEvent(final Type type, final Chunk chunk) { + super(type, chunk.getWorld()); + + this.chunk = chunk; + } + + /** + * Gets the chunk being loaded/unloaded + * + * @return Chunk that triggered this event + */ + public Chunk getChunk() { + return chunk; + } +} diff --git a/paper-api/src/main/java/org/bukkit/event/world/ChunkUnloadedEvent.java b/paper-api/src/main/java/org/bukkit/event/world/ChunkUnloadedEvent.java new file mode 100644 index 0000000000..fc9d57b1de --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/world/ChunkUnloadedEvent.java @@ -0,0 +1,36 @@ + +package org.bukkit.event.world; + +import org.bukkit.Chunk; +import org.bukkit.event.Cancellable; + +/** + * Called when a chunk is unloaded + */ +public class ChunkUnloadedEvent extends ChunkLoadedEvent implements Cancellable { + private boolean cancel = false; + + public ChunkUnloadedEvent(final Type type, final Chunk chunk) { + super(type, chunk); + } + + /** + * 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/paper-api/src/main/java/org/bukkit/event/world/WorldEvent.java b/paper-api/src/main/java/org/bukkit/event/world/WorldEvent.java new file mode 100644 index 0000000000..d877758a99 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/world/WorldEvent.java @@ -0,0 +1,27 @@ + +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.Event; + +/** + * Represents events within a world + */ +public class WorldEvent extends Event { + private final World world; + + public WorldEvent(final Type type, final World world) { + super(type); + + this.world = world; + } + + /** + * Gets the world primarily involved with this event + * + * @return World which caused this event + */ + public World getWorld() { + return world; + } +} diff --git a/paper-api/src/main/java/org/bukkit/event/world/WorldListener.java b/paper-api/src/main/java/org/bukkit/event/world/WorldListener.java new file mode 100644 index 0000000000..fc8f5799f3 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/event/world/WorldListener.java @@ -0,0 +1,25 @@ + +package org.bukkit.event.world; + +import org.bukkit.event.Listener; + +/** + * Handles all World related events + */ +public class WorldListener implements Listener { + /** + * Called when a chunk is loaded + * + * @param event Relevant event details + */ + public void onChunkLoaded(ChunkLoadedEvent event) { + } + + /** + * Called when a chunk is unloaded + * + * @param event Relevant event details + */ + public void onChunkUnloaded(ChunkUnloadedEvent event) { + } +} diff --git a/paper-api/src/main/java/org/bukkit/fillr/Getter.java b/paper-api/src/main/java/org/bukkit/fillr/Getter.java index f38eda4557..1bbd5b4c27 100644 --- a/paper-api/src/main/java/org/bukkit/fillr/Getter.java +++ b/paper-api/src/main/java/org/bukkit/fillr/Getter.java @@ -1,8 +1,11 @@ package org.bukkit.fillr; import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; import org.bukkit.*; +import org.bukkit.plugin.InvalidDescriptionException; import org.bukkit.plugin.InvalidPluginException; public class Getter { @@ -25,8 +28,8 @@ public class Getter { player.sendMessage("Finished Download!"); enablePlugin(reader); player.sendMessage("Loading " + reader.getName()); - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception ex) { + Logger.getLogger(Getter.class.getName()).log(Level.SEVERE, null, ex); } } @@ -36,8 +39,10 @@ public class Getter { File plugin = new File(directory, name + ".jar"); try { server.getPluginManager().loadPlugin(plugin); - } catch (InvalidPluginException e) { - e.printStackTrace(); + } catch (InvalidPluginException ex) { + Logger.getLogger(Getter.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvalidDescriptionException ex) { + Logger.getLogger(Getter.class.getName()).log(Level.SEVERE, null, ex); } } } diff --git a/paper-api/src/main/java/org/bukkit/fillr/Updater.java b/paper-api/src/main/java/org/bukkit/fillr/Updater.java index c429ed908c..1ca26b60a2 100644 --- a/paper-api/src/main/java/org/bukkit/fillr/Updater.java +++ b/paper-api/src/main/java/org/bukkit/fillr/Updater.java @@ -4,6 +4,8 @@ import org.bukkit.*; import org.bukkit.plugin.*; import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; public class Updater { public static String directory = Fillr.directory; @@ -95,8 +97,10 @@ public class Updater { File plugin = new File(directory, name + ".jar"); try { server.getPluginManager().loadPlugin(plugin); - } catch (InvalidPluginException e) { - e.printStackTrace(); + } catch (InvalidPluginException ex) { + Logger.getLogger(Getter.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvalidDescriptionException ex) { + Logger.getLogger(Getter.class.getName()).log(Level.SEVERE, null, ex); } } diff --git a/paper-api/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java b/paper-api/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java index 1179721285..a1a7551a35 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java +++ b/paper-api/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java @@ -1,36 +1,62 @@ - -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; - } -} + +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; + private final String message; + + /** + * Constructs a new InvalidDescriptionException based on the given Exception + * + * @param throwable Exception that triggered this Exception + */ + public InvalidDescriptionException(Throwable throwable) { + this(throwable, "Invalid plugin.yml"); + } + + /** + * Constructs a new InvalidDescriptionException with the given message + * + * @param message Brief message explaining the cause of the exception + */ + public InvalidDescriptionException(final String message) { + this(null, message); + } + + /** + * Constructs a new InvalidDescriptionException based on the given Exception + * + * @param message Brief message explaining the cause of the exception + * @param throwable Exception that triggered this Exception + */ + public InvalidDescriptionException(final Throwable throwable, final String message) { + this.cause = null; + this.message = message; + } + + /** + * Constructs a new InvalidDescriptionException + */ + public InvalidDescriptionException() { + this(null, "Invalid plugin.yml"); + } + + /** + * 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; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java index ed1ca0c934..72a26304a5 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java @@ -20,11 +20,7 @@ public final class PluginDescriptionFile { @SuppressWarnings("unchecked") public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException { - try { - loadMap((Map)yaml.load(stream)); - } catch (ClassCastException ex) { - throw new InvalidDescriptionException(ex); - } + loadMap((Map)yaml.load(stream)); } /** @@ -32,10 +28,10 @@ public final class PluginDescriptionFile { * @param reader */ @SuppressWarnings("unchecked") - public PluginDescriptionFile(final Reader reader) { + public PluginDescriptionFile(final Reader reader) throws InvalidDescriptionException { loadMap((Map)yaml.load(reader)); } - + /** * Creates a new PluginDescriptionFile with the given detailed * @@ -65,7 +61,7 @@ public final class PluginDescriptionFile { public String getName() { return name; } - + /** * Returns the version of a plugin * @@ -84,10 +80,30 @@ public final class PluginDescriptionFile { return main; } - private void loadMap(Map map) throws ClassCastException { - name = (String)map.get("name"); - main = (String)map.get("main"); - version = (String)map.get("version"); + private void loadMap(Map map) throws InvalidDescriptionException { + try { + name = map.get("name").toString(); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "name is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "name is of wrong type"); + } + + try { + version = map.get("version").toString(); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "version is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "version is of wrong type"); + } + + try { + main = map.get("main").toString(); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "main is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "main is of wrong type"); + } } private Map saveMap() { diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java index a652b4bacf..d8a266449f 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java @@ -19,7 +19,7 @@ public interface PluginLoader { * unsuccessful * @throws InvalidPluginException Thrown when the specified file is not a plugin */ - public Plugin loadPlugin(File file) throws InvalidPluginException; + public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException; /** * Returns a list of all filename filters expected by this PluginLoader diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginManager.java b/paper-api/src/main/java/org/bukkit/plugin/PluginManager.java index 0b6d7a308d..a2d35e394c 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginManager.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginManager.java @@ -56,8 +56,9 @@ public interface PluginManager { * @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 + * @throws InvalidDescriptionException Thrown when the specified file contains an invalid description */ - public Plugin loadPlugin(File file) throws InvalidPluginException; + public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException; /** * Loads the plugins contained within the specified directory diff --git a/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 44cc0eb9df..d9f25afa1d 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -79,7 +79,9 @@ public final class SimplePluginManager implements PluginManager { try { plugin = loadPlugin(file); } catch (InvalidPluginException ex) { - Logger.getLogger(SimplePluginManager.class.getName()).log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath(), ex); + Logger.getLogger(SimplePluginManager.class.getName()).log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex); + } catch (InvalidDescriptionException ex) { + Logger.getLogger(SimplePluginManager.class.getName()).log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex); } if (plugin != null) { @@ -98,8 +100,9 @@ public final class SimplePluginManager implements PluginManager { * @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 + * @throws InvalidDescriptionException Thrown when the specified file contains an invalid description */ - public Plugin loadPlugin(File file) throws InvalidPluginException { + public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException { Set filters = fileAssociations.keySet(); Plugin result = null; diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index ba220c3e64..f0d7d13c2a 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -23,6 +23,9 @@ import org.bukkit.event.player.*; import org.bukkit.event.server.PluginEvent; import org.bukkit.event.server.ServerListener; import org.bukkit.event.vehicle.*; +import org.bukkit.event.world.ChunkLoadedEvent; +import org.bukkit.event.world.ChunkUnloadedEvent; +import org.bukkit.event.world.WorldListener; import org.bukkit.plugin.*; /** @@ -38,7 +41,7 @@ public final class JavaPluginLoader implements PluginLoader { server = instance; } - public Plugin loadPlugin(File file) throws InvalidPluginException { + public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException { JavaPlugin result = null; PluginDescriptionFile description = null; @@ -60,8 +63,6 @@ public final class JavaPluginLoader implements PluginLoader { jar.close(); } catch (IOException ex) { throw new InvalidPluginException(ex); - } catch (InvalidDescriptionException ex) { - throw new InvalidPluginException(ex); } try { @@ -124,6 +125,9 @@ public final class JavaPluginLoader implements PluginLoader { case BLOCK_FLOW: trueListener.onBlockFlow((BlockFromToEvent)event); break; + case LEAVES_DECAY: + trueListener.onLeavesDecay((LeavesDecayEvent)event); + break; } } else if(listener instanceof ServerListener) { ServerListener trueListener = (ServerListener)listener; @@ -136,6 +140,17 @@ public final class JavaPluginLoader implements PluginLoader { trueListener.onPluginDisabled((PluginEvent)event); break; } + } else if(listener instanceof WorldListener) { + WorldListener trueListener = (WorldListener)listener; + + switch (event.getType()) { + case CHUNK_LOADED: + trueListener.onChunkLoaded((ChunkLoadedEvent)event); + break; + case CHUNK_UNLOADED: + trueListener.onChunkUnloaded((ChunkUnloadedEvent)event); + break; + } } else if(listener instanceof EntityListener) { EntityListener trueListener = (EntityListener) listener; switch(event.getType())