add minimum item prices

Took 40 minutes
This commit is contained in:
Kiran Hart 2022-04-04 09:11:04 -04:00
parent 0f97190c6b
commit 62c9f4632c
11 changed files with 378 additions and 6 deletions

View File

@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ca.tweetzy</groupId>
<artifactId>auctionhouse</artifactId>
<version>2.60.3</version>
<version>2.61.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -23,7 +23,7 @@
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>Auction House-${project.version}</finalName>
<finalName>Auction House</finalName>
<plugins>
<plugin>
@ -132,7 +132,7 @@
<resources>
<resource>
<directory>C:\Users\Kiran\Documents\Development\Minecraft\Active\Auction House\target</directory>
<include>Auction House-${project.version}.jar</include>
<include>Auction House.jar</include>
<filtering>false</filtering>
</resource>
</resources>
@ -149,7 +149,7 @@
<resources>
<resource>
<directory>C:\Users\Kiran\Documents\Development\Minecraft\Active\Auction House\target</directory>
<include>Auction House-${project.version}.jar</include>
<include>Auction House.jar</include>
<filtering>false</filtering>
</resource>
</resources>

View File

@ -87,6 +87,9 @@ public class AuctionHouse extends TweetyPlugin {
@Getter
private AuctionStatManager auctionStatManager;
@Getter
private MinItemPriceManager minItemPriceManager;
@Getter
private DatabaseConnector databaseConnector;
@ -179,7 +182,8 @@ public class AuctionHouse extends TweetyPlugin {
new _9_StatsMigration(),
new _10_InfiniteItemsMigration(),
new _11_AdminLogMigration(),
new _12_SerializeFormatDropMigration()
new _12_SerializeFormatDropMigration(),
new _13_MinItemPriceMigration()
);
dataMigrationManager.runMigrations();
@ -200,6 +204,9 @@ public class AuctionHouse extends TweetyPlugin {
this.auctionBanManager = new AuctionBanManager();
this.auctionBanManager.loadBans();
this.minItemPriceManager = new MinItemPriceManager();
this.minItemPriceManager.loadMinPrices();
this.auctionStatManager = new AuctionStatManager();
this.auctionStatManager.loadStats();
@ -226,7 +233,8 @@ public class AuctionHouse extends TweetyPlugin {
new CommandBan(),
new CommandUnban(),
new CommandMarkChest(),
new CommandUpload()
new CommandUpload(),
new CommandMinPrice()
);
// Placeholder API

View File

@ -6,6 +6,7 @@ import ca.tweetzy.auctionhouse.api.hook.MMOItemsHook;
import ca.tweetzy.auctionhouse.api.hook.McMMOHook;
import ca.tweetzy.auctionhouse.auction.AuctionPlayer;
import ca.tweetzy.auctionhouse.auction.AuctionedItem;
import ca.tweetzy.auctionhouse.auction.MinItemPrice;
import ca.tweetzy.auctionhouse.auction.enums.AuctionSaleType;
import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper;
import ca.tweetzy.auctionhouse.helpers.MaterialCategorizer;
@ -654,6 +655,25 @@ public class AuctionAPI {
return;
}
if (!AuctionHouse.getInstance().getMinItemPriceManager().getMinPrices().isEmpty() && !isUsingBundle) {
final MinItemPrice foundMinPriceItem = AuctionHouse.getInstance().getMinItemPriceManager().getMinPrice(original);
if (foundMinPriceItem != null) {
boolean valid = true;
if (isBiddingItem) {
if (basePrice < foundMinPriceItem.getPrice() || bidStartPrice < foundMinPriceItem.getPrice()) valid = false;
} else {
if (basePrice < foundMinPriceItem.getPrice()) valid = false;
}
if (!valid) {
AuctionHouse.getInstance().getLocale().getMessage("pricing.minitemprice").processPlaceholder("price", AuctionAPI.getInstance().formatNumber(foundMinPriceItem.getPrice())).sendPrefixedMessage(seller);
return;
}
}
}
AuctionedItem auctionedItem = new AuctionedItem();
auctionedItem.setId(UUID.randomUUID());
auctionedItem.setOwner(seller.getUniqueId());

View File

@ -0,0 +1,26 @@
package ca.tweetzy.auctionhouse.auction;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
/**
* Date Created: April 04 2022
* Time Created: 8:30 a.m.
*
* @author Kiran Hart
*/
@AllArgsConstructor
@Getter
public final class MinItemPrice {
private UUID uuid;
private ItemStack itemStack;
private double price;
public MinItemPrice(ItemStack itemStack, double price) {
this(UUID.randomUUID(), itemStack, price);
}
}

View File

@ -0,0 +1,95 @@
package ca.tweetzy.auctionhouse.commands;
import ca.tweetzy.auctionhouse.AuctionHouse;
import ca.tweetzy.auctionhouse.api.AuctionAPI;
import ca.tweetzy.auctionhouse.auction.MinItemPrice;
import ca.tweetzy.auctionhouse.guis.GUIMinItemPrices;
import ca.tweetzy.auctionhouse.helpers.PlayerHelper;
import ca.tweetzy.core.commands.AbstractCommand;
import ca.tweetzy.core.compatibility.XMaterial;
import ca.tweetzy.core.utils.NumberUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
/**
* The current file has been created by Kiran Hart
* Date Created: June 22 2021
* Time Created: 3:18 p.m.
* Usage of any code found within this class is prohibited unless given explicit permission otherwise
*/
public class CommandMinPrice extends AbstractCommand {
public CommandMinPrice() {
super(CommandType.PLAYER_ONLY, "minprices");
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
Player player = (Player) sender;
if (CommandMiddleware.handle(player) == ReturnType.FAILURE) return ReturnType.FAILURE;
if (args.length == 0) {
AuctionHouse.getInstance().getGuiManager().showGUI(player, new GUIMinItemPrices());
return ReturnType.SUCCESS;
}
if (args.length == 2 && args[0].equalsIgnoreCase("add")) {
ItemStack held = PlayerHelper.getHeldItem(player);
if (held.getType() == XMaterial.AIR.parseMaterial()) {
AuctionHouse.getInstance().getLocale().getMessage("general.min item price air").sendPrefixedMessage(player);
return ReturnType.FAILURE;
}
if (AuctionHouse.getInstance().getMinItemPriceManager().getMinPrice(held.clone()) != null) {
AuctionHouse.getInstance().getLocale().getMessage("general.min price already added").sendPrefixedMessage(player);
return ReturnType.FAILURE;
}
if (!NumberUtils.isNumeric(args[1])) {
AuctionHouse.getInstance().getLocale().getMessage("general.notanumber").sendPrefixedMessage(player);
return ReturnType.FAILURE;
}
final double price = Double.parseDouble(args[1]);
AuctionHouse.getInstance().getDataManager().insertMinPriceAsync(new MinItemPrice(held.clone(), price), (error, inserted) -> {
if (error == null) {
AuctionHouse.getInstance().getMinItemPriceManager().addItem(inserted);
AuctionHouse.getInstance().getLocale().getMessage("general.added min price")
.processPlaceholder("item", AuctionAPI.getInstance().getItemName(inserted.getItemStack()))
.processPlaceholder("price", AuctionAPI.getInstance().formatNumber(inserted.getPrice()))
.sendPrefixedMessage(player);
}
});
}
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return "auctionhouse.cmd.minprice";
}
@Override
public String getSyntax() {
return AuctionHouse.getInstance().getLocale().getMessage("commands.syntax.min price").getMessage();
}
@Override
public String getDescription() {
return AuctionHouse.getInstance().getLocale().getMessage("commands.description.min price").getMessage();
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
if (args.length == 1) return Collections.singletonList("add");
return null;
}
}

View File

@ -12,6 +12,7 @@ import ca.tweetzy.core.database.DataManagerAbstract;
import ca.tweetzy.core.database.DatabaseConnector;
import ca.tweetzy.core.database.MySQLConnector;
import ca.tweetzy.core.utils.TextUtils;
import net.royawesome.jlibnoise.module.combiner.Min;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
@ -335,6 +336,63 @@ public class DataManager extends DataManagerAbstract {
});
}
public void insertMinPrice(MinItemPrice item, Callback<MinItemPrice> callback) {
this.databaseConnector.connect(connection -> {
try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + this.getTablePrefix() + "min_item_prices (id, item, price) VALUES(?, ?, ?)")) {
PreparedStatement fetch = connection.prepareStatement("SELECT * FROM " + this.getTablePrefix() + "min_item_prices WHERE id = ?");
fetch.setString(1, item.getUuid().toString());
statement.setString(1, item.getUuid().toString());
statement.setString(2, AuctionAPI.encodeItem(item.getItemStack()));
statement.setDouble(3, item.getPrice());
statement.executeUpdate();
if (callback != null) {
ResultSet res = fetch.executeQuery();
res.next();
callback.accept(null, extractMinItemPrice(res));
}
} catch (Exception e) {
e.printStackTrace();
resolveCallback(callback, e);
}
});
}
public void insertMinPriceAsync(MinItemPrice item, Callback<MinItemPrice> callback) {
this.thread.execute(() -> this.insertMinPrice(item, callback));
}
public void getMinItemPrices(Callback<ArrayList<MinItemPrice>> callback) {
ArrayList<MinItemPrice> minItemPrices = new ArrayList<>();
this.async(() -> this.databaseConnector.connect(connection -> {
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + this.getTablePrefix() + "min_item_prices")) {
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
minItemPrices.add(extractMinItemPrice(resultSet));
}
callback.accept(null, minItemPrices);
} catch (Exception e) {
resolveCallback(callback, e);
}
}));
}
public void deleteMinItemPrice(Collection<UUID> minPrices) {
this.async(() -> this.databaseConnector.connect(connection -> {
PreparedStatement statement = connection.prepareStatement("DELETE FROM " + this.getTablePrefix() + "min_item_prices WHERE id = ?");
for (UUID id : minPrices) {
statement.setString(1, id.toString());
statement.addBatch();
}
statement.executeBatch();
}));
}
public void getStats(Callback<Map<UUID, AuctionStat<Integer, Integer, Integer, Double, Double>>> callback) {
Map<UUID, AuctionStat<Integer, Integer, Integer, Double, Double>> stats = new HashMap<>();
this.async(() -> this.databaseConnector.connect(connection -> {
@ -491,6 +549,14 @@ public class DataManager extends DataManagerAbstract {
return auctionItem;
}
private MinItemPrice extractMinItemPrice(ResultSet resultSet) throws SQLException {
return new MinItemPrice(
UUID.fromString(resultSet.getString("id")),
AuctionAPI.decodeItem(resultSet.getString("item")),
resultSet.getDouble("price")
);
}
private Transaction extractTransaction(ResultSet resultSet) throws SQLException {
return new Transaction(
UUID.fromString(resultSet.getString("id")),

View File

@ -0,0 +1,33 @@
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: August 12 2021
* Time Created: 11:58 a.m.
* Usage of any code found within this class is prohibited unless given explicit permission otherwise
*/
public class _13_MinItemPriceMigration extends DataMigration {
public _13_MinItemPriceMigration() {
super(13);
}
@Override
public void migrate(Connection connection, String tablePrefix) throws SQLException {
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "min_item_prices (" +
"id VARCHAR(36) PRIMARY KEY, " +
"item TEXT NOT NULL, " +
"price DOUBLE NOT NULL" +
" )");
}
}
}

View File

@ -0,0 +1,61 @@
package ca.tweetzy.auctionhouse.guis;
import ca.tweetzy.auctionhouse.AuctionHouse;
import ca.tweetzy.auctionhouse.api.AuctionAPI;
import ca.tweetzy.auctionhouse.auction.MinItemPrice;
import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper;
import ca.tweetzy.auctionhouse.settings.Settings;
import ca.tweetzy.core.gui.Gui;
import ca.tweetzy.core.utils.TextUtils;
import ca.tweetzy.core.utils.items.TItemBuilder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Date Created: April 04 2022
* Time Created: 8:21 a.m.
*
* @author Kiran Hart
*/
public final class GUIMinItemPrices extends Gui {
final List<MinItemPrice> minPrices;
public GUIMinItemPrices() {
this.minPrices = AuctionHouse.getInstance().getMinItemPriceManager().getMinPrices();
setTitle(TextUtils.formatText(Settings.GUI_MIN_ITEM_PRICES_TITLE.getString()));
setRows(6);
setAcceptsItems(false);
draw();
}
private void draw() {
reset();
pages = (int) Math.max(1, Math.ceil(this.minPrices.size() / (double) 45));
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;
List<MinItemPrice> data = this.minPrices.stream().skip((page - 1) * 45L).limit(45).collect(Collectors.toList());
for (MinItemPrice minItemPrice : data) {
final List<String> lore = AuctionAPI.getInstance().getItemLore(minItemPrice.getItemStack());
lore.addAll(Settings.GUI_MIN_ITEM_PRICES_LORE.getStringList());
setButton(slot++, ConfigurationItemHelper.createConfigurationItem(minItemPrice.getItemStack(), AuctionAPI.getInstance().getItemName(minItemPrice.getItemStack()), lore, new HashMap<String, Object>() {{
put("%price%", AuctionAPI.getInstance().formatNumber(minItemPrice.getPrice()));
}}), click -> {
AuctionHouse.getInstance().getDataManager().deleteMinItemPrice(Collections.singletonList(minItemPrice.getUuid()));
AuctionHouse.getInstance().getMinItemPriceManager().removeItem(minItemPrice);
click.manager.showGUI(click.player, new GUIMinItemPrices());
});
}
}
}

View File

@ -0,0 +1,47 @@
package ca.tweetzy.auctionhouse.managers;
import ca.tweetzy.auctionhouse.AuctionHouse;
import ca.tweetzy.auctionhouse.api.AuctionAPI;
import ca.tweetzy.auctionhouse.auction.MinItemPrice;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
/**
* Date Created: April 04 2022
* Time Created: 8:22 a.m.
*
* @author Kiran Hart
*/
public final class MinItemPriceManager {
private final List<MinItemPrice> minPrices = new ArrayList<>();
public void addItem(MinItemPrice minItemPrice) {
if (this.minPrices.contains(minItemPrice)) return;
this.minPrices.add(minItemPrice);
}
public void removeItem(MinItemPrice minItemPrice) {
if (!this.minPrices.contains(minItemPrice)) return;
this.minPrices.remove(minItemPrice);
}
public MinItemPrice getMinPrice(ItemStack item) {
return this.minPrices.stream().filter(mins -> mins.getItemStack().isSimilar(item)).findFirst().orElse(null);
}
public List<MinItemPrice> getMinPrices() {
return this.minPrices;
}
public void loadMinPrices() {
this.minPrices.clear();
AuctionHouse.getInstance().getDataManager().getMinItemPrices((error, items) -> {
if (error == null)
items.forEach(this::addItem);
});
}
}

View File

@ -32,6 +32,7 @@ public class LocaleSettings {
languageNodes.put("general.blockedlore", "&cThat item contains a blocked lore phrase");
languageNodes.put("general.air", "&cSorry, but you cannot sell air o.O");
languageNodes.put("general.filter air", "&cSorry, but you cannot add air to a filter whitelist");
languageNodes.put("general.min item price air", "&cSorry, but you cannot add a price to air");
languageNodes.put("general.blocked", "&cSorry, you are not allowed to sell &e%item%");
languageNodes.put("general.sellinglimit", "&cYou cannot sell more items, please remove/sell current active items");
languageNodes.put("general.noroom", "&cPlease clear room in your inventory to purchase that item.");
@ -61,6 +62,8 @@ public class LocaleSettings {
languageNodes.put("general.requires creative", "&cThat action requires you to be in creative mode");
languageNodes.put("general.deleted transactions", "&cDeleted a total of &4%deleted_transactions% &ctransactions");
languageNodes.put("general.transaction delete begin", "&cBeginning transaction deletion, this may take some time.");
languageNodes.put("general.min price already added", "&cThere is already a minimum price set, please delete the existing one first.");
languageNodes.put("general.added min price", "&aSuccessfully set minimum price for %item% &ato &2$%price%");
languageNodes.put("pricing.minbaseprice", "&cThe minimum base price must be &a$%price%");
@ -73,6 +76,7 @@ public class LocaleSettings {
languageNodes.put("pricing.moneyremove", "&c&l- $%price% &7(%player_balance%)");
languageNodes.put("pricing.moneyadd", "&a&l+ $%price% &7(%player_balance%)");
languageNodes.put("pricing.bidmusthigherthanprevious", "&cYour bid must be higher than &4%current_bid%");
languageNodes.put("pricing.minitemprice", "&cThe minimum price for this item must be &a$%price%");
languageNodes.put("prompts.enter new buy now price", "&aPlease enter the new buy now price in chat:");
languageNodes.put("prompts.enter new starting bid", "&aPlease enter the new starting bid in chat:");
@ -171,6 +175,7 @@ public class LocaleSettings {
languageNodes.put("commands.syntax.unban", "unban <player>");
languageNodes.put("commands.syntax.togglelistinfo", "togglelistinfo");
languageNodes.put("commands.syntax.markchest", "markchest");
languageNodes.put("commands.syntax.min price", "minprices [add] [price]");
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.");
@ -187,6 +192,7 @@ public class LocaleSettings {
languageNodes.put("commands.description.unban", "Unban a player from the auction house");
languageNodes.put("commands.description.togglelistinfo", "Toggle whether auction house should message you when you list an item");
languageNodes.put("commands.description.markchest", "Toggles whether a chest is an auction chest");
languageNodes.put("commands.description.min price", "Adds a minimum sell price to an item");
}
public static void send(CommandSender sender, String msg) {

View File

@ -578,6 +578,16 @@ public class Settings {
"&eyear"
));
/* ===============================
* MIN ITEM PRICES GUI
* ===============================*/
public static final ConfigSetting GUI_MIN_ITEM_PRICES_TITLE = new ConfigSetting(config, "gui.min item prices.title", "&7&LMinimum Item Prices");
public static final ConfigSetting GUI_MIN_ITEM_PRICES_LORE = new ConfigSetting(config, "gui.min item prices.lore", Arrays.asList(
"&7&m-------------------------",
"&7Minimum Price&f: &a%price%",
"",
"&7Click to delete"
));
/* ===============================
* LOGS LIST GUI