diff --git a/pom.xml b/pom.xml index d3ca529..166059f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.artillexstudios AxRankMenu - 1.4.0 + 1.5.0 jar AxRankMenu @@ -23,8 +23,8 @@ maven-compiler-plugin 3.8.1 - 9 - 9 + 11 + 11 @@ -116,7 +116,7 @@ com.artillexstudios.axapi axapi - 1.4.186 + 1.4.190 compile all @@ -199,6 +199,13 @@ 2.6.4 provided + + me.mraxetv.beasttokens + BeastTokens + 3.13.3 + ${project.basedir}/libs/bt-api-3.13.3.jar + system + diff --git a/src/main/java/com/artillexstudios/axrankmenu/AxRankMenu.java b/src/main/java/com/artillexstudios/axrankmenu/AxRankMenu.java index 8122e1c..990665e 100644 --- a/src/main/java/com/artillexstudios/axrankmenu/AxRankMenu.java +++ b/src/main/java/com/artillexstudios/axrankmenu/AxRankMenu.java @@ -11,11 +11,9 @@ import com.artillexstudios.axapi.scheduler.Scheduler; import com.artillexstudios.axapi.utils.FeatureFlags; import com.artillexstudios.axapi.utils.MessageUtils; -import com.artillexstudios.axrankmenu.commands.MainCommand; -import com.artillexstudios.axrankmenu.commands.TabComplete; +import com.artillexstudios.axrankmenu.commands.Commands; import com.artillexstudios.axrankmenu.hooks.HookManager; import org.bstats.bukkit.Metrics; -import org.bukkit.Bukkit; import java.io.File; @@ -45,9 +43,7 @@ public void enable() { MESSAGEUTILS = new MessageUtils(LANG.getBackingDocument(), "prefix", CONFIG.getBackingDocument()); - final MainCommand command = new MainCommand(); - this.getCommand("axrankmenu").setExecutor(command); - Bukkit.getPluginCommand("axrankmenu").setTabCompleter(new TabComplete()); + Commands.registerCommand(); Scheduler.get().run(task -> new HookManager().updateHooks()); } diff --git a/src/main/java/com/artillexstudios/axrankmenu/commands/Commands.java b/src/main/java/com/artillexstudios/axrankmenu/commands/Commands.java new file mode 100644 index 0000000..8fcfbe7 --- /dev/null +++ b/src/main/java/com/artillexstudios/axrankmenu/commands/Commands.java @@ -0,0 +1,131 @@ +package com.artillexstudios.axrankmenu.commands; + +import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.block.implementation.Section; +import com.artillexstudios.axrankmenu.AxRankMenu; +import com.artillexstudios.axrankmenu.commands.annotations.Groups; +import com.artillexstudios.axrankmenu.gui.impl.RankGui; +import com.artillexstudios.axrankmenu.hooks.HookManager; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.group.Group; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import revxrsal.commands.annotation.DefaultFor; +import revxrsal.commands.annotation.Subcommand; +import revxrsal.commands.bukkit.BukkitCommandHandler; +import revxrsal.commands.bukkit.annotation.CommandPermission; +import revxrsal.commands.orphan.OrphanCommand; +import revxrsal.commands.orphan.Orphans; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.artillexstudios.axrankmenu.AxRankMenu.CONFIG; +import static com.artillexstudios.axrankmenu.AxRankMenu.LANG; +import static com.artillexstudios.axrankmenu.AxRankMenu.MESSAGEUTILS; +import static com.artillexstudios.axrankmenu.AxRankMenu.RANKS; + +public class Commands implements OrphanCommand { + + @DefaultFor({"~", "~ open"}) + @CommandPermission(value = "axrankmenu.use") + public void open(@NotNull Player sender) { + new RankGui(sender).open(); + } + + @Subcommand({"reload"}) + @CommandPermission(value = "axrankmenu.reload") + public void reload(@NotNull Player sender) { + if (!CONFIG.reload()) { + MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "tiers.yml")); + return; + } + + if (!LANG.reload()) { + MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "lang.yml")); + return; + } + + if (!RANKS.reload()) { + MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "ranks.yml")); + return; + } + + new HookManager().updateHooks(); + Commands.registerCommand(); + + MESSAGEUTILS.sendLang(sender, "reload.success"); + } + + @Subcommand({"addrank"}) + @CommandPermission(value = "axrankmenu.addrank") + public void addRank(@NotNull Player sender, @Groups String group) { + final Section section = RANKS.getBackingDocument().createSection(group); + section.set("rank", group); + section.set("server", ""); + section.set("price", -1.0); + section.set("currency", "Vault"); + section.set("slot", getFirstEmptySlot()); + section.set("item.type", "GRAY_BANNER"); + section.set("item.name", "�FF00" + group + " &fRANK"); + section.set("item.lore", Arrays.asList( + " ", + " &7- &fPrice: �AA00$%price%", + " ", + "�FF00ᴘᴇʀᴍɪssɪᴏɴs", + " &7- &f%permission%", + " ", + "�FF00&l(!) �FF00Click here to purchase!" + )); + section.set("item.buy-actions", Arrays.asList( + "[MESSAGE] �FF00You have purchased the &f%name%�FF00! &7(%rank%)", + "[CONSOLE] lp user %player% parent set " + group, + "[CLOSE] menu" + )); + RANKS.save(); + MESSAGEUTILS.sendLang(sender, "add-rank", Map.of("%rank%", group)); + } + + private int getFirstEmptySlot() { + final ArrayList filled = new ArrayList<>(); + for (String str : RANKS.getBackingDocument().getRoutesAsStrings(false)) { + filled.add(RANKS.getInt(str + ".slot", -1)); + } + for (int i = 0; i < RANKS.getInt("rows", 3) * 9; i++) { + if (filled.contains(i)) continue; + return i; + } + return -1; + } + + public static void registerCommand() { // todo: fix unregister + final BukkitCommandHandler handler = BukkitCommandHandler.create(AxRankMenu.getInstance()); + handler.unregisterAllCommands(); + + handler.getAutoCompleter().registerSuggestionFactory(parameter -> { + if (parameter.hasAnnotation(Groups.class)) { + return (args, sender, command) -> { + final LuckPerms luckPerms = LuckPermsProvider.get(); + final Set groups = new HashSet<>(luckPerms.getGroupManager().getLoadedGroups()); + groups.removeIf(group -> { + for (String str : RANKS.getBackingDocument().getRoutesAsStrings(false)) { + if (RANKS.getString(str + ".rank", "").equalsIgnoreCase(group.getName())) return true; + } + return false; + }); + + return groups.stream().map(Group::getName).collect(Collectors.toList()); + }; + } + return null; + }); + + handler.register(Orphans.path(CONFIG.getStringList("command-aliases").toArray(String[]::new)).handler(new Commands())); + handler.registerBrigadier(); + } +} diff --git a/src/main/java/com/artillexstudios/axrankmenu/commands/MainCommand.java b/src/main/java/com/artillexstudios/axrankmenu/commands/MainCommand.java deleted file mode 100644 index 164e148..0000000 --- a/src/main/java/com/artillexstudios/axrankmenu/commands/MainCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.artillexstudios.axrankmenu.commands; - -import com.artillexstudios.axrankmenu.gui.impl.RankGui; -import com.artillexstudios.axrankmenu.hooks.HookManager; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; - -import static com.artillexstudios.axrankmenu.AxRankMenu.CONFIG; -import static com.artillexstudios.axrankmenu.AxRankMenu.LANG; -import static com.artillexstudios.axrankmenu.AxRankMenu.MESSAGEUTILS; -import static com.artillexstudios.axrankmenu.AxRankMenu.RANKS; - -public class MainCommand implements CommandExecutor { - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 1 && args[0].equalsIgnoreCase("reload") && sender.hasPermission("axrankmenu.reload")) { - - if (!CONFIG.reload()) { - MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "tiers.yml")); - return true; - } - - if (!LANG.reload()) { - MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "lang.yml")); - return true; - } - - if (!RANKS.reload()) { - MESSAGEUTILS.sendLang(sender, "reload.failed", Collections.singletonMap("%file%", "ranks.yml")); - return true; - } - - new HookManager().updateHooks(); - - MESSAGEUTILS.sendLang(sender, "reload.success"); - return true; - } - - new RankGui((Player) sender).open(); - return true; - } -} diff --git a/src/main/java/com/artillexstudios/axrankmenu/commands/TabComplete.java b/src/main/java/com/artillexstudios/axrankmenu/commands/TabComplete.java deleted file mode 100644 index 9156a8a..0000000 --- a/src/main/java/com/artillexstudios/axrankmenu/commands/TabComplete.java +++ /dev/null @@ -1,20 +0,0 @@ - -package com.artillexstudios.axrankmenu.commands; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collections; -import java.util.List; - -public class TabComplete implements TabCompleter { - - @Nullable - @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args) { - return sender.hasPermission("axrankmenu.reload") ? Collections.singletonList("reload") : null; - } -} diff --git a/src/main/java/com/artillexstudios/axrankmenu/commands/annotations/Groups.java b/src/main/java/com/artillexstudios/axrankmenu/commands/annotations/Groups.java new file mode 100644 index 0000000..9757cd6 --- /dev/null +++ b/src/main/java/com/artillexstudios/axrankmenu/commands/annotations/Groups.java @@ -0,0 +1,11 @@ +package com.artillexstudios.axrankmenu.commands.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface Groups { +} diff --git a/src/main/java/com/artillexstudios/axrankmenu/hooks/HookManager.java b/src/main/java/com/artillexstudios/axrankmenu/hooks/HookManager.java index ad9fe77..a2762bb 100644 --- a/src/main/java/com/artillexstudios/axrankmenu/hooks/HookManager.java +++ b/src/main/java/com/artillexstudios/axrankmenu/hooks/HookManager.java @@ -1,6 +1,7 @@ package com.artillexstudios.axrankmenu.hooks; import com.artillexstudios.axapi.utils.StringUtils; +import com.artillexstudios.axrankmenu.hooks.currency.BeastTokensHook; import com.artillexstudios.axrankmenu.hooks.currency.CoinsEngineHook; import com.artillexstudios.axrankmenu.hooks.currency.CurrencyHook; import com.artillexstudios.axrankmenu.hooks.currency.PlayerPointsHook; @@ -47,6 +48,11 @@ public void updateHooks() { currency.add(new UltraEconomyHook()); Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("!FF33[AxRankMenu] Hooked into UltraEconomy!")); } + + if (CONFIG.getBoolean("hooks.BeastTokens.register", true) && Bukkit.getPluginManager().getPlugin("BeastTokens") != null) { + currency.add(new BeastTokensHook()); + Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("!FF33[AxRankMenu] Hooked into BeastTokens!")); + } for (CurrencyHook hook : currency) hook.setup(); diff --git a/src/main/java/com/artillexstudios/axrankmenu/hooks/currency/BeastTokensHook.java b/src/main/java/com/artillexstudios/axrankmenu/hooks/currency/BeastTokensHook.java new file mode 100644 index 0000000..6903b28 --- /dev/null +++ b/src/main/java/com/artillexstudios/axrankmenu/hooks/currency/BeastTokensHook.java @@ -0,0 +1,37 @@ +package com.artillexstudios.axrankmenu.hooks.currency; + +import me.mraxetv.beasttokens.api.BeastTokensAPI; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class BeastTokensHook implements CurrencyHook { + + @Override + public void setup() { + } + + @Override + public String getName() { + return "BeastTokens"; + } + + @Override + public boolean isPersistent() { + return false; + } + + @Override + public double getBalance(@NotNull Player p) { + return BeastTokensAPI.getTokensManager().getTokens(p); + } + + @Override + public void giveBalance(@NotNull Player p, double amount) { + BeastTokensAPI.getTokensManager().addTokens(p, amount); + } + + @Override + public void takeBalance(@NotNull Player p, double amount) { + BeastTokensAPI.getTokensManager().removeTokens(p, amount); + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5942ba4..4c9fcd3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,6 +13,8 @@ hooks: UltraEconomy: register: true currency-name: "coins" + BeastTokens: + register: true PlaceholderAPI: register: true @@ -36,5 +38,13 @@ force-buy-order: enabled: false track: "trackName" +# you must define at least 1 +# reloading will add new commands, however a restart is recommended when editing this +command-aliases: + - "axrankmenu" + - "rankmenu" + - "rank" + - "ranks" + # do not change -version: 3 \ No newline at end of file +version: 5 \ No newline at end of file diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index 5f30f5a..4e74e41 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -14,9 +14,11 @@ reload: buy: no-currency: "&#FF3333You don't have enough money to buy this rank!" +add-rank: "!FF33You have added the &f%rank% !FF33rank to the gui! &7Now go to the plugins/AxRankMenu/ranks.yml file to edit it!" + error: buy-order: "&#FF3333You must buy ranks in order!" downgrade-disabled: "&#FF3333You can't downgrade your rank!" # do not change -version: 3 \ No newline at end of file +version: 4 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a1bbb9d..a0c34db 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -13,18 +13,12 @@ softdepend: - PlayerPoints - RoyaleEconomy - UltraEconomy - -commands: - axrankmenu: - usage: / - aliases: - - axranks - - ranks - - axrank - - rankmenu - - ranksmenu - - rank + - BeastTokens permissions: + axrankmenu.use: + default: true axrankmenu.reload: + default: op + axrankmenu.addrank: default: op \ No newline at end of file