diff --git a/pom.xml b/pom.xml
index 6755f6b1..b9414d0a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
Markets
A new take on traditional player owned shops
- 2.23.0
+ 2.30.0
jar
@@ -16,7 +16,7 @@
${project.name}
${project.groupId}.${project.artifactId}.${project.name}
16
- 3.27.1
+ 3.30.0
ca.tweetzy
UTF-8
@@ -236,21 +236,22 @@
+
+
+
+ com.coderplus.maven.plugins
+ copy-rename-maven-plugin
+ 1.0.1
+
- copy-files-on-build-2
+ copy-named-jar
package
- copy-resources
+ copy
- D:\Development\Spigot Servers\20.1\plugins
-
-
- ${project.build.directory}
- ${project.name}.jar
- false
-
-
+ ${project.build.directory}/${project.name}.jar
+ D:\Development\Spigot Plugins\Ready Jars\${project.name}\${project.name} - v${project.version}.jar
diff --git a/src/main/java/ca/tweetzy/markets/Markets.java b/src/main/java/ca/tweetzy/markets/Markets.java
index afb1d505..1d3a5a84 100644
--- a/src/main/java/ca/tweetzy/markets/Markets.java
+++ b/src/main/java/ca/tweetzy/markets/Markets.java
@@ -4,6 +4,7 @@
import ca.tweetzy.flight.command.CommandManager;
import ca.tweetzy.flight.database.DataMigrationManager;
import ca.tweetzy.flight.database.DatabaseConnector;
+import ca.tweetzy.flight.database.MySQLConnector;
import ca.tweetzy.flight.database.SQLiteConnector;
import ca.tweetzy.flight.gui.GuiManager;
import ca.tweetzy.flight.utils.Common;
@@ -60,7 +61,16 @@ protected void onFlight() {
taskChainFactory = BukkitTaskChainFactory.create(this);
// Set up the database if enabled
- this.databaseConnector = new SQLiteConnector(this);
+ this.databaseConnector = Settings.DATABASE_USE.getBoolean() ? new MySQLConnector(
+ this,
+ Settings.DATABASE_HOST.getString(),
+ Settings.DATABASE_PORT.getInt(),
+ Settings.DATABASE_NAME.getString(),
+ Settings.DATABASE_USERNAME.getString(),
+ Settings.DATABASE_PASSWORD.getString(),
+ Settings.DATABASE_CUSTOM_PARAMS.getString().equalsIgnoreCase("None") ? "" : Settings.DATABASE_CUSTOM_PARAMS.getString()
+ ) : new SQLiteConnector(this);
+
this.dataManager = new DataManager(this.databaseConnector, this);
final DataMigrationManager dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
diff --git a/src/main/java/ca/tweetzy/markets/api/market/core/AbstractMarket.java b/src/main/java/ca/tweetzy/markets/api/market/core/AbstractMarket.java
index 1f94a3be..82397ec8 100644
--- a/src/main/java/ca/tweetzy/markets/api/market/core/AbstractMarket.java
+++ b/src/main/java/ca/tweetzy/markets/api/market/core/AbstractMarket.java
@@ -2,10 +2,12 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
+import lombok.Setter;
@AllArgsConstructor
public abstract class AbstractMarket implements Market {
@Getter
+ @Setter
protected MarketType marketType;
}
diff --git a/src/main/java/ca/tweetzy/markets/api/market/core/Market.java b/src/main/java/ca/tweetzy/markets/api/market/core/Market.java
index deddaa19..7ab1780a 100644
--- a/src/main/java/ca/tweetzy/markets/api/market/core/Market.java
+++ b/src/main/java/ca/tweetzy/markets/api/market/core/Market.java
@@ -1,23 +1,32 @@
package ca.tweetzy.markets.api.market.core;
+import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.markets.api.*;
import ca.tweetzy.markets.api.market.layout.Layout;
+import ca.tweetzy.markets.impl.ServerMarket;
+import ca.tweetzy.markets.settings.Settings;
import lombok.NonNull;
+import org.bukkit.Bukkit;
+import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.UUID;
public interface Market extends Identifiable, Displayable, Trackable, Synchronize, Storeable {
- @NonNull UUID getOwnerUUID();
+ @NonNull
+ UUID getOwnerUUID();
- @NonNull String getOwnerName();
+ @NonNull
+ String getOwnerName();
void setOwnerName(@NonNull String ownerName);
- @NonNull List getCategories();
+ @NonNull
+ List getCategories();
- @NonNull List getRatings();
+ @NonNull
+ List getRatings();
boolean isOpen();
@@ -33,12 +42,22 @@ public interface Market extends Identifiable, Displayable, Trackable, Synchroniz
void setCloseWhenOutOfStock(final boolean closeWhenOutOfStock);
+ default ItemStack getDynamicIcon() {
+ return getOwnerUUID().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString())) ? QuickItem.of(Settings.SERVER_MARKET_TEXTURE.getString()).make() : QuickItem.of(Bukkit.getOfflinePlayer(getOwnerUUID())).make();
+ }
+
+ default boolean isServerMarket() {
+ return this instanceof ServerMarket || getOwnerUUID().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString())) ;
+ }
+
default boolean isEmpty() {
boolean isEmpty = true;
for (Category category : getCategories()) {
- if (!category.getItems().isEmpty()) {
- isEmpty = false;
- break;
+ for (MarketItem item : category.getItems()) {
+ if (item.getStock() > 0) {
+ isEmpty = false;
+ break;
+ }
}
}
return isEmpty;
diff --git a/src/main/java/ca/tweetzy/markets/api/market/core/MarketUser.java b/src/main/java/ca/tweetzy/markets/api/market/core/MarketUser.java
index 1eb9011c..38998942 100644
--- a/src/main/java/ca/tweetzy/markets/api/market/core/MarketUser.java
+++ b/src/main/java/ca/tweetzy/markets/api/market/core/MarketUser.java
@@ -3,6 +3,7 @@
import ca.tweetzy.markets.api.Storeable;
import ca.tweetzy.markets.api.Synchronize;
import ca.tweetzy.markets.api.market.MarketSortType;
+import ca.tweetzy.markets.settings.Settings;
import lombok.NonNull;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
@@ -41,4 +42,8 @@ public interface MarketUser extends Synchronize, Storeable {
void setLastSeenAt(final long lastSeenAt);
void setMarketSortType(MarketSortType marketSortType);
+
+ default boolean isServerMarket() {
+ return getUUID().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString()));
+ }
}
diff --git a/src/main/java/ca/tweetzy/markets/api/market/offer/Offer.java b/src/main/java/ca/tweetzy/markets/api/market/offer/Offer.java
index 223f6b02..f4a6458f 100644
--- a/src/main/java/ca/tweetzy/markets/api/market/offer/Offer.java
+++ b/src/main/java/ca/tweetzy/markets/api/market/offer/Offer.java
@@ -39,6 +39,8 @@ public interface Offer extends Identifiable, Trackable, Storeable {
void setOfferedAmount(final double amount);
+ void setRequestAmount(final int amount);
+
void accept(@NonNull final Consumer result);
void reject(@NonNull final BiConsumer result);
diff --git a/src/main/java/ca/tweetzy/markets/commands/CommandAdd.java b/src/main/java/ca/tweetzy/markets/commands/CommandAdd.java
index d3ebfa51..97559ba8 100644
--- a/src/main/java/ca/tweetzy/markets/commands/CommandAdd.java
+++ b/src/main/java/ca/tweetzy/markets/commands/CommandAdd.java
@@ -14,6 +14,7 @@
import ca.tweetzy.markets.api.market.core.MarketItem;
import ca.tweetzy.markets.gui.user.category.MarketCategoryEditGUI;
import ca.tweetzy.markets.impl.CategoryItem;
+import ca.tweetzy.markets.model.BlacklistChecker;
import ca.tweetzy.markets.model.FlagExtractor;
import ca.tweetzy.markets.settings.Settings;
import ca.tweetzy.markets.settings.Translations;
@@ -56,6 +57,9 @@ protected ReturnType execute(CommandSender sender, String... args) {
final ItemStack toSell = PlayerUtil.getHand(player).clone();
final Category category = Markets.getCategoryManager().getByName(market, args[0]);
+ // check blacklist
+ if (!BlacklistChecker.passesChecks(player, toSell)) return ReturnType.FAIL;
+
if (category == null) {
tell(player, TranslationManager.string(player, Translations.INVALID_CATEGORY, "category_id", args[0]));
return ReturnType.FAIL;
diff --git a/src/main/java/ca/tweetzy/markets/commands/CommandAdmin.java b/src/main/java/ca/tweetzy/markets/commands/CommandAdmin.java
index 0045c887..a6f1ba44 100644
--- a/src/main/java/ca/tweetzy/markets/commands/CommandAdmin.java
+++ b/src/main/java/ca/tweetzy/markets/commands/CommandAdmin.java
@@ -5,7 +5,12 @@
import ca.tweetzy.flight.command.ReturnType;
import ca.tweetzy.flight.settings.TranslationManager;
import ca.tweetzy.markets.Markets;
+import ca.tweetzy.markets.api.market.core.Category;
+import ca.tweetzy.markets.api.market.core.Market;
+import ca.tweetzy.markets.gui.admin.MarketsAdminGUI;
import ca.tweetzy.markets.gui.shared.MarketsMainGUI;
+import ca.tweetzy.markets.gui.shared.view.content.MarketCategoryViewGUI;
+import ca.tweetzy.markets.gui.shared.view.content.MarketViewGUI;
import ca.tweetzy.markets.gui.user.BankGUI;
import ca.tweetzy.markets.settings.Settings;
import ca.tweetzy.markets.settings.Translations;
@@ -26,14 +31,15 @@ public CommandAdmin() {
@Override
protected ReturnType execute(CommandSender sender, String... args) {
if (args.length == 0) {
+ if (sender instanceof final Player player)
+ Markets.getGuiManager().showGUI(player, new MarketsAdminGUI(player));
return ReturnType.SUCCESS;
}// 0 1 2
-
if (args.length == 1) {
if (!(sender instanceof final Player player)) return ReturnType.FAIL;
- switch(args[0].toLowerCase()) {
+ switch (args[0].toLowerCase()) {
case "collecttax":
Markets.getGuiManager().showGUI(player, new BankGUI(null, player, true));
}
@@ -54,9 +60,30 @@ protected ReturnType execute(CommandSender sender, String... args) {
case "openmain":
Markets.getGuiManager().showGUI(target, new MarketsMainGUI(target));
break;
+ case "openserver":
+ final Market market = Markets.getMarketManager().getServerMarket();
+ if (market == null) {
+ tell(sender, "&cThe server market is not setup, please create it in /markets admin");
+ break;
+ }
+
+ if (market.isEmpty() || !market.isOpen()) {
+ tell(sender, "&cThe server market is closed/has no items - cannot open for player.");
+ break;
+ }
+
+ final Category locatedCategory = args.length == 3 ? market.getCategories().stream().filter(category -> category.getName().equalsIgnoreCase(args[2])).findFirst().orElse(null) : null;
+
+ if (locatedCategory != null) {
+ Markets.getGuiManager().showGUI(target, new MarketCategoryViewGUI(target, market, locatedCategory, false, true));
+ return ReturnType.SUCCESS;
+ }
+
+ Markets.getGuiManager().showGUI(target, new MarketViewGUI(null, target, market, false));
+ break;
}
- }
+ }
return ReturnType.SUCCESS;
}
diff --git a/src/main/java/ca/tweetzy/markets/commands/CommandTransactions.java b/src/main/java/ca/tweetzy/markets/commands/CommandTransactions.java
index 2a79cd26..432d54ee 100644
--- a/src/main/java/ca/tweetzy/markets/commands/CommandTransactions.java
+++ b/src/main/java/ca/tweetzy/markets/commands/CommandTransactions.java
@@ -20,7 +20,7 @@ public CommandTransactions() {
@Override
protected ReturnType execute(CommandSender sender, String... args) {
if (sender instanceof final Player player) {
- Markets.getGuiManager().showGUI(player, new TransactionsGUI(null, player));
+ Markets.getGuiManager().showGUI(player, new TransactionsGUI(null, player, false));
}
return ReturnType.SUCCESS;
}
diff --git a/src/main/java/ca/tweetzy/markets/commands/CommandView.java b/src/main/java/ca/tweetzy/markets/commands/CommandView.java
index f4ec5892..9baefebd 100644
--- a/src/main/java/ca/tweetzy/markets/commands/CommandView.java
+++ b/src/main/java/ca/tweetzy/markets/commands/CommandView.java
@@ -52,6 +52,11 @@ protected ReturnType execute(CommandSender sender, String... args) {
return ReturnType.FAIL;
}
+ if (Markets.getMarketManager().isBannedFrom(market, player)) {
+ Common.tell(player, TranslationManager.string(player, Translations.BANNED_FROM_MARKET, "market_owner", market.getOwnerName()));
+ return ReturnType.FAIL;
+ }
+
if (args.length == 1){
if (market.getOwnerUUID().equals(player.getUniqueId())) {
Markets.getGuiManager().showGUI(player, new MarketOverviewGUI(player, market));
diff --git a/src/main/java/ca/tweetzy/markets/database/DataManager.java b/src/main/java/ca/tweetzy/markets/database/DataManager.java
index 35cf410b..881d5cc4 100644
--- a/src/main/java/ca/tweetzy/markets/database/DataManager.java
+++ b/src/main/java/ca/tweetzy/markets/database/DataManager.java
@@ -942,6 +942,25 @@ private AbstractMarket extractMarket(@NonNull final ResultSet resultSet) throws
homeLayout = resultSet.getString("home_layout") != null ? MarketLayout.decodeJSON(resultSet.getString("home_layout")) : new HomeLayout();
categoryLayout = resultSet.getString("category_layout") != null ? MarketLayout.decodeJSON(resultSet.getString("category_layout")) : new HomeLayout();
+ if (Enum.valueOf(MarketType.class, resultSet.getString("type").toUpperCase()) == MarketType.SERVER) {
+ return new ServerMarket(
+ UUID.fromString(resultSet.getString("id")),
+ UUID.fromString(resultSet.getString("owner")),
+ resultSet.getString("owner_name"),
+ resultSet.getString("display_name"),
+ new ArrayList<>(List.of(resultSet.getString("description").split(";;;"))),
+ new ArrayList<>(),
+ new ArrayList<>(),
+ bannedUsers,
+ resultSet.getBoolean("open"),
+ resultSet.getBoolean("close_when_out_of_stock"),
+ homeLayout,
+ categoryLayout,
+ resultSet.getLong("created_at"),
+ resultSet.getLong("updated_at")
+ );
+ }
+
return new PlayerMarket(
UUID.fromString(resultSet.getString("id")),
UUID.fromString(resultSet.getString("owner")),
diff --git a/src/main/java/ca/tweetzy/markets/database/migrations/_16_InfiniteItemsMigration.java b/src/main/java/ca/tweetzy/markets/database/migrations/_16_InfiniteItemsMigration.java
index efd15e60..11c36210 100644
--- a/src/main/java/ca/tweetzy/markets/database/migrations/_16_InfiniteItemsMigration.java
+++ b/src/main/java/ca/tweetzy/markets/database/migrations/_16_InfiniteItemsMigration.java
@@ -15,7 +15,7 @@ public _16_InfiniteItemsMigration() {
@Override
public void migrate(Connection connection, String tablePrefix) throws SQLException {
try (Statement statement = connection.createStatement()) {
- statement.execute("ALTER TABLE " + tablePrefix + "category_item ADD infinite BOOLEAN NOT NULL default 'false';");
+ statement.execute("ALTER TABLE " + tablePrefix + "category_item ADD infinite BOOLEAN NOT NULL default 0;");
}
}
diff --git a/src/main/java/ca/tweetzy/markets/gui/admin/MarketsAdminGUI.java b/src/main/java/ca/tweetzy/markets/gui/admin/MarketsAdminGUI.java
new file mode 100644
index 00000000..200d7456
--- /dev/null
+++ b/src/main/java/ca/tweetzy/markets/gui/admin/MarketsAdminGUI.java
@@ -0,0 +1,110 @@
+package ca.tweetzy.markets.gui.admin;
+
+import ca.tweetzy.flight.comp.enums.CompMaterial;
+import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.QuickItem;
+import ca.tweetzy.markets.Markets;
+import ca.tweetzy.markets.api.market.MarketSortType;
+import ca.tweetzy.markets.api.market.core.AbstractMarket;
+import ca.tweetzy.markets.api.market.core.MarketUser;
+import ca.tweetzy.markets.gui.MarketsBaseGUI;
+import ca.tweetzy.markets.gui.shared.selector.ConfirmGUI;
+import ca.tweetzy.markets.gui.user.market.MarketOverviewGUI;
+import ca.tweetzy.markets.impl.MarketPlayer;
+import ca.tweetzy.markets.impl.ServerMarket;
+import ca.tweetzy.markets.impl.layout.HomeLayout;
+import ca.tweetzy.markets.settings.Settings;
+import ca.tweetzy.markets.settings.Translations;
+import lombok.NonNull;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public final class MarketsAdminGUI extends MarketsBaseGUI {
+
+ public MarketsAdminGUI(@NonNull Player player) {
+ super(null, player, TranslationManager.string(player, Translations.GUI_MAIN_ADMIN_TITLE), 3);
+ draw();
+ }
+
+ @Override
+ protected void draw() {
+ ServerMarket adminMarket = Markets.getMarketManager().getServerMarket();
+
+ setButton(1, 4, QuickItem
+ .of(adminMarket != null ? adminMarket.getDynamicIcon() : CompMaterial.CHEST.parseItem())
+ .name(TranslationManager.string(Translations.GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET))
+ .lore(TranslationManager.list(adminMarket == null ? Translations.GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET_LORE_CREATE : Translations.GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET_LORE_VIEW))
+ .make(), click -> {
+
+ if (adminMarket != null) {
+ click.manager.showGUI(click.player, new MarketOverviewGUI(click.player, adminMarket));
+ return;
+ }
+
+ final AbstractMarket market = new ServerMarket(
+ UUID.randomUUID(),
+ UUID.fromString(Settings.SERVER_MARKET_UUID.getString()),
+ Settings.NAME.getString(),
+ TranslationManager.string(player, Translations.DEFAULTS_MARKET_DISPLAY_NAME, "player_name", Settings.NAME.getString()),
+ TranslationManager.list(player, Translations.DEFAULTS_MARKET_DESCRIPTION),
+ new ArrayList<>(),
+ new ArrayList<>(),
+ new ArrayList<>(),
+ false,
+ true,
+ new HomeLayout(),
+ new HomeLayout(),
+ System.currentTimeMillis(),
+ System.currentTimeMillis()
+ );
+
+ if (Settings.USE_ADDITIONAL_CONFIRMS.getBoolean()) {
+ click.manager.showGUI(click.player, new ConfirmGUI(this, click.player, confirmed -> {
+ if (confirmed)
+ market.store(storedMarket -> {
+ if (storedMarket != null) {
+ Markets.getMarketManager().add(storedMarket);
+ createAdminUser();
+ click.manager.showGUI(click.player, new MarketsAdminGUI(click.player));
+ }
+ });
+ else
+ click.manager.showGUI(click.player, new MarketsAdminGUI(click.player));
+ }));
+
+ } else {
+ market.store(storedMarket -> {
+ if (storedMarket != null) {
+ Markets.getMarketManager().add(storedMarket);
+ createAdminUser();
+ click.manager.showGUI(click.player, new MarketsAdminGUI(click.player));
+ }
+ });
+ }
+ });
+ }
+
+ private void createAdminUser() {
+ if (Markets.getPlayerManager().get(UUID.fromString(Settings.SERVER_MARKET_UUID.getString())) == null) {
+ final MarketUser marketUser = new MarketPlayer(
+ UUID.fromString(Settings.SERVER_MARKET_UUID.getString()),
+ null,
+ Settings.NAME.getString(),
+ List.of("Server market"),
+ "english",
+ "US",
+ MarketSortType.ITEMS,
+ System.currentTimeMillis()
+ );
+
+ marketUser.store(storedUser -> {
+ if (storedUser != null) {
+ Markets.getPlayerManager().add(storedUser.getUUID(), storedUser);
+ }
+ });
+ }
+ }
+}
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/checkout/OfferCreateGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/checkout/OfferCreateGUI.java
index 016648be..163ef6c8 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/checkout/OfferCreateGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/checkout/OfferCreateGUI.java
@@ -4,6 +4,7 @@
import ca.tweetzy.flight.settings.TranslationManager;
import ca.tweetzy.flight.utils.Common;
import ca.tweetzy.flight.utils.ItemUtil;
+import ca.tweetzy.flight.utils.MathUtil;
import ca.tweetzy.flight.utils.QuickItem;
import ca.tweetzy.flight.utils.input.TitleInput;
import ca.tweetzy.markets.Markets;
@@ -51,7 +52,47 @@ protected void draw() {
.make()
);
- setButton(1, 4, QuickItem
+ setButton(1, 3, QuickItem
+ .of(Settings.GUI_OFFER_CREATE_ITEMS_REQUEST_AMT.getItemStack())
+ .name(TranslationManager.string(this.player, Translations.GUI_OFFER_CREATE_ITEMS_TOTAL_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_OFFER_CREATE_ITEMS_TOTAL_LORE,
+ "offer_itemsrequested", this.offer.getRequestAmount(),
+ "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK)
+ ))
+ .make(), click -> new TitleInput(Markets.getInstance(), click.player, TranslationManager.string(this.player, Translations.PROMPT_OFFER_TOTAL_ITEMS_TITLE), TranslationManager.string(this.player, Translations.PROMPT_OFFER_TOTAL_ITEMS_SUBTITLE)) {
+
+ @Override
+ public void onExit(Player player) {
+ click.manager.showGUI(click.player, OfferCreateGUI.this);
+ }
+
+ @Override
+ public boolean onResult(String string) {
+ string = ChatColor.stripColor(string);
+
+ if (!MathUtil.isInt(string)) {
+ Common.tell(click.player, TranslationManager.string(click.player, Translations.NOT_A_NUMBER, "value", string));
+ return false;
+ }
+
+ int offerTotal = Integer.parseInt(string);
+
+ if (offerTotal <= 0) {
+ Common.tell(click.player, TranslationManager.string(click.player, Translations.MUST_BE_HIGHER_THAN_ZERO, "value", string));
+ return false;
+ }
+
+ if (offerTotal >= OfferCreateGUI.this.marketItem.getStock()) {
+ offerTotal = OfferCreateGUI.this.marketItem.getStock();
+ }
+
+ OfferCreateGUI.this.offer.setRequestAmount(offerTotal);
+ click.manager.showGUI(click.player, new OfferCreateGUI(OfferCreateGUI.this.parent, OfferCreateGUI.this.player, OfferCreateGUI.this.market, OfferCreateGUI.this.marketItem, OfferCreateGUI.this.offer));
+ return true;
+ }
+ });
+
+ setButton(1, 5, QuickItem
.of(Settings.GUI_OFFER_CREATE_ITEMS_AMOUNT.getItemStack())
.name(TranslationManager.string(this.player, Translations.GUI_OFFER_CREATE_ITEMS_AMOUNT_NAME))
.lore(TranslationManager.list(this.player, Translations.GUI_OFFER_CREATE_ITEMS_AMOUNT_LORE,
@@ -125,6 +166,7 @@ public boolean onResult(String string) {
this.marketItem,
this.offer.getCurrency(),
this.offer.getCurrencyItem(),
+ this.offer.getRequestAmount(),
this.offer.getOfferedAmount(),
created -> {
if (!created) return;
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/view/AllMarketsViewGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/view/AllMarketsViewGUI.java
index 44d30ab2..ca1d8706 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/view/AllMarketsViewGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/view/AllMarketsViewGUI.java
@@ -22,10 +22,8 @@
import ca.tweetzy.markets.settings.Translations;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.SkullMeta;
import java.util.ArrayList;
import java.util.Comparator;
@@ -36,7 +34,7 @@ public final class AllMarketsViewGUI extends MarketsPagedGUI {
MarketUser marketUser;
public AllMarketsViewGUI(Gui parent, @NonNull Player player) {
- super(parent, player, TranslationManager.string(player, Translations.GUI_ALL_MARKETS_TITLE), 6, new ArrayList<>(Markets.getMarketManager().getOpenMarketsExclusive(player)));
+ super(parent, player, TranslationManager.string(player, Translations.GUI_ALL_MARKETS_TITLE), 6, new ArrayList<>());
this.marketUser = Markets.getPlayerManager().get(player.getUniqueId());
setAsync(true);
setDefaultItem(QuickItem.bg(Settings.GUI_ALL_MARKETS_BACKGROUND.getItemStack()));
@@ -45,21 +43,34 @@ public AllMarketsViewGUI(Gui parent, @NonNull Player player) {
@Override
protected void prePopulate() {
+ this.items = new ArrayList<>(Markets.getMarketManager().getOpenMarketsExclusive(player));
+
if (this.marketUser.getMarketSortType() == MarketSortType.NAME) {
- items.sort(Comparator.comparing(Market::getDisplayName).reversed());
+ this.items.sort(Comparator.comparing(Market::getDisplayName).reversed());
}
if (this.marketUser.getMarketSortType() == MarketSortType.ITEMS) {
- items.sort(Comparator.comparing(Market::getItemCount).reversed());
+ this.items.sort(Comparator.comparing(Market::getItemCount).reversed());
}
if (this.marketUser.getMarketSortType() == MarketSortType.REVIEWS) {
- items.sort(Comparator.comparing(Market::getReviewAvg).reversed());
+ this.items.sort(Comparator.comparing(Market::getReviewAvg).reversed());
}
if (this.marketUser.getMarketSortType() == MarketSortType.LAST_UPDATED) {
- items.sort(Comparator.comparing(Market::getLastUpdated).reversed());
+ this.items.sort(Comparator.comparing(Market::getLastUpdated).reversed());
}
+
+ // place server markets first
+ this.items = this.items.stream().sorted((m1, m2) -> {
+ if (m1.isServerMarket() && !m2.isServerMarket()) {
+ return -1;
+ } else if (!m1.isServerMarket() && m2.isServerMarket()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }).toList();
}
@Override
@@ -75,12 +86,12 @@ protected ItemStack makeDisplayItem(Market market) {
));
- return XSkull
+ return XSkull
.of(item.make())
.profile(Profileable.of(market.getOwnerUUID()))
.fallback(Profileable.of(
ProfileInputType.TEXTURE_URL,
- "http://textures.minecraft.net/texture/533fc9a45be13ca57a78b21762c6e1262dae411f13048b963d972a29e07096ab"
+ Settings.SERVER_MARKET_TEXTURE.getString()
))
.lenient()
.apply();
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/view/UserProfileGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/view/UserProfileGUI.java
index a72d42b1..fff53fb1 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/view/UserProfileGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/view/UserProfileGUI.java
@@ -19,14 +19,19 @@
import org.bukkit.inventory.ItemStack;
import java.util.List;
+import java.util.UUID;
public final class UserProfileGUI extends MarketsPagedGUI {
private final OfflinePlayer profileUser;
+ private boolean serverProfile = false;
public UserProfileGUI(Gui parent, @NonNull Player player, @NonNull final OfflinePlayer profileUser) {
- super(parent, player, TranslationManager.string(player, Translations.GUI_USER_PROFILE_TITLE, "player_name", profileUser.getName()), 6, Markets.getRatingManager().getRatingsByOrFor(profileUser));
+ super(parent, player, TranslationManager.string(player, Translations.GUI_USER_PROFILE_TITLE,
+ "player_name", profileUser.getUniqueId().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString())) ? TranslationManager.string(Translations.SERVER_MARKET_NAME) : profileUser.getName()
+ ), 6, Markets.getRatingManager().getRatingsByOrFor(profileUser));
this.profileUser = profileUser;
+ this.serverProfile = profileUser.getUniqueId().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString()));
setDefaultItem(QuickItem.bg(Settings.GUI_USER_PROFILE_BACKGROUND.getItemStack()));
draw();
}
@@ -35,12 +40,14 @@ public UserProfileGUI(Gui parent, @NonNull Player player, @NonNull final Offline
protected void drawFixed() {
final MarketUser user = Markets.getPlayerManager().get(this.profileUser.getUniqueId());
+ ItemStack texture = user.isServerMarket() ? QuickItem.of(Settings.SERVER_MARKET_TEXTURE.getString()).make() : QuickItem.of(this.profileUser).make();
+
setItem(1, 4, QuickItem
- .of(this.profileUser)
- .name(TranslationManager.string(this.player, Translations.GUI_USER_PROFILE_ITEMS_USER_NAME, "player_name", this.profileUser.getName()))
+ .of(texture)
+ .name(TranslationManager.string(this.player, Translations.GUI_USER_PROFILE_ITEMS_USER_NAME, "player_name", serverProfile ? TranslationManager.string(Translations.SERVER_MARKET_NAME) : this.profileUser.getName()))
.lore(TranslationManager.list(this.player, Translations.GUI_USER_PROFILE_ITEMS_USER_LORE,
- "user_last_seen", TimeUtil.convertToReadableDate(user.getLastSeenAt(),Settings.DATETIME_FORMAT.getString()),
- "true", TranslationManager.string(this.player, this.profileUser.isOnline() ? Translations.TRUE : Translations.FALSE)
+ "user_last_seen", TimeUtil.convertToReadableDate(serverProfile ? System.currentTimeMillis() : user.getLastSeenAt(), Settings.DATETIME_FORMAT.getString()),
+ "true", TranslationManager.string(this.player, (this.profileUser.isOnline() || this.serverProfile) ? Translations.TRUE : Translations.FALSE)
))
.make()
);
@@ -55,7 +62,7 @@ protected ItemStack makeDisplayItem(Rating rating) {
.name(TranslationManager.string(player, Translations.GUI_USER_PROFILE_ITEMS_RATING_NAME, "rater_name", rating.getRaterName()))
.lore(TranslationManager.list(player, Translations.GUI_USER_PROFILE_ITEMS_RATING_LORE,
"rating_stars", StringUtils.repeat("★", rating.getStars()),
- "rating_date", TimeUtil.convertToReadableDate(rating.getTimeCreated(),Settings.DATETIME_FORMAT.getString()),
+ "rating_date", TimeUtil.convertToReadableDate(rating.getTimeCreated(), Settings.DATETIME_FORMAT.getString()),
"rating_feedback", rating.getFeedback()
))
.make();
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketCategoryViewGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketCategoryViewGUI.java
index 6923a7f4..589ac828 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketCategoryViewGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketCategoryViewGUI.java
@@ -33,9 +33,10 @@ public final class MarketCategoryViewGUI extends MarketsPagedGUI {
private final Market market;
private final Category category;
private final boolean viewAsCustomer;
+ private final boolean fromAdminCommand;
- public MarketCategoryViewGUI(Gui parent, @NonNull final Player player, @NonNull final Market market, @NonNull final Category category, boolean viewAsCustomer) {
- super(parent, player, TranslationManager.string(player, Translations.GUI_MARKET_CATEGORY_VIEW_TITLE,
+ public MarketCategoryViewGUI(Gui parent, @NonNull final Player player, @NonNull final Market market, @NonNull final Category category, boolean viewAsCustomer, boolean fromAdminCommand) {
+ super(fromAdminCommand ? null : parent, player, TranslationManager.string(player, Translations.GUI_MARKET_CATEGORY_VIEW_TITLE,
"market_display_name", market.getDisplayName(),
"category_display_name", category.getDisplayName()
), 6, category.getInStockItems());
@@ -44,6 +45,7 @@ public MarketCategoryViewGUI(Gui parent, @NonNull final Player player, @NonNull
this.market = market;
this.category = category;
this.viewAsCustomer = viewAsCustomer;
+ this.fromAdminCommand = fromAdminCommand;
setDefaultItem(this.market.getCategoryLayout().getBackgroundItem());
@@ -53,8 +55,12 @@ public MarketCategoryViewGUI(Gui parent, @NonNull final Player player, @NonNull
draw();
}
+ public MarketCategoryViewGUI(@NonNull final Player player, @NonNull final Market market, @NonNull final Category category, boolean viewAsCustomer, boolean fromAdminCommand) {
+ this(new MarketViewGUI(player, market), player, market, category, viewAsCustomer, fromAdminCommand);
+ }
+
public MarketCategoryViewGUI(@NonNull final Player player, @NonNull final Market market, @NonNull final Category category, boolean viewAsCustomer) {
- this(new MarketViewGUI(player, market), player, market, category, viewAsCustomer);
+ this(new MarketViewGUI(player, market), player, market, category, viewAsCustomer, false);
}
@Override
@@ -64,7 +70,7 @@ protected ItemStack makeDisplayItem(MarketItem marketItem) {
item.lore(TranslationManager.list(this.player, Translations.GUI_MARKET_CATEGORY_VIEW_ITEMS_ITEM_LORE_INFO,
"market_item_price", String.format("%,.2f", marketItem.getPrice()),
"market_item_currency", marketItem.getCurrencyDisplayName(),
- "market_item_stock", marketItem.getStock(),
+ "market_item_stock", marketItem.isInfinite() ? "∞" : marketItem.getStock(),
"market_item_wholesale", TranslationManager.string(this.player, marketItem.isPriceForAll() ? Translations.TRUE : Translations.FALSE)
));
@@ -88,7 +94,7 @@ protected void drawFixed() {
// set custom shit
setButton(this.market.getCategoryLayout().getOwnerProfileSlot(), QuickItem
- .of(Bukkit.getOfflinePlayer(this.market.getOwnerUUID()))
+ .of(this.market.getDynamicIcon())
.name(TranslationManager.string(this.player, Translations.GUI_MARKET_CATEGORY_VIEW_ITEMS_PROFILE_NAME))
.lore(TranslationManager.list(this.player, Translations.GUI_MARKET_CATEGORY_VIEW_ITEMS_PROFILE_LORE,
"market_owner", this.market.getOwnerName(),
@@ -154,10 +160,12 @@ public boolean onResult(String string) {
};
});
- setAction(getRows() - 1, 0, click -> {
- this.category.getViewingPlayers().remove(click.player);
- click.manager.showGUI(click.player, new MarketViewGUI(null, this.player, this.market, this.viewAsCustomer));
- });
+ if (!this.fromAdminCommand) {
+ setAction(getRows() - 1, 0, click -> {
+ this.category.getViewingPlayers().remove(click.player);
+ click.manager.showGUI(click.player, new MarketViewGUI(null, this.player, this.market, this.viewAsCustomer));
+ });
+ }
}
@Override
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketSearchGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketSearchGUI.java
index 56daa74e..e3889727 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketSearchGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketSearchGUI.java
@@ -55,7 +55,7 @@ protected ItemStack makeDisplayItem(MarketItem marketItem) {
item.lore(TranslationManager.list(this.player, Translations.GUI_SEARCH_ITEMS_ITEM_LORE_INFO,
"market_item_price", String.format("%,.2f", marketItem.getPrice()),
"market_item_currency", marketItem.getCurrencyDisplayName(),
- "market_item_stock", marketItem.getStock(),
+ "market_item_stock", marketItem.isInfinite() ? "∞" : marketItem.getStock(),
"market_item_wholesale", TranslationManager.string(this.player, marketItem.isPriceForAll() ? Translations.TRUE : Translations.FALSE),
"market_item_owner", itemMarket.getOwnerName(),
"market_item_market_name", itemMarket.getDisplayName()
diff --git a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketViewGUI.java b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketViewGUI.java
index 0de46a83..aa648b1c 100644
--- a/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketViewGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/shared/view/content/MarketViewGUI.java
@@ -52,7 +52,7 @@ protected void drawFixed() {
// set custom shit
setButton(this.market.getHomeLayout().getOwnerProfileSlot(), QuickItem
- .of(Bukkit.getOfflinePlayer(this.market.getOwnerUUID()))
+ .of(this.market.getDynamicIcon())
.name(TranslationManager.string(this.player, Translations.GUI_MARKET_VIEW_ITEMS_PROFILE_NAME))
.lore(TranslationManager.list(this.player, Translations.GUI_MARKET_VIEW_ITEMS_PROFILE_LORE,
"market_owner", this.market.getOwnerName(),
@@ -136,7 +136,7 @@ protected ItemStack makeDisplayItem(Category category) {
@Override
protected void onClick(Category category, GuiClickEvent click) {
- click.manager.showGUI(click.player, new MarketCategoryViewGUI(this, click.player, this.market, category, this.viewingAsCustomer));
+ click.manager.showGUI(click.player, new MarketCategoryViewGUI(this, click.player, this.market, category, this.viewingAsCustomer, false));
}
@Override
diff --git a/src/main/java/ca/tweetzy/markets/gui/user/BankGUI.java b/src/main/java/ca/tweetzy/markets/gui/user/BankGUI.java
index cfffe24e..1fe7bf01 100644
--- a/src/main/java/ca/tweetzy/markets/gui/user/BankGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/user/BankGUI.java
@@ -18,7 +18,9 @@
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+import java.util.HashMap;
import java.util.List;
public final class BankGUI extends MarketsPagedGUI {
@@ -162,11 +164,25 @@ public boolean onResult(String string) {
};
}
+ private void givePlayerItems(Player player, ItemStack itemToGive) {
+ PlayerInventory inventory = player.getInventory();
+ HashMap leftoverItems = inventory.addItem(itemToGive);
+
+ if (!leftoverItems.isEmpty()) {
+ for (ItemStack leftover : leftoverItems.values()) {
+ player.getWorld().dropItemNaturally(player.getLocation(), leftover);
+ }
+ }
+ }
+
private void deleteAndGiveEntry(@NonNull final BankEntry bankEntry, @NonNull final GuiClickEvent click) {
bankEntry.unStore(result -> {
if (result == SynchronizeResult.FAILURE) return;
- for (int i = 0; i < bankEntry.getQuantity(); i++)
- PlayerUtil.giveItem(click.player, bankEntry.getItem());
+ Markets.newChain().sync(() -> {
+ for (int i = 0; i < bankEntry.getQuantity(); i++)
+// PlayerUtil.giveItem(click.player, bankEntry.getItem());
+ givePlayerItems(click.player, bankEntry.getItem());
+ }).execute();
updateAndRedraw();
});
diff --git a/src/main/java/ca/tweetzy/markets/gui/user/TransactionsGUI.java b/src/main/java/ca/tweetzy/markets/gui/user/TransactionsGUI.java
index 1a5aae73..a70de0df 100644
--- a/src/main/java/ca/tweetzy/markets/gui/user/TransactionsGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/user/TransactionsGUI.java
@@ -21,10 +21,12 @@
public final class TransactionsGUI extends MarketsPagedGUI {
private final Player player;
+ private boolean viewAll;
- public TransactionsGUI(Gui parent, @NonNull final Player player) {
- super(parent, player, TranslationManager.string(player, Translations.GUI_TRANSACTIONS_TITLE), 6, new ArrayList<>(Markets.getTransactionManager().getManagerContent()));
+ public TransactionsGUI(Gui parent, @NonNull final Player player, boolean viewAll) {
+ super(parent, player, TranslationManager.string(player, Translations.GUI_TRANSACTIONS_TITLE), 6, new ArrayList<>());
this.player = player;
+ this.viewAll = viewAll;
setAcceptsItems(true);
setDefaultItem(QuickItem.bg(Settings.GUI_TRANSACTIONS_BACKGROUND.getItemStack()));
@@ -33,9 +35,37 @@ public TransactionsGUI(Gui parent, @NonNull final Player player) {
@Override
protected void prePopulate() {
+ if (this.viewAll) {
+ this.items = new ArrayList<>(Markets.getTransactionManager().getManagerContent());
+ } else {
+ this.items = new ArrayList<>(Markets.getTransactionManager().getOfflineTransactionsFor(this.player.getUniqueId()));
+ }
+
this.items.sort(Comparator.comparing(Transaction::getTimeCreated).reversed());
}
+ @Override
+ protected void drawFixed() {
+ if (!Settings.USE_ADDITIONAL_CONFIRMS.getBoolean()) {
+ setTransactionViewButton();
+ } else {
+ if (this.player.hasPermission("markets.viewalltransactions"))
+ setTransactionViewButton();
+ }
+ }
+
+ private void setTransactionViewButton() {
+ setButton(getRows() - 1, 8, QuickItem
+ .of(Settings.GUI_TRANSACTIONS_VIEW_ALL_ITEM.getItemStack())
+ .name(TranslationManager.string(Translations.GUI_TRANSACTIONS_ITEMS_VIEW_ALL_NAME))
+ .lore(TranslationManager.list(Translations.GUI_TRANSACTIONS_ITEMS_VIEW_ALL_LORE, "is_true", TranslationManager.string(this.viewAll ? Translations.TRUE : Translations.FALSE), "left_click", TranslationManager.string(Translations.MOUSE_LEFT_CLICK)))
+ .make(), click -> {
+
+ this.viewAll = !this.viewAll;
+ draw();
+ });
+ }
+
@Override
protected ItemStack makeDisplayItem(Transaction transaction) {
final ItemStack item = transaction.getItem();
diff --git a/src/main/java/ca/tweetzy/markets/gui/user/category/CategoryNewItemGUI.java b/src/main/java/ca/tweetzy/markets/gui/user/category/CategoryNewItemGUI.java
index a64f0202..619259d5 100644
--- a/src/main/java/ca/tweetzy/markets/gui/user/category/CategoryNewItemGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/user/category/CategoryNewItemGUI.java
@@ -13,6 +13,7 @@
import ca.tweetzy.markets.gui.MarketsBaseGUI;
import ca.tweetzy.markets.gui.shared.selector.CurrencyPickerGUI;
import ca.tweetzy.markets.impl.CategoryItem;
+import ca.tweetzy.markets.model.BlacklistChecker;
import ca.tweetzy.markets.settings.Settings;
import ca.tweetzy.markets.settings.Translations;
import lombok.NonNull;
@@ -141,8 +142,13 @@ public boolean onResult(String string) {
}));
});
- // offers
- drawOffersButton();
+ // server market can't have offers
+ if (this.market.isServerMarket()) {
+ drawInfiniteButton();
+ } else {
+ drawOffersButton();
+ }
+
// new item button
setButton(getRows() - 1, 4, QuickItem.of(Settings.GUI_CATEGORY_ADD_ITEM_ITEMS_NEW_ITEM_ITEM.getItemStack()).name(TranslationManager.string(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_NEW_ITEM_NAME)).lore(TranslationManager.list(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_NEW_ITEM_LORE, "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK))).make(), click -> {
@@ -153,10 +159,17 @@ public boolean onResult(String string) {
return;
}
+ // check blacklist
+ if (!BlacklistChecker.passesChecks(click.player, placedItem)) return;
+
this.marketItem.setItem(placedItem.clone());
this.marketItem.setStock(placedItem.clone().getAmount());
if (this.marketItem.getPrice() <= 0) return;
+ if (this.market.isServerMarket()) {
+ this.marketItem.setIsAcceptingOffers(false);
+ }
+
// create the item
Bukkit.getScheduler().runTaskLaterAsynchronously(Markets.getInstance(), () -> {
if (!click.gui.isOpen()) {
@@ -164,7 +177,7 @@ public boolean onResult(String string) {
return;
}
- Markets.getCategoryItemManager().create(this.category, this.marketItem.getItem(), this.marketItem.getCurrency(), this.marketItem.getCurrencyItem(), this.marketItem.getPrice(), this.marketItem.isPriceForAll(), this.marketItem.isAcceptingOffers(), false, created -> {
+ Markets.getCategoryItemManager().create(this.category, this.marketItem.getItem(), this.marketItem.getCurrency(), this.marketItem.getCurrencyItem(), this.marketItem.getPrice(), this.marketItem.isPriceForAll(), this.marketItem.isAcceptingOffers(), this.marketItem.isInfinite(), created -> {
if (created) {
setItem(1, 4, CompMaterial.AIR.parseItem());
click.manager.showGUI(click.player, new MarketCategoryEditGUI(this.player, this.market, this.category));
@@ -191,7 +204,15 @@ public boolean onResult(String string) {
private void drawOffersButton() {
if (!Settings.DISABLE_OFFERS.getBoolean()) {
- setButton(getRows() - 1, 2, QuickItem.of(Settings.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_ITEM.getItemStack()).name(TranslationManager.string(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_NAME)).lore(TranslationManager.list(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_LORE, "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK), "enabled", TranslationManager.string(this.player, this.marketItem.isAcceptingOffers() ? Translations.ENABLED : Translations.DISABLED))).hideTags(true).make(), click -> {
+ setButton(getRows() - 1, 2, QuickItem
+ .of(Settings.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_ITEM.getItemStack())
+ .name(TranslationManager.string(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_LORE,
+ "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK),
+ "enabled", TranslationManager.string(this.player, this.marketItem.isAcceptingOffers() ? Translations.ENABLED : Translations.DISABLED)))
+ .hideTags(true)
+ .make(), click -> {
+
if (getItem(1, 4) != null) this.marketItem.setItem(getItem(1, 4));
this.marketItem.setIsAcceptingOffers(!this.marketItem.isAcceptingOffers());
@@ -218,4 +239,20 @@ private void drawPriceForAllButton() {
});
}
}
+
+ private void drawInfiniteButton() {
+ setButton(getRows() - 1, 2, QuickItem
+ .of(Settings.GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_ITEM.getItemStack())
+ .name(TranslationManager.string(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_NAME))
+ .lore(TranslationManager.list(this.player, Translations.GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_LORE,
+ "left_click", TranslationManager.string(this.player, Translations.MOUSE_LEFT_CLICK),
+ "enabled", TranslationManager.string(this.player, this.marketItem.isInfinite() ? Translations.ENABLED : Translations.DISABLED)))
+ .hideTags(true)
+ .make(), click -> {
+
+
+ this.marketItem.setInfinite(!this.marketItem.isInfinite());
+ click.manager.showGUI(click.player, new CategoryNewItemGUI(CategoryNewItemGUI.this.player, CategoryNewItemGUI.this.market, CategoryNewItemGUI.this.category, CategoryNewItemGUI.this.marketItem));
+ });
+ }
}
diff --git a/src/main/java/ca/tweetzy/markets/gui/user/category/MarketItemEditGUI.java b/src/main/java/ca/tweetzy/markets/gui/user/category/MarketItemEditGUI.java
index 9cab0326..7d43ec1e 100644
--- a/src/main/java/ca/tweetzy/markets/gui/user/category/MarketItemEditGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/user/category/MarketItemEditGUI.java
@@ -2,7 +2,12 @@
import ca.tweetzy.flight.comp.enums.CompMaterial;
import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.Common;
+import ca.tweetzy.flight.utils.MathUtil;
+import ca.tweetzy.flight.utils.PlayerUtil;
import ca.tweetzy.flight.utils.QuickItem;
+import ca.tweetzy.flight.utils.input.TitleInput;
+import ca.tweetzy.markets.Markets;
import ca.tweetzy.markets.api.SynchronizeResult;
import ca.tweetzy.markets.api.market.core.Category;
import ca.tweetzy.markets.api.market.core.Market;
@@ -12,7 +17,11 @@
import ca.tweetzy.markets.settings.Settings;
import ca.tweetzy.markets.settings.Translations;
import lombok.NonNull;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
public final class MarketItemEditGUI extends MarketsBaseGUI {
@@ -47,20 +56,80 @@ protected void draw() {
private void drawStockButton() {
setButton(3, 7, QuickItem.of(Settings.GUI_EDIT_ITEM_ITEMS_STOCK_ITEM.getItemStack())
.name(TranslationManager.string(this.player, Translations.GUI_EDIT_ITEM_ITEMS_STOCK_NAME))
- .lore(TranslationManager.list(this.player, Translations.GUI_EDIT_ITEM_ITEMS_STOCK_LORE, "market_item_stock", this.marketItem.getStock()))
+ .lore(TranslationManager.list(this.player, Translations.GUI_EDIT_ITEM_ITEMS_STOCK_LORE,
+ "market_item_stock", this.marketItem.getStock(),
+ "right_click", TranslationManager.string(this.player, Translations.MOUSE_RIGHT_CLICK),
+ "shift_left_click", TranslationManager.string(this.player, Translations.MOUSE_SHIFT_LEFT_CLICK)
+ ))
.make(), click -> {
- final ItemStack cursor = click.cursor;
- if (cursor != null && cursor.getType() != CompMaterial.AIR.parseMaterial()) {
- if (!this.marketItem.getItem().isSimilar(cursor)) return;
+ if (click.clickType == ClickType.LEFT) {
+ final ItemStack cursor = click.cursor;
+ if (cursor != null && cursor.getType() != CompMaterial.AIR.parseMaterial()) {
+ if (!this.marketItem.getItem().isSimilar(cursor)) return;
- this.marketItem.addStock(cursor, result -> {
- if (result == SynchronizeResult.FAILURE) return;
+ this.marketItem.addStock(cursor, result -> {
+ if (result == SynchronizeResult.FAILURE) return;
+
+ click.player.setItemOnCursor(CompMaterial.AIR.parseItem());
+ drawStockButton();
+ });
+ }
+ }
+
+ if (click.clickType == ClickType.SHIFT_LEFT) {
+ int itemCount = PlayerUtil.getItemCountInPlayerInventory(click.player, this.marketItem.getItem());
+ if (itemCount == 0) return;
+
+ this.marketItem.setStock(this.marketItem.getStock() + itemCount);
+ PlayerUtil.removeSpecificItemQuantityFromPlayer(click.player, this.marketItem.getItem(), itemCount);
- click.player.setItemOnCursor(CompMaterial.AIR.parseItem());
+ this.marketItem.sync(result -> {
+ if (result == SynchronizeResult.FAILURE) return;
drawStockButton();
});
}
+
+ if (click.clickType == ClickType.RIGHT) {
+ new TitleInput(Markets.getInstance(), click.player, TranslationManager.string(click.player, Translations.PROMPT_STOCK_WITHDRAW_TITLE), TranslationManager.string(click.player, Translations.PROMPT_STOCK_WITHDRAW_SUBTITLE)) {
+ @Override
+ public void onExit(Player player) {
+ click.manager.showGUI(click.player, MarketItemEditGUI.this);
+ }
+
+ @Override
+ public boolean onResult(String string) {
+ string = ChatColor.stripColor(string);
+
+ if (!MathUtil.isInt(string)) {
+ Common.tell(click.player, TranslationManager.string(click.player, Translations.NOT_A_NUMBER, "value", string));
+ return false;
+ }
+
+ int qty = Integer.parseInt(string);
+ if (marketItem.getStock() < qty) {
+ Common.tell(click.player, TranslationManager.string(click.player, Translations.NOT_ENOUGH_STOCK));
+ return false;
+ }
+
+ marketItem.setStock(marketItem.getStock() - qty);
+
+ final ItemStack item = marketItem.getItem().clone();
+ item.setAmount(1);
+
+ Bukkit.getServer().getScheduler().runTask(Markets.getInstance(), () -> {
+ for (int i = 0; i < qty; i++)
+ PlayerUtil.giveItem(click.player, item);
+ });
+
+ marketItem.sync(result -> {
+ click.manager.showGUI(click.player, new MarketItemEditGUI(click.player, MarketItemEditGUI.this.market, MarketItemEditGUI.this.category, MarketItemEditGUI.this.marketItem));
+ });
+
+ return true;
+ }
+ };
+ }
});
}
diff --git a/src/main/java/ca/tweetzy/markets/gui/user/market/MarketOverviewGUI.java b/src/main/java/ca/tweetzy/markets/gui/user/market/MarketOverviewGUI.java
index dc8ece9f..0b544716 100644
--- a/src/main/java/ca/tweetzy/markets/gui/user/market/MarketOverviewGUI.java
+++ b/src/main/java/ca/tweetzy/markets/gui/user/market/MarketOverviewGUI.java
@@ -159,20 +159,51 @@ public boolean onResult(String string) {
)).make(), click -> click.manager.showGUI(click.player, new MarketRatingsViewGUI(this, click.player, this.market)));
// unStore button
- setButton(getRows() - 1, 8, QuickItem
- .of(Settings.GUI_MARKET_OVERVIEW_ITEMS_DELETE_ITEM.getItemStack())
- .name(TranslationManager.string(Translations.GUI_MARKET_OVERVIEW_ITEMS_DELETE_NAME))
- .lore(TranslationManager.list(Translations.GUI_MARKET_OVERVIEW_ITEMS_DELETE_LORE))
- .make(), click -> {
+ if (!this.market.isServerMarket()) {
+ setButton(getRows() - 1, 8, QuickItem
+ .of(Settings.GUI_MARKET_OVERVIEW_ITEMS_DELETE_ITEM.getItemStack())
+ .name(TranslationManager.string(Translations.GUI_MARKET_OVERVIEW_ITEMS_DELETE_NAME))
+ .lore(TranslationManager.list(Translations.GUI_MARKET_OVERVIEW_ITEMS_DELETE_LORE))
+ .make(), click -> {
+
+ if (Settings.USE_ADDITIONAL_CONFIRMS.getBoolean()) {
+
+ click.manager.showGUI(click.player, new ConfirmGUI(this, click.player, confirmed -> {
+ if (!confirmed) {
+ click.manager.showGUI(click.player, new MarketOverviewGUI(click.player, this.market));
+ return;
+ }
- if (Settings.USE_ADDITIONAL_CONFIRMS.getBoolean()) {
+ // skip category check if there is none
+ if (this.market.getCategories().isEmpty()) {
+ // just delete since no categories
+ yeetMarket(click);
+ return;
+ }
- click.manager.showGUI(click.player, new ConfirmGUI(this, click.player, confirmed -> {
- if (!confirmed) {
- click.manager.showGUI(click.player, new MarketOverviewGUI(click.player, this.market));
- return;
- }
+ // loop through categories with items
+ market.getCategories().forEach(category -> {
+ category.getItems().forEach(item -> item.getViewingPlayers().clear());
+
+ Markets.getDataManager().deleteMarketItems(category, (error, itemResult) -> {
+ if (error == null && itemResult) {
+ category.getItems().forEach(item -> {
+ giveBackMarketItem(item);
+ Markets.getCategoryItemManager().remove(item);
+ });
+ }
+ });
+ });
+
+ // kill categories
+ market.getCategories().forEach(category -> category.unStore(categoryRemoveResult -> {
+ }));
+
+ // remove market
+ yeetMarket(click);
+ }));
+ } else {
// skip category check if there is none
if (this.market.getCategories().isEmpty()) {
// just delete since no categories
@@ -200,38 +231,9 @@ public boolean onResult(String string) {
// remove market
yeetMarket(click);
- }));
-
- } else {
- // skip category check if there is none
- if (this.market.getCategories().isEmpty()) {
- // just delete since no categories
- yeetMarket(click);
- return;
}
-
- // loop through categories with items
- market.getCategories().forEach(category -> {
- category.getItems().forEach(item -> item.getViewingPlayers().clear());
-
- Markets.getDataManager().deleteMarketItems(category, (error, itemResult) -> {
- if (error == null && itemResult) {
- category.getItems().forEach(item -> {
- giveBackMarketItem(item);
- Markets.getCategoryItemManager().remove(item);
- });
- }
- });
- });
-
- // kill categories
- market.getCategories().forEach(category -> category.unStore(categoryRemoveResult -> {
- }));
-
- // remove market
- yeetMarket(click);
- }
- });
+ });
+ }
}
private void yeetMarket(@NonNull final GuiClickEvent event) {
diff --git a/src/main/java/ca/tweetzy/markets/impl/CategoryItem.java b/src/main/java/ca/tweetzy/markets/impl/CategoryItem.java
index 9b5fbd86..25ed3d36 100644
--- a/src/main/java/ca/tweetzy/markets/impl/CategoryItem.java
+++ b/src/main/java/ca/tweetzy/markets/impl/CategoryItem.java
@@ -248,13 +248,15 @@ public void performPurchase(@NonNull final Market market, @NonNull Player buyer,
this.stock = 0;
- if (Settings.AUTO_REMOVE_ITEM_WHEN_OUT_OF_STOCK.getBoolean()) {
- unStore(result -> alertOutOfStock(seller, buyer, newPurchaseAmount));
- } else {
- sync(result -> alertOutOfStock(seller, buyer, newPurchaseAmount));
+ if (!market.isServerMarket()) {
+ if (Settings.AUTO_REMOVE_ITEM_WHEN_OUT_OF_STOCK.getBoolean()) {
+ unStore(result -> alertOutOfStock(seller, buyer, newPurchaseAmount));
+ } else {
+ sync(result -> alertOutOfStock(seller, buyer, newPurchaseAmount));
+ }
}
} else {
- if (seller.isOnline()) {
+ if (!market.isServerMarket() && seller.isOnline()) {
Common.tell(seller.getPlayer(), TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
"purchase_price", isCurrencyOfItem() ? total : (int) total,
"purchase_quantity", newPurchaseAmount,
@@ -265,47 +267,51 @@ public void performPurchase(@NonNull final Market market, @NonNull Player buyer,
}
} else {
- if (!this.infinite) {
- setStock(newStock);
- sync(result -> {
+ if (!market.isServerMarket()) {
+ if (!this.infinite) {
+ setStock(newStock);
+ sync(result -> {
+ if (seller.isOnline()) {
+ Common.tell(seller.getPlayer(), TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
+ "purchase_quantity", newPurchaseAmount,
+ "item_name", ItemUtil.getItemName(this.item),
+ "buyer_name", buyer.getName()
+ ));
+ }
+ });
+ } else {
if (seller.isOnline()) {
Common.tell(seller.getPlayer(), TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
+ "purchase_price", isCurrencyOfItem() ? total : (int) total,
"purchase_quantity", newPurchaseAmount,
"item_name", ItemUtil.getItemName(this.item),
"buyer_name", buyer.getName()
));
}
- });
- } else {
- if (seller.isOnline()) {
- Common.tell(seller.getPlayer(), TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
- "purchase_price", isCurrencyOfItem() ? total : (int) total,
- "purchase_quantity", newPurchaseAmount,
- "item_name", ItemUtil.getItemName(this.item),
- "buyer_name", buyer.getName()
- ));
}
}
}
- if (isCurrencyOfItem()) {
- if (seller.isOnline() && seller.getPlayer() != null)
- Markets.getCurrencyManager().deposit(seller.getPlayer(), this.currencyItem, (int) total);
- else
- Markets.getOfflineItemPaymentManager().create(
- seller.getUniqueId(),
- this.currencyItem,
- (int) total,
- TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
- "purchase_price", isCurrencyOfItem() ? total : (int) total,
- "purchase_quantity", newPurchaseAmount,
- "item_name", ItemUtil.getItemName(this.item),
- "buyer_name", buyer.getName()
- ), created -> {
- // todo maybe do something here
- });
- } else {
- Markets.getCurrencyManager().deposit(seller, currencyPlugin, currencyName, total);
+ if (!market.isServerMarket()) {
+ if (isCurrencyOfItem()) {
+ if (seller.isOnline() && seller.getPlayer() != null)
+ Markets.getCurrencyManager().deposit(seller.getPlayer(), this.currencyItem, (int) total);
+ else
+ Markets.getOfflineItemPaymentManager().create(
+ seller.getUniqueId(),
+ this.currencyItem,
+ (int) total,
+ TranslationManager.string(seller.getPlayer(), Translations.MARKET_ITEM_BOUGHT_SELLER,
+ "purchase_price", isCurrencyOfItem() ? total : (int) total,
+ "purchase_quantity", newPurchaseAmount,
+ "item_name", ItemUtil.getItemName(this.item),
+ "buyer_name", buyer.getName()
+ ), created -> {
+ // todo maybe do something here
+ });
+ } else {
+ Markets.getCurrencyManager().deposit(seller, currencyPlugin, currencyName, total);
+ }
}
// insert tax
diff --git a/src/main/java/ca/tweetzy/markets/impl/MarketOffer.java b/src/main/java/ca/tweetzy/markets/impl/MarketOffer.java
index d49f393f..f51b0c4c 100644
--- a/src/main/java/ca/tweetzy/markets/impl/MarketOffer.java
+++ b/src/main/java/ca/tweetzy/markets/impl/MarketOffer.java
@@ -31,7 +31,7 @@ public final class MarketOffer implements Offer {
private final String senderName;
private final UUID offerTo;
private final UUID marketItem;
- private final int requestAmount;
+ private int requestAmount;
private String currency;
private ItemStack currencyItem;
private double offeredAmount;
@@ -113,6 +113,11 @@ public void setOfferedAmount(double amount) {
this.offeredAmount = amount;
}
+ @Override
+ public void setRequestAmount(int amount) {
+ this.requestAmount = amount;
+ }
+
@Override
public long getTimeCreated() {
return this.offeredAt;
@@ -207,8 +212,13 @@ private void giveItemAndCleanup(@NonNull final MarketItem marketItem, @NonNull C
});
// delete the item
- marketItem.unStore(result -> {
- });
+
+ int newTotal = marketItem.getStock() - this.requestAmount;
+ if (newTotal < 0)
+ newTotal = 0;
+
+ marketItem.setStock(newTotal);
+ marketItem.sync(null);
Markets.getOfflineItemPaymentManager().create(
this.sender,
diff --git a/src/main/java/ca/tweetzy/markets/impl/PlayerMarket.java b/src/main/java/ca/tweetzy/markets/impl/PlayerMarket.java
index 45f9860a..309f21ab 100644
--- a/src/main/java/ca/tweetzy/markets/impl/PlayerMarket.java
+++ b/src/main/java/ca/tweetzy/markets/impl/PlayerMarket.java
@@ -11,7 +11,7 @@
import java.util.UUID;
import java.util.function.Consumer;
-public final class PlayerMarket extends AbstractMarket {
+public class PlayerMarket extends AbstractMarket {
private final UUID id;
diff --git a/src/main/java/ca/tweetzy/markets/impl/ServerMarket.java b/src/main/java/ca/tweetzy/markets/impl/ServerMarket.java
new file mode 100644
index 00000000..45d18cf9
--- /dev/null
+++ b/src/main/java/ca/tweetzy/markets/impl/ServerMarket.java
@@ -0,0 +1,18 @@
+package ca.tweetzy.markets.impl;
+
+import ca.tweetzy.markets.api.market.core.Category;
+import ca.tweetzy.markets.api.market.core.MarketType;
+import ca.tweetzy.markets.api.market.core.Rating;
+import ca.tweetzy.markets.api.market.layout.Layout;
+import lombok.NonNull;
+
+import java.util.List;
+import java.util.UUID;
+
+public final class ServerMarket extends PlayerMarket{
+
+ public ServerMarket(@NonNull UUID id, @NonNull UUID ownerUUID, @NonNull String ownerName, @NonNull String displayName, @NonNull List description, @NonNull List categories, @NonNull List ratings, @NonNull List bannedUsers, boolean open, boolean closeWhenOutOfStock, Layout homeLayout, Layout categoryLayout, long createdAt, long updatedAt) {
+ super(id, ownerUUID, ownerName, displayName, description, categories, ratings, bannedUsers, open, closeWhenOutOfStock, homeLayout, categoryLayout, createdAt, updatedAt);
+ this.marketType = MarketType.SERVER;
+ }
+}
diff --git a/src/main/java/ca/tweetzy/markets/listeners/MarketTransactionListener.java b/src/main/java/ca/tweetzy/markets/listeners/MarketTransactionListener.java
index 8e50ea6d..3030bdab 100644
--- a/src/main/java/ca/tweetzy/markets/listeners/MarketTransactionListener.java
+++ b/src/main/java/ca/tweetzy/markets/listeners/MarketTransactionListener.java
@@ -5,6 +5,7 @@
import ca.tweetzy.markets.api.event.MarketTransactionEvent;
import ca.tweetzy.markets.api.market.Transaction;
import ca.tweetzy.markets.impl.MarketTransaction;
+import ca.tweetzy.markets.settings.Settings;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -19,7 +20,7 @@ public void onTransactionEvent(final MarketTransactionEvent event) {
event.getBuyer().getUniqueId(),
event.getBuyer().getName(),
event.getSeller().getUniqueId(),
- event.getSeller().getName(),
+ event.getSeller().getUniqueId().equals(UUID.fromString(Settings.SERVER_MARKET_UUID.getString())) ? Settings.NAME.getString() : event.getSeller().getName(),
event.getType(),
event.getItem(),
event.getCurrency(),
diff --git a/src/main/java/ca/tweetzy/markets/model/BlacklistChecker.java b/src/main/java/ca/tweetzy/markets/model/BlacklistChecker.java
index e90edc5e..46a53f1f 100644
--- a/src/main/java/ca/tweetzy/markets/model/BlacklistChecker.java
+++ b/src/main/java/ca/tweetzy/markets/model/BlacklistChecker.java
@@ -1,9 +1,117 @@
package ca.tweetzy.markets.model;
+import ca.tweetzy.flight.comp.enums.ServerVersion;
+import ca.tweetzy.flight.nbtapi.NBT;
+import ca.tweetzy.flight.settings.TranslationManager;
+import ca.tweetzy.flight.utils.ChatUtil;
+import ca.tweetzy.flight.utils.Common;
+import ca.tweetzy.markets.settings.Settings;
+import ca.tweetzy.markets.settings.Translations;
import lombok.experimental.UtilityClass;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
@UtilityClass
public final class BlacklistChecker {
+ public boolean passesChecks(Player player, ItemStack itemStack) {
+ boolean meets = true;
+
+ for (String item : Settings.BLOCKED_ITEMS.getStringList()) {
+ final String[] split = item.split(":");
+
+ if (split.length == 1) {
+ if (split[0].contains(itemStack.getType().name())) {
+ Common.tell(player, TranslationManager.string(Translations.BLOCKED_ITEM, "item", ChatUtil.capitalize(itemStack.getType())));
+ return false;
+ }
+ }
+
+ if (split.length == 2 && isInt(split[1]) && ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) {
+ if (split[0].contains(itemStack.getType().name()) && itemStack.getItemMeta() != null && itemStack.getItemMeta().getCustomModelData() == Integer.parseInt(split[1])) {
+ Common.tell(player, TranslationManager.string(Translations.BLOCKED_ITEM, "item", ChatUtil.capitalize(itemStack.getType())));
+ return false;
+ }
+ }
+ }
+
+ // Check NBT tags
+ for (String nbtTag : Settings.BLOCKED_NBT_TAGS.getStringList()) {
+ if (NBT.get(itemStack, nbt -> (boolean) nbt.hasTag(nbtTag))) {
+ Common.tell(player, TranslationManager.string(Translations.BLOCKED_ITEM_TAG, ChatUtil.capitalize(itemStack.getType())));
+ return false;
+ }
+ }
+
+ String itemName = ChatColor.stripColor(getItemName(itemStack).toLowerCase());
+ List itemLore = getItemLore(itemStack).stream().map(line -> ChatColor.stripColor(line.toLowerCase())).toList();
+
+ // Check for blocked names and lore
+ for (String s : Settings.BLOCKED_ITEM_NAMES.getStringList()) {
+ if (match(s, itemName)) {
+ Common.tell(player, TranslationManager.string(Translations.BLOCKED_ITEM_NAME, "blacklisted_word", s));
+ meets = false;
+ break;
+ }
+ }
+
+ if (!itemLore.isEmpty() && meets) {
+ for (String s : Settings.BLOCKED_ITEM_LORES.getStringList()) {
+ for (String line : itemLore) {
+ if (match(s, line)) {
+ Common.tell(player, TranslationManager.string(Translations.BLOCKED_ITEM_LORE, "blacklisted_word", s));
+ meets = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return meets;
+ }
+
+ private boolean match(String pattern, String sentence) {
+ Pattern patt = Pattern.compile("\\b" + Pattern.quote(ChatColor.stripColor(pattern)) + "\\b", Pattern.CASE_INSENSITIVE);
+ Matcher matcher = patt.matcher(sentence);
+ return matcher.find();
+ }
+
+ private String getItemName(ItemStack stack) {
+ Objects.requireNonNull(stack, "Item stack cannot be null when getting name");
+ final String name = stack.getItemMeta().hasDisplayName() ? stack.getItemMeta().getDisplayName() : ChatUtil.capitalizeFully(stack.getType());
+ return name;
+ }
+
+ /**
+ * Used to get the lore from an item stack
+ *
+ * @param stack is the item being checked
+ * @return the item lore if available
+ */
+ private List getItemLore(ItemStack stack) {
+ List lore = new ArrayList<>();
+ Objects.requireNonNull(stack, "Item stack cannot be null when getting lore");
+ if (stack.hasItemMeta()) {
+ if (stack.getItemMeta().hasLore() && stack.getItemMeta().getLore() != null) {
+ lore.addAll(stack.getItemMeta().getLore());
+ }
+ }
+ return lore;
+ }
+ private boolean isInt(String s) {
+ try {
+ Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/main/java/ca/tweetzy/markets/model/manager/MarketManager.java b/src/main/java/ca/tweetzy/markets/model/manager/MarketManager.java
index fdc6e475..b425af33 100644
--- a/src/main/java/ca/tweetzy/markets/model/manager/MarketManager.java
+++ b/src/main/java/ca/tweetzy/markets/model/manager/MarketManager.java
@@ -5,10 +5,12 @@
import ca.tweetzy.flight.utils.Filterer;
import ca.tweetzy.markets.Markets;
import ca.tweetzy.markets.api.manager.ListManager;
+import ca.tweetzy.markets.api.market.core.AbstractMarket;
import ca.tweetzy.markets.api.market.core.Category;
import ca.tweetzy.markets.api.market.core.Market;
import ca.tweetzy.markets.api.market.core.MarketItem;
import ca.tweetzy.markets.impl.PlayerMarket;
+import ca.tweetzy.markets.impl.ServerMarket;
import ca.tweetzy.markets.impl.layout.HomeLayout;
import ca.tweetzy.markets.settings.Settings;
import ca.tweetzy.markets.settings.Translations;
@@ -52,6 +54,15 @@ public List getOpenMarketsExclusive(@NonNull final OfflinePlayer ignored
return getManagerContent().stream().filter(market -> !market.getOwnerUUID().equals(ignoredUser.getUniqueId()) && market.isOpen() && !market.isEmpty()).collect(Collectors.toList());
}
+ public ServerMarket getServerMarket() {
+ return getManagerContent()
+ .stream()
+ .filter(ServerMarket.class::isInstance)
+ .map(ServerMarket.class::cast)
+ .findFirst()
+ .orElse(null);
+ }
+
public List getOpenMarketsInclusive() {
return getManagerContent().stream().filter(Market::isOpen).collect(Collectors.toList());
}
diff --git a/src/main/java/ca/tweetzy/markets/model/manager/OfferManager.java b/src/main/java/ca/tweetzy/markets/model/manager/OfferManager.java
index da2129cf..6c7d5a28 100644
--- a/src/main/java/ca/tweetzy/markets/model/manager/OfferManager.java
+++ b/src/main/java/ca/tweetzy/markets/model/manager/OfferManager.java
@@ -30,14 +30,14 @@ public List getOffersSentTo(@NonNull final UUID playerUUID) {
return getManagerContent().stream().filter(offer -> offer.getOfferFor().equals(playerUUID)).collect(Collectors.toList());
}
- public void create(@NonNull final Player sender, @NonNull final Market owningMarket, @NonNull final MarketItem marketItem, @NonNull final String currency, @NonNull final ItemStack currencyItem, final double offeredAmount, @NonNull final Consumer created) {
+ public void create(@NonNull final Player sender, @NonNull final Market owningMarket, @NonNull final MarketItem marketItem, @NonNull final String currency, @NonNull final ItemStack currencyItem, final int amountWant, final double offeredAmount, @NonNull final Consumer created) {
final Offer offer = new MarketOffer(
UUID.randomUUID(),
sender.getUniqueId(),
sender.getName(),
owningMarket.getOwnerUUID(),
marketItem.getId(),
- marketItem.getStock(),
+ amountWant,
currency,
currencyItem,
offeredAmount,
diff --git a/src/main/java/ca/tweetzy/markets/settings/Settings.java b/src/main/java/ca/tweetzy/markets/settings/Settings.java
index dd25d134..218778ab 100644
--- a/src/main/java/ca/tweetzy/markets/settings/Settings.java
+++ b/src/main/java/ca/tweetzy/markets/settings/Settings.java
@@ -5,13 +5,41 @@
import ca.tweetzy.flight.settings.FlightSettings;
import ca.tweetzy.markets.Markets;
+import java.util.Collections;
import java.util.List;
public final class Settings extends FlightSettings {
public static ConfigEntry PREFIX = create("prefix", "&8[&eMarkets&8]").withComment("The prefix for the plugin");
+ public static ConfigEntry NAME = create("name", "&eMarkets").withComment("The plugin name");
public static ConfigEntry LANGUAGE = create("language", "en_us").withComment("The primary language of the plugin");
public static ConfigEntry DATETIME_FORMAT = create("date time format", "MMM dd, yyyy hh:mm:ss a").withComment("How should timestamps be formatted");
+
+
+ /*
+ ========================= Database Stuff =========================
+ */
+ public static final ConfigEntry DATABASE_USE = create("database.use database", false, "Should the plugin use a database to store market data?");
+ public static final ConfigEntry DATABASE_TABLE_PREFIX = create("database.table prefix", "markets_", "What prefix should be used for table names");
+ public static final ConfigEntry DATABASE_HOST = create("database.host", "localhost", "What is the connection url/host");
+ public static final ConfigEntry DATABASE_PORT = create("database.port", 3306, "What is the port to database (default is 3306)");
+ public static final ConfigEntry DATABASE_NAME = create("database.name", "plugin_dev", "What is the name of the database?");
+ public static final ConfigEntry DATABASE_USERNAME = create("database.username", "root", "What is the name of the user connecting?");
+ public static final ConfigEntry DATABASE_PASSWORD = create("database.password", "Password1.", "What is the password to the user connecting?");
+ public static final ConfigEntry DATABASE_CUSTOM_PARAMS = create("database.custom parameters", "?useUnicode=yes&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true&useSSL=true", "Leave this alone if you don't know what you're doing. Set to 'None' to use no custom connection params");
+
+
+ /*
+ ========================= Admin Market Stuff =========================
+ */
+ public static final ConfigEntry SERVER_MARKET_UUID = create("settings.server market.uuid", "00000000-0000-0000-0000-000000000000", "Do not touch this");
+ public static final ConfigEntry SERVER_MARKET_TEXTURE = create("settings.server market.icon", "http://textures.minecraft.net/texture/533fc9a45be13ca57a78b21762c6e1262dae411f13048b963d972a29e07096ab", "The head texture url or item name for the server market icon");
+
+
+ /*
+ ========================= General Settings =========================
+ */
+
public static ConfigEntry MAIN_COMMAND_REQUIRES_PERM = create("settings.main command requires permission", false).withComment("If true, players will need the permission: 'markets.command' to use /markets");
public static ConfigEntry DEFAULT_MAX_ALLOWED_MARKET_ITEMS = create("settings.max allowed market items", 64).withComment("The maximum # of items a player can add to their market before special permissions.");
public static ConfigEntry DEFAULT_MAX_ALLOWED_MARKET_CATEGORIES = create("settings.max allowed market categories", 20).withComment("The maximum # of categories a player can add to their market before special permissions.");
@@ -46,9 +74,10 @@ public final class Settings extends FlightSettings {
public static ConfigEntry DISABLE_OFFERS = create("settings.disable offers", false).withComment("If true, offers will be disabled");
public static ConfigEntry DISABLE_WHOLESALE = create("settings.disable wholesale", false).withComment("If true, wholesale will be disabled");
public static ConfigEntry DISABLE_LAYOUT_EDITING = create("settings.disable layout editing", false).withComment("If true, users will not be able to change the layout of their markets");
- public static ConfigEntry PURCHASE_ITEM_SHIFT_MULTI_AMT = create("settings.purchase item.shift multiply amount",10).withComment("Ex. if the player shift clicks the increase 5 button it becomes 50, 1 -> 10, 10 -> 100");
- public static ConfigEntry REQUEST_MENU_SHOWS_OWN_FIRST = create("settings.request menu shows own first",true).withComment("If false, the request menu will show global requests by default instead of your own.");
- public static ConfigEntry USE_ADDITIONAL_CONFIRMS = create("settings.additional confirmations.enabled",true).withComment("If true, markets will ask the player to confirm sensitive actions (ie. deleting, creating) ");
+ public static ConfigEntry PURCHASE_ITEM_SHIFT_MULTI_AMT = create("settings.purchase item.shift multiply amount", 10).withComment("Ex. if the player shift clicks the increase 5 button it becomes 50, 1 -> 10, 10 -> 100");
+ public static ConfigEntry REQUEST_MENU_SHOWS_OWN_FIRST = create("settings.request menu shows own first", true).withComment("If false, the request menu will show global requests by default instead of your own.");
+ public static ConfigEntry USE_ADDITIONAL_CONFIRMS = create("settings.additional confirmations.enabled", true).withComment("If true, markets will ask the player to confirm sensitive actions (ie. deleting, creating) ");
+ public static ConfigEntry TRANSACTION_VIEW_ALL_NEEDS_PERM = create("settings.require permission to view all transactions", true).withComment("If true, players will need the perm: markets.viewalltransactions to see the toggle button.");
/*
========================= COMMAND ALIASES =========================
@@ -68,6 +97,20 @@ public final class Settings extends FlightSettings {
/*
========================= BLACKLISTED ITEMS =========================
*/
+ public static final ConfigEntry BLOCKED_ITEMS = create("blocked items", Collections.singletonList("ENDER_CHEST"), "Materials that should be blocked (not allowed to sell) You can add model data by using :# ex. PAPER:5");
+ public static final ConfigEntry BLOCKED_NBT_TAGS = create("blocked nbt tags", Collections.singletonList("example_tag"), "A list of NBT tags that are blocked from the being added to markets. These are case sensitive");
+ public static final ConfigEntry BLOCKED_ITEM_NAMES = create("blocked item names", List.of(
+ "fuck",
+ "bitch",
+ "nigger",
+ "nigga",
+ "pussy"
+ ), "If an item contains any words/names specified here, it won't list.");
+
+ public static final ConfigEntry BLOCKED_ITEM_LORES = create("blocked item lores", List.of(
+ "kill yourself",
+ "another random phrase"
+ ), "If an item lore contains any of these values, it won't list");
/*
========================= CLICKS =========================
@@ -139,6 +182,7 @@ public final class Settings extends FlightSettings {
public static ConfigEntry GUI_CATEGORY_ADD_ITEM_ITEMS_OFFERS_ITEM = create("gui.category add item.items.offers.item", CompMaterial.FLOWER_BANNER_PATTERN.name());
public static ConfigEntry GUI_CATEGORY_ADD_ITEM_ITEMS_PRICE_ITEM = create("gui.category add item.items.price.item", CompMaterial.SUNFLOWER.name());
public static ConfigEntry GUI_CATEGORY_ADD_ITEM_ITEMS_PRICE_FOR_ALL_ITEM = create("gui.category add item.items.price for all.item", CompMaterial.RED_SHULKER_BOX.name());
+ public static ConfigEntry GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_ITEM = create("gui.category add item.items.infinite.item", CompMaterial.HEART_OF_THE_SEA.name());
public static ConfigEntry GUI_MARKET_SETTINGS_BACKGROUND = create("gui.market settings.items.background", CompMaterial.BLACK_STAINED_GLASS_PANE.name());
@@ -176,8 +220,10 @@ public final class Settings extends FlightSettings {
public static ConfigEntry GUI_OFFER_CREATE_ITEMS_CREATE_OFFER = create("gui.offer creation.items.create offer.item", CompMaterial.LIME_DYE.name());
public static ConfigEntry GUI_OFFER_CREATE_ITEMS_BREAKDOWN = create("gui.offer creation.items.breakdown.item", CompMaterial.PAPER.name());
public static ConfigEntry GUI_OFFER_CREATE_ITEMS_AMOUNT = create("gui.offer creation.items.offered amount.item", CompMaterial.SUNFLOWER.name());
+ public static ConfigEntry GUI_OFFER_CREATE_ITEMS_REQUEST_AMT = create("gui.offer creation.items.requested amount.item", CompMaterial.REPEATER.name());
public static ConfigEntry GUI_OFFER_CREATE_ITEMS_CURRENCY = create("gui.offer creation.items.currency.item", CompMaterial.GOLD_INGOT.name());
public static ConfigEntry GUI_TRANSACTIONS_BACKGROUND = create("gui.transactions.items.background", CompMaterial.BLACK_STAINED_GLASS_PANE.name());
+ public static ConfigEntry GUI_TRANSACTIONS_VIEW_ALL_ITEM = create("gui.transactions.items.view all", CompMaterial.NETHER_STAR.name());
public static ConfigEntry GUI_BANK_BACKGROUND = create("gui.bank.items.background", CompMaterial.BLACK_STAINED_GLASS_PANE.name());
public static ConfigEntry GUI_BANK_ITEMS_ADD = create("gui.bank.items.add.item", CompMaterial.LIME_DYE.name());
diff --git a/src/main/java/ca/tweetzy/markets/settings/Translations.java b/src/main/java/ca/tweetzy/markets/settings/Translations.java
index d75cc687..240ba0f9 100644
--- a/src/main/java/ca/tweetzy/markets/settings/Translations.java
+++ b/src/main/java/ca/tweetzy/markets/settings/Translations.java
@@ -37,6 +37,7 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry NO_MARKET_FOUND = create("error.no market found", "&cCould not find any market for&F: &4%player_name%");
public static TranslationEntry ONE_FILL_SLOT_REQUIRED = create("error.one fill slot required", "&cThis layout requires at least one fill slot!");
public static TranslationEntry ITEM_OUT_OF_STOCK = create("error.item out of stock", "&cSorry that item is now out of stock");
+ public static TranslationEntry NOT_ENOUGH_STOCK = create("error.not enough stock", "&cSorry there is not enough stock");
public static TranslationEntry ITEM_NO_LONGER_AVAILABLE = create("error.item no longer available", "&cSorry that item is no longer available");
public static TranslationEntry BANNED_FROM_MARKET = create("error.banned from market", "&4%market_owner% &chas banned you from viewing their market!");
public static TranslationEntry MARKET_IS_CLOSED = create("error.market is closed", "&4%market_owner%&c's market is currently closed!");
@@ -47,6 +48,13 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry NO_REVIEWS = create("error.no reviews", "&cThere are no reviews currently.");
public static TranslationEntry IN_CUSTOMER_MODE = create("error.not available in customer mode", "&cYou cannot do that in customer preview mode.");
+ public static TranslationEntry BLOCKED_ITEM = create("error.blacklist.item", "&cThe sale of %item% in markets is not allowed!");
+ public static TranslationEntry BLOCKED_ITEM_NAME = create("error.blacklist.name", "&cYou cannot sell an item w/%blacklisted_word% &cin its name");
+ public static TranslationEntry BLOCKED_ITEM_LORE = create("error.blacklist.lore", "&cYou cannot sell an item w/%blacklisted_word% &cin its lore");
+ public static TranslationEntry BLOCKED_ITEM_TAG = create("error.blacklist.nbt tag", "&cThat item is currently blacklisted.");
+
+ public static TranslationEntry SERVER_MARKET_NAME = create("info.server market.name", "&eServer Market");
+
public static TranslationEntry DELETED_MARKET = create("info.deleted market", "&eSuccessfully deleted your market!");
public static TranslationEntry REMOVED_PLAYER_MARKET = create("info.admin.removed market", "&eSuccessfully removed market owned by &b%player_name%");
public static TranslationEntry MARKET_ITEM_BOUGHT_SELLER = create("info.market item bought.seller", "&fx&a%purchase_quantity% &f%item_name% &ewas bought by &b%buyer_name%");
@@ -90,6 +98,10 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry PROMPT_SEARCH_TITLE = create("prompts.search.title", "&LSearch");
public static TranslationEntry PROMPT_SEARCH_SUBTITLE = create("prompts.search.subtitle", "&fEnter search keywords into chat");
+
+ public static TranslationEntry PROMPT_STOCK_WITHDRAW_TITLE = create("prompts.stock withdraw.title", "&LStock Withdrawal");
+ public static TranslationEntry PROMPT_STOCK_WITHDRAW_SUBTITLE = create("prompts.stock withdraw.subtitle", "&fEnter the withdraw quantity in chat");
+
public static TranslationEntry PROMPT_REQUEST_AMOUNT_TITLE = create("prompts.request amount.title", "&lRequest Amount");
public static TranslationEntry PROMPT_REQUEST_AMOUNT_SUBTITLE = create("prompts.request amount.subtitle", "&fEnter how many of that item you want");
public static TranslationEntry PROMPT_REQUEST_PRICE_TITLE = create("prompts.price.title", "&lRequest Price");
@@ -110,6 +122,9 @@ public Translations(@NonNull JavaPlugin plugin) {
public static TranslationEntry PROMPT_MARKET_DESC_TITLE = create("prompts.market description.title", "&LMarket Description");
public static TranslationEntry PROMPT_MARKET_DESC_SUBTITLE = create("prompts.market description.subtitle", "&fEnter new description into chat");
+ public static TranslationEntry PROMPT_OFFER_TOTAL_ITEMS_TITLE = create("prompts.requested amount.title", "&LRequested Amount");
+ public static TranslationEntry PROMPT_OFFER_TOTAL_ITEMS_SUBTITLE = create("prompts.requested amount.subtitle", "&fEnter how many items you want");
+
public static TranslationEntry PROMPT_OFFER_PRICE_TITLE = create("prompts.offer price.title", "&LOffer Price");
public static TranslationEntry PROMPT_OFFER_PRICE_SUBTITLE = create("prompts.offer price.subtitle", "&fEnter how much you want to offer");
public static TranslationEntry PROMPT_WITHDRAW_ENTRY_TITLE = create("prompts.withdraw bank entry.title", "&LEnter Amount");
@@ -142,8 +157,20 @@ public Translations(@NonNull JavaPlugin plugin) {
"&e&l%left_click% &7to go to next page"
);
- public static TranslationEntry GUI_MAIN_VIEW_TITLE = create("gui.main view.title", "&eMarkets &f- &7Home");
+ public static TranslationEntry GUI_MAIN_ADMIN_TITLE = create("gui.admin main.title", "&eMarkets &f- &cAdmin");
+ public static TranslationEntry GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET = create("gui.admin main.items.admin market.name", "&LAdmin Market");
+ public static TranslationEntry GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET_LORE_CREATE = create("gui.admin main.items.admin market.create lore",
+ "&7There is no server market setup.",
+ "",
+ "&a&lClick &7to create one."
+ );
+
+ public static TranslationEntry GUI_MAIN_ADMIN_ITEMS_ADMIN_MARKET_LORE_VIEW = create("gui.admin main.items.admin market.view lore",
+ "&a&lClick &7to view server market"
+ );
+
+ public static TranslationEntry GUI_MAIN_VIEW_TITLE = create("gui.main view.title", "&eMarkets &f- &7Home");
public static TranslationEntry GUI_MAIN_VIEW_ITEMS_YOUR_MARKET_NAME = create("gui.main view.items.your market.name", "&e&lYour Market");
public static TranslationEntry GUI_MAIN_VIEW_ITEMS_YOUR_MARKET_LORE_CREATE = create("gui.main view.items.your market.lore",
"&7You currently don't have a market",
@@ -384,6 +411,17 @@ public Translations(@NonNull JavaPlugin plugin) {
"&e&l%left_click% &7to toggle price mode"
);
+ public static TranslationEntry GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_NAME = create("gui.category add item.items.infinite.name", "&lToggle Infinite Stock");
+ public static TranslationEntry GUI_CATEGORY_ADD_ITEM_ITEMS_INFINITE_LORE = create("gui.category add item.items.infinite.lore",
+ "&7By default items will run out of stock",
+ "&7since this is a server market, it's suggested that",
+ "&7you keep this enabled so you won't have to restock.",
+ "",
+ "&7Current&f: %enabled%",
+ "",
+ "&e&l%left_click% &7to toggle infinite stock"
+ );
+
public static TranslationEntry GUI_CATEGORY_ADD_ITEM_ITEMS_CUSTOM_CURRENCY_LORE = create("gui.category add item.items.custom currency.lore",
"&7----------------------------",
"&eThis item is the custom currency",
@@ -766,6 +804,15 @@ public Translations(@NonNull JavaPlugin plugin) {
);
+ public static TranslationEntry GUI_OFFER_CREATE_ITEMS_TOTAL_NAME = create("gui.offer creation.items.requested amount.name", "&LItems Requested");
+ public static TranslationEntry GUI_OFFER_CREATE_ITEMS_TOTAL_LORE = create("gui.offer creation.items.requested amount.lore",
+ "&7Total items &f: &a%offer_itemsrequested%",
+ "",
+ "&e&l%left_click% &7to change request amount"
+
+ );
+
+
public static TranslationEntry GUI_OFFER_CREATE_ITEMS_CURRENCY_NAME = create("gui.offer creation.items.currency.name", "&lSwitch Currency");
public static TranslationEntry GUI_OFFER_CREATE_ITEMS_CURRENCY_LORE = create("gui.offer creation.items.currency.lore",
"&7Used to adjust which currency you will",
@@ -777,6 +824,16 @@ public Translations(@NonNull JavaPlugin plugin) {
);
public static TranslationEntry GUI_TRANSACTIONS_TITLE = create("gui.transactions.title", "&eMarkets &f- &7Transactions");
+ public static TranslationEntry GUI_TRANSACTIONS_ITEMS_VIEW_ALL_NAME = create("gui.transactions.items.view all.name", "&lSwitch View Mode");
+ public static TranslationEntry GUI_TRANSACTIONS_ITEMS_VIEW_ALL_LORE = create("gui.transactions.items.view all.lore",
+ "&7Used to toggle whether you see every transaction",
+ "&7or just the transactions related to you.",
+ "",
+ "&7Viewing all&f: %is_true%",
+ "",
+ "&e&l%left_click% &7to toggle view all"
+ );
+
public static TranslationEntry GUI_TRANSACTIONS_ITEMS_ENTRY_LORE = create("gui.transactions.items.entry.lore",
"&7----------------------------",
"&7Quantity&f: &E%item_quantity%",
@@ -789,7 +846,7 @@ public Translations(@NonNull JavaPlugin plugin) {
);
public static TranslationEntry GUI_BANK_TAX_TITLE = create("gui.tax bank.title", "&eMarkets &f- &7Tax Collection");
- public static TranslationEntry GUI_BANK_TAX_ITEMS_ENTRY_NAME = create("gui.tax bank.items.entry.name","&a%entry_name%");
+ public static TranslationEntry GUI_BANK_TAX_ITEMS_ENTRY_NAME = create("gui.tax bank.items.entry.name", "&a%entry_name%");
public static TranslationEntry GUI_BANK_TAX_ITEMS_ENTRY_LORE = create("gui.tax bank.items.entry.lore",
"&7Value&f: &E%entry_quantity%",
"",
@@ -881,7 +938,10 @@ public Translations(@NonNull JavaPlugin plugin) {
"&7If you have any of this item in your",
"&7inventory you can &edrop &7it here to add to stock.",
"",
- "&7Current Stock&F: &e%market_item_stock%"
+ "&7Current Stock&F: &e%market_item_stock%",
+ "",
+ "&e&l%shift_left_click% &7to deposit all items from inventory",
+ "&b&l%right_click% &7to withdraw from stock"
);
public static TranslationEntry GUI_EDIT_ITEM_ITEMS_CURRENCY_NAME = create("gui.edit market item.items.currency.name", "&lSwitch Currency");