Remove API module

This commit is contained in:
Len
2022-08-07 17:28:38 +02:00
parent aeb6d79495
commit 5ccd5b6f0c
34 changed files with 88 additions and 263 deletions
@@ -0,0 +1,81 @@
package com.alttd.playershops;
import com.alttd.playershops.config.Config;
import com.alttd.playershops.config.MessageConfig;
import com.alttd.playershops.handler.ShopHandler;
import com.alttd.playershops.listener.PlayerListener;
import com.alttd.playershops.listener.ShopListener;
import lombok.Getter;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
public class PlayerShops extends JavaPlugin {
@Getter
private static PlayerShops instance;
@Getter
private Economy econ = null;
@Getter
private ShopHandler shopHandler;
private ShopListener shopListener;
private PlayerListener playerListener;
public void onEnable() {
instance = this;
if(!setupEconomy()) {
Bukkit.getLogger().warning("Error loading Vault and economy.\n Disabling plugin");
this.setEnabled(false);
return;
}
Bukkit.getLogger().info("Hooked into Vault economy provided by " + econ.getName());
reloadConfigs();
registerListeners();
registerCommands();
shopHandler = new ShopHandler(instance);
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return true;
}
public Economy getEconomy() {
if(econ == null)
setupEconomy();
return econ;
}
private void registerListeners() {
shopListener = new ShopListener(this);
playerListener = new PlayerListener(this);
}
private void UnregisterListeners() {
shopListener.unregister();
playerListener.unregister();
}
private void registerCommands() {
// for(String command : this.getDescription().getCommands().keySet()) {
// getCommand(command).setExecutor();
// }
}
public void reloadConfigs() {
Config.reload();
MessageConfig.reload();
}
}
@@ -0,0 +1,51 @@
package com.alttd.playershops.config;
import com.alttd.galaxy.configuration.AbstractConfiguration;
import com.alttd.playershops.shop.ShopType;
import java.io.File;
import java.util.HashMap;
@SuppressWarnings("unused")
public class Config extends AbstractConfiguration {
public static File configPath = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "com/alttd/playershops");
private Config() {
super(Config.configPath, "config");
}
static Config config;
static int version;
static HashMap<ShopType, ShopTypeConfig> shopTypeConfigs;
public static void reload() {
config = new Config();
version = config.getInt("config-version", 1);
config.set("config-version", 1);
config.readConfig(Config.class, null);
shopTypeConfigs = new HashMap<>();
for (ShopType shopType : ShopType.values()) {
shopTypeConfigs.put(shopType, new ShopTypeConfig(shopType.toString()));
}
}
public static int shopLimit = 100;
public static boolean usePermissionShopLimit = false;
public static String shopCreationWord = "[SHOP]";
private static void shopSettings() {
String path = "shop-settings.";
shopLimit = config.getInt(path + "player-shop-limit", shopLimit);
usePermissionShopLimit = config.getBoolean(path + "use-permission-based-shop-limit", usePermissionShopLimit);
shopCreationWord = config.getString(path + "creation-word", shopCreationWord);
}
public static String shopLimitPermission = "shop.buildlimit";
private static void permissionSettings() {
String path = "permission.";
shopLimitPermission = config.getString(path + "build-limit", shopLimitPermission);
}
}
@@ -0,0 +1,47 @@
package com.alttd.playershops.config;
import com.alttd.galaxy.configuration.AbstractConfiguration;
import com.alttd.playershops.shop.ShopType;
import java.util.HashMap;
public class DatabaseConfig extends AbstractConfiguration {
private DatabaseConfig() {
super(Config.configPath, "database");
}
static DatabaseConfig config;
static int version;
static HashMap<ShopType, ShopTypeConfig> shopTypeConfigs;
public static void reload() {
config = new DatabaseConfig();
version = config.getInt("config-version", 1);
config.set("config-version", 1);
config.readConfig(DatabaseConfig.class, null);
shopTypeConfigs = new HashMap<>();
for (ShopType shopType : ShopType.values()) {
shopTypeConfigs.put(shopType, new ShopTypeConfig(shopType.toString()));
}
}
public static String DRIVER = "mysql";
public static String IP = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "AltitudeQuests";
public static String USERNAME = "root";
public static String PASSWORD = "root";
private static void loadDatabase() {
DRIVER = config.getString("database.driver", DRIVER);
IP = config.getString("database.ip", IP);
PORT = config.getString("database.port", PORT);
DATABASE_NAME = config.getString("database.name", DATABASE_NAME);
USERNAME = config.getString("database.username", USERNAME);
PASSWORD = config.getString("database.password", PASSWORD);
}
}
@@ -0,0 +1,41 @@
package com.alttd.playershops.config;
import com.alttd.galaxy.configuration.AbstractConfiguration;
import com.alttd.playershops.shop.ShopType;
import java.util.HashMap;
public class MessageConfig extends AbstractConfiguration {
public MessageConfig() {
super(Config.configPath, "messageconfig");
}
static MessageConfig config;
static int version;
static HashMap<ShopType, ShopTypeConfig> shopTypeConfigs;
public static void reload() {
config = new MessageConfig();
version = config.getInt("config-version", 1);
config.set("config-version", 1);
config.readConfig(Config.class, null);
shopTypeConfigs = new HashMap<>();
for (ShopType shopType : ShopType.values()) {
shopTypeConfigs.put(shopType, new ShopTypeConfig(shopType.toString()));
}
}
public static String SHOP_ALREADY_EXISTS = "<red>This block is already a Shop</red>";
public static String NO_SHOP_CREATE_PERMISSION = "<red>You don't have permission to create shops.</red>";
public static String SHOP_LIMIT_REACHED = "<red>You cannot create this shop as you already have reached the limit (<limit>).</red>";
void loadErrorMessages() {
SHOP_ALREADY_EXISTS = getString("errors.shop-already-exists", SHOP_ALREADY_EXISTS);
NO_SHOP_CREATE_PERMISSION = getString("errors.no-shop-create-permission", NO_SHOP_CREATE_PERMISSION);
SHOP_LIMIT_REACHED = getString("errors.shop-limit-reached", SHOP_LIMIT_REACHED);
}
}
@@ -0,0 +1,30 @@
package com.alttd.playershops.config;
public class ShopTypeConfig {
private final String shopType;
private final String configPath;
private final String defaultPath;
public ShopTypeConfig(String shopType) {
this.shopType = shopType;
this.configPath = "shop.type." + this.shopType + ".";
this.defaultPath = "shop.type.default.";
init();
}
public void init() {
Config.config.readConfig(ShopTypeConfig.class, this);
}
private static void set(String path, Object def) {
Config.config.set(path, def);
}
private String getString(String path, String def) {
set(defaultPath + path, def);
return Config.config.getNode(configPath + path).getString(
Config.config.getNode(defaultPath + path).getString(def));
}
}
@@ -0,0 +1,118 @@
package com.alttd.playershops.database;
import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.config.DatabaseConfig;
import com.alttd.playershops.utils.Logger;
import org.bukkit.Bukkit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Database {
private static Database instance = null;
private Connection connection = null;
private Database() {}
public static Database getDatabase(){
if (instance == null)
{
instance = new Database();
instance.init();
}
return (instance);
}
protected void init() {
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
}
//Run all create table functions
for (Method method : Database.class.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
try {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
Logger.severe("Error invoking " + method + ".");
ex.printStackTrace();
}
}
}
}
}
/**
* Opens the connection if it's not already open.
* @throws SQLException If it can't create the connection.
*/
private void openConnection() throws SQLException {
if (connection != null && !connection.isClosed()) {
return;
}
synchronized (this) {
if (connection != null && !connection.isClosed()) {
return;
}
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
connection = DriverManager.getConnection(
"jdbc:mysql://" + DatabaseConfig.IP + ":" + DatabaseConfig.PORT + "/" + DatabaseConfig.DATABASE_NAME +
"?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true",
DatabaseConfig.USERNAME, DatabaseConfig.PASSWORD);
}
}
public Connection getConnection() {
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
private static void createShopTable() {
try {
String sql = "CREATE TABLE IF NOT EXISTS shops(" +
"id INT NOT NULL AUTO_INCREMENT, " +
"owner_name VARCHAR(16) NOT NULL, " +
"owner_uuid VARCHAR(36) NOT NULL, " +
"shop_type VARCHAR(36) NOT NULL, " +
"server VARCHAR(16) NOT NULL, " +
"container_location VARCHAR(256), " +
"sign_location VARCHAR(256), " +
"price DOUBLE NOT NULL, " +
"amount INT NOT NULL, " +
"balance DOUBLE NOT NULL, " +
"item_one TEXT, " +
"item_two TEXT, " +
"last_transaction BIGINT, " +
"PRIMARY KEY (id)" +
")";
getDatabase().getConnection().prepareStatement(sql).executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
Logger.severe("Error while trying to create shop table");
Logger.severe("Shutting down PlayerShops");
Bukkit.getPluginManager().disablePlugin(PlayerShops.getInstance());
}
}
}
@@ -0,0 +1,151 @@
package com.alttd.playershops.database;
import com.alttd.playershops.shop.AbstractShop;
import com.alttd.playershops.shop.ShopType;
import com.alttd.playershops.utils.AMath;
import com.alttd.playershops.utils.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ShopQueries {
public static boolean saveShop(AbstractShop shop) {
String sql = "INSERT INTO shops " +
"(id, owner_name, owner_uuid, shop_type, server, container_location, sign_location, " +
"price, amount, balance, item_one, item_two, last_transaction)" +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
"ON DUPLICATE KEY UPDATE owner_name = ?, owner_uuid = ?, shop_type = ?, server = ?, " +
"container_location = ?, sign_location = ?, price = ?, amount = ?, balance = ?, " +
"item_one = ?, item_two = ?, last_transaction = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
statement.setInt(1, shop.getId());
statement.setString(2, shop.getOwnerName());
statement.setString(3, shop.getOwnerUUID().toString());
statement.setString(4, shop.getServer());
statement.setString(5, shop.getType().toString());
statement.setString(6, locationToString(shop.getContainerLocation()));
statement.setString(7, locationToString(shop.getSignLocation()));
statement.setDouble(8, shop.getPrice());
statement.setInt(9, shop.getAmount());
statement.setDouble(10, shop.getBalance());
statement.setBytes(11, shop.getItemStack().serializeAsBytes());
statement.setBytes(12, shop.getSecondaryItem().serializeAsBytes());
statement.setLong(13, shop.getLastTransaction());
//repeat everything except id for update
statement.setString(14, shop.getOwnerName());
statement.setString(15, shop.getOwnerUUID().toString());
statement.setString(16, shop.getServer());
statement.setString(17, shop.getType().toString());
statement.setString(18, locationToString(shop.getContainerLocation()));
statement.setString(19, locationToString(shop.getSignLocation()));
statement.setDouble(20, shop.getPrice());
statement.setInt(21, shop.getAmount());
statement.setDouble(22, shop.getBalance());
statement.setBytes(23, shop.getItemStack().serializeAsBytes());
statement.setBytes(24, shop.getSecondaryItem().serializeAsBytes());
statement.setLong(25, shop.getLastTransaction());
return statement.executeUpdate() == 1;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public static AbstractShop loadShop(int id) {
String sql = "SELECT * FROM shops WHERE id = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
statement.setInt(1, id);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next())
return shopFromResultSet(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static List<AbstractShop> loadShops() {
String sql = "SELECT * FROM shops";
ArrayList<AbstractShop> shops = new ArrayList<>();
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
AbstractShop shop = shopFromResultSet(resultSet);
if (shop == null) {
Logger.warn("Tried to load a shop but failed [" + resultSet + "]");
continue;
}
shops.add(shop);
}
} catch (SQLException e) {
e.printStackTrace();
}
return shops;
}
/**
* Loads a shop from a result set, does not iterate
* @param resultSet Result set to load from
* @return A shop
* @throws SQLException if data is missing or formatted incorrectly
*/
private static AbstractShop shopFromResultSet(ResultSet resultSet) throws SQLException {
int id = resultSet.getInt("id");
String ownerName = resultSet.getString("owner_name");
UUID ownerUuid = UUID.fromString(resultSet.getString("owner_uuid"));
ShopType shopType = ShopType.valueOf(resultSet.getString("shop_type"));
String server = resultSet.getString("server");
Location containerLocation = stringToLocation(resultSet.getString("container_location"));
Location signLocation = stringToLocation(resultSet.getString("sign_location"));
double price = resultSet.getDouble("price");
int amount = resultSet.getInt("amount");
double balance = resultSet.getDouble("balance");
ItemStack itemOne = ItemStack.deserializeBytes(resultSet.getBytes("item_one"));
ItemStack itemTwo = ItemStack.deserializeBytes(resultSet.getBytes("item_two"));
long lastTransaction = resultSet.getLong("last_transaction");
if (containerLocation == null || signLocation == null)
return null;
return AbstractShop.create(id, ownerName, ownerUuid, shopType, server, containerLocation, signLocation,
price, amount, balance, itemOne, itemTwo, lastTransaction);
}
private static String locationToString(Location location) {
return location.getWorld() + ":" +
AMath.round(location.getX(), 1) + ":" +
AMath.round(location.getY(), 1) + ":" +
AMath.round(location.getZ(), 1);
}
private static Location stringToLocation(String string) {
String[] split = string.split(":");
if (split.length != 4) {
Logger.warn("Unable to load location [" + string + "] due to invalid format");
return null;
}
try {
return new Location(Bukkit.getWorld(split[0]),
Double.parseDouble(split[1]), Double.parseDouble(split[2]), Double.parseDouble(split[3]));
} catch (NumberFormatException e) {
Logger.warn("Unable to load location [" + string + "] due to invalid format");
return null;
}
}
}
@@ -0,0 +1,31 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCreateShopEvent extends ShopEvent {
private static final HandlerList handlers = new HandlerList();
private final Player player;
public PlayerCreateShopEvent(Player player, AbstractShop shop) {
super(shop);
this.player = player;
}
public Player getPlayer() {
return player;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -0,0 +1,32 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerDestroyShopEvent extends ShopEvent {
private static final HandlerList handlers = new HandlerList();
private final Player player;
public PlayerDestroyShopEvent(Player player, AbstractShop shop) {
super(shop);
this.player = player;
}
public Player getPlayer() {
return player;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -0,0 +1,32 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerExchangeShopEvent extends ShopEvent {
private static final HandlerList handlers = new HandlerList();
private final Player player;
public PlayerExchangeShopEvent(Player player, AbstractShop shop) {
super(shop);
this.player = player;
}
public Player getPlayer() {
return player;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -0,0 +1,32 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerInitializeShopEvent extends ShopEvent {
private static final HandlerList handlers = new HandlerList();
private final Player player;
public PlayerInitializeShopEvent(Player player, AbstractShop shop) {
super(shop);
this.player = player;
}
public Player getPlayer() {
return player;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}
@@ -0,0 +1,41 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class ShopBalanceChangeEvent extends ShopEvent {
private static final HandlerList handlers = new HandlerList();
private final ChangeReason changeReason;
public ShopBalanceChangeEvent(AbstractShop shop, ChangeReason reason) {
super(shop);
this.changeReason = reason;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
public ChangeReason getChangeReason() {
return changeReason;
}
public enum ChangeReason {
DEPOSIT,
WIDRAW,
SELL,
BUY,
UPKEEP
}
}
@@ -0,0 +1,30 @@
package com.alttd.playershops.events;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public abstract class ShopEvent extends Event implements Cancellable {
private boolean cancelled;
private final AbstractShop shop;
public ShopEvent(AbstractShop shop) {
this.shop = shop;
}
public AbstractShop getShop() {
return shop;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean b) {
this.cancelled = true;
}
}
@@ -0,0 +1,112 @@
package com.alttd.playershops.handler;
import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.config.Config;
import com.alttd.playershops.events.PlayerCreateShopEvent;
import com.alttd.playershops.shop.AbstractShop;
import com.alttd.playershops.shop.ShopType;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class ShopHandler {
private final PlayerShops plugin;
@Getter
private final Object2IntMap<UUID> shopBuildLimits;
@Getter
private final Map<Location, AbstractShop> shopLocation;
@Getter
private final ArrayList<Material> shopMaterials;
public ShopHandler(PlayerShops instance) {
plugin = instance;
shopLocation = new ConcurrentHashMap<>();
shopBuildLimits = new Object2IntOpenHashMap<>();
shopBuildLimits.defaultReturnValue(Config.shopLimit);
shopMaterials = new ArrayList<>(); // TODO move into parent method where materials are loaded in.
}
public AbstractShop getShop(Location location) {
Location newLocation = new Location(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
return shopLocation.get(newLocation);
}
public boolean isShop(Location location) {
return getShop(location) != null;
}
public Collection<AbstractShop> getShops() {
return Collections.unmodifiableCollection(shopLocation.values());
}
public void addPlayerLimit(UUID uuid, int limit) {
shopBuildLimits.put(uuid, limit);
}
public int getShopLimit(UUID uuid) {
return shopBuildLimits.getInt(uuid);
}
public void removeShops() {
shopLocation.clear();
}
public boolean isShopMaterial(Block block) {
if (Tag.SHULKER_BOXES.isTagged(block.getType())) {
return true;
}
return shopMaterials.contains(block.getType());
}
public List<AbstractShop> getShops(UUID uuid) {
List<AbstractShop> shops = new ArrayList<>();
for (AbstractShop shop : shopLocation.values()) {
if (shop.getOwnerUUID().equals(uuid))
shops.add(shop);
}
return shops;
}
public AbstractShop getShopBySignLocation(Location signLocation) {
for (AbstractShop shop : shopLocation.values()) {
if (shop.getSignLocation().equals(signLocation))
return shop;
}
return null;
}
public AbstractShop getShopNearBlock(Block block) {
BlockFace[] faces = {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
for (BlockFace face : faces) {
if (this.isShopMaterial(block.getRelative(face))) {
Block blockRelative = block.getRelative(face);
if (isShop(blockRelative.getLocation()))
return getShop(blockRelative.getLocation());
}
}
return null;
}
public AbstractShop createShop(Location signLocation, Player player, double price, int amount, ShopType shopType) {
AbstractShop shop = AbstractShop.create(signLocation, player.getUniqueId(), price, amount, shopType);
PlayerCreateShopEvent playerCreateShopEvent = new PlayerCreateShopEvent(player, shop);
plugin.getServer().getPluginManager().callEvent(playerCreateShopEvent);
if(playerCreateShopEvent.isCancelled())
return null;
return shop;
}
}
@@ -0,0 +1,21 @@
package com.alttd.playershops.listener;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
public class EventListener implements Listener {
protected boolean isRegistered = false;
public void register(JavaPlugin instance) {
Bukkit.getServer().getPluginManager().registerEvents(this, instance);
isRegistered = true;
}
public void unregister() {
HandlerList.unregisterAll(this);
isRegistered = false;
}
}
@@ -0,0 +1,39 @@
package com.alttd.playershops.listener;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
public class InventoryListener extends EventListener {
protected final Inventory inventory;
protected boolean cancelCloseUnregister = false;
public InventoryListener(Inventory inv) {
this.inventory = inv;
}
@EventHandler(ignoreCancelled = true)
public void unregisterOnClose(InventoryCloseEvent event) {
if (event.getView().getTopInventory().equals(inventory) && !cancelCloseUnregister) unregister();
}
@EventHandler(ignoreCancelled = true)
public void unregisterOnLeaveEvent(PlayerQuitEvent event) {
if ((inventory.getHolder() instanceof OfflinePlayer) && event.getPlayer().getUniqueId().equals(((OfflinePlayer) inventory.getHolder()).getUniqueId()))
unregister();
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onInventoryDrag(InventoryDragEvent event) {
if (event.getView().getTopInventory().equals(inventory)) for (int slot : event.getRawSlots()) if (slot < inventory.getSize()) {
event.setCancelled(true);
return;
}
}
}
@@ -0,0 +1,133 @@
package com.alttd.playershops.listener;
import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.config.Config;
import com.alttd.playershops.config.MessageConfig;
import com.alttd.playershops.handler.ShopHandler;
import com.alttd.playershops.shop.AbstractShop;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.Rotatable;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
import java.util.UUID;
public class PlayerListener extends EventListener {
private final PlayerShops plugin;
public PlayerListener(PlayerShops plugin) {
this.plugin = plugin;
this.register(this.plugin);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
if(!this.isRegistered || !Config.usePermissionShopLimit) return;
Player player = event.getPlayer();
if (!player.hasPermission(Config.shopLimitPermission)) return;
ShopHandler shopHandler = plugin.getShopHandler();
UUID uuid = player.getUniqueId();
// early return to not check this all the time, if this changes by rankup etc handle it in another event
if (shopHandler.getShopLimit(uuid) != Config.shopLimit) return;
int buildPermissionNumber = -1;
for (PermissionAttachmentInfo permInfo : player.getEffectivePermissions()) {
if (permInfo.getPermission().startsWith("shop.buildlimit.")) {
try {
int tempNum = Integer.parseInt(permInfo.getPermission().substring(permInfo.getPermission().lastIndexOf(".") + 1));
if (tempNum > buildPermissionNumber) {
buildPermissionNumber = tempNum;
}
} catch (Exception ignore) {}
}
}
if (buildPermissionNumber == -1)
shopHandler.addPlayerLimit(player.getUniqueId(), buildPermissionNumber);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onSignChange(SignChangeEvent event) {
Block block = event.getBlock();
if (!(block.getState() instanceof Sign)) return;
AbstractShop shop = plugin.getShopHandler().getShop(block.getLocation());
if(shop == null) return;
if(shop.isInitialized()) event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onShopCreation(SignChangeEvent event) {
Block b = event.getBlock();
if (!(b.getState() instanceof Sign))
return;
BlockFace facing;
BlockData data = b.getState().getBlockData();
if (data instanceof WallSign) {
facing = ((Directional) data).getFacing();
} else {
facing = ((Rotatable) data).getRotation();
}
Block bRelative = b.getRelative(facing.getOppositeFace());
ShopHandler shopHandler = plugin.getShopHandler();
if (shopHandler.isShopMaterial(bRelative)) {
Sign signBlock = (Sign) b.getState();
Component signLine = event.line(0);
if (signLine == null)
return;
String signLineString = PlainTextComponentSerializer.plainText().serialize(signLine);
if (!signLineString.equalsIgnoreCase(Config.shopCreationWord))
return;
AbstractShop shop = shopHandler.getShop(bRelative.getLocation());
Player player = event.getPlayer();
if(shop != null) {
event.setCancelled(true);
player.sendMiniMessage(MessageConfig.SHOP_ALREADY_EXISTS, null);
return;
}
UUID playerUUID = player.getUniqueId();
if (!player.hasPermission("shop.create")) {
event.setCancelled(true);
player.sendMiniMessage(MessageConfig.NO_SHOP_CREATE_PERMISSION, null);
return;
}
int numberOfShops = shopHandler.getShops(playerUUID).size();
int shopLimit = shopHandler.getShopLimit(playerUUID);
if (numberOfShops >= shopLimit) {
event.setCancelled(true);
player.sendMiniMessage(MessageConfig.SHOP_LIMIT_REACHED, Placeholder.parsed("limit", String.valueOf(shopLimit)));
return;
}
// TODO instance shopCreationManagement
}
}
}
@@ -0,0 +1,44 @@
package com.alttd.playershops.listener;
import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.shop.AbstractShop;
import org.bukkit.Location;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityExplodeEvent;
import java.util.Iterator;
public class ShopListener extends EventListener {
private final PlayerShops plugin;
public ShopListener(PlayerShops plugin) {
this.plugin = plugin;
this.register(this.plugin);
}
@EventHandler(ignoreCancelled = true)
public void onEntityExplosion(EntityExplodeEvent event) {
if(!this.isRegistered) return;
// This might be heavy when tnt is chained, would it be better to expand the unbreakable block api in galaxy and use that?
// No need for slow bukkit events eating up cpu and memory
Iterator<Block> blockIterator = event.blockList().iterator();
AbstractShop shop = null;
while (blockIterator.hasNext()) {
Block block = blockIterator.next();
Location location = block.getLocation();
if (Tag.WALL_SIGNS.isTagged(block.getType())) {
shop = plugin.getShopHandler().getShopBySignLocation(location);
} else if (plugin.getShopHandler().isShopMaterial(block)) {
shop = plugin.getShopHandler().getShop(location);
}
if (shop != null) {
blockIterator.remove();
}
}
}
}
@@ -0,0 +1,105 @@
package com.alttd.playershops.shop;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.data.Directional;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public abstract class AbstractShop {
@Getter
private int id;
private String ownerName;
@Getter
private UUID ownerUUID;
@Getter @Setter
private ShopType type;
@Getter
private Location signLocation;
@Getter
private Location containerLocation;
@Getter
private String server;
@Getter @Setter
private double price;
@Getter @Setter
private int amount;
@Getter @Setter
private double balance;
@Getter @Setter
private ItemStack itemStack;
@Getter @Setter
private ItemStack secondaryItem;
@Getter @Setter
private long lastTransaction;
protected boolean initialized;
AbstractShop(Location signLocation, UUID uuid, double price, int amount) {
this.signLocation = signLocation;
if (signLocation != null) {
Directional sign = (Directional) signLocation.getBlock().getState().getBlockData();
this.containerLocation = signLocation.getBlock().getRelative(sign.getFacing().getOppositeFace()).getLocation();
}
this.ownerUUID = uuid;
ownerName = getOwnerName();
this.price = price;
this.amount = amount;
this.server = Bukkit.getServerName();
}
AbstractShop(int id, String ownerName, UUID ownerUUID, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
this.id = id;
this.ownerName = ownerName;
this.ownerUUID = ownerUUID;
this.server = server;
this.containerLocation = containerLocation;
this.signLocation = signLocation;
this.price = price;
this.amount = amount;
this.balance = balance;
this.itemStack = itemOne;
this.secondaryItem = itemTwo;
this.lastTransaction = lastTransaction;
}
public static AbstractShop create(Location signLocation, UUID player, double price, int amount, ShopType shopType) {
return switch (shopType) {
case SELL -> new SellShop(signLocation, player, price, amount);
case BUY -> new BuyShop(signLocation, player, price, amount);
case GAMBLE -> new GambleShop(signLocation, player, price, amount);
case BARTER -> new BarterShop(signLocation, player, price, amount);
};
}
public static AbstractShop create(int id, String ownerName, UUID ownerUUID, ShopType shopType, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
return switch (shopType) {
case SELL -> new SellShop(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount, balance, itemOne, itemTwo, lastTransaction);
case BUY -> new BuyShop(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount, balance, itemOne, itemTwo, lastTransaction);
case GAMBLE -> new GambleShop(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount, balance, itemOne, itemTwo, lastTransaction);
case BARTER -> new BarterShop(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount, balance, itemOne, itemTwo, lastTransaction);
};
}
public String getOwnerName() {
if(this.ownerName != null) return ownerName;
if (this.getOwnerUUID() != null) {
ownerName = Bukkit.getOfflinePlayer(this.getOwnerUUID()).getName();
return ownerName;
}
return ChatColor.RED + "[CLOSED]";
}
public boolean isInitialized() {
return initialized;
}
}
@@ -0,0 +1,24 @@
package com.alttd.playershops.shop;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public class BarterShop extends AbstractShop {
public BarterShop(Location location, UUID player, double price, int amount) {
super(location, player, price, amount);
this.setType(ShopType.BARTER);
}
public BarterShop(int id, String ownerName, UUID ownerUUID, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
super(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount,
balance, itemOne, itemTwo, lastTransaction);
this.setType(ShopType.BARTER);
}
}
@@ -0,0 +1,23 @@
package com.alttd.playershops.shop;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public class BuyShop extends AbstractShop {
public BuyShop(Location location, UUID player, double price, int amount) {
super(location, player, price, amount);
this.setType(ShopType.BUY);
}
public BuyShop(int id, String ownerName, UUID ownerUUID, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
super(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount,
balance, itemOne, itemTwo, lastTransaction);
this.setType(ShopType.BUY);
}
}
@@ -0,0 +1,27 @@
package com.alttd.playershops.shop;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public class GambleShop extends AbstractShop {
private ItemStack gambleItem;
public GambleShop(Location location, UUID player, double price, int amount) {
super(location, player, price, amount);
this.setType(ShopType.GAMBLE);
this.gambleItem = this.getItemStack();
}
public GambleShop(int id, String ownerName, UUID ownerUUID, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
super(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount,
balance, itemOne, itemTwo, lastTransaction);
this.setType(ShopType.GAMBLE);
}
}
@@ -0,0 +1,24 @@
package com.alttd.playershops.shop;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public class SellShop extends AbstractShop {
public SellShop(Location location, UUID player, double price, int amount) {
super(location, player, price, amount);
this.setType(ShopType.SELL);
}
public SellShop(int id, String ownerName, UUID ownerUUID, String server,
Location containerLocation, Location signLocation, double price, int amount,
double balance, ItemStack itemOne, ItemStack itemTwo, long lastTransaction) {
super(id, ownerName, ownerUUID, server, containerLocation, signLocation, price, amount,
balance, itemOne, itemTwo, lastTransaction);
this.setType(ShopType.SELL);
}
}
@@ -0,0 +1,13 @@
package com.alttd.playershops.shop;
public class ShopTransaction {
public enum ShopTransactionError {
CANCELLED,
INSUFFICIENT_FUNDS_SHOP,
INSUFFICIENT_FUNDS_PLAYER,
INVENTORY_FULL_SHOP,
INVENTORY_FULL_PLAYER,
NONE;
}
}
@@ -0,0 +1,10 @@
package com.alttd.playershops.shop;
public enum ShopTransactionError {
CANCELLED,
INSUFFICIENT_FUNDS_SHOP,
INSUFFICIENT_FUNDS_PLAYER,
INVENTORY_FULL_SHOP,
INVENTORY_FULL_PLAYER,
NONE;
}
@@ -0,0 +1,13 @@
package com.alttd.playershops.shop;
public enum ShopType {
SELL,
BUY,
GAMBLE,
BARTER;
@Override
public String toString() {
return name().toLowerCase();
}
}
@@ -0,0 +1,8 @@
package com.alttd.playershops.utils;
public class AMath {
public static double round (double value, int precision) {
int scale = (int) Math.pow(10, precision);
return (double) Math.round(value * scale) / scale;
}
}
@@ -0,0 +1,29 @@
package com.alttd.playershops.utils;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import java.util.logging.Level;
public class Logger
{
public static void info(String str) {
log(Level.INFO,"&e" + str);
}
public static void warn(String str) {
log(Level.SEVERE,"&6" + str);
}
public static void severe(String str) {
log(Level.SEVERE,"&c" + str);
}
public static void log(Level level, String str) {
Bukkit.getLogger().log(level,
ChatColor.translateAlternateColorCodes('&',
"&r " + str));
}
}