This commit is contained in:
Kiran Hart 2021-08-24 16:54:48 -04:00
parent a42c137808
commit cb59797d18
13 changed files with 179 additions and 30 deletions

View File

@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ca.tweetzy</groupId>
<artifactId>auctionhouse</artifactId>
<version>2.28.1</version>
<version>2.29.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -145,7 +145,8 @@ public class AuctionHouse extends TweetyPlugin {
new _4_ItemsChangeMigration(),
new _5_TransactionChangeMigration(),
new _6_BigIntMigration(),
new _7_TransactionBigIntMigration()
new _7_TransactionBigIntMigration(),
new _8_ItemPerWorldMigration()
);
dataMigrationManager.runMigrations();

View File

@ -19,6 +19,7 @@ import ca.tweetzy.core.utils.items.ItemUtils;
import ca.tweetzy.core.utils.nms.NBTEditor;
import io.lumine.mythic.lib.api.item.NBTItem;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -575,6 +576,7 @@ public class AuctionAPI {
auctionedItem.setBidStartingPrice(bidStartPrice);
auctionedItem.setBidIncrementPrice(bidIncPrice);
auctionedItem.setCurrentPrice(currentPrice);
auctionedItem.setListedWorld(seller.getWorld().getName());
if (Settings.TAX_ENABLED.getBoolean() && Settings.TAX_CHARGE_LISTING_FEE.getBoolean()) {
if (!EconomyManager.hasBalance(seller, Settings.TAX_LISTING_FEE.getDouble())) {
@ -664,7 +666,71 @@ public class AuctionAPI {
logger.log(Level.FINER, th, () -> "A " + (type == null ? "critical" : type) + " error occurred");
}
void x(ItemStack item) {
NBTItem.get(item).getType();
/**
* Converts the time from a human readable format like "10 minutes"
* to seconds.
*
* @param humanReadableTime the human readable time format: {time} {period}
* example: 5 seconds, 10 ticks, 7 minutes, 12 hours etc..
* @return the converted human time to seconds
*/
public static long toTicks(final String humanReadableTime) {
if (humanReadableTime == null) return 0;
long seconds = 0L;
final String[] split = humanReadableTime.split(" ");
if (!(split.length > 1)) {
return 0;
}
for (int i = 1; i < split.length; i++) {
final String sub = split[i].toLowerCase();
int multiplier = 0; // e.g 2 hours = 2
long unit = 0; // e.g hours = 3600
boolean isTicks = false;
try {
multiplier = Integer.parseInt(split[i - 1]);
} catch (final NumberFormatException e) {
continue;
}
// attempt to match the unit time
if (sub.startsWith("tick"))
isTicks = true;
else if (sub.startsWith("second"))
unit = 1;
else if (sub.startsWith("minute"))
unit = 60;
else if (sub.startsWith("hour"))
unit = 3600;
else if (sub.startsWith("day"))
unit = 86400;
else if (sub.startsWith("week"))
unit = 604800;
else if (sub.startsWith("month"))
unit = 2629743;
else if (sub.startsWith("year"))
unit = 31556926;
else if (sub.startsWith("potato"))
unit = 1337;
else
throw new IllegalArgumentException("Must define date type! Example: '1 second' (Got '" + sub + "')");
seconds += multiplier * (isTicks ? 1 : unit);
}
return seconds;
}
}

View File

@ -47,6 +47,8 @@ public class AuctionedItem {
private boolean expired;
private long expiresAt;
private String listedWorld = null;
public AuctionedItem() {}
public AuctionedItem(

View File

@ -12,11 +12,13 @@ import ca.tweetzy.core.compatibility.XMaterial;
import ca.tweetzy.core.utils.NumberUtils;
import ca.tweetzy.core.utils.PlayerUtils;
import ca.tweetzy.core.utils.nms.NBTEditor;
import com.sun.prism.shader.Texture_ImagePattern_Loader;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -82,9 +84,17 @@ public final class CommandSell extends AbstractCommand {
}
// Check for block items
if (Settings.BLOCKED_ITEMS.getStringList().contains(itemToSell.getType().name())) {
AuctionHouse.getInstance().getLocale().getMessage("general.blockeditem").processPlaceholder("item", itemToSell.getType().name()).sendPrefixedMessage(player);
return ReturnType.FAILURE;
if (Settings.MAKE_BLOCKED_ITEMS_A_WHITELIST.getBoolean()) {
if (!Settings.BLOCKED_ITEMS.getStringList().contains(itemToSell.getType().name())) {
AuctionHouse.getInstance().getLocale().getMessage("general.blockeditem").processPlaceholder("item", itemToSell.getType().name()).sendPrefixedMessage(player);
return ReturnType.FAILURE;
}
} else {
if (Settings.BLOCKED_ITEMS.getStringList().contains(itemToSell.getType().name())) {
AuctionHouse.getInstance().getLocale().getMessage("general.blockeditem").processPlaceholder("item", itemToSell.getType().name()).sendPrefixedMessage(player);
return ReturnType.FAILURE;
}
}
boolean blocked = false;
@ -126,18 +136,27 @@ public final class CommandSell extends AbstractCommand {
Double bidIncrement = null;
boolean isBundle = false;
for (String arg : args) {
if (NumberUtils.isDouble(arg)) {
for (int i = 0; i < args.length; i++) {
if (NumberUtils.isDouble(args[i])) {
if (buyNowPrice == null)
buyNowPrice = Double.parseDouble(arg);
buyNowPrice = Double.parseDouble(args[i]);
else if (startingBid == null)
startingBid = Double.parseDouble(arg);
startingBid = Double.parseDouble(args[i]);
else
bidIncrement = Double.parseDouble(arg);
bidIncrement = Double.parseDouble(args[i]);
}
if (arg.equalsIgnoreCase("-b"))
if (args[i].equalsIgnoreCase("-b") || args[i].equalsIgnoreCase("-bundle"))
isBundle = true;
if (args[i].toLowerCase().startsWith("-t") && Settings.ALLOW_PLAYERS_TO_DEFINE_AUCTION_TIME.getBoolean()) {
if (i + 2 < args.length) {
int customTime = (int) AuctionAPI.toTicks(args[i + 1] + " " + args[i + 2]);
if (customTime <= Settings.MAX_CUSTOM_DEFINED_TIME.getInt())
allowedTime = customTime;
}
}
}
boolean isBiddingItem = Settings.FORCE_AUCTION_USAGE.getBoolean() || buyNowPrice != null && startingBid != null && Settings.ALLOW_USAGE_OF_BID_SYSTEM.getBoolean();
@ -231,8 +250,12 @@ public final class CommandSell extends AbstractCommand {
@Override
protected List<String> onTab(CommandSender sender, String... args) {
if (args.length <= 3) return Arrays.asList("1", "2", "3", "4", "5");
if (args.length == 4) return Collections.singletonList("-b");
if (args.length == 1)
return Arrays.asList(AuctionHouse.getInstance().getLocale().getMessage("commands.sell.args.suggestion one").getMessage().split(" "));
if (args.length == 2)
return Arrays.asList(AuctionHouse.getInstance().getLocale().getMessage("commands.sell.args.suggestion two").getMessage().split(" "));
if (args.length == 3)
return Arrays.asList(AuctionHouse.getInstance().getLocale().getMessage("commands.sell.args.suggestion three").getMessage().split(" "));
return null;
}

View File

@ -248,7 +248,7 @@ public class DataManager extends DataManagerAbstract {
public void insertAuction(AuctionedItem item, Callback<AuctionedItem> callback) {
this.databaseConnector.connect(connection -> {
try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + this.getTablePrefix() + "auctions(id, owner, highest_bidder, owner_name, highest_bidder_name, category, base_price, bid_start_price, bid_increment_price, current_price, expired, expires_at, item_material, item_name, item_lore, item_enchants, item) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + this.getTablePrefix() + "auctions(id, owner, highest_bidder, owner_name, highest_bidder_name, category, base_price, bid_start_price, bid_increment_price, current_price, expired, expires_at, item_material, item_name, item_lore, item_enchants, item, listed_world) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
PreparedStatement fetch = connection.prepareStatement("SELECT * FROM " + this.getTablePrefix() + "auctions WHERE id = ?");
fetch.setString(1, item.getId().toString());
@ -269,6 +269,7 @@ public class DataManager extends DataManagerAbstract {
statement.setString(15, AuctionAPI.getInstance().serializeLines(AuctionAPI.getInstance().getItemLore(item.getItem())));
statement.setString(16, AuctionAPI.getInstance().serializeLines(AuctionAPI.getInstance().getItemEnchantments(item.getItem())));
statement.setString(17, AuctionAPI.encodeItem(item.getItem()));
statement.setString(18, item.getListedWorld());
statement.executeUpdate();
if (callback != null) {
@ -415,7 +416,7 @@ public class DataManager extends DataManagerAbstract {
}
private AuctionedItem extractAuctionedItem(ResultSet resultSet) throws SQLException {
return new AuctionedItem(
AuctionedItem auctionItem = new AuctionedItem(
UUID.fromString(resultSet.getString("id")),
UUID.fromString(resultSet.getString("owner")),
UUID.fromString(resultSet.getString("highest_bidder")),
@ -431,6 +432,10 @@ public class DataManager extends DataManagerAbstract {
resultSet.getBoolean("expired"),
resultSet.getLong("expires_at")
);
auctionItem.setListedWorld(resultSet.getString("listed_world"));
return auctionItem;
}
private Transaction extractTransaction(ResultSet resultSet) throws SQLException {

View File

@ -0,0 +1,27 @@
package ca.tweetzy.auctionhouse.database.migrations;
import ca.tweetzy.core.database.DataMigration;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
/**
* The current file has been created by Kiran Hart
* Date Created: August 24 2021
* Time Created: 4:04 p.m.
* Usage of any code found within this class is prohibited unless given explicit permission otherwise
*/
public final class _8_ItemPerWorldMigration extends DataMigration {
public _8_ItemPerWorldMigration() {
super(8);
}
@Override
public void migrate(Connection connection, String tablePrefix) throws SQLException {
try (Statement statement = connection.createStatement()) {
statement.execute("ALTER TABLE " + tablePrefix + "auctions ADD listed_world VARCHAR(64) NULL");
}
}
}

View File

@ -54,6 +54,12 @@ public class GUIActiveAuctions extends Gui {
private void drawItems() {
AuctionHouse.newChain().asyncFirst(() -> {
this.items = this.auctionPlayer.getItems(false);
// per world check
if (Settings.PER_WORLD_ITEMS.getBoolean()) {
this.items = this.items.stream().filter(item -> item.getListedWorld() == null || this.auctionPlayer.getPlayer().getWorld().getName().equals(item.getListedWorld())).collect(Collectors.toList());
}
return this.items.stream().sorted(Comparator.comparingLong(AuctionedItem::getExpiresAt).reversed()).skip((page - 1) * 45L).limit(45).collect(Collectors.toList());
}).asyncLast((data) -> {
pages = (int) Math.max(1, Math.ceil(this.items.size() / (double) 45L));

View File

@ -98,7 +98,13 @@ public class GUIAuctionHouse extends Gui {
for (Map.Entry<UUID, AuctionedItem> entry : AuctionHouse.getInstance().getAuctionItemManager().getItems().entrySet()) {
AuctionedItem auctionItem = entry.getValue();
if (!auctionItem.isExpired() && !AuctionHouse.getInstance().getAuctionItemManager().getGarbageBin().containsKey(auctionItem.getId())) {
this.items.add(auctionItem);
if (Settings.PER_WORLD_ITEMS.getBoolean()) {
if (auctionItem.getListedWorld() == null || this.auctionPlayer.getPlayer().getWorld().getName().equals(auctionItem.getListedWorld())) {
this.items.add(auctionItem);
}
} else {
this.items.add(auctionItem);
}
}
}

View File

@ -50,6 +50,11 @@ public class GUIExpiredItems extends Gui {
AuctionHouse.newChain().asyncFirst(() -> {
this.items = this.auctionPlayer.getItems(true);
if (Settings.PER_WORLD_ITEMS.getBoolean()) {
this.items = this.items.stream().filter(item -> item.getListedWorld() == null || this.auctionPlayer.getPlayer().getWorld().getName().equals(item.getListedWorld())).collect(Collectors.toList());
}
return this.items.stream().sorted(Comparator.comparingLong(AuctionedItem::getExpiresAt).reversed()).skip((page - 1) * 45L).limit(45).collect(Collectors.toList());
}).asyncLast((data) -> {
pages = (int) Math.max(1, Math.ceil(this.auctionPlayer.getItems(true).size() / (double) 45));

View File

@ -116,19 +116,20 @@ public class GUISellItem extends Gui {
reset();
// the draw item that is being listed
setButton(1, 4, this.itemToBeListed, e -> {
if (e.clickType == ClickType.RIGHT || e.clickType == ClickType.NUMBER_KEY) e.event.setCancelled(true);
// Is the user selling with an item in hand?
if (AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().containsKey(e.player.getUniqueId())) {
if (AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().get(e.player.getUniqueId()).getType() != XMaterial.AIR.parseMaterial()) {
e.event.setCancelled(true);
setButton(1, 4, this.itemToBeListed, e -> {
if (e.clickType == ClickType.RIGHT || e.clickType == ClickType.NUMBER_KEY) e.event.setCancelled(true);
// Is the user selling with an item in hand?
if (AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().containsKey(e.player.getUniqueId())) {
if (AuctionHouse.getInstance().getAuctionPlayerManager().getSellHolding().get(e.player.getUniqueId()).getType() != XMaterial.AIR.parseMaterial()) {
e.event.setCancelled(true);
}
}
}
this.itemToBeListed = e.clickedItem;
});
this.itemToBeListed = e.clickedItem;
});
if (Settings.ALLOW_USAGE_OF_BUY_NOW_SYSTEM.getBoolean()) {
if (Settings.ALLOW_USAGE_OF_BUY_NOW_SYSTEM.getBoolean() && this.isAllowingBuyNow) {
setButton(3, 1, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_SELL_ITEMS_BUY_NOW_ITEM.getString(), Settings.GUI_SELL_ITEMS_BUY_NOW_NAME.getString(), Settings.GUI_SELL_ITEMS_BUY_NOW_LORE.getStringList(), new HashMap<String, Object>() {{
put("%buy_now_price%", AuctionAPI.getInstance().formatNumber(buyNowPrice));
}}), ClickType.LEFT, e -> {
@ -153,7 +154,7 @@ public class GUISellItem extends Gui {
}
if (this.isBiddingItem) {
setButton(3, Settings.FORCE_CUSTOM_BID_AMOUNT.getBoolean() ? 3 : Settings.ALLOW_USAGE_OF_BUY_NOW_SYSTEM.getBoolean() ? 2 : 1, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_SELL_ITEMS_STARTING_BID_ITEM.getString(), Settings.GUI_SELL_ITEMS_STARTING_BID_NAME.getString(), Settings.GUI_SELL_ITEMS_STARTING_BID_LORE.getStringList(), new HashMap<String, Object>() {{
setButton(3, Settings.FORCE_CUSTOM_BID_AMOUNT.getBoolean() ? 2 : Settings.ALLOW_USAGE_OF_BUY_NOW_SYSTEM.getBoolean() ? 2 : 1, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_SELL_ITEMS_STARTING_BID_ITEM.getString(), Settings.GUI_SELL_ITEMS_STARTING_BID_NAME.getString(), Settings.GUI_SELL_ITEMS_STARTING_BID_LORE.getStringList(), new HashMap<String, Object>() {{
put("%starting_bid_price%", AuctionAPI.getInstance().formatNumber(bidStartPrice));
}}), ClickType.LEFT, e -> {
setTheItemToBeListed();
@ -217,7 +218,7 @@ public class GUISellItem extends Gui {
return;
}
if (this.isBiddingItem && this.buyNowPrice <= this.bidStartPrice && Settings.BASE_PRICE_MUST_BE_HIGHER_THAN_BID_START.getBoolean()) {
if (this.isAllowingBuyNow && this.isBiddingItem && this.buyNowPrice <= this.bidStartPrice && Settings.BASE_PRICE_MUST_BE_HIGHER_THAN_BID_START.getBoolean()) {
AuctionHouse.getInstance().getLocale().getMessage("pricing.basepricetoolow").sendPrefixedMessage(e.player);
return;
}

View File

@ -122,6 +122,9 @@ public class LocaleSettings {
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.");
languageNodes.put("commands.sell.args.suggestion one", "100");
languageNodes.put("commands.sell.args.suggestion two", "50 -b");
languageNodes.put("commands.sell.args.suggestion three", "10 -b");
languageNodes.put("commands.syntax.active", "active");
languageNodes.put("commands.syntax.auctionhouse", "/ah");

View File

@ -79,6 +79,9 @@ public class Settings {
public static final ConfigSetting USE_ALTERNATE_CURRENCY_FORMAT = new ConfigSetting(config, "auction setting.use alternate currency format", false, "If true, $123,456.78 will become $123.456,78");
public static final ConfigSetting DATE_FORMAT = new ConfigSetting(config, "auction setting.date format", "MMM dd, yyyy hh:mm aa", "You can learn more about date formats by googling SimpleDateFormat patterns or visiting this link", "https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html");
public static final ConfigSetting ALLOW_PLAYERS_TO_ACCEPT_BID = new ConfigSetting(config, "auction setting.allow players to accept bid", true, "If true, players can right click a biddable item inside their active listings menu to accept the current bid");
public static final ConfigSetting PER_WORLD_ITEMS = new ConfigSetting(config, "auction setting.per world items", false, "If true, items can only be seen in the world they were listed in, same goes for bidding/buying/collecting");
public static final ConfigSetting ALLOW_PLAYERS_TO_DEFINE_AUCTION_TIME = new ConfigSetting(config, "auction setting.allow players to set auction time", false, "If true players can use -t 1 day for example to set the listing time for their item");
public static final ConfigSetting MAX_CUSTOM_DEFINED_TIME = new ConfigSetting(config, "auction setting.max custom defined time", 604800, "What should the limit on custom defined listing times be in seconds?");
public static final ConfigSetting USE_SEPARATE_FILTER_MENU = new ConfigSetting(config, "auction setting.use separate filter menu", false, "If true, rather than using a single filter item inside the auction menu", "it will open an entirely new menu to select the filter");
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.");
@ -240,6 +243,7 @@ public class Settings {
* BLACK LISTED
* ===============================*/
public static final ConfigSetting BLOCKED_ITEMS = new ConfigSetting(config, "blocked items", Collections.singletonList("ENDER_CHEST"), "Materials that should be blocked (not allowed to sell)");
public static final ConfigSetting MAKE_BLOCKED_ITEMS_A_WHITELIST = new ConfigSetting(config, "blocked items is whitelist", false, "If true, blocked items will become a whitelist, meaning only items specified in blacked list will be allowed in the ah");
public static final ConfigSetting BLOCKED_ITEM_NAMES = new ConfigSetting(config, "blocked item names", Arrays.asList(
"fuck",
"bitch",