Begin work for proper API

This commit is contained in:
Eric 2019-08-13 18:11:11 +02:00
parent 2a1375254e
commit 3684f96338
20 changed files with 996 additions and 0 deletions

View File

@ -0,0 +1,29 @@
package de.epiceric.shopchest.api;
import org.bukkit.OfflinePlayer;
/**
* The plugin's main entry point
*
* @since 1.13
*/
public interface ShopChest {
/**
* Gets an instance of the shop manager
*
* @return the shop manager
*/
ShopManager getShopManager();
/**
* Gets the amount of shops the given player is allowed to have
* <p>
* If the player has no shop limit {@link Integer#MAX_VALUE} is returned.
*
* @param player the player
* @return the shop limit
*/
int getShopLimit(OfflinePlayer player);
}

View File

@ -0,0 +1,134 @@
package de.epiceric.shopchest.api;
import java.util.Collection;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import de.epiceric.shopchest.api.event.ShopReloadEvent;
import de.epiceric.shopchest.api.exceptions.ChestNotFoundException;
import de.epiceric.shopchest.api.exceptions.NoSpaceAboveChestException;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.api.shop.ShopProduct;
/**
* Collection of methods to get, add or remove shops
*
* @since 1.13
*/
public interface ShopManager {
/**
* Gets all shops
*
* @return a collection of shops
*/
Collection<Shop> getShops();
/**
* Gets the shop by its ID
*
* @param id the shop's ID
* @return the shop or an empty optional if there is no shop
* @since 1.13
*/
Optional<Shop> getShop(int id);
/**
* Gets the shop at the given location
*
* @param location the shop's chest location
* @return the shop or an empty optional if there is no shop
* @since 1.13
*/
Optional<Shop> getShop(Location location);
/**
* Gets all shops by the given player
*
* @param vendor the player
* @return a collection of shops
* @since 1.13
*/
Collection<Shop> getShops(OfflinePlayer vendor);
/**
* Gets all shops in the given world
*
* @param world the world
* @return a collection of shops
* @since 1.13
*/
Collection<Shop> getShops(World world);
/**
* Creates a shop and adds it to the database
* <p>
* When {@code buyPrice} is zero, a player cannot buy from the shop.
* When {@code sellPrice} is zero, a player cannot sell to the shop.
* You cannot have {@code buyPrice} and {@code sellPrice} be zero.
*
* @param vendor the shop's vendor
* @param product the shop's product
* @param location the shop's chest location.
* Can be either chest if it's on a double chest
* @param buyPrice the price a player can buy the product for.
* @param sellPrice the price a player can sell the product for.
* @throws ChestNotFoundException when there is no chest at the given location
* @throws NoSpaceAboveChestException when there is no empty space above the chest
* @return the shop if created successfully or an empty optional if not
* @since 1.13
* @see ShopManager#addAdminShop(ShopProduct, Location, double, double)
*/
Shop addShop(OfflinePlayer vendor, ShopProduct product, Location location, double buyPrice, double sellPrice)
throws ChestNotFoundException, NoSpaceAboveChestException;
/**
* Creates an admin shop and adds it to the database
* <p>
* When {@code buyPrice} is zero, a player cannot buy from the shop.
* When {@code sellPrice} is zero, a player cannot sell to the shop.
* You cannot have {@code buyPrice} and {@code sellPrice} be zero.
*
* @param product the shop's product
* @param location the shop's chest location.
* Can be either chest if it's on a double chest
* @param buyPrice the price a player can buy the product for.
* @param sellPrice the price a player can sell the product for.
* @throws ChestNotFoundException when there is no chest at the given location
* @throws NoSpaceAboveChestException when there is no empty space above the chest
* @return the created admin shop
* @since 1.13
* @see ShopManager#addShop(OfflinePlayer, ShopProduct, Location, double, double)
*/
Shop addAdminShop(ShopProduct product, Location location, double buyPrice, double sellPrice)
throws ChestNotFoundException, NoSpaceAboveChestException;
/**
* Removes a shop from the database
*
* @param shop the shop to remove
* @since 1.13
*/
void removeShop(Shop shop);
/**
* Removes a shop from the database by its ID
*
* @param shopId the id of the shop to remove
* @since 1.13
*/
void removeShop(int shopId);
/**
* Asynchronously reloads all shops from the database
* <p>
* This does not trigger the {@link ShopReloadEvent}.
*
* @since 1.13
*/
void reloadShops();
}

View File

@ -0,0 +1,59 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player buys or sells something from or to a shop
*/
public class ShopBuySellEvent extends ShopEvent implements Cancellable {
private Type type;
private int amount;
private double price;
private boolean cancelled;
public ShopBuySellEvent(Player player, Shop shop, Type type, int amount, double price) {
super(player, shop);
this.type = type;
this.amount = amount;
this.price = price;
}
/**
* @return Whether the player buys or sells something
*/
public Type getType() {
return type;
}
/**
* @return The amount which might be modified because of automatic item amount calculation
*/
public int getAmount() {
return amount;
}
/**
* @return The price which might be modified because of automatic item amount calculation
*/
public double getPrice() {
return price;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public enum Type {
BUY,
SELL;
}
}

View File

@ -0,0 +1,35 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player creates a shop (clicks on a chest)
*/
public class ShopCreateEvent extends ShopEvent implements Cancellable {
private double creationPrice;
private boolean cancelled;
public ShopCreateEvent(Player player, Shop shop, double creationPrice) {
super(player, shop);
this.creationPrice = creationPrice;
}
/**
* @return The price the player has to pay in order to create the shop (only if the event is not cancelled)
*/
public double getCreationPrice() {
return creationPrice;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,42 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public abstract class ShopEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Shop shop;
private Player player;
public ShopEvent(Player player, Shop shop) {
this.player = player;
this.shop = shop;
}
/**
* @return Shop which is involved in this event
*/
public Shop getShop() {
return shop;
}
/**
* @return Player who is involved in this event
*/
public Player getPlayer() {
return player;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,37 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player extends a shop (making a chest a double chest)
*/
public class ShopExtendEvent extends ShopEvent implements Cancellable {
private boolean cancelled;
private Location newChestLocation;
public ShopExtendEvent(Player player, Shop shop, Location newChest) {
super(player, shop);
this.newChestLocation = newChest;
}
/**
* @return Location of the placed chest
*/
public Location getNewChestLocation() {
return newChestLocation;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,26 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player retrieves information about a shop (clicks on a chest)
*/
public class ShopInfoEvent extends ShopEvent implements Cancellable {
private boolean cancelled;
public ShopInfoEvent(Player player, Shop shop) {
super(player, shop);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,27 @@
package de.epiceric.shopchest.api.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class ShopInitializedEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private int amount;
public ShopInitializedEvent(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,26 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player opens a shop (clicks on a chest)
*/
public class ShopOpenEvent extends ShopEvent implements Cancellable {
private boolean cancelled;
public ShopOpenEvent(Player player, Shop shop) {
super(player, shop);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,84 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.ShopProduct;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player wants to create a shop (enters the command)
*/
public class ShopPreCreateEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private ShopProduct product;
private double buyPrice;
private double sellPrice;
private boolean admin;
private boolean cancelled;
public ShopPreCreateEvent(Player player, ShopProduct product, double buyPrice, double sellPrice, boolean admin) {
this.player = player;
this.product = product;
this.buyPrice = buyPrice;
this.sellPrice = sellPrice;
this.admin = admin;
}
/**
* @return the player
*/
public Player getPlayer() {
return player;
}
/**
* @return the product
*/
public ShopProduct getProduct() {
return product;
}
/**
* @return the buyPrice
*/
public double getBuyPrice() {
return buyPrice;
}
/**
* @return the sellPrice
*/
public double getSellPrice() {
return sellPrice;
}
/**
* @return the admin
*/
public boolean isAdminShop() {
return admin;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,46 @@
package de.epiceric.shopchest.api.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player wants to retrieve information about a shop (enters the command)
*/
public class ShopPreInfoEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private boolean cancelled;
public ShopPreInfoEvent(Player player) {
this.player = player;
}
/**
* @return Player who is involved in this event
*/
public Player getPlayer() {
return player;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,46 @@
package de.epiceric.shopchest.api.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player wants to open a shop (enters the command)
*/
public class ShopPreOpenEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private boolean cancelled;
public ShopPreOpenEvent(Player player) {
this.player = player;
}
/**
* @return Player who is involved in this event
*/
public Player getPlayer() {
return player;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,46 @@
package de.epiceric.shopchest.api.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player wants to remove a shop (enters the command)
*/
public class ShopPreRemoveEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Player player;
private boolean cancelled;
public ShopPreRemoveEvent(Player player) {
this.player = player;
}
/**
* @return Player who is involved in this event
*/
public Player getPlayer() {
return player;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,46 @@
package de.epiceric.shopchest.api.event;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player reloads the shops
*/
public class ShopReloadEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private CommandSender sender;
private boolean cancelled;
public ShopReloadEvent(CommandSender sender) {
this.sender = sender;
}
/**
* @return Sender who triggered the reload
*/
public CommandSender getSender() {
return sender;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,56 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.shop.Shop;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.List;
public class ShopRemoveAllEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private CommandSender sender;
private OfflinePlayer vendor;
private List<Shop> shops;
private boolean cancelled;
public ShopRemoveAllEvent(CommandSender sender, OfflinePlayer vendor, List<Shop> shops) {
this.sender = sender;
this.vendor = vendor;
this.shops = shops;
}
public CommandSender getSender() {
return sender;
}
public OfflinePlayer getVendor() {
return vendor;
}
public List<Shop> getShops() {
return shops;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
@Override
public boolean isCancelled() {
return cancelled;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -0,0 +1,26 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player removes a shop (clicks on a chest)
*/
public class ShopRemoveEvent extends ShopEvent implements Cancellable {
private boolean cancelled;
public ShopRemoveEvent(Player player, Shop shop) {
super(player, shop);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,12 @@
package de.epiceric.shopchest.api.exceptions;
import org.bukkit.Location;
public class ChestNotFoundException extends Exception {
private static final long serialVersionUID = -6446875473671870708L;
public ChestNotFoundException(Location location) {
super(String.format("No chest found in world '%s' at x=%d y=%d z=%d", location.getWorld().getName(),
location.getBlockX(), location.getBlockY(), location.getBlockZ()));
}
}

View File

@ -0,0 +1,12 @@
package de.epiceric.shopchest.api.exceptions;
import org.bukkit.Location;
public class NoSpaceAboveChestException extends Exception {
private static final long serialVersionUID = 3718475607700458355L;
public NoSpaceAboveChestException(Location location) {
super(String.format("No space above chest in world '%s' at x=%d y=%d z=%d", location.getWorld().getName(),
location.getBlockX(), location.getBlockY(), location.getBlockZ()));
}
}

View File

@ -0,0 +1,153 @@
package de.epiceric.shopchest.api.shop;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.inventory.Inventory;
import de.epiceric.shopchest.api.ShopManager;
/**
* Represents a shop
*
* @since 1.13
* @see ShopManager#addShop(OfflinePlayer, ShopProduct, Location, double, double)
* @see ShopManager#addAdminShop(ShopProduct, Location, double, double)
*/
public interface Shop {
/**
* Gets this shop's ID
*
* @return the ID
* @since 1.13
*/
int getId();
/**
* Gets the player who created this shop
*
* @return the vendor
* @since 1.13
*/
OfflinePlayer getVendor();
/**
* Gets the product this shop is buying or selling
*
* @return the product
* @since 1.13
*/
ShopProduct getProduct();
/**
* Gets the location of this shop's chest
* <p>
* If the shop is on a double chest, it returns one of the chest's location.
*
* @return the location
* @since 1.13
*/
Location getLocation();
/**
* Gets the world this shop is located in
*
* @return the world
* @since 1.13
*/
default World getWorld() {
return getLocation().getWorld();
}
/**
* Gets whether this shop is on a double chest
*
* @return whether the shop is on a double chest
* @since 1.13
*/
boolean isDoubleChest();
/**
* Gets the inventory of this shop's chest
*
* @return the inventory
* @since 1.13
*/
Inventory getInventory();
/**
* Gets whether this shop is an admin shop
*
* @return whether this shop is an admin shop
* @since 1.13
*/
boolean isAdminShop();
/**
* Sets whether this shop is an admin shop
*
* @param adminShop whether this shop should be an admin shop
* @since 1.13
*/
void setAdminShop(boolean adminShop);
/**
* Gets the price for which a player can buy the product from this shop
*
* @return the buy price
* @since 1.13
*/
double getBuyPrice();
/**
* Sets the price for which a player can sell the product to this shop
* <p>
* If set to zero, a player cannot buy from this shop.
*
* @param buyPrice the buy price
* @throws IllegalStateException when a player can neither buy nor sell from this shop
* @since 1.13
*/
void setBuyPrice(double buyPrice);
/**
* Gets whether a player can buy from this shop
*
* @return whether buying is enabled
* @since 1.13
*/
default boolean canPlayerBuy() {
return getBuyPrice() > 0;
}
/**
* Gets the price for which a player can sell the product to this shop
*
* @return the sell price
* @since 1.13
*/
double getSellPrice();
/**
* Sets the price for which a player can sell the product to this shop
* <p>
* If set to zero, a player cannot sell to this shop.
*
* @param sellPrice the sell price
* @throws IllegalStateException when a player can neither buy nor sell from this shop
* @since 1.13
*/
void setSellPrice(double sellPrice);
/**
* Gets whether a player can sell to this shop
*
* @return whether selling is enabled
* @since 1.13
*/
default boolean canPlayerSell() {
return getSellPrice() > 0;
}
}

View File

@ -0,0 +1,54 @@
package de.epiceric.shopchest.api.shop;
import org.bukkit.inventory.ItemStack;
/**
* Represents the item that can be bought or sold in one transaction
*
* @since 1.13
*/
public interface ShopProduct {
/**
* Gets the {@link ItemStack} with an amount of one
*
* @return the item
* @since 1.13
*/
ItemStack getItemStack();
/**
* Sets the {@link ItemStack}
* <p>
* The passed item stack will be cloned and its amount set to one.
*
* @param itemStack the item
* @since 1.13
*/
void setItemStack(ItemStack itemStack);
/**
* Gets the amount of items bought or sold in one transaction
*
* @return the amount
* @since 1.13
*/
int getAmount();
/**
* Sets the amount of items bought or sold in one transaction
*
* @param amount the amount
* @since 1.13
*/
void setAmount(int amount);
/**
* Gets the localized name of this product's item in the configured langauge file
*
* @return the localized name
* @since 1.13
*/
String getLocalizedName();
}