Refactor/rework
This commit is contained in:
parent
658837814a
commit
3aa8414c5b
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -47,5 +47,6 @@ out/
|
|||
*~
|
||||
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
/run/
|
||||
/run1/
|
||||
/lib/
|
||||
/run/
|
||||
|
|
|
|||
|
|
@ -82,10 +82,23 @@ bukkit {
|
|||
authors = listOf("destro174")
|
||||
depend = listOf("Vault")
|
||||
|
||||
commands {
|
||||
register("playershop") {
|
||||
description = "This is a test command!"
|
||||
aliases = listOf("shop")
|
||||
permission = "playershops.command.playershop"
|
||||
}
|
||||
}
|
||||
|
||||
permissions {
|
||||
register("playershops.admin") {
|
||||
description = "Admin permission for the ${rootProject.name} plugin."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
children = listOf(
|
||||
"playershops.shop.create",
|
||||
"playershops.shop.break.other",
|
||||
"playershops.shop.use"
|
||||
)
|
||||
}
|
||||
register("playershops.shoplimit") {
|
||||
description = "Base permission to allow per player shop limits."
|
||||
|
|
@ -102,6 +115,30 @@ bukkit {
|
|||
register("playershops.shop.break.other") {
|
||||
description = "Allows players to break other players shops."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
children = listOf(
|
||||
"playershops.shop.break",
|
||||
)
|
||||
}
|
||||
register("playershops.shop.use") {
|
||||
description = "Allows players to use all playershops."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
children = listOf(
|
||||
"playershops.shop.use.buy",
|
||||
"playershops.shop.use.sell",
|
||||
"playershops.shop.use.gamble"
|
||||
)
|
||||
}
|
||||
register("playershops.shop.use.buy") {
|
||||
description = "Allows players to use buying playershops."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
}
|
||||
register("playershops.shop.use.sell") {
|
||||
description = "Allows players to use selling playershops."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
}
|
||||
register("playershops.shop.use.gamble") {
|
||||
description = "Allows players to use gamble playershops."
|
||||
default = BukkitPluginDescription.Permission.Default.FALSE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.alttd.playershops.handler.ShopHandler;
|
|||
import com.alttd.playershops.listener.BlockListener;
|
||||
import com.alttd.playershops.listener.PlayerListener;
|
||||
import com.alttd.playershops.listener.ShopListener;
|
||||
import com.alttd.playershops.listener.TransactionListener;
|
||||
import com.alttd.playershops.shop.ShopType;
|
||||
import com.alttd.playershops.storage.DatabaseManager;
|
||||
import lombok.Getter;
|
||||
|
|
@ -31,6 +32,7 @@ public class PlayerShops extends JavaPlugin {
|
|||
private ShopListener shopListener;
|
||||
private PlayerListener playerListener;
|
||||
private BlockListener blockListener;
|
||||
private TransactionListener transactionListener;
|
||||
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
|
@ -77,12 +79,14 @@ public class PlayerShops extends JavaPlugin {
|
|||
shopListener = new ShopListener(this);
|
||||
playerListener = new PlayerListener(this);
|
||||
blockListener = new BlockListener(this);
|
||||
transactionListener = new TransactionListener(this);
|
||||
}
|
||||
|
||||
private void unRegisterListeners() {
|
||||
shopListener.unregister();
|
||||
playerListener.unregister();
|
||||
blockListener.unregister();
|
||||
transactionListener.unregister();
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package com.alttd.playershops.commands;
|
||||
|
||||
import com.alttd.playershops.gui.ShopManagementGui;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
// expose brig in Galaxy?
|
||||
public class ShopCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) return true;
|
||||
if (args.length == 0) {
|
||||
return true;
|
||||
}
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "reload":
|
||||
break;
|
||||
case "open":
|
||||
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), new PlayerShop(player.getLocation(), player.getLocation(), player));
|
||||
gui.open();
|
||||
break;
|
||||
default:
|
||||
sender.sendMessage("invalid command useage");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Stream.of("reload", "open")
|
||||
.filter(arg -> arg.startsWith(args[0].toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.alttd.playershops.config;
|
||||
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class GuiIconConfig {
|
||||
|
||||
|
||||
private final String icon;
|
||||
private final String configPath;
|
||||
private final String defaultPath;
|
||||
public GuiIconConfig(String icon) {
|
||||
this.icon = icon;
|
||||
this.configPath = "gui-icon." + this.icon + ".";
|
||||
this.defaultPath = "gui-icon.divider.";
|
||||
init();
|
||||
}
|
||||
|
||||
static int version;
|
||||
|
||||
public void init() {
|
||||
Config.config.readConfig(GuiIconConfig.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));
|
||||
}
|
||||
|
||||
private int getInt(String path, int def) {
|
||||
set(defaultPath + path, def);
|
||||
return Config.config.getNode(configPath + path).getInt(
|
||||
Config.config.getNode(defaultPath + path).getInt(def));
|
||||
}
|
||||
|
||||
private List<String> getStringList(String path, List<String> def) {
|
||||
try {
|
||||
set(defaultPath + path, def);
|
||||
return Config.config.getNode(configPath + path).getList(TypeToken.get(String.class),
|
||||
Config.config.getNode(defaultPath + path).getList(TypeToken.get(String.class), def));
|
||||
} catch(SerializationException ignore) {}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public int slot = 0;
|
||||
public String displayName = "Default";
|
||||
public String material = "dirt";
|
||||
public List<String> lore = new ArrayList<>();
|
||||
private void guiItems() {
|
||||
slot = getInt("slot", slot);
|
||||
material = getString("material", material);
|
||||
displayName = getString("display-name", displayName);
|
||||
lore = getStringList("lore", lore);
|
||||
}
|
||||
|
||||
}
|
||||
116
src/main/java/com/alttd/playershops/gui/AbstractGui.java
Normal file
116
src/main/java/com/alttd/playershops/gui/AbstractGui.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.config.GuiIconConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractGui implements InventoryHolder {
|
||||
|
||||
Inventory inventory;
|
||||
protected final int INV_SIZE = 54;
|
||||
int currentSlot;
|
||||
UUID uuid;
|
||||
int pageIndex;
|
||||
|
||||
AbstractGui(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
this.currentSlot = 0;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
}
|
||||
|
||||
boolean close() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
player.closeInventory();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void scrollPageNext() {
|
||||
ItemStack nextPageIcon = inventory.getItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot());
|
||||
if (nextPageIcon != null && nextPageIcon.equals(getNextPageIcon())) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), getPrevPageIcon());
|
||||
++pageIndex;
|
||||
initInvContents();
|
||||
}
|
||||
}
|
||||
|
||||
void scrollPagePrev() {
|
||||
ItemStack prevPageIcon = inventory.getItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot());
|
||||
if (prevPageIcon != null && prevPageIcon.equals(getPrevPageIcon())) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), getNextPageIcon());
|
||||
--pageIndex;
|
||||
if (pageIndex == 0) {
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), null);
|
||||
}
|
||||
initInvContents();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean addItem(ItemStack icon) {
|
||||
if (currentSlot == inventory.getSize())
|
||||
return false;
|
||||
|
||||
inventory.setItem(currentSlot, icon);
|
||||
currentSlot++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void initInvContents() {
|
||||
clearInvBody();
|
||||
currentSlot = 0;
|
||||
}
|
||||
|
||||
protected void clearInvBody() {
|
||||
for (int i = 0; i < inventory.getSize() - 9; ++i) {
|
||||
inventory.setItem(i, null);
|
||||
}
|
||||
}
|
||||
|
||||
void makeMenuBar() {
|
||||
for (int i = inventory.getSize() - 9; i < inventory.getSize(); ++i) {
|
||||
inventory.setItem(i, getDivider());
|
||||
}
|
||||
}
|
||||
|
||||
Player getPlayer() {
|
||||
return Bukkit.getPlayer(uuid);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
ItemStack getPrevPageIcon() {
|
||||
return GuiIcon.MENUBAR_PREV_PAGE.getItemStack();
|
||||
}
|
||||
|
||||
ItemStack getNextPageIcon() {
|
||||
return GuiIcon.MENUBAR_NEXT_PAGE.getItemStack();
|
||||
}
|
||||
|
||||
ItemStack getExitIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack getDivider() {
|
||||
return GuiIcon.DIVIDER.getItemStack();
|
||||
}
|
||||
|
||||
}
|
||||
76
src/main/java/com/alttd/playershops/gui/GuiIcon.java
Normal file
76
src/main/java/com/alttd/playershops/gui/GuiIcon.java
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.config.GuiIconConfig;
|
||||
import com.alttd.playershops.config.ShopTypeConfig;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public enum GuiIcon {
|
||||
DIVIDER,
|
||||
MENUBAR_BACK,
|
||||
MENUBAR_EXIT,
|
||||
MENUBAR_SEARCH,
|
||||
MENUBAR_PREV_PAGE,
|
||||
MENUBAR_NEXT_PAGE,
|
||||
|
||||
MANAGE_SHOP,
|
||||
MANAGE_SHOP_BALANCE_ADD,
|
||||
MANAGE_SHOP_BALANCE_REMOVE,
|
||||
MANAGE_SHOP_SALES,
|
||||
MANAGE_SHOP_ITEM,
|
||||
MANAGE_SHOP_TYPE,
|
||||
|
||||
HOME_LIST_OWN_SHOPS,
|
||||
HOME_LIST_PLAYERS,
|
||||
HOME_SETTINGS,
|
||||
LIST_SHOP,
|
||||
LIST_PLAYER,
|
||||
LIST_PLAYER_ADMIN;
|
||||
|
||||
@Getter
|
||||
private final int slot;
|
||||
@Getter
|
||||
private final ItemStack itemStack;
|
||||
|
||||
GuiIcon() {
|
||||
GuiIconConfig config = new GuiIconConfig(this.toString());
|
||||
this.slot = config.slot;
|
||||
this.itemStack = createItem(config.material, config.displayName, config.lore);
|
||||
}
|
||||
|
||||
private ItemStack createItem(String materialString, String displayName, List<String> itemlore) {
|
||||
Material material = Material.getMaterial(materialString);
|
||||
if (material == null)
|
||||
return null;
|
||||
|
||||
ItemStack item = new ItemStack(material);
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
|
||||
itemMeta.displayName(format(displayName));
|
||||
List<Component> lore = new ArrayList<>();
|
||||
for (String line : itemlore) {
|
||||
lore.add(format(line));
|
||||
}
|
||||
itemMeta.lore(lore);
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private Component format(String s) {
|
||||
return Util.parseMiniMessage(s, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.alttd.playershops.gui;
|
||||
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ShopManagementGui extends AbstractGui {
|
||||
|
||||
PlayerShop shop;
|
||||
|
||||
public ShopManagementGui(UUID uuid, PlayerShop shop) {
|
||||
super(uuid);
|
||||
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage("Config.gui.management-title", null));
|
||||
this.shop = shop;
|
||||
initInvContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initInvContents() {
|
||||
// super.initInvContents();
|
||||
makeMenuBar();
|
||||
for (int i = 0; i < inventory.getSize() - 9; ++i) {
|
||||
inventory.setItem(i, getDivider());
|
||||
}
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP.getSlot(), GuiIcon.MANAGE_SHOP.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_SALES.getSlot(), GuiIcon.MANAGE_SHOP_SALES.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_ITEM.getSlot(), GuiIcon.MANAGE_SHOP_ITEM.getItemStack());
|
||||
inventory.setItem(GuiIcon.MANAGE_SHOP_TYPE.getSlot(), GuiIcon.MANAGE_SHOP_TYPE.getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
void makeMenuBar() {
|
||||
super.makeMenuBar();
|
||||
inventory.setItem(GuiIcon.MENUBAR_BACK.getSlot(), GuiIcon.MENUBAR_BACK.getItemStack());
|
||||
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), GuiIcon.MENUBAR_PREV_PAGE.getItemStack());
|
||||
// inventory.setItem(49, new ItemStack(Material.NETHER_STAR));
|
||||
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), GuiIcon.MENUBAR_NEXT_PAGE.getItemStack());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -22,12 +22,14 @@ public class ShopHandler {
|
|||
private final Object2IntMap<UUID> shopBuildLimits;
|
||||
@Getter
|
||||
private final Map<Location, PlayerShop> shopLocation;
|
||||
private final Map<Location, PlayerShop> shopSignLocation;
|
||||
@Getter
|
||||
private final ArrayList<Material> shopMaterials;
|
||||
|
||||
public ShopHandler(PlayerShops instance) {
|
||||
plugin = instance;
|
||||
shopLocation = new ConcurrentHashMap<>();
|
||||
shopSignLocation = new ConcurrentHashMap<>();
|
||||
shopBuildLimits = new Object2IntOpenHashMap<>();
|
||||
shopBuildLimits.defaultReturnValue(Config.shopLimit);
|
||||
shopMaterials = new ArrayList<>(); // TODO move into parent method where materials are loaded in.
|
||||
|
|
@ -58,6 +60,7 @@ public class ShopHandler {
|
|||
|
||||
public void removeShops() {
|
||||
shopLocation.clear();
|
||||
shopSignLocation.clear();
|
||||
}
|
||||
|
||||
public boolean isShopMaterial(Block block) {
|
||||
|
|
@ -77,18 +80,22 @@ public class ShopHandler {
|
|||
}
|
||||
|
||||
public PlayerShop getShopBySignLocation(Location signLocation) {
|
||||
for (PlayerShop shop : shopLocation.values()) {
|
||||
if (shop.getSignLocation().equals(signLocation))
|
||||
return shop;
|
||||
}
|
||||
return null;
|
||||
Location newLocation = new Location(signLocation.getWorld(), signLocation.getBlockX(), signLocation.getBlockY(), signLocation.getBlockZ());
|
||||
|
||||
return shopSignLocation.get(newLocation);
|
||||
}
|
||||
|
||||
public void addShop(PlayerShop shop) {
|
||||
shopLocation.put(shop.getShopLocation(), shop);
|
||||
shopSignLocation.put(shop.getSignLocation(), shop);
|
||||
}
|
||||
|
||||
public boolean canPlayerBreakShop(Player player, PlayerShop shop) {
|
||||
public void removeShop(PlayerShop shop) {
|
||||
shopLocation.remove(shop.getShopLocation());
|
||||
shopSignLocation.remove(shop.getSignLocation());
|
||||
}
|
||||
|
||||
public boolean canPlayerBreakShop(Player player, PlayerShop shop) { // TODO move to util?
|
||||
if (player.getUniqueId().equals(shop.getOwnerUUID()) && player.hasPermission("playershops.shop.break"))
|
||||
return true;
|
||||
|
||||
|
|
|
|||
11
src/main/java/com/alttd/playershops/hook/WorldGuardHook.java
Normal file
11
src/main/java/com/alttd/playershops/hook/WorldGuardHook.java
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package com.alttd.playershops.hook;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
public static boolean canUseShopInRegion(Player player, Location location) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +97,7 @@ public class PlayerListener extends EventListener {
|
|||
Component signLine = event.line(0);
|
||||
if (signLine == null)
|
||||
return;
|
||||
|
||||
String signLineString = PlainTextComponentSerializer.plainText().serialize(signLine);
|
||||
if (!signLineString.equalsIgnoreCase(Config.shopCreationWord))
|
||||
return;
|
||||
|
|
@ -131,5 +132,4 @@ public class PlayerListener extends EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
package com.alttd.playershops.listener;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.gui.ShopManagementGui;
|
||||
import com.alttd.playershops.handler.ShopHandler;
|
||||
import com.alttd.playershops.hook.WorldGuardHook;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import com.alttd.playershops.shop.TransactionError;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
/**
|
||||
* Dedicated class to listen to transactions for shops.
|
||||
*
|
||||
*/
|
||||
public class TransactionListener extends EventListener {
|
||||
|
||||
private final PlayerShops plugin;
|
||||
|
||||
public TransactionListener(PlayerShops plugin) {
|
||||
this.plugin = plugin;
|
||||
this.register(this.plugin);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onShopSignClick(PlayerInteractEvent event) {
|
||||
if (event.getHand() == EquipmentSlot.OFF_HAND) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK))
|
||||
return;
|
||||
|
||||
Block block = event.getClickedBlock();
|
||||
if (block == null || Tag.WALL_SIGNS.isTagged(block.getType()))
|
||||
return;
|
||||
|
||||
PlayerShop playerShop = plugin.getShopHandler().getShopBySignLocation(block.getLocation());
|
||||
if (playerShop == null || !playerShop.isInitialized())
|
||||
return;
|
||||
|
||||
// if we ever need worldguard support add it to the hook
|
||||
if (!WorldGuardHook.canUseShopInRegion(player, block.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.hasPermission("playershops.shop.use." + playerShop.getType().toString())) {
|
||||
player.sendMiniMessage("<red>You do not have permission to use " + playerShop.getType().toString() + " shops.", null); // TODO config
|
||||
}
|
||||
|
||||
ShopHandler shopHandler = plugin.getShopHandler();
|
||||
|
||||
// Failsafe. If we have a shopsign but no block cancel the event, log error save and unload the shop
|
||||
if (!shopHandler.isShopMaterial(playerShop.getShopLocation().getBlock())) {
|
||||
event.setCancelled(true);
|
||||
shopHandler.removeShop(playerShop);
|
||||
}
|
||||
|
||||
// TODO upgrade this to an util method check if owner/trusted and open management interface
|
||||
if (playerShop.getOwnerUUID().equals(player.getUniqueId())) {
|
||||
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||
gui.open();
|
||||
return;
|
||||
}
|
||||
executeTransaction(player, playerShop);
|
||||
}
|
||||
|
||||
private void executeTransaction(Player player, PlayerShop shop) {
|
||||
if (shop == null || shop.getItemStack() == null)
|
||||
return;
|
||||
|
||||
int orders = 1;
|
||||
|
||||
if (player.isSneaking())
|
||||
orders = shop.getItemStack().getMaxStackSize();
|
||||
TransactionError transactionError = shop.executeTransaction(orders, player);
|
||||
|
||||
if (transactionError != TransactionError.NONE) {
|
||||
switch (transactionError) {
|
||||
case INVENTORY_FULL_PLAYER -> {
|
||||
|
||||
}
|
||||
case CANCELLED -> {
|
||||
}
|
||||
case INSUFFICIENT_FUNDS_SHOP -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
package com.alttd.playershops.shop;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.events.PlayerExchangeShopEvent;
|
||||
import com.alttd.playershops.utils.EconomyUtils;
|
||||
import com.alttd.playershops.utils.InventoryUtils;
|
||||
import com.alttd.playershops.utils.ShopUtil;
|
||||
import com.alttd.playershops.utils.Util;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
|
@ -27,7 +31,7 @@ public class PlayerShop {
|
|||
@Getter
|
||||
private UUID ownerUUID;
|
||||
@Getter @Setter
|
||||
private ShopType type = ShopType.DEFAULT;
|
||||
private ShopType type = ShopType.NONE;
|
||||
@Getter
|
||||
private final Location signLocation;
|
||||
@Getter
|
||||
|
|
@ -76,7 +80,7 @@ public class PlayerShop {
|
|||
}
|
||||
|
||||
public int getRemainingStock() {
|
||||
return ShopUtil.countItems(getInventory(), getItemStack());
|
||||
return InventoryUtils.countItems(getInventory(), getItemStack());
|
||||
}
|
||||
|
||||
public int getRemainingSpace() {
|
||||
|
|
@ -121,7 +125,7 @@ public class PlayerShop {
|
|||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return type != ShopType.DEFAULT;
|
||||
return type != ShopType.NONE;
|
||||
}
|
||||
|
||||
public void updateSign() {
|
||||
|
|
@ -149,4 +153,108 @@ public class PlayerShop {
|
|||
}
|
||||
}.runTaskLater(PlayerShops.getInstance(), 2L);
|
||||
}
|
||||
|
||||
public double getPricePerItem() {
|
||||
double pricePer = this.getPrice() / this.getAmount();
|
||||
return this.getPrice() / this.getAmount();
|
||||
}
|
||||
|
||||
public void removeBalance(double amount) {
|
||||
this.balance -= amount;
|
||||
}
|
||||
|
||||
public void addBalance(double amount) {
|
||||
this.balance += amount;
|
||||
}
|
||||
|
||||
|
||||
public TransactionError executeTransaction(int orders, Player player) {
|
||||
return switch (getType()) {
|
||||
case SELL -> executeSellTransaction(orders, player);
|
||||
case BUY -> executeBuyTransaction(orders, player);
|
||||
case GAMBLE -> executeGambleTransaction(orders, player);
|
||||
default -> TransactionError.NONE; // This should not happen
|
||||
};
|
||||
}
|
||||
|
||||
private TransactionError executeSellTransaction(int orders, Player player) {
|
||||
ItemStack itemStack = getItemStack().clone();
|
||||
double price = getPrice();
|
||||
if (orders == itemStack.getMaxStackSize()) {
|
||||
itemStack.setAmount(orders);
|
||||
price = getPricePerItem() * orders;
|
||||
}
|
||||
|
||||
int shopItems = InventoryUtils.countItems(getInventory(), itemStack);
|
||||
if (shopItems < itemStack.getAmount())
|
||||
return TransactionError.INSUFFICIENT_FUNDS_SHOP;
|
||||
|
||||
boolean hasFunds = EconomyUtils.hasSufficientFunds(player, price);
|
||||
if (!hasFunds)
|
||||
return TransactionError.INSUFFICIENT_FUNDS_PLAYER;
|
||||
|
||||
boolean hasRoom = EconomyUtils.canAcceptFunds(this, price);
|
||||
if (!hasRoom)
|
||||
return TransactionError.INVENTORY_FULL_SHOP;
|
||||
|
||||
boolean playerHasRoom = InventoryUtils.hasRoom(player.getInventory(), itemStack);
|
||||
if (!playerHasRoom)
|
||||
return TransactionError.INVENTORY_FULL_PLAYER;
|
||||
|
||||
PlayerExchangeShopEvent playerExchangeShopEvent = new PlayerExchangeShopEvent(player, this);
|
||||
if (Util.callCancellableEvent(playerExchangeShopEvent)) {
|
||||
return TransactionError.CANCELLED;
|
||||
}
|
||||
|
||||
InventoryUtils.removeItem(getInventory(), itemStack);
|
||||
EconomyUtils.removeFunds(player, price);
|
||||
addBalance(price);
|
||||
InventoryUtils.addItem(player.getInventory(), itemStack);
|
||||
player.updateInventory();
|
||||
|
||||
return TransactionError.NONE;
|
||||
}
|
||||
|
||||
private TransactionError executeBuyTransaction(int orders, Player player) {
|
||||
ItemStack itemStack = getItemStack().clone();
|
||||
double price = getPrice();
|
||||
if (orders == itemStack.getMaxStackSize()) {
|
||||
itemStack.setAmount(orders);
|
||||
price = getPricePerItem() * orders;
|
||||
}
|
||||
|
||||
int playerItems = InventoryUtils.countItems(player.getInventory(), itemStack);
|
||||
if (playerItems < itemStack.getAmount())
|
||||
return TransactionError.INSUFFICIENT_FUNDS_PLAYER;
|
||||
|
||||
boolean hasFunds = EconomyUtils.hasSufficientFunds(this, price);
|
||||
if (!hasFunds)
|
||||
return TransactionError.INSUFFICIENT_FUNDS_SHOP;
|
||||
|
||||
boolean hasRoom = EconomyUtils.canAcceptFunds(player, price);
|
||||
if (!hasRoom)
|
||||
return TransactionError.INVENTORY_FULL_PLAYER;
|
||||
|
||||
boolean shopHasRoom = InventoryUtils.hasRoom(getInventory(), itemStack);
|
||||
if (!shopHasRoom)
|
||||
return TransactionError.INVENTORY_FULL_SHOP;
|
||||
|
||||
PlayerExchangeShopEvent playerExchangeShopEvent = new PlayerExchangeShopEvent(player, this);
|
||||
if (Util.callCancellableEvent(playerExchangeShopEvent)) {
|
||||
return TransactionError.CANCELLED;
|
||||
}
|
||||
|
||||
InventoryUtils.removeItem(player.getInventory(), itemStack);
|
||||
removeBalance(price);
|
||||
EconomyUtils.addFunds(player, price);
|
||||
InventoryUtils.addItem(getInventory(), itemStack);
|
||||
player.updateInventory();
|
||||
|
||||
return TransactionError.NONE;
|
||||
}
|
||||
|
||||
private TransactionError executeGambleTransaction(int orders, Player player) {
|
||||
return TransactionError.NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.alttd.playershops.config.ShopTypeConfig;
|
|||
|
||||
public enum ShopType {
|
||||
|
||||
DEFAULT(),
|
||||
NONE(),
|
||||
SELL(),
|
||||
BUY(),
|
||||
GAMBLE();
|
||||
|
|
|
|||
58
src/main/java/com/alttd/playershops/utils/EconomyUtils.java
Normal file
58
src/main/java/com/alttd/playershops/utils/EconomyUtils.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package com.alttd.playershops.utils;
|
||||
|
||||
import com.alttd.playershops.PlayerShops;
|
||||
import com.alttd.playershops.shop.PlayerShop;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
// TODO document
|
||||
public class EconomyUtils {
|
||||
|
||||
//check to see if the player has enough funds to take out [amount]
|
||||
//return false if they do not
|
||||
public static boolean hasSufficientFunds(Player player, double amount) {
|
||||
double balance = PlayerShops.getInstance().getEconomy().getBalance(player);
|
||||
return (balance >= amount);
|
||||
}
|
||||
|
||||
public static boolean hasSufficientFunds(PlayerShop shop, double amount) {
|
||||
double balance = shop.getBalance();
|
||||
return (balance >= amount);
|
||||
}
|
||||
|
||||
//gets the current funds of the player
|
||||
public static double getFunds(Player player) {
|
||||
return PlayerShops.getInstance().getEconomy().getBalance(player);
|
||||
}
|
||||
|
||||
//removes [amount] of funds from the player
|
||||
//return false if the player did not have sufficient funds or if something went wrong
|
||||
public static boolean removeFunds(Player player, double amount) {
|
||||
EconomyResponse response = PlayerShops.getInstance().getEconomy().withdrawPlayer(player, amount);
|
||||
return response.transactionSuccess();
|
||||
}
|
||||
|
||||
//adds [amount] of funds to the player
|
||||
//return false if the player is offline
|
||||
public static boolean addFunds(Player player, double amount) {
|
||||
if(player.isOnline()) {
|
||||
EconomyResponse response = PlayerShops.getInstance().getEconomy().depositPlayer(player, amount);
|
||||
return response.transactionSuccess();
|
||||
} else {
|
||||
return false;
|
||||
// int temp = PlayerShops.getInstance().Earnings.getInt(player.getUniqueId() + ".earnings");
|
||||
// PlayerShops.getInstance().Earnings.set(player.getUniqueId() + ".earnings", temp + amount);
|
||||
// PlayerShops.getInstance().Earnings.save();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canAcceptFunds(Player player, double price) {
|
||||
// if we ever need to limit the maximum balance a player can have this is the place
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean canAcceptFunds(PlayerShop shop, double price) {
|
||||
// if we ever need to limit the maximum balance a shop can have this is the place
|
||||
return true;
|
||||
}
|
||||
}
|
||||
119
src/main/java/com/alttd/playershops/utils/InventoryUtils.java
Normal file
119
src/main/java/com/alttd/playershops/utils/InventoryUtils.java
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
package com.alttd.playershops.utils;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class InventoryUtils {
|
||||
|
||||
/**
|
||||
* Counts the number of items in the given inventory where
|
||||
* Util.matches(inventory item, item) is true.
|
||||
*
|
||||
* @param inv
|
||||
* The inventory to search
|
||||
* @param item
|
||||
* The ItemStack to search for
|
||||
* @return The number of items that match in this inventory.
|
||||
*/
|
||||
public static int countItems(Inventory inv, ItemStack item) {
|
||||
int items = 0;
|
||||
for (ItemStack iStack : inv.getContents()) {
|
||||
if (iStack == null)
|
||||
continue;
|
||||
if (ShopUtil.matches(item, iStack)) {
|
||||
items += iStack.getAmount();
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
// TODO DOCS
|
||||
//removes itemstack from inventory
|
||||
//returns the amount of items it could not remove
|
||||
public static int removeItem(Inventory inventory, ItemStack itemStack) {
|
||||
if (inventory == null)
|
||||
return itemStack.getAmount();
|
||||
if (itemStack == null || itemStack.getAmount() <= 0)
|
||||
return 0;
|
||||
ItemStack[] contents = inventory.getContents();
|
||||
int amount = itemStack.getAmount();
|
||||
for (ItemStack stack : contents) {
|
||||
if (stack != null) {
|
||||
if (ShopUtil.matches(stack, itemStack)) {
|
||||
if (stack.getAmount() > amount) {
|
||||
stack.setAmount(stack.getAmount() - amount);
|
||||
inventory.setContents(contents);
|
||||
return 0;
|
||||
} else if (stack.getAmount() == amount) {
|
||||
stack.setType(Material.AIR);
|
||||
inventory.setContents(contents);
|
||||
return 0;
|
||||
} else {
|
||||
amount -= stack.getAmount();
|
||||
stack.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inventory.setContents(contents);
|
||||
return amount;
|
||||
}
|
||||
|
||||
//takes an ItemStack and splits it up into multiple ItemStacks with correct stack sizes
|
||||
//then adds those items to the given inventory
|
||||
public static int addItem(Inventory inventory, ItemStack itemStack) {
|
||||
if (inventory == null)
|
||||
return itemStack.getAmount();
|
||||
if (itemStack.getAmount() <= 0)
|
||||
return 0;
|
||||
ArrayList<ItemStack> itemStacksAdding = new ArrayList<>();
|
||||
|
||||
//break up the itemstack into multiple ItemStacks with correct stack size
|
||||
int fullStacks = itemStack.getAmount() / itemStack.getMaxStackSize();
|
||||
int partialStack = itemStack.getAmount() % itemStack.getMaxStackSize();
|
||||
for (int i = 0; i < fullStacks; i++) {
|
||||
ItemStack is = itemStack.clone();
|
||||
is.setAmount(is.getMaxStackSize());
|
||||
itemStacksAdding.add(is);
|
||||
}
|
||||
ItemStack is = itemStack.clone();
|
||||
is.setAmount(partialStack);
|
||||
if (partialStack > 0)
|
||||
itemStacksAdding.add(is);
|
||||
|
||||
//try adding all items from itemStacksAdding and return number of ones you couldn't add
|
||||
int amount = 0;
|
||||
for (ItemStack addItem : itemStacksAdding) {
|
||||
HashMap<Integer, ItemStack> noAdd = inventory.addItem(addItem);
|
||||
for (ItemStack noAddItemstack : noAdd.values()) {
|
||||
amount += noAddItemstack.getAmount();
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
public static boolean hasRoom(Inventory inventory, ItemStack itemStack) {
|
||||
if (inventory == null)
|
||||
return false;
|
||||
if (itemStack.getAmount() <= 0)
|
||||
return true;
|
||||
|
||||
int overflow = addItem(inventory, itemStack);
|
||||
|
||||
//revert back if inventory cannot hold all of the items
|
||||
if (overflow > 0) {
|
||||
ItemStack revert = itemStack.clone();
|
||||
revert.setAmount(revert.getAmount() - overflow);
|
||||
InventoryUtils.removeItem(inventory, revert);
|
||||
return false;
|
||||
}
|
||||
removeItem(inventory, itemStack);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
83
src/main/java/com/alttd/playershops/utils/Util.java
Normal file
83
src/main/java/com/alttd/playershops/utils/Util.java
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package com.alttd.playershops.utils;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Util {
|
||||
|
||||
private static MiniMessage miniMessage = null;
|
||||
|
||||
public static HashMap<String, String> colors;
|
||||
static { // this might be in minimessage already?
|
||||
colors = new HashMap<>();
|
||||
colors.put("&0", "<black>");
|
||||
colors.put("&1", "<dark_blue>");
|
||||
colors.put("&2", "<dark_green>");
|
||||
colors.put("&3", "<dark_aqua>");
|
||||
colors.put("&4", "<dark_red>");
|
||||
colors.put("&5", "<dark_purple>");
|
||||
colors.put("&6", "<gold>");
|
||||
colors.put("&7", "<gray>");
|
||||
colors.put("&8", "<dark_gray>");
|
||||
colors.put("&9", "<blue>");
|
||||
colors.put("&a", "<green>");
|
||||
colors.put("&b", "<aqua>");
|
||||
colors.put("&c", "<red>");
|
||||
colors.put("&d", "<light_purple>");
|
||||
colors.put("&e", "<yellow>");
|
||||
colors.put("&f", "<white>");
|
||||
colors.put("&l", "<bold>");
|
||||
colors.put("&o", "<italic>");
|
||||
}
|
||||
|
||||
public static String parseColors(String message) {
|
||||
for (String key : colors.keySet()) {
|
||||
if (message.contains(key)) {
|
||||
message = message.replace(key, colors.get(key));
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private static MiniMessage miniMessage() {
|
||||
if (miniMessage == null)
|
||||
miniMessage = MiniMessage.miniMessage();
|
||||
return miniMessage;
|
||||
}
|
||||
|
||||
public static Component parseMiniMessage(String message, TagResolver tagResolver) {
|
||||
message = parseColors(message);
|
||||
if (tagResolver == null) {
|
||||
return miniMessage().deserialize(message);
|
||||
} else {
|
||||
return miniMessage().deserialize(message, tagResolver);
|
||||
}
|
||||
}
|
||||
|
||||
public static String capitalize(String string) {
|
||||
if (string.length() <= 1)
|
||||
return string.toUpperCase();
|
||||
string = string.toLowerCase();
|
||||
return string.substring(0, 1).toUpperCase() + string.toLowerCase().substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call an event and check it is cancelled.
|
||||
*
|
||||
* @param event The event implement the Cancellable interface.
|
||||
* @return The event is cancelled.
|
||||
*/
|
||||
public static boolean callCancellableEvent(Cancellable event) {
|
||||
if (!(event instanceof Event)) {
|
||||
throw new IllegalArgumentException("Cancellable must is event implement");
|
||||
}
|
||||
Bukkit.getPluginManager().callEvent((Event) event);
|
||||
return event.isCancelled();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user