diff --git a/API/src/main/java/fr/maxlego08/shop/api/event/ShopAction.java b/API/src/main/java/fr/maxlego08/shop/api/event/ShopAction.java index 33d7b40..26a4503 100644 --- a/API/src/main/java/fr/maxlego08/shop/api/event/ShopAction.java +++ b/API/src/main/java/fr/maxlego08/shop/api/event/ShopAction.java @@ -8,11 +8,13 @@ public class ShopAction { private final ItemStack itemStack; private final ItemButton itemButton; private double price; + private int totalAmount; public ShopAction(ItemStack itemStack, ItemButton itemButton, double price) { this.itemStack = itemStack; this.itemButton = itemButton; this.price = price; + this.totalAmount = itemStack.getAmount(); } public ItemStack getItemStack() { @@ -30,4 +32,16 @@ public double getPrice() { public void setPrice(double price) { this.price = price; } + + public int getTotalAmount() { + return totalAmount; + } + + public void setTotalAmount(int totalAmount) { + this.totalAmount = totalAmount; + } + + public void addAmount(int amount) { + this.totalAmount += amount; + } } diff --git a/API/src/main/java/fr/maxlego08/shop/api/limit/LimiterManager.java b/API/src/main/java/fr/maxlego08/shop/api/limit/LimiterManager.java index 98e9cd5..e11704e 100644 --- a/API/src/main/java/fr/maxlego08/shop/api/limit/LimiterManager.java +++ b/API/src/main/java/fr/maxlego08/shop/api/limit/LimiterManager.java @@ -9,6 +9,8 @@ public interface LimiterManager { Collection getLimits(); + Collection getLimits(LimitType limitType); + void create(Limit limit); Optional getLimit(LimitType limitType, String material); diff --git a/src/main/java/fr/maxlego08/shop/ZShopManager.java b/src/main/java/fr/maxlego08/shop/ZShopManager.java index 0e81440..df4a41d 100644 --- a/src/main/java/fr/maxlego08/shop/ZShopManager.java +++ b/src/main/java/fr/maxlego08/shop/ZShopManager.java @@ -392,7 +392,7 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento List> buttons = this.itemButtons.stream().map(button -> { ItemStack itemStack = button.getItemStack().build(player, false); return new Pair<>(itemStack, button); - }).collect(Collectors.toList()); + }).toList(); /* SCAN ITEMS */ for (int slot = 0; slot != inventory.getContents().length; slot++) { @@ -400,13 +400,13 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento if (itemStack == null) continue; Optional optional = buttons.stream().filter(e -> e.first.isSimilar(itemStack)).map(e -> e.second).findFirst(); - if (!optional.isPresent()) continue; + if (optional.isEmpty()) continue; ItemButton itemButton = optional.get(); if (!itemButton.canSell()) continue; double price = itemButton.getSellPrice(player, itemStack.getAmount()); - ShopAction shopAction = new ShopAction(itemStack, itemButton, price); + ShopAction shopAction = new ShopAction(itemStack.clone(), itemButton, price); shopActions.add(shopAction); } @@ -424,6 +424,8 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento ItemButton button = action.getItemButton(); ItemStack itemStack = action.getItemStack(); + int requestedAmount = itemStack.getAmount(); + int actualSellAmount = requestedAmount; // Amount that will actually be sold int newServerLimitAmount = 0; int newPlayerLimitAmount = 0; String material = button.getItemStack().getMaterial(); @@ -435,8 +437,15 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento /* SERVER LIMIT */ if (optionalServer.isPresent()) { Limit serverSellLimit = optionalServer.get(); - newServerLimitAmount = serverSellLimit.getAmount() + itemStack.getAmount(); - if (newServerLimitAmount > serverSellLimit.getLimit()) return; + int currentServerAmount = serverSellLimit.getAmount(); + int maxCanSell = serverSellLimit.getLimit() - currentServerAmount; + + if (maxCanSell <= 0) { + action.setTotalAmount(0); + return; + } + actualSellAmount = Math.min(actualSellAmount, maxCanSell); + newServerLimitAmount = currentServerAmount + actualSellAmount; } /* END SERVER LIMIT */ @@ -444,11 +453,25 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento if (optionalPlayer.isPresent()) { Limit playerSellLimit = optionalPlayer.get(); Optional optional = limiterManager.getLimit(player); - newPlayerLimitAmount = optional.map(e -> e.getSellAmount(material)).orElse(0) + itemStack.getAmount(); - if (newPlayerLimitAmount > playerSellLimit.getLimit()) return; + int currentPlayerAmount = optional.map(e -> e.getSellAmount(material)).orElse(0); + int maxCanSell = playerSellLimit.getLimit() - currentPlayerAmount; + + if (maxCanSell <= 0) { + action.setTotalAmount(0); + return; + } + actualSellAmount = Math.min(actualSellAmount, maxCanSell); + newPlayerLimitAmount = currentPlayerAmount + actualSellAmount; } /* END PLAYER LIMIT */ + if (actualSellAmount != requestedAmount) { + itemStack.setAmount(actualSellAmount); + double actualPrice = button.getSellPrice(player, actualSellAmount); + action.setPrice(actualPrice); + } + action.setTotalAmount(actualSellAmount); + /* UPDATE LIMIT VALUES */ if (optionalServer.isPresent()) optionalServer.get().setAmount(newServerLimitAmount); if (newPlayerLimitAmount > 0) @@ -457,8 +480,7 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento /* REMOVE ITEMS AND UPDATE MONEY */ prices.put(button.getEconomy(), prices.getOrDefault(button.getEconomy(), 0.0) + action.getPrice()); - // inventory.remove(itemStack); - InventoryUtils.removeItem(inventory, itemStack, itemStack.getAmount()); + InventoryUtils.removeItem(inventory, itemStack, actualSellAmount); }); if (prices.isEmpty()) { @@ -469,23 +491,25 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento List fixedShopActions = new ArrayList<>(); shopActions.forEach(action -> { + if (action.getTotalAmount() == 0) return; + Optional optional = fixedShopActions.stream().filter(e -> e.getItemStack().isSimilar(action.getItemStack())).findFirst(); if (optional.isPresent()) { ShopAction currentAction = optional.get(); currentAction.setPrice(currentAction.getPrice() + action.getPrice()); - currentAction.getItemStack().setAmount(currentAction.getItemStack().getAmount() + action.getItemStack().getAmount()); + currentAction.addAmount(action.getTotalAmount()); } else fixedShopActions.add(action); }); var translationManager = this.plugin.getTranslationManager(); - String results = toList(fixedShopActions.stream().map(action -> getMessage(Message.SELL_ALL_INFO, "%amount%", action.getItemStack().getAmount(), "%item%", translationManager.translateItemStack(action.getItemStack()), "%price%", action.getItemButton().getEconomy().format(transformPrice(action.getPrice()), action.getPrice()))).collect(Collectors.toList()), Message.SELL_ALL_COLOR_SEPARATOR.msg(), Message.SELL_ALL_COLOR_INFO.msg()); + String results = toList(fixedShopActions.stream().map(action -> getMessage(Message.SELL_ALL_INFO, "%amount%", action.getTotalAmount(), "%item%", translationManager.translateItemStack(action.getItemStack()), "%price%", action.getItemButton().getEconomy().format(transformPrice(action.getPrice()), action.getPrice()))).collect(Collectors.toList()), Message.SELL_ALL_COLOR_SEPARATOR.msg(), Message.SELL_ALL_COLOR_INFO.msg()); if (results == null) { Logger.info("Error with results on sellall !"); player.sendMessage("§cError with results on sellall !"); } - String resultsReason = toList(fixedShopActions.stream().map(action -> getMessage(Config.depositAllLine, "%amount%", action.getItemStack().getAmount(), "%item%", translationManager.translateItemStack(action.getItemStack()), "%price%", action.getItemButton().getEconomy().format(transformPrice(action.getPrice()), action.getPrice()))).collect(Collectors.toList()), "", ""); + String resultsReason = toList(fixedShopActions.stream().map(action -> getMessage(Config.depositAllLine, "%amount%", action.getTotalAmount(), "%item%", translationManager.translateItemStack(action.getItemStack()), "%price%", action.getItemButton().getEconomy().format(transformPrice(action.getPrice()), action.getPrice()))).collect(Collectors.toList()), "", ""); prices.forEach((economy, price) -> economy.depositMoney(player, price, Config.depositAllReason.replace("%items%", resultsReason == null ? "" : resultsReason))); message(this.plugin, player, Message.SELL_ALL_MESSAGE, "%items%", results == null ? "ERROR" : results); @@ -510,7 +534,7 @@ public void sellAllContent(Player player, org.bukkit.inventory.Inventory invento public void sellHand(Player player, int amount) { ItemStack itemInHand = player.getItemInHand(); // Use old method for 1.8 support - if (itemInHand == null || itemInHand.getType().equals(Material.AIR)) { + if (itemInHand.getType().equals(Material.AIR)) { message(this.plugin, player, Message.SELL_HAND_AIR); return; } diff --git a/src/main/java/fr/maxlego08/shop/command/commands/CommandShop.java b/src/main/java/fr/maxlego08/shop/command/commands/CommandShop.java index ff99ec4..3246a7e 100644 --- a/src/main/java/fr/maxlego08/shop/command/commands/CommandShop.java +++ b/src/main/java/fr/maxlego08/shop/command/commands/CommandShop.java @@ -13,6 +13,7 @@ public CommandShop(ShopPlugin plugin) { this.addSubCommand(new CommandShopReload(plugin)); this.addSubCommand(new CommandShopLogs(plugin)); this.addSubCommand(new CommandShopConvert(plugin)); + this.addSubCommand(new CommandShopResetLimit(plugin)); } @Override diff --git a/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimit.java b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimit.java new file mode 100644 index 0000000..3e618c6 --- /dev/null +++ b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimit.java @@ -0,0 +1,32 @@ +package fr.maxlego08.shop.command.commands; + +import fr.maxlego08.shop.ShopPlugin; +import fr.maxlego08.shop.api.limit.Limit; +import fr.maxlego08.shop.api.limit.LimitType; +import fr.maxlego08.shop.api.limit.LimiterManager; +import fr.maxlego08.shop.command.VCommand; +import fr.maxlego08.shop.zcore.enums.Message; +import fr.maxlego08.shop.zcore.enums.Permission; +import fr.maxlego08.shop.zcore.utils.commands.CommandType; + +import java.util.Optional; + +public class CommandShopResetLimit extends VCommand { + + public CommandShopResetLimit(ShopPlugin plugin) { + super(plugin); + this.setPermission(Permission.ZSHOP_RESET_LIMIT); + this.addSubCommand("resetlimit"); + this.setDescription(Message.DESCRIPTION_RESET_LIMIT); + this.addSubCommand(new CommandShopResetLimitAll(plugin)); + this.addSubCommand(new CommandShopResetLimitPlayer(plugin)); + this.addSubCommand(new CommandShopResetLimitServer(plugin)); + } + + @Override + protected CommandType perform(ShopPlugin plugin) { + syntaxMessage(); + return CommandType.SUCCESS; + } +} + diff --git a/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitAll.java b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitAll.java new file mode 100644 index 0000000..3d5e5af --- /dev/null +++ b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitAll.java @@ -0,0 +1,28 @@ +package fr.maxlego08.shop.command.commands; + +import fr.maxlego08.shop.ShopPlugin; +import fr.maxlego08.shop.api.limit.Limit; +import fr.maxlego08.shop.api.limit.LimiterManager; +import fr.maxlego08.shop.command.VCommand; +import fr.maxlego08.shop.zcore.enums.Message; +import fr.maxlego08.shop.zcore.enums.Permission; +import fr.maxlego08.shop.zcore.utils.commands.CommandType; + +public class CommandShopResetLimitAll extends VCommand { + public CommandShopResetLimitAll(ShopPlugin plugin) { + super(plugin); + this.setPermission(Permission.ZSHOP_RESET_LIMIT_ALL); + this.addSubCommand("all"); + this.setDescription(Message.DESCRIPTION_RESET_LIMIT_ALL); + } + + @Override + protected CommandType perform(ShopPlugin plugin) { + LimiterManager limiterManager = plugin.getLimiterManager(); + for (Limit limit : limiterManager.getLimits()){ + limiterManager.reset(limit); + } + message(plugin, sender, Message.RESET_LIMIT_ALL_SUCCESS); + return CommandType.SUCCESS; + } +} diff --git a/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitPlayer.java b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitPlayer.java new file mode 100644 index 0000000..c7bff0a --- /dev/null +++ b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitPlayer.java @@ -0,0 +1,56 @@ +package fr.maxlego08.shop.command.commands; + +import fr.maxlego08.shop.ShopPlugin; +import fr.maxlego08.shop.api.limit.Limit; +import fr.maxlego08.shop.api.limit.LimitType; +import fr.maxlego08.shop.api.limit.LimiterManager; +import fr.maxlego08.shop.command.VCommand; +import fr.maxlego08.shop.zcore.enums.Message; +import fr.maxlego08.shop.zcore.enums.Permission; +import fr.maxlego08.shop.zcore.utils.commands.CommandType; + +import java.util.Collection; +import java.util.Optional; + +public class CommandShopResetLimitPlayer extends VCommand { + public CommandShopResetLimitPlayer(ShopPlugin plugin) { + super(plugin); + this.setPermission(Permission.ZSHOP_RESET_LIMIT_PLAYER); + this.addSubCommand("resetlimitplayer", "resetplayerlimit", "rpl"); + this.setDescription(Message.DESCRIPTION_RESET_LIMIT_PLAYER); + this.addOptionalArg("item"); + } + + @Override + protected CommandType perform(ShopPlugin plugin) { + LimiterManager limiterManager = plugin.getLimiterManager(); + String materialName = this.argAsString(0); + if (materialName == null) { + Collection limitsBuy = limiterManager.getLimits(LimitType.PLAYER_BUY); + Collection limitsSell = limiterManager.getLimits(LimitType.PLAYER_SELL); + for (Limit limit : limitsBuy) { + limiterManager.reset(limit); + } + for (Limit limit : limitsSell) { + limiterManager.reset(limit); + } + message(plugin, sender, Message.RESET_LIMIT_PLAYERS_SUCCESS); + + } else { + Optional limitsBuy = limiterManager.getLimit(LimitType.PLAYER_BUY, materialName); + Optional limitsSell = limiterManager.getLimit(LimitType.PLAYER_SELL, materialName); + if (limitsSell.isPresent()){ + limiterManager.reset(limitsSell.get()); + message(plugin, sender, Message.RESET_LIMIT_PLAYER_ITEM_SUCCESS, "%item%", materialName, "%type%", "sell"); + } + if (limitsBuy.isPresent()){ + limiterManager.reset(limitsBuy.get()); + message(plugin, sender, Message.RESET_LIMIT_PLAYER_ITEM_SUCCESS, "%item%", materialName, "%type%", "buy"); + } + if (limitsBuy.isEmpty() && limitsSell.isEmpty()) { + message(plugin, sender, Message.RESET_LIMIT_NOT_FOUND, "%item%", materialName); + } + } + return CommandType.SUCCESS; + } +} diff --git a/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitServer.java b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitServer.java new file mode 100644 index 0000000..fa6a2c7 --- /dev/null +++ b/src/main/java/fr/maxlego08/shop/command/commands/CommandShopResetLimitServer.java @@ -0,0 +1,56 @@ +package fr.maxlego08.shop.command.commands; + +import fr.maxlego08.shop.ShopPlugin; +import fr.maxlego08.shop.api.limit.Limit; +import fr.maxlego08.shop.api.limit.LimitType; +import fr.maxlego08.shop.api.limit.LimiterManager; +import fr.maxlego08.shop.command.VCommand; +import fr.maxlego08.shop.zcore.enums.Message; +import fr.maxlego08.shop.zcore.enums.Permission; +import fr.maxlego08.shop.zcore.utils.commands.CommandType; + +import java.util.Collection; +import java.util.Optional; + +public class CommandShopResetLimitServer extends VCommand { + public CommandShopResetLimitServer(ShopPlugin plugin) { + super(plugin); + this.setPermission(Permission.ZSHOP_RESET_LIMIT_SERVER); + this.addSubCommand("resetlimitserver", "resetserverlimit", "rsl"); + this.setDescription(Message.DESCRIPTION_RESET_LIMIT_SERVER); + this.addOptionalArg("item"); + } + + @Override + protected CommandType perform(ShopPlugin plugin) { + LimiterManager limiterManager = plugin.getLimiterManager(); + String materialName = this.argAsString(0); + if (materialName == null) { + Collection limitsBuy = limiterManager.getLimits(LimitType.SERVER_BUY); + Collection limitsSell = limiterManager.getLimits(LimitType.SERVER_SELL); + for (Limit limit : limitsBuy) { + limiterManager.reset(limit); + } + for (Limit limit : limitsSell) { + limiterManager.reset(limit); + } + message(plugin, sender, Message.RESET_LIMIT_SERVERS_SUCCESS); + + } else { + Optional limitsBuy = limiterManager.getLimit(LimitType.SERVER_BUY, materialName); + Optional limitsSell = limiterManager.getLimit(LimitType.SERVER_SELL, materialName); + if (limitsSell.isPresent()){ + limiterManager.reset(limitsSell.get()); + message(plugin, sender, Message.RESET_LIMIT_SERVER_ITEM_SUCCESS, "%item%", materialName, "%type%", "sell"); + } + if (limitsBuy.isPresent()){ + limiterManager.reset(limitsBuy.get()); + message(plugin, sender, Message.RESET_LIMIT_SERVER_ITEM_SUCCESS, "%item%", materialName, "%type%", "buy"); + } + if (limitsBuy.isEmpty() && limitsSell.isEmpty()) { + message(plugin, sender, Message.RESET_LIMIT_NOT_FOUND, "%item%", materialName); + } + } + return CommandType.SUCCESS; + } +} diff --git a/src/main/java/fr/maxlego08/shop/limit/ZLimitManager.java b/src/main/java/fr/maxlego08/shop/limit/ZLimitManager.java index 062c57b..f3f315e 100644 --- a/src/main/java/fr/maxlego08/shop/limit/ZLimitManager.java +++ b/src/main/java/fr/maxlego08/shop/limit/ZLimitManager.java @@ -21,14 +21,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Stream; public class ZLimitManager extends ZUtils implements LimiterManager, Saveable, Listener { @@ -131,7 +124,18 @@ public void onQuit(PlayerQuitEvent event) { @Override public Collection getLimits() { - return null; + return Collections.unmodifiableList(limits); + } + + @Override + public Collection getLimits(LimitType limitType) { + List filteredLimits = new ArrayList<>(); + for (Limit limit : limits) { + if (limit.getType() == limitType) { + filteredLimits.add(limit); + } + } + return Collections.unmodifiableList(filteredLimits); } @Override diff --git a/src/main/java/fr/maxlego08/shop/zcore/enums/Message.java b/src/main/java/fr/maxlego08/shop/zcore/enums/Message.java index 3e5ce5e..8b5a9d6 100644 --- a/src/main/java/fr/maxlego08/shop/zcore/enums/Message.java +++ b/src/main/java/fr/maxlego08/shop/zcore/enums/Message.java @@ -58,6 +58,16 @@ public enum Message { LOG_INFO_MESSAGE("§7%date% §8- §f%message%"), LOG_INFO_FOOTER("§7§m-------------------------------------"), LOG_INFO_NONE("§cAucune log pour le joueur §f%player%§c."), + DESCRIPTION_RESET_LIMIT("Reset global or player limits for items"), + DESCRIPTION_RESET_LIMIT_ALL("Reset all limits"), + DESCRIPTION_RESET_LIMIT_PLAYER("Reset player limits for an item (all items if no item specified)"), + DESCRIPTION_RESET_LIMIT_SERVER("Reset server limits for an item (all items if no item specified)"), + RESET_LIMIT_ALL_SUCCESS("§aYou have successfully reset all limits."), + RESET_LIMIT_NOT_FOUND("§cLimit not found for §f%item%§c."), + RESET_LIMIT_PLAYERS_SUCCESS("§aYou have successfully reset the player limits for all items."), + RESET_LIMIT_PLAYER_ITEM_SUCCESS("§aYou have successfully reset the player limits %type% for §f%item%§a."), + RESET_LIMIT_SERVERS_SUCCESS("§aYou have successfully reset the server limits for all items."), + RESET_LIMIT_SERVER_ITEM_SUCCESS("§aYou have successfully reset the server limits %type% for §f%item%§a.") ; @@ -73,15 +83,13 @@ public enum Message { /** * @param message */ - private Message(String message) { + Message(String message) { this.message = message; - this.use = true; } Message(String message, String messageNewVersion) { this.message = message; this.messageNewVersion = messageNewVersion; - this.use = true; } /** @@ -91,8 +99,7 @@ private Message(String message) { * @param b * @param c */ - private Message(String title, String subTitle, int a, int b, int c) { - this.use = true; + Message(String title, String subTitle, int a, int b, int c) { this.titles.put("title", title); this.titles.put("subtitle", subTitle); this.titles.put("start", a); @@ -105,26 +112,23 @@ private Message(String title, String subTitle, int a, int b, int c) { /** * @param message */ - private Message(String... message) { + Message(String... message) { this.messages = Arrays.asList(message); - this.use = true; } /** * @param message */ - private Message(MessageType type, String... message) { + Message(MessageType type, String... message) { this.messages = Arrays.asList(message); - this.use = true; this.type = type; } /** * @param message */ - private Message(MessageType type, String message) { + Message(MessageType type, String message) { this.message = message; - this.use = true; this.type = type; } @@ -132,7 +136,7 @@ private Message(MessageType type, String message) { * @param message * @param use */ - private Message(String message, boolean use) { + Message(String message, boolean use) { this.message = message; this.use = use; } diff --git a/src/main/java/fr/maxlego08/shop/zcore/enums/Permission.java b/src/main/java/fr/maxlego08/shop/zcore/enums/Permission.java index a481be9..3c64e69 100644 --- a/src/main/java/fr/maxlego08/shop/zcore/enums/Permission.java +++ b/src/main/java/fr/maxlego08/shop/zcore/enums/Permission.java @@ -9,10 +9,14 @@ public enum Permission { ZSHOP_SELL_ALL, ZSHOP_SELL_HAND, ZSHOP_SELL_HAND_ALL, + ZSHOP_RESET_LIMIT, + ZSHOP_RESET_LIMIT_ALL, + ZSHOP_RESET_LIMIT_PLAYER, + ZSHOP_RESET_LIMIT_SERVER ; - private String permission; + private final String permission; private Permission() { this.permission = this.name().toLowerCase().replace("_", ".");