diff --git a/pom.xml b/pom.xml index 4d61b52..dc0e6f2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ tsp.headdb HeadDB - 5.0.0-rc.2 + 5.0.0-rc.3 jar HeadDB @@ -129,7 +129,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.4.1 package @@ -142,6 +142,21 @@ tsp.headdb.HeadDB + + + net.wesjd.anvilgui + tsp.headdb.core.util.anvilgui + + + + + *:* + false + + tsp.headdb.core.util.anvilgui + + + diff --git a/src/main/java/tsp/headdb/HeadDB.java b/src/main/java/tsp/headdb/HeadDB.java index d12914b..fda1087 100644 --- a/src/main/java/tsp/headdb/HeadDB.java +++ b/src/main/java/tsp/headdb/HeadDB.java @@ -20,10 +20,10 @@ import tsp.headdb.core.storage.Storage; import tsp.headdb.core.task.UpdateTask; import tsp.headdb.core.util.BuildProperties; +import tsp.headdb.core.util.HeadDBLogger; import tsp.smartplugin.SmartPlugin; import tsp.smartplugin.inventory.PaneListener; import tsp.smartplugin.localization.TranslatableLocalization; -import tsp.smartplugin.logger.PluginLogger; import tsp.smartplugin.utils.PluginUtils; import java.io.IOException; @@ -34,7 +34,7 @@ import java.util.Optional; public class HeadDB extends SmartPlugin { private static HeadDB instance; - private PluginLogger logger; + private HeadDBLogger logger; private BuildProperties buildProperties; private TranslatableLocalization localization; private Storage storage; @@ -45,7 +45,7 @@ public class HeadDB extends SmartPlugin { public void onStart() { instance = this; instance.saveDefaultConfig(); - instance.logger = new PluginLogger(this, getConfig().getBoolean("debug")); + instance.logger = new HeadDBLogger(getConfig().getBoolean("debug")); instance.logger.info("Loading HeadDB - " + instance.getDescription().getVersion()); instance.buildProperties = new BuildProperties(this); @@ -56,7 +56,6 @@ public class HeadDB extends SmartPlugin { instance.initEconomy(); new PaneListener(this); - //new PlayerJoinListener(); instance.commandManager = new CommandManager(); loadCommands(); @@ -167,7 +166,7 @@ public class HeadDB extends SmartPlugin { return Optional.ofNullable(economyProvider); } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings("DataFlowIssue") private DecimalFormat decimalFormat = new DecimalFormat(getConfig().getString("economy.format")); public DecimalFormat getDecimalFormat() { @@ -182,7 +181,7 @@ public class HeadDB extends SmartPlugin { return buildProperties; } - public PluginLogger getLog() { + public HeadDBLogger getLog() { return logger; } diff --git a/src/main/java/tsp/headdb/core/api/event/HeadPurchaseEvent.java b/src/main/java/tsp/headdb/core/api/event/HeadPurchaseEvent.java index ffc01f8..4a9acb5 100644 --- a/src/main/java/tsp/headdb/core/api/event/HeadPurchaseEvent.java +++ b/src/main/java/tsp/headdb/core/api/event/HeadPurchaseEvent.java @@ -16,7 +16,10 @@ import java.math.BigDecimal; * * @author TheSilentPro (Silent) * @see Event#isAsynchronous() + * + * @deprecated Possible issues. */ +@Deprecated public class HeadPurchaseEvent extends Event implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); diff --git a/src/main/java/tsp/headdb/core/command/CommandMain.java b/src/main/java/tsp/headdb/core/command/CommandMain.java index c7a30c3..6c1be8d 100644 --- a/src/main/java/tsp/headdb/core/command/CommandMain.java +++ b/src/main/java/tsp/headdb/core/command/CommandMain.java @@ -90,24 +90,12 @@ public class CommandMain extends HeadDBCommand implements CommandExecutor, TabCo // favorites pane.setButton(getInstance().getConfig().getInt("gui.main.meta.favorites.slot"), new Button(Utils.getItemFromConfig("gui.main.meta.favorites.item", Material.BOOK), e -> { e.setCancelled(true); - List heads = HeadAPI.getFavoriteHeads(player.getUniqueId()); - PagedPane main = Utils.createPaged(player, Utils.translateTitle(getLocalization().getMessage(player.getUniqueId(), "menu.main.favorites.name").orElse("Favorites"), heads.size(), "Favorites")); - for (Head head : heads) { - main.addButton(new Button(head.getItem(player.getUniqueId()), fe -> { - if (fe.isLeftClick()) { - ItemStack favoriteItem = head.getItem(player.getUniqueId()); - if (fe.isShiftClick()) { - favoriteItem.setAmount(64); - } - - player.getInventory().addItem(favoriteItem); - } else if (fe.isRightClick()) { - HeadDB.getInstance().getStorage().getPlayerStorage().removeFavorite(player.getUniqueId(), head.getTexture()); - } - })); + if (!player.hasPermission("headdb.favorites")) { + HeadDB.getInstance().getLocalization().sendMessage(player, "noAccessFavorites"); + return; } - main.open(player); + Utils.openFavoritesMenu(player); })); // search diff --git a/src/main/java/tsp/headdb/core/economy/VaultProvider.java b/src/main/java/tsp/headdb/core/economy/VaultProvider.java index 1f8eaaa..0082445 100644 --- a/src/main/java/tsp/headdb/core/economy/VaultProvider.java +++ b/src/main/java/tsp/headdb/core/economy/VaultProvider.java @@ -16,7 +16,7 @@ public class VaultProvider implements BasicEconomyProvider { @Override public CompletableFuture canPurchase(Player player, BigDecimal cost) { double effectiveCost = cost.doubleValue(); - return CompletableFuture.supplyAsync(() -> economy.has(player, effectiveCost >= 0 ? effectiveCost : 0)); // Vault is really old... + return CompletableFuture.supplyAsync(() -> economy.has(player, effectiveCost >= 0 ? effectiveCost : 0)); } @Override @@ -28,12 +28,12 @@ public class VaultProvider implements BasicEconomyProvider { @Override public void init() { - if (!Bukkit.getServer().getPluginManager().isPluginEnabled("Vault")) { + if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) { HeadDB.getInstance().getLog().error("Vault is not installed!"); return; } - RegisteredServiceProvider economyProvider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class); + RegisteredServiceProvider economyProvider = Bukkit.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); if (economyProvider == null) { HeadDB.getInstance().getLog().error("Could not find vault economy provider!"); return; diff --git a/src/main/java/tsp/headdb/core/listener/PlayerJoinListener.java b/src/main/java/tsp/headdb/core/listener/PlayerJoinListener.java deleted file mode 100644 index 187f522..0000000 --- a/src/main/java/tsp/headdb/core/listener/PlayerJoinListener.java +++ /dev/null @@ -1,20 +0,0 @@ -package tsp.headdb.core.listener; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import tsp.headdb.HeadDB; - -public final class PlayerJoinListener implements Listener { - - public PlayerJoinListener() { - Bukkit.getPluginManager().registerEvents(this, HeadDB.getInstance()); - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - //HeadDB.getInstance().getStorage().getPlayerStorage().register(new PlayerData(event.getPlayer().getUniqueId(), "")); - } - -} diff --git a/src/main/java/tsp/headdb/core/task/UpdateTask.java b/src/main/java/tsp/headdb/core/task/UpdateTask.java index faf22d7..0950374 100644 --- a/src/main/java/tsp/headdb/core/task/UpdateTask.java +++ b/src/main/java/tsp/headdb/core/task/UpdateTask.java @@ -2,11 +2,12 @@ package tsp.headdb.core.task; import tsp.headdb.HeadDB; import tsp.headdb.core.api.HeadAPI; +import tsp.headdb.implementation.head.Head; import tsp.smartplugin.tasker.Task; +import java.util.List; import java.util.concurrent.TimeUnit; -@SuppressWarnings("ClassCanBeRecord") public class UpdateTask implements Task { private final long interval; @@ -17,7 +18,15 @@ public class UpdateTask implements Task { @Override public void run() { - HeadAPI.getDatabase().update((time, heads) -> HeadDB.getInstance().getLog().debug("Fetched: " + heads.size() + " Heads | Provider: " + HeadAPI.getDatabase().getRequester().getProvider().name() + " | Time: " + time + "ms (" + TimeUnit.MILLISECONDS.toSeconds(time) + "s)")); + HeadAPI.getDatabase().update((time, heads) -> { + int size = 0; + for (List list : heads.values()) { + for (Head ignored : list) { + size++; + } + } + HeadDB.getInstance().getLog().debug("Fetched: " + size + " Heads | Provider: " + HeadAPI.getDatabase().getRequester().getProvider().name() + " | Time: " + time + "ms (" + TimeUnit.MILLISECONDS.toSeconds(time) + "s)"); + }); HeadDB.getInstance().getStorage().getPlayerStorage().backup(); HeadDB.getInstance().getLog().debug("UpdateTask finished!"); } diff --git a/src/main/java/tsp/headdb/core/util/HeadDBLogger.java b/src/main/java/tsp/headdb/core/util/HeadDBLogger.java new file mode 100644 index 0000000..190d15c --- /dev/null +++ b/src/main/java/tsp/headdb/core/util/HeadDBLogger.java @@ -0,0 +1,62 @@ +package tsp.headdb.core.util; + +import org.bukkit.Bukkit; +import tsp.smartplugin.utils.StringUtils; + +public class HeadDBLogger { + + private final boolean debug; + + public HeadDBLogger(boolean debug) { + this.debug = debug; + } + public void info(String message) { + this.log(LogLevel.INFO, message); + } + + public void warning(String message) { + this.log(LogLevel.WARNING, message); + } + + public void error(String message) { + this.log(LogLevel.ERROR, message); + } + + public void debug(String message) { + this.log(LogLevel.DEBUG, message); + } + + public void trace(String message) { + this.log(LogLevel.TRACE, message); + } + + public void log(LogLevel level, String message) { + if ((level == LogLevel.DEBUG || level == LogLevel.TRACE) && !debug) { + return; + } + Bukkit.getConsoleSender().sendMessage(StringUtils.colorize(level.getColor() + "[" + level.name() + "]: " + message)); + } + + public boolean isDebug() { + return this.debug; + } + + public static enum LogLevel { + INFO, + WARNING, + ERROR, + DEBUG, + TRACE; + + public String getColor() { + return switch (this) { + case INFO -> "\u001b[32m"; + case WARNING -> "\u001b[33m"; + case ERROR -> "\u001b[31m"; + case DEBUG -> "\u001b[36m"; + case TRACE -> "\u001b[35m"; + }; + } + } + +} diff --git a/src/main/java/tsp/headdb/core/util/Utils.java b/src/main/java/tsp/headdb/core/util/Utils.java index 8648699..aba7548 100644 --- a/src/main/java/tsp/headdb/core/util/Utils.java +++ b/src/main/java/tsp/headdb/core/util/Utils.java @@ -12,7 +12,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import tsp.headdb.HeadDB; import tsp.headdb.core.api.HeadAPI; -import tsp.headdb.core.api.event.HeadPurchaseEvent; import tsp.headdb.core.economy.BasicEconomyProvider; import tsp.headdb.core.hook.Hooks; import tsp.headdb.implementation.category.Category; @@ -90,7 +89,7 @@ public class Utils { if (item == null) { item = new ItemStack(Material.BLACK_STAINED_GLASS_PANE); ItemMeta meta = item.getItemMeta(); - //noinspection ConstantConditions + //noinspection DataFlowIssue meta.setDisplayName(""); item.setItemMeta(meta); } @@ -113,6 +112,34 @@ public class Utils { return main; } + public static void openFavoritesMenu(Player player) { + List heads = HeadAPI.getFavoriteHeads(player.getUniqueId()); + PagedPane main = Utils.createPaged(player, Utils.translateTitle(HeadDB.getInstance().getLocalization().getMessage(player.getUniqueId(), "menu.main.favorites.name").orElse("Favorites"), heads.size(), "Favorites")); + for (Head head : heads) { + main.addButton(new Button(head.getItem(player.getUniqueId()), fe -> { + if (!player.hasPermission("headdb.favorites")) { + HeadDB.getInstance().getLocalization().sendMessage(player, "noAccessFavorites"); + return; + } + + if (fe.isLeftClick()) { + int amount = 1; + if (fe.isShiftClick()) { + amount = 64; + } + + Utils.purchase(player, head, amount); + } else if (fe.isRightClick()) { + HeadDB.getInstance().getStorage().getPlayerStorage().removeFavorite(player.getUniqueId(), head.getTexture()); + HeadDB.getInstance().getLocalization().sendMessage(player, "removedFavorites"); + openFavoritesMenu(player); + } + })); + } + + main.open(player); + } + @ParametersAreNonnullByDefault public static void addHeads(Player player, @Nullable Category category, PagedPane pane, Collection heads) { for (Head head : heads) { @@ -133,7 +160,12 @@ public class Utils { purchase(player, head, amount); } else if (e.isRightClick()) { - HeadDB.getInstance().getStorage().getPlayerStorage().addFavorite(player.getUniqueId(), head.getTexture()); + if (player.hasPermission("headdb.favorites")) { + HeadDB.getInstance().getStorage().getPlayerStorage().addFavorite(player.getUniqueId(), head.getTexture()); + HeadDB.getInstance().getLocalization().sendMessage(player, "addedFavorites"); + } else { + HeadDB.getInstance().getLocalization().sendMessage(player, "noAccessFavorites"); + } } })); } @@ -151,35 +183,52 @@ public class Utils { .replace("%cost%", HeadDB.getInstance().getDecimalFormat().format(cost)) ); return optional.get().purchase(player, cost).thenApply(success -> { - HeadPurchaseEvent event = new HeadPurchaseEvent(player, head, cost, success); - Bukkit.getPluginManager().callEvent(event); - return !event.isCancelled() && success; + Bukkit.getScheduler().runTask(HeadDB.getInstance(), () -> { + if (success) { + HeadDB.getInstance().getLocalization().sendMessage(player, "completePayment", msg -> msg + .replace("%name%", head.getName()) + .replace("%cost%", cost.toString())); + } else { + HeadDB.getInstance().getLocalization().sendMessage(player, "invalidFunds", msg -> msg.replace("%name%", head.getName())); + } + }); + return success; + + /* Note: Issues caused by sync call to async event but when run async above method fucks up. + Bukkit.getScheduler().runTaskAsynchronously(HeadDB.getInstance(), () -> { + HeadPurchaseEvent event = new HeadPurchaseEvent(player, head, cost, success); + Bukkit.getPluginManager().callEvent(event); + }); + return true; + */ }); } } - private static void purchase(Player player, Head head, int amount) { + public static void purchase(Player player, Head head, int amount) { processPayment(player, head, amount).whenComplete((success, ex) -> { if (ex != null) { HeadDB.getInstance().getLog().error("Failed to purchase head '" + head.getName() + "' for player: " + player.getName()); ex.printStackTrace(); } else { - // Bukkit API, therefore task is ran sync. - Bukkit.getScheduler().runTask(HeadDB.getInstance(), () -> { - ItemStack item = head.getItem(player.getUniqueId()); - item.setAmount(amount); - player.getInventory().addItem(item); - HeadDB.getInstance().getConfig().getStringList("commands.purchase").forEach(command -> { - if (command.isEmpty()) { - return; - } - if (Hooks.PAPI.enabled()) { - command = PlaceholderAPI.setPlaceholders(player, command); - } + // Bukkit API, therefore task is ran sync. + Bukkit.getScheduler().runTask(HeadDB.getInstance(), () -> { + if (success) { + ItemStack item = head.getItem(player.getUniqueId()); + item.setAmount(amount); + player.getInventory().addItem(item); + HeadDB.getInstance().getConfig().getStringList("commands.purchase").forEach(command -> { + if (command.isEmpty()) { + return; + } + if (Hooks.PAPI.enabled()) { + command = PlaceholderAPI.setPlaceholders(player, command); + } - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + }); + } }); - }); } }); } @@ -220,7 +269,6 @@ public class Utils { ConfigurationSection section = HeadDB.getInstance().getConfig().getConfigurationSection(path); Validate.notNull(section, "Section can not be null!"); - System.out.println("Checking for: provided material in '" + section.getName() + "' -> " + section.getString("material")); Material material = Material.matchMaterial(section.getString("material", def.name())); if (material == null) { material = def; @@ -230,7 +278,7 @@ public class Utils { ItemMeta meta = item.getItemMeta(); if (meta != null) { - //noinspection ConstantConditions + //noinspection DataFlowIssue meta.setDisplayName(StringUtils.colorize(section.getString("name"))); List lore = new ArrayList<>(); diff --git a/src/main/java/tsp/headdb/implementation/head/Head.java b/src/main/java/tsp/headdb/implementation/head/Head.java index a67e05b..31d5d71 100644 --- a/src/main/java/tsp/headdb/implementation/head/Head.java +++ b/src/main/java/tsp/headdb/implementation/head/Head.java @@ -57,7 +57,7 @@ public class Head { GameProfile profile = new GameProfile(uniqueId, name); profile.getProperties().put("textures", new Property("textures", texture)); try { - //noinspection ConstantConditions + //noinspection DataFlowIssue Field profileField = meta.getClass().getDeclaredField("profile"); profileField.setAccessible(true); profileField.set(meta, profile); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 03d2adf..1508643 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -11,7 +11,7 @@ requireCategoryPermission: false # Economy Options economy: - enable: false + enabled: false provider: "VAULT" # Supported: VAULT format: "##.##" cost: diff --git a/src/main/resources/messages/en.yml b/src/main/resources/messages/en.yml index eb82795..0f0a6b4 100644 --- a/src/main/resources/messages/en.yml +++ b/src/main/resources/messages/en.yml @@ -7,6 +7,7 @@ invalidTarget: "&cInvalid target: &e%name%" invalidCategory: "&cInvalid Category!" invalidNumber: "&e%name% &cis not a number!" invalidPageIndex: "&cThat page is out of bounds! Max: %pages%" +noAccessFavorites: "&cYou do not have access to favorites!" openDatabase: "" # Intentionally empty. Sent when the main gui is opened updateDatabase: "&7Updating..." @@ -19,10 +20,13 @@ giveCommand: "&7Gave &6x%size% %name% &7to &6%receiver%" itemTexture: "&7Texture: &6%texture%" itemNoTexture: "&cThis item does not have a texture!" copyTexture: "&6Click to copy texture!" +addedFavorite: "&7Added &6%name% &7to your favorites!" +removedFavorite: "&7Removed &6%name% &7from your favorites!" # Only shown if economy is enabled processPayment: "&7Purchasing &6%name% &7for &6%cost%&7! Please wait..." completePayment: "&7Received &6%name% &7for &6%cost%" +invalidFunds: "&cYou do not have enough to buy &6%name%&c!" invalidLanguage: "&cInvalid Language! Available: &e%languages%" languageChanged: "&7Your language was set to: &6%language%" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ae8c845..44f8622 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,9 +1,10 @@ +#file: noinspection YAMLSchemaValidation name: ${project.name} description: ${project.description} main: tsp.headdb.HeadDB version: ${project.version} -softdepend: [Vault, Treasury] +depend: ["Vault"] api-version: 1.19 author: TheSilentPro (Silent) spigot-id: 84967