diff --git a/.github/workflows/pitest.yml b/.github/workflows/pitest.yml deleted file mode 100644 index 45fee65..0000000 --- a/.github/workflows/pitest.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: PIT test -on: - push: - paths: - - 'src/**' - -jobs: - test: - if: github.ref == 'refs/heads/master' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup JDK - uses: actions/setup-java@v2 - with: - java-version: 11 - distribution: 'adopt' - - name: Gradle Test - run: ./gradlew pitest --no-daemon - - name: Upload Tests - uses: easingthemes/ssh-deploy@v2 - env: - SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }} - ARGS: "-rvzt --delete" - SOURCE: "build/reports/pitest/" - REMOTE_HOST: ${{ secrets.REMOTE_HOST }} - REMOTE_USER: ${{ secrets.REMOTE_USER }} - TARGET: ${{ secrets.PITEST_TARGET }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index b05ace7..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Test -on: - push: - paths: - - 'src/**' - -jobs: - pitest: - if: github.ref == 'refs/heads/master' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup JDK - uses: actions/setup-java@v2 - with: - java-version: 11 - distribution: 'adopt' - - name: Gradle Test - run: ./gradlew test --no-daemon - - name: Upload Tests - uses: easingthemes/ssh-deploy@v2 - env: - SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }} - ARGS: "-rvzt --delete" - SOURCE: "build/reports/tests/test/" - REMOTE_HOST: ${{ secrets.REMOTE_HOST }} - REMOTE_USER: ${{ secrets.REMOTE_USER }} - TARGET: ${{ secrets.REMOTE_TARGET }} diff --git a/README.md b/README.md index fcaf10e..73bf4ba 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,37 @@ # Rankup3 +## Compiling +### Prerequisites +Compilation requires the jdk8 (java development kit). +#### Windows +The [Eclipse Foundation](https://www.eclipse.org/org/) releases [the required build tools here](https://adoptium.net/temurin/releases). +It's recommended to select an installer download for simplicity and/or compiling other plugins. Don't select a zip archive. +You can easily clone this repo using the [github desktop app](https://desktop.github.com/). +1. Copy the link provided in the above green `Code` button. +2. In the github desktop app, Select `Clone a repository from the Internet` or `Clone repository...`, then select URL, and paste into the url line. +3. Open the Rankup3 directory you downloaded. The default location is in your user's `\Documents\GitHub\Rankup3` folder. +4. Open a command prompt in the directory and run [`dir`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/dir) to catalog the directory. +5. When you see the `gradlew` file listed, you can now try the [build command](#building). -## Installation +#### Linux +Add `jdk8` or `jdk8-openjdk` from your package manager. +Add `git` (required) and/or `gh` (optional, for github integration) from your package manager. +After installing packages, clone the repository by running `git clone` on the url provided above in the Code button, or the provided `gh` cloning command, from your shell. +Then try the [build command](#building). -Rankup can be compiled with the `gradlew build` command. The compiled plugin jar will be in the `/build/libs` directory. A gradle wrapper is included, so installation of Gradle is not necessary. +### Building +In the Rankup3 directory, a jar can be compiled with the provided `gradlew` wrapper: +- Command Prompt: `gradlew build` +- Unix/Powershell/Other: `./gradlew build` + +#### Known Build Errors +##### `Unsupported class file major version #` +This error indicates you are building with the wrong version of the JDK. +Solution: +- Windows: Correct your `Environment Variables` for `JAVA_HOME` to point to the installation location of the JDK 8. `Environment Variables` is program searchable in the start menu that will prompt you with a list of filepaths to your jvm installations in the `JAVA_HOME` variable. The JDK 8's filepath should be moved to the top of the list before [building](#building). +- Linux: Your package manager may natively support installing multiple JDK versions simultaneously. Consult your package manger's docs for information about managing your jvm's. Here are some examples: [`sudo update-alternatives --config java`](https://help.ubuntu.com/community/Java#Choosing_the_default_Java_to_use) or [`sudo archlinux-java set java-8-openjdk`](https://wiki.archlinux.org/title/Java#Switching_between_JVM). The JDK 8 should be selected before [building](#building). +### Jars +The compiled plugin jar will be in the `/build/libs` directory. +All branches are using the same jar name. Rename your build artifacts. ## Translation diff --git a/build.gradle b/build.gradle index 915c329..5f12a00 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ pitest { } group 'sh.okx' -version '3.13.3' +version '3.14.2' java { sourceCompatibility = JavaVersion.VERSION_1_8 @@ -46,7 +46,7 @@ dependencies { implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30' compileOnly 'org.jetbrains:annotations:22.0.0' - compileOnly 'org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT' + compileOnly 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT' compileOnly('com.github.Realizedd:TokenManager:3.2.4') { transitive = false } @@ -62,10 +62,12 @@ dependencies { compileOnly('com.github.mcMMO-Dev:mcMMO:601297') { exclude group: 'com.sk89q.worldguard' } - compileOnly ('com.bencodez:votingplugin:6.9.5') { + compileOnly ('com.bencodez:votingplugin:6.13.1') { transitive = false } + compileOnly 'net.luckperms:api:5.4' + compileOnly 'com.github.LlmDl:Towny:25fc18a' testImplementation 'com.github.LlmDl:Towny:25fc18a' diff --git a/src/main/java/sh/okx/rankup/RankupPlugin.java b/src/main/java/sh/okx/rankup/RankupPlugin.java index aa25570..1cf9ea7 100644 --- a/src/main/java/sh/okx/rankup/RankupPlugin.java +++ b/src/main/java/sh/okx/rankup/RankupPlugin.java @@ -1,12 +1,6 @@ package sh.okx.rankup; import com.electronwill.nightconfig.toml.TomlFormat; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -21,12 +15,7 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import sh.okx.rankup.commands.InfoCommand; -import sh.okx.rankup.commands.MaxRankupCommand; -import sh.okx.rankup.commands.PrestigeCommand; -import sh.okx.rankup.commands.PrestigesCommand; -import sh.okx.rankup.commands.RanksCommand; -import sh.okx.rankup.commands.RankupCommand; +import sh.okx.rankup.commands.*; import sh.okx.rankup.economy.Economy; import sh.okx.rankup.economy.EconomyProvider; import sh.okx.rankup.economy.VaultEconomyProvider; @@ -49,24 +38,7 @@ import sh.okx.rankup.ranksgui.RanksGuiListener; import sh.okx.rankup.requirements.Requirement; import sh.okx.rankup.requirements.RequirementRegistry; -import sh.okx.rankup.requirements.requirement.AdvancementRequirement; -import sh.okx.rankup.requirements.requirement.BlockBreakRequirement; -import sh.okx.rankup.requirements.requirement.CraftItemRequirement; -import sh.okx.rankup.requirements.requirement.GroupRequirement; -import sh.okx.rankup.requirements.requirement.ItemDeductibleRequirement; -import sh.okx.rankup.requirements.requirement.ItemRequirement; -import sh.okx.rankup.requirements.requirement.MobKillsRequirement; -import sh.okx.rankup.requirements.requirement.MoneyDeductibleRequirement; -import sh.okx.rankup.requirements.requirement.MoneyRequirement; -import sh.okx.rankup.requirements.requirement.PermissionRequirement; -import sh.okx.rankup.requirements.requirement.PlaceholderRequirement; -import sh.okx.rankup.requirements.requirement.PlayerKillsRequirement; -import sh.okx.rankup.requirements.requirement.PlaytimeMinutesRequirement; -import sh.okx.rankup.requirements.requirement.TotalMobKillsRequirement; -import sh.okx.rankup.requirements.requirement.UseItemRequirement; -import sh.okx.rankup.requirements.requirement.WorldRequirement; -import sh.okx.rankup.requirements.requirement.XpLevelDeductibleRequirement; -import sh.okx.rankup.requirements.requirement.XpLevelRequirement; +import sh.okx.rankup.requirements.requirement.*; import sh.okx.rankup.requirements.requirement.advancedachievements.AdvancedAchievementsAchievementRequirement; import sh.okx.rankup.requirements.requirement.advancedachievements.AdvancedAchievementsTotalRequirement; import sh.okx.rankup.requirements.requirement.mcmmo.McMMOPowerLevelRequirement; @@ -74,12 +46,7 @@ import sh.okx.rankup.requirements.requirement.superbvote.SuperbVoteVotesRequirement; import sh.okx.rankup.requirements.requirement.tokenmanager.TokensDeductibleRequirement; import sh.okx.rankup.requirements.requirement.tokenmanager.TokensRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyKingNumberResidentsRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyKingNumberTownsRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyKingRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyMayorNumberResidentsRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyMayorRequirement; -import sh.okx.rankup.requirements.requirement.towny.TownyResidentRequirement; +import sh.okx.rankup.requirements.requirement.towny.*; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginPointsDeductibleRequirement; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginPointsRequirement; import sh.okx.rankup.requirements.requirement.votingplugin.VotingPluginVotesRequirement; @@ -89,6 +56,13 @@ import sh.okx.rankup.util.UpdateNotifier; import sh.okx.rankup.util.VersionChecker; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class RankupPlugin extends JavaPlugin { public static final int CONFIG_VERSION = 10; @@ -327,7 +301,7 @@ public void refreshRanks() { - } catch (Exception e) { + } catch (RuntimeException e) { this.errorMessage = e.getClass().getName() + ": " + e.getMessage(); e.printStackTrace(); } @@ -380,59 +354,67 @@ private void registerRequirements() { requirements.addRequirements( new XpLevelRequirement(this, "xp-levelh"), new XpLevelDeductibleRequirement(this, "xp-level"), - new PlaytimeMinutesRequirement(this), - new AdvancementRequirement(this), - new GroupRequirement(this), - new PermissionRequirement(this), - new PlaceholderRequirement(this), - new WorldRequirement(this), - new BlockBreakRequirement(this), - new PlayerKillsRequirement(this), - new MobKillsRequirement(this), + new PlaytimeMinutesRequirement(this, "playtime-minutes"), + new AdvancementRequirement(this, "advancement"), + new GroupRequirement(this, "group"), + new PermissionRequirement(this, "permission"), + new PlaceholderRequirement(this, "placeholder"), + new WorldRequirement(this, "world"), + new BlockBreakRequirement(this, "block-break"), + new PlayerKillsRequirement(this, "player-kills"), + new MobKillsRequirement(this, "mob-kills"), new ItemRequirement(this, "itemh"), new ItemDeductibleRequirement(this, "item"), - new UseItemRequirement(this), - new TotalMobKillsRequirement(this), - new CraftItemRequirement(this)); + new UseItemRequirement(this, "use-item"), + new TotalMobKillsRequirement(this, "total-mob-kills"), + new CraftItemRequirement(this, "craft-item")); if (economy != null) { requirements.addRequirements( - new MoneyRequirement(this, "moneyh"), - new MoneyDeductibleRequirement(this, "money")); + new MoneyRequirement(this, "moneyh"), + new MoneyDeductibleRequirement(this, "money") + ); } PluginManager pluginManager = Bukkit.getPluginManager(); if (pluginManager.isPluginEnabled("mcMMO")) { requirements.addRequirements( - new McMMOSkillRequirement(this), - new McMMOPowerLevelRequirement(this)); + new McMMOSkillRequirement(this, "mcmmo"), + new McMMOPowerLevelRequirement(this, "mcmmo-power-level") + ); } if (pluginManager.isPluginEnabled("AdvancedAchievements")) { requirements.addRequirements( - new AdvancedAchievementsAchievementRequirement(this), - new AdvancedAchievementsTotalRequirement(this)); + new AdvancedAchievementsAchievementRequirement(this, "advancedachievements-achievement"), + new AdvancedAchievementsTotalRequirement(this, "advancedachievements-total") + ); } if (pluginManager.isPluginEnabled("VotingPlugin")) { requirements.addRequirements( - new VotingPluginVotesRequirement(this), - new VotingPluginPointsRequirement(this, "votingplugin-pointsh"), - new VotingPluginPointsDeductibleRequirement(this, "votingplugin-points")); + new VotingPluginVotesRequirement(this, "votingplugin-votes"), + new VotingPluginPointsRequirement(this, "votingplugin-pointsh"), + new VotingPluginPointsDeductibleRequirement(this, "votingplugin-points") + ); } if (Bukkit.getPluginManager().isPluginEnabled("Towny")) { requirements.addRequirements( - new TownyResidentRequirement(this), - new TownyMayorRequirement(this), - new TownyMayorNumberResidentsRequirement(this), - new TownyKingRequirement(this), - new TownyKingNumberResidentsRequirement(this), - new TownyKingNumberTownsRequirement(this)); + new TownyResidentRequirement(this, "towny-resident"), + new TownyMayorRequirement(this, "towny-mayor"), + new TownyMayorNumberResidentsRequirement(this, "towny-mayor-residents"), + new TownyKingRequirement(this, "towny-king"), + new TownyKingNumberResidentsRequirement(this, "towny-king-residents"), + new TownyKingNumberTownsRequirement(this, "towny-king-towns") + ); } if (Bukkit.getPluginManager().isPluginEnabled("TokenManager")) { requirements.addRequirements( - new TokensRequirement(this, "tokenmanager-tokensh"), - new TokensDeductibleRequirement(this, "tokenmanager-tokens")); + new TokensRequirement(this, "tokenmanager-tokensh"), + new TokensDeductibleRequirement(this, "tokenmanager-tokens") + ); } if (Bukkit.getPluginManager().isPluginEnabled("SuperbVote")) { - requirements.addRequirements(new SuperbVoteVotesRequirement(this)); + requirements.addRequirements( + new SuperbVoteVotesRequirement(this, "superbvote-votes") + ); } } private void setupEconomy() { diff --git a/src/main/java/sh/okx/rankup/commands/RankupCommand.java b/src/main/java/sh/okx/rankup/commands/RankupCommand.java index b24fd68..e446015 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -1,8 +1,10 @@ package sh.okx.rankup.commands; +import java.util.Arrays; import java.util.Map; import java.util.WeakHashMap; import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -29,6 +31,11 @@ public boolean onCommand(CommandSender sender, Command command, String label, St return true; } + if (plugin.getConfig().getBoolean("enable-noconfirm", true) && args.length > 0 && args[0].equalsIgnoreCase("noconfirm")) { + handleNoConfirm(sender, label, Arrays.copyOfRange(args, 1, args.length)); + return true; + } + // check if player if (!(sender instanceof Player)) { return false; @@ -39,6 +46,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St if (!plugin.getHelper().checkRankup(player)) { return true; } + RankElement rankElement = rankups.getByPlayer(player); FileConfiguration config = plugin.getConfig(); @@ -79,4 +87,23 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } return true; } + + private void handleNoConfirm(CommandSender sender, String label, String[] args) { + if (sender.hasPermission("rankup.noconfirm.other") && args.length > 0) { + Player player = Bukkit.getPlayer(args[0]); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Player not found: " + args[0]); + } else { + plugin.getHelper().rankup(player); + sender.sendMessage(ChatColor.GREEN + "Triggered no-confirmation rankup for " + player.getName()); + } + } else { + if (!(sender instanceof Player)) { + sender.sendMessage("/" + label + " noconfirm "); + return; + } + + plugin.getHelper().rankup((Player) sender); + } + } } diff --git a/src/main/java/sh/okx/rankup/hook/LuckPermsGroupProvider.java b/src/main/java/sh/okx/rankup/hook/LuckPermsGroupProvider.java new file mode 100644 index 0000000..c79964b --- /dev/null +++ b/src/main/java/sh/okx/rankup/hook/LuckPermsGroupProvider.java @@ -0,0 +1,64 @@ +package sh.okx.rankup.hook; + +import java.util.UUID; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.context.ContextSet; +import net.luckperms.api.context.ImmutableContextSet; +import net.luckperms.api.model.group.Group; +import net.luckperms.api.model.user.User; +import net.luckperms.api.node.types.InheritanceNode; + +public class LuckPermsGroupProvider implements GroupProvider { + + private final LuckPerms luckPerms; + private final ContextSet contextSet; + + public LuckPermsGroupProvider(LuckPerms luckPerms, ContextSet contextSet) { + this.luckPerms = luckPerms; + this.contextSet = contextSet; + } + + public static LuckPermsGroupProvider createFromString(LuckPerms luckPerms, String context) { + try { + ImmutableContextSet.Builder builder = ImmutableContextSet.builder(); + for (String contextPair : context.split(" ")) { + String[] keyValue = contextPair.split("=", 2); + if (keyValue.length == 2) { + builder.add(keyValue[0], keyValue[1]); + } + } + + return new LuckPermsGroupProvider(luckPerms, builder.build()); + } catch (NullPointerException | IllegalArgumentException ex) { + throw new IllegalArgumentException("Context is invalid: " + context, ex); + } + } + + + @Override + public boolean inGroup(UUID uuid, String group) { + User user = luckPerms.getUserManager().getUser(uuid); + for (Group lpGroup : user.getInheritedGroups(user.getQueryOptions().toBuilder().context(contextSet).build())) { + if (lpGroup.getName().equals(group)) { + return true; + } + } + return false; + } + + @Override + public void addGroup(UUID uuid, String group) { + User user = luckPerms.getUserManager().getUser(uuid); + user.data().add(InheritanceNode.builder(group).context(contextSet).build()); + + luckPerms.getUserManager().saveUser(user); + } + + @Override + public void removeGroup(UUID uuid, String group) { + User user = luckPerms.getUserManager().getUser(uuid); + user.data().remove(InheritanceNode.builder(group).context(contextSet).build()); + + luckPerms.getUserManager().saveUser(user); + } +} diff --git a/src/main/java/sh/okx/rankup/hook/VaultPermissionManager.java b/src/main/java/sh/okx/rankup/hook/VaultPermissionManager.java index 68d50c4..eaeaa27 100644 --- a/src/main/java/sh/okx/rankup/hook/VaultPermissionManager.java +++ b/src/main/java/sh/okx/rankup/hook/VaultPermissionManager.java @@ -1,6 +1,8 @@ package sh.okx.rankup.hook; +import net.luckperms.api.LuckPerms; import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; import org.bukkit.plugin.RegisteredServiceProvider; import sh.okx.rankup.RankupPlugin; @@ -26,6 +28,14 @@ private GroupProvider getVaultPermissionProvider() { if (!provider.hasGroupSupport()) { return null; } + String lpContext = plugin.getConfig().getString("luckperms-context"); + if (lpContext != null && !lpContext.isEmpty()) { + RegisteredServiceProvider lpProvider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); + if (lpProvider != null) { + return LuckPermsGroupProvider.createFromString(lpProvider.getProvider(), lpContext); + } + } + return new VaultGroupProvider(provider); } diff --git a/src/main/java/sh/okx/rankup/messages/NullMessageBuilder.java b/src/main/java/sh/okx/rankup/messages/NullMessageBuilder.java index dbea283..f1263e2 100644 --- a/src/main/java/sh/okx/rankup/messages/NullMessageBuilder.java +++ b/src/main/java/sh/okx/rankup/messages/NullMessageBuilder.java @@ -30,7 +30,7 @@ public MessageBuilder replaceOldRank(Rank rank) { @Override public MessageBuilder replaceSeconds(long seconds, long secondsLeft) { - return null; + return this; } @Override diff --git a/src/main/java/sh/okx/rankup/messages/pebble/RequirementContext.java b/src/main/java/sh/okx/rankup/messages/pebble/RequirementContext.java index 2e80d0c..12fa90c 100644 --- a/src/main/java/sh/okx/rankup/messages/pebble/RequirementContext.java +++ b/src/main/java/sh/okx/rankup/messages/pebble/RequirementContext.java @@ -3,6 +3,9 @@ import org.bukkit.entity.Player; import sh.okx.rankup.requirements.Requirement; +import java.util.Arrays; +import java.util.List; + public class RequirementContext { private final Player player; @@ -33,6 +36,18 @@ public String getName() { return requirement.getName(); } + public String getSub(){ + return requirement.hasSubRequirement() ? requirement.getSub() : ""; + } + + public String getValue(){ + return requirement.getValue(); + } + + public List getValues(){ + return Arrays.asList(requirement.getValuesString()); + } + public double getQuotient() { double total = getTotal(); return total == 0 ? 1 : getProgress() / total; @@ -43,6 +58,6 @@ public double getPercent() { } public String toString() { - return "Requirement[" + requirement.getFullName() + "]"; + return "Requirements[" + requirement.getFullName() + "]"; } } diff --git a/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java b/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java index d2cfd03..82a1ae6 100644 --- a/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java +++ b/src/main/java/sh/okx/rankup/placeholders/RankupExpansion.java @@ -173,15 +173,15 @@ private String getPlaceholderRequirement(Player player, Rank rank, String requir Requirement requirement = rank.getRequirement(player, requirementName); switch (params) { case "": - return orElse(requirement, Requirement::getValueString, "0"); + return orElse(requirement, Requirement::getValue, "0"); case "left": return placeholders.getSimpleFormat().format(orElse(requirement, r -> r.getRemaining(player), 0)); case "done": - return placeholders.getSimpleFormat().format(orElse(requirement, r -> r.getValueDouble() - r.getRemaining(player), 0)); + return placeholders.getSimpleFormat().format(orElse(requirement, r -> r.getTotal(player) - r.getRemaining(player), 0)); case "percent_left": - return placeholders.getPercentFormat().format(orElse(requirement, r -> (r.getRemaining(player) / r.getValueDouble()) * 100, 0)); + return placeholders.getPercentFormat().format(orElse(requirement, r -> (r.getRemaining(player) / r.getTotal(player)) * 100, 0)); case "percent_done": - return placeholders.getPercentFormat().format(orElse(requirement, r -> (1 - (r.getRemaining(player) / r.getValueDouble())) * 100, 100)); + return placeholders.getPercentFormat().format(orElse(requirement, r -> (1 - (r.getRemaining(player) / r.getTotal(player))) * 100, 100)); default: return null; } diff --git a/src/main/java/sh/okx/rankup/ranks/RankList.java b/src/main/java/sh/okx/rankup/ranks/RankList.java index 24d6341..1e32669 100644 --- a/src/main/java/sh/okx/rankup/ranks/RankList.java +++ b/src/main/java/sh/okx/rankup/ranks/RankList.java @@ -1,14 +1,11 @@ package sh.okx.rankup.ranks; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; import lombok.Getter; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; +import java.util.*; + public abstract class RankList { protected RankupPlugin plugin; @@ -81,9 +78,7 @@ public T getFirst() { } public T getRankByName(String name) { - if (name == null) { - return null; - } + if (name == null || tree == null){return null;} for (T rank : tree) { if (name.equalsIgnoreCase(rank.getRank())) { return rank; @@ -93,9 +88,7 @@ public T getRankByName(String name) { } public RankElement getByName(String name) { - if (name == null) { - return null; - } + if (name == null || tree == null){return null;} List> rankElements = tree.asList(); for (RankElement rank : rankElements) { if (name.equalsIgnoreCase(rank.getRank().getRank())) { @@ -107,6 +100,7 @@ public RankElement getByName(String name) { public RankElement getByPlayer(Player player) { + if (tree == null){return null;} List> list = tree.asList(); Collections.reverse(list); for (RankElement t : list) { @@ -118,6 +112,7 @@ public RankElement getByPlayer(Player player) { } public T getRankByPlayer(Player player) { + if (tree == null){return null;} List> list = tree.asList(); Collections.reverse(list); for (RankElement t : list) { diff --git a/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java b/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java index c792865..e713187 100644 --- a/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java +++ b/src/main/java/sh/okx/rankup/ranksgui/RanksGui.java @@ -63,12 +63,11 @@ public void open() { RankElement rankElement0 = rankElement; ItemStack item = get((section, path0) -> Gui.getItem(plugin, section.getConfigurationSection(path0), player, rankElement0), path, rankPath, basePath, null); - - inventory.setItem(index++, item); - if (index > rows * 9) { - throw new IllegalArgumentException("Ranks GUI is too small for the number of ranks. Increase the number of rows on the ranks GUI."); + if (index > rows * width - offset) { + throw new IllegalArgumentException("Ranks GUI is set to " + (rows * width - offset) + ", which is too small for " + index + " ranks. Set a larger valid ranks GUI."); } - if (index == rowIndex) { + inventory.setItem(index, item); + if (++index == rowIndex) { rowIndex += 9; index += 9 - width; } diff --git a/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java index e437efa..d01bafe 100644 --- a/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java +++ b/src/main/java/sh/okx/rankup/ranksgui/RanksGuiCommand.java @@ -18,6 +18,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (!(sender instanceof Player)) { return false; } + if (plugin.error(sender)) { + return true; + } Player player = (Player) sender; listener.open(new RanksGui(plugin, player)); diff --git a/src/main/java/sh/okx/rankup/requirements/Requirement.java b/src/main/java/sh/okx/rankup/requirements/Requirement.java index e16353f..1e5fdf5 100644 --- a/src/main/java/sh/okx/rankup/requirements/Requirement.java +++ b/src/main/java/sh/okx/rankup/requirements/Requirement.java @@ -8,6 +8,7 @@ public abstract class Requirement implements Cloneable { protected final RankupPlugin plugin; @Getter protected final String name; + @Getter private String value; @Getter private String sub; @@ -45,10 +46,6 @@ public void setValue(String value) { } } - public String getValueString() { - return value; - } - public String[] getValuesString() { return value.split(" "); } diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/AdvancementRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/AdvancementRequirement.java index ad75b90..11ed259 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/AdvancementRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/AdvancementRequirement.java @@ -15,8 +15,8 @@ * @author Link, with modifications from Okx */ public class AdvancementRequirement extends Requirement { - public AdvancementRequirement(RankupPlugin plugin) { - super(plugin, "advancement"); + public AdvancementRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected AdvancementRequirement(Requirement clone) { @@ -25,22 +25,19 @@ protected AdvancementRequirement(Requirement clone) { @Override public boolean check(Player player) { - for (String string : getValuesString()) { - Iterator advancementIterator = Bukkit.advancementIterator(); - while (advancementIterator.hasNext()) { - Advancement adv = advancementIterator.next(); - String key = adv.getKey().getKey(); - Pattern pattern = Pattern.compile(string.replace("*", ".*").replace("-", "")); - if (pattern.matcher(key).find()) { - boolean positive = !string.startsWith("-"); - - AdvancementProgress progress = player.getAdvancementProgress(adv); - if (progress.isDone() == positive) { - return true; - } + String string = getValue(); + Iterator advancementIterator = Bukkit.advancementIterator(); + while (advancementIterator.hasNext()) { + Advancement adv = advancementIterator.next(); + Pattern pattern = Pattern.compile(string.replace("*", ".*").replace("-", "")); + if (pattern.matcher(adv.getKey().getKey()).find()) { + boolean positive = !string.startsWith("-"); + AdvancementProgress progress = player.getAdvancementProgress(adv); + if (progress.isDone() == positive) { + return true; + } else { + return false; } - - } } return false; diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/BlockBreakRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/BlockBreakRequirement.java index fded98f..3f7d068 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/BlockBreakRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/BlockBreakRequirement.java @@ -8,8 +8,8 @@ import sh.okx.rankup.requirements.Requirement; public class BlockBreakRequirement extends ProgressiveRequirement { - public BlockBreakRequirement(RankupPlugin plugin) { - super(plugin, "block-break", true); + public BlockBreakRequirement(RankupPlugin plugin, String name) { + super(plugin, name, true); } protected BlockBreakRequirement(BlockBreakRequirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/CraftItemRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/CraftItemRequirement.java index 9499b16..8cf934e 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/CraftItemRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/CraftItemRequirement.java @@ -8,8 +8,8 @@ import sh.okx.rankup.requirements.Requirement; public class CraftItemRequirement extends ProgressiveRequirement { - public CraftItemRequirement(RankupPlugin plugin) { - super(plugin, "craft-item", true); + public CraftItemRequirement(RankupPlugin plugin, String name) { + super(plugin, name, true); } protected CraftItemRequirement(CraftItemRequirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/GroupRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/GroupRequirement.java index 757fa37..c8a8318 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/GroupRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/GroupRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class GroupRequirement extends Requirement { - public GroupRequirement(RankupPlugin plugin) { - super(plugin, "group"); + public GroupRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected GroupRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/MobKillsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/MobKillsRequirement.java index 4406c6e..2db6c37 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/MobKillsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/MobKillsRequirement.java @@ -10,8 +10,8 @@ import java.util.Objects; public class MobKillsRequirement extends ProgressiveRequirement { - public MobKillsRequirement(RankupPlugin plugin) { - super(plugin, "mob-kills", true); + public MobKillsRequirement(RankupPlugin plugin, String name) { + super(plugin, name, true); } protected MobKillsRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/PermissionRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/PermissionRequirement.java index 5546af6..96c2212 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/PermissionRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/PermissionRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class PermissionRequirement extends Requirement { - public PermissionRequirement(RankupPlugin plugin) { - super(plugin, "permission"); + public PermissionRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected PermissionRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/PlaceholderRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/PlaceholderRequirement.java index 583833f..4183b25 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/PlaceholderRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/PlaceholderRequirement.java @@ -10,8 +10,8 @@ public class PlaceholderRequirement extends ProgressiveRequirement { public static final double DELTA = 0.00001D; - public PlaceholderRequirement(RankupPlugin plugin) { - super(plugin, "placeholder"); + public PlaceholderRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } public PlaceholderRequirement(PlaceholderRequirement clone) { @@ -63,7 +63,7 @@ public double getTotal(Player player) { } private String[] getParts(Player player) { - String[] parts = getValueString().split(" "); + String[] parts = getValue().split(" "); if (parts.length < 3) { throw new IllegalArgumentException( "Placeholder requirements must be in the form %placeholder% string"); @@ -78,8 +78,13 @@ private String[] getParts(Player player) { @Override public String getFullName() { - String[] parts = getValueString().split(" "); - return name + "#" + parts[0].replace("%", ""); + return name + "#" + getSub(); + } + + @Override + public String getSub() { + String[] parts = getValue().split(" "); + return parts[0].replace("%", ""); } @Override diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/PlayerKillsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/PlayerKillsRequirement.java index d53adf7..778df55 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/PlayerKillsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/PlayerKillsRequirement.java @@ -7,8 +7,8 @@ import sh.okx.rankup.requirements.Requirement; public class PlayerKillsRequirement extends ProgressiveRequirement { - public PlayerKillsRequirement(RankupPlugin plugin) { - super(plugin, "player-kills"); + public PlayerKillsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected PlayerKillsRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/PlaytimeMinutesRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/PlaytimeMinutesRequirement.java index e802c20..1f74f11 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/PlaytimeMinutesRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/PlaytimeMinutesRequirement.java @@ -10,8 +10,8 @@ public class PlaytimeMinutesRequirement extends ProgressiveRequirement { private static final int TICKS_PER_MINUTE = 20 * 60; private Statistic playOneTick; - public PlaytimeMinutesRequirement(RankupPlugin plugin) { - super(plugin, "playtime-minutes"); + public PlaytimeMinutesRequirement(RankupPlugin plugin, String name) { + super(plugin, name); try { playOneTick = Statistic.valueOf("PLAY_ONE_MINUTE"); } catch (IllegalArgumentException e) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/TotalMobKillsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/TotalMobKillsRequirement.java index 1d634aa..26a29b9 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/TotalMobKillsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/TotalMobKillsRequirement.java @@ -7,8 +7,8 @@ import sh.okx.rankup.requirements.Requirement; public class TotalMobKillsRequirement extends ProgressiveRequirement { - public TotalMobKillsRequirement(RankupPlugin plugin) { - super(plugin, "total-mob-kills"); + public TotalMobKillsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } private TotalMobKillsRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/UseItemRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/UseItemRequirement.java index 54d2c7c..187f039 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/UseItemRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/UseItemRequirement.java @@ -8,8 +8,8 @@ import sh.okx.rankup.requirements.Requirement; public class UseItemRequirement extends ProgressiveRequirement { - public UseItemRequirement(RankupPlugin plugin) { - super(plugin, "use-item", true); + public UseItemRequirement(RankupPlugin plugin, String name) { + super(plugin, name, true); } protected UseItemRequirement(UseItemRequirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/WorldRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/WorldRequirement.java index 8414347..891823a 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/WorldRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/WorldRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class WorldRequirement extends Requirement { - public WorldRequirement(RankupPlugin plugin) { - super(plugin, "world"); + public WorldRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected WorldRequirement(Requirement clone) { @@ -15,8 +15,7 @@ protected WorldRequirement(Requirement clone) { @Override public boolean check(Player player) { - String[] worlds = getValuesString(); - for (String world : worlds) { + for (String world : getValuesString()) { return player.getWorld().getName().equalsIgnoreCase(world); } return false; diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsAchievementRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsAchievementRequirement.java index 5e7f8bd..d286e5b 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsAchievementRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsAchievementRequirement.java @@ -4,26 +4,33 @@ import com.hm.achievement.api.AdvancedAchievementsAPIFetcher; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; -import sh.okx.rankup.requirements.Requirement; +import sh.okx.rankup.requirements.ProgressiveRequirement; -public class AdvancedAchievementsAchievementRequirement extends Requirement { - public AdvancedAchievementsAchievementRequirement(RankupPlugin plugin) { - super(plugin, "advancedachievements-achievement"); +public class AdvancedAchievementsAchievementRequirement extends ProgressiveRequirement +{ + public AdvancedAchievementsAchievementRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } - protected AdvancedAchievementsAchievementRequirement(Requirement clone) { + protected AdvancedAchievementsAchievementRequirement(ProgressiveRequirement clone) { super(clone); } @Override public boolean check(Player player) { AdvancedAchievementsAPI api = AdvancedAchievementsAPIFetcher.fetchInstance().get(); - return api.hasPlayerReceivedAchievement(player.getUniqueId(), getValueString()); + for (String achievement : getValuesString()) { + if (api.hasPlayerReceivedAchievement(player.getUniqueId(), achievement)) { + return true; + } + } + + return false; } @Override public String getFullName() { - return super.getFullName() + "#" + getValueString(); + return super.getFullName() + "#" + getValue(); } @Override @@ -32,7 +39,13 @@ public double getTotal(Player player) { } @Override - public Requirement clone() { + public double getProgress(Player player) + { + return this.check(player) ? 1 : 0; + } + + @Override + public ProgressiveRequirement clone() { return new AdvancedAchievementsAchievementRequirement(this); } } diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsTotalRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsTotalRequirement.java index efbc2ea..5f3beb0 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsTotalRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/advancedachievements/AdvancedAchievementsTotalRequirement.java @@ -7,8 +7,8 @@ import sh.okx.rankup.requirements.ProgressiveRequirement; public class AdvancedAchievementsTotalRequirement extends ProgressiveRequirement { - public AdvancedAchievementsTotalRequirement(RankupPlugin plugin) { - super(plugin, "advancedachievements-total"); + public AdvancedAchievementsTotalRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } private AdvancedAchievementsTotalRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOPowerLevelRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOPowerLevelRequirement.java index ba752e0..b601668 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOPowerLevelRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOPowerLevelRequirement.java @@ -7,8 +7,8 @@ import sh.okx.rankup.requirements.ProgressiveRequirement; public class McMMOPowerLevelRequirement extends ProgressiveRequirement { - public McMMOPowerLevelRequirement(RankupPlugin plugin) { - super(plugin, "mcmmo-power-level"); + public McMMOPowerLevelRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected McMMOPowerLevelRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOSkillRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOSkillRequirement.java index fc30d63..9f7224a 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOSkillRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/mcmmo/McMMOSkillRequirement.java @@ -6,8 +6,8 @@ import sh.okx.rankup.requirements.ProgressiveRequirement; public class McMMOSkillRequirement extends ProgressiveRequirement { - public McMMOSkillRequirement(RankupPlugin plugin) { - super(plugin, "mcmmo", true); + public McMMOSkillRequirement(RankupPlugin plugin, String name) { + super(plugin, name, true); } protected McMMOSkillRequirement(McMMOSkillRequirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/superbvote/SuperbVoteVotesRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/superbvote/SuperbVoteVotesRequirement.java index 47d7253..8d777e9 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/superbvote/SuperbVoteVotesRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/superbvote/SuperbVoteVotesRequirement.java @@ -7,8 +7,8 @@ import sh.okx.rankup.requirements.Requirement; public class SuperbVoteVotesRequirement extends ProgressiveRequirement { - public SuperbVoteVotesRequirement(RankupPlugin plugin) { - super(plugin, "superbvote-votes"); + public SuperbVoteVotesRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } private SuperbVoteVotesRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberResidentsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberResidentsRequirement.java index d6a04c1..f80a9cb 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberResidentsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberResidentsRequirement.java @@ -6,8 +6,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyKingNumberResidentsRequirement extends ProgressiveRequirement { - public TownyKingNumberResidentsRequirement(RankupPlugin plugin) { - super(plugin, "towny-king-residents"); + public TownyKingNumberResidentsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyKingNumberResidentsRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberTownsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberTownsRequirement.java index e31c173..d4290f0 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberTownsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingNumberTownsRequirement.java @@ -6,8 +6,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyKingNumberTownsRequirement extends ProgressiveRequirement { - public TownyKingNumberTownsRequirement(RankupPlugin plugin) { - super(plugin, "towny-king-towns"); + public TownyKingNumberTownsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyKingNumberTownsRequirement(TownyKingNumberTownsRequirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingRequirement.java index 4161433..b0977d5 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyKingRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyKingRequirement extends Requirement { - public TownyKingRequirement(RankupPlugin plugin) { - super(plugin, "towny-king"); + public TownyKingRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyKingRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorNumberResidentsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorNumberResidentsRequirement.java index dcf25de..0683dc0 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorNumberResidentsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorNumberResidentsRequirement.java @@ -6,8 +6,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyMayorNumberResidentsRequirement extends ProgressiveRequirement { - public TownyMayorNumberResidentsRequirement(RankupPlugin plugin) { - super(plugin, "towny-mayor-residents"); + public TownyMayorNumberResidentsRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyMayorNumberResidentsRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorRequirement.java index 722ee95..f3cf71a 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyMayorRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyMayorRequirement extends Requirement { - public TownyMayorRequirement(RankupPlugin plugin) { - super(plugin, "towny-mayor"); + public TownyMayorRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyMayorRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyResidentRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyResidentRequirement.java index f470a5c..1efa240 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyResidentRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/towny/TownyResidentRequirement.java @@ -5,8 +5,8 @@ import sh.okx.rankup.requirements.Requirement; public class TownyResidentRequirement extends Requirement { - public TownyResidentRequirement(RankupPlugin plugin) { - super(plugin, "towny-resident"); + public TownyResidentRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected TownyResidentRequirement(Requirement clone) { diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java index 880020e..aa7da86 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsDeductibleRequirement.java @@ -1,6 +1,5 @@ package sh.okx.rankup.requirements.requirement.votingplugin; -import com.bencodez.votingplugin.user.UserManager; import com.bencodez.votingplugin.user.VotingPluginUser; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; @@ -19,7 +18,7 @@ protected VotingPluginPointsDeductibleRequirement(Requirement clone) { @Override public void apply(Player player, double multiplier) { - VotingPluginUser user = UserManager.getInstance().getVotingPluginUser(player); + VotingPluginUser user = VotingPluginUtil.getInstance().getUserManager().getVotingPluginUser(player); if(!user.removePoints(getValueInt())) { plugin.getLogger().warning("Unable to remove VotingPlugin points"); } diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java index 67c1c52..3259c4e 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginPointsRequirement.java @@ -1,6 +1,5 @@ package sh.okx.rankup.requirements.requirement.votingplugin; -import com.bencodez.votingplugin.user.UserManager; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.requirements.ProgressiveRequirement; @@ -18,7 +17,7 @@ protected VotingPluginPointsRequirement(Requirement clone) { @Override public double getProgress(Player player) { - return UserManager.getInstance().getVotingPluginUser(player).getPoints(); + return VotingPluginUtil.getInstance().getUserManager().getVotingPluginUser(player).getPoints(); } @Override diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginUtil.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginUtil.java new file mode 100644 index 0000000..0d44f5f --- /dev/null +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginUtil.java @@ -0,0 +1,33 @@ +package sh.okx.rankup.requirements.requirement.votingplugin; + +import com.bencodez.votingplugin.VotingPluginMain; +import com.bencodez.votingplugin.user.UserManager; + +import java.lang.reflect.InvocationTargetException; + +public class VotingPluginUtil { + private static VotingPluginUtil instance; + + private UserManager userManager; + + private VotingPluginUtil() { + try { + userManager = (UserManager) UserManager.class.getMethod("getInstance").invoke(null); + } catch (NoSuchMethodException e) { + userManager = VotingPluginMain.getPlugin().getVotingPluginUserManager(); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static VotingPluginUtil getInstance() { + if (instance == null) { + instance = new VotingPluginUtil(); + } + return instance; + } + + public UserManager getUserManager() { + return userManager; + } +} diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginVotesRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginVotesRequirement.java index be691f0..7cb2508 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginVotesRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/votingplugin/VotingPluginVotesRequirement.java @@ -1,15 +1,14 @@ package sh.okx.rankup.requirements.requirement.votingplugin; import com.bencodez.votingplugin.topvoter.TopVoter; -import com.bencodez.votingplugin.user.UserManager; import org.bukkit.entity.Player; import sh.okx.rankup.RankupPlugin; import sh.okx.rankup.requirements.ProgressiveRequirement; import sh.okx.rankup.requirements.Requirement; public class VotingPluginVotesRequirement extends ProgressiveRequirement { - public VotingPluginVotesRequirement(RankupPlugin plugin) { - super(plugin, "votingplugin-votes"); + public VotingPluginVotesRequirement(RankupPlugin plugin, String name) { + super(plugin, name); } protected VotingPluginVotesRequirement(Requirement clone) { @@ -18,7 +17,7 @@ protected VotingPluginVotesRequirement(Requirement clone) { @Override public double getProgress(Player player) { - return UserManager.getInstance().getVotingPluginUser(player).getTotal(TopVoter.AllTime); + return VotingPluginUtil.getInstance().getUserManager().getVotingPluginUser(player).getTotal(TopVoter.AllTime); } @Override diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 52e5467..606c9d5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,82 +1,116 @@ -# this is used for letting you know that you need to update/change your config file +# This is used for letting you know that you need to update/change your config file. +# Do not change this. version: 10 -# the locale to use for messages -# all messages can be customised but this allows you to -# choose messages that are already translated -# locales can be found in the locale/ folder +# +----------------------------------------------------------------+ +# | You must restart your server if you make changes to this file! | +# +----------------------------------------------------------------+ + +# The locale to use for messages. +# All messages can be customised but this allows you to. +# Choose messages that are already translated. +# Locales can be found in the locale/ folder. locale: en -# interval (in minutes) to check to autorankup players -# ranking up manually will always be enabled -# set to 0 to disable +# Interval (in minutes) to check to autorankup players. +# Ranking up manually will always be enabled. +# Set to 0 to disable. + +# Players will need the rankup.auto permission to make use of this! +# Permission is given by default. autorankup-interval: 0 -# whether /ranks and /prestiges should be enabled (true) or disabled (false) +# Whether /ranks and /prestiges should be enabled (true) or disabled (false) # /rankup3 reload will not do anything if this is changed, -# you will have to restart your server. +# You will have to restart your server. ranks: true -# you can alternatively negate the permission rankup.prestiges -# this will also make the command not autocomplete in 1.13 + +# You can alternatively negate the permission rankup.prestiges. +# This will also make the command not autocomplete in 1.13+. prestiges: true -# whether to enable the /ranks GUI. -# will override the /ranks command +# Whether to enable the /ranks GUI. +# Will override the /ranks command. ranks-gui: false -# whether or not /prestige and /prestiges should be enabled. -# when a player reaches the top rank, they can do /prestige to return to the first rank, +# Whether /prestige and /prestiges should be enabled. +# When a player reaches the top rank, they can /prestige to return to the first rank, # but you will be able to grant them an additional "prestige" group or additional items. # -# if you do not want this command to autocomplete, make sure +# If you do not want this command to autocomplete, make sure # you negate the permission rankup.prestige with your permissions plugin. -# if enabled, a prestiges.yml file will be generated with some example prestiges -# You must restart your server when you change this for it to work! +# If enabled, a prestiges.yml file will be generated with some example prestiges +# you must restart your server when you change this for it to work! prestige: false -# if true, players with the permission rankup.notify will receive notifications when they join +# If true, players with the permission rankup.notify will receive notifications when they join # to update if the server is on an older version of Rankup. notify-update: true -# if rankups and prestiges should be by permissions -# if false, players will be checked for if they have a group of the same name as in rankups.yml, +# +------------------------------------------------------+ +# | Don't change this unless you know what you're doing! | +# +------------------------------------------------------+ +# Changing this setting to "true" can lead to your rankups.yml no longer working. +# Does the following: +# if false, players will be checked for if they have a group of the same name as in rankups.yml, # and automatically added and taken away from those groups. -# if true, players will be checked for the permission rankup.rank.RANK, where RANK +# if true, players will be checked for the permission rankup.rank.RANK, where RANK # is the rankup in rankups.yml. Nothing will automatically happen on rankup, so you must # use commands to change a player's group or permission. +# Learn more about this: +# https://okx.sh/rankup/Advanced-Configuration/Permission-Rankup.html permission-rankup: false -# how people should confirm ranking up -# options are: gui, text or none +# if not empty, these are the contexts to use when modifying groups if LuckPerms is enabled +# if empty, this will be based on your LuckPerms config.yml 'use-vault-server' and 'vault-server' +# this option will only if permission-rankup is disabled +# +# luckperms-context: 'server=global' # to make all rankups global +# luckperms-context: 'server=survival' # to make all rankups specific to survival +# luckperms-context: 'server=survival world=world_nether' # to make all rankups specific to the nether world in survival +luckperms-context: '' + +# if players can use /rankup noconfirm to bypass any confirmation +# the permission rankup.noconfirm is used for this command, but it is true by default +# the console can always do /rankup noconfirm +enable-noconfirm: true + +# How people should confirm ranking up +# Options are: gui, text or none confirmation-type: 'gui' -# how long, in seconds, people have to wait between a successful /rankup or /prestige +# How long in seconds people have to wait between a successful /rankup or /prestige # set to 0 to disable. cooldown: 1 -# if enabled, players can run /maxrankup to rankup as many times as possible, +# If enabled, players can run /maxrankup to rankup as many times as possible, # before they fail the requirements for the next rank. -# the permission rankup.maxrankup is used for this command, but it is given by default. -# note that /maxrankup, if enabled, has no confirmation. +# The permission rankup.maxrankup is used for this command, but it is given by default. +# Note that /maxrankup, if enabled, has no confirmation. max-rankup: - # You must restart your server if you enable or disable /maxrankup! enabled: false - # whether to send a message for each rankup a player does - # if set to true, the chat may be spammed for each rankup a player goes through with /maxrankup - # if set to false, only the last rankup will be shown (if a player starts on rank A, then does - # /maxrankup and ranks up to B and then C, it will just say "player has ranked up to C") - individual-messages: true -# options when using the text rankup confirmation + # Whether to send a message for each rank a player ranks up for. + # -> If true, the chat may be spammed for each rankup a player goes through with /maxrankup + # Example: a player starts on rank A, but can rankup to rank D, the chat will say: + # "player has ranked up to B" + # "player has ranked up to C" + # "player has ranked up to D" + # -> If false, only the last rankup will be shown + # Example: a player starts on rank A, but can rankup to rank D, the chat will say: + # "player has ranked up to D". + individual-messages: false + +# Options when using the text rankup confirmation text: - # the time in seconds for a player to - # confirm by typing /rankup again + # The time in seconds for a player to + # confirm by typing /rankup again. timeout: 10 -# placeholders: +# Placeholders: # https://okx.sh/rankup/Placeholders.html placeholders: - # format for money. for more information, see + # Format for money. for more information, see # https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html money-format: "#,##0.##" percent-format: "0.##" @@ -95,12 +129,12 @@ placeholders: incomplete: "Incomplete" last-rank-display-name: "last rank" -# what to shorten money by. +# What to shorten money by. # ie 1000 -> 1k -# set to an empty list to disable -# for each entry here, it counts as increasing by a factor of 1,000 -# the first represents thousands (1,000) then millions (1,000,000) then billions (1,000,000,000) etc. -# this is used in the "| shortmoney" filter +# Set to an empty list to disable +# For each entry here, it counts as increasing by a factor of 1,000 +# The first represents thousands (1,000) then millions (1,000,000) then billions (1,000,000,000) etc. +# This is used in the "| shortmoney" filter shorten: - 'K' - 'M' @@ -108,4 +142,4 @@ shorten: - 'T' - 'Q' - 'Qu' -- 'S' \ No newline at end of file +- 'S' diff --git a/src/main/resources/locale/en.yml b/src/main/resources/locale/en.yml index b7b781b..3b0c9db 100644 --- a/src/main/resources/locale/en.yml +++ b/src/main/resources/locale/en.yml @@ -1,40 +1,53 @@ -# the messages in this section can be customised for each rankup in rankups.yml. +# The messages in this section can be customised for each rankup in rankups.yml. rankup: requirements-not-met: "&cYou need {{rank.requirement('money').total | money}} money to rankup." - no-rankup: "&eYou are at the highest rank." - # set to an empty string, ie: success-public: "" + + # Set to an empty string, ie: success-public: "" # to hide that message. success-public: "&a{{player}} &ehas ranked up to: &d{{next.rank}}" success-private: "&aYou have ranked up to: &d{{next.rank}}" - # used for the text confirmation + + must-prestige: "&cYou must prestige to /rankup further!" + no-rankup: "&eYou are at the highest rank." + + # Only applies if confirmation-type: 'text' in config.yml. confirmation: |- &eAre you sure you want to rankup to &a{{next.rank}}&e? &eType &c/rankup &eagain to confirm. - must-prestige: "&cYou must prestige to /rankup further!" + # Only applies if confirmation-type: 'gui' in config.yml (Default). gui: rows: 1 title: "Rankup to {{next.rank}}" rankup: - material: EMERALD_BLOCK - # index can be separated by spaces to show in multiple groups - # for example: 0-3 9-12 18-21 - # you can also just use a single number instead of a range. + + # ===[ IMPORTANT PRE-FLATTENING INFO ]=== + # If you are using a 1.8-1.12 and you want to change this + # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 + # This works for both the rankup, cancel and fill blocks as well. + + material: GREEN_STAINED_GLASS_PANE + + # Index can be separated by spaces to show in multiple groups. + # -> For example: 0-3 9-12 18-21 + # But the "rows" must have enough space. + # You can also just use a single number instead of a range. + index: 0-3 - name: '&a&lConfirm' - # lore is optional - lore: '&6Rankup to &b{{next.rank}}' + name: "&a&lConfirm" + + # Lore is optional + lore: "&6Rankup to &b{{next.rank}}" cancel: - material: REDSTONE_BLOCK + material: RED_STAINED_GLASS_PANE index: 5-8 - name: '&c&lCancel' + name: "&c&lCancel" + lore: "&4Stay at &c{{rank.rank}}" fill: name: ' ' - # if you are using a 1.8-1.12 and you want to change this - # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 - # this works for both the rankup and cancel blocks as well material: BLACK_STAINED_GLASS_PANE + # Only applies if ranks-gui: true in config.yml. ranksgui: title: "Ranks" rows: 3 @@ -42,40 +55,38 @@ rankup: width: 7 complete: material: GREEN_STAINED_GLASS_PANE - name: "&aRank &7{{next.rank}} &a(completed)" + name: "&aRank &7{{next.rank}}" + # Lore is optional. + lore: "&aCompleted" current: material: ORANGE_STAINED_GLASS_PANE name: "&dRankup to &7{{next.rank}}" + lore: "&cClick me to /rankup!" incomplete: material: RED_STAINED_GLASS_PANE - name: "&cRank &7{{next.rank}} &c(requires rankup)" + name: "&cRank &7{{next.rank}}" + lore: "&cRequires rankup" fill: material: BLACK_STAINED_GLASS_PANE name: ' ' - - # you can (and probably should) you override these in rankups.yml - # to show the specific requirements for each rank. - # however if you are just using money or don't need to change the message per rank, you can use any combination of: - # {{rank.requirement('money').total | simple}} {MONEY_NEEDED} {PERCENT_DONE } {PERCENT_LEFT } {AMOUNT } {AMOUNT_NEEDED } - # {{rank.requirement('money').total | simple}} and {MONEY_NEEDED} are different from {AMOUNT money} and {AMOUNT_NEEDED money} in that they use a different format. - # here is an example of showing the requirements for just money: - #list: - # complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}} &efor &7${{rank.requirement('money').total | simple}}" - # current: "&c{{rank.rank}} &e\xbb &c{{next.rank}} &efor &a${{rank.requirement('money').total | simple}} &e{PERCENT_DONE money}%" - # incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}} &efor &a${{rank.requirement('money').total | simple}}" + # Only applies if ranks-gui: false in config.yml (Default). list: complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}}" current: "&c{{rank.rank}} &e\xbb &c{{next.rank}}" incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}}" - # an empty string disables the header/footer + # An empty string disables the header/footer. header: "" footer: "" - # sent when a player tries to rankup when they are on cooldown + + # Sent when a player tries to rankup when they are on cooldown cooldown: singular: "&cYou must wait {{seconds_left}} more second to rankup again." plural: "&cYou must wait {{seconds_left}} more seconds to rankup again." -# prestige messages can also be customised + +# Prestige messages can also be customised. +# They can be customized on a per-prestige basis in the prestiges.yml. +# If you do not see a prestiges.yml, enable it in the config.yml. prestige: requirements-not-met: "&cYou need {{rank.requirement('money').total | money}} money to prestige." no-prestige: "&eYou are at the highest prestige." @@ -89,20 +100,23 @@ prestige: gui: title: "Prestige to {{next.rank}}" + + # ===[ IMPORTANT PRE-FLATTENING INFO ]=== + # If you are using a 1.8-1.12 and you want to change this + # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 + # This works for both the rankup, cancel and fill blocks as well. + rankup: - material: GOLD_BLOCK + material: BLUE_STAINED_GLASS_PANE index: 0-3 name: '&a&lConfirm' lore: '&6Prestige to &b{{next.rank}}' cancel: - material: REDSTONE_BLOCK + material: RED_STAINED_GLASS_PANE index: 5-8 name: '&c&lCancel' fill: name: ' ' - # if you are using a 1.8-1.12 and you want to change this - # you can use MATERIAL:data, for example STAINED_GLASS_PANE:8 - # this works for both the rankup and cancel blocks as well material: BLACK_STAINED_GLASS_PANE list: @@ -115,5 +129,6 @@ prestige: singular: "&cYou must wait {{seconds_left}} second to prestige again." plural: "&cYou must wait {{seconds_left}} more seconds to prestige again." +# Other strings not-high-enough: "&cYou cannot prestige at your rank!" not-in-ladder: "&cSorry, but we could not find any rankups for the group(s) you are in. Use /ranks to list the rankups." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5b95e1b..d16c456 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ version: "${version}" main: sh.okx.rankup.RankupPlugin author: Okx depend: [Vault] -softdepend: [PlaceholderAPI, mcMMO, AdvancedAchievements, Towny, SuperbVote, VotingPlugin] +softdepend: [PlaceholderAPI, mcMMO, AdvancedAchievements, Towny, SuperbVote, VotingPlugin, LuckPerms] api-version: 1.13 commands: @@ -36,6 +36,7 @@ permissions: rankup.prestiges: true rankup.auto: true rankup.maxrankup: true + rankup.noconfirm: true rankup.admin: children: # if a player can see if the plugin needs updating when they run /pru @@ -47,6 +48,7 @@ permissions: # if a player receives notifications to update rankup when they log in. rankup.notify: true rankup.playtime: true + rankup.noconfirm.other: true default: op rankup.rankup: default: true @@ -60,6 +62,8 @@ permissions: default: true rankup.maxrankup: default: true + rankup.noconfirm: + default: true rankup.playtime: description: Use all /rankup3 playtime subcommands for anyone. children: diff --git a/src/main/resources/rankups.yml b/src/main/resources/rankups.yml index 1eb94fb..e9008c6 100644 --- a/src/main/resources/rankups.yml +++ b/src/main/resources/rankups.yml @@ -5,40 +5,81 @@ # Join the discord server for live support: https://discord.gg/maB4382 (buyers only) # -# this name doesn't matter -Aexample: - # the name of the group - # players have to be in this rank to rankup +# This name must be unique +# but can be anything you like. +ExampleA: + + # The name of the group players + # have to be in order to rank up. + # + # Prioritize displaynames! rank: 'A' - # the name of the rank a player can rankup to + + # The name of the group players + # will rank up to next. + # + # Prioritize displaynames! next: 'B' - # List of requirements to go to the next rank - # This example will charge 1000 money to rankup from A to B. - # https://okx.sh/rankup/List-of-Requirements.html - # custom requirements can also be added by other plugins. + + # List of requirements to go to the next rank. + # This example will charge 1000 money to rank up from A to B. + + # Learn more https://okx.sh/rankup/List-of-Requirements.html requirements: - 'money 1000' - # the console will run these commands when a player ranks up - # nb: groups are automatically changed with vault - #commands: - # this will run when a player ranks up from A to B. - #- 'say {{player}} well done for ranking up from {{rank.rank}} to {{next.rank}}!' -Bexample: + +ExampleB: rank: 'B' next: 'C' + + # This message will be sent + # in the server chat. + success-public: "&a{{player}} &ehas ranked up to: &d{{next.rank}}" requirements: - 'money 2500' -Cexample: + +ExampleC: rank: 'C' next: 'D' requirements: - 'money 5000' - 'xp-level 2' - # you can have a custom messages for each rank - # the paths of these messages are the same as in the messages for your locale + + # You can have a custom messages for each rank! + # the paths of these messages are the same as in the messages for your locale. rankup: - requirements-not-met: '&cYou need 5000 money and 2 levels of XP to rankup to D.' - list: - complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}} &e(5000 money, 2 XP levels)" - current: "&c{{rank.rank}} &e\xbb &c{{next.rank}} &e(5000 money, 2 XP levels)" - incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}} &e(5000 money, 2 XP levels)" \ No newline at end of file + + # The following message contains a placeholder. + + # Quick breakdown: + # - rank.req = specifies the rank. + # - money = specifies the requirement. + # - total = specifies what you want from the placeholder. + # - simple = formats the placeholder. + # Learn more: https://okx.sh/rankup/Text-Templating.html + + requirements-not-met: "&cYou need {{ rank.req('money').total | simple }} money and {{ rank.req('xp-level').total | simple }} levels of XP to rank up to {{next.rank}}." + +ExampleD: + rank: 'D' + next: 'E' + requirements: + - 'money 10000' + - 'xp-level 5' + rankup: + + # Small intro to multi-line syntax + # -> Notice the | after requirements-not-met. + # It means it's a multi-line message. + # + # -> The actual message is on the following + # line indented by 2 spaces. + # + # -> Notice that the message doesn't + # double quotes ("") like the others. + + requirements-not-met: | + &cYou need: + &c- {{ rank.req('money').total | simple }} money + &c- {{ rank.req('xp-level').total | simple }} XP levels + &cTo rank up to {{next.rank}}! \ No newline at end of file diff --git a/src/test/java/sh/okx/rankup/RankupBasicsTest.java b/src/test/java/sh/okx/rankup/RankupBasicsTest.java index 78ed6d8..1296143 100644 --- a/src/test/java/sh/okx/rankup/RankupBasicsTest.java +++ b/src/test/java/sh/okx/rankup/RankupBasicsTest.java @@ -41,7 +41,7 @@ public void testNotInLadder() { public void testLastRank() { PlayerMock player = server.addPlayer(); - groupProvider.addGroup(player.getUniqueId(), "D"); + groupProvider.addGroup(player.getUniqueId(), "E"); plugin.getHelper().rankup(player); diff --git a/src/test/java/sh/okx/rankup/RankupCommandsTest.java b/src/test/java/sh/okx/rankup/RankupCommandsTest.java deleted file mode 100644 index db09752..0000000 --- a/src/test/java/sh/okx/rankup/RankupCommandsTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package sh.okx.rankup; - -public class RankupCommandsTest extends RankupTest { - -} diff --git a/src/test/java/sh/okx/rankup/WorldRequirementTest.java b/src/test/java/sh/okx/rankup/WorldRequirementTest.java new file mode 100644 index 0000000..41c5326 --- /dev/null +++ b/src/test/java/sh/okx/rankup/WorldRequirementTest.java @@ -0,0 +1,29 @@ +package sh.okx.rankup; + + +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.bukkit.Location; +import org.junit.jupiter.api.Test; +import sh.okx.rankup.placeholders.RankupExpansion; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WorldRequirementTest extends RankupTest { + + public WorldRequirementTest() { + super("world"); + } + + @Test + public void testStatusComplete() { + PlayerMock player = server.addPlayer(); + groupProvider.addGroup(player.getUniqueId(), "a"); + + RankupExpansion expansion = plugin.getPlaceholders().getExpansion(); + assertEquals("0", expansion.placeholder(player, "requirement_world_percent_done")); + + player.teleport(new Location(server.getWorld("the_nether"), 0, 0, 0)); + + assertEquals("100", expansion.placeholder(player, "requirement_world_percent_done")); + } +} \ No newline at end of file diff --git a/src/test/java/sh/okx/rankup/commands/DisabledNoConfirmCommandTest.java b/src/test/java/sh/okx/rankup/commands/DisabledNoConfirmCommandTest.java new file mode 100644 index 0000000..d5f6e42 --- /dev/null +++ b/src/test/java/sh/okx/rankup/commands/DisabledNoConfirmCommandTest.java @@ -0,0 +1,27 @@ +package sh.okx.rankup.commands; + +import static org.junit.jupiter.api.Assertions.*; + +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.junit.jupiter.api.Test; +import sh.okx.rankup.RankupTest; + +public class DisabledNoConfirmCommandTest extends RankupTest { + + public DisabledNoConfirmCommandTest() { + super("noconfirm"); + } + + @Test + public void testNoConfirmDisabled() { + PlayerMock player = server.addPlayer(); + player.addAttachment(plugin, "rankup.rankup", true); + player.addAttachment(plugin, "rankup.noconfirm", true); + + plugin.getPermissions().addGroup(player.getUniqueId(), "A"); + plugin.getEconomy().setPlayer(player, 10000); + + plugin.getCommand("rankup").execute(player, "rankup", new String[] {"noconfirm"}); + assertFalse(plugin.getPermissions().inGroup(player.getUniqueId(), "B")); + } +} diff --git a/src/test/java/sh/okx/rankup/commands/EnabledNoConfirmCommandTest.java b/src/test/java/sh/okx/rankup/commands/EnabledNoConfirmCommandTest.java new file mode 100644 index 0000000..f52bc9c --- /dev/null +++ b/src/test/java/sh/okx/rankup/commands/EnabledNoConfirmCommandTest.java @@ -0,0 +1,23 @@ +package sh.okx.rankup.commands; + +import static org.junit.jupiter.api.Assertions.*; + +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.junit.jupiter.api.Test; +import sh.okx.rankup.RankupTest; + +public class EnabledNoConfirmCommandTest extends RankupTest { + + @Test + public void testNoConfirmEnabled() { + PlayerMock player = server.addPlayer(); + player.addAttachment(plugin, "rankup.rankup", true); + player.addAttachment(plugin, "rankup.noconfirm", true); + + plugin.getPermissions().addGroup(player.getUniqueId(), "A"); + plugin.getEconomy().setPlayer(player, 10000); + + plugin.getCommand("rankup").execute(player, "rankup", new String[] {"noconfirm"}); + assertTrue(plugin.getPermissions().inGroup(player.getUniqueId(), "B")); + } +} diff --git a/src/test/resources/noconfirm/config.yml b/src/test/resources/noconfirm/config.yml new file mode 100644 index 0000000..8bc4244 --- /dev/null +++ b/src/test/resources/noconfirm/config.yml @@ -0,0 +1,116 @@ +# this is used for letting you know that you need to update/change your config file +version: 10 + +# the locale to use for messages +# all messages can be customised but this allows you to +# choose messages that are already translated +# locales can be found in the locale/ folder +locale: en + +# interval (in minutes) to check to autorankup players +# ranking up manually will always be enabled +# set to 0 to disable +autorankup-interval: 0 + +# whether /ranks and /prestiges should be enabled (true) or disabled (false) +# /rankup3 reload will not do anything if this is changed, +# you will have to restart your server. +ranks: true +# you can alternatively negate the permission rankup.prestiges +# this will also make the command not autocomplete in 1.13 +prestiges: true + +# whether to enable the /ranks GUI. +# will override the /ranks command +ranks-gui: false + +# whether /prestige and /prestiges should be enabled. +# when a player reaches the top rank, they can do /prestige to return to the first rank, +# but you will be able to grant them an additional "prestige" group or additional items. +# +# if you do not want this command to autocomplete, make sure +# you negate the permission rankup.prestige with your permissions plugin. +# if enabled, a prestiges.yml file will be generated with some example prestiges +# You must restart your server when you change this for it to work! +prestige: false + +# if true, players with the permission rankup.notify will receive notifications when they join +# to update if the server is on an older version of Rankup. +notify-update: true + +# if rankups and prestiges should be by permissions +# if false, players will be checked for if they have a group of the same name as in rankups.yml, +# and automatically added and taken away from those groups. +# if true, players will be checked for the permission rankup.rank.RANK, where RANK +# is the rankup in rankups.yml. Nothing will automatically happen on rankup, so you must +# use commands to change a player's group or permission. +permission-rankup: false + +# if players can use /rankup noconfirm to bypass any confirmation +# the permission rankup.noconfirm is used for this command, but it is true by default +# the console can always do /rankup noconfirm +enable-noconfirm: false + +# how people should confirm ranking up +# options are: gui, text or none +confirmation-type: 'gui' + +# how long, in seconds, people have to wait between a successful /rankup or /prestige +# set to 0 to disable. +cooldown: 1 + +# if enabled, players can run /maxrankup to rankup as many times as possible, +# before they fail the requirements for the next rank. +# the permission rankup.maxrankup is used for this command, but it is given by default. +# note that /maxrankup, if enabled, has no confirmation. +max-rankup: + # You must restart your server if you enable or disable /maxrankup! + enabled: false + # whether to send a message for each rankup a player does + # if set to true, the chat may be spammed for each rankup a player goes through with /maxrankup + # if set to false, only the last rankup will be shown (if a player starts on rank A, then does + # /maxrankup and ranks up to B and then C, it will just say "player has ranked up to C") + individual-messages: true + +# options when using the text rankup confirmation +text: + # the time in seconds for a player to + # confirm by typing /rankup again + timeout: 10 + +# placeholders: +# https://okx.sh/rankup/Placeholders.html +placeholders: + # format for money. for more information, see + # https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html + money-format: "#,##0.##" + percent-format: "0.##" + # the format used for requirements + simple-format: "#.##" + # used for current_rank and next_rank placeholders when a player is not in anything in rankups.yml + not-in-ladder: "None" + # used in the current_prestige placeholders when a player hasn't prestiged yet + no-prestige: "None" + # used in the next_rank and next_prestige placeholders when a player is at the highest rank or prestige + highest-rank: "None" + # used in the %rankup_status_[rank]% placeholders + status: + complete: "Complete" + current: "Current" + incomplete: "Incomplete" + last-rank-display-name: "last rank" + +# what to shorten money by. +# ie 1000 -> 1k +# set to an empty list to disable +# for each entry here, it counts as increasing by a factor of 1,000 +# the first represents thousands (1,000) then millions (1,000,000) then billions (1,000,000,000) etc. +# this is used in the "| shortmoney" filter +shorten: +- 'K' +- 'M' +- 'B' +- 'T' +- 'Q' +- 'Qu' +- 'S' \ No newline at end of file diff --git a/src/test/resources/world/rankups.yml b/src/test/resources/world/rankups.yml new file mode 100644 index 0000000..625f9dc --- /dev/null +++ b/src/test/resources/world/rankups.yml @@ -0,0 +1,5 @@ +a: + rank: 'a' + next: 'b' + requirements: + - 'world the_nether' \ No newline at end of file