diff --git a/pom.xml b/pom.xml index 30b97525..3f47a24a 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ org.shanerx tradeshop - 2.5.1-STABLE + 2.6.0-DEV jar TradeShop https://tradeshop.github.io/ @@ -73,36 +73,60 @@ UTF-8 yyyy-MM-dd'T'HH.mm.ss ${maven.build.timestamp} - + org/shanerx/tradeshop + src/main/resources + + + + + + + + target/output-files + + expiration - builddate.yml + builddate.yml + + + + clean + + clean + + + + skipDocs + + true - install - ${project.artifactId}-${project.version}-${maven.build.timestamp} + ${doClean} install + ${project.name}-${project.version}-${maven.build.timestamp} + src/main/java . true - ${basedir}/src/main/resources/ + ${basedir}/${resourceDir} plugin.yml - ${builddate} + ${expirationFile} ./Lang false - ${basedir}/src/main/resources/Lang + ${basedir}/${resourceDir}/Lang @@ -110,7 +134,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.0 + 3.8.1 1.8 1.8 @@ -119,25 +143,34 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.3.0 + ${outputDir}/PreShade false org.bstats:* - de.themoep:* + de.themoep:* org.bstats - org.shanerx.tradeshop + ${project.groupId}.${project.artifactId}.bstats de.themoep - io.github.apfelcreme.Pipes.libs + ${project.groupId}.${project.artifactId} + + + *:* + + META-INF/maven/** + + + @@ -151,17 +184,18 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + 3.4.0 false + ${outputDir}/JavaDocs - ${skip_docs} + ${skipDocs} - org/shanerx/tradeshop/TradeShop.java - org/shanerx/tradeshop/commands/** - org/shanerx/tradeshop/listeners/** - org/shanerx/tradeshop/utils/Updater.java - org/shanerx/tradeshop/utils/BukkitVersion.java + ${pluginDir}/TradeShop.java + ${pluginDir}/commands/** + ${pluginDir}/shop/listeners/** + ${pluginDir}/utils/versionmanagement/** + ${pluginDir}/player/JoinEventListener.java @@ -197,7 +231,7 @@ org.spigotmc spigot-api - 1.18.1-R0.1-SNAPSHOT + 1.19.2-R0.1-SNAPSHOT provided @@ -211,15 +245,14 @@ de.themoep inventorygui - - 1.4.2-SNAPSHOT + 1.6-SNAPSHOT compile org.apache.maven.plugins maven-javadoc-plugin - 3.3.2 + 3.4.1 maven-plugin diff --git a/src/main/java/org/shanerx/tradeshop/TradeShop.java b/src/main/java/org/shanerx/tradeshop/TradeShop.java index ded24daf..0430f3d3 100644 --- a/src/main/java/org/shanerx/tradeshop/TradeShop.java +++ b/src/main/java/org/shanerx/tradeshop/TradeShop.java @@ -30,25 +30,26 @@ import org.bukkit.plugin.java.JavaPlugin; import org.shanerx.tradeshop.commands.CommandCaller; import org.shanerx.tradeshop.commands.CommandTabCaller; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.ShopSign; -import org.shanerx.tradeshop.enumys.ShopStorage; -import org.shanerx.tradeshop.listeners.JoinEventListener; -import org.shanerx.tradeshop.listeners.ShopCreateListener; -import org.shanerx.tradeshop.listeners.ShopProtectionListener; -import org.shanerx.tradeshop.listeners.ShopRestockListener; -import org.shanerx.tradeshop.listeners.ShopTradeListener; -import org.shanerx.tradeshop.objects.Debug; -import org.shanerx.tradeshop.objects.ListManager; -import org.shanerx.tradeshop.utils.BukkitVersion; -import org.shanerx.tradeshop.utils.Expirer; +import org.shanerx.tradeshop.data.config.ConfigManager; +import org.shanerx.tradeshop.data.config.Language; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.storage.DataStorage; +import org.shanerx.tradeshop.data.storage.DataType; +import org.shanerx.tradeshop.player.JoinEventListener; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.shop.ShopSign; +import org.shanerx.tradeshop.shop.ShopStorage; +import org.shanerx.tradeshop.shop.listeners.ShopCreateListener; +import org.shanerx.tradeshop.shop.listeners.ShopProtectionListener; +import org.shanerx.tradeshop.shop.listeners.ShopRestockListener; +import org.shanerx.tradeshop.shop.listeners.ShopTradeListener; +import org.shanerx.tradeshop.utils.ListManager; import org.shanerx.tradeshop.utils.MetricsManager; -import org.shanerx.tradeshop.utils.Updater; -import org.shanerx.tradeshop.utils.config.ConfigManager; -import org.shanerx.tradeshop.utils.config.Language; -import org.shanerx.tradeshop.utils.config.Setting; -import org.shanerx.tradeshop.utils.data.DataStorage; -import org.shanerx.tradeshop.utils.data.DataType; +import org.shanerx.tradeshop.utils.debug.Debug; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.versionmanagement.BukkitVersion; +import org.shanerx.tradeshop.utils.versionmanagement.Expirer; +import org.shanerx.tradeshop.utils.versionmanagement.Updater; public class TradeShop extends JavaPlugin { @@ -58,8 +59,6 @@ public class TradeShop extends JavaPlugin { private final NamespacedKey signKey = new NamespacedKey(this, "tradeshop-sign-data"); private MetricsManager metricsManager; - - private boolean useInternalPerms = false; private boolean skipHopperProtection = false; private ListManager lists; @@ -101,8 +100,12 @@ public void onEnable() { getSettingManager().reload(); getMessageManager().reload(); + getSettingManager().updateSkipHoppers(); + getDebugger(); + Permissions.registerPermissions(); + if (getDataStorage() == null) return; @@ -138,14 +141,6 @@ public void onDisable() { getListManager().clearManager(); } - public boolean useInternalPerms() { - return useInternalPerms; - } - - public void setUseInternalPerms(boolean useInternalPerms) { - this.useInternalPerms = useInternalPerms; - } - public boolean doSkipHopperProtection() { return skipHopperProtection; } diff --git a/src/main/java/org/shanerx/tradeshop/commands/CommandCaller.java b/src/main/java/org/shanerx/tradeshop/commands/CommandCaller.java index 7f8e3464..27666d66 100644 --- a/src/main/java/org/shanerx/tradeshop/commands/CommandCaller.java +++ b/src/main/java/org/shanerx/tradeshop/commands/CommandCaller.java @@ -29,7 +29,20 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.utils.config.Message; +import org.shanerx.tradeshop.commands.commandrunners.AdminCommand; +import org.shanerx.tradeshop.commands.commandrunners.BasicTextCommand; +import org.shanerx.tradeshop.commands.commandrunners.CommandRunner; +import org.shanerx.tradeshop.commands.commandrunners.CreateCommand; +import org.shanerx.tradeshop.commands.commandrunners.EditCommand; +import org.shanerx.tradeshop.commands.commandrunners.GeneralPlayerCommand; +import org.shanerx.tradeshop.commands.commandrunners.ShopCommand; +import org.shanerx.tradeshop.commands.commandrunners.ShopItemCommand; +import org.shanerx.tradeshop.commands.commandrunners.ShopUserCommand; +import org.shanerx.tradeshop.commands.commandrunners.WhatCommand; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.framework.ShopChange; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.player.ShopRole; /** * This class is used for calling command methods from CommandRunner @@ -73,94 +86,97 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String switch (command) { case HELP: - cmdRnnr.help(); + new BasicTextCommand(plugin, cmdPass).help(); break; case BUGS: - cmdRnnr.bugs(); + new BasicTextCommand(plugin, cmdPass).bugs(); break; case SETUP: - cmdRnnr.setup(); + new BasicTextCommand(plugin, cmdPass).setup(); break; case RELOAD: - cmdRnnr.reload(); + new AdminCommand(plugin, cmdPass).reload(); break; case ADD_PRODUCT: - cmdRnnr.addProduct(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.PRODUCT).addSide(); break; case ADD_COST: - cmdRnnr.addCost(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.COST).addSide(); break; case OPEN: - cmdRnnr.open(); + new ShopCommand(plugin, cmdPass).open(); break; case CLOSE: - cmdRnnr.close(); + new ShopCommand(plugin, cmdPass).close(); break; case SWITCH: - cmdRnnr.switchShop(); + new ShopCommand(plugin, cmdPass).switchShop(); break; case WHAT: new WhatCommand(plugin, cmdPass).what(); break; case WHO: - cmdRnnr.who(); - break; - case ADD_MANAGER: - cmdRnnr.addManager(); + new ShopUserCommand(plugin, cmdPass).who(); break; case REMOVE_USER: - cmdRnnr.removeUser(); + new ShopUserCommand(plugin, cmdPass).editUser(ShopRole.SHOPPER, ShopChange.REMOVE_USER); + break; + case ADD_MANAGER: + new ShopUserCommand(plugin, cmdPass).editUser(ShopRole.MANAGER, ShopChange.ADD_MANAGER); break; case ADD_MEMBER: - cmdRnnr.addMember(); + new ShopUserCommand(plugin, cmdPass).editUser(ShopRole.MEMBER, ShopChange.ADD_MEMBER); + break; + case SET_MANAGER: + new ShopUserCommand(plugin, cmdPass).editUser(ShopRole.MANAGER, ShopChange.SET_MANAGER); + break; + case SET_MEMBER: + new ShopUserCommand(plugin, cmdPass).editUser(ShopRole.MEMBER, ShopChange.SET_MEMBER); break; case MULTI: - cmdRnnr.multi(); + new GeneralPlayerCommand(plugin, cmdPass).multi(); break; case SET_PRODUCT: - cmdRnnr.setProduct(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.PRODUCT).setSide(); break; case SET_COST: - cmdRnnr.setCost(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.COST).setSide(); break; case LIST_PRODUCT: - cmdRnnr.listProduct(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.PRODUCT).listSide(); break; case LIST_COST: - cmdRnnr.listCost(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.COST).listSide(); break; case REMOVE_PRODUCT: - cmdRnnr.removeProduct(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.PRODUCT).removeSide(); break; case REMOVE_COST: - cmdRnnr.removeCost(); - break; - case PLAYER_LEVEL: - cmdRnnr.playerLevel(); + new ShopItemCommand(plugin, cmdPass, ShopItemSide.COST).removeSide(); break; case STATUS: - cmdRnnr.status(); + new GeneralPlayerCommand(plugin, cmdPass).status(); break; case EDIT: new EditCommand(plugin, cmdPass).edit(); break; case TOGGLE_STATUS: - cmdRnnr.toggleStatus(); + new GeneralPlayerCommand(plugin, cmdPass).toggleStatus(); break; case CREATE_TRADE: - cmdRnnr.createTrade(); + new CreateCommand(plugin, cmdPass).createTrade(); break; case CREATE_BITRADE: - cmdRnnr.createBiTrade(); + new CreateCommand(plugin, cmdPass).createBiTrade(); break; case CREATE_ITRADE: - cmdRnnr.createITrade(); + new CreateCommand(plugin, cmdPass).createITrade(); break; case TOGGLE_ADMIN: - cmdRnnr.toggleAdmin(); + new AdminCommand(plugin, cmdPass).toggleAdmin(); break; case ADMIN: - cmdRnnr.admin(); + new AdminCommand(plugin, cmdPass).admin(); break; } diff --git a/src/main/java/org/shanerx/tradeshop/commands/CommandRunner.java b/src/main/java/org/shanerx/tradeshop/commands/CommandRunner.java deleted file mode 100644 index 53516a36..00000000 --- a/src/main/java/org/shanerx/tradeshop/commands/CommandRunner.java +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.commands; - -import de.themoep.inventorygui.GuiPageElement; -import de.themoep.inventorygui.InventoryGui; -import de.themoep.inventorygui.StaticGuiElement; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.PermStatus; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.enumys.ShopRole; -import org.shanerx.tradeshop.enumys.ShopStatus; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.framework.ShopChange; -import org.shanerx.tradeshop.framework.events.PlayerShopChangeEvent; -import org.shanerx.tradeshop.framework.events.PlayerShopCloseEvent; -import org.shanerx.tradeshop.framework.events.PlayerShopCreateEvent; -import org.shanerx.tradeshop.framework.events.PlayerShopOpenEvent; -import org.shanerx.tradeshop.framework.events.TradeShopReloadEvent; -import org.shanerx.tradeshop.objects.IllegalItemList; -import org.shanerx.tradeshop.objects.PlayerSetting; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChest; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.objects.ShopLocation; -import org.shanerx.tradeshop.objects.ShopUser; -import org.shanerx.tradeshop.utils.ObjectHolder; -import org.shanerx.tradeshop.utils.Tuple; -import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; -import org.shanerx.tradeshop.utils.config.Variable; -import org.shanerx.tradeshop.utils.data.DataType; - -public class CommandRunner extends Utils { - - protected final TradeShop plugin; - protected final CommandPass command; - protected Player pSender; - - protected final GuiPageElement PREV_BUTTON = new GuiPageElement('p', new ItemStack(Material.POTION), GuiPageElement.PageAction.PREVIOUS, "Go to previous page (%prevpage%)"), - NEXT_BUTTON = new GuiPageElement('n', new ItemStack(Material.SPLASH_POTION), GuiPageElement.PageAction.NEXT, "Go to next page (%nextpage%)"); - protected final StaticGuiElement CANCEL_BUTTON = new StaticGuiElement('c', new ItemStack(Material.END_CRYSTAL), click3 -> { - InventoryGui.goBack(pSender); - return true; - }, "Cancel Changes"), - BACK_BUTTON = new StaticGuiElement('b', new ItemStack(Material.END_CRYSTAL), click3 -> { - InventoryGui.goBack(pSender); - return true; - }, "Back"); - protected final String[] MENU_LAYOUT = {"a b c"}, - EDIT_LAYOUT = {"aggggggga", "ap c s na"}, - ITEM_LAYOUT = {"aggggggga", "aggggggga", "a cbs a"}, - WHAT_MENU = {"141125333", "1aaa2bbb3", "11p123n33"}; - - public CommandRunner(TradeShop instance, CommandPass command) { - this.plugin = instance; - this.command = command; - - if (command.getSender() instanceof Player) { - pSender = (Player) command.getSender(); - } - } - - /** - * Builds and sends the sender the help message - */ - public void help() { - if (command.argsSize() == 2) { - usage(command.getArgAt(1)); - return; - } - - StringBuilder sb = new StringBuilder(); - - sb.append("\n&2") - .append(getPluginName()) - .append(" ") - .append(getVersion()) - .append(" by ").append(pdf.getAuthors().get(0)).append(" & ").append(pdf.getAuthors().get(1)) - .append("\n\n&b/tradeshop &f &f Display help message\n"); - - for (Commands c : Commands.values()) { - if (c.checkPerm(command.getSender()) == PermStatus.GOOD) { - sb.append(plugin.getMessageManager().colour(String.format("&b/ts %s &f %s\n", c.getFirstName(), c.getDescription()))); - } - } - - sb.append("\n "); - command.sendMessage(colorize(sb.toString())); - } - - public void usage(String subcmd) { - Commands cmd = Commands.getType(subcmd); - if (cmd == null) { - command.sendMessage(plugin.getMessageManager().colour(String.format("&4Cannot find usages for &c%s&r", subcmd))); - return; - } - command.sendMessage(plugin.getMessageManager().colour(String.format("&6Showing help for &c%s&r\n&bUsage:&e %s \n&bAliases: %s\n&bDescription:&e %s", subcmd, cmd.getUsage(), cmd.getAliases(), cmd.getDescription()))); - } - - /** - * Sends the sender the bug message - */ - public void bugs() { - command.sendMessage("\n&a[&eTradeShop&a] \n&2To report any bugs to the author, either send a PM on &cSpigot &2- &egoo.gl/s6Jk23 &2or open an issue on &cGitHub &2-&e goo.gl/X4qqyg\n"); - } - - /** - * Sends the sender the setup message - */ - public void setup() { - Message.SETUP_HELP.sendMessage(pSender, new Tuple<>(Variable.HEADER.toString(), Setting.TRADESHOP_HEADER.getString())); - } - - /** - * Reloads the plugin and sends success message - */ - public void reload() { - plugin.getLanguage().reload(); - plugin.getSettingManager().reload(); - plugin.getMessageManager().reload(); - plugin.getListManager().reload(); - plugin.getDebugger().reload(); - try { - plugin.getDataStorage().reload(DataType.valueOf(Setting.DATA_STORAGE_TYPE.getString().toUpperCase())); - } catch (IllegalArgumentException iae) { - debugger.log("Config value for data storage set to an invalid value: " + Setting.DATA_STORAGE_TYPE.getString(), DebugLevels.DATA_ERROR); - debugger.log("TradeShop will now disable...", DebugLevels.DATA_ERROR); - plugin.getServer().getPluginManager().disablePlugin(plugin); - return; - } - - command.sendMessage(Setting.MESSAGE_PREFIX.getString() + "&6The configuration files have been reloaded!"); - Bukkit.getPluginManager().callEvent(new TradeShopReloadEvent(plugin, command.getSender())); - } - - /** - * Lists products with their index - */ - public void listProduct() { - Shop shop = findShop(); - - if (shop == null) - return; - - StringBuilder sb = new StringBuilder(); - int counter = 1; - - for (ShopItemStack itm : shop.getProduct()) { - sb.append(String.format("&b[&f%d&b] &2- &f%s\n", counter, itm.getCleanItemName())); - counter++; - } - - Message.SHOP_ITEM_LIST.sendMessage(pSender, new Tuple<>(Variable.TYPE.toString(), "products"), new Tuple<>(Variable.LIST.toString(), sb.toString())); - } - - /** - * Lists costs with their index - */ - public void listCost() { - Shop shop = findShop(); - - if (shop == null) - return; - - StringBuilder sb = new StringBuilder(); - int counter = 1; - - for (ShopItemStack itm : shop.getCost()) { - sb.append(String.format("&b[&f%d&b] &2- &f%s\n", counter, itm.getCleanItemName())); - counter++; - } - - Message.SHOP_ITEM_LIST.sendMessage(pSender, new Tuple<>(Variable.TYPE.toString(), "costs"), new Tuple<>(Variable.LIST.toString(), sb.toString())); - } - - /** - * Removes product at index - */ - public void removeProduct() { - Shop shop = findShop(); - - if (shop == null) - return; - - int index = 0; - - if (isInt(command.getArgAt(1))) { - index = Integer.parseInt(command.getArgAt(1)) - 1; - } else { - Message.INVALID_ARGUMENTS.sendMessage(pSender); - return; - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.REMOVE_PRODUCT, new ObjectHolder(index)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - if (shop.removeProduct(index)) - Message.ITEM_REMOVED.sendMessage(pSender); - else - Message.ITEM_NOT_REMOVED.sendMessage(pSender); - } - - /** - * Removes cost at index - */ - public void removeCost() { - Shop shop = findShop(); - - if (shop == null) - return; - - int index; - - if (isInt(command.getArgAt(1))) { - index = Integer.parseInt(command.getArgAt(1)) - 1; - } else { - Message.INVALID_ARGUMENTS.sendMessage(pSender); - return; - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.REMOVE_COST, new ObjectHolder(index)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - if (shop.removeCost(index)) - Message.ITEM_REMOVED.sendMessage(pSender); - else - Message.ITEM_NOT_REMOVED.sendMessage(pSender); - } - - /** - * Sets a product to a Shop - *

- * With no variables sent will use the amount and data of the held item for product - *

- *

- * If the player uses a int in the first variable they can change the amount for the item they are holding - *

- *

- * With 2 variables used the player can use an amount and material to set the sign instead of a held item - *

- */ - public void setProduct() { - Shop shop = findShop(); - - if (shop == null) - return; - - int amount = 0; - Material mat = null; - - if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { - amount = Integer.parseInt(command.getArgAt(1)); - } - - if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { - mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - ItemStack itemInHand; - - if (mat == null) { - itemInHand = pSender.getInventory().getItemInMainHand().clone(); - } else { - itemInHand = new ItemStack(mat, 1); - } - - if (itemInHand.getType() == Material.AIR) { - Message.HELD_EMPTY.sendMessage(pSender); - return; - } - - if (isIllegal(IllegalItemList.TradeItemType.PRODUCT, itemInHand.getType())) { - Message.ILLEGAL_ITEM.sendMessage(pSender); - return; - } - - if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && itemInHand.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { - Message.NO_SHULKER_COST.sendMessage(pSender); - return; - } - - if (amount > 0) { - itemInHand.setAmount(amount); - } - - if (Math.ceil((double) itemInHand.getAmount() / (double) itemInHand.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { - Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), "product")); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.SET_PRODUCT, new ObjectHolder(itemInHand)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.setProduct(itemInHand); - - Message.ITEM_ADDED.sendMessage(pSender); - } - - /** - * Adds a product to a Shop - *

- * With no variables sent will use the amount and data of the held item for product - *

- *

- * If the player uses a int in the first variable they can change the amount for the item they are holding - *

- *

- * With 2 variables used the player can use an amount and material to set the sign instead of a held item - *

- */ - public void addProduct() { - Shop shop = findShop(); - - if (shop == null) - return; - - int amount = 0; - Material mat = null; - - if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { - amount = Integer.parseInt(command.getArgAt(1)); - } - - if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { - mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - ItemStack itemInHand; - - if (mat == null) { - itemInHand = pSender.getInventory().getItemInMainHand().clone(); - } else { - itemInHand = new ItemStack(mat, 1); - } - - if (itemInHand.getType() == Material.AIR) { - Message.HELD_EMPTY.sendMessage(pSender); - return; - } - - if (isIllegal(IllegalItemList.TradeItemType.PRODUCT, itemInHand.getType())) { - Message.ILLEGAL_ITEM.sendMessage(pSender); - return; - } - - if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && itemInHand.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { - Message.NO_SHULKER_COST.sendMessage(pSender); - return; - } - - if (amount > 0) { - itemInHand.setAmount(amount); - } - - if (shop.getProduct().size() + Math.ceil((double) itemInHand.getAmount() / (double) itemInHand.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { - Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), "product")); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.ADD_PRODUCT, new ObjectHolder(itemInHand)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.addProduct(itemInHand); - - Message.ITEM_ADDED.sendMessage(pSender); - } - - /** - * Sets the item to the shop - *

- * With no variables sent will use the amount and data of the held item for cost - *

- *

- * If the player uses a int in the first variable they can change the amount for the item they are holding - *

- *

- * With 2 variables used the player can use an amount and material to set the sign instead of a held item - *

- */ - public void setCost() { - Shop shop = findShop(); - - if (shop == null) - return; - - int amount = 0; - Material mat = null; - - if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { - amount = Integer.parseInt(command.getArgAt(1)); - } - - if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { - mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - ItemStack costItem; - - if (mat == null) { - costItem = pSender.getInventory().getItemInMainHand().clone(); - } else { - costItem = new ItemStack(mat, 1); - } - - if (costItem.getType() == Material.AIR) { - Message.HELD_EMPTY.sendMessage(pSender); - return; - } - - if (isIllegal(IllegalItemList.TradeItemType.COST, costItem.getType())) { - Message.ILLEGAL_ITEM.sendMessage(pSender); - return; - } - - if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && costItem.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { - Message.NO_SHULKER_COST.sendMessage(pSender); - return; - } - - if (amount > 0) { - costItem.setAmount(amount); - } - - if (Math.ceil((double) costItem.getAmount() / (double) costItem.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { - Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), "cost")); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.SET_COST, new ObjectHolder(costItem)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.setCost(costItem); - - Message.ITEM_ADDED.sendMessage(pSender); - } - - /** - * Adds a cost to a Shop - *

- * With no variables sent will use the amount and data of the held item for cost - *

- *

- * If the player uses a int in the first variable they can change the amount for the item they are holding - *

- *

- * With 2 variables used the player can use an amount and material to set the sign instead of a held item - *

- */ - public void addCost() { - Shop shop = findShop(); - - if (shop == null) - return; - - int amount = 0; - Material mat = null; - - if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { - amount = Integer.parseInt(command.getArgAt(1)); - } - - if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { - mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - ItemStack itemInHand; - - if (mat == null) { - itemInHand = pSender.getInventory().getItemInMainHand().clone(); - } else { - itemInHand = new ItemStack(mat, 1); - } - - if (itemInHand.getType() == Material.AIR) { - Message.HELD_EMPTY.sendMessage(pSender); - return; - } - - if (isIllegal(IllegalItemList.TradeItemType.COST, itemInHand.getType())) { - Message.ILLEGAL_ITEM.sendMessage(pSender); - return; - } - - if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && itemInHand.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { - Message.NO_SHULKER_COST.sendMessage(pSender); - return; - } - - if (amount > 0) { - itemInHand.setAmount(amount); - } - - if (shop.getCost().size() + Math.ceil((double) itemInHand.getAmount() / (double) itemInHand.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { - Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), "cost")); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.ADD_COST, new ObjectHolder(itemInHand)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.addCost(itemInHand); - - Message.ITEM_ADDED.sendMessage(pSender); - } - - /** - * Sets the shop to the open status allowing trades to happen - */ - public void open() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) || - shop.getManagersUUID().contains(pSender.getUniqueId()) || - Permissions.isAdminEnabled(pSender))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - PlayerShopOpenEvent event = new PlayerShopOpenEvent(pSender, shop); - if (event.isCancelled()) return; - - ShopStatus status = shop.setOpen(); - - switch (status) { - case OPEN: - Message.CHANGE_OPEN.sendMessage(pSender); - break; - case INCOMPLETE: - if (shop.isMissingItems()) - Message.MISSING_ITEM.sendMessage(pSender); - else if (shop.getChestAsSC() == null) - Message.MISSING_CHEST.sendMessage(pSender); - break; - case OUT_OF_STOCK: - Message.SHOP_EMPTY.sendMessage(pSender); - break; - } - } - - /** - * Sets the shop to the close status preventing trades from happen - */ - public void close() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) || - shop.getManagersUUID().contains(pSender.getUniqueId()) || - Permissions.isAdminEnabled(pSender))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - PlayerShopCloseEvent event = new PlayerShopCloseEvent(pSender, shop); - if (event.isCancelled()) return; - - shop.setStatus(ShopStatus.CLOSED); - shop.updateSign(); - shop.saveShop(); - - Message.CHANGE_CLOSED.sendMessage(pSender); - } - - /** - * Switches the shop type between BiTrade and Trade - */ - public void switchShop() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!Permissions.hasPermission(pSender, Permissions.EDIT)) { - Message.NO_COMMAND_PERMISSION.sendMessage(pSender); - return; - } - - switch (shop.getShopType()) { - case TRADE: - if (!Permissions.hasPermission(pSender, Permissions.CREATEBI)) { - Message.NO_COMMAND_PERMISSION.sendMessage(pSender); - return; - } - case BITRADE: - if (!Permissions.hasPermission(pSender, Permissions.CREATE)) { - Message.NO_COMMAND_PERMISSION.sendMessage(pSender); - return; - } - } - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || shop.getManagersUUID().contains(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - shop.switchType(); - - Message.SHOP_TYPE_SWITCHED.sendMessage(pSender, new Tuple<>(Variable.NEW_TYPE.toString(), shop.getShopType().toHeader())); - } - - /** - * Tells the player who the Owner/Managers/Members that are on the shop are - */ - public void who() { - String owner = ""; - StringBuilder managers = new StringBuilder(); - StringBuilder members = new StringBuilder(); - Shop shop = findShop(); - - if (shop == null) - return; - - if (shop.getShopType().isITrade()) { - Message.WHO_MESSAGE.sendMessage(pSender, - new Tuple<>(Variable.OWNER.toString(), Setting.ITRADESHOP_OWNER.getString()), - new Tuple<>(Variable.MANAGERS.toString(), "None"), - new Tuple<>(Variable.MEMBERS.toString(), "None")); - return; - } - - if (shop.getOwner() != null) - owner = shop.getOwner().getName(); - - if (shop.getManagers().size() > 0) { - for (ShopUser usr : shop.getManagers()) { - if (managers.toString().equals("")) - managers = new StringBuilder(usr.getName()); - else - managers.append(", ").append(usr.getName()); - } - } - - if (shop.getMembers().size() > 0) { - for (ShopUser usr : shop.getMembers()) { - if (members.toString().equals("")) - members = new StringBuilder(usr.getName()); - else - members.append(", ").append(usr.getName()); - } - } - - if (managers.toString().equals("")) { - managers = new StringBuilder("None"); - } - if (members.toString().equals("")) { - members = new StringBuilder("None"); - } - Message.WHO_MESSAGE.sendMessage(pSender, - new Tuple<>(Variable.OWNER.toString(), owner), - new Tuple<>(Variable.MANAGERS.toString(), managers.toString()), - new Tuple<>(Variable.MEMBERS.toString(), members.toString())); - } - - /** - * Adds the specified player to the shop as a manager - */ - public void addManager() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - OfflinePlayer target = Bukkit.getOfflinePlayer(command.getArgAt(1)); - if (!target.hasPlayedBefore()) { - Message.PLAYER_NOT_FOUND.sendMessage(pSender); - return; - } - - if (shop.getUsersUUID().contains(target.getUniqueId())) { - Message.UNSUCCESSFUL_SHOP_MEMBERS.sendMessage(pSender); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.ADD_MANAGER, new ObjectHolder(target)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.addManager(target.getUniqueId()); - - Message.UPDATED_SHOP_MEMBERS.sendMessage(pSender); - } - - /** - * Removes the specified player from the shop if they currently are a manager - */ - public void removeUser() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - OfflinePlayer target = Bukkit.getOfflinePlayer(command.getArgAt(1)); - if (!target.hasPlayedBefore()) { - Message.PLAYER_NOT_FOUND.sendMessage(pSender); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.REMOVE_USER, new ObjectHolder(target)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - if (!shop.removeUser(target.getUniqueId())) { - Message.UNSUCCESSFUL_SHOP_MEMBERS.sendMessage(pSender); - return; - } - - Message.UPDATED_SHOP_MEMBERS.sendMessage(pSender); - } - - /** - * Adds the specified player to the shop as a member - */ - public void addMember() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!shop.getOwner().getUUID().equals(pSender.getUniqueId()) - || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender))) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - OfflinePlayer target = Bukkit.getOfflinePlayer(command.getArgAt(1)); - if (!target.hasPlayedBefore()) { - Message.PLAYER_NOT_FOUND.sendMessage(pSender); - return; - } - - - if (shop.getUsersUUID().contains(target.getUniqueId())) { - Message.UNSUCCESSFUL_SHOP_MEMBERS.sendMessage(pSender); - return; - } - - PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.ADD_MEMBER, new ObjectHolder(target)); - Bukkit.getPluginManager().callEvent(changeEvent); - if (changeEvent.isCancelled()) return; - - shop.addMember(target.getUniqueId()); - - Message.UPDATED_SHOP_MEMBERS.sendMessage(pSender); - } - - /** - * Changes the players trade multiplier for current login - */ - public void multi() { - if (!Setting.ALLOW_MULTI_TRADE.getBoolean()) { - Message.FEATURE_DISABLED.sendMessage(pSender); - return; - } - - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); - - if (command.argsSize() == 1) { - Message.MULTI_AMOUNT.sendMessage(pSender, new Tuple<>(Variable.AMOUNT.toString(), String.valueOf(playerSetting.getMulti()))); - } else { - int amount = Setting.MULTI_TRADE_DEFAULT.getInt(); - - if (isInt(command.getArgAt(1))) - amount = Integer.parseInt(command.getArgAt(1)); - - if (amount < 2) - amount = 2; - else if (amount > Setting.MULTI_TRADE_MAX.getInt()) - amount = Setting.MULTI_TRADE_MAX.getInt(); - - playerSetting.setMulti(amount); - plugin.getDataStorage().savePlayer(playerSetting); - - Message.MULTI_UPDATE.sendMessage(pSender, new Tuple<>(Variable.AMOUNT.toString(), String.valueOf(amount))); - } - } - - /** - * Changes the players with the ADMIN permission to toggle whether it is enabled for them - */ - public void toggleAdmin() { - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); - - playerSetting.setAdminEnabled(!playerSetting.isAdminEnabled()); - plugin.getDataStorage().savePlayer(playerSetting); - - Message.ADMIN_TOGGLED.sendMessage(pSender, new Tuple<>(Variable.STATE.toString(), playerSetting.isAdminEnabled() ? "enabled" : "disabled")); - } - - /** - * Shows players their current admin mode or changes with optional variable - */ - public void admin() { - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); - boolean initialValue = playerSetting.isAdminEnabled(); - - if (command.hasArgAt(1)) { - - switch (command.getArgAt(1).toLowerCase()) { - case "true": - case "t": - playerSetting.setAdminEnabled(true); - break; - case "false": - case "f": - playerSetting.setAdminEnabled(false); - break; - } - - if (initialValue != playerSetting.isAdminEnabled()) - plugin.getDataStorage().savePlayer(playerSetting); - } - - Message.ADMIN_TOGGLED.sendMessage(pSender, new Tuple<>(Variable.STATE.toString(), playerSetting.isAdminEnabled() ? "enabled" : "disabled")); - } - - /** - * Toggles the join status message for the player - */ - public void toggleStatus() { - if (!Setting.ALLOW_TOGGLE_STATUS.getBoolean()) { - Message.FEATURE_DISABLED.sendMessage(pSender); - return; - } - - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); - playerSetting.setShowInvolvedStatus(!playerSetting.showInvolvedStatus()); - plugin.getDataStorage().savePlayer(playerSetting); - Message.TOGGLED_STATUS.sendMessage(pSender, new Tuple<>(Variable.STATUS.toString(), playerSetting.showInvolvedStatus() ? "on" : "off")); - } - - /** - * Create a regular shop from a sign in front of the player - */ - public void createTrade() { - Sign sign = findSign(); - - if (sign == null) - return; - - createShop(sign, ShopType.TRADE); - } - - /** - * Create a BiTrade shop from a sign in front of the player - */ - public void createBiTrade() { - Sign sign = findSign(); - - if (sign == null) - return; - - createShop(sign, ShopType.BITRADE); - } - - /** - * Create a iTrade shop from a sign in front of the player - */ - public void createITrade() { - Sign sign = findSign(); - - if (sign == null) - return; - - createShop(sign, ShopType.ITRADE); - } - - - /** - * Create a shop from a non-shop sign in front of the player - * - * @param shopSign sign to make into a shop - * @param shopType type of shop to make - */ - private void createShop(Sign shopSign, ShopType shopType) { - if (ShopType.isShop(shopSign)) { - Message.EXISTING_SHOP.sendMessage(pSender); - return; - } - - ShopUser owner = new ShopUser(pSender, ShopRole.OWNER); - - if (!checkShopChest(shopSign.getBlock()) && !shopType.isITrade()) { - Message.NO_CHEST.sendMessage(pSender); - return; - } - - if (Setting.MAX_SHOPS_PER_CHUNK.getInt() <= plugin.getDataStorage().getShopCountInChunk(shopSign.getChunk())) { - Message.TOO_MANY_CHESTS.sendMessage(pSender); - return; - } - - ShopChest shopChest; - Shop shop; - Block chest = findShopChest(shopSign.getBlock()); - - if (!shopType.isITrade()) { - if (ShopChest.isShopChest(chest)) { - shopChest = new ShopChest(chest.getLocation()); - } else { - shopChest = new ShopChest(chest, pSender.getUniqueId(), shopSign.getLocation()); - } - - if (shopChest.hasOwner() && !shopChest.getOwner().equals(owner.getUUID())) { - Message.NO_SHOP_PERMISSION.sendMessage(pSender); - return; - } - - if (shopChest.hasShopSign() && !shopChest.getShopSign().getLocation().equals(shopSign.getLocation())) { - Message.EXISTING_SHOP.sendMessage(pSender); - return; - } - - shop = new Shop(new Tuple<>(shopSign.getLocation(), shopChest.getChest().getLocation()), shopType, owner); - shopChest.setName(); - - - if (shopChest.isEmpty() && shop.hasProduct()) { - Message.EMPTY_TS_ON_SETUP.sendMessage(pSender); - } - } else { - shop = new Shop(shopSign.getLocation(), shopType, owner); - } - - PlayerShopCreateEvent shopCreateEvent = new PlayerShopCreateEvent(pSender, shop); - Bukkit.getPluginManager().callEvent(shopCreateEvent); - if (shopCreateEvent.isCancelled()) { - return; - } - - shopSign.setLine(0, shopType.toHeader()); - shopSign.update(); - - shop.saveShop(); - - Message.SUCCESSFUL_SETUP.sendMessage(pSender); - } - - /** - * Changes/Sets the players permission level if internal permissions is enabled - */ - public void playerLevel() { - if (Bukkit.getOfflinePlayer(command.getArgAt(1)).hasPlayedBefore()) { - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(Bukkit.getOfflinePlayer(command.getArgAt(1)).getUniqueId()); - if (command.argsSize() == 2) { - Message.VIEW_PLAYER_LEVEL.sendMessage(pSender, - new Tuple<>(Variable.PLAYER.toString(), Bukkit.getOfflinePlayer(command.getArgAt(1)).getName()), - new Tuple<>(Variable.LEVEL.toString(), playerSetting.getType() + "")); - } else { - if (isInt(command.getArgAt(2))) { - int newLevel = Integer.parseInt(command.getArgAt(2)); - - playerSetting.setType(newLevel); - plugin.getDataStorage().savePlayer(playerSetting); - - Message.SET_PLAYER_LEVEL.sendMessage(pSender, - new Tuple<>(Variable.PLAYER.toString(), Bukkit.getOfflinePlayer(command.getArgAt(1)).getName()), - new Tuple<>(Variable.LEVEL.toString(), playerSetting.getType() + "")); - } else { - Message.INVALID_ARGUMENTS.sendMessage(pSender); - } - } - } else { - Message.PLAYER_NOT_FOUND.sendMessage(pSender); - } - } - - /** - * Shows the player the status of all shops they are involved with or the specified player is involved with - */ - public void status() { - if (command.hasArgAt(1)) { - if (!Permissions.isAdminEnabled(pSender)) { - Message.NO_COMMAND_PERMISSION.sendMessage(pSender); - return; - } - if (Bukkit.getOfflinePlayer(command.getArgAt(1)).hasPlayedBefore()) { - plugin.getDataStorage().loadPlayer(Bukkit.getOfflinePlayer(command.getArgAt(1)).getUniqueId()) - .getInvolvedStatusesInventory().show(pSender.getPlayer()); - } else { - Message.PLAYER_NOT_FOUND.sendMessage(pSender); - } - } else { - plugin.getDataStorage().loadPlayer(pSender.getUniqueId()).getInvolvedStatusesInventory().show(pSender.getPlayer()); - } - } - - /** - * Returns the Shop the player is looking at - * - * @return null if Shop is not found, Shop object if it is - */ - protected Shop findShop() { - if (pSender == null) { - Message.PLAYER_ONLY_COMMAND.sendMessage(pSender); - return null; - } - - Block b = pSender.getTargetBlockExact(Setting.MAX_EDIT_DISTANCE.getInt()); - try { - if (b == null) - throw new NoSuchFieldException(); - - if (ShopType.isShop(b)) { - return Shop.loadShop((Sign) b.getState()); - - } else if (ShopChest.isShopChest(b)) { - if (plugin.getDataStorage().getChestLinkage(new ShopLocation(b.getLocation())) != null) - return plugin.getDataStorage().loadShopFromStorage(new ShopLocation(b.getLocation())); - - return Shop.loadShop(new ShopChest(b.getLocation()).getShopSign()); - - } else - throw new NoSuchFieldException(); - - } catch (NoSuchFieldException ex) { - Message.NO_SIGHTED_SHOP.sendMessage(pSender); - return null; - } - } - - /** - * Returns the Sign the player is looking at - * - * @return null if Sign is not found, Sign object if it is - */ - protected Sign findSign() { - if (pSender == null) { - Message.PLAYER_ONLY_COMMAND.sendMessage(pSender); - return null; - } - - Block b = pSender.getTargetBlockExact(Setting.MAX_EDIT_DISTANCE.getInt()); - try { - if (b == null) - throw new NoSuchFieldException(); - - if (plugin.getSigns().getSignTypes().contains(b.getType())) { - return (Sign) b.getState(); - - } else - throw new NoSuchFieldException(); - - } catch (NoSuchFieldException ex) { - Message.NO_SIGN_FOUND.sendMessage(pSender); - return null; - } - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/commands/CommandTabCaller.java b/src/main/java/org/shanerx/tradeshop/commands/CommandTabCaller.java index a788afa9..509636d0 100644 --- a/src/main/java/org/shanerx/tradeshop/commands/CommandTabCaller.java +++ b/src/main/java/org/shanerx/tradeshop/commands/CommandTabCaller.java @@ -29,7 +29,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.utils.config.Message; +import org.shanerx.tradeshop.data.config.Message; import java.util.ArrayList; import java.util.Collections; @@ -75,7 +75,8 @@ public List onTabComplete(CommandSender sender, Command cmd, String labe return tabCompleter.fillShopPlayer(); case ADD_MANAGER: case ADD_MEMBER: - case PLAYER_LEVEL: + case SET_MEMBER: + case SET_MANAGER: return tabCompleter.fillServerPlayer(); default: return Collections.EMPTY_LIST; diff --git a/src/main/java/org/shanerx/tradeshop/commands/CommandTabCompleter.java b/src/main/java/org/shanerx/tradeshop/commands/CommandTabCompleter.java index 51baaa01..7e9e513f 100644 --- a/src/main/java/org/shanerx/tradeshop/commands/CommandTabCompleter.java +++ b/src/main/java/org/shanerx/tradeshop/commands/CommandTabCompleter.java @@ -29,10 +29,11 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopType; import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Setting; import java.util.ArrayList; import java.util.Arrays; @@ -99,7 +100,7 @@ public List fillShopPlayer() { } Shop shop = Shop.loadShop(s); - return shop.getUserNames(); + return shop.getUserNames(ShopRole.MANAGER, ShopRole.MEMBER); } return Collections.EMPTY_LIST; diff --git a/src/main/java/org/shanerx/tradeshop/commands/Commands.java b/src/main/java/org/shanerx/tradeshop/commands/Commands.java index 718aab30..67b78cb5 100644 --- a/src/main/java/org/shanerx/tradeshop/commands/Commands.java +++ b/src/main/java/org/shanerx/tradeshop/commands/Commands.java @@ -28,8 +28,8 @@ import com.google.common.collect.Lists; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.shanerx.tradeshop.enumys.PermStatus; -import org.shanerx.tradeshop.enumys.Permissions; +import org.shanerx.tradeshop.player.PermStatus; +import org.shanerx.tradeshop.player.Permissions; import java.util.List; @@ -52,17 +52,19 @@ public enum Commands { CREATE_ITRADE(Lists.newArrayList("createitrade", "createi", "cri"), Permissions.CREATEI, 1, 1, true, "Create iTrade shop", "/tradeshop $cmd$"), // Shop user management commands - ADD_MANAGER(Lists.newArrayList("addManager"), Permissions.NONE, 2, 2, true, "Add manager to shop", "/tradeshop $cmd$ "), - REMOVE_USER(Lists.newArrayList("removeUser", "removeManager", "removeMember"), Permissions.NONE, 2, 2, true, "Remove user from shop", "/tradeshop $cmd$ "), - ADD_MEMBER(Lists.newArrayList("addMember"), Permissions.NONE, 2, 2, true, "Add member to shop", "/tradeshop $cmd$ "), + REMOVE_USER(Lists.newArrayList("removeUser", "removeManager", "removeMember"), Permissions.NONE, 2, 3, true, "Remove user from shop", "/tradeshop $cmd$ [all shops]"), + ADD_MANAGER(Lists.newArrayList("addManager"), Permissions.NONE, 2, 3, true, "Add manager to shop", "/tradeshop $cmd$ [all shops]"), + ADD_MEMBER(Lists.newArrayList("addMember"), Permissions.NONE, 2, 3, true, "Add member to shop", "/tradeshop $cmd$ [all shops]"), + SET_MANAGER(Lists.newArrayList("setManager"), Permissions.NONE, 2, 3, true, "Sets a player to Manager on a shop", "/tradeshop $cmd$ [all shops]"), + SET_MEMBER(Lists.newArrayList("setMember"), Permissions.NONE, 2, 3, true, "Sets a player to Member on a shop", "/tradeshop $cmd$ [all shops]"), // Shop item management commands ADD_PRODUCT(Lists.newArrayList("addProduct"), Permissions.NONE, 1, 3, true, "Add product to shop", "/tradeshop $cmd$ [Amount] [Material]"), ADD_COST(Lists.newArrayList("addCost"), Permissions.NONE, 1, 3, true, "Add cost to shop", "/tradeshop $cmd$ [Amount] [Material]"), SET_PRODUCT(Lists.newArrayList("setProduct"), Permissions.NONE, 1, 3, true, "Set product of shop ", "/tradeshop $cmd$ [Amount] [Material]"), SET_COST(Lists.newArrayList("setCost"), Permissions.NONE, 1, 3, true, "Set cost of shop", "/tradeshop $cmd$ [Amount] [Material]"), - REMOVE_PRODUCT(Lists.newArrayList("removeProduct", "delProduct"), Permissions.NONE, 2, 2, true, "Removes a product from the shop", "/tradeshop $cmd$ "), - REMOVE_COST(Lists.newArrayList("removeCost", "delCost"), Permissions.NONE, 2, 2, true, "Removes a product from the shop", "/tradeshop $cmd$ "), + REMOVE_PRODUCT(Lists.newArrayList("removeProduct", "delProduct"), Permissions.NONE, 1, 2, true, "Removes a product from the shop", "/tradeshop $cmd$ "), + REMOVE_COST(Lists.newArrayList("removeCost", "delCost"), Permissions.NONE, 1, 2, true, "Removes a product from the shop", "/tradeshop $cmd$ "), LIST_PRODUCT(Lists.newArrayList("listProduct"), Permissions.NONE, 1, 1, true, "Lists the products in the shop", "/tradeshop $cmd$"), LIST_COST(Lists.newArrayList("listCost"), Permissions.NONE, 1, 1, true, "Lists the costs in a shop", "/tradeshop $cmd$"), @@ -77,7 +79,6 @@ public enum Commands { HELP(Lists.newArrayList("help", "?"), Permissions.HELP, 1, 2, false, "Display help message", "/tradeshop $cmd$ [command]"), SETUP(Lists.newArrayList("setup", "start", "create", "make"), Permissions.HELP, 1, 1, false, "Display shop setup tutorial", "/tradeshop $cmd$"), BUGS(Lists.newArrayList("bugs", "bug"), Permissions.NONE, 1, 1, false, "Report bugs to the developers", "/tradeshop $cmd$"), - PLAYER_LEVEL(Lists.newArrayList("playerlevel", "pl"), Permissions.MANAGE_PLUGIN, 2, 3, false, "If Internal Permissions is enable this allows the getting and setting of player permission levels.", "/tradeshop $cmd$ "), TOGGLE_ADMIN(Lists.newArrayList("toggleadmin", "tadmin", "ta"), Permissions.ADMIN, 1, 1, true, "Toggles Admin mode for players with the admin permission", "/tradeshop $cmd$"), ADMIN(Lists.newArrayList("admin"), Permissions.ADMIN, 1, 2, true, "Shows players their current admin mode or changes with optional variable", "/tradeshop $cmd$ [True/False]"), RELOAD(Lists.newArrayList("reload"), Permissions.MANAGE_PLUGIN, 1, 1, false, "Reload configuration files", "/tradeshop $cmd$"); diff --git a/src/main/java/org/shanerx/tradeshop/commands/EditCommand.java b/src/main/java/org/shanerx/tradeshop/commands/EditCommand.java deleted file mode 100644 index 69b33035..00000000 --- a/src/main/java/org/shanerx/tradeshop/commands/EditCommand.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.commands; - -import com.google.common.collect.Iterables; -import de.themoep.inventorygui.GuiElementGroup; -import de.themoep.inventorygui.GuiStateElement; -import de.themoep.inventorygui.InventoryGui; -import de.themoep.inventorygui.StaticGuiElement; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.FireworkMeta; -import org.bukkit.inventory.meta.ItemMeta; -import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.enumys.ShopItemStackSettingKeys; -import org.shanerx.tradeshop.enumys.ShopRole; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.objects.ShopUser; -import org.shanerx.tradeshop.utils.ObjectHolder; -import org.shanerx.tradeshop.utils.config.Message; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class EditCommand extends CommandRunner { - - private Shop shop; - private InventoryGui mainMenu, - userEdit, - costEdit, - productEdit; - private List costItems, - productItems; - private List costItemsRemoval, - productItemsRemoval; - public final ItemStack TRUE_ITEM = new ItemStack(Material.EMERALD_BLOCK); - public final ItemStack FALSE_ITEM = new ItemStack(Material.REDSTONE_BLOCK); - - - public EditCommand(TradeShop instance, CommandPass command) { - super(instance, command); - } - - /** - * Opens a GUI allowing the player to edit the shop - */ - public void edit() { - shop = findShop(); - - if (shop == null) - return; - - if (!(shop.getOwner().getUUID().equals(pSender.getUniqueId()) || - shop.getManagersUUID().contains(pSender.getUniqueId()) || - Permissions.isAdminEnabled(pSender))) { - command.sendMessage(Message.NO_SHOP_PERMISSION.getPrefixed()); - return; - } - - mainMenu = new InventoryGui(plugin, "Edit Menu-" + shop.getShopLocationAsSL().serialize(), MENU_LAYOUT); - - mainMenu.setFiller(new ItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE, 1)); - - // ShopUser edit menu, currently can only change/remove. Adding only available through commands - mainMenu.addElement(new StaticGuiElement('a', new ItemStack(Material.PLAYER_HEAD), click -> { - userEdit = new InventoryGui(plugin, "Edit Users", EDIT_LAYOUT); - Set shopUsers = new HashSet<>(); - GuiElementGroup userGroup = new GuiElementGroup('g'); - - // Previous page - userEdit.addElement(PREV_BUTTON); - - // Next page - userEdit.addElement(NEXT_BUTTON); - - // Cancel and Back - userEdit.addElement(CANCEL_BUTTON); - - userEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.BLUE_STAINED_GLASS_PANE), " ")); - - // Owner added separately as it is not editable - userGroup.addElement(new StaticGuiElement('e', shop.getOwner().getHead(), shop.getOwner().getName(), "Position: " + shop.getOwner().getRole().toString())); - - if (shop.getOwner().getUUID().equals(pSender.getUniqueId())) { - - // Save and Back - userEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { - shop.updateShopUsers(shopUsers); - InventoryGui.goBack(pSender); - return true; - }, "Save Changes")); - - for (ShopUser user : Iterables.concat(shop.getManagers(), shop.getMembers())) { - shopUsers.add(user); - userGroup.addElement(new GuiStateElement('e', - user.getRole().toString(), - new GuiStateElement.State(change -> { - shopUsers.remove(user); - user.setRole(ShopRole.MANAGER); - shopUsers.add(user); - }, - "MANAGER", - user.getHead(), - user.getName(), - "Position: MANAGER", - "Click here to change to Member."), - new GuiStateElement.State(change -> { - shopUsers.remove(user); - user.setRole(ShopRole.MEMBER); - shopUsers.add(user); - }, - "MEMBER", - user.getHead(), - user.getName(), - "Position: MEMBER", - "Click here to remove this player."), - new GuiStateElement.State(change -> { - shopUsers.remove(user); - user.setRole(ShopRole.SHOPPER); - shopUsers.add(user); - }, - "SHOPPER", - new ItemStack(Material.BARRIER), - user.getName(), - "Position: NONE", - "Click here to add the player as a Manager.") - )); - - } - } else { - for (ShopUser user : Iterables.concat(shop.getManagers(), shop.getMembers())) { - userGroup.addElement(new StaticGuiElement('e', user.getHead(), user.getName(), "Position: " + user.getRole().toString())); - } - } - userEdit.addElement(userGroup); - userEdit.show(pSender); - return true; - }, "Edit Shop Users")); - - mainMenu.addElement(new StaticGuiElement('b', new ItemStack(Material.GOLD_NUGGET), click -> { - costEdit = new InventoryGui(plugin, "Edit Costs", EDIT_LAYOUT); - costItems = new ArrayList<>(); - costItemsRemoval = new ArrayList<>(); - for (ShopItemStack item : shop.getCost()) { - costItems.add(item.clone()); - costItemsRemoval.add(false); - } - GuiElementGroup costGroup = new GuiElementGroup('g'); - - // Previous page - costEdit.addElement(PREV_BUTTON); - - // Next page - costEdit.addElement(NEXT_BUTTON); - - // Cancel and Back - costEdit.addElement(CANCEL_BUTTON); - - // Save and Back - costEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { - for (int i = costItems.size() - 1; i >= 0; i--) { - if (costItemsRemoval.get(i)) - costItems.remove(i); - } - shop.updateCost(costItems); - InventoryGui.goBack(pSender); - return true; - }, "Save Changes")); - - costEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); - - for (int i = 0; i < costItems.size(); i++) { - costGroup.addElement(shopItemEditMenu(i, true)); - } - - costEdit.addElement(costGroup); - costEdit.show(pSender); - return true; - }, "Edit Shop Costs")); - - mainMenu.addElement(new StaticGuiElement('c', new ItemStack(Material.GRASS_BLOCK), click -> { - productEdit = new InventoryGui(plugin, "Edit Products", EDIT_LAYOUT); - productItems = new ArrayList<>(); - productItemsRemoval = new ArrayList<>(); - for (ShopItemStack item : shop.getProduct()) { - productItems.add(item.clone()); - productItemsRemoval.add(false); - } - GuiElementGroup productGroup = new GuiElementGroup('g'); - - // Previous page - productEdit.addElement(PREV_BUTTON); - - // Next page - productEdit.addElement(NEXT_BUTTON); - - // Cancel and Back - productEdit.addElement(CANCEL_BUTTON); - - // Save and Back - productEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { - for (int i = productItems.size() - 1; i >= 0; i--) { - if (productItemsRemoval.get(i)) - productItems.remove(i); - } - shop.updateProduct(productItems); - InventoryGui.goBack(pSender); - return true; - }, "Save Changes")); - - productEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); - - for (int i = 0; i < productItems.size(); i++) { - productGroup.addElement(shopItemEditMenu(i, false)); - } - - productEdit.addElement(productGroup); - productEdit.show(pSender); - return true; - }, "Edit Shop Products")); - - mainMenu.show(pSender); - } - - private StaticGuiElement shopItemEditMenu(int index, boolean isCost) { - ShopItemStack item = (isCost ? costItems : productItems).get(index).clone(); - ItemStack tempStack = item.getItemStack(); - ItemMeta tempMeta = tempStack.getItemMeta(); - List newLore = new ArrayList<>(); - newLore.add(colorize("&8Amount &7» &f" + item.getAmount())); - - if (tempMeta != null && tempMeta.hasLore()) { - newLore.add(""); - newLore.addAll(tempMeta.getLore()); - } - - tempMeta.setLore(newLore); - tempStack.setItemMeta(tempMeta); - - return new StaticGuiElement('e', tempStack, click2 -> { - InventoryGui itemEdit = new InventoryGui(plugin, "Edit Cost Item", ITEM_LAYOUT); - GuiElementGroup itemGroup = new GuiElementGroup('g'); - - // Cancel and Back - itemEdit.addElement(CANCEL_BUTTON); - - // Save and Back - itemEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { - (isCost ? costItems : productItems).set(index, item); - InventoryGui.goBack(pSender); - return true; - }, "Save Changes")); - - itemEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); - - itemGroup.addElement(new GuiStateElement('e', - (isCost ? costItemsRemoval : productItemsRemoval).get(index) + "", - new GuiStateElement.State(change -> (isCost ? costItemsRemoval : productItemsRemoval).set(index, true), - "true", - new ItemStack(Material.BARRIER), - item.getItemName()), - new GuiStateElement.State(change -> (isCost ? costItemsRemoval : productItemsRemoval).set(index, false), - "false", - item.getItemStack()) - - )); - - //Add new item settings below - if (item.getItemStack().getItemMeta() instanceof Damageable) { - itemGroup.addElement(numericalOption(ShopItemStackSettingKeys.COMPARE_DURABILITY, item, new ItemStack[]{ - FALSE_ITEM, new ItemStack(Material.IRON_BLOCK), TRUE_ITEM, new ItemStack(Material.GOLD_BLOCK) - })); - } - - if (tempMeta instanceof BookMeta) { - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES, item, TRUE_ITEM, FALSE_ITEM)); - } - - if (tempMeta instanceof FireworkMeta) { - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_FIREWORK_DURATION, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_FIREWORK_EFFECTS, item, TRUE_ITEM, FALSE_ITEM)); - } - - if (tempStack.getType().toString().endsWith("SHULKER_BOX")) { - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY, item, TRUE_ITEM, FALSE_ITEM)); - } - - if (plugin.getVersion().isAtLeast(1, 17) && tempStack.getType().equals(Material.BUNDLE)) { - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BUNDLE_INVENTORY, item, TRUE_ITEM, FALSE_ITEM)); - } - - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_NAME, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_LORE, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA, item, TRUE_ITEM, FALSE_ITEM)); - itemGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER, item, TRUE_ITEM, FALSE_ITEM)); - - - itemEdit.addElement(itemGroup); - itemEdit.show(pSender); - return true; - }); - } - - private GuiStateElement numericalOption(ShopItemStackSettingKeys setting, ShopItemStack tempItem, ItemStack[] indexedTempItem) { - - return new GuiStateElement('e', - String.valueOf(tempItem.getShopSettingAsInteger(setting)), - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(2)); - }, - "2", - indexedTempItem[3], - setting.makeReadable(), - "State: >="), - - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(-1)); - }, - "-1", - indexedTempItem[0], - setting.makeReadable(), - "State: False"), - - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(0)); - }, - "0", - indexedTempItem[1], - setting.makeReadable(), - "State: <="), - - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(1)); - }, - "1", - indexedTempItem[2], - setting.makeReadable(), - "State: ==" - - )); - } - - private GuiStateElement booleanOption(ShopItemStackSettingKeys setting, ShopItemStack tempItem, ItemStack trueTempItem, ItemStack falseTempItem) { - return new GuiStateElement('e', - String.valueOf(tempItem.getShopSettingAsBoolean(setting)), - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(true)); - }, - "true", - trueTempItem, - setting.makeReadable(), - "State: True"), - new GuiStateElement.State(change -> { - tempItem.setShopSettings(setting, new ObjectHolder<>(false)); - }, - "false", - falseTempItem, - setting.makeReadable(), - "State: False" - )); - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/commands/WhatCommand.java b/src/main/java/org/shanerx/tradeshop/commands/WhatCommand.java deleted file mode 100644 index 6710e681..00000000 --- a/src/main/java/org/shanerx/tradeshop/commands/WhatCommand.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.commands; - -import de.themoep.inventorygui.GuiElementGroup; -import de.themoep.inventorygui.InventoryGui; -import de.themoep.inventorygui.StaticGuiElement; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.enumys.ShopItemStackSettingKeys; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; - -import java.util.ArrayList; -import java.util.List; - -public class WhatCommand extends CommandRunner { - - public WhatCommand(TradeShop instance, CommandPass command) { - super(instance, command); - } - - /** - * Opens a GUI containing the items to be traded at the shop the player is looking at - */ - public void what() { - Shop shop = findShop(); - - if (shop == null) - return; - - if (!Permissions.hasPermission(pSender, Permissions.INFO)) { - command.sendMessage(Message.NO_COMMAND_PERMISSION.getPrefixed()); - return; - } - - InventoryGui gui = new InventoryGui(plugin, colorize(shop.getShopType() == ShopType.ITRADE ? - Setting.ITRADESHOP_OWNER.getString() : - Bukkit.getOfflinePlayer(shop.getOwner().getUUID()).getName() + "'s Shop"), - WHAT_MENU); - - GuiElementGroup costGroup = new GuiElementGroup('a'), productGroup = new GuiElementGroup('b'); - - gui.setFiller(new ItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE, 1)); - - for (ShopItemStack item : shop.getCost()) { - costGroup.addElement(shopitemViewMenu(item)); - } - - for (ShopItemStack item : shop.getProduct()) { - productGroup.addElement(shopitemViewMenu(item)); - } - - gui.addElement(new StaticGuiElement('1', new ItemStack(Material.LIME_STAINED_GLASS_PANE), - " ")); - gui.addElement(new StaticGuiElement('2', new ItemStack(Material.BLACK_STAINED_GLASS_PANE), - " ")); - gui.addElement(new StaticGuiElement('3', new ItemStack(Material.LIGHT_BLUE_STAINED_GLASS_PANE), - " ")); - gui.addElement(new StaticGuiElement('4', new ItemStack(Material.GOLD_NUGGET), - "Cost", "This is the item", "that you give to", "make the trade.")); - gui.addElement(new StaticGuiElement('5', new ItemStack(Material.GRASS_BLOCK), - "Product", "This is the item", "that you receive", "from the trade.")); - gui.addElement(PREV_BUTTON); - gui.addElement(NEXT_BUTTON); - gui.addElement(costGroup); - gui.addElement(productGroup); - - gui.show(pSender); - } - - private ItemStack settingItem(boolean state) { - return state ? new ItemStack(Material.EMERALD_BLOCK) : new ItemStack(Material.REDSTONE_BLOCK); - } - - private ItemStack settingItem(int state) { - switch (state) { - case -1: - return new ItemStack(Material.REDSTONE_BLOCK); - case 0: - return new ItemStack(Material.IRON_BLOCK); - case 1: - default: - return new ItemStack(Material.EMERALD_BLOCK); - case 2: - return new ItemStack(Material.GOLD_BLOCK); - } - } - - private String stateText(int state) { - switch (state) { - case -1: - return "False"; - case 0: - return "<="; - case 1: - default: - return "=="; - case 2: - return ">="; - } - } - - private StaticGuiElement shopitemViewMenu(ShopItemStack item) { - ItemStack tempStack = item.getItemStack().clone(); - ItemMeta tempMeta = tempStack.getItemMeta(); - List newLore = new ArrayList<>(); - newLore.add("Amount: " + item.getAmount()); - - if (tempMeta != null && tempMeta.hasLore()) { - newLore.add(""); - newLore.addAll(tempMeta.getLore()); - } - - tempMeta.setLore(newLore); - tempStack.setItemMeta(tempMeta); - return new StaticGuiElement('e', tempStack, click2 -> { - InventoryGui itemView = new InventoryGui(plugin, "Edit Cost Item", ITEM_LAYOUT); - GuiElementGroup itemGroup = new GuiElementGroup('g'); - - itemView.addElement(BACK_BUTTON); - - itemView.addElement(new StaticGuiElement('a', new ItemStack(Material.BLACK_STAINED_GLASS_PANE), " ")); - - itemGroup.addElement(new StaticGuiElement('e', tempStack)); - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_NAME)), "Compare Name", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_NAME))); - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_LORE)), "Compare Lore", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_LORE))); - - if (item.getItemStack().getType().toString().endsWith("SHULKER_BOX")) { - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY)), "Compare Shulker Inventory", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY))); - } - - if (item.getItemStack().getItemMeta() instanceof Damageable) { - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsInteger(ShopItemStackSettingKeys.COMPARE_DURABILITY)), "Compare Durability", "State: " + stateText(item.getShopSettingAsInteger(ShopItemStackSettingKeys.COMPARE_DURABILITY)))); - } - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS)), "Compare Enchantments", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS))); - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE)), "Compare Unbreakable", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE))); - - if (item.getItemStack().getItemMeta() instanceof BookMeta) { - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR)), "Compare Book Author", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR))); - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES)), "Compare Book Pages", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES))); - } - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS)), "Compare Item Flags", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS))); - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA)), "Compare Custom Model Data", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA))); - - itemGroup.addElement(new StaticGuiElement('e', settingItem(item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER)), "Compare Attribute Modifier", "State: " + item.getShopSettingAsBoolean(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER))); - - itemView.addElement(itemGroup); - itemView.show(pSender); - return true; - }); - } -} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/AdminCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/AdminCommand.java new file mode 100644 index 00000000..1d1f4314 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/AdminCommand.java @@ -0,0 +1,111 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.Bukkit; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.data.storage.DataType; +import org.shanerx.tradeshop.framework.events.TradeShopReloadEvent; +import org.shanerx.tradeshop.player.PlayerSetting; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.objects.Tuple; + +/** + * Implementation of CommandRunner for commands that are used for administration purposes + * + * @since 2.6.0 + */ +public class AdminCommand extends CommandRunner { + + public AdminCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Reloads the plugin and sends success message + */ + public void reload() { + plugin.getLanguage().reload(); + plugin.getSettingManager().reload(); + plugin.getMessageManager().reload(); + plugin.getListManager().reload(); + plugin.getDebugger().reload(); + try { + plugin.getDataStorage().reload(DataType.valueOf(Setting.DATA_STORAGE_TYPE.getString().toUpperCase())); + } catch (IllegalArgumentException iae) { + PLUGIN.getDebugger().log("Config value for data storage set to an invalid value: " + Setting.DATA_STORAGE_TYPE.getString(), DebugLevels.DATA_ERROR); + PLUGIN.getDebugger().log("TradeShop will now disable...", DebugLevels.DATA_ERROR); + plugin.getServer().getPluginManager().disablePlugin(plugin); + return; + } + + command.sendMessage(Setting.MESSAGE_PREFIX.getString().trim() + "&6The configuration files have been reloaded!"); + Bukkit.getPluginManager().callEvent(new TradeShopReloadEvent(plugin, command.getSender())); + } + + /** + * Changes the players with the ADMIN permission to toggle whether it is enabled for them + */ + public void toggleAdmin() { + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); + + playerSetting.setAdminEnabled(!playerSetting.isAdminEnabled()); + plugin.getDataStorage().savePlayer(playerSetting); + + Message.ADMIN_TOGGLED.sendMessage(pSender, new Tuple<>(Variable.STATE.toString(), playerSetting.isAdminEnabled() ? "enabled" : "disabled")); + } + + /** + * Shows players their current admin mode or changes with optional variable + */ + public void admin() { + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); + boolean initialValue = playerSetting.isAdminEnabled(); + + if (command.hasArgAt(1)) { + + switch (command.getArgAt(1).toLowerCase()) { + case "true": + case "t": + playerSetting.setAdminEnabled(true); + break; + case "false": + case "f": + playerSetting.setAdminEnabled(false); + break; + } + + if (initialValue != playerSetting.isAdminEnabled()) + plugin.getDataStorage().savePlayer(playerSetting); + } + + Message.ADMIN_TOGGLED.sendMessage(pSender, new Tuple<>(Variable.STATE.toString(), playerSetting.isAdminEnabled() ? "enabled" : "disabled")); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/BasicTextCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/BasicTextCommand.java new file mode 100644 index 00000000..4f4379be --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/BasicTextCommand.java @@ -0,0 +1,103 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.commands.Commands; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.player.PermStatus; +import org.shanerx.tradeshop.utils.objects.Tuple; + +/** + * Implementation of CommandRunner for plugin commands that return basic text/info to the user + * + * @since 2.6.0 + */ +public class BasicTextCommand extends CommandRunner { + + public BasicTextCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Builds and sends the sender the help message + */ + public void help() { + if (command.argsSize() == 2) { + usage(command.getArgAt(1)); + return; + } + + StringBuilder sb = new StringBuilder(); + + sb.append("\n&2") + .append(getPluginName()) + .append(" ") + .append(getVersion()) + .append(" by ").append(pdf.getAuthors().get(0)).append(" & ").append(pdf.getAuthors().get(1)) + .append("\n\n&b/tradeshop &f &f Display help message\n"); + + for (Commands c : Commands.values()) { + if (c.checkPerm(command.getSender()) == PermStatus.GOOD) { + sb.append(plugin.getMessageManager().colour(String.format("&b/ts %s &f %s\n", c.getFirstName(), c.getDescription()))); + } + } + + sb.append("\n "); + command.sendMessage(colorize(sb.toString())); + } + + /** + * Retrieves and sends usage string to player for requested sub-command or error message if command cannot be found + * + * @param subcmd string we should search for a sub-command + */ + public void usage(String subcmd) { + Commands cmd = Commands.getType(subcmd); + if (cmd == null) { + command.sendMessage(plugin.getMessageManager().colour(String.format("&4Cannot find usages for &c%s&r", subcmd))); + return; + } + command.sendMessage(plugin.getMessageManager().colour(String.format("&6Showing help for &c%s&r\n&bUsage:&e %s \n&bAliases: %s\n&bDescription:&e %s", subcmd, cmd.getUsage(), cmd.getAliases(), cmd.getDescription()))); + } + + /** + * Sends the sender the bug message + */ + public void bugs() { + command.sendMessage("\n&a[&eTradeShop&a] \n&2To report any bugs to the author, either send a PM on &cSpigot &2- &egoo.gl/s6Jk23 &2or open an issue on &cGitHub &2-&e goo.gl/X4qqyg\n"); + } + + /** + * Sends the sender the setup message + */ + public void setup() { + Message.SETUP_HELP.sendMessage(pSender, new Tuple<>(Variable.HEADER.toString(), Setting.TRADESHOP_HEADER.getString())); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CommandRunner.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CommandRunner.java new file mode 100644 index 00000000..030d5220 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CommandRunner.java @@ -0,0 +1,95 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopChest; +import org.shanerx.tradeshop.shop.ShopType; +import org.shanerx.tradeshop.shoplocation.ShopLocation; +import org.shanerx.tradeshop.utils.Utils; + +public class CommandRunner extends Utils { + + protected final TradeShop plugin; + protected final CommandPass command; + protected Player pSender; + + public CommandRunner(TradeShop instance, CommandPass command) { + this.plugin = instance; + this.command = command; + + if (command.getSender() instanceof Player) { + pSender = (Player) command.getSender(); + } + } + + + //region Util Methods + //------------------------------------------------------------------------------------------------------------------ + + /** + * Returns the Shop the player is looking at + * + * @return null if Shop is not found, Shop object if it is + */ + protected Shop findShop() { + if (pSender == null) { + return null; + } + + Block b = pSender.getTargetBlockExact(Setting.MAX_EDIT_DISTANCE.getInt()); + try { + if (b == null) + throw new NoSuchFieldException(); + + if (ShopType.isShop(b)) { + return Shop.loadShop((Sign) b.getState()); + + } else if (ShopChest.isShopChest(b)) { + if (plugin.getDataStorage().getChestLinkage(new ShopLocation(b.getLocation())) != null) + return plugin.getDataStorage().loadShopFromStorage(new ShopLocation(b.getLocation())); + + return Shop.loadShop(new ShopChest(b.getLocation()).getShopSign()); + + } else + throw new NoSuchFieldException(); + + } catch (NoSuchFieldException ex) { + Message.NO_SIGHTED_SHOP.sendMessage(pSender); + return null; + } + } + + //------------------------------------------------------------------------------------------------------------------ + //endregion +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CreateCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CreateCommand.java new file mode 100644 index 00000000..c0b0b793 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/CreateCommand.java @@ -0,0 +1,116 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.shop.ShopType; + +/** + * Implementation of CommandRunner for plugin commands that create new shops + * + * @since 2.6.0 + */ +public class CreateCommand extends CommandRunner { + + public CreateCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Create a regular shop from a sign in front of the player + */ + public void createTrade() { + Sign sign = findSign(); + + if (sign == null) + return; + + createShop(sign, pSender, ShopType.TRADE); + } + + /** + * Create a BiTrade shop from a sign in front of the player + */ + public void createBiTrade() { + Sign sign = findSign(); + + if (sign == null) + return; + + createShop(sign, pSender, ShopType.BITRADE); + } + + /** + * Create a iTrade shop from a sign in front of the player + */ + public void createITrade() { + Sign sign = findSign(); + + if (sign == null) + return; + + createShop(sign, pSender, ShopType.ITRADE); + } + + //region Util Methods + //------------------------------------------------------------------------------------------------------------------ + + /** + * Returns the Sign the player is looking at + * + * @return null if Sign is not found, Sign object if it is + */ + protected Sign findSign() { + if (pSender == null) { + Message.PLAYER_ONLY_COMMAND.sendMessage(pSender); + return null; + } + + Block b = pSender.getTargetBlockExact(Setting.MAX_EDIT_DISTANCE.getInt()); + try { + if (b == null) + throw new NoSuchFieldException(); + + if (plugin.getSigns().getSignTypes().contains(b.getType())) { + return (Sign) b.getState(); + + } else + throw new NoSuchFieldException(); + + } catch (NoSuchFieldException ex) { + Message.NO_SIGN_FOUND.sendMessage(pSender); + return null; + } + } + + //------------------------------------------------------------------------------------------------------------------ + //endregion +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/EditCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/EditCommand.java new file mode 100644 index 00000000..0a6f8233 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/EditCommand.java @@ -0,0 +1,330 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import de.themoep.inventorygui.*; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.player.ShopUser; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopSettingKeys; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Implementation of GUICommand for the `edit` command + * + * @since 2.3.0 + */ +public class EditCommand extends GUICommand { + + private Shop shop; + private InventoryGui mainMenu, + userEdit, + costEdit, + productEdit, + settingEdit; + + + public EditCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Opens a GUI allowing the player to edit the shop + */ + public void edit() { + shop = findShop(); + + if (shop == null) + return; + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || Permissions.isAdminEnabled(pSender))) { + command.sendMessage(Message.NO_SHOP_PERMISSION.getPrefixed()); + return; + } + + mainMenu = new InventoryGui(plugin, "Edit Menu-" + shop.getShopLocationAsSL().toString(), MENU_LAYOUT); + + mainMenu.setFiller(new ItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE, 1)); + + // ShopUser edit menu, currently can only change/remove. Adding only available through commands + mainMenu.addElement(editUserMenu('a')); + + mainMenu.addElement(editCostMenu('b')); + + mainMenu.addElement(editProductMenu('c')); + + mainMenu.addElement(editSettingsMenu('d')); + + mainMenu.show(pSender); + } + + private GuiElement editSettingsMenu(char slotChar) { + return new StaticGuiElement(slotChar, new ItemStack(Material.CRAFTING_TABLE), click -> { + Map> changedSettings = new HashMap<>(); + + settingEdit = new InventoryGui(plugin, "Edit Shop Settings", SETTING_LAYOUT); + GuiElementGroup viewGroup = new GuiElementGroup('g'), + changeGroup = new GuiElementGroup('h'); + + shop.getShopSettings().forEach((key, value) -> { + viewGroup.addElement(new StaticGuiElement('e', key.getDisplayItem(), key.makeReadable(), value.toString())); + + ObjectHolder state = shop.getShopSetting(key); + if (!(state == null || state.getObject() == null)) { + if (state.isBoolean()) { + if (key.isUserEditable(shop.getShopType())) { + changeGroup.addElement(new GuiStateElement('e', + state.asBoolean().toString(), + new GuiStateElement.State(change -> { + if (!state.asBoolean()) + changedSettings.put(key, new ObjectHolder<>(true)); + else + changedSettings.remove(key); + }, + "true", + getBooleanItem(true), + key.makeReadable(), + "State: True" + ), + new GuiStateElement.State(change -> { + if (state.asBoolean()) + changedSettings.put(key, new ObjectHolder<>(false)); + else + changedSettings.remove(key); + }, + "false", + getBooleanItem(false), + key.makeReadable(), + "State: False" + ))); + } else { + changeGroup.addElement(new StaticGuiElement('e', getBooleanItem(state.asBoolean()), key.makeReadable(), value.toString())); + } + + + } // Add else-if later if other type settings are added... + } + }); + + // Add Cancel Button - Cancels changes and Goes to previous screen + settingEdit.addElement(getBackButton(true)); + + // Add Save Button - Saves and Goes to previous menu + settingEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { + shop.setShopSettings(changedSettings); + shop.saveShop(changedSettings.size() > 0); + InventoryGui.goBack(pSender); + return true; + }, "Save Changes")); + + settingEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); + + settingEdit.addElements(getNextButton(), getPrevButton(), viewGroup, changeGroup); + + settingEdit.show(pSender); + return true; + }, colorize("&eEdit Shop Settings")); + } + + private GuiElement editUserMenu(char slotChar) { + return new StaticGuiElement(slotChar, new ItemStack(Material.PLAYER_HEAD), click -> { + userEdit = new InventoryGui(plugin, "Edit Users", EDIT_LAYOUT); + Set shopUsers = new HashSet<>(); + GuiElementGroup userGroup = new GuiElementGroup('g'); + + // Previous page + userEdit.addElement(getPrevButton()); + + // Next page + userEdit.addElement(getNextButton()); + + // Cancel and Back + userEdit.addElement(getBackButton(true)); + + userEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.BLUE_STAINED_GLASS_PANE), " ")); + + // Owner added separately as it is not editable + userGroup.addElement(new StaticGuiElement('e', shop.getOwner().getHead(), shop.getOwner().getName(), "Position: " + shop.getOwner().getRole().toString())); + + if (shop.getOwner().getUUID().equals(pSender.getUniqueId())) { + + // Save and Back + userEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { + shop.updateShopUsers(shopUsers); + InventoryGui.goBack(pSender); + return true; + }, "Save Changes")); + + for (ShopUser user : shop.getUsers(ShopRole.MANAGER, ShopRole.MEMBER)) { + shopUsers.add(user); + userGroup.addElement(new GuiStateElement('e', + user.getRole().toString(), + new GuiStateElement.State(change -> { + shopUsers.remove(user); + user.setRole(ShopRole.MANAGER); + shopUsers.add(user); + }, + "MANAGER", + user.getHead(), + user.getName(), + "Position: MANAGER", + "Click to cycle the player to Member."), + new GuiStateElement.State(change -> { + shopUsers.remove(user); + user.setRole(ShopRole.MEMBER); + shopUsers.add(user); + }, + "MEMBER", + user.getHead(), + user.getName(), + "Position: MEMBER", + "Click to cycle the player to Removed."), + new GuiStateElement.State(change -> { + shopUsers.remove(user); + user.setRole(ShopRole.SHOPPER); + shopUsers.add(user); + }, + "SHOPPER", + new ItemStack(Material.BARRIER), + user.getName(), + "Position: NONE", + "Click to cycle the player to Manager.") + )); + + } + } else { + for (ShopUser user : shop.getUsers(ShopRole.MANAGER, ShopRole.MEMBER)) { + userGroup.addElement(new StaticGuiElement('e', user.getHead(), user.getName(), "Position: " + user.getRole().toString())); + } + } + userEdit.addElement(userGroup); + userEdit.show(pSender); + return true; + }, colorize("&eEdit Shop Users")); + } + + private GuiElement editCostMenu(char slotChar) { + return new StaticGuiElement(slotChar, new ItemStack(Material.GOLD_NUGGET), click -> { + costEdit = new InventoryGui(plugin, "Edit Costs", EDIT_LAYOUT); + if (costItems.isEmpty()) { + for (ShopItemStack item : shop.getSideList(ShopItemSide.COST)) { + costItems.add(item.clone()); + costItemsRemoval.add(false); + } + } + GuiElementGroup costGroup = new GuiElementGroup('g'); + + // Previous page + costEdit.addElement(getPrevButton()); + + // Next page + costEdit.addElement(getNextButton()); + + // Cancel and Back + costEdit.addElement(getBackButton(true)); + + // Save and Back + costEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { + for (int i = costItems.size() - 1; i >= 0; i--) { + if (costItemsRemoval.get(i)) + costItems.remove(i); + } + shop.updateSide(ShopItemSide.COST, costItems); + shop.saveShop(); + InventoryGui.goBack(pSender); + return true; + }, "Save Changes")); + + costEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); + + for (int i = 0; i < costItems.size(); i++) { + costGroup.addElement(itemSettingMenu(i, ShopItemSide.COST, true)); + } + + costEdit.addElement(costGroup); + costEdit.show(pSender); + return true; + }, colorize("&eEdit Shop Costs")); + } + + private GuiElement editProductMenu(char slotChar) { + return new StaticGuiElement(slotChar, new ItemStack(Material.GRASS_BLOCK), click -> { + productEdit = new InventoryGui(plugin, "Edit Products", EDIT_LAYOUT); + if (productItems.isEmpty()) { + for (ShopItemStack item : shop.getSideList(ShopItemSide.PRODUCT)) { + productItems.add(item.clone()); + productItemsRemoval.add(false); + } + } + GuiElementGroup productGroup = new GuiElementGroup('g'); + + // Previous page + productEdit.addElement(getPrevButton()); + + // Next page + productEdit.addElement(getNextButton()); + + // Cancel and Back + productEdit.addElement(getBackButton(true)); + + // Save and Back + productEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { + for (int i = productItems.size() - 1; i >= 0; i--) { + if (productItemsRemoval.get(i)) + productItems.remove(i); + } + shop.updateSide(ShopItemSide.PRODUCT, productItems); + shop.saveShop(); + InventoryGui.goBack(pSender); + return true; + }, "Save Changes")); + + productEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); + + for (int i = 0; i < productItems.size(); i++) { + productGroup.addElement(itemSettingMenu(i, ShopItemSide.PRODUCT, true)); + } + + productEdit.addElement(productGroup); + productEdit.show(pSender); + return true; + }, colorize("&eEdit Shop Products")); + } +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GUICommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GUICommand.java new file mode 100644 index 00000000..74567967 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GUICommand.java @@ -0,0 +1,286 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import de.themoep.inventorygui.*; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.item.ShopItemStackSettingKeys; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Implementation of CommandRunner for plugin commands that generate GUI screens + * + * @since 2.6.0 + */ +public class GUICommand extends CommandRunner { + + //region Util Variables + //------------------------------------------------------------------------------------------------------------------ + + + protected final String[] MENU_LAYOUT = {"ad bc"}, + EDIT_LAYOUT = {"aggggggga", "ap c s na"}, + ITEM_LAYOUT = {"u ggggggg", "j hhhhhhh", "ap cbs na"}, + SETTING_LAYOUT = {"ggggggggg", "hhhhhhhhh", "ap cbs na"}, + WHAT_MENU = {"141125333", "1qqq2eee3", "11p123n33"}; + protected List costItems = new ArrayList<>(), + productItems = new ArrayList<>(); + protected List costItemsRemoval = new ArrayList<>(), + productItemsRemoval = new ArrayList<>(); + + + //------------------------------------------------------------------------------------------------------------------ + //endregion + + public GUICommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + + //region Util Methods + //------------------------------------------------------------------------------------------------------------------ + + protected StaticGuiElement itemSettingMenu(int index, ShopItemSide side, boolean editable) { + ShopItemStack item = (side.equals(ShopItemSide.COST) ? costItems : productItems).get(index); + ItemStack tempStack = item.getItemStack(); + ItemMeta tempMeta = tempStack.getItemMeta(); + List newLore = new ArrayList<>(); + newLore.add(colorize("&8Amount &7» &f" + item.getAmount())); + + if (tempMeta != null && tempMeta.hasLore()) { + newLore.add(""); + newLore.addAll(tempMeta.getLore()); + } + + tempMeta.setLore(newLore); + tempStack.setItemMeta(tempMeta); + + return new StaticGuiElement('e', tempStack, click2 -> { + InventoryGui itemEdit = new InventoryGui(plugin, (editable ? "Edit " : "View ") + ((side.equals(ShopItemSide.COST) ? "Cost Item" : "Product Item")), ITEM_LAYOUT); + GuiElementGroup itemGroup = new GuiElementGroup('g'), + settingGroup = new GuiElementGroup('h'); + + // Add Cancel button when editable and Back button when not - Goes to previous screen without saving changes + itemEdit.addElement(getBackButton(editable)); + + // Add Save button only when editable - Saves and Goes to previous screen + if (editable) itemEdit.addElement(new StaticGuiElement('s', new ItemStack(Material.ANVIL), click3 -> { + (side.equals(ShopItemSide.COST) ? costItems : productItems).set(index, item); + InventoryGui.goBack(pSender); + return true; + }, "Save Changes")); + + itemEdit.addElement(new StaticGuiElement('a', new ItemStack(Material.YELLOW_STAINED_GLASS_PANE), " ")); + itemEdit.addElement(getNextButton()); + itemEdit.addElement(getPrevButton()); + + itemEdit.addElement(new StaticGuiElement('u', item.getItemStack())); + if (editable) { + itemEdit.addElement(new GuiStateElement('j', + (side.equals(ShopItemSide.COST) ? costItemsRemoval : productItemsRemoval).get(index) + "", + new GuiStateElement.State(change -> (side.equals(ShopItemSide.COST) ? costItemsRemoval : productItemsRemoval).set(index, true), + "true", + getBooleanItem(false), + "Item Removed", + "Click to RE-ADD!"), + new GuiStateElement.State(change -> (side.equals(ShopItemSide.COST) ? costItemsRemoval : productItemsRemoval).set(index, false), + "false", + getBooleanItem(true), + "Item Valid", + "Click to REMOVE!") + + )); + } else { + itemEdit.addElement(new StaticGuiElement('j', getBooleanItem(true), "Item Valid", " ")); + } + + + //Add new item settings below + if (item.getItemStack().getItemMeta() instanceof Damageable) { + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_DURABILITY, item)); + settingGroup.addElement(numericalOption(ShopItemStackSettingKeys.COMPARE_DURABILITY, item, editable)); + } + + if (tempMeta instanceof BookMeta) { + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR, item, editable)); + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES, item, editable)); + } + + if (tempMeta instanceof FireworkMeta) { + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_FIREWORK_DURATION, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_FIREWORK_DURATION, item, editable)); + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_FIREWORK_EFFECTS, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_FIREWORK_EFFECTS, item, editable)); + } + + if (tempStack.getType().toString().endsWith("SHULKER_BOX")) { + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY, item, editable)); + } + + if (plugin.getVersion().isAtLeast(1, 17) && tempStack.getType().equals(Material.BUNDLE)) { + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_BUNDLE_INVENTORY, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_BUNDLE_INVENTORY, item, editable)); + } + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_NAME, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_NAME, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_LORE, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_LORE, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA, item, editable)); + + itemGroup.addElement(settingDisplayItem(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER, item)); + settingGroup.addElement(booleanOption(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER, item, editable)); + + + itemEdit.addElement(itemGroup); + itemEdit.addElement(settingGroup); + itemEdit.show(pSender); + return true; + }); + } + + private GuiElement numericalOption(ShopItemStackSettingKeys setting, ShopItemStack tempItem, boolean editable) { + ItemStack[] indexedTempItem = new ItemStack[]{getBooleanItem(false), new ItemStack(Material.IRON_BLOCK), getBooleanItem(true), new ItemStack(Material.GOLD_BLOCK)}; + + if (setting.isUserEditable() && editable) { + return new GuiStateElement('e', + String.valueOf(tempItem.getShopSettingAsInteger(setting)), + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(2)); + }, + "2", + indexedTempItem[3], + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(2))), + + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(-1)); + }, + "-1", + indexedTempItem[0], + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(-1))), + + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(0)); + }, + "0", + indexedTempItem[1], + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(0))), + + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(1)); + }, + "1", + indexedTempItem[2], + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(1)) + + )); + } + + return new StaticGuiElement('e', indexedTempItem[tempItem.getShopSettingAsInteger(setting) + 1], setting.makeReadable(), tempItem.getStateString(setting)); + } + + private GuiElement booleanOption(ShopItemStackSettingKeys setting, ShopItemStack tempItem, boolean editable) { + if (setting.isUserEditable() && editable) { + return new GuiStateElement('e', + String.valueOf(tempItem.getShopSettingAsBoolean(setting)), + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(true)); + }, + "true", + getBooleanItem(true), + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(true)) + ), + new GuiStateElement.State(change -> { + tempItem.setShopSettings(setting, new ObjectHolder<>(false)); + }, + "false", + getBooleanItem(false), + setting.makeReadable(), + tempItem.getStateString(new ObjectHolder<>(false)) + )); + } + + return new StaticGuiElement('e', tempItem.getShopSettingAsBoolean(setting) ? getBooleanItem(true) : getBooleanItem(false), setting.makeReadable(), tempItem.getStateString(setting)); + } + + private StaticGuiElement settingDisplayItem(ShopItemStackSettingKeys setting, ShopItemStack tempItem) { + return new StaticGuiElement('e', setting.getDisplayItem(), setting.makeReadable(), tempItem.getStateString(setting)); + } + + protected GuiElement getPrevButton() { + return new GuiPageElement('p', new ItemStack(Material.POTION), GuiPageElement.PageAction.PREVIOUS, "Go to previous page (%prevpage%)", " "); + } + + protected GuiElement getNextButton() { + return new GuiPageElement('n', new ItemStack(Material.SPLASH_POTION), GuiPageElement.PageAction.NEXT, "Go to next page (%nextpage%)", " "); + } + + protected GuiElement getBackButton(boolean asCancel) { + return new StaticGuiElement(asCancel ? 'c' : 'b', new ItemStack(Material.END_CRYSTAL), click3 -> { + InventoryGui.goBack(pSender); + return true; + }, asCancel ? "Cancel Changes" : "Back"); + } + + protected ItemStack getBooleanItem(boolean item) { + return item ? new ItemStack(Material.EMERALD_BLOCK) : new ItemStack(Material.REDSTONE_BLOCK); + } + + //------------------------------------------------------------------------------------------------------------------ + //endregion +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GeneralPlayerCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GeneralPlayerCommand.java new file mode 100644 index 00000000..16856700 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/GeneralPlayerCommand.java @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.Bukkit; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.PlayerSetting; +import org.shanerx.tradeshop.utils.objects.Tuple; + +public class GeneralPlayerCommand extends CommandRunner { + + public GeneralPlayerCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Changes the players trade multiplier for current login + */ + public void multi() { + if (!Setting.ALLOW_MULTI_TRADE.getBoolean()) { + Message.FEATURE_DISABLED.sendMessage(pSender); + return; + } + + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); + + if (command.argsSize() == 1) { + Message.MULTI_AMOUNT.sendMessage(pSender, new Tuple<>(Variable.AMOUNT.toString(), String.valueOf(playerSetting.getMulti()))); + } else { + int amount = Setting.MULTI_TRADE_DEFAULT.getInt(); + + if (isInt(command.getArgAt(1))) + amount = Integer.parseInt(command.getArgAt(1)); + + if (amount < 2) + amount = 2; + else if (amount > Setting.MULTI_TRADE_MAX.getInt()) + amount = Setting.MULTI_TRADE_MAX.getInt(); + + playerSetting.setMulti(amount); + plugin.getDataStorage().savePlayer(playerSetting); + + Message.MULTI_UPDATE.sendMessage(pSender, new Tuple<>(Variable.AMOUNT.toString(), String.valueOf(amount))); + } + } + + /** + * Toggles the join status message for the player + */ + public void toggleStatus() { + if (!Setting.ALLOW_TOGGLE_STATUS.getBoolean()) { + Message.FEATURE_DISABLED.sendMessage(pSender); + return; + } + + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(pSender.getUniqueId()); + playerSetting.setShowInvolvedStatus(!playerSetting.showInvolvedStatus()); + plugin.getDataStorage().savePlayer(playerSetting); + Message.TOGGLED_STATUS.sendMessage(pSender, new Tuple<>(Variable.STATUS.toString(), playerSetting.showInvolvedStatus() ? "on" : "off")); + } + + /** + * Shows the player the status of all shops they are involved with or the specified player is involved with + */ + public void status() { + if (command.hasArgAt(1)) { + if (!Permissions.isAdminEnabled(pSender)) { + Message.NO_COMMAND_PERMISSION.sendMessage(pSender); + return; + } + if (Bukkit.getOfflinePlayer(command.getArgAt(1)).hasPlayedBefore()) { + plugin.getDataStorage().loadPlayer(Bukkit.getOfflinePlayer(command.getArgAt(1)).getUniqueId()) + .getInvolvedStatusesInventory().show(pSender.getPlayer()); + } else { + Message.PLAYER_NOT_FOUND.sendMessage(pSender); + } + } else { + plugin.getDataStorage().loadPlayer(pSender.getUniqueId()).getInvolvedStatusesInventory().show(pSender.getPlayer()); + } + } +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopCommand.java new file mode 100644 index 00000000..02824d29 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopCommand.java @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.framework.events.PlayerShopCloseEvent; +import org.shanerx.tradeshop.framework.events.PlayerShopOpenEvent; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopStatus; +import org.shanerx.tradeshop.utils.objects.Tuple; + +public class ShopCommand extends CommandRunner { + + public ShopCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Sets the shop to the open status allowing trades to happen + */ + public void open() { + Shop shop = findShop(); + + if (shop == null) + return; + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || Permissions.isAdminEnabled(pSender))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + PlayerShopOpenEvent event = new PlayerShopOpenEvent(pSender, shop); + if (event.isCancelled()) return; + + ShopStatus status = shop.setOpen(); + + switch (status) { + case OPEN: + Message.CHANGE_OPEN.sendMessage(pSender); + break; + case INCOMPLETE: + if (shop.isMissingItems()) + Message.MISSING_ITEM.sendMessage(pSender); + else if (shop.getChestAsSC() == null) + Message.MISSING_CHEST.sendMessage(pSender); + break; + case OUT_OF_STOCK: + Message.SHOP_EMPTY.sendMessage(pSender); + break; + } + } + + /** + * Sets the shop to the close status preventing trades from happen + */ + public void close() { + Shop shop = findShop(); + + if (shop == null) + return; + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || Permissions.isAdminEnabled(pSender))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + PlayerShopCloseEvent event = new PlayerShopCloseEvent(pSender, shop); + if (event.isCancelled()) return; + + shop.setStatus(ShopStatus.CLOSED); + shop.updateSign(); + shop.saveShop(); + + Message.CHANGE_CLOSED.sendMessage(pSender); + } + + /** + * Switches the shop type between BiTrade and Trade + */ + public void switchShop() { + Shop shop = findShop(); + + if (shop == null) + return; + + if (!Permissions.hasPermission(pSender, Permissions.EDIT)) { + Message.NO_COMMAND_PERMISSION.sendMessage(pSender); + return; + } + + switch (shop.getShopType()) { + case TRADE: + if (!Permissions.hasPermission(pSender, Permissions.CREATEBI)) { + Message.NO_COMMAND_PERMISSION.sendMessage(pSender); + return; + } + case BITRADE: + if (!Permissions.hasPermission(pSender, Permissions.CREATE)) { + Message.NO_COMMAND_PERMISSION.sendMessage(pSender); + return; + } + } + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + shop.switchType(); + + Message.SHOP_TYPE_SWITCHED.sendMessage(pSender, new Tuple<>(Variable.NEW_TYPE.toString(), shop.getShopType().toHeader())); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopItemCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopItemCommand.java new file mode 100644 index 00000000..c72933af --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopItemCommand.java @@ -0,0 +1,262 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.framework.ShopChange; +import org.shanerx.tradeshop.framework.events.PlayerShopChangeEvent; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; +import org.shanerx.tradeshop.utils.objects.Tuple; + +public class ShopItemCommand extends CommandRunner { + + ShopItemSide side; + + public ShopItemCommand(TradeShop instance, CommandPass command, ShopItemSide side) { + super(instance, command); + this.side = side; + } + + /** + * Lists items on a shops specified side with their index + */ + public void listSide() { + Shop shop = findShop(); + + if (shop == null) + return; + + StringBuilder sb = new StringBuilder(); + int counter = 1; + + for (ShopItemStack itm : shop.getSideList(side)) { + sb.append(String.format("&b[&f%d&b] &2- &f%s\n", counter, itm.getCleanItemName())); + counter++; + } + + Message.SHOP_ITEM_LIST.sendMessage(pSender, new Tuple<>(Variable.TYPE.toString(), side.toString().toLowerCase() + "s"), new Tuple<>(Variable.LIST.toString(), sb.toString())); + } + + /** + * Removes the item at index from the shops specified side + */ + public void removeSide() { + Shop shop = findShop(); + + if (shop == null) + return; + + int index; + + if (isInt(command.getArgAt(1))) { + index = Integer.parseInt(command.getArgAt(1)) - 1; + } else if (shop.getSideList(side).size() == 1) { + index = 0; + } else { + Message.INVALID_ARGUMENTS.sendMessage(pSender); + return; + } + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.valueOf("REMOVE_" + side.toString()), new ObjectHolder(index)); + Bukkit.getPluginManager().callEvent(changeEvent); + if (changeEvent.isCancelled()) return; + + if (shop.removeSideIndex(side, index)) + Message.ITEM_REMOVED.sendMessage(pSender); + else + Message.ITEM_NOT_REMOVED.sendMessage(pSender); + } + + /** + * Sets the item for the specified side to a Shop + *

+ * With no variables sent, this will use the amount and data of the held item + *

+ *

+ * If the player uses a int in the first variable they can change the amount for the item they are holding + *

+ *

+ * With 2 variables used the player can use an amount and material to set the sign instead of a held item + *

+ */ + public void setSide() { + Shop shop = findShop(); + + if (shop == null) + return; + + int amount = 0; + Material mat = null; + + if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { + amount = Integer.parseInt(command.getArgAt(1)); + } + + if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { + mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); + } + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + ItemStack itemInHand; + + if (mat == null) { + itemInHand = pSender.getInventory().getItemInMainHand().clone(); + } else { + itemInHand = new ItemStack(mat, 1); + } + + if (itemInHand.getType() == Material.AIR) { + Message.HELD_EMPTY.sendMessage(pSender); + return; + } + + if (isIllegal(side, itemInHand.getType())) { + Message.ILLEGAL_ITEM.sendMessage(pSender); + return; + } + + if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && itemInHand.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { + Message.NO_SHULKER_ITEM.sendMessage(pSender); + return; + } + + if (amount > 0) { + itemInHand.setAmount(amount); + } + + if (Math.ceil((double) itemInHand.getAmount() / (double) itemInHand.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { + Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), side.toString().toLowerCase())); + return; + } + + PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.valueOf("SET_" + side.toString()), new ObjectHolder(itemInHand)); + Bukkit.getPluginManager().callEvent(changeEvent); + if (changeEvent.isCancelled()) return; + + shop.setSideItems(side, itemInHand); + + Message.ITEM_ADDED.sendMessage(pSender); + } + + /** + * Adds a item to the specified side of a Shop + *

+ * With no variables sent will use the amount and data of the held item + *

+ *

+ * If the player uses a int in the first variable they can change the amount for the item they are holding + *

+ *

+ * With 2 variables used the player can use an amount and material to set the sign instead of a held item + *

+ */ + public void addSide() { + Shop shop = findShop(); + + if (shop == null) + return; + + int amount = 0; + Material mat = null; + + if (command.hasArgAt(1) && isInt(command.getArgAt(1))) { + amount = Integer.parseInt(command.getArgAt(1)); + } + + if (command.hasArgAt(2) && Material.getMaterial(command.getArgAt(2).toUpperCase()) != null) { + mat = Material.getMaterial(command.getArgAt(2).toUpperCase()); + } + + if (!(shop.getUsersUUID(ShopRole.MANAGER, ShopRole.OWNER).contains(pSender.getUniqueId()) + || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender)))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + return; + } + + ItemStack itemInHand; + + if (mat == null) { + itemInHand = pSender.getInventory().getItemInMainHand().clone(); + } else { + itemInHand = new ItemStack(mat, 1); + } + + if (itemInHand.getType() == Material.AIR) { + Message.HELD_EMPTY.sendMessage(pSender); + return; + } + + if (isIllegal(side, itemInHand.getType())) { + Message.ILLEGAL_ITEM.sendMessage(pSender); + return; + } + + if (!(shop.getShopType().isITrade() && shop.getInventoryLocation() == null) && itemInHand.getType().toString().endsWith("SHULKER_BOX") && shop.getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")) { + Message.NO_SHULKER_ITEM.sendMessage(pSender); + return; + } + + if (amount > 0) { + itemInHand.setAmount(amount); + } + + if (shop.getSideList(side).size() + Math.ceil((double) itemInHand.getAmount() / (double) itemInHand.getMaxStackSize()) > Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()) { + Message.TOO_MANY_ITEMS.sendMessage(pSender, new Tuple<>(Variable.SIDE.toString(), side.toString().toLowerCase())); + return; + } + + PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, ShopChange.valueOf("ADD_" + side.toString()), new ObjectHolder(itemInHand)); + Bukkit.getPluginManager().callEvent(changeEvent); + if (changeEvent.isCancelled()) return; + + shop.addSideItem(side, itemInHand); + + Message.ITEM_ADDED.sendMessage(pSender); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopUserCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopUserCommand.java new file mode 100644 index 00000000..86cb6e2f --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/ShopUserCommand.java @@ -0,0 +1,260 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; +import org.shanerx.tradeshop.framework.ShopChange; +import org.shanerx.tradeshop.framework.events.PlayerShopChangeEvent; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.player.ShopUser; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shoplocation.ShopLocation; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; +import org.shanerx.tradeshop.utils.objects.Tuple; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +enum UserOperationStatus { + SUCCESSFUL(Message.UPDATED_SHOP_USERS_SUCCESSFUL), + FAILED(Message.UPDATED_SHOP_USERS_FAILED), + FAILED_CAPACITY(Message.UPDATED_SHOP_USERS_FAILED_CAPACITY), + FAILED_EXISTING(Message.UPDATED_SHOP_USERS_FAILED_EXISTING), + FAILED_MISSING(Message.UPDATED_SHOP_USERS_FAILED_MISSING); + + private final Message text; + + UserOperationStatus(Message text) { + this.text = text; + } + + @Override + public String toString() { + return text.toString(); + } +} + +/** + * Implementation of CommandRunner for commands that view/change shop users + * + * @since 2.6.0 + */ +public class ShopUserCommand extends CommandRunner { + + private OfflinePlayer target; + + public ShopUserCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Tells the player who the Owner/Managers/Members that are on the shop are + */ + public void who() { + String owner = ""; + StringBuilder managers = new StringBuilder(); + StringBuilder members = new StringBuilder(); + Shop shop = findShop(); + + if (shop == null) + return; + + if (shop.getShopType().isITrade()) { + Message.WHO_MESSAGE.sendMessage(pSender, + new Tuple<>(Variable.OWNER.toString(), Setting.ITRADESHOP_OWNER.getString()), + new Tuple<>(Variable.MANAGERS.toString(), "None"), + new Tuple<>(Variable.MEMBERS.toString(), "None")); + return; + } + + if (shop.getOwner() != null) + owner = shop.getOwner().getName(); + + if (shop.hasUsers(ShopRole.MANAGER)) { + for (ShopUser usr : shop.getUsers(ShopRole.MANAGER)) { + if (managers.toString().equals("")) + managers = new StringBuilder(usr.getName()); + else + managers.append(", ").append(usr.getName()); + } + } + + if (shop.hasUsers(ShopRole.MEMBER)) { + for (ShopUser usr : shop.getUsers(ShopRole.MEMBER)) { + if (members.toString().equals("")) + members = new StringBuilder(usr.getName()); + else + members.append(", ").append(usr.getName()); + } + } + + if (managers.toString().equals("")) { + managers = new StringBuilder("None"); + } + if (members.toString().equals("")) { + members = new StringBuilder("None"); + } + Message.WHO_MESSAGE.sendMessage(pSender, + new Tuple<>(Variable.OWNER.toString(), owner), + new Tuple<>(Variable.MANAGERS.toString(), managers.toString()), + new Tuple<>(Variable.MEMBERS.toString(), members.toString())); + } + + /** + * Adds or Removes the specified player to/from the shop as the specified role + */ + public void editUser(ShopRole role, ShopChange change) { + boolean applyAllOwned = command.hasArgAt(2) && command.getArgAt(2).length() > 0 && toBool(command.getArgAt(2)); + Set ownedShops = new HashSet<>(); + Map updateStatuses = new HashMap<>(); + + Shop tempShop = shopUserCommandStart(applyAllOwned); + + if (tempShop == null && target == null) { + return; + } + + if (applyAllOwned) { + for (String location : plugin.getDataStorage().loadPlayer(pSender.getUniqueId()).getOwnedShops()) { + ownedShops.add(plugin.getDataStorage().loadShopFromSign(ShopLocation.fromString(location))); + } + } else { + ownedShops.add(tempShop); + } + + for (Shop shop : ownedShops) { + eachOwnedShop: + { + switch (change) { + case REMOVE_USER: + if (!shop.getUsersUUID(ShopRole.MANAGER, ShopRole.MEMBER).contains(target.getUniqueId())) { + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.FAILED_MISSING.toString()); + break eachOwnedShop; + } + break; + case ADD_MANAGER: + case ADD_MEMBER: + if (shop.getUsersUUID(ShopRole.MANAGER, ShopRole.MEMBER).contains(target.getUniqueId())) { + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.FAILED_EXISTING.toString()); + break eachOwnedShop; + } else if (shop.getUsers(ShopRole.MANAGER, ShopRole.MEMBER).size() >= Setting.MAX_SHOP_USERS.getInt()) { + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.FAILED_CAPACITY.toString()); + break eachOwnedShop; + } + break; + case SET_MANAGER: + case SET_MEMBER: + if (shop.getUsersExcluding(Collections.singletonList(target.getUniqueId()), ShopRole.MANAGER, ShopRole.MEMBER).size() >= Setting.MAX_SHOP_USERS.getInt()) { + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.FAILED_CAPACITY.toString()); + break eachOwnedShop; + } + break; + } + + PlayerShopChangeEvent changeEvent = new PlayerShopChangeEvent(pSender, shop, change, new ObjectHolder(target)); + Bukkit.getPluginManager().callEvent(changeEvent); + if (changeEvent.isCancelled()) return; + + boolean success = false; + + switch (change) { + case SET_MANAGER: + case SET_MEMBER: + success = shop.setUser(target.getUniqueId(), role); + break; + case ADD_MEMBER: + case ADD_MANAGER: + success = shop.addUser(target.getUniqueId(), role); + break; + case REMOVE_USER: + success = shop.removeUser(target.getUniqueId()); + break; + } + + if (success) + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.SUCCESSFUL.toString()); + else + updateStatuses.put(shop.getShopLocationAsSL().toString(), UserOperationStatus.FAILED.toString()); + } + } + + Message.UPDATED_SHOP_USERS.sendUserEditMultiLineMessage(pSender, Collections.singletonMap(Variable.UPDATED_SHOPS, updateStatuses)); + } + + + //region Util Methods + //------------------------------------------------------------------------------------------------------------------ + + /** + * Checks if targeted player exists and if player is looking at a shop while not targetting all owned shops + * + * @param applyAllOwned Is Player targetting all owned shops + * @return shop if found or null if not needed; returning null while setting target to null indicates failure, command should respond with an immediate blank return. + */ + private Shop shopUserCommandStart(boolean applyAllOwned) { + target = Bukkit.getOfflinePlayer(command.getArgAt(1)); + if (!target.hasPlayedBefore()) { + Message.PLAYER_NOT_FOUND.sendMessage(pSender); + target = null; + return null; + } + + if (!applyAllOwned) { + Shop shop = findShop(); + + if (shop == null) { + // Message.NO_SIGHTED_SHOP.sendMessage(pSender); // Message is sent by findShop() + target = null; + return null; + } + + if (!shop.getOwner().getUUID().equals(pSender.getUniqueId()) + || (Setting.UNLIMITED_ADMIN.getBoolean() && Permissions.isAdminEnabled(pSender))) { + Message.NO_SHOP_PERMISSION.sendMessage(pSender); + target = null; + return null; + } + + return shop; + } + + return null; + } + + + //------------------------------------------------------------------------------------------------------------------ + //endregion +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/commands/commandrunners/WhatCommand.java b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/WhatCommand.java new file mode 100644 index 00000000..a1699523 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/commands/commandrunners/WhatCommand.java @@ -0,0 +1,119 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.commands.commandrunners; + +import de.themoep.inventorygui.GuiElementGroup; +import de.themoep.inventorygui.InventoryGui; +import de.themoep.inventorygui.StaticGuiElement; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.commands.CommandPass; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopType; + +/** + * Implementation of GUICommand for the `what` command + * + * @since 2.3.0 + */ +public class WhatCommand extends GUICommand { + + public WhatCommand(TradeShop instance, CommandPass command) { + super(instance, command); + } + + /** + * Opens a GUI containing the items to be traded at the shop the player is looking at + */ + public void what() { + Shop shop = findShop(); + + if (shop == null) + return; + + shop.updateFullTradeCount(); + shop.updateSign(); + + if (!Permissions.hasPermission(pSender, Permissions.INFO)) { + command.sendMessage(Message.NO_COMMAND_PERMISSION.getPrefixed()); + return; + } + + InventoryGui gui = new InventoryGui(plugin, colorize(shop.getShopType() == ShopType.ITRADE ? + Setting.ITRADESHOP_OWNER.getString() : + Bukkit.getOfflinePlayer(shop.getOwner().getUUID()).getName() + "'s Shop"), + WHAT_MENU); + + GuiElementGroup costGroup = new GuiElementGroup('q'), productGroup = new GuiElementGroup('e'); + + gui.setFiller(new ItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE, 1)); + + if (costItems.isEmpty()) { + for (ShopItemStack item : shop.getSideList(ShopItemSide.COST)) { + costItems.add(item.clone()); + } + } + + if (productItems.isEmpty()) { + for (ShopItemStack item : shop.getSideList(ShopItemSide.PRODUCT)) { + productItems.add(item.clone()); + } + } + + + for (int i = 0; i < costItems.size(); i++) { + costGroup.addElement(itemSettingMenu(i, ShopItemSide.COST, false)); + } + + for (int i = 0; i < productItems.size(); i++) { + productGroup.addElement(itemSettingMenu(i, ShopItemSide.PRODUCT, false)); + } + + gui.addElement(new StaticGuiElement('1', new ItemStack(Material.LIME_STAINED_GLASS_PANE), + " ")); + gui.addElement(new StaticGuiElement('2', new ItemStack(Material.BLACK_STAINED_GLASS_PANE), + " ")); + gui.addElement(new StaticGuiElement('3', new ItemStack(Material.LIGHT_BLUE_STAINED_GLASS_PANE), + " ")); + gui.addElement(new StaticGuiElement('4', new ItemStack(Material.GOLD_NUGGET), + "Cost", "This is the item", "that you give to", "make the trade.")); + gui.addElement(new StaticGuiElement('5', new ItemStack(Material.GRASS_BLOCK), + "Product", "This is the item", "that you receive", "from the trade.")); + gui.addElement(getPrevButton()); + gui.addElement(getNextButton()); + gui.addElement(costGroup); + gui.addElement(productGroup); + + gui.show(pSender); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/ConfigManager.java b/src/main/java/org/shanerx/tradeshop/data/config/ConfigManager.java similarity index 60% rename from src/main/java/org/shanerx/tradeshop/utils/config/ConfigManager.java rename to src/main/java/org/shanerx/tradeshop/data/config/ConfigManager.java index fa086e71..8eab75e8 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/ConfigManager.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/ConfigManager.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import com.google.common.base.CaseFormat; import com.google.common.base.Charsets; @@ -33,6 +33,8 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.shop.ShopSettingKeys; +import org.shanerx.tradeshop.shop.ShopType; import java.io.File; import java.io.FileOutputStream; @@ -41,7 +43,10 @@ import java.io.Writer; import java.util.Arrays; import java.util.Comparator; +import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; import java.util.logging.Level; public class ConfigManager { @@ -77,7 +82,7 @@ public String colour(String toColour) { return ChatColor.translateAlternateColorCodes('&', toColour); } - public void load() { + public boolean load() { try { if (!PLUGIN.getDataFolder().isDirectory()) { PLUGIN.getDataFolder().mkdirs(); @@ -92,40 +97,67 @@ public void load() { config = YamlConfiguration.loadConfiguration(file); - setDefaults(); + return setDefaults(); } public void reload() { - load(); + Set hasUpgraded = new HashSet<>(); + hasUpgraded.add(load()); switch (configType) { case CONFIG: - Setting.upgrade(); - PLUGIN.setUseInternalPerms(Setting.USE_INTERNAL_PERMISSIONS.getBoolean()); + hasUpgraded.add(Setting.upgrade()); break; case MESSAGES: - Message.upgrade(); + hasUpgraded.add(Message.upgrade()); break; } - save(); + save(hasUpgraded.contains(true)); - PLUGIN.setSkipHopperProtection( - Setting.BITRADESHOP_HOPPER_EXPORT.getBoolean() && - Setting.BITRADESHOP_HOPPER_IMPORT.getBoolean() && - Setting.TRADESHOP_HOPPER_IMPORT.getBoolean() && - Setting.TRADESHOP_HOPPER_EXPORT.getBoolean()); + updateSkipHoppers(); } - public void setDefaults() { + public void updateSkipHoppers() { + try { + Set skipCheck = new HashSet<>(); + skipCheck.add(ShopSettingKeys.HOPPER_EXPORT.getDefaultValue(ShopType.TRADE).asBoolean()); + skipCheck.add(ShopSettingKeys.HOPPER_IMPORT.getDefaultValue(ShopType.TRADE).asBoolean()); + skipCheck.add(ShopSettingKeys.HOPPER_EXPORT.getDefaultValue(ShopType.BITRADE).asBoolean()); + skipCheck.add(ShopSettingKeys.HOPPER_IMPORT.getDefaultValue(ShopType.BITRADE).asBoolean()); + skipCheck.add(!ShopSettingKeys.HOPPER_EXPORT.isUserEditable(ShopType.TRADE)); + skipCheck.add(!ShopSettingKeys.HOPPER_IMPORT.isUserEditable(ShopType.TRADE)); + skipCheck.add(!ShopSettingKeys.HOPPER_EXPORT.isUserEditable(ShopType.BITRADE)); + skipCheck.add(!ShopSettingKeys.HOPPER_IMPORT.isUserEditable(ShopType.BITRADE)); + skipCheck.remove(true); + + PLUGIN.setSkipHopperProtection(!skipCheck.contains(false)); + } catch (NullPointerException ignored) { + } + } + + public boolean setDefaults() { + Set hasUpgraded = new HashSet<>(); + switch (configType) { case CONFIG: - Arrays.stream(Setting.values()).forEach((setting) -> addKeyValue(setting.getPath(), setting.getDefaultValue())); + Arrays.stream(Setting.values()).forEach((setting) -> hasUpgraded.add(addKeyValue(setting.getPath(), setting.getDefaultValue()))); break; case MESSAGES: - Arrays.stream(Message.values()).forEach((message) -> addKeyValue(message.getPath(), message.getDefaultValue())); + Arrays.stream(Message.values()).forEach((message) -> hasUpgraded.add(addKeyValue(message.getPath(), message.getDefaultValue()))); break; } + + return hasUpgraded.contains(true); + } + + /** + * Saves the file if passed boolean is true + * + * @param shouldSave true if save should proceed + */ + public void save(boolean shouldSave) { + if (shouldSave) save(); } public void save() { @@ -153,14 +185,14 @@ public void save() { switch (configType) { case CONFIG: - Arrays.stream(SettingSection.values()).sorted(new CompareSettingSections()).forEach((section) -> outputMap.put(section.getPath(), section.getFileString())); - Arrays.stream(Setting.values()).forEach((section) -> outputMap.put(section.getSection().getPath(), - outputMap.getOrDefault(section.getSection().getPath(), "") + section.getFileString())); + Arrays.stream(SettingSection.values()).sorted(new CompareSettingSections()).forEach((section) -> outputMap.put(section.getPath().toLowerCase().replace("_", "-"), section.getFileString())); + Arrays.stream(Setting.values()).forEach((setting) -> outputMap.put(setting.getSection().getPath().toLowerCase().replace("_", "-"), + outputMap.getOrDefault(setting.getSection().getPath().toLowerCase().replace("_", "-"), "") + setting.getFileString())); break; case MESSAGES: - Arrays.stream(MessageSection.values()).sorted(new CompareMessageSections()).forEach((section) -> outputMap.put(section.getPath(), section.getFileString())); - Arrays.stream(Message.values()).forEach((section) -> outputMap.put(section.getSection().getPath(), - outputMap.getOrDefault(section.getSection().getPath(), "") + section.getFileString())); + Arrays.stream(MessageSection.values()).sorted(new CompareMessageSections()).forEach((section) -> outputMap.put(section.getPath().toLowerCase().replace("_", "-"), section.getFileString())); + Arrays.stream(Message.values()).forEach((message) -> outputMap.put(message.getSection().getPath().toLowerCase().replace("_", "-"), + outputMap.getOrDefault(message.getSection().getPath().toLowerCase().replace("_", "-"), "") + message.getFileString())); break; } @@ -180,10 +212,22 @@ public void save() { config = YamlConfiguration.loadConfiguration(file); } - private void addKeyValue(String node, Object value) { - if (config.get(node) == null || (config.get(node) != null && config.get(node).toString().isEmpty())) { + private boolean addKeyValue(String node, Object value) { + node = node.toLowerCase().replace("_", "-"); + if (value instanceof Map) { + for (Map.Entry entry : ((Map) value).entrySet()) { + String newNode = node + "." + entry.getKey().toString().toLowerCase().replace("_", "-"); + if (config.get(newNode) == null || (config.get(newNode) != null && config.get(newNode).toString().isEmpty())) { + config.set(newNode, entry.getValue().toString()); + return true; + } + } + } else if (config.get(node) == null || (config.get(node) != null && config.get(node).toString().isEmpty())) { config.set(node, value); + return true; } + + return false; } public enum ConfigType { @@ -212,7 +256,12 @@ public int compare(SettingSection o1, SettingSection o2) { // if o1's parent is o2 then o2 goes first } else if (o1.getParent() == o2) { return 1; - // if neither of the above are true and one Section has a parent and the other doesn't, then the one without the parent goes first + // if neither is the parent of the other but one Section has a parent and the other doesn't + } else if (o1.hasParent() != o2.hasParent()) { + return o1.hasParent() ? compare(o1.getParent(), o2) : compare(o1, o2.getParent()); // compare existing parent to other section + // if both have parents but they aren't the same parent + } else if (o1.getParent() != null && !o1.getParent().equals(o2.getParent())) { + return compare(o1.getParent(), o2.getParent()); // compare the parents of both } // Otherwise, compare weight @@ -229,9 +278,12 @@ public int compare(MessageSection o1, MessageSection o2) { // if o1's parent is o2 then o2 goes first } else if (o1.getParent() == o2) { return 1; - // if neither of the above are true and one Section has a parent and the other doesn't, then the one without the parent goes first + // if neither is the parent of the other but one Section has a parent and the other doesn't } else if (o1.hasParent() != o2.hasParent()) { - return o1.hasParent() ? 1 : -1; + return o1.hasParent() ? compare(o1.getParent(), o2) : compare(o1, o2.getParent()); // compare existing parent to other section + // if both have parents but they aren't the same parent + } else if (o1.getParent() != null && !o1.getParent().equals(o2.getParent())) { + return compare(o1.getParent(), o2.getParent()); // compare the parents of both } // Otherwise, compare weight diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/Language.java b/src/main/java/org/shanerx/tradeshop/data/config/Language.java similarity index 73% rename from src/main/java/org/shanerx/tradeshop/utils/config/Language.java rename to src/main/java/org/shanerx/tradeshop/data/config/Language.java index aeb0d9d3..c92ad819 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/Language.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/Language.java @@ -23,11 +23,11 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import org.bukkit.configuration.file.YamlConfiguration; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; +import org.shanerx.tradeshop.utils.debug.DebugLevels; import java.io.File; import java.io.InputStream; @@ -105,36 +105,41 @@ public String getLang() { return lang; } - public String getHeader(LangSection section, String path) { - String fullPath = section + "." + path + ".header"; - return langYAML.getString(fullPath, ""); + public String getHeader(LangSection section, LangSubSection subSection, String path) { + return getString(section, subSection, path, "header"); } - public Object getDefault(LangSection section, String path) { - String fullPath = section + "." + path + ".default", defaultValue = langYAML.getString(fullPath); - return defaultValue != null ? defaultValue : getDefaultLangValue(fullPath).toString(); + public String getDefault(LangSection section, LangSubSection subSection, String path) { + return getStringOrDefault(section, subSection, path, "default"); } - public String getPreComment(LangSection section, String path) { - String fullPath = section + "." + path + ".pre-comment"; - return langYAML.getString(fullPath, ""); + public String getPreComment(LangSection section, LangSubSection subSection, String path) { + return getString(section, subSection, path, "pre-comment"); + } + + public String getPostComment(LangSection section, LangSubSection subSection, String path) { + return getString(section, subSection, path, "post-comment"); } - public String getPostComment(LangSection section, String path) { - String fullPath = section + "." + path + ".post-comment"; + public String getString(LangSection section, LangSubSection subSection, String key, String field) { + String fullPath = section + "." + subSection + "." + key + "." + field; return langYAML.getString(fullPath, ""); } + public String getStringOrDefault(LangSection section, LangSubSection subSection, String key, String field) { + String fullPath = section + "." + subSection + "." + key + "." + field, value = getString(section, subSection, key, field); + return value != null ? value : getDefaultLangValue(fullPath).toString(); + } + public boolean isLoaded() { return loaded; } public enum LangSection { - MESSAGE_SECTION, MESSAGE, - SETTING_SECTION, - SETTING; + SETTING, + PERMISSION; LangSection() { } @@ -145,4 +150,18 @@ public String toString() { } } + + public enum LangSubSection { + VALUES, + SECTIONS; + + LangSubSection() { + } + + @Override + public String toString() { + return name().toLowerCase().replace("_", "-"); + } + } + } diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/Message.java b/src/main/java/org/shanerx/tradeshop/data/config/Message.java similarity index 77% rename from src/main/java/org/shanerx/tradeshop/utils/config/Message.java rename to src/main/java/org/shanerx/tradeshop/data/config/Message.java index aaba7126..82f46992 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/Message.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/Message.java @@ -23,23 +23,25 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.objects.Debug; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.utils.Tuple; +import org.shanerx.tradeshop.item.ShopItemStack; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.Debug; +import org.shanerx.tradeshop.utils.objects.Tuple; import org.yaml.snakeyaml.Yaml; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -55,7 +57,7 @@ public enum Message { FEATURE_DISABLED(MessageSection.NONE, "feature-disabled"), HELD_EMPTY(MessageSection.NONE, "held-empty"), ILLEGAL_ITEM(MessageSection.NONE, "illegal-item"), - NO_SHULKER_COST(MessageSection.NONE, "no-shulker-cost"), + NO_SHULKER_ITEM(MessageSection.NONE, "no-shulker-item"), INSUFFICIENT_ITEMS(MessageSection.NONE, "insufficient-items"), SHOP_INSUFFICIENT_ITEMS(MessageSection.NONE, "shop-insufficient-items"), INVALID_ARGUMENTS(MessageSection.NONE, "invalid-arguments"), @@ -90,8 +92,12 @@ public enum Message { SUCCESSFUL_SETUP(MessageSection.NONE, "successful-setup"), TOO_MANY_CHESTS(MessageSection.NONE, "too-many-chests"), TOO_MANY_ITEMS(MessageSection.NONE, "too-many-items"), - UNSUCCESSFUL_SHOP_MEMBERS(MessageSection.NONE, "unsuccessful-shop-members"), - UPDATED_SHOP_MEMBERS(MessageSection.NONE, "updated-shop-members"), + UPDATED_SHOP_USERS(MessageSection.NONE, "updated-shop-users"), + UPDATED_SHOP_USERS_SUCCESSFUL(MessageSection.NONE, "pdated-shop-users-successful"), + UPDATED_SHOP_USERS_FAILED(MessageSection.NONE, "updated-shop-users-failed"), + UPDATED_SHOP_USERS_FAILED_CAPACITY(MessageSection.NONE, "updated-shop-users-failed-capacity"), + UPDATED_SHOP_USERS_FAILED_EXISTING(MessageSection.NONE, "updated-shop-users-failed-existing"), + UPDATED_SHOP_USERS_FAILED_MISSING(MessageSection.NONE, "updated-shop-users-failed-missing"), WHO_MESSAGE(MessageSection.NONE, "who-message"), VIEW_PLAYER_LEVEL(MessageSection.NONE, "view-player-level"), SET_PLAYER_LEVEL(MessageSection.NONE, "set-player-level"), @@ -113,13 +119,15 @@ public enum Message { } // Method to fix any values that have changed with updates - static void upgrade() { + static boolean upgrade() { double version = MESSAGE_VERSION.getDouble(); + Set hasUpgraded = new HashSet<>(); // Uses this instead of a boolean to later replace below ifs with boolean return methods... //Changes if CONFIG_VERSION is below 1.1, then update to 1.1 if (checkVersion(version, 1.1)) { if (TOO_MANY_ITEMS.getString().equals("&cThis trade can not take any more %side%!")) { - TOO_MANY_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, TOO_MANY_ITEMS.getPath())); + TOO_MANY_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.SETTING, Language.LangSubSection.VALUES, TOO_MANY_ITEMS.getPath())); + hasUpgraded.add(true); } version = 1.1; } @@ -129,8 +137,10 @@ static void upgrade() { Arrays.stream(values()).forEach((message) -> { String str = message.getString().replace("{", "%").replace("}", "%"); - if (!str.equals(message.getString())) + if (!str.equals(message.getString())) { message.setValue(str); + hasUpgraded.add(true); + } }); version = 1.2; @@ -139,13 +149,16 @@ static void upgrade() { //Changes if CONFIG_VERSION is below 1.3, then update to 1.3 if (checkVersion(version, 1.3)) { if (INSUFFICIENT_ITEMS.getString().equals("&cYou do not have &e%AMOUNT% %ITEM%&c!")) { - INSUFFICIENT_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, INSUFFICIENT_ITEMS.getPath())); + INSUFFICIENT_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, INSUFFICIENT_ITEMS.getPath())); + hasUpgraded.add(true); } if (SHOP_INSUFFICIENT_ITEMS.getString().equals("&cThis shop does not have enough &e%AMOUNT% %ITEM%&c to trade!")) { - SHOP_INSUFFICIENT_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, SHOP_INSUFFICIENT_ITEMS.getPath())); + SHOP_INSUFFICIENT_ITEMS.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, SHOP_INSUFFICIENT_ITEMS.getPath())); + hasUpgraded.add(true); } if (ON_TRADE.getString().equals("&aYou have traded your &e%AMOUNT2% %ITEM2% &afor &e%AMOUNT1% %ITEM1% &awith %SELLER%")) { - ON_TRADE.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, ON_TRADE.getPath())); + ON_TRADE.setValue(PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, ON_TRADE.getPath())); + hasUpgraded.add(true); } @@ -153,6 +166,8 @@ static void upgrade() { } MESSAGE_VERSION.setValue(version != 0.0 ? version : 1.3); + + return hasUpgraded.contains(true); } private static boolean checkVersion(double version, double maxVersion) { @@ -168,15 +183,15 @@ public String getKey() { } public Object getDefaultValue() { - return PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, path); + return PLUGIN.getLanguage().getDefault(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, path); } public String getPostComment() { - return PLUGIN.getLanguage().getPostComment(Language.LangSection.MESSAGE, path); + return PLUGIN.getLanguage().getPostComment(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, path); } public String getPreComment() { - return PLUGIN.getLanguage().getPreComment(Language.LangSection.MESSAGE, path); + return PLUGIN.getLanguage().getPreComment(Language.LangSection.MESSAGE, Language.LangSubSection.VALUES, path); } public MessageSection getSection() { @@ -224,7 +239,7 @@ public String toString() { } public String getPrefixed() { - return PLUGIN.getMessageManager().colour(Setting.MESSAGE_PREFIX.getString() + " " + this); + return PLUGIN.getMessageManager().colour(Setting.MESSAGE_PREFIX.getString().trim() + " " + this); } @@ -278,7 +293,7 @@ public final void sendItemMultiLineMessage(Player player, Map> entry : itemsToFill.entrySet()) { Pattern pattern = Pattern.compile(MULTILINEREGEX.replace("&V&", entry.getKey().toString())); @@ -315,6 +330,52 @@ public final void sendItemMultiLineMessage(Player player, Map> valuesToFill, Tuple... replacements) { + if (valuesToFill.isEmpty()) { + sendMessage(player, replacements); + return; + } + + boolean isJson = getString().startsWith("#json "); + String message = getPrefixed().replaceFirst("#json ", ""); + + Debug debug = new Utils().PLUGIN.getDebugger(); + + for (Map.Entry> entry : valuesToFill.entrySet()) { + Pattern pattern = Pattern.compile(MULTILINEREGEX.replace("&V&", entry.getKey().toString())); + Matcher matcher = pattern.matcher(message); + + if (entry.getValue().get(0) == null) { + entry.getValue().remove(0); + } + + while (matcher.find()) { + StringBuilder itemList = new StringBuilder(); + String found = matcher.group(), format = found.replaceAll("[{}]", "").split("=")[1]; + + entry.getValue().forEach((k, v) -> { + itemList.append("\n") + .append(format.replace(Variable.SHOP.toString(), k).replace(Variable.STATUS.toString(), v)); + }); + + message = message.replace(found, itemList.toString()); + } + } + + for (Tuple replace : replacements) { + message = message.replace(replace.getLeft().toUpperCase(), replace.getRight()) + .replace(replace.getLeft().toLowerCase(), replace.getRight()) + .replace(replace.getLeft(), replace.getRight()); + } + + if (isJson) { + sendMessageDirectJson(player, message); + } else { + sendMessageDirect(player, message); + } + } + @SafeVarargs public final void sendMessage(CommandSender sender, Tuple... replacements) { if (sender instanceof Player) { diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/MessageSection.java b/src/main/java/org/shanerx/tradeshop/data/config/MessageSection.java similarity index 93% rename from src/main/java/org/shanerx/tradeshop/utils/config/MessageSection.java rename to src/main/java/org/shanerx/tradeshop/data/config/MessageSection.java index 501f128b..e4b36fd1 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/MessageSection.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/MessageSection.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import org.bukkit.Bukkit; import org.shanerx.tradeshop.TradeShop; @@ -77,15 +77,15 @@ public boolean hasParent() { } public String getPostComment() { - return PLUGIN.getLanguage().getPostComment(Language.LangSection.MESSAGE_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getPostComment(Language.LangSection.MESSAGE, Language.LangSubSection.SECTIONS, name().toLowerCase().replace("_", "-")); } public String getPreComment() { - return PLUGIN.getLanguage().getPreComment(Language.LangSection.MESSAGE_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getPreComment(Language.LangSection.MESSAGE, Language.LangSubSection.SECTIONS, name().toLowerCase().replace("_", "-")); } public String getSectionHeader() { - return PLUGIN.getLanguage().getHeader(Language.LangSection.MESSAGE_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getHeader(Language.LangSection.MESSAGE, Language.LangSubSection.SECTIONS, name().toLowerCase().replace("_", "-")); } public String getFileString() { diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/Setting.java b/src/main/java/org/shanerx/tradeshop/data/config/Setting.java similarity index 61% rename from src/main/java/org/shanerx/tradeshop/utils/config/Setting.java rename to src/main/java/org/shanerx/tradeshop/data/config/Setting.java index fb9613f7..7178328d 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/Setting.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/Setting.java @@ -23,23 +23,31 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import org.bukkit.Bukkit; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.objects.IllegalItemList; +import org.shanerx.tradeshop.item.IllegalItemList; +import org.shanerx.tradeshop.item.ShopItemStackSettingKeys; +import org.shanerx.tradeshop.shop.ShopSettingKeys; +import org.shanerx.tradeshop.shop.ShopSign; +import org.shanerx.tradeshop.shop.ShopType; import org.yaml.snakeyaml.Yaml; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.List; -import java.util.Objects; +import java.util.Map; +import java.util.Set; public enum Setting { // PostComment " " adds single newline below setting and "\n" adds 2 newlines below // PreComment `/n ` will have a new comment marker added after a sufficient space for proper formatting - CONFIG_VERSION(SettingSection.NONE, "config-version", 0.0), + CONFIG_VERSION(SettingSection.NONE, "config-version", 1.3), // System Options DATA_STORAGE_TYPE(SettingSection.SYSTEM_OPTIONS, "data-storage-type", "FLATFILE"), @@ -47,10 +55,9 @@ public enum Setting { CHECK_UPDATES(SettingSection.SYSTEM_OPTIONS, "check-updates", true), ALLOW_METRICS(SettingSection.SYSTEM_OPTIONS, "allow-metrics", true), UNLIMITED_ADMIN(SettingSection.SYSTEM_OPTIONS, "unlimited-admin", false), - USE_INTERNAL_PERMISSIONS(SettingSection.SYSTEM_OPTIONS, "use-internal-permissions", false), // Language Options - MESSAGE_PREFIX(SettingSection.LANGUAGE_OPTIONS, "message-prefix", "&a[&eTradeShop&a] "), + MESSAGE_PREFIX(SettingSection.LANGUAGE_OPTIONS, "message-prefix", "&a[&eTradeShop&a]"), SHOP_GOOD_COLOUR(SettingSection.LANGUAGE_OPTIONS, "shop-good-colour", "&2"), SHOP_INCOMPLETE_COLOUR(SettingSection.LANGUAGE_OPTIONS, "shop-incomplete-colour", "&7"), @@ -62,7 +69,7 @@ public enum Setting { SHOP_OUTOFSTOCK_STATUS(SettingSection.LANGUAGE_OPTIONS, "shop-outofstock-status", "&c"), // Global Options - ALLOWED_DIRECTIONS(SettingSection.GLOBAL_OPTIONS, "allowed-directions", new String[]{"DOWN", "WEST", "SOUTH", "EAST", "NORTH", "UP"}), + CHEST_DIRECTIONS(SettingSection.GLOBAL_OPTIONS, "chest-directions", new String[]{"BACK", "DOWN", "LEFT", "RIGHT", "UP", "FRONT"}), ALLOWED_SHOPS(SettingSection.GLOBAL_OPTIONS, "allowed-shops", new String[]{"CHEST", "TRAPPED_CHEST", "SHULKER"}), MAX_EDIT_DISTANCE(SettingSection.GLOBAL_OPTIONS, "max-edit-distance", 4), ALLOW_TOGGLE_STATUS(SettingSection.GLOBAL_OPTIONS, "allow-toggle-status", true), @@ -74,46 +81,51 @@ public enum Setting { MULTI_TRADE_DEFAULT(SettingSection.GLOBAL_MULTI_TRADE, "default-multi", 2), MULTI_TRADE_MAX(SettingSection.GLOBAL_MULTI_TRADE, "max-multi", 6), - // Illegal Item Options - GLOBAL_ILLEGAL_ITEMS_TYPE(SettingSection.GLOBAL_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.BLACKLIST.toString()), - GLOBAL_ILLEGAL_ITEMS_LIST(SettingSection.GLOBAL_ILLEGAL_ITEMS, "list", new String[]{"Bedrock", "Command_Block", "Barrier"}), - COST_ILLEGAL_ITEMS_TYPE(SettingSection.COST_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.DISABLED.toString()), - COST_ILLEGAL_ITEMS_LIST(SettingSection.COST_ILLEGAL_ITEMS, "list", new String[]{}), - PRODUCT_ILLEGAL_ITEMS_TYPE(SettingSection.PRODUCT_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.DISABLED.toString()), - PRODUCT_ILLEGAL_ITEMS_LIST(SettingSection.PRODUCT_ILLEGAL_ITEMS, "list", new String[]{}), - // Shop Options MAX_SHOP_USERS(SettingSection.SHOP_OPTIONS, "max-shop-users", 5), MAX_SHOPS_PER_CHUNK(SettingSection.SHOP_OPTIONS, "max-shops-per-chunk", 128), MAX_ITEMS_PER_TRADE_SIDE(SettingSection.SHOP_OPTIONS, "max-items-per-trade-side", 6), ALLOW_USER_PURCHASING(SettingSection.SHOP_OPTIONS, "allow-user-purchasing", false), MULTIPLE_ITEMS_ON_SIGN(SettingSection.SHOP_OPTIONS, "multiple-items-on-sign", "Use '/ts what'"), + NO_COST_TEXT(SettingSection.SHOP_OPTIONS, "no-cost-text", "nothing"), + NO_COST_AMOUNT(SettingSection.SHOP_OPTIONS, "no-cost-amount", "1"), + + SHOP_PER_ITEM_SETTINGS(SettingSection.SHOP_ITEM_OPTIONS, "shop-per-item-settings", ShopItemStackSettingKeys.getDefaultConfigMap()), + + SHOP_SIGN_DEFAULT_COLOURS(SettingSection.SHOP_SIGN_OPTIONS, "sign-default-colours", ShopSign.getDefaultColourMap()), // Trade Shop Options TRADESHOP_HEADER(SettingSection.TRADE_SHOP_OPTIONS, "header", "Trade"), TRADESHOP_EXPLODE(SettingSection.TRADE_SHOP_OPTIONS, "allow-explode", false), - TRADESHOP_HOPPER_EXPORT(SettingSection.TRADE_SHOP_OPTIONS, "allow-hopper-export", false), - TRADESHOP_HOPPER_IMPORT(SettingSection.TRADE_SHOP_OPTIONS, "allow-hopper-import", false), + TRADE_PER_SHOP_SETTINGS(SettingSection.TRADE_SHOP_OPTIONS, "trade-per-shop-settings", ShopSettingKeys.getSettingConfigMap(ShopType.TRADE)), // ITrade Shop Options ITRADESHOP_OWNER(SettingSection.ITRADE_SHOP_OPTIONS, "owner", "Server Shop"), ITRADESHOP_HEADER(SettingSection.ITRADE_SHOP_OPTIONS, "header", "iTrade"), ITRADESHOP_EXPLODE(SettingSection.ITRADE_SHOP_OPTIONS, "allow-explode", false), - ITRADESHOP_NO_COST_TEXT(SettingSection.ITRADE_SHOP_OPTIONS, "no-cost-text", "nothing"), - ITRADESHOP_NO_COST_AMOUNT(SettingSection.ITRADE_SHOP_OPTIONS, "no-cost-amount", "1"), + ITRADE_PER_SHOP_SETTINGS(SettingSection.ITRADE_SHOP_OPTIONS, "itrade-per-shop-settings", ShopSettingKeys.getSettingConfigMap(ShopType.ITRADE)), // BiTrade Shop Options BITRADESHOP_HEADER(SettingSection.BITRADE_SHOP_OPTIONS, "header", "BiTrade"), BITRADESHOP_EXPLODE(SettingSection.BITRADE_SHOP_OPTIONS, "allow-explode", false), - BITRADESHOP_HOPPER_EXPORT(SettingSection.BITRADE_SHOP_OPTIONS, "allow-hopper-export", false), - BITRADESHOP_HOPPER_IMPORT(SettingSection.BITRADE_SHOP_OPTIONS, "allow-hopper-import", false); + BITRADE_PER_SHOP_SETTINGS(SettingSection.BITRADE_SHOP_OPTIONS, "bitrade-per-shop-settings", ShopSettingKeys.getSettingConfigMap(ShopType.BITRADE)), - public static final TradeShop PLUGIN = Objects.requireNonNull((TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop")); + // Illegal Item Options + GLOBAL_ILLEGAL_ITEMS_TYPE(SettingSection.GLOBAL_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.BLACKLIST.toString()), + GLOBAL_ILLEGAL_ITEMS_LIST(SettingSection.GLOBAL_ILLEGAL_ITEMS, "list", new String[]{"Bedrock", "Command_Block", "Barrier"}), + COST_ILLEGAL_ITEMS_TYPE(SettingSection.COST_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.DISABLED.toString()), + COST_ILLEGAL_ITEMS_LIST(SettingSection.COST_ILLEGAL_ITEMS, "list", new String[]{}), + PRODUCT_ILLEGAL_ITEMS_TYPE(SettingSection.PRODUCT_ILLEGAL_ITEMS, "type", IllegalItemList.ListType.DISABLED.toString()), + PRODUCT_ILLEGAL_ITEMS_LIST(SettingSection.PRODUCT_ILLEGAL_ITEMS, "list", new String[]{}); + + public static final TradeShop PLUGIN = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); private final String key, path; private final Object defaultValue; private final SettingSection section; + private final String leadIncrease = " "; + Setting(SettingSection section, String key, Object defaultValue) { this.section = section; this.key = key; @@ -126,8 +138,9 @@ public static Setting findSetting(String search) { } // Method to fix any values that have changed with updates - static void upgrade() { + static boolean upgrade() { double version = CONFIG_VERSION.getDouble(); + Set hasUpgraded = new HashSet<>(); // Uses this instead of a boolean to later replace below ifs with boolean return methods... ConfigManager configManager = PLUGIN.getSettingManager(); // 2.2.2 Changed enable debug from true/false to integer @@ -140,46 +153,55 @@ static void upgrade() { if (configManager.getConfig().contains("itradeshop.owner")) { configManager.getConfig().set(ITRADESHOP_OWNER.path, configManager.getConfig().get("itradeshop.owner")); configManager.getConfig().set("itradeshop.owner", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("itradeshop.header")) { configManager.getConfig().set(ITRADESHOP_HEADER.path, configManager.getConfig().get("itradeshop.header")); configManager.getConfig().set("itradeshop.header", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("itradeshop.allow-explode")) { configManager.getConfig().set(ITRADESHOP_EXPLODE.path, configManager.getConfig().get("itradeshop.allow-explode")); configManager.getConfig().set("itradeshop.allow-explode", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("tradeshop.header")) { configManager.getConfig().set(TRADESHOP_HEADER.path, configManager.getConfig().get("tradeshop.header")); configManager.getConfig().set("tradeshop.header", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("tradeshop.allow-explode")) { configManager.getConfig().set(TRADESHOP_EXPLODE.path, configManager.getConfig().get("tradeshop.allow-explode")); configManager.getConfig().set("tradeshop.allow-explode", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("tradeshop.allow-hopper-export")) { - configManager.getConfig().set(TRADESHOP_HOPPER_EXPORT.path, configManager.getConfig().get("tradeshop.allow-hopper-export")); + configManager.getConfig().set("trade-shop-options.allow-hopper-export", configManager.getConfig().get("tradeshop.allow-hopper-export")); configManager.getConfig().set("tradeshop.allow-hopper-export", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("bitradeshop.header")) { configManager.getConfig().set(BITRADESHOP_HEADER.path, configManager.getConfig().get("bitradeshop.header")); configManager.getConfig().set("bitradeshop.header", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("bitradeshop.allow-explode")) { configManager.getConfig().set(BITRADESHOP_EXPLODE.path, configManager.getConfig().get("bitradeshop.allow-explode")); configManager.getConfig().set("bitradeshop.allow-explode", null); + hasUpgraded.add(true); } if (configManager.getConfig().contains("bitradeshop.allow-hopper-export")) { - configManager.getConfig().set(BITRADESHOP_HOPPER_EXPORT.path, configManager.getConfig().get("bitradeshop.allow-hopper-export")); + configManager.getConfig().set("bitrade-shop-options.allow-hopper-export", configManager.getConfig().get("bitradeshop.allow-hopper-export")); configManager.getConfig().set("bitradeshop.allow-hopper-export", null); + hasUpgraded.add(true); } @@ -191,12 +213,61 @@ static void upgrade() { configManager.getConfig().set(GLOBAL_ILLEGAL_ITEMS_LIST.path, configManager.getConfig().get("global-options.illegal-items")); GLOBAL_ILLEGAL_ITEMS_LIST.setValue(configManager.getConfig().getStringList("global-options.illegal-items").removeAll(Arrays.asList("Air", "Void_Air", "Cave_Air"))); configManager.getConfig().set("global-options.illegal-items", null); + hasUpgraded.add(true); } version = 1.2; } + if (version < 1.3) { + String oldKey = "itrade-shop-options.no-cost-text"; + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(NO_COST_TEXT.path, configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + oldKey = "itrade-shop-options.no-cost-amount"; + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(NO_COST_AMOUNT.path, configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + oldKey = "bitrade-shop-options.allow-hopper-export"; + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(BITRADE_PER_SHOP_SETTINGS.getPath() + ".allow-hopper-export", configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + oldKey = "bitrade-shop-options.allow-hopper-import";// + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(BITRADE_PER_SHOP_SETTINGS.getPath() + ".allow-hopper-import", configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + oldKey = "trade-shop-options.allow-hopper-export";// + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(TRADE_PER_SHOP_SETTINGS.getPath() + ".allow-hopper-export", configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + oldKey = "trade-shop-options.allow-hopper-import";// + if (configManager.getConfig().contains(oldKey)) { + configManager.getConfig().set(TRADE_PER_SHOP_SETTINGS.getPath() + ".allow-hopper-import", configManager.getConfig().get(oldKey)); + configManager.getConfig().set(oldKey, null); + hasUpgraded.add(true); + } + + version = 1.3; + } + CONFIG_VERSION.setValue(version); + + return hasUpgraded.contains(true); } public String getKey() { @@ -207,12 +278,24 @@ public Object getDefaultValue() { return defaultValue; } + public String getMappedString(String subKey) { + return PLUGIN.getSettingManager().getConfig().getConfigurationSection(getPath()).getString(subKey.toLowerCase().replace("_", "-")); + } + + public boolean getMappedBoolean(String subKey) { + return PLUGIN.getSettingManager().getConfig().getConfigurationSection(getPath()).getBoolean(subKey.toLowerCase().replace("_", "-")); + } + + public Object getMappedObject(String subKey) { + return PLUGIN.getSettingManager().getConfig().getConfigurationSection(getPath()).get(subKey.toLowerCase().replace("_", "-")); + } + public String getPostComment() { - return PLUGIN.getLanguage().getPostComment(Language.LangSection.SETTING, path); + return PLUGIN.getLanguage().getPostComment(Language.LangSection.SETTING, Language.LangSubSection.VALUES, path); } public String getPreComment() { - return PLUGIN.getLanguage().getPreComment(Language.LangSection.SETTING, path); + return PLUGIN.getLanguage().getPreComment(Language.LangSection.SETTING, Language.LangSubSection.VALUES, path); } public SettingSection getSection() { @@ -223,6 +306,27 @@ public String getPath() { return path; } + private String processMapValue(Map valueMap, String localLead) { + StringBuilder processed = new StringBuilder(); + + List sortedKeys = new ArrayList<>(valueMap.keySet()); + Collections.sort(sortedKeys, (o1, o2) -> o1.toString().compareTo(o1.toString())); + + //PLUGIN.getDebugger().log("Sorted Value: " + sortedValue +"\nValue: " + valueMap, DebugLevels.DATA_ERROR); + + for (Object key : sortedKeys) { + Object value = valueMap.get(key); + if (value instanceof Map) { + processed.append(localLead).append(key.toString()).append(":\n"); + processed.append(processMapValue(((Map) value), localLead + leadIncrease)); + } else { + processed.append(localLead).append(key.toString()).append(": ").append(new Yaml().dump(value)); + } + } + + return processed.toString(); + } + public String getFileString() { StringBuilder keyOutput = new StringBuilder(); @@ -230,7 +334,12 @@ public String getFileString() { keyOutput.append(section.getSectionLead()).append("# ").append(PLUGIN.getSettingManager().fixCommentNewLines(section.getSectionLead(), getPreComment())).append("\n"); } - keyOutput.append(section.getSectionLead()).append(getKey()).append(": ").append(new Yaml().dump(getSetting())); + if (defaultValue instanceof Map) { + keyOutput.append(section.getSectionLead()).append(getKey()).append(":\n"); + keyOutput.append(processMapValue(((Map) defaultValue), section.getSectionLead() + leadIncrease)); + } else { + keyOutput.append(section.getSectionLead()).append(getKey()).append(": ").append(new Yaml().dump(getSetting())); + } if (!getPostComment().isEmpty()) { if (getPostComment().equals(" ") || getPostComment().equals("\n")) @@ -246,6 +355,11 @@ public void setValue(Object obj) { PLUGIN.getSettingManager().getConfig().set(getPath(), obj); } + public void setMappedValue(String subKey, Object obj) { + String newNode = getPath() + "." + subKey; + PLUGIN.getSettingManager().getConfig().set(newNode, obj); + } + public void clearSetting() { PLUGIN.getSettingManager().getConfig().set(getPath(), null); } @@ -254,7 +368,7 @@ public Object getSetting() { return PLUGIN.getSettingManager().getConfig().get(getPath()); } - public String getString() { + public String getString() { return PLUGIN.getSettingManager().getConfig().getString(getPath()); } diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/SettingSection.java b/src/main/java/org/shanerx/tradeshop/data/config/SettingSection.java similarity index 82% rename from src/main/java/org/shanerx/tradeshop/utils/config/SettingSection.java rename to src/main/java/org/shanerx/tradeshop/data/config/SettingSection.java index f8fb6788..15a2ef44 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/SettingSection.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/SettingSection.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; import org.bukkit.Bukkit; import org.shanerx.tradeshop.TradeShop; @@ -32,19 +32,26 @@ public enum SettingSection { + //Weight for primary Sections should start at 0 and each sub-section should start at increments of 50 + NONE(0, ""), SYSTEM_OPTIONS(1, "system-options"), LANGUAGE_OPTIONS(2, "language-options"), GLOBAL_OPTIONS(3, "global-options"), - GLOBAL_MULTI_TRADE(0, GLOBAL_OPTIONS, "multi-trade"), + GLOBAL_MULTI_TRADE(50, GLOBAL_OPTIONS, "multi-trade"), SHOP_OPTIONS(4, "shop-options"), - TRADE_SHOP_OPTIONS(6, "trade-shop-options"), - ITRADE_SHOP_OPTIONS(7, "itrade-shop-options"), - BITRADE_SHOP_OPTIONS(8, "bitrade-shop-options"), - ILLEGAL_ITEM_OPTIONS(9, "illegal-item-options"), - GLOBAL_ILLEGAL_ITEMS(0, ILLEGAL_ITEM_OPTIONS, "global-illegal-items"), - COST_ILLEGAL_ITEMS(1, ILLEGAL_ITEM_OPTIONS, "cost-illegal-items"), - PRODUCT_ILLEGAL_ITEMS(2, ILLEGAL_ITEM_OPTIONS, "product-illegal-items"); + + SHOP_ITEM_OPTIONS(5, SHOP_OPTIONS, "shop-per-item-options"), + + SHOP_SIGN_OPTIONS(6, "shop-sign-options"), + + TRADE_SHOP_OPTIONS(7, "trade-shop-options"), + ITRADE_SHOP_OPTIONS(8, "itrade-shop-options"), + BITRADE_SHOP_OPTIONS(9, "bitrade-shop-options"), + ILLEGAL_ITEM_OPTIONS(10, "illegal-item-options"), + GLOBAL_ILLEGAL_ITEMS(50, ILLEGAL_ITEM_OPTIONS, "global-illegal-items"), + COST_ILLEGAL_ITEMS(51, ILLEGAL_ITEM_OPTIONS, "cost-illegal-items"), + PRODUCT_ILLEGAL_ITEMS(52, ILLEGAL_ITEM_OPTIONS, "product-illegal-items"); public static final TradeShop PLUGIN = Objects.requireNonNull((TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop")); @@ -60,7 +67,7 @@ public enum SettingSection { this.weight = weight; this.key = key; this.parent = parent; - this.lineLead = !key.isEmpty() ? parent != null ? parent.lineLead + " " : " " : ""; + this.lineLead = !key.isEmpty() ? " " : ""; } public String getKey() { @@ -88,15 +95,15 @@ public boolean hasParent() { } public String getPostComment() { - return PLUGIN.getLanguage().getPostComment(Language.LangSection.SETTING_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getPostComment(Language.LangSection.SETTING, Language.LangSubSection.SECTIONS, key); } public String getPreComment() { - return PLUGIN.getLanguage().getPreComment(Language.LangSection.SETTING_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getPreComment(Language.LangSection.SETTING, Language.LangSubSection.SECTIONS, key); } public String getSectionHeader() { - return PLUGIN.getLanguage().getHeader(Language.LangSection.SETTING_SECTION, name().toLowerCase().replace("_", "-")); + return PLUGIN.getLanguage().getHeader(Language.LangSection.SETTING, Language.LangSubSection.SECTIONS, key); } public String getFileString() { @@ -130,7 +137,7 @@ public String getFileString() { } // Add Sections Key line - sectionHeader.append(getLineLead()).append(getKey()).append(": ").append("\n"); + sectionHeader.append(getLineLead()).append(getKey()).append(": \n"); // If Section has a Post Comment add it if (!getPostComment().isEmpty()) { diff --git a/src/main/java/org/shanerx/tradeshop/utils/config/Variable.java b/src/main/java/org/shanerx/tradeshop/data/config/Variable.java similarity index 94% rename from src/main/java/org/shanerx/tradeshop/utils/config/Variable.java rename to src/main/java/org/shanerx/tradeshop/data/config/Variable.java index 0c32a0ce..2d9679c5 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/config/Variable.java +++ b/src/main/java/org/shanerx/tradeshop/data/config/Variable.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.config; +package org.shanerx.tradeshop.data.config; public enum Variable { @@ -44,7 +44,9 @@ public enum Variable { STATE, MISSING_ITEMS, RECEIVED_LINES, - GIVEN_LINES; + GIVEN_LINES, + UPDATED_SHOPS, + SHOP; final String SURROUND = "%"; diff --git a/src/main/java/org/shanerx/tradeshop/data/storage/DataStorage.java b/src/main/java/org/shanerx/tradeshop/data/storage/DataStorage.java new file mode 100644 index 00000000..06ccf458 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/data/storage/DataStorage.java @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.data.storage; + +import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Chunk; +import org.bukkit.World; +import org.shanerx.tradeshop.data.storage.Json.JsonLinkageConfiguration; +import org.shanerx.tradeshop.data.storage.Json.JsonPlayerConfiguration; +import org.shanerx.tradeshop.data.storage.Json.JsonShopConfiguration; +import org.shanerx.tradeshop.player.PlayerSetting; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shoplocation.ShopChunk; +import org.shanerx.tradeshop.shoplocation.ShopLocation; +import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; + +import java.io.File; +import java.util.UUID; + +public class DataStorage extends Utils { + + private transient DataType dataType; + + public DataStorage(DataType dataType) { + reload(dataType); + } + + public void reload(DataType dataType) { + this.dataType = dataType; + PLUGIN.getDebugger().log("Data storage set to: " + dataType.name(), DebugLevels.DISABLED); + } + + public Shop loadShopFromSign(ShopLocation sign) { + return getShopConfiguration(sign.getChunk()).load(sign); + } + + public Shop loadShopFromStorage(ShopLocation chest) { + return loadShopFromSign(getLinkageConfiguration(chest.getWorld()).getLinkedShop(chest)); + } + + public void saveShop(Shop shop) { + getShopConfiguration(shop.getShopLocation().getChunk()).save(shop); + } + + public void removeShop(Shop shop) { + getShopConfiguration(shop.getShopLocation().getChunk()).remove(shop.getShopLocationAsSL()); + getLinkageConfiguration(shop.getShopLocationAsSL().getWorld()).removeShop(shop.getShopLocationAsSL()); + } + + public int getShopCountInChunk(Chunk chunk) { + return getShopConfiguration(chunk).size(); + } + + public int getShopCountInWorld(World world) { + int count = 0; + switch (dataType) { + case FLATFILE: + File folder = new File(PLUGIN.getDataFolder().getAbsolutePath() + File.separator + "Data" + File.separator + world.getName()); + if (folder.exists() && folder.listFiles() != null) { + for (File file : folder.listFiles()) { + if (file.getName().contains(world.getName())) + count += new JsonShopConfiguration(ShopChunk.fromString(file.getName().replace(".json", ""))).size(); + } + } + break; + case SQLITE: + //TODO add SQLITE support + throw new NotImplementedException("SQLITE for getShopCountInWorld has not been implemented yet."); + } + return count; + } + + public PlayerSetting loadPlayer(UUID uuid) { + PlayerSetting playerSetting = getPlayerConfiguration(uuid).load(); + + //If playerSetting data not find create new and return + return playerSetting != null ? playerSetting : new PlayerSetting(uuid); + } + + public void savePlayer(PlayerSetting playerSetting) { + getPlayerConfiguration(playerSetting.getUuid()).save(playerSetting); + } + + public void removePlayer(PlayerSetting playerSetting) { + getPlayerConfiguration(playerSetting.getUuid()).remove(); + } + + public ShopLocation getChestLinkage(ShopLocation chestLocation) { + return getLinkageConfiguration(chestLocation.getWorld()).getLinkedShop(chestLocation); + } + + public void addChestLinkage(ShopLocation chestLocation, ShopLocation shopLocation) { + getLinkageConfiguration(chestLocation.getWorld()).add(chestLocation, shopLocation); + } + + public void removeChestLinkage(ShopLocation chestLocation) { + getLinkageConfiguration(chestLocation.getWorld()).removeChest(chestLocation); + } + + protected PlayerConfiguration getPlayerConfiguration(UUID uuid) { + if (dataType == DataType.FLATFILE) { + return new JsonPlayerConfiguration(uuid); + } + throw new NotImplementedException("Data storage type " + dataType + " has not been implemented yet."); + } + + protected ShopConfiguration getShopConfiguration(Chunk chunk) { + return getShopConfiguration(new ShopChunk(chunk)); + } + + protected ShopConfiguration getShopConfiguration(ShopChunk chunk) { + if (dataType == DataType.FLATFILE) { + return new JsonShopConfiguration(chunk); + } + throw new NotImplementedException("Data storage type " + dataType + " has not been implemented yet."); + } + + protected LinkageConfiguration getLinkageConfiguration(World w) { + if (dataType == DataType.FLATFILE) { + return new JsonLinkageConfiguration(w); + } + throw new NotImplementedException("Data storage type " + dataType + " has not been implemented yet."); + } +} + diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/DataType.java b/src/main/java/org/shanerx/tradeshop/data/storage/DataType.java similarity index 96% rename from src/main/java/org/shanerx/tradeshop/utils/data/DataType.java rename to src/main/java/org/shanerx/tradeshop/data/storage/DataType.java index b814175f..b200e99e 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/data/DataType.java +++ b/src/main/java/org/shanerx/tradeshop/data/storage/DataType.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.data; +package org.shanerx.tradeshop.data.storage; public enum DataType { FLATFILE, diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/Json/JsonConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonConfiguration.java similarity index 98% rename from src/main/java/org/shanerx/tradeshop/utils/data/Json/JsonConfiguration.java rename to src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonConfiguration.java index 4c3a5ac1..3080720e 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/data/Json/JsonConfiguration.java +++ b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonConfiguration.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils.data.Json; +package org.shanerx.tradeshop.data.storage.Json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; diff --git a/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonLinkageConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonLinkageConfiguration.java new file mode 100644 index 00000000..8cfb0eb7 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonLinkageConfiguration.java @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.data.storage.Json; + +import com.google.gson.reflect.TypeToken; +import org.bukkit.World; +import org.shanerx.tradeshop.data.storage.LinkageConfiguration; + +import java.util.HashMap; +import java.util.Map; + +public class JsonLinkageConfiguration extends JsonConfiguration implements LinkageConfiguration { + + Map linkageData; + + public JsonLinkageConfiguration(World world) { + super(world.getName(), "chest_linkage"); + load(); + } + + @Override + public void load() { + linkageData = gson.fromJson(jsonObj.get("linkage_data"), new TypeToken>() { + }.getType()); + if (linkageData == null) + linkageData = new HashMap<>(); + } + + @Override + public Map getLinkageData() { + return linkageData; + } + + @Override + public void save() { + jsonObj.add("linkage_data", gson.toJsonTree(linkageData)); + + saveFile(); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/Json/PlayerConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonPlayerConfiguration.java similarity index 85% rename from src/main/java/org/shanerx/tradeshop/utils/data/Json/PlayerConfiguration.java rename to src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonPlayerConfiguration.java index c06440e1..8bd4a946 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/data/Json/PlayerConfiguration.java +++ b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonPlayerConfiguration.java @@ -23,25 +23,27 @@ * */ -package org.shanerx.tradeshop.utils.data.Json; +package org.shanerx.tradeshop.data.storage.Json; import com.google.gson.reflect.TypeToken; -import org.shanerx.tradeshop.objects.PlayerSetting; +import org.shanerx.tradeshop.data.storage.PlayerConfiguration; +import org.shanerx.tradeshop.player.PlayerSetting; import java.util.Map; import java.util.UUID; -public class PlayerConfiguration extends JsonConfiguration { +public class JsonPlayerConfiguration extends JsonConfiguration implements PlayerConfiguration { private final transient UUID playerUUID; private transient PlayerSetting playerSetting; - public PlayerConfiguration(UUID uuid) { + public JsonPlayerConfiguration(UUID uuid) { super("Players", uuid.toString()); playerUUID = uuid; } + @Override public void save(PlayerSetting playerSetting) { this.playerSetting = playerSetting; jsonObj.add(playerSetting.getUuid().toString(), gson.toJsonTree(playerSetting)); @@ -49,6 +51,7 @@ public void save(PlayerSetting playerSetting) { saveFile(); } + @Override public PlayerSetting load() { if (jsonObj.has("data")) { playerSetting = new PlayerSetting(playerUUID, gson.fromJson(jsonObj.get("data"), new TypeToken>() { @@ -65,6 +68,7 @@ public PlayerSetting load() { return playerSetting; } + @Override public void remove() { file.delete(); } diff --git a/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonShopConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonShopConfiguration.java new file mode 100644 index 00000000..3b45aea0 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/data/storage/Json/JsonShopConfiguration.java @@ -0,0 +1,100 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.data.storage.Json; + +import com.google.common.collect.Sets; +import com.google.gson.JsonElement; +import org.shanerx.tradeshop.data.storage.ShopConfiguration; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shoplocation.ShopChunk; +import org.shanerx.tradeshop.shoplocation.ShopLocation; + +import java.io.File; +import java.util.Map; + +public class JsonShopConfiguration extends JsonConfiguration implements ShopConfiguration { + + private final ShopChunk chunk; + + public JsonShopConfiguration(ShopChunk chunk) { + super(chunk.getWorld().getName(), chunk.toString()); + this.chunk = chunk; + } + + @Override + public void loadFile() { + if (!this.file.exists()) { + // If could not find file try with old separators + String oldFile = path + File.separator + chunk.toString().replace(";;", "_") + ".json"; + if (new File(oldFile).exists()) + new File(oldFile).renameTo(file); + } + + super.loadFile(); + + for (Map.Entry entry : Sets.newHashSet(jsonObj.entrySet())) { + if (entry.getKey().contains("l_")) { + jsonObj.add(ShopLocation.fromString(entry.getKey()).toString(), entry.getValue()); + jsonObj.remove(entry.getKey()); + } + } + } + + @Override + public void save(Shop shop) { + jsonObj.add(shop.getShopLocationAsSL().toString(), gson.toJsonTree(shop)); + + saveFile(); + } + + @Override + public void remove(ShopLocation loc) { + if (jsonObj.has(loc.toString())) + jsonObj.remove(loc.toString()); + + saveFile(); + } + + @Override + public Shop load(ShopLocation loc) { + Shop shop; + String locStr = loc.toString(); + + if (!jsonObj.has(locStr)) { + return null; + } + + shop = gson.fromJson(jsonObj.get(locStr), Shop.class); + + shop.fixAfterLoad(); + return shop; + } + + @Override + public int size() { + return jsonObj.size(); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/data/storage/LinkageConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/LinkageConfiguration.java new file mode 100644 index 00000000..53d9a330 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/data/storage/LinkageConfiguration.java @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.data.storage; + +import org.shanerx.tradeshop.shop.ShopChest; +import org.shanerx.tradeshop.shoplocation.ShopLocation; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public interface LinkageConfiguration { + + void save(); + + void load(); + + Map getLinkageData(); + + default ShopLocation getLinkedShop(ShopLocation chestLocation) { + String loc = chestLocation.toString(); + return getLinkageData().containsKey(loc) ? ShopLocation.fromString(getLinkageData().get(chestLocation.toString())) : null; + } + + default int size() { + return getLinkageData().size(); + } + + default void addLinkage(ShopLocation chestLocation, ShopLocation shopLocation) { + if (getLinkageData().containsKey(chestLocation.toString())) + getLinkageData().replace(chestLocation.toString(), shopLocation.toString()); + else + getLinkageData().put(chestLocation.toString(), shopLocation.toString()); + save(); + } + + default void add(ShopLocation chestLocation, ShopLocation shopLocation) { + if (ShopChest.isDoubleChest(chestLocation.getLocation().getBlock())) { + ShopLocation otherSideLocation = new ShopLocation(ShopChest.getOtherHalfOfDoubleChest(chestLocation.getLocation().getBlock()).getLocation()); + addLinkage(otherSideLocation, shopLocation); + } + + addLinkage(chestLocation, shopLocation); + save(); + } + + default void removeChest(ShopLocation chestLocation) { + getLinkageData().remove(chestLocation); + save(); + } + + default void removeShop(ShopLocation shopLocation) { + List removeChests = new ArrayList<>(); + String shopLoc = shopLocation.toString(); + + getLinkageData().forEach((key, value) -> { + if (value.equals(shopLoc)) + removeChests.add(key); + }); + + removeChests.forEach((k) -> getLinkageData().remove(k)); + save(); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/ObjectHolder.java b/src/main/java/org/shanerx/tradeshop/data/storage/PlayerConfiguration.java similarity index 80% rename from src/main/java/org/shanerx/tradeshop/utils/ObjectHolder.java rename to src/main/java/org/shanerx/tradeshop/data/storage/PlayerConfiguration.java index 5fef81db..7bcb4092 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/ObjectHolder.java +++ b/src/main/java/org/shanerx/tradeshop/data/storage/PlayerConfiguration.java @@ -23,22 +23,15 @@ * */ -package org.shanerx.tradeshop.utils; +package org.shanerx.tradeshop.data.storage; -public class ObjectHolder { +import org.shanerx.tradeshop.player.PlayerSetting; - private final Type obj; +public interface PlayerConfiguration { - public ObjectHolder(Type obj) { - this.obj = obj; - } + void save(PlayerSetting playerSetting); - public Type getObject() { - return obj; - } + PlayerSetting load(); - @Override - public String toString() { - return obj.toString(); - } + void remove(); } diff --git a/src/main/java/org/shanerx/tradeshop/data/storage/ShopConfiguration.java b/src/main/java/org/shanerx/tradeshop/data/storage/ShopConfiguration.java new file mode 100644 index 00000000..ccff0eda --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/data/storage/ShopConfiguration.java @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.data.storage; + +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shoplocation.ShopLocation; + +public interface ShopConfiguration { + + void save(Shop shop); + + void remove(ShopLocation loc); + + Shop load(ShopLocation loc); + + int size(); +} diff --git a/src/main/java/org/shanerx/tradeshop/enumys/Permissions.java b/src/main/java/org/shanerx/tradeshop/enumys/Permissions.java deleted file mode 100644 index 3502cf54..00000000 --- a/src/main/java/org/shanerx/tradeshop/enumys/Permissions.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.enumys; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.shanerx.tradeshop.TradeShop; - -public enum Permissions { - - HELP("help", 0), - - CREATE("create", 0), - - CREATEI("create.infinite", 1), - - CREATEBI("create.bi", 0), - - ADMIN("admin", 1), - - EDIT("edit", 0), // non admin perm - - INFO("info", 0), - - MANAGE_PLUGIN("manage-plugin", 2), - - PREVENT_TRADE("prevent-trade", -1), - - NONE("", 0); - - private final static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); - private final String key; - private final int level; - - Permissions(String key, int level) { - this.key = key; - this.level = level; - } - - @Override - public String toString() { - return "tradeshop." + key; - } - - public String getValue() { - return this.toString(); - } - - public Permission getPerm() { - return new Permission(toString()); - } - - public static boolean hasPermission(Player player, Permissions permission) { - if (plugin.useInternalPerms()) { - return plugin.getDataStorage().loadPlayer(player.getUniqueId()).getType() >= permission.getLevel(); - } else { - return permission.equals(Permissions.NONE) || player.hasPermission(permission.getPerm()); - } - } - - - public static boolean isAdminEnabled(Player player) { - return hasPermission(player, Permissions.ADMIN) && plugin.getDataStorage().loadPlayer(player.getUniqueId()).isAdminEnabled(); - } - - public int getLevel() { - return level; - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopItemStackSettingKeys.java b/src/main/java/org/shanerx/tradeshop/enumys/ShopItemStackSettingKeys.java deleted file mode 100644 index 630eeab8..00000000 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopItemStackSettingKeys.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.enumys; - -import org.shanerx.tradeshop.utils.ObjectHolder; - -public enum ShopItemStackSettingKeys { - - //New per shop settings and their default value should be added below and will be added to the shops - - COMPARE_DURABILITY(new ObjectHolder<>(1)), // -1 == 'off', 0 == '<=', 1 == '==', 2 == '>=' - COMPARE_ENCHANTMENTS(new ObjectHolder<>(true)), - COMPARE_NAME(new ObjectHolder<>(true)), - COMPARE_LORE(new ObjectHolder<>(true)), - COMPARE_CUSTOM_MODEL_DATA(new ObjectHolder<>(true)), - COMPARE_ITEM_FLAGS(new ObjectHolder<>(true)), - COMPARE_UNBREAKABLE(new ObjectHolder<>(true)), - COMPARE_ATTRIBUTE_MODIFIER(new ObjectHolder<>(true)), - COMPARE_BOOK_AUTHOR(new ObjectHolder<>(true)), - COMPARE_BOOK_PAGES(new ObjectHolder<>(true)), - COMPARE_SHULKER_INVENTORY(new ObjectHolder<>(true)), - COMPARE_BUNDLE_INVENTORY(new ObjectHolder<>(true)), - COMPARE_FIREWORK_DURATION(new ObjectHolder<>(true)), - COMPARE_FIREWORK_EFFECTS(new ObjectHolder<>(true)); - - private final ObjectHolder defaultValue; - - ShopItemStackSettingKeys(ObjectHolder defaultValue) { - this.defaultValue = defaultValue; - } - - public ObjectHolder getDefaultValue() { - return defaultValue; - } - - public String makeReadable() { - StringBuilder ret = new StringBuilder(); - - //Replaces '_' with ' ' followed by a Capital letter, other letters are lower cased. - for (int i = 0; i < name().length(); i++) { - char ch = name().charAt(i); - - if (i == 0) - ret.append(Character.toUpperCase(ch)); - else if (ret.charAt(i - 1) == ' ') - ret.append(Character.toUpperCase(ch)); - else if (ch == '_') - ret.append(" "); - else - ret.append(Character.toLowerCase(ch)); - } - - //removes any Leading/Trailing spaces and returns - return ret.toString().trim(); - - } -} diff --git a/src/main/java/org/shanerx/tradeshop/enumys/package-info.java b/src/main/java/org/shanerx/tradeshop/enumys/package-info.java deleted file mode 100644 index 5d2c2bc5..00000000 --- a/src/main/java/org/shanerx/tradeshop/enumys/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This package contains all the enum types the plugin's internal API makes use of. - * We are including them into the javadocs so that you can have a full picture of the - * plugin's API, since the TSAF makes use of it. - */ -package org.shanerx.tradeshop.enumys; \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/framework/ShopChange.java b/src/main/java/org/shanerx/tradeshop/framework/ShopChange.java index a63fdf1f..2c42d466 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/ShopChange.java +++ b/src/main/java/org/shanerx/tradeshop/framework/ShopChange.java @@ -1,12 +1,39 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework; /** * This enum's entries represent the possible changes the {@link org.shanerx.tradeshop.framework.events.PlayerShopChangeEvent} is fired upon. */ public enum ShopChange { - + ADD_MANAGER, ADD_MEMBER, + SET_MANAGER, + SET_MEMBER, ADD_PRODUCT, ADD_COST, REMOVE_USER, diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/HopperShopAccessEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/HopperShopAccessEvent.java index 1c59ddf0..0c3f1c94 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/HopperShopAccessEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/HopperShopAccessEvent.java @@ -1,10 +1,35 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.event.HandlerList; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This event is is fired when a hopper attempts to modify the contents of a shop's inventory. @@ -22,8 +47,17 @@ public enum HopperDirection { private static final HandlerList handlers = new HandlerList(); private Shop shop; private boolean isForbidden; - private HopperDirection dir; - + private final HopperDirection dir; + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + /** * Constructor for the object. * @param s The {@link Shop} object representing the Shop in question. diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPreTradeEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPreTradeEvent.java index 45d3021b..b8ad8774 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPreTradeEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPreTradeEvent.java @@ -32,8 +32,8 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopItemStack; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.shop.Shop; import java.util.List; @@ -45,10 +45,10 @@ public class PlayerPreTradeEvent extends PlayerInteractEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); - private Shop shop; - private List product; - private List cost; - private Block clickedBlock; + private final Shop shop; + private final List product; + private final List cost; + private final Block clickedBlock; private boolean cancelled; /** diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPrepareTradeEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPrepareTradeEvent.java index aad8d84e..741ea6db 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPrepareTradeEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerPrepareTradeEvent.java @@ -32,8 +32,8 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopItemStack; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.shop.Shop; import java.util.List; @@ -45,12 +45,12 @@ public class PlayerPrepareTradeEvent extends PlayerInteractEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); - private Shop shop; - private List product; - private List cost; - private Block clickedBlock; + private final Shop shop; + private final List product; + private final List cost; + private final Block clickedBlock; private boolean cancelled; - + /** * Constructor for the object. * @param who The {@link org.bukkit.entity.Player} object representing the player who is attempting the trade. diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopChangeEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopChangeEvent.java index c12cfd1d..49f38bea 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopChangeEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopChangeEvent.java @@ -1,3 +1,28 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.entity.Player; @@ -5,18 +30,19 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.shanerx.tradeshop.framework.ShopChange; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.utils.ObjectHolder; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; /** * This class represents a {@link org.bukkit.event.Cancellable} event, which gets fired when someone is about to * modify shop information such as product, cost, managers and members. */ public class PlayerShopChangeEvent extends PlayerEvent implements Cancellable { - + private static final HandlerList handlers = new HandlerList(); - private Shop shop; + private final Shop shop; private ObjectHolder what; + private ShopChange change; private boolean cancelled; /** @@ -29,8 +55,14 @@ public class PlayerShopChangeEvent extends PlayerEvent implements Cancellable { public PlayerShopChangeEvent(Player player, Shop s, ShopChange change, ObjectHolder what) { super(player); this.shop = s; + this.what = what; + this.change = change; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; @@ -70,4 +102,13 @@ public void setCancelled(boolean cancelled) { public ObjectHolder getWhat() { return what; } + + /** + * Returns the {@link ShopChange} instance which wraps the object representing the data which is being changed. + * This is an enum type entry which represents which property or attribute was changed. + * @return the type of change. + */ + public ShopChange getChange() { + return change; + } } diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCloseEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCloseEvent.java index a44a0887..26450ed3 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCloseEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCloseEvent.java @@ -1,19 +1,44 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This class represents the event which is fired when the owner of a shop closes the shop. * Since it implements {@link org.bukkit.event.Cancellable}, it is possible to cancel the event. */ public class PlayerShopCloseEvent extends PlayerEvent implements Cancellable { - + private static final HandlerList handlers = new HandlerList(); - private Shop shop; + private final Shop shop; private boolean cancelled; /** @@ -25,7 +50,11 @@ public PlayerShopCloseEvent(Player buyer, Shop s) { super(buyer); this.shop = s; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCreateEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCreateEvent.java index b089e487..af17b28b 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCreateEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopCreateEvent.java @@ -1,10 +1,35 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This class represents the event being fired upon shop creation. It implements {@link org.bukkit.event.Cancellable}, @@ -14,7 +39,7 @@ public class PlayerShopCreateEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean cancelled; - private Shop shop; + private final Shop shop; /** * Constructor for the object. @@ -25,7 +50,11 @@ public PlayerShopCreateEvent(Player p, Shop shop) { super(p); this.shop = shop; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopDestroyEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopDestroyEvent.java index 7f17245d..e94328aa 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopDestroyEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopDestroyEvent.java @@ -29,7 +29,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This class represents the event being fired upon shop creation. It implements {@link org.bukkit.event.Cancellable}, @@ -39,7 +39,7 @@ public class PlayerShopDestroyEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean cancelled, destroyBlock; - private Shop shop; + private final Shop shop; /** * Constructor for the object. @@ -50,7 +50,11 @@ public PlayerShopDestroyEvent(Player p, Shop shop) { super(p); this.shop = shop; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopInventoryOpenEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopInventoryOpenEvent.java index d0dc9122..9ecaccef 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopInventoryOpenEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopInventoryOpenEvent.java @@ -1,3 +1,28 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.block.Block; @@ -8,16 +33,16 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This class represents the event being fired when someone who has the required permissions attempts to open a shop. * It implements {@link org.bukkit.event.Cancellable}, which makes it possible to cancel the event. */ public class PlayerShopInventoryOpenEvent extends PlayerInteractEvent implements Cancellable { - + private static final HandlerList handlers = new HandlerList(); - private Shop shop; + private final Shop shop; private boolean cancelled; /** @@ -33,7 +58,11 @@ public PlayerShopInventoryOpenEvent(Player p, Shop s, Action action, ItemStack i super(p, action, itm, chest, chestFace); this.shop = s; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopOpenEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopOpenEvent.java index 22b4d228..032ae3e4 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopOpenEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerShopOpenEvent.java @@ -1,19 +1,44 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + package org.shanerx.tradeshop.framework.events; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; /** * This class represents the event which is fired when the owner of a shop opens the shop. * Since it implements {@link org.bukkit.event.Cancellable}, it is possible to cancel the event. */ public class PlayerShopOpenEvent extends PlayerEvent implements Cancellable { - + private static final HandlerList handlers = new HandlerList(); - private Shop shop; + private final Shop shop; private boolean cancelled; /** @@ -25,7 +50,11 @@ public PlayerShopOpenEvent(Player buyer, Shop s) { super(buyer); this.shop = s; } - + + public static HandlerList getHandlerList() { + return handlers; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerSuccessfulTradeEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerSuccessfulTradeEvent.java index 19a0051a..7d488155 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/PlayerSuccessfulTradeEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/PlayerSuccessfulTradeEvent.java @@ -32,7 +32,7 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.objects.Shop; +import org.shanerx.tradeshop.shop.Shop; import java.util.List; diff --git a/src/main/java/org/shanerx/tradeshop/framework/events/TradeShopReloadEvent.java b/src/main/java/org/shanerx/tradeshop/framework/events/TradeShopReloadEvent.java index db8d3f2c..8e994004 100644 --- a/src/main/java/org/shanerx/tradeshop/framework/events/TradeShopReloadEvent.java +++ b/src/main/java/org/shanerx/tradeshop/framework/events/TradeShopReloadEvent.java @@ -30,22 +30,22 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.server.ServerEvent; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.objects.Debug; -import org.shanerx.tradeshop.objects.ListManager; -import org.shanerx.tradeshop.utils.data.DataStorage; +import org.shanerx.tradeshop.data.storage.DataStorage; +import org.shanerx.tradeshop.utils.ListManager; +import org.shanerx.tradeshop.utils.debug.Debug; // TODO javadocs for TradeShopReloadEvent public class TradeShopReloadEvent extends ServerEvent { private static final HandlerList handlers = new HandlerList(); + public TradeShop plugin; + public CommandSender sender; + public static HandlerList getHandlerList() { return handlers; } - public TradeShop plugin; - public CommandSender sender; - @Override public HandlerList getHandlers() { return handlers; diff --git a/src/main/java/org/shanerx/tradeshop/objects/IllegalItemList.java b/src/main/java/org/shanerx/tradeshop/item/IllegalItemList.java similarity index 94% rename from src/main/java/org/shanerx/tradeshop/objects/IllegalItemList.java rename to src/main/java/org/shanerx/tradeshop/item/IllegalItemList.java index 3f4e1f99..667c970a 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/IllegalItemList.java +++ b/src/main/java/org/shanerx/tradeshop/item/IllegalItemList.java @@ -23,11 +23,11 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.item; import org.bukkit.Material; -import org.shanerx.tradeshop.enumys.DebugLevels; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; import java.util.ArrayList; import java.util.Arrays; @@ -80,7 +80,7 @@ public void clear() { } public boolean add(Material mat) { - debugger.log("Material being added to Illegal Item List: " + mat, DebugLevels.ILLEGAL_ITEMS_LIST); + PLUGIN.getDebugger().log("Material being added to Illegal Item List: " + mat, DebugLevels.ILLEGAL_ITEMS_LIST); return list.add(mat); } @@ -157,11 +157,4 @@ public enum ListType { DISABLED } - - public enum TradeItemType { - - COST, - PRODUCT - - } } diff --git a/src/main/java/org/shanerx/tradeshop/enumys/NonObtainableMaterials.java b/src/main/java/org/shanerx/tradeshop/item/NonObtainableMaterials.java similarity index 98% rename from src/main/java/org/shanerx/tradeshop/enumys/NonObtainableMaterials.java rename to src/main/java/org/shanerx/tradeshop/item/NonObtainableMaterials.java index d6dc7610..da6583f8 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/NonObtainableMaterials.java +++ b/src/main/java/org/shanerx/tradeshop/item/NonObtainableMaterials.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.item; public enum NonObtainableMaterials { CARROTS, diff --git a/src/main/java/org/shanerx/tradeshop/item/ShopItemSide.java b/src/main/java/org/shanerx/tradeshop/item/ShopItemSide.java new file mode 100644 index 00000000..1733d46b --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/item/ShopItemSide.java @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.item; + +public enum ShopItemSide { + COST, + PRODUCT; + + private final ShopItemSide reverse; + + ShopItemSide() { + this.reverse = this; + } + + public ShopItemSide getReverse() { + return reverse.equals(COST) ? PRODUCT : COST; + } + + +} diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopItemStack.java b/src/main/java/org/shanerx/tradeshop/item/ShopItemStack.java similarity index 79% rename from src/main/java/org/shanerx/tradeshop/objects/ShopItemStack.java rename to src/main/java/org/shanerx/tradeshop/item/ShopItemStack.java index e77fb81a..9899b48b 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopItemStack.java +++ b/src/main/java/org/shanerx/tradeshop/item/ShopItemStack.java @@ -23,75 +23,73 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.item; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; import net.md_5.bungee.api.ChatColor; import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; import org.bukkit.FireworkEffect; import org.bukkit.Material; import org.bukkit.block.ShulkerBox; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; -import org.bukkit.inventory.meta.BookMeta; -import org.bukkit.inventory.meta.BundleMeta; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.EnchantmentStorageMeta; -import org.bukkit.inventory.meta.FireworkMeta; -import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.*; import org.bukkit.util.io.BukkitObjectInputStream; -import org.bukkit.util.io.BukkitObjectOutputStream; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.ShopItemStackSettingKeys; -import org.shanerx.tradeshop.utils.ObjectHolder; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.Debug; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import java.util.Objects; -public class ShopItemStack implements Serializable, Cloneable { +public class ShopItemStack implements Cloneable { private transient ItemStack itemStack; private transient Debug debugger; + @Expose(serialize = false) private String itemStackB64; - private HashMap> shopSettings; + @Expose + private Map serialItemStack; + + @Expose + @SerializedName(value = "itemSettings", alternate = "shopSettings") + private Map> itemSettings; public ShopItemStack(ItemStack itemStack) { - this.itemStack = itemStack; - shopSettings = new HashMap<>(); - buildMap(); - toBase64(); + this(itemStack, new HashMap<>()); } - public ShopItemStack(ItemStack itemStack, HashMap> settingMap) { + public ShopItemStack(ItemStack itemStack, HashMap> itemSettings) { this.itemStack = itemStack; - this.shopSettings = settingMap; + this.itemSettings = itemSettings; buildMap(); - toBase64(); + packData(); } public ShopItemStack(String itemStackB64) { - this.itemStackB64 = itemStackB64; - shopSettings = new HashMap<>(); - buildMap(); - fromBase64(); + this(itemStackB64, new HashMap<>()); } - public ShopItemStack(String itemStackB64, HashMap> settingMap) { + public ShopItemStack(String itemStackB64, HashMap> itemSettings) { this.itemStackB64 = itemStackB64; - this.shopSettings = settingMap; + this.itemSettings = new HashMap<>(); + + itemSettings.forEach((key, value) -> this.itemSettings.put(ShopItemStackSettingKeys.match(key), value)); + buildMap(); - fromBase64(); + loadData(); } //Re-added for backwards compatibility @@ -102,60 +100,60 @@ public ShopItemStack(String itemStackB64, int compareDurability, boolean compare boolean compareBookAuthor, boolean compareBookPages, boolean compareShulkerInventory) { this.itemStackB64 = itemStackB64; - shopSettings = new HashMap<>(); + itemSettings = new HashMap<>(); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_DURABILITY, new ObjectHolder<>(compareDurability)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_NAME, new ObjectHolder<>(compareName)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_LORE, new ObjectHolder<>(compareLore)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA, new ObjectHolder<>(compareCustomModelData)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS, new ObjectHolder<>(compareItemFlags)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE, new ObjectHolder<>(compareUnbreakable)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER, new ObjectHolder<>(compareAttributeModifier)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR, new ObjectHolder<>(compareBookAuthor)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES, new ObjectHolder<>(compareBookPages)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY, new ObjectHolder<>(compareShulkerInventory)); - shopSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS, new ObjectHolder<>(compareEnchantments)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_DURABILITY, new ObjectHolder<>(compareDurability)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_NAME, new ObjectHolder<>(compareName)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_LORE, new ObjectHolder<>(compareLore)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_CUSTOM_MODEL_DATA, new ObjectHolder<>(compareCustomModelData)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ITEM_FLAGS, new ObjectHolder<>(compareItemFlags)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_UNBREAKABLE, new ObjectHolder<>(compareUnbreakable)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ATTRIBUTE_MODIFIER, new ObjectHolder<>(compareAttributeModifier)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_BOOK_AUTHOR, new ObjectHolder<>(compareBookAuthor)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_BOOK_PAGES, new ObjectHolder<>(compareBookPages)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_SHULKER_INVENTORY, new ObjectHolder<>(compareShulkerInventory)); + itemSettings.putIfAbsent(ShopItemStackSettingKeys.COMPARE_ENCHANTMENTS, new ObjectHolder<>(compareEnchantments)); buildMap(); - fromBase64(); + loadData(); } - public HashMap> getShopSettings() { - return shopSettings; + public Map> getItemSettings() { + return itemSettings; } - public static ShopItemStack deserialize(String serialized) { - ShopItemStack item = new Gson().fromJson(serialized, ShopItemStack.class); - item.fromBase64(); - item.buildMap(); - return item; - } public boolean getShopSettingAsBoolean(ShopItemStackSettingKeys key) { - try { - ObjectHolder tempObj = shopSettings.get(key); - return shopSettings.containsKey(key) ? (Boolean) tempObj.getObject() : (Boolean) key.getDefaultValue().getObject(); - } catch (ClassCastException | NullPointerException e) { - return (Boolean) key.getDefaultValue().getObject(); + if (key.isUserEditable()) { + try { + ObjectHolder tempObj = itemSettings.get(key); + return itemSettings.containsKey(key) ? (Boolean) tempObj.getObject() : (Boolean) key.getDefaultValue().getObject(); + } catch (ClassCastException | NullPointerException ignored) { + } } + + return (Boolean) key.getDefaultValue().getObject(); } public int getShopSettingAsInteger(ShopItemStackSettingKeys key) { - try { - ObjectHolder tempObj = shopSettings.get(key); - return shopSettings.containsKey(key) ? (Integer) tempObj.getObject() : (Integer) key.getDefaultValue().getObject(); - } catch (ClassCastException | NullPointerException e) { - return (Integer) key.getDefaultValue().getObject(); + if (key.isUserEditable()) { + try { + ObjectHolder tempObj = itemSettings.get(key); + return itemSettings.containsKey(key) ? (Integer) tempObj.getObject() : (Integer) key.getDefaultValue().getObject(); + } catch (ClassCastException | NullPointerException ignored) { + } } + + return (Integer) key.getDefaultValue().getObject(); } private void buildMap() { - if (shopSettings == null) { - shopSettings = new HashMap<>(); + if (itemSettings == null) { + itemSettings = new HashMap<>(); } for (ShopItemStackSettingKeys key : ShopItemStackSettingKeys.values()) { - shopSettings.putIfAbsent(key, key.getDefaultValue()); + itemSettings.putIfAbsent(key, key.getDefaultValue()); } } @@ -172,12 +170,12 @@ public ShopItemStack clone() { } public boolean setShopSettings(ShopItemStackSettingKeys key, ObjectHolder value) { - if (shopSettings == null) { - shopSettings = new HashMap<>(); + if (itemSettings == null) { + itemSettings = new HashMap<>(); buildMap(); } - shopSettings.put(key, value); + itemSettings.put(key, value); return false; } @@ -189,7 +187,7 @@ public int getAmount() { public void setAmount(int amount) { itemStack.setAmount(amount); - toBase64(); + packData(); } public String getItemStackB64() { @@ -201,7 +199,7 @@ public boolean hasBase64() { } public boolean isSimilar(ItemStack toCompare) { - debugger = new Utils().debugger; + debugger = new Utils().PLUGIN.getDebugger(); // Return False if either item is null if (itemStack == null || toCompare == null) { @@ -485,7 +483,7 @@ public boolean isSimilar(ItemStack toCompare) { public ItemStack getItemStack() { if (itemStack == null) - fromBase64(); + loadData(); return itemStack; } @@ -510,15 +508,50 @@ public String getCleanItemName() { return ShopItemStack.getCleanItemName(itemStack); } - public String serialize() { - return new Gson().toJson(this); + public String getStateString(ShopItemStackSettingKeys key) { + return getStateString(itemSettings.get(key)); + } + + public String getStateString(ObjectHolder stateSetting) { + try { + String ret = ""; + if (stateSetting.isBoolean()) { + if ((Boolean) stateSetting.getObject()) { + ret = "True"; + } else { + ret = "False"; + } + } else if (stateSetting.isInteger() || stateSetting.isDouble()) { + switch (stateSetting.isDouble() ? ((Double) stateSetting.getObject()).intValue() : (Integer) stateSetting.getObject()) { + case 2: + ret = ">="; + break; + case 1: + ret = "=="; + break; + case 0: + ret = "<="; + break; + case -1: + default: + ret = "False"; + } + } + + if (ret.length() < 2) + ret = "Unknown"; + + return "State: " + ret; + } catch (ClassCastException ex) { + return "State: ERROR"; + } } @Override public String toString() { return "ShopItemStack{" + - "itemStack=" + getItemStack() + - ", shopSettings=" + shopSettings + + "itemStack=" + getItemStack().serialize() + + ", shopSettings=" + itemSettings + '}'; } @@ -530,43 +563,44 @@ public String toString() { */ /** - * Sets the objects Base64 from its {@link ItemStack} + * Converts the {@link ItemStack} to a store-able object */ - private void toBase64() { - try { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream); - - // Save every element in the list - dataOutput.writeObject(itemStack); - - // Serialize that array - dataOutput.close(); - itemStackB64 = Base64Coder.encodeLines(outputStream.toByteArray()); - } catch (IOException e) { + private void packData() { + if (itemStack != null) { itemStackB64 = null; + serialItemStack = itemStack.serialize(); } } /** * Sets the objects {@link ItemStack} from its Base64. */ - private void fromBase64() { - try { - ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(itemStackB64)); - BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); + private void loadData() { + if (serialItemStack != null && !serialItemStack.isEmpty()) { + itemStack = ItemStack.deserialize(serialItemStack); + } + + if (itemStack == null && hasBase64()) { + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(itemStackB64)); + BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); - // Read the serialized inventory - itemStack = new ItemStack((ItemStack) dataInput.readObject()); + // Read the serialized inventory + itemStack = new ItemStack((ItemStack) dataInput.readObject()); - dataInput.close(); - } catch (ClassNotFoundException | IOException e) { - itemStack = null; + dataInput.close(); + } catch (ClassNotFoundException | IOException e) { + itemStack = null; + } } } + public int getItemSize() { + packData(); + return serialItemStack.toString().length(); + } + public String toConsoleText() { return new GsonBuilder().setPrettyPrinting().create().toJson(this); } - } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/item/ShopItemStackSettingKeys.java b/src/main/java/org/shanerx/tradeshop/item/ShopItemStackSettingKeys.java new file mode 100644 index 00000000..a4f8fd69 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/item/ShopItemStackSettingKeys.java @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.item; + +import org.apache.commons.lang.WordUtils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; + +import java.util.HashMap; +import java.util.Map; + +public enum ShopItemStackSettingKeys { + + //New per shop settings and their default value should be added below and will be added to the shops + + COMPARE_DURABILITY(new ItemStack(Material.DAMAGED_ANVIL), 1), // -1 = 'off', 0 = '<=', 1 = '==', 2 = '>=' + COMPARE_ENCHANTMENTS(new ItemStack(Material.ENCHANTED_BOOK), true), + COMPARE_NAME(new ItemStack(Material.NAME_TAG), true), + COMPARE_LORE(new ItemStack(Material.BOOK), true), + COMPARE_CUSTOM_MODEL_DATA(new ItemStack(Material.STICK), true), + COMPARE_ITEM_FLAGS(new ItemStack(Material.WHITE_BANNER), true), + COMPARE_UNBREAKABLE(new ItemStack(Material.BEDROCK), true), + COMPARE_ATTRIBUTE_MODIFIER(new ItemStack(Material.BARRIER), true), + COMPARE_BOOK_AUTHOR(new ItemStack(Material.PLAYER_HEAD), true), + COMPARE_BOOK_PAGES(new ItemStack(Material.PAPER), true), + COMPARE_SHULKER_INVENTORY(new ItemStack(Material.CHEST_MINECART), true), + COMPARE_BUNDLE_INVENTORY(new ItemStack(Material.CHEST_MINECART), true), + COMPARE_FIREWORK_DURATION(new ItemStack(Material.GUNPOWDER), true), + COMPARE_FIREWORK_EFFECTS(new ItemStack(Material.FIREWORK_STAR), true); + + private final ItemStack displayItem; + private final Object preConfigDefault; + private static final String defaultKey = "default", userEditableKey = "user-editable"; + + ShopItemStackSettingKeys(ItemStack displayItem, Object preConfigDefault) { + this.displayItem = displayItem; + this.preConfigDefault = preConfigDefault; + } + + public static Map getDefaultConfigMap() { + Map configMap = new HashMap<>(); + + for (ShopItemStackSettingKeys value : values()) { + String key = value.getConfigName(); + Map subConfigMap = new HashMap<>(); + subConfigMap.put(defaultKey, value.preConfigDefault); + subConfigMap.put(userEditableKey, true); + + configMap.put(key, subConfigMap); + } + + return configMap; + } + + public String makeReadable() { + return WordUtils.capitalizeFully(name().replace("_", " ")); + + } + + public ObjectHolder getDefaultValue() { + return new ObjectHolder<>(Setting.SHOP_PER_ITEM_SETTINGS.getMappedObject(getConfigName() + "." + defaultKey)); + } + + public ItemStack getDisplayItem() { + return displayItem; + } + + public boolean isUserEditable() { + return Setting.SHOP_PER_ITEM_SETTINGS.getMappedBoolean(getConfigName() + "." + userEditableKey); + } + + public String getConfigName() { + return name().toLowerCase().replace("_", "-"); + } + + public static ShopItemStackSettingKeys match(String name) { + return valueOf(name.toUpperCase().replace("-", "_")); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/listeners/ShopCreateListener.java b/src/main/java/org/shanerx/tradeshop/listeners/ShopCreateListener.java deleted file mode 100644 index f7903f30..00000000 --- a/src/main/java/org/shanerx/tradeshop/listeners/ShopCreateListener.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.listeners; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.Sign; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.enumys.ShopRole; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.framework.events.PlayerShopCreateEvent; -import org.shanerx.tradeshop.objects.IllegalItemList; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChest; -import org.shanerx.tradeshop.objects.ShopUser; -import org.shanerx.tradeshop.utils.Tuple; -import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; - -@SuppressWarnings("unused") -public class ShopCreateListener extends Utils implements Listener { - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onSignChange(SignChangeEvent event) { - - if (event.isCancelled()) - return; - - Sign shopSign = (Sign) event.getBlock().getState(); - shopSign.setLine(0, event.getLine(0)); - shopSign.setLine(1, event.getLine(1)); - shopSign.setLine(2, event.getLine(2)); - shopSign.setLine(3, event.getLine(3)); - - if (!ShopType.isShop(shopSign)) { - return; - } - - ShopType shopType = ShopType.getType(shopSign); - Player p = event.getPlayer(); - ShopUser owner = new ShopUser(p, ShopRole.OWNER); - - if (!shopType.checkPerm(p)) { - failedSign(event, shopType, Message.NO_TS_CREATE_PERMISSION); - return; - } - - if (!checkShopChest(shopSign.getBlock()) && !shopType.isITrade()) { - failedSign(event, shopType, Message.NO_CHEST); - return; - } - - if (Setting.MAX_SHOPS_PER_CHUNK.getInt() <= PLUGIN.getDataStorage().getShopCountInChunk(shopSign.getChunk())) { - failedSign(event, shopType, Message.TOO_MANY_CHESTS); - return; - } - - ShopChest shopChest; - Shop shop; - Block chest = findShopChest(event.getBlock()); - - if (!shopType.isITrade()) { - if (ShopChest.isShopChest(chest)) { - shopChest = new ShopChest(chest.getLocation()); - } else { - shopChest = new ShopChest(chest, p.getUniqueId(), shopSign.getLocation()); - } - - if (shopChest.hasOwner() && !shopChest.getOwner().equals(owner.getUUID())) { - failedSign(event, shopType, Message.NO_SHOP_PERMISSION); - return; - } - - if (shopChest.hasShopSign() && !shopChest.getShopSign().getLocation().equals(shopSign.getLocation())) { - failedSign(event, shopType, Message.EXISTING_SHOP); - return; - } - - shop = new Shop(new Tuple<>(shopSign.getLocation(), shopChest.getChest().getLocation()), shopType, owner); - shopChest.setName(); - - - if (shopChest.isEmpty() && shop.hasProduct()) { - p.sendMessage(Message.EMPTY_TS_ON_SETUP.getPrefixed()); - } - } else { - shop = new Shop(shopSign.getLocation(), shopType, owner); - } - - shop.setEvent(event); - - ItemStack product = lineCheck(IllegalItemList.TradeItemType.PRODUCT, event.getLine(1)), - cost = lineCheck(IllegalItemList.TradeItemType.COST, event.getLine(2)); - - if (product != null && shop.getProduct().isEmpty()) - shop.setProduct(product); - - if (cost != null && shop.getCost().isEmpty()) - shop.setCost(cost); - - PlayerShopCreateEvent shopCreateEvent = new PlayerShopCreateEvent(p, shop); - Bukkit.getPluginManager().callEvent(shopCreateEvent); - if (shopCreateEvent.isCancelled()) { - event.setCancelled(true); - return; - } - - shop.updateSign(event); - shop.removeEvent(); - shop.saveShop(); - - p.sendMessage(Message.SUCCESSFUL_SETUP.getPrefixed()); - } - - private ItemStack lineCheck(IllegalItemList.TradeItemType type, String line) { - if (line == null || line.equalsIgnoreCase("") || !line.contains(" ") || line.split(" ").length != 2) - return null; - - String[] info = line.split(" "); - - for (String str : info) { - if (str == null || str.equalsIgnoreCase("")) - return null; - } - - if (!isInt(info[0]) || Material.matchMaterial(info[1]) == null) - return null; - - ItemStack item = new ItemStack(Material.matchMaterial(info[1]), Integer.parseInt(info[0])); - - if (PLUGIN.getListManager().isIllegal(type, item.getType())) - return null; - - return item; - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/objects/Shop.java b/src/main/java/org/shanerx/tradeshop/objects/Shop.java deleted file mode 100644 index 87dbb070..00000000 --- a/src/main/java/org/shanerx/tradeshop/objects/Shop.java +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.objects; - -import com.google.gson.Gson; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Container; -import org.bukkit.block.Sign; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.ShopRole; -import org.shanerx.tradeshop.enumys.ShopStatus; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.utils.Tuple; -import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Setting; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -public class Shop implements Serializable { - - private ShopUser owner; - private List managers, members; - private ShopType shopType; - private final ShopLocation shopLoc; - private List product, cost; - private ShopLocation chestLoc; - private transient SignChangeEvent signChangeEvent; - private transient Inventory storageInv; - private transient Utils utils = new Utils(); - private ShopStatus status = ShopStatus.INCOMPLETE; - - private int availableTrades = 0; - - /** - * Creates a Shop object - * - * @param locations Location of shop sign and chest as Tuple, left = Sign location, right = inventory location - * @param owner Owner of the shop as a ShopUser - * @param shopType Type of the shop as ShopType - * @param items Items to go into the shop as Tuple, left = Product, right = Cost - * @param players Users to be added to the shop as Tuple, left = Managers, right = Members - */ - public Shop(Tuple locations, ShopType shopType, ShopUser owner, Tuple, List> players, Tuple items) { - shopLoc = new ShopLocation(locations.getLeft()); - this.owner = owner; - chestLoc = new ShopLocation(locations.getRight()); - utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); - this.shopType = shopType; - managers = players.getLeft(); - members = players.getRight(); - - product = new ArrayList<>(); - cost = new ArrayList<>(); - - product.add(new ShopItemStack(items.getLeft())); - cost.add(new ShopItemStack(items.getRight())); - - fixAfterLoad(); - } - - /** - * Creates a Shop object - * - * @param locations Location of shop sign and chest as Tuple, left = Sign location, right = inventory location - * @param owner Owner of the shop as a ShopUser - * @param shopType Type of the shop as ShopType - */ - public Shop(Tuple locations, ShopType shopType, ShopUser owner) { - shopLoc = new ShopLocation(locations.getLeft()); - this.owner = owner; - chestLoc = new ShopLocation(locations.getRight()); - utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); - this.shopType = shopType; - managers = Collections.emptyList(); - members = Collections.emptyList(); - - product = new ArrayList<>(); - cost = new ArrayList<>(); - - fixAfterLoad(); - } - - /** - * Creates a Shop object - * - * @param location Location of shop sign - * @param owner Owner of the shop as a ShopUser - * @param shopType Type of the shop as ShopType - */ - public Shop(Location location, ShopType shopType, ShopUser owner) { - shopLoc = new ShopLocation(location); - this.owner = owner; - this.shopType = shopType; - managers = Collections.emptyList(); - members = Collections.emptyList(); - - product = new ArrayList<>(); - cost = new ArrayList<>(); - - fixAfterLoad(); - } - - /** - * Deserializes the object to Json using Gson - * - * @param serialized Shop GSON to be deserialized - * - * @return Shop object from file - */ - public static Shop deserialize(String serialized) { - Shop shop = new Gson().fromJson(serialized, Shop.class); - shop.fixAfterLoad(); - - return shop; - } - - /** - * Loads a shop from file and returns the Shop object - * - * @param loc Location of the shop sign - * @return The shop from file - */ - public static Shop loadShop(ShopLocation loc) { - return new Utils().PLUGIN.getDataStorage().loadShopFromSign(loc); - } - - /** - * Loads the shop from file - * - * @param s Shop sign to load from - * @return Shop Object - */ - public static Shop loadShop(Sign s) { - return loadShop(new ShopLocation(s.getLocation())); - } - - /** - * Returns the shops owner - * - * @return ShopUser object of owner - */ - public ShopUser getOwner() { - return owner; - } - - /** - * Sets the owner (don't know if this will ever be used) - * - * @param owner The new owner of the shop - */ - public void setOwner(ShopUser owner) { - this.owner = owner; - } - - /** - * Sets the storageInventory - */ - public void setStorageInventory() { - if (getStorage() != null && getStorage() instanceof Container) - storageInv = ((Container) getStorage()).getInventory(); - else - storageInv = null; - } - - /** - * Adds the sign change event to the shop to be used during sign update - * - * @param event The SignChangeEvent to hold - */ - public void setEvent(SignChangeEvent event) { - this.signChangeEvent = event; - } - - /** - * Removes the SignChangeEvent from the shop(Should be done before leaving the event) - */ - public void removeEvent() { - this.signChangeEvent = null; - } - - /** - * Returns the managers - * - * @return List of managers as ShopUser - */ - public List getManagers() { - List tempManagers = new ArrayList<>(); - - for (UUID user : managers) { - tempManagers.add(new ShopUser(user, ShopRole.MANAGER)); - } - - return tempManagers; - } - - /** - * Sets the managers - * - * @param managers the managers to be set to the shop - */ - public void setManagers(List managers) { - this.managers = managers; - } - - /** - * Returns a list of all users for the shop, including; owners, managers, and members. - * - * @return the sign. - */ - public List getUsers() { - List users = new ArrayList<>(); - users.add(owner); - users.addAll(getManagers()); - users.addAll(getMembers()); - - return users; - } - - /** - * Returns the storage block as a ShopChest - * - * @return Shop storage as ShopChest - */ - public ShopChest getChestAsSC() { - try { - return new ShopChest(chestLoc.getLocation()); - } catch (NullPointerException ex) { - return null; - } - } - - /** - * Gets the members of the shop as ShopUser - * - * @return List of members as ShopUser - */ - public List getMembers() { - List tempMembers = new ArrayList<>(); - - for (UUID user : members) { - tempMembers.add(new ShopUser(user, ShopRole.MEMBER)); - } - - return tempMembers; - } - - /** - * Sets the members - * - * @param members the members to be set to the shop - */ - public void setMembers(List members) { - this.members = members; - } - - /** - * Adds a manager to the shop - * - * @param newManager the player to be added as a shopUser object - * @return true if player has been added - */ - public boolean addManager(UUID newManager) { - if (!getUsersUUID().contains(newManager)) { - managers.add(newManager); - saveShop(); - return true; - } - return false; - } - - /** - * Updates the saved player data for all users - */ - private void updateUserFiles() { - TradeShop plugin = new Utils().PLUGIN; - for (UUID user : getUsersUUID()) { - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(user); - playerSetting.updateShops(this); - plugin.getDataStorage().savePlayer(playerSetting); - } - } - - /** - * Removes this shop from all users - */ - private void purgeFromUserFiles() { - TradeShop plugin = new Utils().PLUGIN; - for (UUID user : getUsersUUID()) { - PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(user); - playerSetting.removeShop(this); - plugin.getDataStorage().savePlayer(playerSetting); - } - } - - /** - * Removes a user from the shop - * - * @param oldUser the UUID of the player to be removed - * @return true if user was removed - */ - public boolean removeUser(UUID oldUser) { - boolean ret = false; - if (getManagersUUID().contains(oldUser)) { - managers.remove(oldUser); - ret = true; - } - - if (getMembersUUID().contains(oldUser)) { - members.remove(oldUser); - ret = true; - } - - saveShop(); - - return ret; - } - - /** - * Adds a member to the shop - * - * @param newMember the player to be added as a shopUser object - * @return true if player has been added - */ - public boolean addMember(UUID newMember) { - if (!getUsersUUID().contains(newMember)) { - members.add(newMember); - saveShop(); - return true; - } - - return false; - } - - /** - * Returns a list of managers uuid - * - * @return List of all managers uuid - */ - public List getManagersUUID() { - return managers; - } - - /** - * Returns a list of all members uuid - * - * @return list of member uuid - */ - public List getMembersUUID() { - return members; - } - - /** - * Returns location of shops inventory - * - * @return inventory location as Location - */ - public Location getInventoryLocation() { - return chestLoc != null ? chestLoc.getLocation() : null; - } - - /** - * Sets the inventory location - * - * @param newLoc new location to set - */ - public void setInventoryLocation(Location newLoc) { - chestLoc = new ShopLocation(newLoc); - utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); - } - - /** - * Returns the location of the shop sign - * - * @return Location of the shops sign - */ - public Location getShopLocation() { - return getShopLocationAsSL().getLocation(); - } - - /** - * Returns the type of the shop - * - * @return list of managers as ShopUser - */ - public ShopType getShopType() { - return shopType; - } - - /** - * Sets the shops type - * - * @param newType new type as ShopType - */ - public void setShopType(ShopType newType) { - shopType = newType; - } - - /** - * Sets the cost item - * - * @param newItem ItemStack to be set - */ - public void setCost(ItemStack newItem) { - if (utils.isIllegal(IllegalItemList.TradeItemType.COST, newItem.getType())) - return; - - cost.clear(); - - addCost(newItem); - } - - /** - * Adds more cost items - * - * @param newItem ItemStack to be added - */ - public void addCost(ItemStack newItem) { - if (utils.isIllegal(IllegalItemList.TradeItemType.COST, newItem.getType())) - return; - - ///* Added stacks are not separated and are added ontop of existing similar stacks - ShopItemStack toAddShopItemStack = new ShopItemStack(newItem); - int toRemoveShopItemStack = -1; - - - for (int i = 0; i < getCost().size(); i++) { - if (getCost().get(i).getItemStack().getType().equals(newItem.getType()) && getCost().get(i).isSimilar(newItem)) { - toRemoveShopItemStack = i; - toAddShopItemStack = getCost().get(i).clone(); - toAddShopItemStack.setAmount(getCost().get(i).getAmount() + newItem.getAmount()); - break; - } - } - - if (toRemoveShopItemStack > -1) - cost.remove(toRemoveShopItemStack); - - cost.add(toAddShopItemStack); - //*/ - - - if (!getShopType().isITrade() && chestLoc != null) - cost.removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); - - saveShop(); - updateSign(); - } - - /** - * Removes the cost item at the index - * - * @param index index of item to remove - * - * @return true if Cost is removed - */ - public boolean removeCost(int index) { - try { - cost.remove(index); - - saveShop(); - updateSign(); - return true; - } catch (IndexOutOfBoundsException ex) { - return false; - } - } - - /** - * Checks if shop has product - * - * @return True if product != null - */ - public boolean hasProduct() { - return product.size() > 0; - } - - /** - * Checks if shop has cost - * - * @return True if cost != null - */ - public boolean hasCost() { - return cost.size() > 0; - } - - - /** - * Returns the amount of trades the shop could do when last accessed - * - * @return amount of trades the shop can do - */ - public int getAvailableTrades() { - return availableTrades; - } - - /** - * Adds more product items - * - * @param newItem ItemStack to be added - */ - public void addProduct(ItemStack newItem) { - if (utils.isIllegal(IllegalItemList.TradeItemType.PRODUCT, newItem.getType())) - return; - - ///* Added stacks are not separated and are added ontop of existing similar stacks - ShopItemStack toAddShopItemStack = new ShopItemStack(newItem); - int toRemoveShopItemStack = -1; - - - for (int i = 0; i < getProduct().size(); i++) { - if (getProduct().get(i).getItemStack().getType().equals(newItem.getType()) && getProduct().get(i).isSimilar(newItem)) { - toRemoveShopItemStack = i; - toAddShopItemStack = getProduct().get(i).clone(); - toAddShopItemStack.setAmount(getProduct().get(i).getAmount() + newItem.getAmount()); - break; - } - } - - if (toRemoveShopItemStack > -1) - product.remove(toRemoveShopItemStack); - - product.add(toAddShopItemStack); - //*/ - - saveShop(); - updateSign(); - } - - /** - * Returns the product items - * - * @return Product ShopItemStack List - */ - public List getProduct() { - List ret = new ArrayList<>(); - for (ShopItemStack itm : product) - ret.add(itm.clone()); - return ret; - } - - /** - * Returns the product items - * - * @return Product ItemStack List - */ - public List getProductItemStacks() { - List ret = new ArrayList<>(); - for (ShopItemStack itm : product) - ret.add(itm.getItemStack().clone()); - return ret; - } - - /** - * returns the cost item - * - * @return Cost ItemStack List - */ - public List getCost() { - List ret = new ArrayList<>(); - for (ShopItemStack itm : cost) - ret.add(itm.clone()); - return ret; - } - - /** - * Returns the cost items - * - * @return Cost ItemStack List - */ - public List getCostItemStacks() { - List ret = new ArrayList<>(); - for (ShopItemStack itm : cost) - ret.add(itm.getItemStack().clone()); - return ret; - } - - /** - * Sets the product item - * - * @param newItem item to be set to product - */ - public void setProduct(ItemStack newItem) { - if (utils.isIllegal(IllegalItemList.TradeItemType.PRODUCT, newItem.getType())) - return; - - product.clear(); - - addProduct(newItem); - } - - /** - * Removes the product item at the index - * - * @param index index of item to remove - * - * @return true if Product is removed - */ - public boolean removeProduct(int index) { - if (product.size() > index) { - product.remove(index); - - saveShop(); - updateSign(); - return true; - } - - return false; - } - - /** - * Serializes the object to Json using Gson - * - * @return serialized string - */ - public String serialize() { - return new Gson().toJson(this); - } - - /** - * Returns the shop signs location as a ShopLocation - * - * @return Shop sign's Location as ShopLocation - */ - public ShopLocation getShopLocationAsSL() { - return shopLoc; - } - - /** - * Returns the shop inventories location as a ShopLocation - * - * @return Shop inventory's Location as ShopLocation - */ - public ShopLocation getInventoryLocationAsSL() { - return chestLoc; - } - - /** - * Fixes values that cannot be serialized after loading - */ - public void fixAfterLoad() { - if (utils == null) - utils = new Utils(); - shopLoc.stringToWorld(); - if (!getShopType().isITrade() && chestLoc != null) { - chestLoc.stringToWorld(); - cost.removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); - utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); - } - - /* TODO Fix this after 2.4 - Removed since this ends up running getItems everytime a hopper trys to access a shop. - Runs up to 3 times per second per hopper under a tradeshop with items inside - Removing this caused errors with shops not being updated properly and causing fail messages during trades - */ - if (getShopSign() != null) - updateSign(); - } - - /** - * Gets all users of shop as UUID List - * - * @return List of all users as UUIDs - */ - public List getUsersUUID() { - return getUsers().stream().map(ShopUser::getUUID).collect(Collectors.toList()); - } - - /** - * Saves the shop to file - */ - public void saveShop() { - updateFullTradeCount(); - utils.PLUGIN.getDataStorage().saveShop(this); - updateUserFiles(); - } - - /** - * Returns the shops sign as a Sign - * - * @return Shop sign as Sign - */ - public Sign getShopSign() { - Block b = getShopLocation().getBlock(); - Sign s = null; - - if (ShopType.isShop(b)) { - s = (Sign) b.getState(); - } - return s; - } - - /** - * Updates the text on the shops sign - */ - public void updateSign() { - if (signChangeEvent != null) { - updateSign(signChangeEvent); - removeEvent(); - } else { - Sign s = getShopSign(); - - if (s != null) { - String[] signLines = updateSignLines(); - - for (int i = 0; i < 4; i++) { - if (signLines[i] != null) - s.setLine(i, signLines[i]); - } - - s.update(); - } - } - } - - /** - * Updates the text on the shops sign during SignChangeEvent - * - * @param signEvent SignEvent to update the sign for - */ - public void updateSign(SignChangeEvent signEvent) { - String[] signLines = updateSignLines(); - - for (int i = 0; i < 4; i++) { - signEvent.setLine(i, signLines[i]); - } - } - - /** - * Updates the text for the shop signs - * - * @return String array containing updated sign lines to be set - */ - private String[] updateSignLines() { - String[] signLines = new String[4]; - - if (isMissingItems()) { - signLines[0] = utils.colorize(Setting.SHOP_INCOMPLETE_COLOUR.getString() + shopType.toHeader()); - } else { - signLines[0] = utils.colorize(Setting.SHOP_GOOD_COLOUR.getString() + shopType.toHeader()); - } - - if (product.isEmpty()) { - signLines[1] = ""; - } else if (product.size() == 1) { - StringBuilder sb = new StringBuilder(); - - ShopItemStack item = product.get(0); - - sb.append(item.getItemStack().getAmount()); - sb.append(" "); - - sb.append(item.getCleanItemName()); - - signLines[1] = sb.substring(0, Math.min(sb.length(), 15)); - - } else { - signLines[1] = Setting.MULTIPLE_ITEMS_ON_SIGN.getString().replace("%amount%", ""); - } - - if (cost.isEmpty()) { - signLines[2] = ""; - } else if (cost.size() == 1) { - StringBuilder sb = new StringBuilder(); - - ShopItemStack item = cost.get(0); - - sb.append(item.getItemStack().getAmount()); - sb.append(" "); - - sb.append(item.getCleanItemName()); - - signLines[2] = sb.substring(0, Math.min(sb.length(), 15)); - } else { - signLines[2] = Setting.MULTIPLE_ITEMS_ON_SIGN.getString(); - } - - signLines[1] = ChatColor.stripColor(signLines[1]); - signLines[2] = ChatColor.stripColor(signLines[2]); - - updateStatus(); - - signLines[3] = status.getLine(); - - return signLines; - } - - /** - * Returns the shops inventory as a BlockState - * - * @return shops inventory as BlockState - */ - public BlockState getStorage() { - try { - return getInventoryLocation().getBlock().getState(); - } catch (NullPointerException npe) { - return null; - } - } - - /** - * Removes the shops inventory from the shop - */ - public void removeStorage() { - if (hasStorage()) { - utils.PLUGIN.getDataStorage().removeChestLinkage(chestLoc); - chestLoc = null; - } - } - - /** - * Returns if the shops inventory exists - * - * @return shops inventory as BlockState - */ - public boolean hasStorage() { - return getStorage() != null; - } - - /** - * Returns the shops status as ShopStatus - * - * @return Shops status as ShopStatus - */ - public ShopStatus getStatus() { - return status; - } - - /** - * Sets the shop to open if the shop has all necessary information to make a trade - * - * @return true if shop opened - */ - public ShopStatus setOpen() { - setStatus(ShopStatus.OPEN); - updateStatus(); - - saveShop(); - updateSign(); - return status; - } - - /** - * Checks if the shop has sufficient product stock to make a trade - */ - public boolean hasProductStock() { - return !shopType.isITrade() && hasProduct() && getChestAsSC() != null && getChestAsSC().hasStock(getProduct()); - } - - /** - * Checks if the shop has sufficient cost stock to make a trade(Use for BiTrade) - */ - public boolean hasCostStock() { - return !shopType.isITrade() && hasCost() && getChestAsSC() != null && getChestAsSC().hasStock(getCost()); - } - - /** - * Automatically updates a shops status if it is not CLOSED - */ - public void updateStatus() { - if (!status.equals(ShopStatus.CLOSED)) { - if (!isMissingItems() && (chestLoc != null || shopType.isITrade())) { - if (shopType.isITrade() || hasProductStock() || (shopType.isBiTrade() && hasCostStock())) - setStatus(ShopStatus.OPEN); - else - setStatus(ShopStatus.OUT_OF_STOCK); - } else { - setStatus(ShopStatus.INCOMPLETE); - } - } - } - - /** - * Checks if shop has necessary items to make a trade - * - * @return true if items are missing - */ - public boolean isMissingItems() { - return shopType.equals(ShopType.ITRADE) ? product.isEmpty() : product.isEmpty() || cost.isEmpty(); - } - - /** - * Sets the shops status to closed - */ - public void setStatus(ShopStatus newStatus) { - status = newStatus; - } - - /** - * Removes this shop from file - */ - public void remove() { - purgeFromUserFiles(); - utils.PLUGIN.getDataStorage().removeShop(this); - } - - /** - * Checks if shop is open - * - * @return true if open - */ - public boolean isTradeable() { - return status.isTradingAllowed(); - } - - /** - * Switches the type of the shop between 'Trade' and 'BiTrade' - */ - public void switchType() { - if (shopType == ShopType.TRADE) - setShopType(ShopType.BITRADE); - else if (shopType == ShopType.BITRADE) - setShopType(ShopType.TRADE); - - saveShop(); - updateSign(); - } - - /** - * Returns a list of Managers' names - * - * @return List of Managers' names - */ - public List getManagersNames() { - List names = Arrays.asList(new String[getManagers().size()]); - - for (int i = 0; i < getManagers().size(); i++) { - names.set(i, getManagers().get(i).getName()); - } - - return names; - } - - /** - * Returns a list of Members' names - * - * @return List of Members' names - */ - public List getMembersNames() { - List names = Arrays.asList(new String[getMembers().size()]); - - for (int i = 0; i < getMembers().size(); i++) { - names.set(i, getMembers().get(i).getName()); - } - - return names; - } - - /** - * Returns a list of Members' and Managers' names - * - * @return List of Members' and Managers' names - */ - public List getUserNames() { - List users = new ArrayList<>(); - users.addAll(getManagersNames()); - users.addAll(getMembersNames()); - - return users; - } - - /** - * Checks if all Costs in the list are valid for trade - * - * @return true if all costs are valid - */ - public boolean areCostsValid() { - return areItemsValid(IllegalItemList.TradeItemType.COST, cost); - } - - /** - * Checks if all Products in the list are valid for trade - * - * @return true if all products are valid - */ - public boolean areProductsValid() { - return areItemsValid(IllegalItemList.TradeItemType.PRODUCT, product); - } - - /** - * Checks if all Items in the list are valid for trade - * - * @param tradeItemType Should Illegal Items be checked as Costs or Products - * @param items List to check - * @return true if all products are valid - */ - private boolean areItemsValid(IllegalItemList.TradeItemType tradeItemType, List items) { - for (ShopItemStack iS : items) { - if (utils.isIllegal(tradeItemType, iS.getItemStack().getType())) - return false; - } - - return true; - } - - /** - * Returns true if shop has enough product to make trade - * - * @param multiplier multiplier to use for check - * @return true if shop has enough product to make trade - */ - public Boolean checkProduct(int multiplier) { - setStorageInventory(); - return utils.checkInventory(storageInv, product, multiplier); - } - - /** - * Returns true if shop has enough cost to make trade - * - * @param multiplier multiplier to use for check - * @return true if shop has enough cost to make trade - */ - public Boolean checkCost(int multiplier) { - setStorageInventory(); - return utils.checkInventory(storageInv, cost, multiplier); - } - - /** - * Returns the ShopRole of the supplied UUID - * - * @param uuidToCheck uuid to check for role of - * @return the ShopRole of the supplied UUID - */ - public ShopRole checkRole(UUID uuidToCheck) { - if (owner.getUUID().equals(uuidToCheck)) { - return ShopRole.OWNER; - } else if (managers.contains(uuidToCheck)) { - return ShopRole.MANAGER; - } else if (members.contains(uuidToCheck)) { - return ShopRole.MEMBER; - } else { - return ShopRole.SHOPPER; - } - } - - /** - * Updates the number of trades the shop can make - */ - public void updateFullTradeCount() { - if (!hasStorage() || !hasProduct()) { - availableTrades = 0; - return; - } - - Inventory shopInventory = hasStorage() ? getChestAsSC().getInventory() : null; - - Inventory clone = Bukkit.createInventory(null, shopInventory.getStorageContents().length); - clone.setContents(shopInventory.getStorageContents()); - int totalCount = 0, currentCount = 0; - - for (ShopItemStack item : getProduct()) { - totalCount += item.getItemStack().getAmount(); - int traded; - for (ItemStack storageItem : clone.getStorageContents()) { - if (storageItem != null && item.isSimilar(storageItem)) { - traded = Math.min(storageItem.getAmount(), item.getItemStack().getMaxStackSize()); - - storageItem.setAmount(traded); - clone.removeItem(storageItem); - currentCount += traded; - } - } - } - - availableTrades = currentCount == 0 || totalCount == 0 ? 0 : currentCount / totalCount; - } - - /** - * Updates all shop users - */ - public void updateShopUsers(Set updatedUserSet) { - for (ShopUser user : updatedUserSet) { - removeUser(user.getUUID()); - switch (user.getRole()) { - case MANAGER: - managers.add(user.getUUID()); - break; - case MEMBER: - members.add(user.getUUID()); - break; - default: - break; - } - } - saveShop(); - } - - /** - * Updates shops cost list - * - * @param updatedCostList list to set as new CostList - */ - public void updateCost(List updatedCostList) { - if (!getShopType().isITrade() && chestLoc != null) - updatedCostList.removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); - cost = updatedCostList; - saveShop(); - updateSign(); - } - - /** - * Updates shops product list - * - * @param updatedProductList list to set as new ProductList - */ - public void updateProduct(List updatedProductList) { - product = updatedProductList; - saveShop(); - updateSign(); - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/objects/WorldlessLocation.java b/src/main/java/org/shanerx/tradeshop/objects/WorldlessLocation.java deleted file mode 100644 index 53e5a86b..00000000 --- a/src/main/java/org/shanerx/tradeshop/objects/WorldlessLocation.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.shanerx.tradeshop.objects; - -import org.bukkit.Location; -import org.bukkit.World; - -public class WorldlessLocation { - - private double x, y, z; - - public WorldlessLocation(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Location getLocation(World w) { - return new Location(w, x, y, z); - } -} diff --git a/src/main/java/org/shanerx/tradeshop/listeners/JoinEventListener.java b/src/main/java/org/shanerx/tradeshop/player/JoinEventListener.java similarity index 88% rename from src/main/java/org/shanerx/tradeshop/listeners/JoinEventListener.java rename to src/main/java/org/shanerx/tradeshop/player/JoinEventListener.java index bb84d9a2..67d765e5 100644 --- a/src/main/java/org/shanerx/tradeshop/listeners/JoinEventListener.java +++ b/src/main/java/org/shanerx/tradeshop/player/JoinEventListener.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.listeners; +package org.shanerx.tradeshop.player; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -31,12 +31,10 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.objects.PlayerSetting; -import org.shanerx.tradeshop.utils.BukkitVersion; -import org.shanerx.tradeshop.utils.Updater; +import org.shanerx.tradeshop.data.config.Message; import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Message; +import org.shanerx.tradeshop.utils.versionmanagement.BukkitVersion; +import org.shanerx.tradeshop.utils.versionmanagement.Updater; public class JoinEventListener extends Utils implements Listener { diff --git a/src/main/java/org/shanerx/tradeshop/enumys/PermStatus.java b/src/main/java/org/shanerx/tradeshop/player/PermStatus.java similarity index 96% rename from src/main/java/org/shanerx/tradeshop/enumys/PermStatus.java rename to src/main/java/org/shanerx/tradeshop/player/PermStatus.java index af4aff7d..cdf7c644 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/PermStatus.java +++ b/src/main/java/org/shanerx/tradeshop/player/PermStatus.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.player; public enum PermStatus { GOOD, diff --git a/src/main/java/org/shanerx/tradeshop/player/Permissions.java b/src/main/java/org/shanerx/tradeshop/player/Permissions.java new file mode 100644 index 00000000..49519289 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/player/Permissions.java @@ -0,0 +1,106 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.player; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.data.config.Language; +import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; + +public enum Permissions { + + HELP("help", PermissionDefault.TRUE), + + CREATE("create", PermissionDefault.TRUE), + + CREATEI("create.infinite", PermissionDefault.OP), + + CREATEBI("create.bi", PermissionDefault.TRUE), + + ADMIN("admin", PermissionDefault.OP), + + EDIT("edit", PermissionDefault.TRUE), // non admin perm + + INFO("info", PermissionDefault.TRUE), + + MANAGE_PLUGIN("manage-plugin", PermissionDefault.OP), + + TRADE("trade", PermissionDefault.TRUE), + + NONE("", PermissionDefault.TRUE); + + private final static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); + private final Utils utils = new Utils(); + private final String key; + private final PermissionDefault defaultState; + private final String description; + + Permissions(String key, PermissionDefault defaultState) { + this.key = key; + this.defaultState = defaultState; + this.description = utils.PLUGIN.getLanguage().getString(Language.LangSection.PERMISSION, Language.LangSubSection.VALUES, name().toLowerCase().replace("_", "-"), "description"); + } + + @Override + public String toString() { + return "tradeshop." + key; + } + + public String getValue() { + return this.toString(); + } + + public static void registerPermissions() { + for (Permissions perm : values()) { + if (!perm.equals(Permissions.NONE)) { + Permission permission = perm.getPerm(); + Bukkit.getPluginManager().addPermission(permission); + plugin.getDebugger().log("Permission registered: " + permission.getName() + " | State: " + permission.getDefault(), DebugLevels.STARTUP); + } + } + + StringBuilder str = new StringBuilder(); + str.append("defaultPermissions: \n"); + Bukkit.getPluginManager().getDefaultPermissions(false).forEach((perm) -> str.append(perm.getName()).append("\n")); + plugin.getDebugger().log(str.toString(), DebugLevels.STARTUP); + } + + public static boolean hasPermission(Player player, Permissions permission) { + return permission.equals(Permissions.NONE) || player.hasPermission(permission.getPerm()); + } + + public static boolean isAdminEnabled(Player player) { + return hasPermission(player, Permissions.ADMIN) && plugin.getDataStorage().loadPlayer(player.getUniqueId()).isAdminEnabled(); + } + + public Permission getPerm() { + return new Permission(toString(), description, defaultState); + } +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/objects/PlayerSetting.java b/src/main/java/org/shanerx/tradeshop/player/PlayerSetting.java similarity index 50% rename from src/main/java/org/shanerx/tradeshop/objects/PlayerSetting.java rename to src/main/java/org/shanerx/tradeshop/player/PlayerSetting.java index f9c622bc..c7d3252a 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/PlayerSetting.java +++ b/src/main/java/org/shanerx/tradeshop/player/PlayerSetting.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.player; import com.google.common.collect.Sets; import com.google.gson.Gson; @@ -34,9 +34,11 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.enumys.ShopRole; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shoplocation.IllegalWorldException; +import org.shanerx.tradeshop.shoplocation.ShopLocation; import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Setting; import java.io.Serializable; import java.util.HashSet; @@ -44,23 +46,22 @@ import java.util.Set; import java.util.UUID; -public class PlayerSetting implements Serializable { +public class PlayerSetting { private transient UUID uuid; private final String uuidString; private final Set ownedShops; - + private final Set staffShops; private boolean showInvolvedStatus, adminEnabled = true; - private int type = 0, multi = Setting.MULTI_TRADE_DEFAULT.getInt(); - private final Set staffShops; + private int multi = Setting.MULTI_TRADE_DEFAULT.getInt(); + private transient Utils utils = new Utils(); public PlayerSetting(UUID playerUUID, Map data) { this.uuid = playerUUID; this.uuidString = uuid.toString(); - if (data.containsKey("type")) type = data.get("type"); if (data.containsKey("multi")) multi = data.get("multi"); ownedShops = Sets.newHashSet(); @@ -79,12 +80,6 @@ public PlayerSetting(UUID playerUUID) { load(); } - public static PlayerSetting deserialize(String serialized) { - PlayerSetting playerSetting = new Gson().fromJson(serialized, PlayerSetting.class); - playerSetting.load(); - return playerSetting; - } - public boolean isAdminEnabled() { return adminEnabled; } @@ -93,14 +88,6 @@ public void setAdminEnabled(boolean adminEnabled) { this.adminEnabled = adminEnabled; } - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - public int getMulti() { return multi; } @@ -115,16 +102,16 @@ public Set getOwnedShops() { public void addShop(Shop shop) { if (shop.getOwner().getUUID().equals(uuid) && - !ownedShops.contains(shop.getShopLocationAsSL().serialize())) - ownedShops.add(shop.getShopLocationAsSL().serialize()); - else if (shop.getUsersUUID().contains(uuid) && - !ownedShops.contains(shop.getShopLocationAsSL().serialize())) - staffShops.add(shop.getShopLocationAsSL().serialize()); + !ownedShops.contains(shop.getShopLocationAsSL().toString())) + ownedShops.add(shop.getShopLocationAsSL().toString()); + else if (shop.getUsersUUID(ShopRole.MANAGER, ShopRole.MEMBER).contains(uuid) && + !ownedShops.contains(shop.getShopLocationAsSL().toString())) + staffShops.add(shop.getShopLocationAsSL().toString()); } public void removeShop(Shop shop) { - ownedShops.remove(shop.getShopLocationAsSL().serialize()); - staffShops.remove(shop.getShopLocationAsSL().serialize()); + ownedShops.remove(shop.getShopLocationAsSL().toString()); + staffShops.remove(shop.getShopLocationAsSL().toString()); } public void removeShop(String shop) { @@ -132,8 +119,8 @@ public void removeShop(String shop) { staffShops.remove(shop); } - public void updateShops(Shop shop) { - if (!shop.getUsersUUID().contains(uuid)) + public void updateShop(Shop shop) { + if (!shop.getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER, ShopRole.MEMBER).contains(uuid)) removeShop(shop); else addShop(shop); @@ -165,29 +152,37 @@ public String getInvolvedStatusesString() { sb.append("&eShop Role &f| &eType &f| &eAvailable Trades &f| &eLocation &f| &eInventory Status\n&b"); if (getOwnedShops().size() > 0) { getOwnedShops().forEach(s -> { - Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.deserialize(s)); - if (shop == null) { - nullShops.add(s); - } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { - sb.append(shop.checkRole(uuid).toString()).append(" &f|&a "); - sb.append(shop.getShopType().toString()).append(" &f|&b "); - sb.append(shop.getAvailableTrades()).append(" &f|&d "); - sb.append(s).append(" &f| "); - sb.append(shop.getStatus().getLine()).append("\n&b"); + try { + Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.fromString(s)); + if (shop == null) { + nullShops.add(s); + } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { + sb.append(shop.checkRole(uuid).toString()).append(" &f|&a "); + sb.append(shop.getShopType().toString()).append(" &f|&b "); + sb.append(shop.getAvailableTrades()).append(" &f|&d "); + sb.append(s).append(" &f| "); + sb.append(shop.getStatus().getLine()).append("\n&b"); + } + } catch (IllegalWorldException ignored) { + //Prevents IllegalWorldException when a player has shops in a world that is not loaded, They are not removed in case the world is loaded again... } }); } if (getStaffShops().size() > 0) { getStaffShops().forEach(s -> { - Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.deserialize(s)); - if (shop == null) { - nullShops.add(s); - } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { - sb.append(shop.checkRole(uuid).toString()).append(" &f|&a "); - sb.append(shop.getShopType().toString()).append(" &f|&b "); - sb.append(shop.getAvailableTrades()).append(" &f|&d "); - sb.append(s).append(" &f| "); - sb.append(shop.getStatus().getLine()).append("\n&b"); + try { + Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.fromString(s)); + if (shop == null) { + nullShops.add(s); + } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { + sb.append(shop.checkRole(uuid).toString()).append(" &f|&a "); + sb.append(shop.getShopType().toString()).append(" &f|&b "); + sb.append(shop.getAvailableTrades()).append(" &f|&d "); + sb.append(s).append(" &f| "); + sb.append(shop.getStatus().getLine()).append("\n&b"); + } + } catch (IllegalWorldException ignored) { + //Prevents IllegalWorldException when a player has shops in a world that is not loaded, They are not removed in case the world is loaded again... } }); } @@ -204,45 +199,53 @@ public InventoryGui getInvolvedStatusesInventory() { GuiElementGroup group = new GuiElementGroup('g'); if (getOwnedShops().size() > 0) { getOwnedShops().forEach(s -> { - Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.deserialize(s)); - if (shop == null) { - nullShops.add(s); - } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { - group.addElement(new StaticGuiElement('e', - new ItemStack(shop.getInventoryLocation() != null ? - shop.getInventoryLocation().getBlock().getType() : - Material.getMaterial(shop.getShopLocation().getBlock().getType().toString().replaceAll("WALL_", ""))), - Math.min(shop.getAvailableTrades(), 64), - click -> { - return true; //Prevents clicking the item from doing anything, required parameter when using amount - }, - utils.colorize("&d" + s), - utils.colorize("&a" + shop.getShopType().toString()), - utils.colorize("&b" + shop.checkRole(uuid).toString()), - utils.colorize("&bAvailable Trades: " + shop.getAvailableTrades()), - utils.colorize(shop.getStatus().getLine()))); + try { + Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.fromString(s)); + if (shop == null) { + nullShops.add(s); + } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { + group.addElement(new StaticGuiElement('e', + new ItemStack(shop.getInventoryLocation() != null ? + shop.getInventoryLocation().getBlock().getType() : + Material.getMaterial(shop.getShopLocation().getBlock().getType().toString().replaceAll("WALL_", ""))), + Math.min(shop.getAvailableTrades(), 64), + click -> { + return true; //Prevents clicking the item from doing anything, required parameter when using amount + }, + utils.colorize("&d" + s), + utils.colorize("&a" + shop.getShopType().toString()), + utils.colorize("&b" + shop.checkRole(uuid).toString()), + utils.colorize("&bAvailable Trades: " + shop.getAvailableTrades()), + utils.colorize(shop.getStatus().getLine()))); + } + } catch (IllegalWorldException ignored) { + //Prevents IllegalWorldException when a player has shops in a world that is not loaded, They are not removed in case the world is loaded again... } }); } if (getStaffShops().size() > 0) { getStaffShops().forEach(s -> { - Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.deserialize(s)); - if (shop == null) { - nullShops.add(s); - } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { - group.addElement(new StaticGuiElement('e', - new ItemStack(shop.getInventoryLocation() != null ? - shop.getInventoryLocation().getBlock().getType() : - Material.getMaterial(shop.getShopLocation().getBlock().getType().toString().replaceAll("WALL_", ""))), - Math.min(shop.getAvailableTrades(), 64), - click -> { - return true; //Prevents clicking the item from doing anything, required parameter when using amount - }, - utils.colorize("&d" + s), - utils.colorize("&a" + shop.getShopType().toString()), - utils.colorize("&b" + shop.checkRole(uuid).toString()), - utils.colorize("&bAvailable Trades: " + shop.getAvailableTrades()), - utils.colorize(shop.getStatus().getLine()))); + try { + Shop shop = utils.PLUGIN.getDataStorage().loadShopFromSign(ShopLocation.fromString(s)); + if (shop == null) { + nullShops.add(s); + } else if (shop.checkRole(uuid) != ShopRole.SHOPPER) { + group.addElement(new StaticGuiElement('e', + new ItemStack(shop.getInventoryLocation() != null ? + shop.getInventoryLocation().getBlock().getType() : + Material.getMaterial(shop.getShopLocation().getBlock().getType().toString().replaceAll("WALL_", ""))), + Math.min(shop.getAvailableTrades(), 64), + click -> { + return true; //Prevents clicking the item from doing anything, required parameter when using amount + }, + utils.colorize("&d" + s), + utils.colorize("&a" + shop.getShopType().toString()), + utils.colorize("&b" + shop.checkRole(uuid).toString()), + utils.colorize("&bAvailable Trades: " + shop.getAvailableTrades()), + utils.colorize(shop.getStatus().getLine()))); + } + } catch (IllegalWorldException ignored) { + //Prevents IllegalWorldException when a player has shops in a world that is not loaded, They are not removed in case the world is loaded again... } }); } diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopRole.java b/src/main/java/org/shanerx/tradeshop/player/ShopRole.java similarity index 97% rename from src/main/java/org/shanerx/tradeshop/enumys/ShopRole.java rename to src/main/java/org/shanerx/tradeshop/player/ShopRole.java index 7cd9c25b..ca8c96d6 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopRole.java +++ b/src/main/java/org/shanerx/tradeshop/player/ShopRole.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.player; @SuppressWarnings("unused") public enum ShopRole { diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopUser.java b/src/main/java/org/shanerx/tradeshop/player/ShopUser.java similarity index 85% rename from src/main/java/org/shanerx/tradeshop/objects/ShopUser.java rename to src/main/java/org/shanerx/tradeshop/player/ShopUser.java index 9af04f16..ae775dcc 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopUser.java +++ b/src/main/java/org/shanerx/tradeshop/player/ShopUser.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.player; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; @@ -32,13 +32,12 @@ import org.bukkit.OfflinePlayer; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; -import org.shanerx.tradeshop.enumys.ShopRole; import java.io.Serializable; import java.util.UUID; @SuppressWarnings("unused") -public class ShopUser implements Serializable { +public class ShopUser { private transient OfflinePlayer player; @SerializedName("player") @@ -57,12 +56,6 @@ public ShopUser(UUID pUUID, ShopRole role) { this.role = role; } - public static ShopUser deserialize(String serialized) { - ShopUser shopUser = new Gson().fromJson(serialized, ShopUser.class); - shopUser.player = Bukkit.getOfflinePlayer(UUID.fromString(shopUser.playerUUID)); - return shopUser; - } - public OfflinePlayer getPlayer() { fix(); return player; @@ -86,10 +79,6 @@ private void fix() { } } - public String serialize() { - return new Gson().toJson(this); - } - public ItemStack getHead() { ItemStack userHead = new ItemStack(Material.PLAYER_HEAD); SkullMeta userMeta = (SkullMeta) userHead.getItemMeta(); diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ExchangeStatus.java b/src/main/java/org/shanerx/tradeshop/shop/ExchangeStatus.java similarity index 97% rename from src/main/java/org/shanerx/tradeshop/enumys/ExchangeStatus.java rename to src/main/java/org/shanerx/tradeshop/shop/ExchangeStatus.java index 95517257..99fcaacd 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ExchangeStatus.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ExchangeStatus.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.shop; //Enum for return from space checks public enum ExchangeStatus { diff --git a/src/main/java/org/shanerx/tradeshop/shop/Shop.java b/src/main/java/org/shanerx/tradeshop/shop/Shop.java new file mode 100644 index 00000000..df6171c0 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/shop/Shop.java @@ -0,0 +1,1162 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.shop; + +import com.google.gson.Gson; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Container; +import org.bukkit.block.Sign; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.player.PlayerSetting; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.player.ShopUser; +import org.shanerx.tradeshop.shoplocation.ShopChunk; +import org.shanerx.tradeshop.shoplocation.ShopLocation; +import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; +import org.shanerx.tradeshop.utils.objects.Tuple; + +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + +public class Shop { + + private ShopUser owner; + private Set managers, members; + private ShopType shopType; + private final ShopLocation shopLoc; + private List product, cost; + private ShopLocation chestLoc; + private transient Inventory storageInv; + private transient Utils utils = new Utils(); + private ShopStatus status = ShopStatus.INCOMPLETE; + + private Map> shopSettings; + + private int availableTrades = 0; + + /** + * Creates a Shop object + * + * @param locations Location of shop sign and chest as Tuple, left = Sign location, right = inventory location + * @param owner Owner of the shop as a ShopUser + * @param shopType Type of the shop as ShopType + * @param productItems Product items to go into the shop + * @param costItems Cost items to go into the shop + * @param players Users to be added to the shop as Tuple, left = Managers, right = Members + */ + public Shop(Tuple locations, ShopType shopType, ShopUser owner, Tuple, Set> players, List productItems, List costItems) { + shopLoc = new ShopLocation(locations.getLeft()); + this.owner = owner; + + if (locations.getRight() != null) { + chestLoc = new ShopLocation(locations.getRight()); + utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); + } + + this.shopType = shopType; + + managers = players.getLeft() == null ? new HashSet<>() : players.getLeft(); + members = players.getRight() == null ? new HashSet<>() : players.getRight(); + + product = productItems != null ? new ArrayList<>(productItems) : new ArrayList<>(); + cost = costItems != null ? new ArrayList<>(costItems) : new ArrayList<>(); + + product.removeIf(shopItemStack -> shopItemStack.getItemStack() == null); + cost.removeIf(shopItemStack -> shopItemStack.getItemStack() == null); + + fixAfterLoad(); + } + + /** + * Creates a Shop object + * + * @param locations Location of shop sign and chest as Tuple, left = Sign location, right = inventory location + * @param owner Owner of the shop as a ShopUser + * @param shopType Type of the shop as ShopType + * @param items Items to go into the shop as Tuple, left = Product, right = Cost + * @param players Users to be added to the shop as Tuple, left = Managers, right = Members + */ + public Shop(Tuple locations, ShopType shopType, ShopUser owner, Tuple, Set> players, Tuple items) { + this(locations, shopType, owner, players, Collections.singletonList(new ShopItemStack(items.getLeft())), Collections.singletonList(new ShopItemStack(items.getRight()))); + } + + /** + * Creates a Shop object + * + * @param locations Location of shop sign and chest as Tuple, left = Sign location, right = inventory location + * @param owner Owner of the shop as a ShopUser + * @param shopType Type of the shop as ShopType + */ + public Shop(Tuple locations, ShopType shopType, ShopUser owner) { + this(locations, shopType, owner, new Tuple<>(null, null), new Tuple<>(null, null)); + } + + /** + * Creates a Shop object + * + * @param location Location of shop sign + * @param owner Owner of the shop as a ShopUser + * @param shopType Type of the shop as ShopType + */ + public Shop(Location location, ShopType shopType, ShopUser owner) { + this(new Tuple<>(location, null), shopType, owner, new Tuple<>(null, null), new Tuple<>(null, null)); + } + + /** + * Loads a shop from file and returns the Shop object + * + * @param loc Location of the shop sign + * @return The shop from file + */ + public static Shop loadShop(ShopLocation loc) { + return new Utils().PLUGIN.getDataStorage().loadShopFromSign(loc); + } + + /** + * Loads the shop from file + * + * @param s Shop sign to load from + * @return Shop Object + */ + public static Shop loadShop(Sign s) { + return loadShop(new ShopLocation(s.getLocation())); + } + + /** + * Sets the storageInventory + */ + public void setStorageInventory() { + if (getStorage() != null && getStorage() instanceof Container) + storageInv = ((Container) getStorage()).getInventory(); + else + storageInv = null; + } + + /** + * Returns the storage block as a ShopChest + * + * @return Shop storage as ShopChest + */ + public ShopChest getChestAsSC() { + try { + return new ShopChest(chestLoc.getLocation()); + } catch (NullPointerException ex) { + return null; + } + } + + /** + * Returns location of shops inventory + * + * @return inventory location as Location + */ + public Location getInventoryLocation() { + return chestLoc != null ? chestLoc.getLocation() : null; + } + + /** + * Sets the inventory location + * + * @param newLoc new location to set + */ + public void setInventoryLocation(Location newLoc) { + chestLoc = new ShopLocation(newLoc); + utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); + } + + /** + * Returns the location of the shop sign + * + * @return Location of the shops sign + */ + public Location getShopLocation() { + return getShopLocationAsSL().getLocation(); + } + + /** + * Returns the type of the shop + * + * @return list of managers as ShopUser + */ + public ShopType getShopType() { + return shopType; + } + + /** + * Sets the shops type + * + * @param newType new type as ShopType + */ + public void setShopType(ShopType newType) { + if (shopType != newType) + setShopSettings(newType); + + shopType = newType; + } + + /** + * Returns the amount of trades the shop could do when last accessed + * + * @return amount of trades the shop can do + */ + public int getAvailableTrades() { + return availableTrades; + } + + /** + * Returns the shop signs location as a ShopLocation + * + * @return Shop sign's Location as ShopLocation + */ + public ShopLocation getShopLocationAsSL() { + return shopLoc; + } + + /** + * Returns the shop inventories location as a ShopLocation + * + * @return Shop inventory's Location as ShopLocation + */ + public ShopLocation getInventoryLocationAsSL() { + return chestLoc; + } + + /** + * Fixes values and objects after loading or creating a Shop + */ + public void fixAfterLoad() { + if (utils == null) + utils = new Utils(); + + shopLoc.stringToWorld(); + if (!getShopType().isITrade() && chestLoc != null) { + chestLoc.stringToWorld(); + cost.removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); + utils.PLUGIN.getDataStorage().addChestLinkage(chestLoc, shopLoc); + } + + setShopSettings(); + + fixSide(ShopItemSide.COST); + fixSide(ShopItemSide.PRODUCT); + + if (getShopSign() != null) + updateSign(); + } + + /** + * Generates a semi readable output of the shop object for debug output + * + * @return Return String for debug output + */ + public String toDebug() { + StringBuilder sb = new StringBuilder(); + sb.append("Shop Debug: \n"); + sb.append("Shop Chunk: ").append(new ShopChunk(shopLoc.getChunk()).toString()).append("\n"); + sb.append("Sign Location: ").append(shopLoc).append("\n"); + sb.append("Shop Type: ").append((isMissingItems() ? Setting.SHOP_INCOMPLETE_COLOUR : Setting.SHOP_GOOD_COLOUR).getString() + shopType.toHeader()).append("\n"); + sb.append("Shop Status: ").append(status.getLine()).append("\n"); + sb.append("Storage Location: ").append(hasStorage() ? getInventoryLocationAsSL().toString() : "N/A").append("\n"); + sb.append("Storage Type: ").append(hasStorage() ? getStorage().getType().toString() : "N/A").append("\n"); + sb.append("Owner: ").append(owner.getName()).append(" | ").append(owner.getUUID()).append("\n"); + sb.append("Managers: ").append(managers.isEmpty() ? "N/A" : managers.size()).append("\n"); + if (!managers.isEmpty()) + getUsers(ShopRole.MANAGER).forEach(manager -> sb.append(" ").append(manager.getName()).append(" | ").append(manager.getUUID()).append("\n")); + sb.append("Members: ").append(members.isEmpty() ? "N/A" : members.size()).append("\n"); + if (!members.isEmpty()) + getUsers(ShopRole.MEMBER).forEach(member -> sb.append(" ").append(member.getName()).append(" | ").append(member.getUUID()).append("\n")); + sb.append("Products: ").append(product.isEmpty() ? "N/A" : product.size()).append("\n"); + if (!product.isEmpty()) + product.forEach(productItem -> sb.append(" ").append(productItem.toConsoleText()).append("\n")); + sb.append("Costs: ").append(cost.isEmpty() ? "N/A" : cost.size()).append("\n"); + if (!cost.isEmpty()) + cost.forEach(costItem -> sb.append(" ").append(costItem.toConsoleText()).append("\n")); + + return utils.colorize(sb.toString()); + } + + /** + * Saves the shop to file + */ + public void saveShop() { + updateFullTradeCount(); + utils.PLUGIN.getDataStorage().saveShop(this); + updateUserFiles(); + } + + /** + * Saves the shop to file if passed boolean is true + * + * @param shouldSave true if save should proceed + */ + public void saveShop(boolean shouldSave) { + if (shouldSave) saveShop(); + } + + /** + * Returns the shops sign as a Sign + * + * @return Shop sign as Sign + */ + public Sign getShopSign() { + Block b = getShopLocation().getBlock(); + Sign s = null; + + if (ShopType.isShop(b)) { + s = (Sign) b.getState(); + } + return s; + } + + /** + * Updates the text on the shops sign + */ + public void updateSign() { + Sign s = getShopSign(); + + if (s == null) + return; + + String[] signLines = updateSignLines(Setting.SHOP_SIGN_DEFAULT_COLOURS.getMappedString(Signs.match(s.getType()).name())); + + for (int i = 0; i < 4; i++) { + s.setLine(i, signLines[i]); + } + + s.update(); + } + + /** + * Updates the text on the shops sign using the events sign if it matches location + */ + public void updateSign(SignChangeEvent event) { + if (event == null || !event.getBlock().getLocation().equals(getShopLocation())) + return; + + String[] signLines = updateSignLines(Setting.SHOP_SIGN_DEFAULT_COLOURS.getMappedString(Signs.match(event.getBlock().getType()).name())); + + for (int i = 0; i < 4; i++) { + event.setLine(i, signLines[i]); + } + } + + /** + * Updates the text on the shops sign using the passed sign if it matches location + */ + public void updateSign(Sign sign) { + if (sign == null || !sign.getLocation().equals(getShopLocation())) + return; + + String[] signLines = updateSignLines(Setting.SHOP_SIGN_DEFAULT_COLOURS.getMappedString(Signs.match(sign.getType()).name())); + + for (int i = 0; i < 4; i++) { + sign.setLine(i, signLines[i]); + } + + sign.update(); + } + + /** + * Updates the text for the shop signs + * + * @return String array containing updated sign lines to be set + */ + private String[] updateSignLines(String defaultColour) { + String[] signLines = new String[4]; + + signLines[0] = utils.colorize((isMissingItems() ? Setting.SHOP_INCOMPLETE_COLOUR : Setting.SHOP_GOOD_COLOUR).getString() + shopType.toHeader()); + + if (product.isEmpty()) { + signLines[1] = ""; + } else if (product.size() == 1) { + signLines[1] = itemLineFormatter(defaultColour, String.valueOf(product.get(0).getItemStack().getAmount()), " ", product.get(0).getCleanItemName()); + } else { + signLines[1] = itemLineFormatter(defaultColour, Setting.MULTIPLE_ITEMS_ON_SIGN.getString().replace("%amount%", "")); + } + + if (cost.isEmpty()) { + signLines[2] = ""; + } else if (cost.size() == 1) { + signLines[2] = itemLineFormatter(defaultColour, String.valueOf(cost.get(0).getItemStack().getAmount()), " ", cost.get(0).getCleanItemName()); + } else { + signLines[2] = itemLineFormatter(defaultColour, Setting.MULTIPLE_ITEMS_ON_SIGN.getString().replace("%amount%", "")); + } + + updateStatus(); + + signLines[3] = status.getLine(); + + for (int i = 0; i < 4; i++) { + if (signLines[i] == null) + signLines[i] = " "; + } + + return signLines; + } + + private String itemLineFormatter(String defaultColour, String... strings) { + StringBuilder sb = new StringBuilder(); + + for (String s : strings) { + sb.append(s); + } + + String colorFix = ChatColor.stripColor(utils.colorize(sb.toString())); + + return utils.colorize(defaultColour + colorFix.substring(0, Math.min(colorFix.length(), 15))); + } + + /** + * Returns the shops inventory as a BlockState + * + * @return shops inventory as BlockState + */ + public BlockState getStorage() { + try { + return getInventoryLocation().getBlock().getState(); + } catch (NullPointerException npe) { + return null; + } + } + + /** + * Removes the shops inventory from the shop + */ + public void removeStorage() { + if (hasStorage()) { + utils.PLUGIN.getDataStorage().removeChestLinkage(chestLoc); + chestLoc = null; + } + } + + /** + * Returns if the shops inventory exists + * + * @return shops inventory as BlockState + */ + public boolean hasStorage() { + return getStorage() != null; + } + + /** + * Returns the shops status as ShopStatus + * + * @return Shops status as ShopStatus + */ + public ShopStatus getStatus() { + return status; + } + + /** + * Sets the shop to open if the shop has all necessary information to make a trade + * + * @return true if shop opened + */ + public ShopStatus setOpen() { + setStatus(ShopStatus.OPEN); + updateStatus(); + + saveShop(); + updateSign(); + return status; + } + + /** + * Automatically updates a shops status if it is not CLOSED + */ + public void updateStatus() { + if (!status.equals(ShopStatus.CLOSED)) { + if (!isMissingItems() && (chestLoc != null || shopType.isITrade())) { + if (getAvailableTrades() > 0) + setStatus(ShopStatus.OPEN); + else + setStatus(ShopStatus.OUT_OF_STOCK); + } else { + setStatus(ShopStatus.INCOMPLETE); + } + } + } + + /** + * Sets the shops status to closed + */ + public void setStatus(ShopStatus newStatus) { + status = newStatus; + } + + /** + * Removes this shop from file + */ + public void remove() { + purgeFromUserFiles(); + utils.PLUGIN.getDataStorage().removeShop(this); + } + + /** + * Checks if shop is open + * + * @return true if open + */ + public boolean isTradeable() { + return status.isTradingAllowed(); + } + + /** + * Switches the type of the shop between 'Trade' and 'BiTrade' + */ + public void switchType() { + if (shopType == ShopType.TRADE) + setShopType(ShopType.BITRADE); + else if (shopType == ShopType.BITRADE) + setShopType(ShopType.TRADE); + + saveShop(); + updateSign(); + } + + /** + * Checks if all Items in the list are valid for trade + * + * @param side Which side of the trade should be checked for illegal items + * @param items List to check + * @return true if all products are valid + */ + private boolean areItemsValid(ShopItemSide side, List items) { + for (ShopItemStack iS : items) { + if (utils.isIllegal(side, iS.getItemStack().getType())) + return false; + } + + return true; + } + + /** + * Updates the number of trades the shop can make + */ + public void updateFullTradeCount() { + if (getShopType().equals(ShopType.ITRADE) && hasSide(ShopItemSide.PRODUCT)) { + availableTrades = 999; + return; + } + + if (!hasStorage() || !hasSide(ShopItemSide.PRODUCT)) { + availableTrades = 0; + return; + } + + Inventory shopInventory = getChestAsSC().getInventory(); + + int count = countItems(getSideList(ShopItemSide.PRODUCT), shopInventory.getStorageContents()); + + if (count == 0 && getShopType().equals(ShopType.BITRADE)) { + count = countItems(getSideList(ShopItemSide.COST), shopInventory.getStorageContents()); + } + + availableTrades = count; + } + + private int countItems(List countItems, ItemStack[] storageContents) { + Inventory storage = Bukkit.createInventory(null, storageContents.length); + storage.setContents(storageContents); + + int totalCount = 0, currentCount = 0; + + for (ShopItemStack item : countItems) { + totalCount += item.getItemStack().getAmount(); + int traded; + for (ItemStack storageItem : storage.getStorageContents()) { + if (storageItem != null && item.isSimilar(storageItem)) { + traded = Math.min(storageItem.getAmount(), item.getItemStack().getMaxStackSize()); + + storageItem.setAmount(traded); + storage.removeItem(storageItem); + currentCount += traded; + } + } + } + + return (currentCount == 0 || totalCount == 0) ? 0 : currentCount / totalCount; + } + + + //region Setting Management - Methods for managing a shops settings + //------------------------------------------------------------------------------------------------------------------ + + /** + * Sets the Shops settings based on the ShopType and server defaults. + */ + public void setShopSettings() { + setShopSettings(shopType); + } + + /** + * Retrieves the specified setting if it is usable on the shop + */ + public ObjectHolder getShopSetting(ShopSettingKeys settingKey) { + return settingKey.isUsable(shopType) ? shopSettings.get(settingKey) : null; + } + + /** + * Retrieves the specified setting if it is usable on the shop + */ + public boolean hasShopSetting(ShopSettingKeys settingKey) { + return settingKey.isUsable(shopType) && shopSettings.containsKey(settingKey); + } + + /** + * Retrieves the specified setting if it is usable on the shop + */ + public Map> getShopSettings() { + return shopSettings; + } + + /** + * Sets the Shops settings based on the passed ShopType + */ + public void setShopSettings(ShopType type) { + if (shopSettings == null) + shopSettings = new HashMap<>(); + + for (ShopSettingKeys settingKey : ShopSettingKeys.values()) { + if (shopSettings.containsKey(settingKey) && !settingKey.isUsable(type)) { + shopSettings.remove(settingKey); + } else { + shopSettings.putIfAbsent(settingKey, settingKey.getDefaultValue(type)); + } + + if (!settingKey.isUserEditable(type) && shopSettings.get(settingKey) != settingKey.getDefaultValue(type)) { + shopSettings.put(settingKey, settingKey.getDefaultValue(type)); + } + } + } + + /** + * Retrieves the specified setting if it is usable on the shop + */ + public void setShopSettings(Map> newSettings) { + if (newSettings.size() > 0) + new Utils().PLUGIN.getListManager().removeSkippableShop(getShopLocation()); + + for (ShopSettingKeys settingKey : newSettings.keySet()) { + if (settingKey.isUsable(shopType) && newSettings.get(settingKey) != null) { + shopSettings.put(settingKey, newSettings.get(settingKey)); + } + } + } + + //------------------------------------------------------------------------------------------------------------------ + //endregion + + //region User Management - Methods for adding/deleting/updating/viewing a shops users + //------------------------------------------------------------------------------------------------------------------ + + /** + * Returns a list of all users for the shop based on specified roles. + * + * @param roles role to get users with + * @return list of ShopUsers. + */ + public List getUsers(ShopRole... roles) { + return getUsersExcluding(Collections.emptyList(), roles); + } + + /** + * Returns a list of all users for the shop based on specified roles. Will exclude any users in the list. + * + * @param excludedPlayers player UUIDs to exclude from the results + * @param roles role to get users with + * @return list of ShopUsers. + */ + public List getUsersExcluding(List excludedPlayers, ShopRole... roles) { + List users = new ArrayList<>(); + for (ShopRole role : roles) { + switch (role) { + case MEMBER: + members.forEach(uuid -> { + if (!excludedPlayers.contains(uuid)) { + users.add(new ShopUser(uuid, role)); + } + }); + break; + case MANAGER: + managers.forEach(uuid -> { + if (!excludedPlayers.contains(uuid)) { + users.add(new ShopUser(uuid, role)); + } + }); + break; + case OWNER: + if (!excludedPlayers.contains(owner.getUUID())) + users.add(owner); + break; + } + } + + return users; + } + + /** + * Returns a list of all user names for the shop based on specified roles. + * + * @param roles role to get users with + * @return List of specified users names + */ + public List getUserNames(ShopRole... roles) { + return getUsers(roles).stream().map(ShopUser::getName).collect(Collectors.toList()); + } + + /** + * Returns a list of all user UUIDs for the shop based on specified roles. + * + * @param roles role to get users with + * @return List of specified users names + */ + public List getUsersUUID(ShopRole... roles) { + List users = new ArrayList<>(); + for (ShopRole role : roles) { + switch (role) { + case MEMBER: + users.addAll(members); + break; + case MANAGER: + users.addAll(managers); + break; + case OWNER: + users.add(owner.getUUID()); + break; + } + } + + return users; + } + + /** + * Returns true if the shop has users of the specified role + * + * @param role role to check for users + * @return true if users exist + */ + public boolean hasUsers(ShopRole role) { + return !getUsers(role).isEmpty(); + } + + /** + * Returns the shops owner + * + * @return ShopUser object of owner + */ + public ShopUser getOwner() { + return owner; + } + + /** + * Sets the owner (don't know if this will ever be used) + * + * @param owner The new owner of the shop + */ + public void setOwner(ShopUser owner) { + this.owner = owner; + } + + /** + * Sets a user to the shop with the specified role after removing it if it was already on the shop + * + * @param newUser the player to be set + * @param role role to set thge player to + * @return true if player has been set + */ + public boolean setUser(UUID newUser, ShopRole role) { + removeUser(newUser); + return addUser(newUser, role); + } + + /** + * Adds a user to the shop with the specified role + * + * @param newUser the player to be added + * @param role role to set thge player to + * @return true if player has been added + */ + public boolean addUser(UUID newUser, ShopRole role) { + if (getUsers(ShopRole.MANAGER, ShopRole.MEMBER).size() >= Setting.MAX_SHOP_USERS.getInt()) + return false; + + if (!getUsersUUID(ShopRole.MANAGER, ShopRole.MEMBER).contains(newUser)) { + switch (role) { + case MANAGER: + saveShop(managers.add(newUser)); + return true; + case MEMBER: + saveShop(members.add(newUser)); + return true; + } + } + + return false; + } + + /** + * Updates all shop users + */ + public void updateShopUsers(Set updatedUserSet) { + for (ShopUser user : updatedUserSet) { + removeUser(user.getUUID()); + addUser(user.getUUID(), user.getRole()); + } + saveShop(); + } + + /** + * Returns the ShopRole of the supplied UUID + * + * @param uuidToCheck uuid to check for role of + * @return the ShopRole of the supplied UUID + */ + public ShopRole checkRole(UUID uuidToCheck) { + if (owner.getUUID().equals(uuidToCheck)) { + return ShopRole.OWNER; + } else if (managers.contains(uuidToCheck)) { + return ShopRole.MANAGER; + } else if (members.contains(uuidToCheck)) { + return ShopRole.MEMBER; + } else { + return ShopRole.SHOPPER; + } + } + + /** + * Removes a user from the shop + * + * @param oldUser the UUID of the player to be removed + * @return true if user was removed + */ + public boolean removeUser(UUID oldUser) { + boolean ret = false; + if (getUsersUUID(ShopRole.MANAGER).contains(oldUser)) { + managers.remove(oldUser); + ret = true; + } + + if (getUsersUUID(ShopRole.MEMBER).contains(oldUser)) { + members.remove(oldUser); + ret = true; + } + + saveShop(ret); + + return ret; + } + + /** + * Sets the a list of users to a role + * + * @param users the managers to be set to the shop + */ + public boolean setUsers(Set users, ShopRole role) { + boolean ret = false; + switch (role) { + case MANAGER: + users.forEach(this::removeUser); + managers = users; + ret = true; + case MEMBER: + users.forEach(this::removeUser); + members = users; + ret = true; + } + + saveShop(ret); + + return ret; + } + + /** + * Updates the saved player data for all users + */ + private void updateUserFiles() { + TradeShop plugin = new Utils().PLUGIN; + for (UUID user : getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER, ShopRole.MEMBER)) { + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(user); + playerSetting.updateShop(this); + plugin.getDataStorage().savePlayer(playerSetting); + } + } + + /** + * Removes this shop from all users + */ + private void purgeFromUserFiles() { + TradeShop plugin = new Utils().PLUGIN; + for (UUID user : getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER, ShopRole.MEMBER)) { + PlayerSetting playerSetting = plugin.getDataStorage().loadPlayer(user); + playerSetting.removeShop(this); + plugin.getDataStorage().savePlayer(playerSetting); + } + } + + + //------------------------------------------------------------------------------------------------------------------ + //endregion + + //region Item Management - Methods for adding/deleting/updating/viewing Cost and Product lists + //------------------------------------------------------------------------------------------------------------------ + + /** + * Checks if shop has a bad side and fixes if necessary + */ + public void fixSide(ShopItemSide side) { + List ogItems = (side.equals(ShopItemSide.PRODUCT) ? product : cost); + + Set matSet = new HashSet<>(); + + ogItems.forEach((item) -> matSet.add(item.getItemStack().getType())); + + + if (ogItems.size() > 1 && ogItems.size() != matSet.size()) { + List scrapList = new ArrayList<>(ogItems); + (side.equals(ShopItemSide.PRODUCT) ? product : cost).clear(); + + ogItems.forEach((item) -> { + while (scrapList.contains(item)) { + addSideItem(side, item); + scrapList.remove(scrapList.lastIndexOf(item)); + } + }); + + updateFullTradeCount(); + updateSign(); + saveShop(); + } + } + + /** + * Checks if shop has items on specified side + * + * @return True if side != null + */ + public boolean hasSide(ShopItemSide side) { + return getSide(side).size() > 0; + } + + /** + * Checks if shop has necessary items to make a trade + * + * @return true if items are missing + */ + public boolean isMissingItems() { + return isNoCost() ? product.isEmpty() : product.isEmpty() || cost.isEmpty(); + } + + /** + * Checks if the shop is set to not use cost + * + * @return true if cost is not needed + */ + public boolean isNoCost() { + if (!ShopSettingKeys.NO_COST.isUsable(getShopType())) return false; + + Boolean noCost = shopSettings.get(ShopSettingKeys.NO_COST).asBoolean(); + return noCost != null ? noCost : false; + } + + /** + * Returns the ItemStacks on specified side + * + * @param side Side to get ItemStacks form + * @return ItemStack List + */ + public List getSideItemStacks(ShopItemSide side) { + List ret = new ArrayList<>(); + for (ShopItemStack itm : getSide(side)) + ret.add(itm.getItemStack().clone()); + return ret; + } + + /** + * Returns the appropriate list for the side of the trade for object internal use + * + * @return Side ShopItemStack List + */ + private List getSide(ShopItemSide side) { + return side.equals(ShopItemSide.PRODUCT) ? product : cost; + } + + /** + * Returns a list of the items on the shops specified side + * + * @param side Side to get items for + * @return Side ShopItemStack List + */ + public List getSideList(ShopItemSide side) { + return getSideList(side, false); + } + + /** + * Returns a list of the items on the shops specified side, or the opposite side it doBiTradeAlternate is true + * + * @param side Side to get items for + * @param doBiTradeAlternate Should side be flipped(for biTrade + Left Click) + * @return Side ShopItemStack List + */ + public List getSideList(ShopItemSide side, boolean doBiTradeAlternate) { + List ret = new ArrayList<>(); + for (ShopItemStack itm : getSide(doBiTradeAlternate ? side.getReverse() : side)) + ret.add(itm.clone()); + return ret; + } + + /** + * Removes the item at the index of the specified side + * + * @param side side of the trade to remove item from + * @param index index of item to remove + * @return true if Item is removed from the specified Side + */ + public boolean removeSideIndex(ShopItemSide side, int index) { + if (getSide(side).size() > index) { + getSide(side).remove(index); + + saveShop(); + updateSign(); + return true; + } + + return false; + } + + /** + * Sets the Item for the specified side of the trade + * + * @param side Side of the trade to set + * @param newItem ItemStack to be set + */ + public void setSideItems(ShopItemSide side, ItemStack newItem) { + if (utils.isIllegal(side, newItem.getType())) + return; + + getSide(side).clear(); + + addSideItem(side, newItem); + } + + /** + * Adds more items to the specified side + * + * @param side Side to add items to + * @param newShopItem ShopItemStack to be added + */ + public void addSideItem(ShopItemSide side, ShopItemStack newShopItem) { + if (utils.isIllegal(side, newShopItem.getItemStack().getType())) + return; + + int toRemoveShopItemStack = -1; + + + for (int i = 0; i < getSide(side).size(); i++) { + if (getSideList(side).get(i).getItemStack().getType().equals(newShopItem.getItemStack().getType()) && getSideList(side).get(i).isSimilar(newShopItem.getItemStack())) { + toRemoveShopItemStack = i; + newShopItem = getSideList(side).get(i).clone(); + newShopItem.setAmount(getSideList(side).get(i).getAmount() + newShopItem.getItemStack().getAmount()); + break; + } + } + + if (toRemoveShopItemStack > -1) + getSide(side).remove(toRemoveShopItemStack); + + getSide(side).add(newShopItem); + //*/ + + + if (!getShopType().isITrade() && chestLoc != null) + getSide(side).removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); + + saveShop(); + updateSign(); + } + + /** + * Adds more items to the specified side + * + * @param side Side to add items to + * @param newItem ItemStack to be added + */ + public void addSideItem(ShopItemSide side, ItemStack newItem) { + addSideItem(side, new ShopItemStack(newItem)); + } + + /** + * Checks if the shop has sufficient stock to make a trade on specified side + */ + public boolean hasSideStock(ShopItemSide side) { + return !shopType.isITrade() && hasSide(side) && getChestAsSC() != null && getChestAsSC().hasStock(getSideList(side)); + } + + /** + * Checks if all Items on the specified side are valid for trade + * + * @param side Side to check + * @return true if all Items are valid + */ + public boolean isSideValid(ShopItemSide side) { + return areItemsValid(side, getSideList(side)); + } + + /** + * Updates list on specified side + * + * @param side Side to be updated + * @param updatedCostList list to set as new CostList + */ + public void updateSide(ShopItemSide side, List updatedCostList) { + if (!getShopType().isITrade() && chestLoc != null) + updatedCostList.removeIf(item -> item.getItemStack().getType().toString().endsWith("SHULKER_BOX") && getInventoryLocation().getBlock().getType().toString().endsWith("SHULKER_BOX")); + if (side.equals(ShopItemSide.PRODUCT)) { + product = updatedCostList; + } else { + cost = updatedCostList; + } + + saveShop(); + updateSign(); + } + + //------------------------------------------------------------------------------------------------------------------ + //endregion +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopChest.java b/src/main/java/org/shanerx/tradeshop/shop/ShopChest.java similarity index 95% rename from src/main/java/org/shanerx/tradeshop/objects/ShopChest.java rename to src/main/java/org/shanerx/tradeshop/shop/ShopChest.java index 7ffc367d..9731c885 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopChest.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopChest.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.shop; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -39,9 +39,11 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.exceptions.IllegalWorldException; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.shoplocation.IllegalWorldException; +import org.shanerx.tradeshop.shoplocation.ShopLocation; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; import java.util.HashMap; import java.util.List; @@ -50,7 +52,7 @@ public class ShopChest extends Utils { - private final transient static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); + private final static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); private ShopLocation shopSign; private final Location loc; private Block chest; @@ -222,7 +224,7 @@ public void loadFromName() { chestData.forEach((k, v) -> plugin.getDebugger().log(k + " = " + v, DebugLevels.PROTECTION)); try { - shopSign = ShopLocation.deserialize(chestData.get("Sign")); + shopSign = ShopLocation.fromString(chestData.get("Sign")); } catch (IllegalWorldException e) { shopSign = new ShopLocation(e.getLoc().getLocation(chest.getWorld())); } @@ -250,7 +252,7 @@ public String getName() { StringBuilder sb = new StringBuilder(); sb.append("$ ^Sign"); sb.append(titleSeparator); - sb.append(shopSign.serialize()); + sb.append(shopSign.toString()); sb.append("$ ^Owner"); sb.append(titleSeparator); sb.append(owner.toString()); diff --git a/src/main/java/org/shanerx/tradeshop/shop/ShopSettingKeys.java b/src/main/java/org/shanerx/tradeshop/shop/ShopSettingKeys.java new file mode 100644 index 00000000..0c9d7b8d --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopSettingKeys.java @@ -0,0 +1,115 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.shop; + +import org.apache.commons.lang.WordUtils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.utils.objects.ObjectHolder; + +import java.util.*; + +public enum ShopSettingKeys { + + // Use null as default if the shop type does not use this setting + + HOPPER_IMPORT(new ItemStack(Material.HOPPER), false, false, null), + HOPPER_EXPORT(new ItemStack(Material.DISPENSER), false, false, null), + NO_COST(new ItemStack(Material.GOLD_INGOT), false, null, false); + + public static final String defaultKey = "default", userEditableKey = "user-editable"; + private final ItemStack displayItem; + private final Map defaults; + + ShopSettingKeys(ItemStack displayItem, Object tradeDefault, Object biTradeDefault, Object iTradeDefault) { + this.displayItem = displayItem; + defaults = new HashMap<>(); + defaults.put(ShopType.TRADE, tradeDefault); + defaults.put(ShopType.BITRADE, biTradeDefault); + defaults.put(ShopType.ITRADE, iTradeDefault); + } + + public static Map getSettingConfigMap(ShopType type) { + Map configMap = new HashMap<>(); + + for (ShopSettingKeys value : getValidSettings(type)) { + Map subConfigMap = new HashMap<>(); + subConfigMap.put(defaultKey, value.defaults.get(type)); + subConfigMap.put(userEditableKey, true); + + configMap.put(value.getConfigKey(), subConfigMap); + } + return configMap; + } + + public static List getValidSettings(ShopType type) { + List settings = new ArrayList<>(); + + Arrays.stream(values()).forEach((setting) -> { + if (setting.defaults.get(type) != null) settings.add(setting); + }); + + return settings; + } + + public static ShopSettingKeys findShopSetting(String search) { + return valueOf(search.toUpperCase().replace("-", "_")); + } + + public static Setting settingExpand(ShopType type) { + return Setting.findSetting(type.name() + "_PER_SHOP_SETTINGS"); + } + + public String makeReadable() { + return WordUtils.capitalizeFully(name().replace("_", " ")); + + } + + public ObjectHolder getDefaultValue(ShopType type) { + return isUsable(type) ? new ObjectHolder<>(settingExpand(type).getMappedObject(getConfigKey() + "." + defaultKey)) : null; + } + + public ObjectHolder getDefault(ShopType type) { + return isUsable(type) ? new ObjectHolder<>(defaults.get(type)) : null; + } + + public boolean isUserEditable(ShopType type) { + return isUsable(type) && settingExpand(type).getMappedBoolean(getConfigKey() + "." + userEditableKey); + } + + public boolean isUsable(ShopType type) { + return defaults.get(type) != null; + } + + public ItemStack getDisplayItem() { + return displayItem; + } + + public String getConfigKey() { + return name().toLowerCase().replace("_", "-"); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopSign.java b/src/main/java/org/shanerx/tradeshop/shop/ShopSign.java similarity index 56% rename from src/main/java/org/shanerx/tradeshop/enumys/ShopSign.java rename to src/main/java/org/shanerx/tradeshop/shop/ShopSign.java index b21f1a56..7bd9af73 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopSign.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopSign.java @@ -23,40 +23,39 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.shop; import org.bukkit.Material; -import org.shanerx.tradeshop.utils.BukkitVersion; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.versionmanagement.BukkitVersion; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; enum Signs { - SIGN("", "1.13.2"), - OAK_SIGN("1.14.0", ""), - SPRUCE_SIGN("1.14.0", ""), - BIRCH_SIGN("1.14.0", ""), - JUNGLE_SIGN("1.14.0", ""), - ACACIA_SIGN("1.14.0", ""), - DARK_OAK_SIGN("1.14.0", ""), - CRIMSON_SIGN("1.16.0", ""), - WARPED_SIGN("1.16.0", ""), - WALL_SIGN("", "1.13.2"), - OAK_WALL_SIGN("1.14.0", ""), - SPRUCE_WALL_SIGN("1.14.0", ""), - BIRCH_WALL_SIGN("1.14.0", ""), - JUNGLE_WALL_SIGN("1.14.0", ""), - ACACIA_WALL_SIGN("1.14.0", ""), - DARK_OAK_WALL_SIGN("1.14.0", ""), - CRIMSON_WALL_SIGN("1.16.0", ""), - WARPED_WALL_SIGN("1.16.0", ""); - - private List minVer = Arrays.asList(new Integer[3]), maxVer = Arrays.asList(new Integer[3]); + SIGN("", "1.13.2", "&0"), + OAK_SIGN("1.14.0", "", "&0"), + SPRUCE_SIGN("1.14.0", "", "&0"), + BIRCH_SIGN("1.14.0", "", "&0"), + JUNGLE_SIGN("1.14.0", "", "&0"), + ACACIA_SIGN("1.14.0", "", "&0"), + DARK_OAK_SIGN("1.14.0", "", "&f"), + CRIMSON_SIGN("1.16.0", "", "&0"), + WARPED_SIGN("1.16.0", "", "&0"), + MANGROVE_SIGN("1.19.0", "", "&0"); + + private final List minVer = Arrays.asList(new Integer[3]); + private final List maxVer = Arrays.asList(new Integer[3]); private boolean hasMin = true, hasMax = true; + private final String defaultColour; + + Signs(String minVersion, String maxVersion, String defaultColour) { + this.defaultColour = defaultColour; - Signs(String minVersion, String maxVersion) { if (minVersion.equalsIgnoreCase("")) hasMin = false; @@ -102,19 +101,26 @@ public String getMaxVersionAsString() { return hasMaxVersion() ? getMaxVer().get(0) + "." + getMaxVer().get(1) + "." + getMaxVer().get(2) : "None"; } + public static Signs match(Material mat) { + return valueOf(mat.toString().replace("WALL_", "")); + } + + public String getDefaultColour() { + return defaultColour; + } } public class ShopSign extends Utils { - private BukkitVersion version = new BukkitVersion(); - private ArrayList signTypes = new ArrayList<>(); + private final BukkitVersion version = new BukkitVersion(); + private final ArrayList signTypes = new ArrayList<>(); public ShopSign() { for (Signs type : Signs.values()) { boolean pass = true; - debugger.log(type.toString(), DebugLevels.STARTUP); - debugger.log(String.format("MinVer: %s", type.getMinVersionAsString()), DebugLevels.STARTUP); - debugger.log(String.format("MaxVer: %s", type.getMaxVersionAsString()), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(type.toString(), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("MinVer: %s", type.getMinVersionAsString()), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("MaxVer: %s", type.getMaxVersionAsString()), DebugLevels.STARTUP); if (type.hasMinVersion() && version.isBelow(type.getMinVer().get(0), type.getMinVer().get(1), type.getMinVer().get(2))) { pass = false; @@ -122,16 +128,32 @@ public ShopSign() { pass = false; } - if (pass) + if (pass) { signTypes.add(Material.matchMaterial(type.toString())); + signTypes.add(Material.matchMaterial(type.toString().toUpperCase().replace("_SIGN", "_WALL_SIGN"))); + } } - - } public List getSignTypes() { return signTypes; } + public static Map getDefaultColourMap() { + final BukkitVersion version = new BukkitVersion(); + Map colourMap = new HashMap<>(); + + for (Signs value : Signs.values()) { + String key = value.name().toLowerCase().replace("_", "-"); + + colourMap.put(key, value.getDefaultColour()); + if (value.hasMinVersion() && version.isBelow(value.getMinVer().get(0), value.getMinVer().get(1), value.getMinVer().get(2))) + colourMap.remove(key); + if (value.hasMaxVersion() && version.isAbove(value.getMaxVer().get(0), value.getMaxVer().get(1), value.getMaxVer().get(2))) + colourMap.remove(key); + } + + return colourMap; + } } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopStatus.java b/src/main/java/org/shanerx/tradeshop/shop/ShopStatus.java similarity index 96% rename from src/main/java/org/shanerx/tradeshop/enumys/ShopStatus.java rename to src/main/java/org/shanerx/tradeshop/shop/ShopStatus.java index fdc60ae0..0c30fc4c 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopStatus.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopStatus.java @@ -23,10 +23,10 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.shop; import org.bukkit.ChatColor; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.data.config.Setting; public enum ShopStatus { diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopStorage.java b/src/main/java/org/shanerx/tradeshop/shop/ShopStorage.java similarity index 84% rename from src/main/java/org/shanerx/tradeshop/enumys/ShopStorage.java rename to src/main/java/org/shanerx/tradeshop/shop/ShopStorage.java index d6f2bc20..9b859d20 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopStorage.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopStorage.java @@ -23,12 +23,13 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.shop; import com.google.common.collect.Lists; import org.bukkit.Material; -import org.shanerx.tradeshop.utils.BukkitVersion; import org.shanerx.tradeshop.utils.Utils; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.versionmanagement.BukkitVersion; import java.util.ArrayList; import java.util.Arrays; @@ -37,16 +38,16 @@ public class ShopStorage extends Utils { - private BukkitVersion version = new BukkitVersion(); - private HashMap storageTypes = new HashMap<>(); + private final BukkitVersion version = new BukkitVersion(); + private final HashMap storageTypes = new HashMap<>(); public ShopStorage() { for (Storages type : Storages.values()) { - debugger.log(type.toString(), DebugLevels.STARTUP); - debugger.log(String.format("- MinVer: %s", type.getMinVersionAsString()), DebugLevels.STARTUP); - debugger.log(String.format("- MaxVer: %s", type.getMaxVersionAsString()), DebugLevels.STARTUP); - debugger.log(String.format("- Weight: %s", type.getWeight()), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(type.toString(), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("- MinVer: %s", type.getMinVersionAsString()), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("- MaxVer: %s", type.getMaxVersionAsString()), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("- Weight: %s", type.getWeight()), DebugLevels.STARTUP); boolean added = false; @@ -56,7 +57,7 @@ public ShopStorage() { added = true; } - debugger.log(String.format("- Added: %s", added), DebugLevels.STARTUP); + PLUGIN.getDebugger().log(String.format("- Added: %s", added), DebugLevels.STARTUP); } } @@ -93,10 +94,11 @@ public enum Storages { SHULKER_BOX("1.11.0", "", 1, Lists.newArrayList(Material.SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.BLACK_SHULKER_BOX)), SMOKER("1.14.0", "", 10, Lists.newArrayList(Material.SMOKER)); - private List minVer = Arrays.asList(new Integer[3]), maxVer = Arrays.asList(new Integer[3]); + private final List minVer = Arrays.asList(new Integer[3]); + private final List maxVer = Arrays.asList(new Integer[3]); private boolean hasMin = true, hasMax = true; private int weight = 10; - private List typeMaterials; + private final List typeMaterials; Storages(String minVersion, String maxVersion, int weight, List typeMaterials) { if (minVersion.equalsIgnoreCase("")) diff --git a/src/main/java/org/shanerx/tradeshop/enumys/ShopType.java b/src/main/java/org/shanerx/tradeshop/shop/ShopType.java similarity index 75% rename from src/main/java/org/shanerx/tradeshop/enumys/ShopType.java rename to src/main/java/org/shanerx/tradeshop/shop/ShopType.java index 9b2e0092..4ea28947 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/ShopType.java +++ b/src/main/java/org/shanerx/tradeshop/shop/ShopType.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.shop; import com.google.gson.Gson; import org.bukkit.Bukkit; @@ -32,25 +32,25 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.player.Permissions; import java.io.Serializable; -public enum ShopType implements Serializable { +public enum ShopType { - TRADE(Setting.TRADESHOP_HEADER.getString(), Permissions.CREATE), + TRADE(Permissions.CREATE), - ITRADE(Setting.ITRADESHOP_HEADER.getString(), Permissions.CREATEI), + ITRADE(Permissions.CREATEI), - BITRADE(Setting.BITRADESHOP_HEADER.getString(), Permissions.CREATEBI); + BITRADE(Permissions.CREATEBI); - private final transient static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); - private final String key; + private final static TradeShop plugin = (TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop"); + private Setting key; private final transient Permissions perm; - ShopType(String key, Permissions perm) { - this.key = key; + ShopType(Permissions perm) { this.perm = perm; } @@ -82,26 +82,23 @@ public static ShopType getType(Sign s) { return null; } - public static ShopRole deserialize(String serialized) { - ShopRole shopRole = new Gson().fromJson(serialized, ShopRole.class); - return shopRole; - } - @Override public String toString() { - return key; + return getKey().getString(); } public String toHeader() { - return "[" + key + "]"; + return "[" + getKey().getString() + "]"; } - public boolean checkPerm(Player pl) { - return Permissions.hasPermission(pl, perm); + private Setting getKey() { + if (key == null) + key = Setting.findSetting(name() + "SHOP_HEADER"); + return key; } - public String serialize() { - return new Gson().toJson(this); + public boolean checkPerm(Player pl) { + return Permissions.hasPermission(pl, perm); } public boolean isTrade() { diff --git a/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopCreateListener.java b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopCreateListener.java new file mode 100644 index 00000000..1f7cb158 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopCreateListener.java @@ -0,0 +1,95 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.shop.listeners; + +import org.bukkit.Material; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.inventory.ItemStack; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopType; +import org.shanerx.tradeshop.utils.Utils; + +@SuppressWarnings("unused") +public class ShopCreateListener extends Utils implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onSignChange(SignChangeEvent event) { + + if (event.isCancelled()) + return; + + Sign shopSign = (Sign) event.getBlock().getState(); + shopSign.setLine(0, event.getLine(0)); + shopSign.setLine(1, event.getLine(1)); + shopSign.setLine(2, event.getLine(2)); + shopSign.setLine(3, event.getLine(3)); + + if (!ShopType.isShop(shopSign)) { + return; + } + + ShopType shopType = ShopType.getType(shopSign); + Player p = event.getPlayer(); + + // Clear the first line since we already know it is going to be a Shop, and we have the type to pass separately + // Required as the createShop method needs to make sure the first line is blank for commands to avoid overwriting existing shops + shopSign.setLine(0, ""); + + Shop shop = createShop(shopSign, p, shopType, lineCheck(ShopItemSide.COST, event.getLine(2)), lineCheck(ShopItemSide.PRODUCT, event.getLine(1)), event); + + if (shop == null) { + failedSignReset(event, shopType); + } + } + + private ItemStack lineCheck(ShopItemSide side, String line) { + if (line == null || line.equalsIgnoreCase("") || !line.contains(" ") || line.split(" ").length != 2) + return null; + + String[] info = line.split(" "); + + for (String str : info) { + if (str == null || str.equalsIgnoreCase("")) + return null; + } + + if (!isInt(info[0]) || Material.matchMaterial(info[1]) == null) + return null; + + ItemStack item = new ItemStack(Material.matchMaterial(info[1]), Integer.parseInt(info[0])); + + if (PLUGIN.getListManager().isIllegal(side, item.getType())) + return null; + + return item; + } +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/listeners/ShopProtectionListener.java b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopProtectionListener.java similarity index 76% rename from src/main/java/org/shanerx/tradeshop/listeners/ShopProtectionListener.java rename to src/main/java/org/shanerx/tradeshop/shop/listeners/ShopProtectionListener.java index 21aa816b..352a6dc3 100644 --- a/src/main/java/org/shanerx/tradeshop/listeners/ShopProtectionListener.java +++ b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopProtectionListener.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.listeners; +package org.shanerx.tradeshop.shop.listeners; import org.bukkit.Bukkit; import org.bukkit.block.Block; @@ -39,22 +39,25 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerInteractEvent; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.enumys.ShopType; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; import org.shanerx.tradeshop.framework.events.HopperShopAccessEvent; import org.shanerx.tradeshop.framework.events.PlayerShopDestroyEvent; import org.shanerx.tradeshop.framework.events.PlayerShopInventoryOpenEvent; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChest; -import org.shanerx.tradeshop.objects.ShopLocation; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopChest; +import org.shanerx.tradeshop.shop.ShopSettingKeys; +import org.shanerx.tradeshop.shop.ShopType; +import org.shanerx.tradeshop.shoplocation.ShopLocation; import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.utils.debug.DebugLevels; import java.util.ArrayList; import java.util.Arrays; @@ -85,13 +88,11 @@ public void onInventoryMoveItem(InventoryMoveItemEvent event) { Boolean skip = plugin.getListManager().canSkipHopper(event.getInitiator().getLocation()); if (skip != null) { - event.setCancelled(skip); + if (skip) event.setCancelled(true); return; } - boolean fromHopper; - - fromHopper = event.getInitiator().equals(event.getSource()); + boolean fromHopper = event.getInitiator().equals(event.getSource()); Block invBlock; @@ -100,31 +101,36 @@ public void onInventoryMoveItem(InventoryMoveItemEvent event) { invBlock = (fromHopper ? event.getDestination() : event.getSource()).getLocation().getBlock(); } catch (NullPointerException ignored) { plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), false); + plugin.getDebugger().log("Protection Null Catch for \n " + event.getInitiator().getLocation(), DebugLevels.PROTECTION); return; } if (!plugin.getListManager().isInventory(invBlock)) { plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), false); + plugin.getDebugger().log("Protection Inventory Catch for \n " + event.getInitiator().getLocation(), DebugLevels.PROTECTION); return; } if (!ShopChest.isShopChest(invBlock)) { - plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), false); + //Just return as adding these to the skip would often catch the second half of hoppers pulling from shops then pushing to a chest + + //plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), false); + //plugin.getDebugger().log("Protection ShopChest Catch for \n " + event.getInitiator().getLocation() + "\n Source: " + event.getSource().getLocation() + "\n Destination: " + event.getDestination().getLocation(), DebugLevels.PROTECTION); return; } Shop shop = plugin.getDataStorage().loadShopFromStorage(new ShopLocation(invBlock.getLocation())); - boolean isForbidden = !Setting.findSetting(shop.getShopType().name() + "SHOP_HOPPER_" + (fromHopper ? "IMPORT" : "EXPORT")).getBoolean(); + boolean isForbidden = !(fromHopper ? shop.getShopSetting(ShopSettingKeys.HOPPER_IMPORT).asBoolean() : shop.getShopSetting(ShopSettingKeys.HOPPER_EXPORT).asBoolean()); if (isForbidden) { event.setCancelled(true); - plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), true); + //plugin.getListManager().addSkippableShop(event.getInitiator().getLocation(), true); return; } - debugger.log("ShopProtectionListener: Triggered > " + (fromHopper ? "FROM_HOPPER" : "TO_HOPPER"), DebugLevels.PROTECTION); - debugger.log("ShopProtectionListener: Shop Location as SL > " + shop.getInventoryLocationAsSL().serialize(), DebugLevels.PROTECTION); - debugger.log("ShopProtectionListener: checked hopper setting > " + shop.getShopType().name() + "SHOP_HOPPER_EXPORT", DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: Triggered > " + (fromHopper ? "FROM_HOPPER" : "TO_HOPPER"), DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: Shop Location as SL > " + shop.getInventoryLocationAsSL().toString(), DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: checked hopper setting > " + shop.getShopType().name() + "SHOP_HOPPER_EXPORT", DebugLevels.PROTECTION); HopperShopAccessEvent hopperEvent = new HopperShopAccessEvent( shop, event.getSource(), @@ -132,15 +138,16 @@ public void onInventoryMoveItem(InventoryMoveItemEvent event) { event.getItem(), fromHopper ? HopperShopAccessEvent.HopperDirection.FROM_HOPPER : HopperShopAccessEvent.HopperDirection.TO_HOPPER ); - debugger.log("ShopProtectionListener: (TSAF) HopperEvent fired! ", DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: (TSAF) HopperEvent fired! ", DebugLevels.PROTECTION); Bukkit.getPluginManager().callEvent(hopperEvent); - debugger.log("ShopProtectionListener: (TSAF) HopperEvent recovered! ", DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: (TSAF) HopperEvent recovered! ", DebugLevels.PROTECTION); + plugin.getDebugger().log("ShopProtectionListener: (TSAF) HopperEvent isForbidden: " + hopperEvent.isForbidden(), DebugLevels.PROTECTION); event.setCancelled(hopperEvent.isForbidden()); - plugin.getListManager().addSkippableHopper(event.getInitiator().getLocation(), hopperEvent.isForbidden()); - debugger.log("ShopProtectionListener: (TSAF) HopperEvent isForbidden: " + hopperEvent.isForbidden(), DebugLevels.PROTECTION); - shop.updateStatus(); - shop.updateSign(); - shop.saveShop(); + //plugin.getListManager().addSkippableShop(event.getInitiator().getLocation(), hopperEvent.isForbidden()); + + if (!hopperEvent.isForbidden()) { + scheduleShopDelayUpdate(shop, 2L); + } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -301,7 +308,7 @@ public void onChestOpen(PlayerInteractEvent e) { return; } - if (!Permissions.isAdminEnabled(e.getPlayer()) && !shop.getUsersUUID().contains(e.getPlayer().getUniqueId())) { + if (!Permissions.isAdminEnabled(e.getPlayer()) && !shop.getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER, ShopRole.MEMBER).contains(e.getPlayer().getUniqueId())) { openEvent.setCancelled(true); } @@ -313,6 +320,19 @@ public void onChestOpen(PlayerInteractEvent e) { } } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onChestInventoryClose(InventoryCloseEvent e) { + if (e.getInventory().getLocation() == null) + return; + + Block block = e.getInventory().getLocation().getBlock(); + + if (ShopChest.isShopChest(block)) { + scheduleShopDelayUpdate(new ShopChest(block.getLocation()).getShop(), 2L); + } + + } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { @@ -334,7 +354,7 @@ public void onBlockPlace(BlockPlaceEvent event) { if (shop.getShopType().isITrade()) return; - if (shop.getUsersUUID().contains(event.getPlayer().getUniqueId())) { + if (shop.getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER).contains(event.getPlayer().getUniqueId())) { if (!shop.hasStorage()) { new ShopChest(block, shop.getOwner().getUUID(), shopSign.getLocation()).setEventName(event); shop.setInventoryLocation(block.getLocation()); @@ -345,4 +365,16 @@ public void onBlockPlace(BlockPlaceEvent event) { } return; } + + private void scheduleShopDelayUpdate(Shop shop, Long delay) { + plugin.getDebugger().log("Shop Being updated from ProtectionListener...\n " + shop.getShopLocationAsSL().toString(), DebugLevels.PROTECTION); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + shop.updateFullTradeCount(); + shop.updateSign(); + shop.saveShop(); + } + }, delay); + } } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/listeners/ShopRestockListener.java b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopRestockListener.java similarity index 93% rename from src/main/java/org/shanerx/tradeshop/listeners/ShopRestockListener.java rename to src/main/java/org/shanerx/tradeshop/shop/listeners/ShopRestockListener.java index 07abb6b1..02d5b258 100644 --- a/src/main/java/org/shanerx/tradeshop/listeners/ShopRestockListener.java +++ b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopRestockListener.java @@ -23,15 +23,15 @@ * */ -package org.shanerx.tradeshop.listeners; +package org.shanerx.tradeshop.shop.listeners; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryCloseEvent; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChest; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopChest; import org.shanerx.tradeshop.utils.Utils; public class ShopRestockListener extends Utils implements Listener { diff --git a/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopTradeListener.java similarity index 55% rename from src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java rename to src/main/java/org/shanerx/tradeshop/shop/listeners/ShopTradeListener.java index df54afef..07f598bf 100644 --- a/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java +++ b/src/main/java/org/shanerx/tradeshop/shop/listeners/ShopTradeListener.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.listeners; +package org.shanerx.tradeshop.shop.listeners; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -39,19 +39,22 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.shanerx.tradeshop.enumys.ExchangeStatus; -import org.shanerx.tradeshop.enumys.Permissions; -import org.shanerx.tradeshop.enumys.ShopType; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.data.config.Variable; import org.shanerx.tradeshop.framework.events.PlayerPreTradeEvent; import org.shanerx.tradeshop.framework.events.PlayerPrepareTradeEvent; import org.shanerx.tradeshop.framework.events.PlayerSuccessfulTradeEvent; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopLocation; -import org.shanerx.tradeshop.utils.Tuple; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.shop.ExchangeStatus; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopType; +import org.shanerx.tradeshop.shoplocation.ShopLocation; import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; -import org.shanerx.tradeshop.utils.config.Variable; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.objects.Tuple; import java.util.Collections; import java.util.HashMap; @@ -89,7 +92,7 @@ public void onBlockInteract(PlayerInteractEvent e) { return; } - if (Permissions.hasPermission(buyer, Permissions.PREVENT_TRADE) && !buyer.isOp()) { + if (!Permissions.hasPermission(buyer, Permissions.TRADE)) { Message.NO_TRADE_PERMISSION.sendMessage(buyer); return; } @@ -98,12 +101,12 @@ public void onBlockInteract(PlayerInteractEvent e) { return; } - if (!shop.getShopType().equals(ShopType.ITRADE) && shop.getUsersUUID().contains(buyer.getUniqueId()) && !Setting.ALLOW_USER_PURCHASING.getBoolean()) { + if (!shop.getShopType().equals(ShopType.ITRADE) && shop.getUsersUUID(ShopRole.OWNER, ShopRole.MANAGER, ShopRole.MEMBER).contains(buyer.getUniqueId()) && !Setting.ALLOW_USER_PURCHASING.getBoolean()) { Message.SELF_OWNED.sendMessage(buyer); return; } - PlayerPreTradeEvent preEvent = new PlayerPreTradeEvent(e.getPlayer(), shop.getCost(), shop.getProduct(), shop, e.getClickedBlock(), e.getBlockFace()); + PlayerPreTradeEvent preEvent = new PlayerPreTradeEvent(e.getPlayer(), shop.getSideList(ShopItemSide.COST), shop.getSideList(ShopItemSide.PRODUCT), shop, e.getClickedBlock(), e.getBlockFace()); Bukkit.getPluginManager().callEvent(preEvent); if (preEvent.isCancelled()) return; @@ -116,7 +119,7 @@ public void onBlockInteract(PlayerInteractEvent e) { return; } - if (!(shop.areProductsValid() && shop.areCostsValid())) { + if (!(shop.isSideValid(ShopItemSide.PRODUCT) && shop.isSideValid(ShopItemSide.COST))) { Message.ILLEGAL_ITEM.sendMessage(buyer); return; } @@ -133,19 +136,22 @@ public void onBlockInteract(PlayerInteractEvent e) { return; case INCOMPLETE: Message.SHOP_EMPTY.sendMessage(buyer); + return; case OUT_OF_STOCK: if (shop.getShopType() == ShopType.ITRADE) { break; } - List searchResult = getItems(shop.getChestAsSC().getInventory().getStorageContents(), doBiTradeAlternate ? shop.getCost() : shop.getProduct(), multiplier); - Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, searchResult)); + if (shop.hasSide(ShopItemSide.PRODUCT)) { + List searchResult = getItems(shop.getChestAsSC().getInventory().getStorageContents(), shop.getSideList(ShopItemSide.PRODUCT, doBiTradeAlternate), multiplier); + Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, searchResult)); + } return; case OPEN: break; } - PlayerPrepareTradeEvent event = new PlayerPrepareTradeEvent(e.getPlayer(), shop.getCost(), shop.getProduct(), shop, e.getClickedBlock(), e.getBlockFace()); + PlayerPrepareTradeEvent event = new PlayerPrepareTradeEvent(e.getPlayer(), shop.getSideList(ShopItemSide.COST), shop.getSideList(ShopItemSide.PRODUCT), shop, e.getClickedBlock(), e.getBlockFace()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; @@ -154,6 +160,7 @@ public void onBlockInteract(PlayerInteractEvent e) { Tuple> canExchangeResult = canExchangeAll(shop, buyer.getInventory(), multiplier, e.getAction()); + PLUGIN.getDebugger().log("ExchangeResult " + canExchangeResult.getLeft(), DebugLevels.TRADE); switch (canExchangeResult.getLeft()) { case SHOP_NO_PRODUCT: Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, canExchangeResult.getRight())); @@ -183,13 +190,18 @@ public void onBlockInteract(PlayerInteractEvent e) { tradedItems.put(Variable.GIVEN_LINES, tradeReturn.getRight()); tradedItems.put(Variable.RECEIVED_LINES, tradeReturn.getLeft()); - if (tradeReturn.getLeft().get(0) != null && tradeReturn.getRight().get(0) != null) { - Message.ON_TRADE.sendItemMultiLineMessage(buyer, tradedItems, - new Tuple<>(Variable.SELLER.toString(), shop.getShopType().isITrade() ? Setting.ITRADESHOP_OWNER.getString() : owner)); - } else { + PLUGIN.getDebugger().log("ShopTradeListener > tradedItems: " + tradedItems, DebugLevels.TRADE); + + if (tradeReturn.getLeft().get(0) == null && tradeReturn.getRight().get(0) == null) { Message.FAILED_TRADE.sendMessage(buyer); + + } else { + Message.ON_TRADE.sendItemMultiLineMessage(buyer, tradedItems, + new Tuple<>(Variable.SELLER.toString(), shop.getShopType().equals(ShopType.ITRADE) ? Setting.ITRADESHOP_OWNER.getString() : owner)); } + + shop.updateFullTradeCount(); shop.updateSign(); shop.saveShop(); } @@ -200,113 +212,85 @@ private Tuple, List> tradeAllItems(Shop shop, int mul Inventory shopInventory = shop.hasStorage() ? shop.getChestAsSC().getInventory() : null; Inventory playerInventory = buyer.getInventory(); - if (shop.getShopType() == ShopType.ITRADE && action.equals(Action.RIGHT_CLICK_BLOCK)) { //ITrade trade - - if (!shop.getCost().isEmpty()) { - costItems = getItems(playerInventory.getStorageContents(), shop.getCost(), multiplier); - if (costItems.get(0) == null) { - ItemStack item = costItems.get(1); - Message.INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, costItems)); - return new Tuple<>(productItems, costItems); - } - - for (ItemStack item : costItems) { - playerInventory.removeItem(item); - } - } else { - costItems.clear(); - - //Create Free item and set amount/name - ItemStack noCostITradeItem = new ItemStack(Material.STICK, Setting.ITRADESHOP_NO_COST_AMOUNT.getInt()); - ItemMeta noCostITradeMeta = noCostITradeItem.getItemMeta(); - noCostITradeMeta.setDisplayName(Setting.ITRADESHOP_NO_COST_TEXT.getString()); - noCostITradeItem.setItemMeta(noCostITradeMeta); - - costItems.add(noCostITradeItem); - } - - Inventory iTradeVirtualInventory = Bukkit.createInventory(null, Math.min((int) (Math.ceil(shop.getProduct().size() / 9.0) * 9) * multiplier, 54)); - while (iTradeVirtualInventory.firstEmpty() != -1) { - for (ItemStack item : shop.getProductItemStacks()) { + if (shop.getShopType().equals(ShopType.ITRADE)) { + shopInventory = Bukkit.createInventory(null, Math.min((int) (Math.ceil(shop.getSideList(ShopItemSide.PRODUCT).size() / 9.0) * 9) * multiplier, 54)); + while (shopInventory.firstEmpty() != -1) { + for (ItemStack item : shop.getSideItemStacks(ShopItemSide.PRODUCT)) { item.setAmount(item.getMaxStackSize()); - iTradeVirtualInventory.addItem(item); + shopInventory.addItem(item); } } + } - productItems = getItems(iTradeVirtualInventory.getStorageContents(), shop.getProduct(), multiplier); - - for (ItemStack item : productItems) { - playerInventory.addItem(item); - } - - Bukkit.getPluginManager().callEvent(new PlayerSuccessfulTradeEvent(buyer, costItems, productItems, shop, event.getClickedBlock(), event.getBlockFace())); - PLUGIN.getMetricsManager().addTrade(); - return new Tuple<>(productItems, costItems); //Successfully completed trade - } else if (shop.getShopType() == ShopType.BITRADE && action == Action.LEFT_CLICK_BLOCK) { //BiTrade Reversed Trade + boolean isBi = shop.getShopType().equals(ShopType.BITRADE) && action.equals(Action.LEFT_CLICK_BLOCK), + useCost = !shop.isNoCost() || shop.hasSide(ShopItemSide.COST); - //Method to find Cost items in player inventory and add to cost array - costItems = getItems(playerInventory.getStorageContents(), shop.getProduct(), multiplier); //Reverse BiTrade, Product is Cost + //Method to find Cost items in player inventory and add to cost array + if (useCost) { + costItems = getItems(playerInventory.getStorageContents(), shop.getSideList(ShopItemSide.COST, isBi), multiplier); if (costItems.get(0) == null) { ItemStack item = costItems.get(1); Message.INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, costItems)); + PLUGIN.getDebugger().log("tradeAllItems", DebugLevels.TRADE); return new Tuple<>(productItems, costItems); } + } else { + costItems.clear(); - //Method to find Product items in shop inventory and add to product array - productItems = getItems(shopInventory.getStorageContents(), shop.getCost(), multiplier); //Reverse BiTrade, Cost is Product - if (productItems.get(0) == null) { - ItemStack item = productItems.get(1); - shop.updateStatus(); - Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, productItems)); - return new Tuple<>(productItems, costItems); - } - } else if (action.equals(Action.RIGHT_CLICK_BLOCK)) { // Normal Trade + ItemStack noCostItem = new ItemStack(Material.STICK, Setting.NO_COST_AMOUNT.getInt()); + ItemMeta noCostMeta = noCostItem.getItemMeta(); + noCostMeta.setDisplayName(Setting.NO_COST_TEXT.getString()); + noCostItem.setItemMeta(noCostMeta); - //Method to find Cost items in player inventory and add to cost array - costItems = getItems(playerInventory.getStorageContents(), shop.getCost(), multiplier); - if (costItems.get(0) == null) { - ItemStack item = costItems.get(1); - Message.INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, costItems)); - return new Tuple<>(productItems, costItems); - } + costItems.add(noCostItem); + } - //Method to find Product items in shop inventory and add to product array - productItems = getItems(shopInventory.getStorageContents(), shop.getProduct(), multiplier); - if (productItems.get(0) == null) { - ItemStack item = productItems.get(1); - shop.updateStatus(); - Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, productItems)); - return new Tuple<>(productItems, costItems); - } + //Method to find Product items in shop inventory and add to product array + productItems = getItems(shopInventory.getStorageContents(), shop.getSideList(ShopItemSide.PRODUCT, isBi), multiplier); + if (productItems.get(0) == null) { + ItemStack item = productItems.get(1); + shop.updateStatus(); + Message.SHOP_INSUFFICIENT_ITEMS.sendItemMultiLineMessage(buyer, Collections.singletonMap(Variable.MISSING_ITEMS, productItems)); + return new Tuple<>(productItems, costItems); + } + if (costItems.size() == 0) { + return new Tuple<>(productItems, costItems); // Failed Trade } - if (costItems.size() > 0) { + PLUGIN.getDebugger().log("ShopTradeListener > tradeAll > preMove-productItems: " + productItems, DebugLevels.TRADE); + PLUGIN.getDebugger().log("ShopTradeListener > tradeAll > preMove-costItems: " + costItems, DebugLevels.TRADE); + + if (useCost) { //For loop to remove cost items from player inventory for (ItemStack item : costItems) { - playerInventory.removeItem(item); + playerInventory.removeItem(item.clone()); } + } - //For loop to remove product items from shop inventory - for (ItemStack item : productItems) { - shopInventory.removeItem(item); - } + //For loop to remove product items from shop inventory + for (ItemStack item : productItems) { + shopInventory.removeItem(item.clone()); + } + if (useCost) { //For loop to put cost items in shop inventory for (ItemStack item : costItems) { - shopInventory.addItem(item); - } - - //For loop to put product items in player inventory - for (ItemStack item : productItems) { - playerInventory.addItem(item); + addItemToInventory(shopInventory, item.clone()); } + } - Bukkit.getPluginManager().callEvent(new PlayerSuccessfulTradeEvent(buyer, costItems, productItems, shop, event.getClickedBlock(), event.getBlockFace())); - PLUGIN.getMetricsManager().addTrade(); - return new Tuple<>(productItems, costItems); //Successfully completed trade - } else { - return new Tuple<>(productItems, costItems); + //For loop to put product items in player inventory + for (ItemStack item : productItems) { + addItemToInventory(playerInventory, item.clone()); } + + PLUGIN.getDebugger().log("ShopTradeListener > tradeAll > end-productItems: " + productItems, DebugLevels.TRADE); + PLUGIN.getDebugger().log("ShopTradeListener > tradeAll > end-costItems: " + costItems, DebugLevels.TRADE); + + Bukkit.getPluginManager().callEvent(new PlayerSuccessfulTradeEvent(buyer, costItems, productItems, shop, event.getClickedBlock(), event.getBlockFace())); + PLUGIN.getMetricsManager().addTrade(); + + return new Tuple<>(productItems, costItems); //Successfully completed trade } } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/exceptions/IllegalWorldException.java b/src/main/java/org/shanerx/tradeshop/shoplocation/IllegalWorldException.java similarity index 93% rename from src/main/java/org/shanerx/tradeshop/exceptions/IllegalWorldException.java rename to src/main/java/org/shanerx/tradeshop/shoplocation/IllegalWorldException.java index 65342eda..e0be6587 100644 --- a/src/main/java/org/shanerx/tradeshop/exceptions/IllegalWorldException.java +++ b/src/main/java/org/shanerx/tradeshop/shoplocation/IllegalWorldException.java @@ -23,9 +23,7 @@ * */ -package org.shanerx.tradeshop.exceptions; - -import org.shanerx.tradeshop.objects.WorldlessLocation; +package org.shanerx.tradeshop.shoplocation; public class IllegalWorldException extends IllegalStateException { diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java b/src/main/java/org/shanerx/tradeshop/shoplocation/ShopChunk.java similarity index 92% rename from src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java rename to src/main/java/org/shanerx/tradeshop/shoplocation/ShopChunk.java index e8087089..266d40c6 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java +++ b/src/main/java/org/shanerx/tradeshop/shoplocation/ShopChunk.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.shoplocation; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -31,7 +31,7 @@ import java.io.Serializable; -public class ShopChunk implements Serializable { +public class ShopChunk { final private String div = ";;"; private final World world; @@ -53,7 +53,7 @@ public ShopChunk(Chunk c) { chunk = c; } - public static ShopChunk deserialize(String loc) { + public static ShopChunk fromString(String loc) { if (loc.startsWith("c")) { String[] locA = loc.contains(";;") ? loc.split(";;") : loc.split("_"); //Keep same as div World world = Bukkit.getWorld(locA[1]); @@ -67,7 +67,8 @@ public static ShopChunk deserialize(String loc) { return null; } - public String serialize() { + @Override + public String toString() { return "c" + div + world.getName() + div + x + div + z; } diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopLocation.java b/src/main/java/org/shanerx/tradeshop/shoplocation/ShopLocation.java similarity index 89% rename from src/main/java/org/shanerx/tradeshop/objects/ShopLocation.java rename to src/main/java/org/shanerx/tradeshop/shoplocation/ShopLocation.java index c2cd5091..b73b4a7c 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopLocation.java +++ b/src/main/java/org/shanerx/tradeshop/shoplocation/ShopLocation.java @@ -23,17 +23,16 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.shoplocation; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; -import org.shanerx.tradeshop.exceptions.IllegalWorldException; import java.io.Serializable; -public class ShopLocation implements Serializable { +public class ShopLocation { final private String div = "::"; private transient World world; @@ -58,7 +57,7 @@ public ShopLocation(Location loc) { this.z = loc.getZ(); } - public static ShopLocation deserialize(String loc) { + public static ShopLocation fromString(String loc) { if (loc.startsWith("l")) { String[] locA = loc.contains("::") ? loc.split("::") : loc.split("_"); //Keep same as div double x = Double.parseDouble(locA[2]), y = Double.parseDouble(locA[3]), z = Double.parseDouble(locA[4]); @@ -68,7 +67,7 @@ public static ShopLocation deserialize(String loc) { world = Bukkit.getWorld(locA[1].replace("-", "_")); if (world == null) { throw new IllegalWorldException("Cannot find world " + locA[1], new WorldlessLocation(x, y, z)); - // Not to maintainer: do NOT remove this aritificial error, it is supposed to be catched elsewhere + // Not to maintainer: do NOT remove this artificial error, it is supposed to be caught elsewhere // (Temporary fix for metadata world renaming bug until metadata is removed entirely) } @@ -78,7 +77,8 @@ public static ShopLocation deserialize(String loc) { return null; } - public String serialize() { + @Override + public String toString() { return "l" + div + world.getName() + div + x + div + y + div + z; } diff --git a/src/main/java/org/shanerx/tradeshop/shoplocation/WorldlessLocation.java b/src/main/java/org/shanerx/tradeshop/shoplocation/WorldlessLocation.java new file mode 100644 index 00000000..a0dbdef7 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/shoplocation/WorldlessLocation.java @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.shoplocation; + +import org.bukkit.Location; +import org.bukkit.World; + +public class WorldlessLocation { + + private final double x; + private final double y; + private final double z; + + public WorldlessLocation(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Location getLocation(World w) { + return new Location(w, x, y, z); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/objects/package-info.java b/src/main/java/org/shanerx/tradeshop/shoplocation/package-info.java similarity index 68% rename from src/main/java/org/shanerx/tradeshop/objects/package-info.java rename to src/main/java/org/shanerx/tradeshop/shoplocation/package-info.java index 2b0d03f0..a20a6449 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/package-info.java +++ b/src/main/java/org/shanerx/tradeshop/shoplocation/package-info.java @@ -24,13 +24,6 @@ */ /** - * This class contains all the classes of the core of the plugin. - * The reason we are adding them to the docs are that the custom event framework - * makes use of the {@link org.shanerx.tradeshop.objects.Shop} class, - * and should only be used for read purposes, ie. accessing getters. - * - * - * NOTE: DO NOT ATTEMPT TO CHANGE THE PLUGIN'S INTERNAL DATA, NOT EVEN WITH SETTER METHODS, - * IF YOU DO NOT POSSESS AN UNDERSTANDING OF THE INTERNAL WORKINGS OF THE PLUGIN! + * The classes in this package handle location data for usage across the plugin */ -package org.shanerx.tradeshop.objects; \ No newline at end of file +package org.shanerx.tradeshop.shoplocation; \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/objects/ListManager.java b/src/main/java/org/shanerx/tradeshop/utils/ListManager.java similarity index 68% rename from src/main/java/org/shanerx/tradeshop/objects/ListManager.java rename to src/main/java/org/shanerx/tradeshop/utils/ListManager.java index f1ebb319..f4706e29 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ListManager.java +++ b/src/main/java/org/shanerx/tradeshop/utils/ListManager.java @@ -23,22 +23,22 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.utils; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.NonObtainableMaterials; -import org.shanerx.tradeshop.enumys.ShopStorage; -import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.item.IllegalItemList; +import org.shanerx.tradeshop.item.NonObtainableMaterials; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.shop.ShopStorage; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.relativedirection.RelativeDirection; import java.util.ArrayList; -import java.util.Arrays; import java.util.concurrent.TimeUnit; @SuppressWarnings("unused") @@ -48,12 +48,12 @@ public class ListManager extends Utils { private final IllegalItemList costList = new IllegalItemList(IllegalItemList.ListType.DISABLED, new ArrayList<>()); private final IllegalItemList productList = new IllegalItemList(IllegalItemList.ListType.DISABLED, new ArrayList<>()); - private final ArrayList directions = new ArrayList<>(); + private final ArrayList directions = new ArrayList<>(); private final ArrayList inventories = new ArrayList<>(); private final ArrayList gameMats = new ArrayList<>(); private final ArrayList addOnMats = new ArrayList<>(); - private Cache skippableHoppers; //second data type doesn't matter and isn't used, boolean chosen as it is the smallest + private Cache skippableHoppers, skippableShop; public ListManager() { @@ -61,26 +61,48 @@ public ListManager() { setGameMatList(); } - private void initSkippableHoppers() { + private void initSkip() { skippableHoppers = CacheBuilder.newBuilder() .maximumSize(100000) .expireAfterAccess(1000, TimeUnit.MILLISECONDS) .build(); + skippableShop = CacheBuilder.newBuilder() + .maximumSize(1000) + .expireAfterWrite(1500, TimeUnit.MILLISECONDS) + .build(); } + /** + * Check if a hopper has already been processed and stored in the cache + * + * @param location What location to check for + * @return return null if not in cache(un-unprocessed) or true/false representing whether to block movement + */ public Boolean canSkipHopper(Location location) { - if (skippableHoppers.getIfPresent(location) == null) + if (skippableHoppers.getIfPresent(location) == null && skippableShop.getIfPresent(location) == null) return null; - else + else if (skippableHoppers.getIfPresent(location) != null) return skippableHoppers.getIfPresent(location); + else if (skippableShop.getIfPresent(location) != null) + return skippableShop.getIfPresent(location); + + return null; } public void addSkippableHopper(Location location, boolean shouldBlock) { skippableHoppers.put(location, shouldBlock); } + public void addSkippableShop(Location location, boolean shouldBlock) { + skippableShop.put(location, shouldBlock); + } + + public void removeSkippableShop(Location location) { + skippableShop.invalidate(location); + } + - public ArrayList getDirections() { + public ArrayList getDirections() { return directions; } @@ -104,18 +126,11 @@ public ArrayList getGameMats() { return gameMats; } - public boolean isIllegal(IllegalItemList.TradeItemType type, Material mat) { + public boolean isIllegal(ShopItemSide side, Material mat) { if (globalList.isIllegal(mat)) return true; - if (type.equals(IllegalItemList.TradeItemType.COST)) - return costList.isIllegal(mat); - else - return productList.isIllegal(mat); - } - - public boolean isDirection(BlockFace face) { - return directions.contains(face); + return side.equals(ShopItemSide.COST) ? costList.isIllegal(mat) : productList.isIllegal(mat); } public boolean isInventory(Block block) { @@ -123,7 +138,7 @@ public boolean isInventory(Block block) { Material blockMaterial = block.getType(); Boolean found = false; - debugger.log("isInventory Block Material: " + blockMaterial.name(), DebugLevels.LIST_MANAGER); + PLUGIN.getDebugger().log("isInventory Block Material: " + blockMaterial.name(), DebugLevels.LIST_MANAGER); //For each ShopStorage.Storages in inventories, check if their block list contains the block material. end loop if true. for (ShopStorage.Storages storage : inventories) { @@ -131,9 +146,9 @@ public boolean isInventory(Block block) { found = true; break; } - } + } - debugger.log("isInventory Block Material found: " + found, DebugLevels.LIST_MANAGER); + PLUGIN.getDebugger().log("isInventory Block Material found: " + found, DebugLevels.LIST_MANAGER); return found; } @@ -143,7 +158,7 @@ public void reload() { updateDirections(); updateInventoryMats(); setGameMatList(); - initSkippableHoppers(); + initSkip(); } public void clearManager() { @@ -170,7 +185,7 @@ private void updateIllegalLists() { if (globalList.getType().equals(IllegalItemList.ListType.DISABLED)) globalList.setType(IllegalItemList.ListType.BLACKLIST); - debugger.log("Loading GLOBAL Illegal Item List with mode: " + globalList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); + PLUGIN.getDebugger().log("Loading GLOBAL Illegal Item List with mode: " + globalList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); if (globalList.getType().equals(IllegalItemList.ListType.BLACKLIST)) { // Add non-removable blacklist items globalList.add(Material.AIR); @@ -186,12 +201,12 @@ private void updateIllegalLists() { globalList.checkAndAdd(str); } - debugger.log("Loading COST Illegal Item List with mode: " + costList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); + PLUGIN.getDebugger().log("Loading COST Illegal Item List with mode: " + costList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); for (String str : Setting.COST_ILLEGAL_ITEMS_LIST.getStringList()) { costList.checkAndAdd(str); } - debugger.log("Loading PRODUCT Illegal Item List with mode: " + productList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); + PLUGIN.getDebugger().log("Loading PRODUCT Illegal Item List with mode: " + productList.getType(), DebugLevels.ILLEGAL_ITEMS_LIST); for (String str : Setting.PRODUCT_ILLEGAL_ITEMS_LIST.getStringList()) { productList.checkAndAdd(str); } @@ -208,22 +223,23 @@ private void setGameMatList() { } } - // Remove all non obtainable materials that we have found + // Remove all non-obtainable materials that we have found for (NonObtainableMaterials mat : NonObtainableMaterials.values()) { gameMats.remove(mat.toString()); } - //Adds any strings that have been added the the AddOnMats list to the autocomplete list + //Adds any strings that have been added the AddOnMats list to the autocomplete list gameMats.addAll(addOnMats); } private void updateDirections() { directions.clear(); - ArrayList allowed = new ArrayList<>(Arrays.asList(BlockFace.DOWN, BlockFace.WEST, BlockFace.SOUTH, BlockFace.EAST, BlockFace.NORTH, BlockFace.UP)); - for (String str : Setting.ALLOWED_DIRECTIONS.getStringList()) { - if (allowed.contains(BlockFace.valueOf(str))) - directions.add(BlockFace.valueOf(str)); + for (String str : Setting.CHEST_DIRECTIONS.getStringList()) { + try { + directions.add(RelativeDirection.valueOf(str)); + } catch (IllegalArgumentException | NullPointerException ignored) { + } } } @@ -231,8 +247,8 @@ private void updateInventoryMats() { //Clears the list before updating inventories.clear(); - debugger.log("Inventory Materials from Config:", DebugLevels.STARTUP); - debugger.log("Config String | Status | Matching Type", DebugLevels.STARTUP); + PLUGIN.getDebugger().log("Inventory Materials from Config:", DebugLevels.STARTUP); + PLUGIN.getDebugger().log("Config String | Status | Matching Type", DebugLevels.STARTUP); //For each String in the Allowed shops config setting, check if it is a valid inventory and add the ShopStorage.Storages object to the list for (String str : Setting.ALLOWED_SHOPS.getStringList()) { @@ -246,7 +262,7 @@ private void updateInventoryMats() { logMsg += " | InValid"; } - debugger.log(logMsg, DebugLevels.STARTUP); + PLUGIN.getDebugger().log(logMsg, DebugLevels.STARTUP); } } } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java b/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java index 58965d4a..04e73bfc 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java +++ b/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java @@ -33,8 +33,8 @@ import org.bstats.charts.SingleLineChart; import org.bukkit.World; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; import java.util.Arrays; import java.util.HashMap; @@ -100,21 +100,17 @@ private void addFeatureMetric() { @Override public Map call() throws Exception { Map map = new HashMap<>(); - List booleanSettingList = Arrays.asList(Setting.CHECK_UPDATES, + List booleanSettingList = Arrays.asList( + Setting.CHECK_UPDATES, Setting.UNLIMITED_ADMIN, - Setting.USE_INTERNAL_PERMISSIONS, Setting.ALLOW_TOGGLE_STATUS, Setting.ALLOW_SIGN_BREAK, Setting.ALLOW_CHEST_BREAK, Setting.ALLOW_MULTI_TRADE, Setting.ALLOW_USER_PURCHASING, Setting.TRADESHOP_EXPLODE, - Setting.TRADESHOP_HOPPER_EXPORT, - Setting.TRADESHOP_HOPPER_IMPORT, Setting.ITRADESHOP_EXPLODE, - Setting.BITRADESHOP_EXPLODE, - Setting.BITRADESHOP_HOPPER_EXPORT, - Setting.BITRADESHOP_HOPPER_IMPORT); + Setting.BITRADESHOP_EXPLODE); for (Setting setting : booleanSettingList) { if (setting.getBoolean()) { @@ -179,7 +175,7 @@ public Map call() throws Exception { } private void addSettingStringListMetrics() { - List settingList = Arrays.asList(Setting.ALLOWED_DIRECTIONS, + List settingList = Arrays.asList(Setting.CHEST_DIRECTIONS, Setting.ALLOWED_SHOPS); for (Setting setting : settingList) { @@ -221,21 +217,17 @@ private void addOtherSettingMetrics() { // Temporary solutions while Bar graphs are unavailable private void addFeaturePieMetrics() { - List booleanSettingList = Arrays.asList(Setting.CHECK_UPDATES, + List booleanSettingList = Arrays.asList( + Setting.CHECK_UPDATES, Setting.UNLIMITED_ADMIN, - Setting.USE_INTERNAL_PERMISSIONS, Setting.ALLOW_TOGGLE_STATUS, Setting.ALLOW_SIGN_BREAK, Setting.ALLOW_CHEST_BREAK, Setting.ALLOW_MULTI_TRADE, Setting.ALLOW_USER_PURCHASING, Setting.TRADESHOP_EXPLODE, - Setting.TRADESHOP_HOPPER_EXPORT, - Setting.TRADESHOP_HOPPER_IMPORT, Setting.ITRADESHOP_EXPLODE, - Setting.BITRADESHOP_EXPLODE, - Setting.BITRADESHOP_HOPPER_EXPORT, - Setting.BITRADESHOP_HOPPER_IMPORT); + Setting.BITRADESHOP_EXPLODE); for (Setting setting : booleanSettingList) { metrics.addCustomChart(new SimplePie(setting.name().toLowerCase(), () -> { @@ -245,7 +237,7 @@ private void addFeaturePieMetrics() { } private void addSettingStringListAdvancedPieMetrics() { - List settingList = Arrays.asList(Setting.ALLOWED_DIRECTIONS, + List settingList = Arrays.asList(Setting.CHEST_DIRECTIONS, Setting.ALLOWED_SHOPS); for (Setting setting : settingList) { diff --git a/src/main/java/org/shanerx/tradeshop/utils/Tuple.java b/src/main/java/org/shanerx/tradeshop/utils/Tuple.java deleted file mode 100644 index 0aad5610..00000000 --- a/src/main/java/org/shanerx/tradeshop/utils/Tuple.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - */ - -package org.shanerx.tradeshop.utils; - -import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; - -import java.io.Serializable; - -public class Tuple implements Serializable { - - @SerializedName("right") - private R r; - @SerializedName("left") - private L l; - - public Tuple() { - } - - public Tuple(L l, R r) { - this.r = r; - this.l = l; - } - - public Tuple(Tuple t) { - this.r = t.r; - this.l = t.l; - } - - public R getRight() { - return r; - } - - public L getLeft() { - return l; - } - - public String serialize() { - return new Gson().toJson(this); - } - - @Override - public String toString() { - return serialize(); - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/Utils.java b/src/main/java/org/shanerx/tradeshop/utils/Utils.java index 01d293d3..d430b532 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/Utils.java +++ b/src/main/java/org/shanerx/tradeshop/utils/Utils.java @@ -31,34 +31,33 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import org.bukkit.plugin.PluginDescriptionFile; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.ExchangeStatus; -import org.shanerx.tradeshop.enumys.ShopType; -import org.shanerx.tradeshop.objects.Debug; -import org.shanerx.tradeshop.objects.IllegalItemList; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChest; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.objects.ShopLocation; -import org.shanerx.tradeshop.utils.config.Message; -import org.shanerx.tradeshop.utils.config.Setting; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; +import org.shanerx.tradeshop.data.config.Message; +import org.shanerx.tradeshop.data.config.Setting; +import org.shanerx.tradeshop.framework.events.PlayerShopCreateEvent; +import org.shanerx.tradeshop.item.ShopItemSide; +import org.shanerx.tradeshop.item.ShopItemStack; +import org.shanerx.tradeshop.player.ShopRole; +import org.shanerx.tradeshop.player.ShopUser; +import org.shanerx.tradeshop.shop.ExchangeStatus; +import org.shanerx.tradeshop.shop.Shop; +import org.shanerx.tradeshop.shop.ShopChest; +import org.shanerx.tradeshop.shop.ShopType; +import org.shanerx.tradeshop.shoplocation.ShopLocation; +import org.shanerx.tradeshop.utils.debug.DebugLevels; +import org.shanerx.tradeshop.utils.objects.Tuple; +import org.shanerx.tradeshop.utils.relativedirection.LocationOffset; +import org.shanerx.tradeshop.utils.relativedirection.RelativeDirection; + +import java.util.*; /** @@ -73,10 +72,7 @@ public class Utils { public final TradeShop PLUGIN = Objects.requireNonNull((TradeShop) Bukkit.getPluginManager().getPlugin("TradeShop")); protected PluginDescriptionFile pdf = PLUGIN.getDescription(); - public Debug debugger; - public Utils() { - debugger = PLUGIN.getDebugger(); } public UUID[] getMakers() { @@ -214,37 +210,15 @@ public void failedSignReset(SignChangeEvent e, ShopType shop) { e.setLine(3, ""); } - /** - * Sets the event sign to a failed creation sign - * - * @param e event where shop creation failed - * @param shop Shoptype enum to get header - * @param msg The enum constant representing the error message - */ - public void failedSign(SignChangeEvent e, ShopType shop, Message msg) { - failedSignReset(e, shop); - e.getPlayer().sendMessage(colorize(Setting.MESSAGE_PREFIX.getString() + msg)); - } - - /** - * Sets the event sign to a failed creation sign - * - * @param e Event to reset the sign for - * @param msg The enum constant representing the error message - */ - public void failedTrade(PlayerInteractEvent e, Message msg) { - e.getPlayer().sendMessage(colorize(Setting.MESSAGE_PREFIX.getString() + msg)); - } - /** * Checks whether or not it is an illegal material. * - * @param type What side of the trade the item is on + * @param side What side of the trade the item is on * @param mat String to check * @return returns true if valid material */ - public boolean isIllegal(IllegalItemList.TradeItemType type, Material mat) { - return PLUGIN.getListManager().isIllegal(type, mat); + public boolean isIllegal(ShopItemSide side, Material mat) { + return PLUGIN.getListManager().isIllegal(side, mat); } /** @@ -288,29 +262,51 @@ public String colorize(String msg) { * @return the sign. */ public Sign findShopSign(Block chest) { + //region Linked Sign Check - Load and Check Chest Linkage first, if it is a shop then return Linked Shop ShopLocation potentialLocation = PLUGIN.getDataStorage().getChestLinkage(new ShopLocation(chest.getLocation())); if (potentialLocation != null && ShopType.isShop(potentialLocation.getLocation().getBlock())) return (Sign) potentialLocation.getLocation().getBlock().getState(); + //endregion - ArrayList faces = PLUGIN.getListManager().getDirections(), - flatFaces = new ArrayList<>(Arrays.asList(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST)); + // Directions to check for Sign(Reversed later as the list is built to check from Sign->Chest and this method checks from Chest->Sign) + ArrayList directions = PLUGIN.getListManager().getDirections(); + // Directions to check for other half of a DoubleChest + ArrayList flatFaces = new ArrayList<>(Arrays.asList(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST)); - for (BlockFace face : faces) { - face = face.getOppositeFace(); // Check in the opposite direction that a sign would check - Block relative = chest.getRelative(face); + Block otherHalf = null; + + for (RelativeDirection direction : directions) { + // Translate Relative Direction and get the Block + LocationOffset relativeOffset = direction.getTranslatedDirection(RelativeDirection.getDirection(chest.getBlockData()).getOppositeFace()); + Block relative = chest.getRelative(relativeOffset.getXOffset(), relativeOffset.getYOffset(), relativeOffset.getZOffset()); + + // Check if it is a shop and return. Add the chest and shop to ChestLinkage, If it is a DoubleChest also add the other half if (ShopType.isShop(relative)) { + PLUGIN.getDataStorage().addChestLinkage(new ShopLocation(chest.getLocation()), new ShopLocation(relative.getLocation())); if (ShopChest.isDoubleChest(chest)) { PLUGIN.getDataStorage().addChestLinkage(new ShopLocation(ShopChest.getOtherHalfOfDoubleChest(chest).getLocation()), new ShopLocation(relative.getLocation())); } return (Sign) relative.getState(); - } else if (flatFaces.contains(face) && (chest.getType().equals(Material.CHEST) || chest.getType().equals(Material.TRAPPED_CHEST))) { + // If the relative block wasn't the ShopSign and we are checking a FlatFace, Then check if it is the other half of this Chest + } else if (flatFaces.stream().anyMatch((face) -> relativeOffset.getXOffset() == face.getModX() || + relativeOffset.getYOffset() == face.getModY() || + relativeOffset.getZOffset() == face.getModZ()) && (chest.getType().equals(Material.CHEST) || chest.getType().equals(Material.TRAPPED_CHEST))) { if (relative.getType().equals(chest.getType()) && ShopChest.isDoubleChest(chest)) { - for (BlockFace face2 : faces) { - Block relative2 = chest.getRelative(face).getRelative(face2.getOppositeFace()); - if (ShopType.isShop(relative2)) { - PLUGIN.getDataStorage().addChestLinkage(new ShopLocation(chest.getLocation()), new ShopLocation(relative2.getLocation())); - return (Sign) relative2.getState(); - } + // Set Aside for later, We want to check the relative directions on one chest at a time + otherHalf = relative; + } + } + } + + // Check the relative Directions for the other half of the chest + if (otherHalf != null) { + for (RelativeDirection direction2 : directions) { + LocationOffset relativeOffset2 = direction2.getTranslatedDirection(RelativeDirection.getDirection(otherHalf.getBlockData()).getOppositeFace()); + Block relative2 = chest.getRelative(relativeOffset2.getXOffset(), relativeOffset2.getYOffset(), relativeOffset2.getZOffset()); + if (ShopType.isShop(relative2)) { + if (ShopType.isShop(relative2)) { + PLUGIN.getDataStorage().addChestLinkage(new ShopLocation(chest.getLocation()), new ShopLocation(relative2.getLocation())); + return (Sign) relative2.getState(); } } } @@ -326,13 +322,19 @@ public Sign findShopSign(Block chest) { * @return the shop's inventory holder block. */ public Block findShopChest(Block sign) { - for (BlockFace face : PLUGIN.getListManager().getDirections()) { - Block relative = sign.getRelative(face); - if (PLUGIN.getListManager().isInventory(relative)) { - return relative; + // For each Relative Direction listed in the config in order + for (RelativeDirection direction : PLUGIN.getListManager().getDirections()) { + // Get the direction the block we want to check is Facing + BlockFace facing = RelativeDirection.getDirection(sign.getBlockData()); + // Translate the Relative Direction from the Direction the Block is Facing and get the Block on that BlockFace + LocationOffset relativeOffset = direction.getTranslatedDirection(facing); + Block relativeBlock = sign.getRelative(relativeOffset.getXOffset(), relativeOffset.getYOffset(), relativeOffset.getZOffset()); + + // Check if relativeBlock is an inventory block and return if true + if (PLUGIN.getListManager().isInventory(relativeBlock)) { + return relativeBlock; } } - return null; } @@ -389,97 +391,63 @@ public Tuple> canExchangeAll(Shop shop, Inventor Inventory shopInventory = null; - if (shop.getShopType() != ShopType.ITRADE) { + if (shop.getShopType().equals(ShopType.ITRADE)) { + shopInventory = Bukkit.createInventory(null, Math.min((int) (Math.ceil(shop.getSideList(ShopItemSide.PRODUCT).size() / 9.0) * 9) * multiplier, 54)); + while (shopInventory.firstEmpty() != -1) { + for (ItemStack item : shop.getSideItemStacks(ShopItemSide.PRODUCT)) { + item.setAmount(item.getMaxStackSize()); + shopInventory.addItem(item); + } + } + } else { Inventory shopInv = shop.getChestAsSC().getInventory(); shopInventory = Bukkit.createInventory(null, shopInv.getStorageContents().length); shopInventory.setContents(shopInv.getStorageContents().clone()); } - List costItems, productItems; - - if (shop.getShopType() == ShopType.ITRADE) { //ITrade trade - - //Method to find Cost items in player inventory and add to cost array - costItems = getItems(playerInventory.getStorageContents(), shop.getCost(), multiplier); - - if (!costItems.isEmpty()) { - if (costItems.get(0) == null) { - return new Tuple<>(ExchangeStatus.PLAYER_NO_COST, costItems); - } + List costItems = new ArrayList<>(), productItems; - for (ItemStack item : costItems) { - playerInventory.removeItem(item); - } - } + boolean isBi = shop.getShopType().equals(ShopType.BITRADE) && action.equals(Action.LEFT_CLICK_BLOCK); - Inventory iTradeVirtualInventory = Bukkit.createInventory(null, Math.min((int) (Math.ceil(shop.getProduct().size() / 9.0) * 9) * multiplier, 54)); - while (iTradeVirtualInventory.firstEmpty() != -1) { - for (ItemStack item : shop.getProductItemStacks()) { - item.setAmount(item.getMaxStackSize()); - iTradeVirtualInventory.addItem(item); - } + //Method to find Cost items in player inventory and add to cost array + if (!shop.isNoCost() || shop.hasSide(ShopItemSide.COST)) { + costItems = getItems(playerInventory.getStorageContents(), shop.getSideList(ShopItemSide.COST, isBi), multiplier); + if (costItems.get(0) == null) { + return new Tuple<>(ExchangeStatus.PLAYER_NO_COST, costItems); } + } - productItems = getItems(iTradeVirtualInventory.getStorageContents(), shop.getProduct(), multiplier); + //Method to find Product items in shop inventory and add to product array + productItems = getItems(shopInventory.getStorageContents(), shop.getSideList(ShopItemSide.PRODUCT, isBi), multiplier); + if (productItems.get(0) == null) { + shop.updateStatus(); + return new Tuple<>(ExchangeStatus.SHOP_NO_PRODUCT, productItems); + } - for (ItemStack item : productItems) { - if (!playerInventory.addItem(item).isEmpty()) { - return new Tuple<>(ExchangeStatus.PLAYER_NO_SPACE, createBadList()); - } + if (costItems.size() > 0) { + //For loop to remove cost items from player inventory + for (ItemStack item : costItems) { + playerInventory.removeItem(item); } + } - return new Tuple<>(ExchangeStatus.SUCCESS, createBadList()); //Successfully completed trade - } else if (shop.getShopType() == ShopType.BITRADE && action == Action.LEFT_CLICK_BLOCK) { //BiTrade Reversed Trade + //For loop to remove product items from shop inventory + for (ItemStack item : productItems) { + shopInventory.removeItem(item); + } - //Method to find Cost items in player inventory and add to cost array - costItems = getItems(playerInventory.getStorageContents(), shop.getProduct(), multiplier); //Reverse BiTrade, Product is Cost - if (costItems.get(0) == null) { - return new Tuple<>(ExchangeStatus.PLAYER_NO_COST, costItems); - } - - //Method to find Product items in shop inventory and add to product array - productItems = getItems(shopInventory.getStorageContents(), shop.getCost(), multiplier); //Reverse BiTrade, Cost is Product - if (productItems.get(0) == null) { - shop.updateStatus(); - return new Tuple<>(ExchangeStatus.SHOP_NO_PRODUCT, productItems); - } - } else { // Normal Trade - - //Method to find Cost items in player inventory and add to cost array - costItems = getItems(playerInventory.getStorageContents(), shop.getCost(), multiplier); - if (costItems.get(0) == null) { - return new Tuple<>(ExchangeStatus.PLAYER_NO_COST, costItems); - } - - //Method to find Product items in shop inventory and add to product array - productItems = getItems(shopInventory.getStorageContents(), shop.getProduct(), multiplier); - if (productItems.get(0) == null) { - shop.updateStatus(); - return new Tuple<>(ExchangeStatus.SHOP_NO_PRODUCT, productItems); - } - - } - - //For loop to remove cost items from player inventory - for (ItemStack item : costItems) { - playerInventory.removeItem(item); - } - - //For loop to remove product items from shop inventory - for (ItemStack item : productItems) { - shopInventory.removeItem(item); - } - - //For loop to put cost items in shop inventory - for (ItemStack item : costItems) { - if (!shopInventory.addItem(item).isEmpty()) { - return new Tuple<>(ExchangeStatus.SHOP_NO_SPACE, createBadList()); + if (!shop.getShopType().isITrade() && costItems.size() > 0) { + //For loop to put cost items in shop inventory + for (ItemStack item : costItems) { + if (!addItemToInventory(shopInventory, item).isEmpty()) { + return new Tuple<>(ExchangeStatus.SHOP_NO_SPACE, createBadList()); + } } } //For loop to put product items in player inventory for (ItemStack item : productItems) { - if (!playerInventory.addItem(item).isEmpty()) { + if (!addItemToInventory(playerInventory, item).isEmpty()) { return new Tuple<>(ExchangeStatus.PLAYER_NO_SPACE, createBadList()); } } @@ -487,6 +455,132 @@ public Tuple> canExchangeAll(Shop shop, Inventor return new Tuple<>(ExchangeStatus.SUCCESS, createBadList()); //Successfully completed trade } + /** + * Create a shop from a non-shop sign in front of the player + * + * @param shopSign sign to make into a shop + * @param creator player that is creating the shop + * @param shopType type of shop to make + * @param cost initial cost item for shop + * @param product initial product item for shop + * @param event SignUpdateEvent if being called from sign creation + * @return returns the shop object that was created + */ + public Shop createShop(Sign shopSign, Player creator, ShopType shopType, ItemStack cost, ItemStack product, SignChangeEvent event) { + if (ShopType.isShop(shopSign)) { + Message.EXISTING_SHOP.sendMessage(creator); + return null; + } + + if (!shopType.checkPerm(creator)) { + Message.NO_TS_CREATE_PERMISSION.sendMessage(creator); + return null; + } + + ShopUser owner = new ShopUser(creator, ShopRole.OWNER); + + if (!checkShopChest(shopSign.getBlock()) && !shopType.isITrade()) { + Message.NO_CHEST.sendMessage(creator); + return null; + } + + if (Setting.MAX_SHOPS_PER_CHUNK.getInt() <= PLUGIN.getDataStorage().getShopCountInChunk(shopSign.getChunk())) { + Message.TOO_MANY_CHESTS.sendMessage(creator); + return null; + } + + ShopChest shopChest; + Shop shop; + Block chest = findShopChest(shopSign.getBlock()); + + if (!shopType.isITrade()) { + if (ShopChest.isShopChest(chest)) { + shopChest = new ShopChest(chest.getLocation()); + } else { + shopChest = new ShopChest(chest, creator.getUniqueId(), shopSign.getLocation()); + } + + if (shopChest.hasOwner() && !shopChest.getOwner().equals(owner.getUUID())) { + Message.NO_SHOP_PERMISSION.sendMessage(creator); + return null; + } + + if (shopChest.hasShopSign() && !shopChest.getShopSign().getLocation().equals(shopSign.getLocation())) { + Message.EXISTING_SHOP.sendMessage(creator); + return null; + } + + shop = new Shop(new Tuple<>(shopSign.getLocation(), shopChest.getChest().getLocation()), shopType, owner); + shopChest.setName(); + + if (cost != null && !shop.hasSide(ShopItemSide.COST)) + shop.setSideItems(ShopItemSide.COST, cost); + + if (product != null && !shop.hasSide(ShopItemSide.PRODUCT)) + shop.setSideItems(ShopItemSide.PRODUCT, product); + + if (shopChest.isEmpty() && shop.hasSide(ShopItemSide.PRODUCT)) { + Message.EMPTY_TS_ON_SETUP.sendMessage(creator); + } + } else { + shop = new Shop(shopSign.getLocation(), shopType, owner); + } + + PLUGIN.getDebugger().log("-----Pre-Event-----", DebugLevels.SHOP_CREATION); + PLUGIN.getDebugger().log(shop.toDebug(), DebugLevels.SHOP_CREATION); + + + PlayerShopCreateEvent shopCreateEvent = new PlayerShopCreateEvent(creator, shop); + Bukkit.getPluginManager().callEvent(shopCreateEvent); + PLUGIN.getDebugger().log("-----Post-Event-----", DebugLevels.SHOP_CREATION); + PLUGIN.getDebugger().log(shop.toDebug(), DebugLevels.SHOP_CREATION); + + if (shopCreateEvent.isCancelled()) { + PLUGIN.getDebugger().log("Creation Failed!", DebugLevels.SHOP_CREATION); + return null; + } + + shop.saveShop(); + + if (event != null) { + shop.updateSign(event); + PLUGIN.getDebugger().log("Event Sign Lines: \n" + event.getLine(0) + "\n" + event.getLine(1) + "\n" + event.getLine(2) + "\n" + event.getLine(3), DebugLevels.SHOP_CREATION); + } else { + shop.updateSign(shopSign); + PLUGIN.getDebugger().log("Sign Lines: \n" + shopSign.getLine(0) + "\n" + shopSign.getLine(1) + "\n" + shopSign.getLine(2) + "\n" + shopSign.getLine(3), DebugLevels.SHOP_CREATION); + } + + Message.SUCCESSFUL_SETUP.sendMessage(creator); + PLUGIN.getDebugger().log("Creation Successful!", DebugLevels.SHOP_CREATION); + return shop; + } + + /** + * Create a shop from a non-shop sign in front of the player + * + * @param shopSign sign to make into a shop + * @param creator player that is creating the shop + * @param shopType type of shop to make + * @return returns the shop object that was created + */ + public Shop createShop(Sign shopSign, Player creator, ShopType shopType) { + return createShop(shopSign, creator, shopType, null, null, null); + } + + /** + * Create a shop from a non-shop sign in front of the player + * + * @param shopSign sign to make into a shop + * @param creator player that is creating the shop + * @param shopType type of shop to make + * @param cost initial cost item for shop + * @param product initial product item for shop + * @return returns the shop object that was created + */ + public Shop createShop(Sign shopSign, Player creator, ShopType shopType, ItemStack cost, ItemStack product) { + return createShop(shopSign, creator, shopType, cost, product, null); + } + /** * Returns an arraylist of the ItemStack Objects to be removed/added, if it could not get enough of any items, it will return index 0 as null, followed by ItemStack Objects that could not be retrieved * @@ -499,7 +593,7 @@ public List getItems(ItemStack[] storageContents, List Map storage = new HashMap<>(), found = new HashMap<>(); List good = new ArrayList(), bad = createBadList(); - debugger.log("Utils > getItems > Search List: " + search, DebugLevels.TRADE); + PLUGIN.getDebugger().log("Utils > getItems > Search List: " + search, DebugLevels.TRADE); for (ItemStack itemStack : storageContents.clone()) { if (itemStack != null) { @@ -512,7 +606,7 @@ public List getItems(ItemStack[] storageContents, List } } - debugger.log("Utils > getItems > Storage List: " + storage, DebugLevels.TRADE); + PLUGIN.getDebugger().log("Utils > getItems > Storage List: " + storage, DebugLevels.TRADE); int totalCount = 0, currentCount = 0; @@ -521,9 +615,9 @@ public List getItems(ItemStack[] storageContents, List totalCount += count; for (ItemStack storageItem : storage.keySet()) { - boolean isSimilar = item.isSimilar(storageItem); - if (isSimilar) { - int taken = Math.min(storage.get(storageItem), count); + if (item.isSimilar(storageItem)) { + int taken; + taken = megaMin(storage.get(storageItem), count); if (found.putIfAbsent(item.getItemStack(), taken) != null) found.put(item.getItemStack(), storage.get(storageItem) + taken); @@ -548,10 +642,59 @@ public List getItems(ItemStack[] storageContents, List } } - debugger.log("Utils > getItems > Good List: " + good, DebugLevels.TRADE); - debugger.log("Utils > getItems > Bad List: " + bad, DebugLevels.TRADE); - debugger.log("Utils > getItems > Return Status: " + (currentCount != totalCount ? "bad" : "good"), DebugLevels.TRADE); + PLUGIN.getDebugger().log("Utils > getItems > Good List: " + good, DebugLevels.TRADE); + PLUGIN.getDebugger().log("Utils > getItems > Bad List: " + bad, DebugLevels.TRADE); + PLUGIN.getDebugger().log("Utils > getItems > Return Status: " + (currentCount != totalCount ? "bad" : "good"), DebugLevels.TRADE); return currentCount != totalCount ? bad : good; } + + /** + * Attempts to add an ItemStack to an Inventory while splitting it with its max stack size as a maximum + * + * @param inv Inventory to attempt to add the ItemStack to + * @param item ItemStack to be added to the ivnentory + * @return smallest integer + */ + public Map addItemToInventory(Inventory inv, ItemStack item) { + int maxStack = inv.getMaxStackSize(); + inv.setMaxStackSize(item.getMaxStackSize()); + Map result = inv.addItem(item); + inv.setMaxStackSize(maxStack); + return result; + } + + /** + * Returns the smallest integer passed to it + * + * @param values list of integers to compare against each other + * @return smallest integer + */ + public int megaMin(int... values) { + int min = values[0]; + for (int i : values) { + min = Math.min(i, min); + } + + return min; + } + + /** + * Converts string to boolean based on acceptable responses + * + * @param check String to convert to boolean + * @return true if acceptable string was found + */ + public boolean toBool(String check) { + switch (check.toLowerCase()) { + case "true": + case "t": + case "yes": + case "y": + case "all": + return true; + default: + return false; + } + } } \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java b/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java deleted file mode 100644 index 2bcc19a2..00000000 --- a/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.utils.data; - -import org.bukkit.Chunk; -import org.bukkit.World; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.objects.PlayerSetting; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChunk; -import org.shanerx.tradeshop.objects.ShopLocation; -import org.shanerx.tradeshop.utils.Utils; -import org.shanerx.tradeshop.utils.data.Json.LinkageConfiguration; -import org.shanerx.tradeshop.utils.data.Json.PlayerConfiguration; -import org.shanerx.tradeshop.utils.data.Json.ShopConfiguration; - -import java.io.File; -import java.util.UUID; - -public class DataStorage extends Utils { - - private transient DataType dataType; - - public DataStorage(DataType dataType) { - reload(dataType); - } - - public void reload(DataType dataType) { - this.dataType = dataType; - debugger.log("Data storage set to: " + dataType.name(), DebugLevels.DISABLED); - } - - public Shop loadShopFromSign(ShopLocation sign) { - switch (dataType) { - case FLATFILE: - return new ShopConfiguration(new ShopChunk(sign.getChunk())).load(sign); - case SQLITE: - return null; //TODO add SQLITE support - } - return null; - } - - public Shop loadShopFromStorage(ShopLocation chest) { - switch (dataType) { - case FLATFILE: - return loadShopFromSign(new LinkageConfiguration(chest.getWorld()).getLinkedShop(chest)); - case SQLITE: - return null; //TODO add SQLITE support - } - return null; - } - - public void saveShop(Shop shop) { - switch (dataType) { - case FLATFILE: - new ShopConfiguration(new ShopChunk(shop.getShopLocation().getChunk())).save(shop); - break; - case SQLITE: - //TODO add SQLITE support - break; - } - } - - public void removeShop(Shop shop) { - switch (dataType) { - case FLATFILE: - new ShopConfiguration(new ShopChunk(shop.getShopLocation().getChunk())).remove(shop.getShopLocationAsSL()); - new LinkageConfiguration(shop.getShopLocationAsSL().getWorld()).removeShop(shop.getShopLocationAsSL()); - break; - case SQLITE: - //TODO add SQLITE support - break; - } - } - - public int getShopCountInChunk(Chunk chunk) { - switch (dataType) { - case FLATFILE: - return new ShopConfiguration(new ShopChunk(chunk)).size(); - case SQLITE: - return 0; //TODO add SQLITE support - } - return 0; - } - - public int getShopCountInWorld(World world) { - int count = 0; - switch (dataType) { - case FLATFILE: - File folder = new File(PLUGIN.getDataFolder().getAbsolutePath() + File.separator + "Data" + File.separator + world.getName()); - if (folder.exists() && folder.listFiles() != null) { - for (File file : folder.listFiles()) { - if (file.getName().contains(world.getName())) - count += new ShopConfiguration(ShopChunk.deserialize(file.getName().replace(".json", ""))).size(); - } - } - break; - case SQLITE: - //TODO add SQLITE support - break; - } - return count; - } - - public PlayerSetting loadPlayer(UUID uuid) { - PlayerSetting playerSetting = null; - switch (dataType) { - case FLATFILE: - playerSetting = new PlayerConfiguration(uuid).load(); - break; - case SQLITE: - //TODO add SQLITE support - break; - } - - //If playerSetting data not find create new and return - return playerSetting != null ? playerSetting : new PlayerSetting(uuid); - } - - public void savePlayer(PlayerSetting playerSetting) { - switch (dataType) { - case FLATFILE: - new PlayerConfiguration(playerSetting.getUuid()).save(playerSetting); - break; - case SQLITE: - //TODO add SQLITE support - break; - } - } - - public void removePlayer(PlayerSetting playerSetting) { - switch (dataType) { - case FLATFILE: - new PlayerConfiguration(playerSetting.getUuid()).remove(); - break; - case SQLITE: - //TODO add SQLITE support - break; - } - } - - public ShopLocation getChestLinkage(ShopLocation chestLocation) { - switch (dataType) { - case FLATFILE: - return new LinkageConfiguration(chestLocation.getWorld()).getLinkedShop(chestLocation); - case SQLITE: - //TODO add SQLITE support - break; - } - - return null; - } - - public void addChestLinkage(ShopLocation chestLocation, ShopLocation shopLocation) { - switch (dataType) { - case FLATFILE: - new LinkageConfiguration(chestLocation.getWorld()).add(chestLocation, shopLocation); - case SQLITE: - //TODO add SQLITE support - break; - } - } - - public void removeChestLinkage(ShopLocation chestLocation) { - switch (dataType) { - case FLATFILE: - new LinkageConfiguration(chestLocation.getWorld()).removeChest(chestLocation); - case SQLITE: - //TODO add SQLITE support - break; - } - } -} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/Json/LinkageConfiguration.java b/src/main/java/org/shanerx/tradeshop/utils/data/Json/LinkageConfiguration.java deleted file mode 100644 index 02141872..00000000 --- a/src/main/java/org/shanerx/tradeshop/utils/data/Json/LinkageConfiguration.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.utils.data.Json; - -import com.google.gson.reflect.TypeToken; -import org.bukkit.World; -import org.shanerx.tradeshop.objects.ShopChest; -import org.shanerx.tradeshop.objects.ShopLocation; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class LinkageConfiguration extends JsonConfiguration { - - Map linkageData; - - public LinkageConfiguration(World world) { - super(world.getName(), "chest_linkage"); - load(); - } - - public void load() { - linkageData = gson.fromJson(jsonObj.get("linkage_data"), new TypeToken>() { - }.getType()); - if (linkageData == null) - linkageData = new HashMap<>(); - } - - public Map getLinkageData() { - return linkageData; - } - - public ShopLocation getLinkedShop(ShopLocation chestLocation) { - String loc = chestLocation.serialize(); - - return linkageData.containsKey(loc) ? ShopLocation.deserialize(linkageData.get(chestLocation.serialize())) : null; - } - - public void save() { - jsonObj.add("linkage_data", gson.toJsonTree(linkageData)); - - saveFile(); - } - - public int size() { - return linkageData.size(); - } - - public void add(ShopLocation chestLocation, ShopLocation shopLocation) { - if (ShopChest.isDoubleChest(chestLocation.getLocation().getBlock())) { - ShopLocation otherSideLocation = new ShopLocation(ShopChest.getOtherHalfOfDoubleChest(chestLocation.getLocation().getBlock()).getLocation()); - addLinkage(otherSideLocation, shopLocation); - } - - addLinkage(chestLocation, shopLocation); - save(); - } - - public void removeChest(ShopLocation chestLocation) { - linkageData.remove(chestLocation); - save(); - } - - public void removeShop(ShopLocation shopLocation) { - List removeChests = new ArrayList<>(); - String shopLoc = shopLocation.serialize(); - - linkageData.forEach((key, value) -> { - if (value.equals(shopLoc)) - removeChests.add(key); - }); - - removeChests.forEach((k) -> linkageData.remove(k)); - } - - private void addLinkage(ShopLocation chestLocation, ShopLocation shopLocation) { - if (linkageData.containsKey(chestLocation.serialize())) - linkageData.replace(chestLocation.serialize(), shopLocation.serialize()); - else - linkageData.put(chestLocation.serialize(), shopLocation.serialize()); - } - -} diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/Json/ShopConfiguration.java b/src/main/java/org/shanerx/tradeshop/utils/data/Json/ShopConfiguration.java deleted file mode 100644 index c10e24c0..00000000 --- a/src/main/java/org/shanerx/tradeshop/utils/data/Json/ShopConfiguration.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * - * Copyright (c) 2016-2019 - * SparklingComet @ http://shanerx.org - * KillerOfPie @ http://killerofpie.github.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * NOTICE: All modifications made by others to the source code belong - * to the respective contributor. No contributor should be held liable for - * any damages of any kind, whether be material or moral, which were - * caused by their contribution(s) to the project. See the full License for more information. - * - */ - -package org.shanerx.tradeshop.utils.data.Json; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.google.gson.JsonElement; -import org.bukkit.inventory.ItemStack; -import org.shanerx.tradeshop.objects.Shop; -import org.shanerx.tradeshop.objects.ShopChunk; -import org.shanerx.tradeshop.objects.ShopItemStack; -import org.shanerx.tradeshop.objects.ShopLocation; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class ShopConfiguration extends JsonConfiguration { - - private final ShopChunk chunk; - - public ShopConfiguration(ShopChunk chunk) { - super(chunk.getWorld().getName(), chunk.serialize()); - this.chunk = chunk; - } - - @Override - public void loadFile() { - if (!this.file.exists()) { - // If could not find file try with old separators - String oldFile = path + File.separator + chunk.serialize().replace(";;", "_") + ".json"; - if (new File(oldFile).exists()) - new File(oldFile).renameTo(file); - } - - super.loadFile(); - - for (Map.Entry entry : Sets.newHashSet(jsonObj.entrySet())) { - if (entry.getKey().contains("l_")) { - jsonObj.add(ShopLocation.deserialize(entry.getKey()).serialize(), entry.getValue()); - jsonObj.remove(entry.getKey()); - } - } - } - - public void save(Shop shop) { - jsonObj.add(shop.getShopLocationAsSL().serialize(), gson.toJsonTree(shop)); - - saveFile(); - } - - public void remove(ShopLocation loc) { - if (jsonObj.has(loc.serialize())) - jsonObj.remove(loc.serialize()); - - saveFile(); - } - - public Shop load(ShopLocation loc) { - Shop shop; - - if (jsonObj.has(loc.serialize())) { - if (jsonObj.getAsJsonObject(loc.serialize()).getAsJsonPrimitive("productB64") != null) { - String str = jsonObj.getAsJsonObject(loc.serialize()).get("productB64").getAsString(); - jsonObj.getAsJsonObject(loc.serialize()).remove("productB64"); - jsonObj.getAsJsonObject(loc.serialize()).add("product", gson.toJsonTree(b64OverstackFixer(str))); - saveFile(); - } - - if (jsonObj.getAsJsonObject(loc.serialize()).getAsJsonPrimitive("costB64") != null) { - String str = jsonObj.getAsJsonObject(loc.serialize()).get("costB64").getAsString(); - jsonObj.getAsJsonObject(loc.serialize()).remove("costB64"); - jsonObj.getAsJsonObject(loc.serialize()).add("cost", gson.toJsonTree(b64OverstackFixer(str))); - saveFile(); - } - - if (jsonObj.getAsJsonObject(loc.serialize()).has("productListB64")) { - List productList = new ArrayList<>(); - gson.fromJson(jsonObj.getAsJsonObject(loc.serialize()).get("productListB64"), List.class).forEach(item -> productList.add(new ShopItemStack(item.toString()))); - jsonObj.getAsJsonObject(loc.serialize()).remove("productListB64"); - jsonObj.getAsJsonObject(loc.serialize()).add("product", gson.toJsonTree(productList)); - } - - if (jsonObj.getAsJsonObject(loc.serialize()).has("costListB64")) { - List costList = new ArrayList<>(); - gson.fromJson(jsonObj.getAsJsonObject(loc.serialize()).get("costListB64"), List.class).forEach(item -> costList.add(new ShopItemStack(item.toString()))); - jsonObj.getAsJsonObject(loc.serialize()).remove("costListB64"); - jsonObj.getAsJsonObject(loc.serialize()).add("cost", gson.toJsonTree(costList)); - } - - - shop = gson.fromJson(jsonObj.get(loc.serialize()), Shop.class); - } else { - return null; - } - - shop.fixAfterLoad(); - return shop; - } - - public int size() { - return jsonObj.size(); - } - - private List b64OverstackFixer(String oldB64) { - ShopItemStack oldStack = new ShopItemStack(oldB64); - - if (oldStack.hasBase64()) - return null; - - if (!(oldStack.getItemStack().getAmount() > oldStack.getItemStack().getMaxStackSize())) { - return Lists.newArrayList(oldStack); - } else { - List newStacks = new ArrayList<>(); - int amount = oldStack.getItemStack().getAmount(); - - while (amount > 0) { - if (oldStack.getItemStack().getMaxStackSize() < amount) { - ItemStack itm = oldStack.getItemStack().clone(); - itm.setAmount(oldStack.getItemStack().getMaxStackSize()); - newStacks.add(new ShopItemStack(itm)); - amount -= oldStack.getItemStack().getMaxStackSize(); - } else { - ItemStack itm = oldStack.getItemStack().clone(); - itm.setAmount(amount); - newStacks.add(new ShopItemStack(itm)); - amount -= amount; - } - } - - return newStacks; - } - } -} diff --git a/src/main/java/org/shanerx/tradeshop/objects/Debug.java b/src/main/java/org/shanerx/tradeshop/utils/debug/Debug.java similarity index 95% rename from src/main/java/org/shanerx/tradeshop/objects/Debug.java rename to src/main/java/org/shanerx/tradeshop/utils/debug/Debug.java index ff6aa403..6ff76df3 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/Debug.java +++ b/src/main/java/org/shanerx/tradeshop/utils/debug/Debug.java @@ -23,11 +23,10 @@ * */ -package org.shanerx.tradeshop.objects; +package org.shanerx.tradeshop.utils.debug; import org.bukkit.Bukkit; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.utils.config.Setting; +import org.shanerx.tradeshop.data.config.Setting; import java.util.logging.Level; diff --git a/src/main/java/org/shanerx/tradeshop/enumys/DebugLevels.java b/src/main/java/org/shanerx/tradeshop/utils/debug/DebugLevels.java similarity index 94% rename from src/main/java/org/shanerx/tradeshop/enumys/DebugLevels.java rename to src/main/java/org/shanerx/tradeshop/utils/debug/DebugLevels.java index 65167eb3..a4239e06 100644 --- a/src/main/java/org/shanerx/tradeshop/enumys/DebugLevels.java +++ b/src/main/java/org/shanerx/tradeshop/utils/debug/DebugLevels.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.enumys; +package org.shanerx.tradeshop.utils.debug; import java.util.logging.Level; @@ -41,8 +41,9 @@ public enum DebugLevels { NAME_COMPARE(7, Level.WARNING), // 64 SHULKERS_SUCK(8, Level.WARNING), // 128 ENCHANT_CHECKS(9, Level.WARNING), // 256 - OUTPUT(10, Level.WARNING) //512 - ; + OUTPUT(10, Level.WARNING), // 512 + SHOP_CREATION(11, Level.INFO), // 1024 + SQLITE(12, Level.INFO); //position is what value to check for this level in the binary string -1. // diff --git a/src/main/java/org/shanerx/tradeshop/utils/debug/package-info.java b/src/main/java/org/shanerx/tradeshop/utils/debug/package-info.java new file mode 100644 index 00000000..64b839e6 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/debug/package-info.java @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +/** + * The classes in this package are used to simplify and manage debug output for Tradeshop. + */ +package org.shanerx.tradeshop.utils.debug; \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/objects/ObjectHolder.java b/src/main/java/org/shanerx/tradeshop/utils/objects/ObjectHolder.java new file mode 100644 index 00000000..cc695d02 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/objects/ObjectHolder.java @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.utils.objects; + +import com.google.gson.annotations.SerializedName; + +public class ObjectHolder { + + @SerializedName(value = "value", alternate = "obj") + private final Type obj; + + public ObjectHolder(Type obj) { + this.obj = obj; + } + + public Type getObject() { + return obj; + } + + public boolean isBoolean() { + return obj != null && obj instanceof Boolean; + } + + public boolean isInteger() { + return obj != null && obj instanceof Integer; + } + + public boolean isDouble() { + return obj != null && obj instanceof Double; + } + + public boolean isString() { + return obj != null && obj instanceof String; + } + + public Boolean asBoolean() { + return isBoolean() ? Boolean.parseBoolean(obj.toString()) : null; + } + + public Integer asInteger() { + return isInteger() ? Integer.parseInt(obj.toString()) : null; + } + + public Double asDouble() { + return isDouble() ? Double.parseDouble(obj.toString()) : null; + } + + @Override + public String toString() { + return obj.toString(); + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/objects/Tuple.java b/src/main/java/org/shanerx/tradeshop/utils/objects/Tuple.java new file mode 100644 index 00000000..aa5e9686 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/objects/Tuple.java @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.utils.objects; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +public class Tuple { + + @SerializedName("right") + private R r; + @SerializedName("left") + private L l; + + public Tuple() { + } + + public Tuple(L l, R r) { + this.r = r; + this.l = l; + } + + public Tuple(Tuple t) { + this.r = t.r; + this.l = t.l; + } + + public R getRight() { + return r; + } + + public L getLeft() { + return l; + } + + @Override + public String toString() { + return new Gson().toJson(this); + } +} \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/objects/package-info.java b/src/main/java/org/shanerx/tradeshop/utils/objects/package-info.java new file mode 100644 index 00000000..d1e78632 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/objects/package-info.java @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +/** + * The classes in this package are used for generic object holding/combining, + * Feel free to implement them within your project as external dependencies. + */ +package org.shanerx.tradeshop.utils.objects; \ No newline at end of file diff --git a/src/main/java/org/shanerx/tradeshop/utils/relativedirection/LocationOffset.java b/src/main/java/org/shanerx/tradeshop/utils/relativedirection/LocationOffset.java new file mode 100644 index 00000000..68f947f6 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/relativedirection/LocationOffset.java @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.utils.relativedirection; + +public class LocationOffset { + + private final int xOffset, yOffset, zOffset; + private final transient int max = 1, min = -1; + + public LocationOffset(int xOffset, int yOffset, int zOffset) { + this.xOffset = xOffset; + this.yOffset = yOffset; + this.zOffset = zOffset; + } + + public LocationOffset add(LocationOffset toAdd) { + return new LocationOffset(getXOffset() + toAdd.getXOffset(), getYOffset() + toAdd.getYOffset(), getZOffset() + toAdd.getZOffset()).normalize(); + } + + public LocationOffset normalize() { + return new LocationOffset(bringWithinRange(getXOffset()), bringWithinRange(getYOffset()), bringWithinRange(getZOffset())); + } + + private int bringWithinRange(int i) { + return Math.max(Math.min(i, max), min); + } + + public int getZOffset() { + return zOffset; + } + + public int getYOffset() { + return yOffset; + } + + public int getXOffset() { + return xOffset; + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/relativedirection/RelativeDirection.java b/src/main/java/org/shanerx/tradeshop/utils/relativedirection/RelativeDirection.java new file mode 100644 index 00000000..e7d0a914 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/relativedirection/RelativeDirection.java @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.utils.relativedirection; + +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; + +import java.util.ArrayList; +import java.util.List; + +public class RelativeDirection { + + private final List cardinals = new ArrayList<>(); + + public RelativeDirection(RelativeCardinals... cardinals) { + for (RelativeCardinals cardinal : cardinals) { + if (cardinal == null) + cardinal = RelativeCardinals.SELF; + + if (!this.cardinals.contains(cardinal)) { + this.cardinals.add(cardinal); + } + } + } + + public static RelativeDirection valueOf(String str) { + String[] cardinals = str.split("[+]"); + + if (cardinals.length == 0) return new RelativeDirection(RelativeCardinals.SELF); + + RelativeCardinals[] processedCardinals = new RelativeCardinals[cardinals.length]; + + for (int i = 0; i < cardinals.length; i++) { + processedCardinals[i] = RelativeCardinals.valueOf(cardinals[i]); + } + + return new RelativeDirection(processedCardinals); + } + + public static BlockFace getDirection(BlockData blockData) { + if (blockData instanceof Rotatable) return ((Rotatable) blockData).getRotation(); + else if (blockData instanceof Directional) return ((Directional) blockData).getFacing(); + else return BlockFace.SELF; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + for (RelativeCardinals cardinal : cardinals) { + sb.append(cardinal.name()).append("+"); + } + + return sb.substring(0, sb.length() - 1); + } + + public LocationOffset getTranslatedDirection(BlockFace directionFacing) { + LocationOffset sum = new LocationOffset(0, 0, 0); + + for (RelativeCardinals cardinal : cardinals) { + sum = sum.add(cardinal.getTranslation(directionFacing)); + } + + return sum; + } + + public enum RelativeCardinals { + + SELF("0", "0", "0"), + DOWN("0", "-1", "0"), + UP("0", "1", "0"), + RIGHT("z", "0", "-x"), + LEFT("-z", "0", "x"), + BACK("-x", "0", "-z"), + FRONT("x", "0", "z"); + + private final transient String xTranslation; + private final transient String yTranslation; + private final transient String zTranslation; + + RelativeCardinals(String xTranslation, String yTranslation, String zTranslation) { + this.xTranslation = xTranslation; + this.yTranslation = yTranslation; + this.zTranslation = zTranslation; + } + + public LocationOffset getTranslation(BlockFace facing) { + return new LocationOffset(processTranslation(xTranslation, facing), processTranslation(yTranslation, facing), processTranslation(zTranslation, facing)); + } + + private int processTranslation(String translation, BlockFace facing) { + int temp = 0; + + try { + temp = Integer.parseInt(translation); + return temp; + } catch (NumberFormatException ignored) { + } + + if (translation.toLowerCase().contains("x")) + temp = facing.getModX(); + else if (translation.toLowerCase().contains("y")) + temp = facing.getModY(); + else if (translation.toLowerCase().contains("z")) + temp = facing.getModZ(); + + if (translation.contains("-")) + return Math.negateExact(temp); + + return temp; + } + } +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/BukkitVersion.java b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/BukkitVersion.java similarity index 98% rename from src/main/java/org/shanerx/tradeshop/utils/BukkitVersion.java rename to src/main/java/org/shanerx/tradeshop/utils/versionmanagement/BukkitVersion.java index d37d2f28..813f4380 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/BukkitVersion.java +++ b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/BukkitVersion.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils; +package org.shanerx.tradeshop.utils.versionmanagement; import org.bukkit.Bukkit; diff --git a/src/main/java/org/shanerx/tradeshop/utils/Expirer.java b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Expirer.java similarity index 97% rename from src/main/java/org/shanerx/tradeshop/utils/Expirer.java rename to src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Expirer.java index c8bd0203..686c1d13 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/Expirer.java +++ b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Expirer.java @@ -23,14 +23,14 @@ * */ -package org.shanerx.tradeshop.utils; +package org.shanerx.tradeshop.utils.versionmanagement; import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.scheduler.BukkitScheduler; import org.shanerx.tradeshop.TradeShop; -import org.shanerx.tradeshop.enumys.DebugLevels; -import org.shanerx.tradeshop.enumys.Permissions; +import org.shanerx.tradeshop.player.Permissions; +import org.shanerx.tradeshop.utils.debug.DebugLevels; import java.io.InputStreamReader; import java.time.Duration; diff --git a/src/main/java/org/shanerx/tradeshop/utils/Updater.java b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Updater.java similarity index 99% rename from src/main/java/org/shanerx/tradeshop/utils/Updater.java rename to src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Updater.java index d85bd006..9ca0bb21 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/Updater.java +++ b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/Updater.java @@ -23,7 +23,7 @@ * */ -package org.shanerx.tradeshop.utils; +package org.shanerx.tradeshop.utils.versionmanagement; import org.bukkit.Bukkit; import org.bukkit.plugin.PluginDescriptionFile; diff --git a/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/package-info.java b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/package-info.java new file mode 100644 index 00000000..5c013d64 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/versionmanagement/package-info.java @@ -0,0 +1,30 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +/** + * The classes in this package are used for checking/comparing versions of this plugin, as well as bukkit. + * All Classes except for BukkitVersion.java are plugin specific and should not be used outside of Tradeshop. + */ +package org.shanerx.tradeshop.utils.versionmanagement; \ No newline at end of file diff --git a/src/main/resources/Lang/en-us.yml b/src/main/resources/Lang/en-us.yml index f2ba39d0..898e72fc 100644 --- a/src/main/resources/Lang/en-us.yml +++ b/src/main/resources/Lang/en-us.yml @@ -1,307 +1,348 @@ -message-section: - none: - header: "" - unused: - header: "" -setting-section: - none: - header: "" - system-options: - header: "System Options" - language-options: - header: "Language Options" - global-options: - header: "Global Options" - global-multi-trade: - header: "" - shop-options: - header: "Shop Options" - trade-shop-options: - header: "Trade Shop Options" - itrade-shop-options: - header: "ITrade Shop Options" - bitrade-shop-options: - header: "BiTrade Shop Options" - illegal-item-options: - header: "Illegal Item Options" - pre-comment: "" - post-comment: "Valid Types: DISABLED, BLACKLIST, WHITELIST\n" - global-illegal-items: - header: "" - pre-comment: "List for illegal items for both Cost and Product" - post-comment: "" - cost-illegal-items: - header: "" - pre-comment: "List for illegal items for only Cost items" - post-comment: "" - product-illegal-items: - header: "" - pre-comment: "List for illegal items for only Product items" - post-comment: "" setting: - config-version: - pre-comment: "" - post-comment: "\n" - system-options: - data-storage-type: - pre-comment: "How would you like your servers data stored? (FLATFILE)" - enable-debug: - pre-comment: "What debug code should be run. This will add significant amounts of spam to the console/log, generally not used unless requested by Devs" - check-updates: - pre-comment: "Should we check for updates when the server starts" - allow-metrics: - pre-comment: "Allow us to connect anonymous metrics so we can see how our plugin is being used to better develop it" - unlimited-admin: - pre-comment: "We do not recommend enabling this setting since any editing an admin should need to do can be done without this.\n Should players with Admin permission be able to use any commands on any shops?" - use-internal-permissions: - pre-comment: "Should our internal permission system be used? (Only enable if you aren't using a permission plugin)" - post-comment: "\n" - language-options: - message-prefix: - pre-comment: "The prefix the displays before all plugin messages" - post-comment: "\n" - shop-good-colour: - pre-comment: "Header Colours, if the codes are showing in the header, set to \"\"\n Color for successfully created and stocked signs" - shop-incomplete-colour: - pre-comment: "Color for shops that are missing data to make trades" - shop-bad-colour: - pre-comment: "Color for shops that were not successfully created" - post-comment: "\n" - shop-open-status: - pre-comment: "Status Text, What will be shown in the bottom line of shop sign for each status\n Open" - shop-closed-status: - pre-comment: "Closed" - shop-incomplete-status: - pre-comment: "Incomplete" - shop-outofstock-status: - pre-comment: "Out of Stock" - post-comment: "\n" - global-options: - allowed-directions: - pre-comment: "Directions an allowed shop can be from a sign. Allowed directions are:\n Up, Down, North, East, South, West" - allowed-shops: - pre-comment: "Inventories to allow for shops. Allowed blocks are:\n Chest, Trapped_Chest, Dropper, Hopper, Dispenser, Shulker, ..." - max-edit-distance: - pre-comment: "Max distance a player can be from a shop to edit it" - allow-toggle-status: - pre-comment: "Can players toggle view of involved shops?" - allow-sign-break: - pre-comment: "Should we allow anyone to destroy a shops sign?" - allow-chest-break: - pre-comment: "Should we allow anyone to destroy a shops storage?" - post-comment: "\n" - multi-trade: - enable: - pre-comment: "Should we allow multi trades with shift + click (true/false)" - default-multi: - pre-comment: "Default multiplier for trades using shift + click" - max-multi: - pre-comment: "Maximum amount a player can set their multiplier to. Not recommended to set any higher than 6 as this can cause bugs with iTrade Shops" - post-comment: "\n" - illegal-item-options: + sections: + none: + header: "" + system-options: + header: "System Options" + language-options: + header: "Language Options" + global-options: + header: "Global Options" + global-multi-trade: + header: "" + shop-options: + header: "Shop Options" + shop-per-item-options: + header: "Shop Per Item Options" + shop-sign-options: + header: "Shop Sign Options" + trade-shop-options: + header: "Trade Shop Options" + itrade-shop-options: + header: "ITrade Shop Options" + bitrade-shop-options: + header: "BiTrade Shop Options" + illegal-item-options: + header: "Illegal Item Options" + pre-comment: "" + post-comment: "Valid Types: DISABLED, BLACKLIST, WHITELIST\n" global-illegal-items: - type: - pre-comment: "" - list: - pre-comment: "" + header: "" + pre-comment: "List for illegal items for both Cost and Product" + post-comment: "" cost-illegal-items: - type: - pre-comment: "" - list: - pre-comment: "" + header: "" + pre-comment: "List for illegal items for only Cost items" + post-comment: "" product-illegal-items: - type: - pre-comment: "" - list: - pre-comment: "" - shop-options: - max-shop-users: - pre-comment: "Maximum users(Managers/Members) a shop can have" - max-shops-per-chunk: - pre-comment: "Maximum shops that can exist in a single chunk" - max-items-per-trade-side: - pre-comment: "Maximum amount of item stacks per side of trade" - allow-user-purchasing: - pre-comment: "Can players purchase from a shop in which they are a user of (true/false)" - multiple-items-on-sign: - pre-comment: "Text that shows on trade signs that contain more than 1 item\n Available variables are: %AMOUNT%" - post-comment: "\n" - trade-shop-options: - header: - pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" - allow-explode: - pre-comment: "Can explosions damage the shop sign/storage (true/false)" - allow-hopper-export: - pre-comment: "Can hoppers pull items from the shop storage (true/false)" - allow-hopper-import: - pre-comment: "Can hoppers push items into the shop storage (true/false)" - post-comment: "\n" - itrade-shop-options: - owner: - pre-comment: "Name to put on the bottom of iTrade signs" - header: - pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" - allow-explode: - pre-comment: "Can explosions damage the shop sign (true/false)" - no-cost-text: - pre-comment: "What text should be used for successful trades when no cost is present" - no-cost-amount: - pre-comment: "What amount should be used for successful trades when no cost is present(must be greater than 0)" - post-comment: "\n" - bitrade-shop-options: - header: - pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" - allow-explode: - pre-comment: "Can explosions damage the shop sign/storage (true/false)" - allow-hopper-export: - pre-comment: "Can hoppers pull items from the shop storage (true/false)" - allow-hopper-import: - pre-comment: "Can hoppers push items into the shop storage (true/false)" + header: "" + pre-comment: "List for illegal items for only Product items" + post-comment: "" + values: + config-version: + pre-comment: "" post-comment: "\n" + system-options: + data-storage-type: + pre-comment: "How would you like your servers data stored? (FLATFILE, SQLITE)" + enable-debug: + pre-comment: "What debug code should be run. This will add significant amounts of spam to the console/log, generally not used unless requested by Devs" + check-updates: + pre-comment: "Should we check for updates when the server starts" + allow-metrics: + pre-comment: "Allow us to connect anonymous metrics so we can see how our plugin is being used to better develop it" + unlimited-admin: + pre-comment: "We do not recommend enabling this setting since any editing an admin should need to do can be done without this.\n Should players with Admin permission be able to use any commands on any shops?" + language-options: + message-prefix: + pre-comment: "The prefix the displays before all plugin messages" + post-comment: "\n" + shop-good-colour: + pre-comment: "Header Colours, if the codes are showing in the header, set to \"\"\n Color for successfully created and stocked signs" + shop-incomplete-colour: + pre-comment: "Color for shops that are missing data to make trades" + shop-bad-colour: + pre-comment: "Color for shops that were not successfully created" + post-comment: "\n" + shop-open-status: + pre-comment: "Status Text, What will be shown in the bottom line of shop sign for each status\n Open" + shop-closed-status: + pre-comment: "Closed" + shop-incomplete-status: + pre-comment: "Incomplete" + shop-outofstock-status: + pre-comment: "Out of Stock" + post-comment: "\n" + global-options: + chest-directions: + pre-comment: "Directions a valid shop chest can be from a sign. Multiple directions can be chained together allowing all 26 blocks surrounding a block to be checked.\n To Chain directions just add a `+` between each one. i.e `Back+Left` or `Back+Left+Up`\n Allowed directions are:\n Up, Down, Left, Right, Back, Front" + allowed-shops: + pre-comment: "Inventories to allow for shops. Allowed blocks are:\n Chest, Trapped_Chest, Dropper, Hopper, Dispenser, Shulker, ..." + max-edit-distance: + pre-comment: "Max distance a player can be from a shop to edit it" + allow-toggle-status: + pre-comment: "Can players toggle view of involved shops?" + allow-sign-break: + pre-comment: "Should we allow anyone to destroy a shops sign?" + allow-chest-break: + pre-comment: "Should we allow anyone to destroy a shops storage?" + post-comment: "\n" + multi-trade: + enable: + pre-comment: "Should we allow multi trades with shift + click (true/false)" + default-multi: + pre-comment: "Default multiplier for trades using shift + click" + max-multi: + pre-comment: "Maximum amount a player can set their multiplier to. Not recommended to set any higher than 6 as this can cause bugs with iTrade Shops" + post-comment: "\n" + illegal-item-options: + global-illegal-items: + type: + pre-comment: "" + list: + pre-comment: "" + cost-illegal-items: + type: + pre-comment: "" + list: + pre-comment: "" + product-illegal-items: + type: + pre-comment: "" + list: + pre-comment: "" + shop-options: + max-shop-users: + pre-comment: "Maximum users(Managers/Members) a shop can have" + max-shops-per-chunk: + pre-comment: "Maximum shops that can exist in a single chunk" + max-items-per-trade-side: + pre-comment: "Maximum amount of item stacks per side of trade" + allow-user-purchasing: + pre-comment: "Can players purchase from a shop in which they are a user of (true/false)" + multiple-items-on-sign: + pre-comment: "Text that shows on trade signs that contain more than 1 item\n Available variables are: %AMOUNT%" + no-cost-text: + pre-comment: "What text should be used for successful trades when no cost is present" + no-cost-amount: + pre-comment: "What amount should be used for successful trades when no cost is present(must be greater than 0)" + post-comment: "\n" + shop-per-item-options: + shop-per-item-settings: + post-comment: "\n" + shop-sign-options: + sign-default-colours: + pre-comment: "What colour should be used for line 2/3 on shop signs per each material type." + post-comment: "\n" + trade-shop-options: + header: + pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" + allow-explode: + pre-comment: "Can explosions damage the shop sign/storage (true/false)" + allow-hopper-export: + pre-comment: "Can hoppers pull items from the shop storage (true/false)" + allow-hopper-import: + pre-comment: "Can hoppers push items into the shop storage (true/false)" + post-comment: "\n" + itrade-shop-options: + owner: + pre-comment: "Name to put on the bottom of iTrade signs" + header: + pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" + allow-explode: + pre-comment: "Can explosions damage the shop sign (true/false)" + bitrade-shop-options: + header: + pre-comment: "The header that appears at the top of the shop signs, this is also what the player types to create the sign" + allow-explode: + pre-comment: "Can explosions damage the shop sign/storage (true/false)" + allow-hopper-export: + pre-comment: "Can hoppers pull items from the shop storage (true/false)" + allow-hopper-import: + pre-comment: "Can hoppers push items into the shop storage (true/false)" + post-comment: "\n" message: - message-version: - default: 0.0 - pre-comment: "Version of the current config file.\n Do not change!" - language: - default: "en-us" - pre-comment: "This currently does not change anything in the message files, but is used in metrics so that we can see what languages we should try to provide built in support for in the future.\n Please use codes as listed at: https://www.andiamo.co.uk/resources/iso-language-codes/" - post-comment: "\n" - change-closed: - default: "&cThe shop is now &l&bCLOSED&r&a." - change-open: - default: "&aThe shop is now &l&bOPEN&r&a." - empty-ts-on-setup: - default: "&cTradeShop empty, please remember to fill it!" - pre-comment: "Text to display when a player places a TradeSign above an empty chest:" - existing-shop: - default: "&cThis storage or sign is already linked to a shop." - feature-disabled: - default: "&cThis feature has been disabled on this server!" - held-empty: - default: "&eYou are currently holding nothing." - pre-comment: "Text to display when the player is not holding anything" - illegal-item: - default: "&cYou cannot use one or more of those items in shops." - pre-comment: "Text to display when a shop failed creation due to an illegal item" - no-shulker-cost: - default: "&cYou cannot add a Shulker Box as a cost when the shop uses it for storage." - pre-comment: "Text to display when a shop failed creation due to using a shulker box as cost when the shop uses it for storage: " - insufficient-items: - default: "&cYou are missing the below items for the trade! \n{%MISSINGITEMS%= &e%AMOUNT% %ITEM%}" - pre-comment: "Text to display when the player does not have enough items:" - shop-insufficient-items: - default: "&cThis shop is missing the below items for the trade! \n{%MISSINGITEMS%= &e%AMOUNT% %ITEM%}" - pre-comment: "Text to display when the shop does not have enough items:" - invalid-arguments: - default: "&eTry &6/tradeshop help &eto display help!" - pre-comment: "Text to display when invalid arguments are submitted through the \"/tradeshop\" command:" - item-added: - default: "&aItem successfully added to shop." - item-not-removed: - default: "&cItem could not be removed from shop." - item-removed: - default: "&aItem successfully removed to shop." - missing-chest: - default: "&cYour shop is missing a chest." - missing-item: - default: "&cYour sign is missing an item for trade." - pre-comment: "Text to display when a shop sign failed creation due to missing an item" - multi-amount: - default: "&aYour trade multiplier is %AMOUNT%." - multi-update: - default: "&aTrade multiplier has been updated to %AMOUNT%." - no-chest: - default: "&cYou need to put a chest under the sign!" - pre-comment: "Text to display when a player attempts to place a sign without placing the chest first:" - no-command-permission: - default: "&cYou do not have permission to execute this command" - pre-comment: "Text to display when a player attempts to run administrator commands:" - no-shop-permission: - default: "&cYou do not have permission to edit that shop." - no-trade-permission: - default: "&cYou do not have permission to trade with TradeShops" - pre-comment: "Text to display when a player attempts to trade while having the `Prevent Trade` permission:" - no-sighted-shop: - default: "&cNo shop in range!" - pre-comment: "Text to display when a player is too far from a shop" - no-ts-create-permission: - default: "&cYou don't have permission to create TradeShops!" - pre-comment: "Text to display when a player attempts to setup a shoptype they are not allowed to create:" - no-ts-destroy: - default: "&cYou may not destroy that TradeShop" - pre-comment: "Text to display when a player attempts to destroy a shop they do not own:" - destroy-shop-sign-first: - default: "&cYou must destroy the shops sign first." - pre-comment: "Text to display when a player attempts to destroy a block with a shop sign attached to it:" - no-ts-open: - default: "&cThat TradeShop does not belong to you" - pre-comment: "Text to display when a player attempts to open a shop they do not own nor have been granted access to:" - on-trade: - default: "&aYou have traded with %SELLER% receiving: \n{%RECEIVEDLINES%= &e%AMOUNT% %ITEM%} \n&aIn exchange for: \n{%GIVENLINES%= &e%AMOUNT% %ITEM%}" - pre-comment: "Text to display upon a successful trade:" - player-full: - default: "&cYour inventory is full, please make room before trading items!" - pre-comment: "Text to display when the players inventory is too full to recieve the trade:" - player-not-found: - default: "&cThat player could not be found." - player-only-command: - default: "&eThis command is only available to players." - pre-comment: "Text to display when console tries to use a player only command" - plugin-behind: - default: "&cThe server is running an old version of TradeShop, please update the plugin." - self-owned: - default: "&cYou cannot buy from a shop in which you are a user." - pre-comment: "Text to display when a player tries to buy form a shop in which they are a user" - setup-help: - default: "\n&2Setting up a TradeShop is easy! Just make sure to follow these steps:\n \nStep 1: &ePlace down a chest.\n&2Step 2: &ePlace a sign on top of or around the chest.\n&2Step 3: &eWrite the following on the sign\n&6 [%HEADER%]\n&6&o-- Leave Blank --\n&6&o-- Leave Blank --\n&6&o-- Leave Blank --\n&2Step 4: &eUse the addCost and addProduct commands to add items to your shop" - pre-comment: "Text to display on \"/tradeshop setup\":" - shop-closed: - default: "&cThis shop is currently closed." - shop-empty: - default: "&cThis TradeShop is currently missing items to complete the trade!" - pre-comment: "Text to display when the shop does not have enough stock:" - shop-full: - default: "&cThis TradeShop is full, please contact the owner to get it emptied!" - pre-comment: "Text to display when the shop storage is full:" - shop-item-list: - default: "&aThe shops %TYPE%:\n%LIST%" - shop-type-switched: - default: "&aShop type has been switched to %NEWTYPE%." - pre-comment: "Text to display when a player uses '/ts toggle'\n Available variables are: %TYPE% %NEWTYPE%" - successful-setup: - default: "&aYou have successfully setup a TradeShop!" - pre-comment: "Text to display when a player successfully creates a TradeShop:" - too-many-chests: - default: "&cThere are too many shops in this chunk, you can not add another one." - too-many-items: - default: "&cThis shop cannot take any more %SIDE% items!" - unsuccessful-shop-members: - default: "&aThat player is either already on the shop, or you have reached the maximum number of users!" - pre-comment: "Text to display when shop users could not be updated" - updated-shop-members: - default: "&aShop owners and members have been updated!" - pre-comment: "Text to display when shop users have been updated successfully" - who-message: - default: "&6Shop users are:\n&2Owner: &e%OWNER%\n&2Managers: &e%MANAGERS%\n&2Members: &e%MEMBERS%" - pre-comment: "Text to display when players use the who command" - view-player-level: - default: "&e%PLAYER% has a level of %LEVEL%." - pre-comment: "Text to display when viewing a players level with /ts PlayerLevel" - set-player-level: - default: "&aYou have set the level of %PLAYER% to %LEVEL%!" - pre-comment: "Text to display after setting a players level" - various-item-type: - default: "Various" - pre-comment: "Text to display when a message uses an Item Type and the Type varies" - toggled-status: - default: "Toggled status: &c%STATUS%" - no-sign-found: - default: "&cNo sign in range!" - pre-comment: "Text to display when a player is too far from a sign" - admin-toggled: - default: "&aYour Admin mode is currently &e%STATE%&a." - pre-comment: "Text to display when an admin toggles or views their Admin abilities. \n# \"%STATE%\" will be replaced by the state that the player is in after the command." - failed-trade: - default: "&cThe Trade has failed for unknown reasons, please notify an Admin or submit a bug report using '/ts bug'!" - pre-comment: "Text to display when a player is too far from a sign" - \ No newline at end of file + sections: + none: + header: "" + unused: + header: "" + values: + message-version: + default: 0.0 + pre-comment: "Version of the current config file.\n Do not change!" + language: + default: "en-us" + pre-comment: "This currently does not change anything in the message files, but is used in metrics so that we can see what languages we should try to provide built in support for in the future.\n Please use codes as listed at: https://www.andiamo.co.uk/resources/iso-language-codes/" + post-comment: "\n" + change-closed: + default: "&cThe shop is now &l&bCLOSED&r&a." + change-open: + default: "&aThe shop is now &l&bOPEN&r&a." + empty-ts-on-setup: + default: "&cTradeShop empty, please remember to fill it!" + pre-comment: "Text to display when a player places a TradeSign above an empty chest:" + existing-shop: + default: "&cThis storage or sign is already linked to a shop." + feature-disabled: + default: "&cThis feature has been disabled on this server!" + held-empty: + default: "&eYou are currently holding nothing." + pre-comment: "Text to display when the player is not holding anything" + illegal-item: + default: "&cYou cannot use one or more of those items in shops." + pre-comment: "Text to display when a shop failed creation due to an illegal item" + no-shulker-item: + default: "&cYou cannot add a Shulker Box when the shop uses it for storage." + pre-comment: "Text to display when a shop failed creation due to using a shulker box when the shop uses it for storage: " + insufficient-items: + default: "&cYou are missing the below items for the trade! \n{%MISSINGITEMS%= &e%AMOUNT% %ITEM%}" + pre-comment: "Text to display when the player does not have enough items:" + shop-insufficient-items: + default: "&cThis shop is missing the below items for the trade! \n{%MISSINGITEMS%= &e%AMOUNT% %ITEM%}" + pre-comment: "Text to display when the shop does not have enough items:" + invalid-arguments: + default: "&eTry &6/tradeshop help &eto display help!" + pre-comment: "Text to display when invalid arguments are submitted through the \"/tradeshop\" command:" + item-added: + default: "&aItem successfully added to shop." + item-not-removed: + default: "&cItem could not be removed from shop." + item-removed: + default: "&aItem successfully removed to shop." + missing-chest: + default: "&cYour shop is missing a chest." + missing-item: + default: "&cYour sign is missing an item for trade." + pre-comment: "Text to display when a shop sign failed creation due to missing an item" + multi-amount: + default: "&aYour trade multiplier is %AMOUNT%." + multi-update: + default: "&aTrade multiplier has been updated to %AMOUNT%." + no-chest: + default: "&cYou need to put a chest under the sign!" + pre-comment: "Text to display when a player attempts to place a sign without placing the chest first:" + no-command-permission: + default: "&cYou do not have permission to execute this command" + pre-comment: "Text to display when a player attempts to run administrator commands:" + no-shop-permission: + default: "&cYou do not have permission to edit that shop." + no-trade-permission: + default: "&cYou do not have permission to trade with TradeShops" + pre-comment: "Text to display when a player attempts to trade while not having the `Trade` permission:" + no-sighted-shop: + default: "&cNo shop in range!" + pre-comment: "Text to display when a player is too far from a shop" + no-ts-create-permission: + default: "&cYou don't have permission to create this type of TradeShop!" + pre-comment: "Text to display when a player attempts to setup a shoptype they are not allowed to create:" + no-ts-destroy: + default: "&cYou may not destroy that TradeShop" + pre-comment: "Text to display when a player attempts to destroy a shop they do not own:" + destroy-shop-sign-first: + default: "&cYou must destroy the shops sign first." + pre-comment: "Text to display when a player attempts to destroy a block with a shop sign attached to it:" + no-ts-open: + default: "&cThat TradeShop does not belong to you" + pre-comment: "Text to display when a player attempts to open a shop they do not own nor have been granted access to:" + on-trade: + default: "&aYou have traded with %SELLER% receiving: \n{%RECEIVEDLINES%= &e%AMOUNT% %ITEM%} \n&aIn exchange for: \n{%GIVENLINES%= &e%AMOUNT% %ITEM%}" + pre-comment: "Text to display upon a successful trade:" + player-full: + default: "&cYour inventory is full, please make room before trading items!" + pre-comment: "Text to display when the players inventory is too full to receive the trade:" + player-not-found: + default: "&cThat player could not be found." + player-only-command: + default: "&eThis command is only available to players." + pre-comment: "Text to display when console tries to use a player only command" + plugin-behind: + default: "&cThe server is running an old version of TradeShop, please update the plugin." + self-owned: + default: "&cYou cannot buy from a shop in which you are a user." + pre-comment: "Text to display when a player tries to buy form a shop in which they are a user" + setup-help: + default: "\n&2Setting up a TradeShop is easy! Just make sure to follow these steps:\n \nStep 1: &ePlace down a chest.\n&2Step 2: &ePlace a sign on top of or around the chest.\n&2Step 3: &eWrite the following on the sign\n&6 [%HEADER%]\n&6&o-- Leave Blank --\n&6&o-- Leave Blank --\n&6&o-- Leave Blank --\n&2Step 4: &eUse the addCost and addProduct commands to add items to your shop" + pre-comment: "Text to display on \"/tradeshop setup\":" + shop-closed: + default: "&cThis shop is currently closed." + shop-empty: + default: "&cThis TradeShop is currently missing items to complete the trade!" + pre-comment: "Text to display when the shop does not have enough stock:" + shop-full: + default: "&cThis TradeShop is full, please contact the owner to get it emptied!" + pre-comment: "Text to display when the shop storage is full:" + shop-item-list: + default: "&aThe shops %TYPE%:\n%LIST%" + shop-type-switched: + default: "&aShop type has been switched to %NEWTYPE%." + pre-comment: "Text to display when a player uses '/ts toggle'\n Available variables are: %TYPE% %NEWTYPE%" + successful-setup: + default: "&aYou have successfully setup a TradeShop!" + pre-comment: "Text to display when a player successfully creates a TradeShop:" + too-many-chests: + default: "&cThere are too many shops in this chunk, you can not add another one." + too-many-items: + default: "&cThis shop cannot take any more %SIDE% items!" + updated-shop-users: + default: "&aShop users have tried to update for the below shops! \n{%UPDATEDSHOPS%= %SHOP% -|- %STATUS%}" + pre-comment: "Text to display when shop users have been updated." + updated-shop-users-successful: + default: "&aSuccessful" + pre-comment: "Text to display when shop users have been updated successfully." + updated-shop-users-failed: + default: "&cFailed" + pre-comment: "Text to display when shop users could not be added for an unknown reason." + updated-shop-users-failed-capacity: + default: "&cMax Capacity" + pre-comment: "Text to display when shop users could not be added due to the shop having max user capacity." + updated-shop-users-failed-existing: + default: "&ePlayer Exists" + pre-comment: "Text to display when shop users could not be added because they are already a user on the shop." + updated-shop-users-failed-missing: + default: "&ePlayer Missing" + pre-comment: "Text to display when shop users could not be removed because the user was not on the shop." + who-message: + default: "&6Shop users are:\n&2Owner: &e%OWNER%\n&2Managers: &e%MANAGERS%\n&2Members: &e%MEMBERS%" + pre-comment: "Text to display when players use the who command" + view-player-level: + default: "&e%PLAYER% has a level of %LEVEL%." + pre-comment: "Text to display when viewing a players level with /ts PlayerLevel" + set-player-level: + default: "&aYou have set the level of %PLAYER% to %LEVEL%!" + pre-comment: "Text to display after setting a players level" + various-item-type: + default: "Various" + pre-comment: "Text to display when a message uses an Item Type and the Type varies" + toggled-status: + default: "Toggled status: &c%STATUS%" + no-sign-found: + default: "&cNo sign in range!" + pre-comment: "Text to display when a player is too far from a sign" + admin-toggled: + default: "&aYour Admin mode is currently &e%STATE%&a." + pre-comment: "Text to display when an admin toggles or views their Admin abilities. \n# \"%STATE%\" will be replaced by the state that the player is in after the command." + failed-trade: + default: "&cThe Trade has failed for unknown reasons, please notify an Admin or submit a bug report using '/ts bug'!" + pre-comment: "Text to display when a player is too far from a sign" +permission: + help: + description: 'Allows players to view the help menu containing only commands they have permission to use.' + create: + description: 'Allows players to create standard `Trade` Shops.' + createi: + description: 'Allows players to create infinite `iTrade` Shops.' + createbi: + description: 'Allows players to create bi-directional `biTrade` Shops.' + admin: + description: 'Allows players to use administrator commands as well as giving administrator access to Shop storages. The player must also enable admin mode through commands when they wish to use these privileges.' + edit: + description: 'Allows players to use the edit gui on shops they have created or have a sufficient role for.' + info: + description: 'Allows players to use informational commands on any shops they can see.' + manage-plugin: + description: 'Allows players to use commands that provide plugin management.' + prevent-trade: + description: 'Depreciated, please remove `trade` permission instead.' + trade: + description: 'Allows players to trade with TradeShops.' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e0ed8e79..743e6fef 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,4 +1,4 @@ -name: TradeShop +name: ${project.name} version: ${project.version} main: org.shanerx.tradeshop.TradeShop api-version: 1.14