diff --git a/pom.xml b/pom.xml index 62973e9..23995b7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 ca.tweetzy auctionhouse - 2.21.1 + 2.22.0 UTF-8 diff --git a/src/main/java/ca/tweetzy/auctionhouse/AuctionHouse.java b/src/main/java/ca/tweetzy/auctionhouse/AuctionHouse.java index fa0a62c..fde7aa2 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/AuctionHouse.java +++ b/src/main/java/ca/tweetzy/auctionhouse/AuctionHouse.java @@ -9,10 +9,7 @@ import ca.tweetzy.auctionhouse.database.migrations._2_FilterWhitelistMigration; import ca.tweetzy.auctionhouse.economy.EconomyManager; import ca.tweetzy.auctionhouse.listeners.AuctionListeners; import ca.tweetzy.auctionhouse.listeners.PlayerListeners; -import ca.tweetzy.auctionhouse.managers.AuctionItemManager; -import ca.tweetzy.auctionhouse.managers.AuctionPlayerManager; -import ca.tweetzy.auctionhouse.managers.FilterManager; -import ca.tweetzy.auctionhouse.managers.TransactionManager; +import ca.tweetzy.auctionhouse.managers.*; import ca.tweetzy.auctionhouse.settings.LocaleSettings; import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.auctionhouse.tasks.AutoSaveTask; @@ -76,6 +73,9 @@ public class AuctionHouse extends TweetyPlugin { @Getter private FilterManager filterManager; + @Getter + private AuctionBanManager auctionBanManager; + @Getter private DatabaseConnector databaseConnector; @@ -146,6 +146,10 @@ public class AuctionHouse extends TweetyPlugin { this.filterManager = new FilterManager(); this.filterManager.loadItems(Settings.DATABASE_USE.getBoolean()); + // load the bans + this.auctionBanManager = new AuctionBanManager(); + this.auctionBanManager.loadBans(Settings.DATABASE_USE.getBoolean()); + // gui manager this.guiManager.init(); @@ -165,7 +169,9 @@ public class AuctionHouse extends TweetyPlugin { new CommandFilter(), new CommandUpload(), new CommandStatus(), - new CommandAdmin() + new CommandAdmin(), + new CommandBan(), + new CommandUnban() ); // start the auction tick task @@ -187,6 +193,7 @@ public class AuctionHouse extends TweetyPlugin { this.auctionItemManager.saveItems(Settings.DATABASE_USE.getBoolean(), false); this.transactionManager.saveTransactions(Settings.DATABASE_USE.getBoolean(), false); this.filterManager.saveFilterWhitelist(Settings.DATABASE_USE.getBoolean(), false); + this.auctionBanManager.saveBans(Settings.DATABASE_USE.getBoolean(), false); } @Override diff --git a/src/main/java/ca/tweetzy/auctionhouse/api/AuctionAPI.java b/src/main/java/ca/tweetzy/auctionhouse/api/AuctionAPI.java index 2e99d34..0dd0c6a 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/api/AuctionAPI.java +++ b/src/main/java/ca/tweetzy/auctionhouse/api/AuctionAPI.java @@ -25,11 +25,8 @@ import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.List; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -300,6 +297,18 @@ public class AuctionAPI { return false; } + /** + * Checks whether a sentence matches the format to convert it into seconds + * + * @param sentence is the string being checked + * @return true if the string matches the time format + */ + public boolean isValidTimeString(String sentence) { + Pattern pattern = Pattern.compile("([0-9]){1,10}(s|m|h|d|y){1}", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(sentence); + return matcher.matches(); + } + /** * Used to format numbers with decimals and commas * @@ -364,6 +373,13 @@ public class AuctionAPI { return total; } + /** + * Used to get any items that are similar to the provided stack in a player's inventory + * + * @param player is the player being checked + * @param stack the item stack is being looked for + * @return all the items that are similar to the stack + */ public List getSimilarItemsFromInventory(Player player, ItemStack stack) { List items = new ArrayList<>(); for (int i = 0; i < player.getInventory().getSize(); i++) { @@ -412,6 +428,13 @@ public class AuctionAPI { } } + /** + * Used to create an item bundle + * + * @param baseItem is the base item of the bundle (original) + * @param items is the items that should be added to the bundle + * @return an item stack with all the items saved in NBT tags + */ public ItemStack createBundledItem(ItemStack baseItem, ItemStack... items) { Objects.requireNonNull(items, "Cannot create a bundled item with no items"); ItemStack item = ConfigurationItemHelper.createConfigurationItem(Settings.ITEM_BUNDLE_ITEM.getString(), Settings.ITEM_BUNDLE_NAME.getString(), Settings.ITEM_BUNDLE_LORE.getStringList(), new HashMap() {{ @@ -430,8 +453,30 @@ public class AuctionAPI { return item; } - public static Predicate distinctByKey(Function keyExtractor) { - Set seen = ConcurrentHashMap.newKeySet(); - return t -> seen.add(keyExtractor.apply(t)); + /** + * Take a string like 5d and convert it into seconds + * Valid suffixes: m, d, w, mn, y + * + * @param time is the string time that will be converted + * @return the total amount of seconds + */ + public long getSecondsFromString(String time) { + time = time.toLowerCase(); + char suffix = time.charAt(time.length() - 1); + int amount = Character.getNumericValue(time.charAt(time.length() - 2)); + switch(suffix) { + case 's': + return amount; + case 'm': + return (long) amount * 60; + case 'h': + return (long) amount * 3600; + case 'd': + return (long) amount * 3600 * 24; + case 'y': + return (long) amount * 3600 * 24 * 365; + default: + return 0L; + } } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/api/events/AuctionBanPlayerEvent.java b/src/main/java/ca/tweetzy/auctionhouse/api/events/AuctionBanPlayerEvent.java new file mode 100644 index 0000000..8c7ea42 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/api/events/AuctionBanPlayerEvent.java @@ -0,0 +1,50 @@ +package ca.tweetzy.auctionhouse.api.events; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.UUID; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 3:38 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ + +@Getter +@Setter +public class AuctionBanPlayerEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + + private Player banner; + private UUID bannedPlayerUUID; + private String reason; + private long seconds; + + public AuctionBanPlayerEvent(Player banner, UUID bannedPlayerUUID, String reason, long seconds, boolean async) { + super(async); + this.banner = banner; + this.bannedPlayerUUID = bannedPlayerUUID; + this.reason = reason; + this.seconds = seconds; + } + + public AuctionBanPlayerEvent(Player banner, UUID bannedPlayerUUID, String reason, long seconds) { + this(banner, bannedPlayerUUID, reason, seconds, true); + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionBan.java b/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionBan.java new file mode 100644 index 0000000..0623926 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionBan.java @@ -0,0 +1,29 @@ +package ca.tweetzy.auctionhouse.auction; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.UUID; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 2:25 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ + +@Getter +@Setter +public class AuctionBan implements Serializable { + + private UUID bannedPlayer; + private String reason; + private long time; + + public AuctionBan(UUID bannedPlayer, String reason, long time) { + this.bannedPlayer = bannedPlayer; + this.reason = reason; + this.time = time; + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandActive.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandActive.java index 6a7384f..31be300 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandActive.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandActive.java @@ -5,6 +5,7 @@ import ca.tweetzy.auctionhouse.auction.AuctionPlayer; import ca.tweetzy.auctionhouse.guis.GUIActiveAuctions; import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -26,6 +27,11 @@ public class CommandActive extends AbstractCommand { @Override protected ReturnType runCommand(CommandSender sender, String... args) { Player player = (Player) sender; + + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + if (AuctionHouse.getInstance().getAuctionPlayerManager().getPlayer(player.getUniqueId()) == null) { AuctionHouse.getInstance().getLocale().newMessage(TextUtils.formatText("&cCould not find auction player instance for&f: &e" + player.getName() + "&c creating one now.")).sendPrefixedMessage(Bukkit.getConsoleSender()); AuctionHouse.getInstance().getAuctionPlayerManager().addPlayer(new AuctionPlayer(player)); diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAuctionHouse.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAuctionHouse.java index 999a96f..dfe23aa 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAuctionHouse.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAuctionHouse.java @@ -5,6 +5,7 @@ import ca.tweetzy.auctionhouse.auction.AuctionPlayer; import ca.tweetzy.auctionhouse.guis.GUIAuctionHouse; import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -28,6 +29,11 @@ public class CommandAuctionHouse extends AbstractCommand { protected ReturnType runCommand(CommandSender sender, String... args) { if (sender instanceof Player) { Player player = (Player) sender; + + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + if (AuctionHouse.getInstance().getAuctionPlayerManager().getPlayer(player.getUniqueId()) == null) { AuctionHouse.getInstance().getLocale().newMessage(TextUtils.formatText("&cCould not find auction player instance for&f: &e" + player.getName() + "&c creating one now.")).sendPrefixedMessage(Bukkit.getConsoleSender()); AuctionHouse.getInstance().getAuctionPlayerManager().addPlayer(new AuctionPlayer(player)); diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandBan.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandBan.java new file mode 100644 index 0000000..c0bbe25 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandBan.java @@ -0,0 +1,105 @@ +package ca.tweetzy.auctionhouse.commands; + +import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.api.events.AuctionBanPlayerEvent; +import ca.tweetzy.auctionhouse.auction.AuctionBan; +import ca.tweetzy.auctionhouse.guis.GUIBans; +import ca.tweetzy.core.commands.AbstractCommand; +import ca.tweetzy.core.utils.PlayerUtils; +import ca.tweetzy.core.utils.TimeUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 3:05 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class CommandBan extends AbstractCommand { + + public CommandBan() { + super(CommandType.PLAYER_ONLY, "ban"); + } + + @Override + protected ReturnType runCommand(CommandSender sender, String... args) { + Player player = (Player) sender; + if (args.length == 0) { + // Open the bans menu + AuctionHouse.getInstance().getGuiManager().showGUI(player, new GUIBans()); + return ReturnType.SUCCESS; + } + + if (args.length < 3) { + return ReturnType.SYNTAX_ERROR; + } + + Player target = PlayerUtils.findPlayer(args[0]); + String timeString = args[1]; + StringBuilder reason = new StringBuilder(); + for (int i = 2; i < args.length; i++) { + reason.append(args[i]).append(" "); + } + + if (target == null) { + AuctionHouse.getInstance().getLocale().getMessage("general.playernotfound").processPlaceholder("player", args[0]).sendPrefixedMessage(player); + return ReturnType.FAILURE; + } + + if (!AuctionAPI.getInstance().isValidTimeString(timeString)) { + AuctionHouse.getInstance().getLocale().getMessage("general.invalidtimestring").sendPrefixedMessage(player); + return ReturnType.FAILURE; + } + + if (reason.toString().length() == 0) { + AuctionHouse.getInstance().getLocale().getMessage("bans.nobanreason").sendPrefixedMessage(player); + return ReturnType.FAILURE; + } + + if (AuctionHouse.getInstance().getAuctionBanManager().getBans().containsKey(target.getUniqueId())) { + AuctionHouse.getInstance().getLocale().getMessage("bans.playeralreadybanned").processPlaceholder("player", args[0]).sendPrefixedMessage(player); + return ReturnType.FAILURE; + } + + long bannedSeconds = AuctionAPI.getInstance().getSecondsFromString(timeString); + + AuctionBanPlayerEvent auctionBanPlayerEvent = new AuctionBanPlayerEvent(player, target.getUniqueId(), reason.toString().trim(), bannedSeconds, false); + Bukkit.getServer().getPluginManager().callEvent(auctionBanPlayerEvent); + if (auctionBanPlayerEvent.isCancelled()) return ReturnType.FAILURE; + + AuctionBan auctionBan = new AuctionBan(target.getUniqueId(), reason.toString().trim(), System.currentTimeMillis() + bannedSeconds * 1000); + AuctionHouse.getInstance().getAuctionBanManager().addBan(auctionBan); + AuctionHouse.getInstance().getLocale().getMessage("bans.bannedplayer").processPlaceholder("player", args[0]).processPlaceholder("ban_amount", TimeUtils.makeReadable(bannedSeconds * 1000)).sendPrefixedMessage(player); + AuctionHouse.getInstance().getLocale().getMessage("bans.remainingtime").processPlaceholder("ban_amount", TimeUtils.makeReadable(bannedSeconds * 1000)).sendPrefixedMessage(target); + return ReturnType.SUCCESS; + } + + @Override + protected List onTab(CommandSender sender, String... args) { + if (args.length == 1) return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); + if (args.length == 2) return Arrays.asList("1m", "1h", "1d", "1y"); + return null; + } + + @Override + public String getPermissionNode() { + return "auctionhouse.cmd.ban"; + } + + @Override + public String getSyntax() { + return AuctionHouse.getInstance().getLocale().getMessage("commands.syntax.ban").getMessage(); + } + + @Override + public String getDescription() { + return AuctionHouse.getInstance().getLocale().getMessage("commands.description.ban").getMessage(); + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandExpired.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandExpired.java index 3eb0a49..6fb92b6 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandExpired.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandExpired.java @@ -5,6 +5,7 @@ import ca.tweetzy.auctionhouse.auction.AuctionPlayer; import ca.tweetzy.auctionhouse.guis.GUIExpiredItems; import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -26,6 +27,11 @@ public class CommandExpired extends AbstractCommand { @Override protected ReturnType runCommand(CommandSender sender, String... args) { Player player = (Player) sender; + + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + if (AuctionHouse.getInstance().getAuctionPlayerManager().getPlayer(player.getUniqueId()) == null) { AuctionHouse.getInstance().getLocale().newMessage(TextUtils.formatText("&cCould not find auction player instance for&f: &e" + player.getName() + "&c creating one now.")).sendPrefixedMessage(Bukkit.getConsoleSender()); AuctionHouse.getInstance().getAuctionPlayerManager().addPlayer(new AuctionPlayer(player)); diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSearch.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSearch.java index 3d8c708..471c25b 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSearch.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSearch.java @@ -5,6 +5,7 @@ import ca.tweetzy.auctionhouse.auction.AuctionPlayer; import ca.tweetzy.auctionhouse.guis.GUIAuctionHouse; import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -28,6 +29,10 @@ public class CommandSearch extends AbstractCommand { if (args.length <= 0) return ReturnType.SYNTAX_ERROR; Player player = (Player) sender; + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + StringBuilder builder = new StringBuilder(); for (String arg : args) { builder.append(arg).append(" "); diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSell.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSell.java index 5502b95..6dbf460 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSell.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandSell.java @@ -13,10 +13,9 @@ import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.compatibility.CompatibleHand; import ca.tweetzy.core.compatibility.XMaterial; -import ca.tweetzy.core.input.ChatPrompt; import ca.tweetzy.core.utils.NumberUtils; import ca.tweetzy.core.utils.PlayerUtils; -import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import ca.tweetzy.core.utils.nms.NBTEditor; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -44,6 +43,11 @@ public class CommandSell extends AbstractCommand { @Override protected ReturnType runCommand(CommandSender sender, String... args) { Player player = (Player) sender; + + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + AuctionPlayer auctionPlayer = AuctionHouse.getInstance().getAuctionPlayerManager().getPlayer(player.getUniqueId()); ItemStack originalItem = PlayerHelper.getHeldItem(player).clone(); @@ -210,6 +214,16 @@ public class CommandSell extends AbstractCommand { false ); + if (Settings.TAX_ENABLED.getBoolean() && Settings.TAX_CHARGE_LISTING_FEE.getBoolean()) { + if (!AuctionHouse.getInstance().getEconomyManager().has(player, Settings.TAX_LISTING_FEE.getDouble())) { + AuctionHouse.getInstance().getLocale().getMessage("auction.tax.cannotpaylistingfee").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(player); + return ReturnType.FAILURE; + } + AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(player, Settings.TAX_LISTING_FEE.getDouble()); + AuctionHouse.getInstance().getLocale().getMessage("auction.tax.paidlistingfee").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(player); + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(player); + } + AuctionStartEvent startEvent = new AuctionStartEvent(player, auctionItem); Bukkit.getServer().getPluginManager().callEvent(startEvent); if (startEvent.isCancelled()) return ReturnType.FAILURE; diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandTransactions.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandTransactions.java index 84d2738..21a5a3b 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandTransactions.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandTransactions.java @@ -3,6 +3,7 @@ package ca.tweetzy.auctionhouse.commands; import ca.tweetzy.auctionhouse.AuctionHouse; import ca.tweetzy.auctionhouse.guis.transaction.GUITransactionList; import ca.tweetzy.core.commands.AbstractCommand; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -23,6 +24,11 @@ public class CommandTransactions extends AbstractCommand { @Override protected ReturnType runCommand(CommandSender sender, String... args) { Player player = (Player) sender; + + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(player)) { + return ReturnType.FAILURE; + } + AuctionHouse.getInstance().getGuiManager().showGUI(player, new GUITransactionList(AuctionHouse.getInstance().getAuctionPlayerManager().getPlayer(player.getUniqueId()))); return ReturnType.SUCCESS; } diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandUnban.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandUnban.java new file mode 100644 index 0000000..c49c9c4 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandUnban.java @@ -0,0 +1,63 @@ +package ca.tweetzy.auctionhouse.commands; + +import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.core.commands.AbstractCommand; +import ca.tweetzy.core.utils.PlayerUtils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 4:11 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class CommandUnban extends AbstractCommand { + + public CommandUnban() { + super(CommandType.CONSOLE_OK, "unban"); + } + + @Override + protected ReturnType runCommand(CommandSender sender, String... args) { + if (args.length != 1) return ReturnType.SYNTAX_ERROR; + Player target = PlayerUtils.findPlayer(args[0]); + + if (target == null) { + AuctionHouse.getInstance().getLocale().getMessage("general.playernotfound").processPlaceholder("player", args[0]).sendPrefixedMessage(sender); + return ReturnType.FAILURE; + } + + if (!AuctionHouse.getInstance().getAuctionBanManager().getBans().containsKey(target.getUniqueId())) { + AuctionHouse.getInstance().getLocale().getMessage("bans.playernotbanned").processPlaceholder("player", args[0]).sendPrefixedMessage(sender); + return ReturnType.FAILURE; + } + + AuctionHouse.getInstance().getAuctionBanManager().removeBan(target.getUniqueId()); + AuctionHouse.getInstance().getLocale().getMessage("bans.playerunbanned").processPlaceholder("player", args[0]).sendPrefixedMessage(sender); + AuctionHouse.getInstance().getLocale().getMessage("bans.unbanned").sendPrefixedMessage(target); + return ReturnType.SUCCESS; + } + + @Override + protected List onTab(CommandSender sender, String... args) { + return null; + } + + @Override + public String getPermissionNode() { + return "auctionhouse.cmd.unban"; + } + + @Override + public String getSyntax() { + return AuctionHouse.getInstance().getLocale().getMessage("commands.syntax.unban").getMessage(); + } + + @Override + public String getDescription() { + return AuctionHouse.getInstance().getLocale().getMessage("commands.description.unban").getMessage(); + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java b/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java index d501438..2b905c1 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java +++ b/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java @@ -1,6 +1,7 @@ package ca.tweetzy.auctionhouse.database; import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.auction.AuctionBan; import ca.tweetzy.auctionhouse.auction.AuctionFilterItem; import ca.tweetzy.auctionhouse.auction.AuctionItem; import ca.tweetzy.auctionhouse.transaction.Transaction; @@ -14,6 +15,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.function.Consumer; /** @@ -67,6 +69,52 @@ public class DataManager extends DataManagerAbstract { } } + public void saveBans(List bans, boolean async) { + if (async) { + this.async(() -> this.databaseConnector.connect(connection -> { + String saveItems = "INSERT IGNORE INTO " + this.getTablePrefix() + "bans SET user = ?, reason = ?, time = ?"; + String truncate = "TRUNCATE TABLE " + this.getTablePrefix() + "bans"; + try (PreparedStatement statement = connection.prepareStatement(truncate)) { + statement.execute(); + } + + PreparedStatement statement = connection.prepareStatement(saveItems); + bans.forEach(ban -> { + try { + statement.setString(1, ban.getBannedPlayer().toString()); + statement.setString(2, ban.getReason()); + statement.setLong(3, ban.getTime()); + statement.addBatch(); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + statement.executeBatch(); + })); + } else { + this.databaseConnector.connect(connection -> { + String saveItems = "INSERT IGNORE INTO " + this.getTablePrefix() + "bans SET user = ?, reason = ?, time = ?"; + String truncate = "TRUNCATE TABLE " + this.getTablePrefix() + "bans"; + try (PreparedStatement statement = connection.prepareStatement(truncate)) { + statement.execute(); + } + + PreparedStatement statement = connection.prepareStatement(saveItems); + bans.forEach(ban -> { + try { + statement.setString(1, ban.getBannedPlayer().toString()); + statement.setString(2, ban.getReason()); + statement.setLong(3, ban.getTime()); + statement.addBatch(); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + statement.executeBatch(); + }); + } + } + public void saveFilterWhitelist(List filterItems, boolean async) { if (async) { this.async(() -> this.databaseConnector.connect(connection -> { @@ -151,6 +199,25 @@ public class DataManager extends DataManagerAbstract { } } + public void getBans(Consumer> callback) { + ArrayList bans = new ArrayList<>(); + this.async(() -> this.databaseConnector.connect(connection -> { + String select = "SELECT * FROM " + this.getTablePrefix() + "bans"; + + try (Statement statement = connection.createStatement()) { + ResultSet result = statement.executeQuery(select); + while (result.next()) { + bans.add(new AuctionBan( + UUID.fromString(result.getString("user")), + result.getString("reason"), + result.getLong("time") + )); + } + } + this.sync(() -> callback.accept(bans)); + })); + } + public void getTransactions(Consumer> callback) { ArrayList transactions = new ArrayList<>(); this.async(() -> this.databaseConnector.connect(connection -> { diff --git a/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_3_BansMigration.java b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_3_BansMigration.java new file mode 100644 index 0000000..72d7069 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_3_BansMigration.java @@ -0,0 +1,35 @@ +package ca.tweetzy.auctionhouse.database.migrations; + +import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.core.database.DataMigration; +import ca.tweetzy.core.database.MySQLConnector; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 2:21 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class _3_BansMigration extends DataMigration { + + public _3_BansMigration() { + super(3); + } + + @Override + public void migrate(Connection connection, String tablePrefix) throws SQLException { + String autoIncrement = AuctionHouse.getInstance().getDatabaseConnector() instanceof MySQLConnector ? " AUTO_INCREMENT" : ""; + + try (Statement statement = connection.createStatement()) { + statement.execute("CREATE TABLE " + tablePrefix + "bans (" + + "id INTEGER PRIMARY KEY" + autoIncrement + ", " + + "user VARCHAR(36) NOT NULL, " + + "reason TEXT NOT NULL, " + + "time BigInt NOT NULL )"); + } + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java index 476bb41..2a08c73 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java @@ -10,11 +10,13 @@ import ca.tweetzy.auctionhouse.guis.transaction.GUITransactionList; import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper; import ca.tweetzy.auctionhouse.managers.SoundManager; import ca.tweetzy.auctionhouse.settings.Settings; +import ca.tweetzy.core.commands.AbstractCommand; import ca.tweetzy.core.compatibility.ServerVersion; import ca.tweetzy.core.compatibility.XMaterial; import ca.tweetzy.core.gui.Gui; import ca.tweetzy.core.gui.events.GuiClickEvent; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import ca.tweetzy.core.utils.items.TItemBuilder; import ca.tweetzy.core.utils.nms.NBTEditor; import org.bukkit.Bukkit; @@ -50,8 +52,18 @@ public class GUIAuctionHouse extends Gui { setAllowShiftClick(false); draw(); + setOnOpen(open -> { + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(open.player)) { + open.gui.exit(); + return; + } + + if (Settings.AUTO_REFRESH_AUCTION_PAGES.getBoolean()) { + makeMess(); + } + }); + if (Settings.AUTO_REFRESH_AUCTION_PAGES.getBoolean()) { - setOnOpen(e -> makeMess()); setOnClose(e -> cleanup()); } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIBans.java b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIBans.java new file mode 100644 index 0000000..9e3a4e9 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIBans.java @@ -0,0 +1,81 @@ +package ca.tweetzy.auctionhouse.guis; + +import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.auction.AuctionBan; +import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper; +import ca.tweetzy.auctionhouse.managers.SoundManager; +import ca.tweetzy.auctionhouse.settings.Settings; +import ca.tweetzy.core.gui.Gui; +import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; +import ca.tweetzy.core.utils.items.TItemBuilder; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 22 2021 + * Time Created: 12:16 a.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class GUIBans extends Gui { + + private List bans; + private BukkitTask task; + + public GUIBans() { + setTitle(TextUtils.formatText(Settings.GUI_BANS_TITLE.getString())); + setDefaultItem(Settings.GUI_BANS_BG_ITEM.getMaterial().parseItem()); + setUseLockedCells(true); + setAcceptsItems(false); + setAllowDrops(false); + setRows(6); + draw(); + setOnOpen(open -> this.task = Bukkit.getServer().getScheduler().runTaskTimerAsynchronously(AuctionHouse.getInstance(), this::drawItems, 0L, 20L)); + setOnClose(close -> this.task.cancel()); + } + + private void draw() { + reset(); + setButton(5, 4, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_CLOSE_BTN_ITEM.getString(), Settings.GUI_CLOSE_BTN_NAME.getString(), Settings.GUI_CLOSE_BTN_LORE.getStringList(), null), e -> e.gui.close()); + drawItems(); + } + + private void drawItems() { + AuctionHouse.newChain().asyncFirst(() -> { + this.bans = new ArrayList<>(AuctionHouse.getInstance().getAuctionBanManager().getBans().values()); + return this.bans.stream().skip((page - 1) * 45L).limit(45L).collect(Collectors.toList()); + }).asyncLast((data) -> { + pages = (int) Math.max(1, Math.ceil(this.bans.size() / (double) 45L)); + setPrevPage(5, 3, new TItemBuilder(Objects.requireNonNull(Settings.GUI_BACK_BTN_ITEM.getMaterial().parseMaterial())).setName(Settings.GUI_BACK_BTN_NAME.getString()).setLore(Settings.GUI_BACK_BTN_LORE.getStringList()).toItemStack()); + setNextPage(5, 5, new TItemBuilder(Objects.requireNonNull(Settings.GUI_NEXT_BTN_ITEM.getMaterial().parseMaterial())).setName(Settings.GUI_NEXT_BTN_NAME.getString()).setLore(Settings.GUI_NEXT_BTN_LORE.getStringList()).toItemStack()); + setOnPage(e -> draw()); + + int slot = 0; + for (AuctionBan ban : data) { + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(ban.getBannedPlayer()); + setButton(slot++, ConfigurationItemHelper.createConfigurationItem(AuctionAPI.getInstance().getPlayerHead(offlinePlayer.getName()), Settings.GUI_BANS_BAN_NAME.getString(), Settings.GUI_BANS_BAN_LORE.getStringList(), new HashMap(){{ + put("%player_name%", offlinePlayer.getName()); + put("%ban_reason%", ban.getReason()); + put("%ban_amount%", TimeUtils.makeReadable(ban.getTime() - System.currentTimeMillis())); + }}), ClickType.RIGHT, e -> { + AuctionHouse.getInstance().getAuctionBanManager().removeBan(ban.getBannedPlayer()); + AuctionHouse.getInstance().getLocale().getMessage("bans.playerunbanned").processPlaceholder("player", offlinePlayer.getName()).sendPrefixedMessage(e.player); + if (offlinePlayer.isOnline()) { + AuctionHouse.getInstance().getLocale().getMessage("bans.unbanned").processPlaceholder("player", offlinePlayer.getName()).sendPrefixedMessage(offlinePlayer.getPlayer()); + } + draw(); + }); + } + }).execute(); + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/GUISellItem.java b/src/main/java/ca/tweetzy/auctionhouse/guis/GUISellItem.java index 1079846..02eca07 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/guis/GUISellItem.java +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/GUISellItem.java @@ -17,6 +17,7 @@ import ca.tweetzy.core.input.ChatPrompt; import ca.tweetzy.core.utils.NumberUtils; import ca.tweetzy.core.utils.PlayerUtils; import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; import org.bukkit.Bukkit; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; @@ -54,8 +55,8 @@ public class GUISellItem extends Gui { setDefaultItem(Settings.GUI_SELL_BG_ITEM.getMaterial().parseItem()); setUseLockedCells(true); setAllowDrops(false); + setAllowClose(false); setRows(5); - draw(); setOnOpen(open -> { // Check if they are already using a sell gui @@ -64,27 +65,40 @@ public class GUISellItem extends Gui { open.gui.exit(); } + if (AuctionHouse.getInstance().getAuctionBanManager().checkAndHandleBan(open.player)) { + open.gui.exit(); + return; + } + ItemStack held = AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().get(open.player.getUniqueId()); - setAcceptsItems(held.getType() == XMaterial.AIR.parseMaterial()); + if (held == null) { + setAcceptsItems(true); + } else { + setAcceptsItems(held.getType() == XMaterial.AIR.parseMaterial()); + } + + AuctionHouse.getInstance().getAuctionPlayerManager().addToUsingSellGUI(open.player.getUniqueId()); }); setOnClose(close -> { - ItemStack toGiveBack = AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().get(close.player.getUniqueId()); - if (toGiveBack != null && toGiveBack.getType() != XMaterial.AIR.parseMaterial()) { - PlayerUtils.giveItem(close.player, toGiveBack); - } else { - if (this.itemToBeListed == null || this.itemToBeListed.getType() == XMaterial.AIR.parseMaterial()) { - PlayerUtils.giveItem(close.player, getItem(1, 4)); + if (!AuctionHouse.getInstance().getAuctionPlayerManager().getUsingSellGUI().contains(close.player.getUniqueId())) { + ItemStack toGiveBack = AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().get(close.player.getUniqueId()); + if (toGiveBack != null && toGiveBack.getType() != XMaterial.AIR.parseMaterial()) { + PlayerUtils.giveItem(close.player, toGiveBack); } else { - PlayerUtils.giveItem(close.player, this.itemToBeListed); + if (this.itemToBeListed == null || this.itemToBeListed.getType() == XMaterial.AIR.parseMaterial()) { + PlayerUtils.giveItem(close.player, getItem(1, 4)); + } else { + PlayerUtils.giveItem(close.player, this.itemToBeListed); + } } + AuctionHouse.getInstance().getAuctionPlayerManager().removeItemFromSellHolding(close.player.getUniqueId()); } - - AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().remove(close.player.getUniqueId()); }); setUnlocked(1, 4); setUnlockedRange(45, 89); + draw(); } public GUISellItem(AuctionPlayer auctionPlayer, ItemStack itemToBeListed) { @@ -111,7 +125,8 @@ public class GUISellItem extends Gui { put("%buy_now_price%", AuctionAPI.getInstance().formatNumber(buyNowPrice)); }}), ClickType.LEFT, e -> { setTheItemToBeListed(); - e.gui.exit(); + setAllowClose(true); + e.gui.close(); ChatPrompt.showPrompt(AuctionHouse.getInstance(), this.auctionPlayer.getPlayer(), TextUtils.formatText(AuctionHouse.getInstance().getLocale().getMessage("prompts.enter new buy now price").getMessage()), chat -> { String msg = chat.getMessage(); @@ -133,7 +148,8 @@ public class GUISellItem extends Gui { put("%starting_bid_price%", AuctionAPI.getInstance().formatNumber(bidStartPrice)); }}), ClickType.LEFT, e -> { setTheItemToBeListed(); - e.gui.exit(); + setAllowClose(true); + e.gui.close(); ChatPrompt.showPrompt(AuctionHouse.getInstance(), this.auctionPlayer.getPlayer(), TextUtils.formatText(AuctionHouse.getInstance().getLocale().getMessage("prompts.enter new starting bid").getMessage()), chat -> { String msg = chat.getMessage(); if (validateChatNumber(msg, Settings.MIN_AUCTION_START_PRICE.getDouble())) { @@ -147,7 +163,8 @@ public class GUISellItem extends Gui { put("%bid_increment_price%", AuctionAPI.getInstance().formatNumber(bidIncrementPrice)); }}), ClickType.LEFT, e -> { setTheItemToBeListed(); - e.gui.exit(); + setAllowClose(true); + e.gui.close(); ChatPrompt.showPrompt(AuctionHouse.getInstance(), this.auctionPlayer.getPlayer(), TextUtils.formatText(AuctionHouse.getInstance().getLocale().getMessage("prompts.enter new bid increment").getMessage()), chat -> { String msg = chat.getMessage(); if (validateChatNumber(msg, Settings.MIN_AUCTION_INCREMENT_PRICE.getDouble())) { @@ -165,6 +182,12 @@ public class GUISellItem extends Gui { } + setButton(3, 4, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_CLOSE_BTN_ITEM.getString(), Settings.GUI_CLOSE_BTN_NAME.getString(), Settings.GUI_CLOSE_BTN_LORE.getStringList(), null), e -> { + AuctionHouse.getInstance().getAuctionPlayerManager().removeFromUsingSellGUI(e.player.getUniqueId()); + setAllowClose(true); + e.gui.close(); + }); + if (Settings.ALLOW_USAGE_OF_BID_SYSTEM.getBoolean()) { setButton(3, 5, ConfigurationItemHelper.createConfigurationItem(this.isBiddingItem ? Settings.GUI_SELL_ITEMS_BIDDING_ENABLED_ITEM.getString() : Settings.GUI_SELL_ITEMS_BIDDING_DISABLED_ITEM.getString(), this.isBiddingItem ? Settings.GUI_SELL_ITEMS_BIDDING_ENABLED_NAME.getString() : Settings.GUI_SELL_ITEMS_BIDDING_DISABLED_NAME.getString(), this.isBiddingItem ? Settings.GUI_SELL_ITEMS_BIDDING_ENABLED_LORE.getStringList() : Settings.GUI_SELL_ITEMS_BIDDING_DISABLED_LORE.getStringList(), null), e -> { this.isBiddingItem = !this.isBiddingItem; @@ -202,13 +225,26 @@ public class GUISellItem extends Gui { Bukkit.getServer().getPluginManager().callEvent(auctionStartEvent); if (auctionStartEvent.isCancelled()) return; + if (Settings.TAX_ENABLED.getBoolean() && Settings.TAX_CHARGE_LISTING_FEE.getBoolean()) { + if (!AuctionHouse.getInstance().getEconomyManager().has(e.player, Settings.TAX_LISTING_FEE.getDouble())) { + AuctionHouse.getInstance().getLocale().getMessage("auction.tax.cannotpaylistingfee").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(e.player); + return; + } + AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(e.player, Settings.TAX_LISTING_FEE.getDouble()); + AuctionHouse.getInstance().getLocale().getMessage("auction.tax.paidlistingfee").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(e.player); + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", String.format("%,.2f", Settings.TAX_LISTING_FEE.getDouble())).sendPrefixedMessage(e.player); + } + AuctionHouse.getInstance().getAuctionItemManager().addItem(auctionItem); SoundManager.getInstance().playSound(e.player, Settings.SOUNDS_LISTED_ITEM_ON_AUCTION_HOUSE.getString(), 1.0F, 1.0F); AuctionHouse.getInstance().getAuctionPlayerManager().removeItemFromSellHolding(e.player.getUniqueId()); + AuctionHouse.getInstance().getAuctionPlayerManager().removeFromUsingSellGUI(e.player.getUniqueId()); if (Settings.OPEN_MAIN_AUCTION_HOUSE_AFTER_MENU_LIST.getBoolean()) { + setAllowClose(true); e.manager.showGUI(e.player, new GUIAuctionHouse(this.auctionPlayer)); } else { + setAllowClose(true); e.gui.exit(); } diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/confirmation/GUIConfirmPurchase.java b/src/main/java/ca/tweetzy/auctionhouse/guis/confirmation/GUIConfirmPurchase.java index 453cbd5..1459c05 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/guis/confirmation/GUIConfirmPurchase.java +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/confirmation/GUIConfirmPurchase.java @@ -112,8 +112,11 @@ public class GUIConfirmPurchase extends Gui { return; } + double buyNowPrice = this.buyingSpecificQuantity ? this.purchaseQuantity * this.pricePerItem : located.getBasePrice(); + double tax = Settings.TAX_ENABLED.getBoolean() ? (Settings.TAX_SALES_TAX_BUY_NOW_PERCENTAGE.getDouble() / 100) * buyNowPrice : 0D; + // Check economy - if (!AuctionHouse.getInstance().getEconomyManager().has(e.player, this.buyingSpecificQuantity ? this.purchaseQuantity * this.pricePerItem : located.getBasePrice())) { + if (!AuctionHouse.getInstance().getEconomyManager().has(e.player, buyNowPrice + (Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? tax : 0D))) { AuctionHouse.getInstance().getLocale().getMessage("general.notenoughmoney").sendPrefixedMessage(e.player); SoundManager.getInstance().playSound(e.player, Settings.SOUNDS_NOT_ENOUGH_MONEY.getString(), 1.0F, 1.0F); e.gui.close(); @@ -135,19 +138,19 @@ public class GUIConfirmPurchase extends Gui { if (item.getAmount() - this.purchaseQuantity >= 1) { item.setAmount(item.getAmount() - this.purchaseQuantity); located.setRawItem(AuctionAPI.getInstance().serializeItem(item)); - located.setBasePrice(located.getBasePrice() - this.purchaseQuantity * this.pricePerItem); + located.setBasePrice(located.getBasePrice() - buyNowPrice); item.setAmount(this.purchaseQuantity); - transferFunds(e.player, this.purchaseQuantity * this.pricePerItem); + transferFunds(e.player, buyNowPrice); } else { - transferFunds(e.player, located.getBasePrice()); + transferFunds(e.player, buyNowPrice); AuctionHouse.getInstance().getAuctionItemManager().sendToGarbage(located); } PlayerUtils.giveItem(e.player, item); - sendMessages(e, located, true, this.purchaseQuantity * this.pricePerItem); + sendMessages(e, located, true, buyNowPrice); } else { - transferFunds(e.player, located.getBasePrice()); + transferFunds(e.player, buyNowPrice); AuctionHouse.getInstance().getAuctionItemManager().sendToGarbage(located); PlayerUtils.giveItem(e.player, AuctionAPI.getInstance().deserializeItem(located.getRawItem())); sendMessages(e, located, false, 0); @@ -183,19 +186,24 @@ public class GUIConfirmPurchase extends Gui { } private void transferFunds(Player from, double amount) { - AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(from, amount); - AuctionHouse.getInstance().getEconomyManager().depositPlayer(Bukkit.getOfflinePlayer(this.auctionItem.getOwner()), amount); + double tax = Settings.TAX_ENABLED.getBoolean() ? (Settings.TAX_SALES_TAX_BUY_NOW_PERCENTAGE.getDouble() / 100) * amount : 0D; + + AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(from, Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? amount + tax : amount); + AuctionHouse.getInstance().getEconomyManager().depositPlayer(Bukkit.getOfflinePlayer(this.auctionItem.getOwner()), Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? amount : amount - tax); } private void sendMessages(GuiClickEvent e, AuctionItem located, boolean overwritePrice, double price) { - AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(overwritePrice ? price : located.getBasePrice())).sendPrefixedMessage(e.player); + double totalPrice = overwritePrice ? price : located.getBasePrice(); + double tax = Settings.TAX_ENABLED.getBoolean() ? (Settings.TAX_SALES_TAX_BUY_NOW_PERCENTAGE.getDouble() / 100) * totalPrice : 0D; + + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? totalPrice - tax : totalPrice)).sendPrefixedMessage(e.player); if (Bukkit.getOfflinePlayer(located.getOwner()).isOnline()) { AuctionHouse.getInstance().getLocale().getMessage("auction.itemsold") .processPlaceholder("item", WordUtils.capitalizeFully(AuctionAPI.getInstance().deserializeItem(located.getRawItem()).getType().name().replace("_", " "))) - .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(overwritePrice ? price : located.getBasePrice())) + .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? totalPrice : totalPrice - tax)) .processPlaceholder("buyer_name", e.player.getName()) .sendPrefixedMessage(Bukkit.getOfflinePlayer(located.getOwner()).getPlayer()); - AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyadd").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(overwritePrice ? price : located.getBasePrice())).sendPrefixedMessage(Bukkit.getOfflinePlayer(located.getOwner()).getPlayer()); + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyadd").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? totalPrice : totalPrice - tax)).sendPrefixedMessage(Bukkit.getOfflinePlayer(located.getOwner()).getPlayer()); } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionBanManager.java b/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionBanManager.java new file mode 100644 index 0000000..5dfcf01 --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionBanManager.java @@ -0,0 +1,75 @@ +package ca.tweetzy.auctionhouse.managers; + +import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.auction.AuctionBan; +import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.TimeUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 2:27 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class AuctionBanManager { + + private final ConcurrentHashMap bans = new ConcurrentHashMap<>(); + + public void addBan(AuctionBan ban) { + if (ban == null) return; + this.bans.put(ban.getBannedPlayer(), ban); + } + + public void removeBan(UUID player) { + if (player == null) return; + this.bans.remove(player); + } + + public ConcurrentHashMap getBans() { + return this.bans; + } + + public boolean checkAndHandleBan(Player player) { + if (this.bans.containsKey(player.getUniqueId())) { + long time = this.bans.get(player.getUniqueId()).getTime(); + if (System.currentTimeMillis() >= time) { + removeBan(player.getUniqueId()); + return false; + } + AuctionHouse.getInstance().getLocale().getMessage("bans.remainingtime").processPlaceholder("ban_amount", TimeUtils.makeReadable(time - System.currentTimeMillis())).sendPrefixedMessage(player); + return true; + } + return false; + } + + public void loadBans(boolean useDatabase) { + if (useDatabase) { + AuctionHouse.getInstance().getDataManager().getBans(all -> all.forEach(this::addBan)); + } else { + if (AuctionHouse.getInstance().getData().contains("auction bans") && AuctionHouse.getInstance().getData().isList("auction bans")) { + List auctionBans = AuctionHouse.getInstance().getData().getStringList("auction bans").stream().map(AuctionAPI.getInstance()::convertBase64ToObject).map(object -> (AuctionBan) object).collect(Collectors.toList()); + long start = System.currentTimeMillis(); + auctionBans.forEach(this::addBan); + AuctionHouse.getInstance().getLocale().newMessage(TextUtils.formatText(String.format("&aLoaded &2%d &abans(s) in &e%d&fms", auctionBans.size(), System.currentTimeMillis() - start))).sendPrefixedMessage(Bukkit.getConsoleSender()); + } + } + } + + public void saveBans(boolean useDatabase, boolean async) { + if (useDatabase) { + AuctionHouse.getInstance().getDataManager().saveBans(new ArrayList<>(getBans().values()), async); + } else { + AuctionHouse.getInstance().getData().set("auction bans", this.bans.values().stream().map(AuctionAPI.getInstance()::convertToBase64).collect(Collectors.toList())); + AuctionHouse.getInstance().getData().save(); + } + } +} \ No newline at end of file diff --git a/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionPlayerManager.java b/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionPlayerManager.java index ac457e7..1803564 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionPlayerManager.java +++ b/src/main/java/ca/tweetzy/auctionhouse/managers/AuctionPlayerManager.java @@ -6,6 +6,7 @@ import lombok.Getter; import org.bukkit.inventory.ItemStack; import java.util.HashMap; +import java.util.HashSet; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -21,6 +22,7 @@ public class AuctionPlayerManager { private final ConcurrentHashMap auctionPlayers = new ConcurrentHashMap<>(); private final HashMap sellHolding = new HashMap<>(); + private final HashSet usingSellGUI = new HashSet<>(); private final HashMap cooldowns = new HashMap<>(); public void addPlayer(AuctionPlayer auctionPlayer) { @@ -28,6 +30,15 @@ public class AuctionPlayerManager { this.auctionPlayers.put(auctionPlayer.getPlayer().getUniqueId(), auctionPlayer); } + public void addToUsingSellGUI(UUID uuid) { + if (uuid == null) return; + this.usingSellGUI.add(uuid); + } + + public void removeFromUsingSellGUI(UUID uuid) { + this.usingSellGUI.remove(uuid); + } + public void addItemToSellHolding(UUID uuid, ItemStack itemStack) { if (itemStack == null) return; this.sellHolding.put(uuid, itemStack); diff --git a/src/main/java/ca/tweetzy/auctionhouse/settings/LocaleSettings.java b/src/main/java/ca/tweetzy/auctionhouse/settings/LocaleSettings.java index 7b82974..023279c 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/settings/LocaleSettings.java +++ b/src/main/java/ca/tweetzy/auctionhouse/settings/LocaleSettings.java @@ -19,6 +19,7 @@ public class LocaleSettings { languageNodes.put("general.prefix", "&8[&eAuctionHouse&8]"); languageNodes.put("general.notanumber", "&cThe entry &4%value% &cis not a valid number!"); languageNodes.put("general.locked", "&cThe Auction House is currently locked!"); + languageNodes.put("general.playernotfound", "&cCould not find the player &4%player%"); languageNodes.put("general.notenoughmoney", "&cYou do not have enough money!"); languageNodes.put("general.cantbidonown", "&cYou cannot bid on your own item!"); languageNodes.put("general.cantbuyown", "&cYou cannot buy your own item!"); @@ -38,6 +39,7 @@ public class LocaleSettings { languageNodes.put("general.filteritemaddedalready", "&cThat item already exists within that category's filter whitelist."); languageNodes.put("general.addeditemtofilterwhitelist", "&aAdded &2%item_name%&a to the &2%filter_category%&a's whitelist"); languageNodes.put("general.finishenteringprice", "&cPlease finish entering the new price first."); + languageNodes.put("general.invalidtimestring", "&cInvalid time, use the following format, ex: 1d (valid suffixes: s,m,h,d,y)"); languageNodes.put("pricing.minbaseprice", "&cThe minimum base price must be &a$%price%"); @@ -66,6 +68,14 @@ public class LocaleSettings { languageNodes.put("discord.is_bid_true", "true"); languageNodes.put("discord.is_bid_false", "false"); + languageNodes.put("bans.nobanreason", "&cPlease enter a ban reason"); + languageNodes.put("bans.bannedplayer", "&aBanned &2%player% &afrom the auction house for &2%ban_amount%"); + languageNodes.put("bans.playeralreadybanned", "&4%player% &cis already banned from the auction house"); + languageNodes.put("bans.playernotbanned", "&4%player% &cis not banned from the auction house"); + languageNodes.put("bans.playerunbanned", "&cUnbanned &4%player% &cfrom the auction house"); + languageNodes.put("bans.remainingtime", "&cYou are banned from the auction house for &4%ban_amount%"); + languageNodes.put("bans.unbanned", "&aYou are now unbanned from the auction house"); + languageNodes.put("auction_filter.sale_types.biddable", "Biddable"); languageNodes.put("auction_filter.sale_types.non_biddable", "Not Biddable"); languageNodes.put("auction_filter.sale_types.both", "All"); @@ -94,6 +104,10 @@ public class LocaleSettings { languageNodes.put("auction.itemnotavailable", "&cThat item is no longer available :("); languageNodes.put("auction.biditemwithdisabledbuynow", "&CN/A"); + languageNodes.put("auction.tax.cannotpaylistingfee", "&cYou do not have enough money to pay the listing fee &f(&4$%price%&f)"); + languageNodes.put("auction.tax.paidlistingfee", "&aPaid &2$%price%&a listing fee"); + + languageNodes.put("commands.invalid_syntax", "&7The valid syntax is: &6%syntax%&7."); languageNodes.put("commands.no_permission", "&dYou do not have permission to do that."); @@ -108,6 +122,8 @@ public class LocaleSettings { languageNodes.put("commands.syntax.transactions", "transactions"); languageNodes.put("commands.syntax.upload", "upload"); languageNodes.put("commands.syntax.filter", "filter [additem] [category]"); + languageNodes.put("commands.syntax.ban", "ban [player] [time] [reason]"); + languageNodes.put("commands.syntax.unban", "ban "); languageNodes.put("commands.description.active", "View all your auction listings"); languageNodes.put("commands.description.auctionhouse", "Main command for the plugin, it opens the auction window."); @@ -120,6 +136,8 @@ public class LocaleSettings { languageNodes.put("commands.description.transactions", "Used to open the transactions menu"); languageNodes.put("commands.description.upload", "Used to upload flat file data to the database"); languageNodes.put("commands.description.filter", "Edit the filter whitelist items"); + languageNodes.put("commands.description.ban", "Ban a player from the auction house for a set amount of time."); + languageNodes.put("commands.description.unban", "Unban a player from the auction house"); } public static void setup() { diff --git a/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java b/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java index b2d6abd..6cf2877 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java +++ b/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java @@ -68,6 +68,13 @@ public class Settings { public static final ConfigSetting SELL_MENU_REQUIRES_USER_TO_HOLD_ITEM = new ConfigSetting(config, "auction setting.require user to hold item when using sell menu", false, "If enabled, when running just /ah sell, the user will need to hold the item in their hand, otherwise they just add it in the gui."); public static final ConfigSetting OPEN_MAIN_AUCTION_HOUSE_AFTER_MENU_LIST = new ConfigSetting(config, "auction setting.open main auction house after listing using menu", true, "Should the main auction house be opened after the user lists an item using the sell menu?"); + public static final ConfigSetting TAX_ENABLED = new ConfigSetting(config, "auction setting.tax.enabled", true, "Should auction house use it's tax system?"); + public static final ConfigSetting TAX_CHARGE_LISTING_FEE = new ConfigSetting(config, "auction setting.tax.charge listing fee", true, "Should auction house charge players to list an item?"); + public static final ConfigSetting TAX_LISTING_FEE = new ConfigSetting(config, "auction setting.tax.listing fee", 5.0, "How much should it cost to list a new item?"); + public static final ConfigSetting TAX_CHARGE_SALES_TAX_TO_BUYER = new ConfigSetting(config, "auction setting.tax.charge sale tax to buyer", false, "Should auction house tax the buyer instead of the seller?"); + public static final ConfigSetting TAX_SALES_TAX_BUY_NOW_PERCENTAGE = new ConfigSetting(config, "auction setting.tax.buy now sales tax", 15.0, "Tax % that should be charged on items that are bought immediately"); + public static final ConfigSetting TAX_SALES_TAX_AUCTION_WON_PERCENTAGE = new ConfigSetting(config, "auction setting.tax.auction won sales tax", 10.0, "Tax % that should be charged on items that are won through the auction"); + public static final ConfigSetting ALL_FILTER_ENABLED = new ConfigSetting(config, "auction setting.enabled filters.all", true, "Should this filter be enabled?"); public static final ConfigSetting FOOD_FILTER_ENABLED = new ConfigSetting(config, "auction setting.enabled filters.food", true, "Should this filter be enabled?"); public static final ConfigSetting ARMOR_FILTER_ENABLED = new ConfigSetting(config, "auction setting.enabled filters.armor", true, "Should this filter be enabled?"); @@ -171,7 +178,7 @@ public class Settings { public static final ConfigSetting DISCORD_ENABLED = new ConfigSetting(config, "discord.enabled", true, "Should the discord webhook feature be enabled?"); public static final ConfigSetting DISCORD_ALERT_ON_AUCTION_START = new ConfigSetting(config, "discord.alert on auction start", true, "Should a message be sent to the discord server when someone lists a new auction item"); public static final ConfigSetting DISCORD_ALERT_ON_AUCTION_FINISH = new ConfigSetting(config, "discord.alert on auction finish", true, "Should a message when an auction finishes?"); - public static final ConfigSetting DISCORD_WEBHOOKS = new ConfigSetting(config, "discord.webhooks", Collections.singletonList("https://discord.com/api/webhooks/821837927444119563/Yd3cWzVB56Tk_VuN1Lv2iGgvsbZt2YV5SDyCkVo6EjRAUqJk3nA2nSG9PH_Bl6rcFNnz"), "A list of webhook urls (channels) you want a message sent to"); + public static final ConfigSetting DISCORD_WEBHOOKS = new ConfigSetting(config, "discord.webhooks", Collections.singletonList("https://discord.com/api/webhooks/867470650112737311/kptC6U4rqVjDaJmquq-ijjsR41t1E4qxF94jwgp5zqYwLjbjo3a_Vqp_mhMWGbqYC-Ju"), "A list of webhook urls (channels) you want a message sent to"); public static final ConfigSetting DISCORD_MSG_USERNAME = new ConfigSetting(config, "discord.user.username", "Auction House", "The name of the user who will send the message"); public static final ConfigSetting DISCORD_MSG_PFP = new ConfigSetting(config, "discord.user.avatar picture", "https://cdn.kiranhart.com/spigot/auctionhouse/icon.png", "The avatar image of the discord user"); public static final ConfigSetting DISCORD_MSG_USE_RANDOM_COLOUR = new ConfigSetting(config, "discord.msg.use random colour", true, "colour of the message bar"); @@ -495,6 +502,20 @@ public class Settings { public static final ConfigSetting GUI_INSPECT_TITLE = new ConfigSetting(config, "gui.inspect.title", "&7&LInspecting Container"); public static final ConfigSetting GUI_INSPECT_BG_ITEM = new ConfigSetting(config, "gui.inspect.bg item", XMaterial.BLACK_STAINED_GLASS_PANE.name()); + /* =============================== + * BANS GUI + * ===============================*/ + public static final ConfigSetting GUI_BANS_TITLE = new ConfigSetting(config, "gui.bans.title", "&7&LAuction House &f- &eBans"); + public static final ConfigSetting GUI_BANS_BG_ITEM = new ConfigSetting(config, "gui.bans.bg item", XMaterial.BLACK_STAINED_GLASS_PANE.name()); + public static final ConfigSetting GUI_BANS_BAN_NAME = new ConfigSetting(config, "gui.bans.ban name", "&e%player_name%"); + public static final ConfigSetting GUI_BANS_BAN_LORE = new ConfigSetting(config, "gui.bans.ban lore", Arrays.asList( + "&7Time Remaining&f: &e%ban_amount%", + "&7Ban Reason&f: &e%ban_reason%", + "", + "&7Right-Click to unban this user" + )); + + /* =============================== * FILTER GUI * ===============================*/ diff --git a/src/main/java/ca/tweetzy/auctionhouse/tasks/TickAuctionsTask.java b/src/main/java/ca/tweetzy/auctionhouse/tasks/TickAuctionsTask.java index f13ba52..d60749c 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/tasks/TickAuctionsTask.java +++ b/src/main/java/ca/tweetzy/auctionhouse/tasks/TickAuctionsTask.java @@ -64,7 +64,10 @@ public class TickAuctionsTask extends BukkitRunnable { OfflinePlayer auctionWinner = Bukkit.getOfflinePlayer(auctionItem.getHighestBidder()); - if (!AuctionHouse.getInstance().getEconomyManager().has(auctionWinner, auctionItem.getCurrentPrice())) { + double finalPrice = auctionItem.getCurrentPrice(); + double tax = Settings.TAX_ENABLED.getBoolean() ? (Settings.TAX_SALES_TAX_AUCTION_WON_PERCENTAGE.getDouble() / 100) * auctionItem.getCurrentPrice() : 0D; + + if (!AuctionHouse.getInstance().getEconomyManager().has(auctionWinner, Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice + tax : finalPrice)) { auctionItem.setExpired(true); continue; } @@ -74,16 +77,16 @@ public class TickAuctionsTask extends BukkitRunnable { if (auctionEndEvent.isCancelled()) continue; - AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(auctionWinner, auctionItem.getCurrentPrice()); - AuctionHouse.getInstance().getEconomyManager().depositPlayer(Bukkit.getOfflinePlayer(auctionItem.getOwner()), auctionItem.getCurrentPrice()); + AuctionHouse.getInstance().getEconomyManager().withdrawPlayer(auctionWinner, Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice + tax : finalPrice); + AuctionHouse.getInstance().getEconomyManager().depositPlayer(Bukkit.getOfflinePlayer(auctionItem.getOwner()), Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice: finalPrice - tax); if (Bukkit.getOfflinePlayer(auctionItem.getOwner()).isOnline()) { AuctionHouse.getInstance().getLocale().getMessage("auction.itemsold") .processPlaceholder("item", WordUtils.capitalizeFully(AuctionAPI.getInstance().deserializeItem(auctionItem.getRawItem()).getType().name().replace("_", " "))) - .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(auctionItem.getCurrentPrice())) + .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice : finalPrice - tax)) .processPlaceholder("buyer_name", Bukkit.getOfflinePlayer(auctionItem.getHighestBidder()).getName()) .sendPrefixedMessage(Bukkit.getOfflinePlayer(auctionItem.getOwner()).getPlayer()); - AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyadd").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(auctionItem.getCurrentPrice())).sendPrefixedMessage(Bukkit.getOfflinePlayer(auctionItem.getOwner()).getPlayer()); + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyadd").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice: finalPrice - tax)).sendPrefixedMessage(Bukkit.getOfflinePlayer(auctionItem.getOwner()).getPlayer()); } if (auctionWinner.isOnline()) { @@ -91,9 +94,9 @@ public class TickAuctionsTask extends BukkitRunnable { AuctionHouse.getInstance().getLocale().getMessage("auction.bidwon") .processPlaceholder("item", WordUtils.capitalizeFully(AuctionAPI.getInstance().deserializeItem(auctionItem.getRawItem()).getType().name().replace("_", " "))) .processPlaceholder("amount", AuctionAPI.getInstance().deserializeItem(auctionItem.getRawItem()).getAmount()) - .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(auctionItem.getCurrentPrice())) + .processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice + tax : finalPrice)) .sendPrefixedMessage(auctionWinner.getPlayer()); - AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(auctionItem.getCurrentPrice())).sendPrefixedMessage(auctionWinner.getPlayer()); + AuctionHouse.getInstance().getLocale().getMessage("pricing.moneyremove").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(Settings.TAX_CHARGE_SALES_TAX_TO_BUYER.getBoolean() ? finalPrice + tax : finalPrice)).sendPrefixedMessage(auctionWinner.getPlayer()); if (Settings.ALLOW_PURCHASE_IF_INVENTORY_FULL.getBoolean()) { PlayerUtils.giveItem(auctionWinner.getPlayer(), AuctionAPI.getInstance().deserializeItem(auctionItem.getRawItem())); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index de55a02..a0ea1f8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -30,6 +30,8 @@ permissions: auctionhouse.cmd.status: true auctionhouse.cmd.admin: true auctionhouse.cmd.filter: true + auctionhouse.cmd.ban: true + auctionhouse.cmd.unban: true auctionhouse.cmd: description: Allows the user to use /ah default: op @@ -65,4 +67,10 @@ permissions: default: op auctionhouse.cmd.filter: description: Allows the user to access the filter whitelist menu + default: op + auctionhouse.cmd.ban: + description: Allows the user to ban players from the auction house + default: op + auctionhouse.cmd.unban: + description: Allows the user to unban players from the auction house default: op \ No newline at end of file diff --git a/src/main/test/Test.java b/src/main/test/Test.java new file mode 100644 index 0000000..751bf93 --- /dev/null +++ b/src/main/test/Test.java @@ -0,0 +1,34 @@ +import ca.tweetzy.core.utils.TimeUtils; + +/** + * The current file has been created by Kiran Hart + * Date Created: July 21 2021 + * Time Created: 2:51 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public class Test { + + public static void main(String[] args) { + System.out.println(TimeUtils.makeReadable(getSecondsFromString("2y")*1000)); + } + + public static long getSecondsFromString(String time) { + time = time.toLowerCase(); + char suffix = time.charAt(time.length() - 1); + int amount = Character.getNumericValue(time.charAt(time.length() - 2)); + switch(suffix) { + case 's': + return amount; + case 'm': + return (long) amount * 60; + case 'h': + return (long) amount * 3600; + case 'd': + return (long) amount * 3600 * 24; + case 'y': + return (long) amount * 3600 * 24 * 365; + default: + return 0L; + } + } +}