From 11200862cd80350c3bf6d9f186e5166787824c6a Mon Sep 17 00:00:00 2001 From: okx-code Date: Sat, 3 Aug 2019 15:29:44 +0100 Subject: [PATCH] 3.5.7-alpha - better reporting of configuration errors (instead of disabling the plugin, send the error on startup and whenever a command is executed) - don't check for updates if on a pre-release version - add infinite rankup loop detection - add itemh requirement (like the item requirement, but not deductible) - make it so i only have to change the plugin version in one place --- build.gradle | 20 ++++-- src/main/java/sh/okx/rankup/AutoRankup.java | 4 ++ src/main/java/sh/okx/rankup/RankList.java | 10 ++- src/main/java/sh/okx/rankup/Rankup.java | 69 +++++++++++++++---- src/main/java/sh/okx/rankup/RankupHelper.java | 1 - .../sh/okx/rankup/commands/InfoCommand.java | 17 +++-- .../okx/rankup/commands/PrestigeCommand.java | 4 ++ .../okx/rankup/commands/PrestigesCommand.java | 4 ++ .../sh/okx/rankup/commands/RanksCommand.java | 4 ++ .../sh/okx/rankup/commands/RankupCommand.java | 4 ++ .../requirements/RequirementRegistry.java | 2 +- .../requirement/ItemRequirement.java | 28 ++++---- .../requirement/ItemhRequirement.java | 33 +++++++++ src/main/resources/plugin.yml | 2 +- 14 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 src/main/java/sh/okx/rankup/requirements/requirement/ItemhRequirement.java diff --git a/build.gradle b/build.gradle index e971046..7a5846e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,10 @@ plugins { id 'java' + id "io.freefair.lombok" version "3.8.0" } group 'sh.okx' -version '3.5.6' +version '3.5.7-alpha' repositories { mavenCentral() @@ -26,9 +27,6 @@ repositories { } dependencies { - compileOnly 'org.projectlombok:lombok:1.18.6' - annotationProcessor 'org.projectlombok:lombok:1.18.6' - testCompile group: 'junit', name: 'junit', version: '4.12' compile 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' @@ -42,3 +40,17 @@ dependencies { } compile 'com.github.Ben12345rocks:VotingPlugin:5.18.2' } + +// automatically copy the version to plugin.yml +processResources { + inputs.property 'version', project.version + + from(sourceSets.main.resources.srcDirs) { + include 'plugin.yml' + expand 'version':project.version + } + + from(sourceSets.main.resources.srcDirs) { + exclude 'plugin.yml' + } +} \ No newline at end of file diff --git a/src/main/java/sh/okx/rankup/AutoRankup.java b/src/main/java/sh/okx/rankup/AutoRankup.java index 9d5749d..ab48433 100644 --- a/src/main/java/sh/okx/rankup/AutoRankup.java +++ b/src/main/java/sh/okx/rankup/AutoRankup.java @@ -11,6 +11,10 @@ public class AutoRankup extends BukkitRunnable { @Override public void run() { + if (rankup.error()) { + return; + } + RankupHelper helper = rankup.getHelper(); for (Player player : Bukkit.getOnlinePlayers()) { if (player.hasPermission("rankup.auto")) { diff --git a/src/main/java/sh/okx/rankup/RankList.java b/src/main/java/sh/okx/rankup/RankList.java index 2533037..995cf48 100644 --- a/src/main/java/sh/okx/rankup/RankList.java +++ b/src/main/java/sh/okx/rankup/RankList.java @@ -41,7 +41,7 @@ public class RankList { if (keys.size() == 1 && keys.iterator().next().equalsIgnoreCase("rank")) { throw new IllegalArgumentException( "Having a final rank (for example: \"Z: rank: 'Z'\") from 3.4.2 or earlier should no longer be used.\n" + - "It is safe to just delete the final rank " + name + ""); + "It is safe to just delete the final rank " + name + ""); } else if (section.getStringList("requirements").isEmpty()) { throw new IllegalArgumentException("Rank " + name + " does not have any requirements."); } @@ -59,13 +59,19 @@ public class RankList { // nothing ranks up to this return rank; } - return null; + throw new IllegalArgumentException("Could not find a first rank. First ranks must not have anything that ranks up to them."); } public List getOrderedList() { List list = new ArrayList<>(); T t = getFirst(); while (t != null) { + for (T existing : list) { + if (existing.equals(t)) { + throw new IllegalArgumentException("Infinite rankup loop detected at rank " + t.getRank() + " to " + t.getNext() + + "\nMake sure no there are no rankups to previous ranks or to the same rank"); + } + } list.add(t); t = next(t); } diff --git a/src/main/java/sh/okx/rankup/Rankup.java b/src/main/java/sh/okx/rankup/Rankup.java index c87f5e1..e780fff 100644 --- a/src/main/java/sh/okx/rankup/Rankup.java +++ b/src/main/java/sh/okx/rankup/Rankup.java @@ -71,12 +71,11 @@ public class Rankup extends JavaPlugin { @Getter private RankupHelper helper; private AutoRankup autoRankup; + private String errorMessage; @Override public void onEnable() { - setupPermissions(); - setupEconomy(); - reload(); + reload(true); Metrics metrics = new Metrics(this); metrics.addCustomChart(new Metrics.SimplePie("confirmation", @@ -112,12 +111,20 @@ public class Rankup extends JavaPlugin { @Override public void onDisable() { closeInventories(); - placeholders.unregister(); + if (placeholders != null) { + placeholders.unregister(); + } } - public void reload() { + public void reload(boolean init) { + errorMessage = null; + if(!setupPermissions()) { + errorMessage = "No permission plugin found"; + } + setupEconomy(); + closeInventories(); - loadConfigs(); + loadConfigs(init); if (autoRankup != null) { autoRankup.cancel(); @@ -141,6 +148,30 @@ public class Rankup extends JavaPlugin { helper = new RankupHelper(this); } + public boolean error() { + return error(null); + } + + /** + * Notify the player of an error if there is one + * @return true if there was an error and action was taken + */ + public boolean error(CommandSender sender) { + if (errorMessage == null) { + return false; + } + + if (!(sender instanceof Player)) { + getLogger().severe("Failed to load Rankup"); + } else { + sender.sendMessage(ChatColor.RED + "Could not load Rankup, check console for more information."); + } + for (String line : errorMessage.split("\n")) { + getLogger().severe(line); + } + return true; + } + private void addAll(Map map, RankList ranks) { for (Rank rank : ranks.ranks) { for (Requirement requirement : rank.getRequirements()) { @@ -165,7 +196,7 @@ public class Rankup extends JavaPlugin { } } - private void loadConfigs() { + private void loadConfigs(boolean init) { saveLocales(); config = loadConfig("config.yml"); @@ -173,7 +204,14 @@ public class Rankup extends JavaPlugin { File localeFile = new File(new File(getDataFolder(), "locale"), locale + ".yml"); messages = YamlConfiguration.loadConfiguration(localeFile); - Bukkit.getScheduler().scheduleSyncDelayedTask(this, this::refreshRanks); + if (init) { + Bukkit.getScheduler().scheduleSyncDelayedTask(this, () -> { + refreshRanks(); + error(); + }); + } else { + refreshRanks(); + } } public void refreshRanks() { @@ -187,11 +225,13 @@ public class Rankup extends JavaPlugin { } else { prestiges = null; } + + // check rankups are not in an infinite loop + rankups.getOrderedList(); + prestiges.getOrderedList(); } catch (Exception e) { + this.errorMessage = e.getMessage(); e.printStackTrace(); - Bukkit.getPluginManager().disablePlugin(this); - getLogger().severe("Could not finish enabling Rankup"); - Bukkit.broadcast(ChatColor.RED + "Could not reload rankup successfully, please check console for more information.", "rankup.reload"); } } @@ -229,6 +269,7 @@ public class Rankup extends JavaPlugin { requirements.addRequirement(new PlayerKillsRequirement(this)); requirements.addRequirement(new MobKillsRequirement(this)); requirements.addRequirement(new ItemRequirement(this)); + requirements.addRequirement(new ItemhRequirement(this)); requirements.addRequirement(new UseItemRequirement(this)); requirements.addRequirement(new TotalMobKillsRequirement(this)); requirements.addRequirement(new CraftItemRequirement(this)); @@ -250,9 +291,13 @@ public class Rankup extends JavaPlugin { } } - private void setupPermissions() { + private boolean setupPermissions() { RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Permission.class); + if (rsp == null) { + return false; + } permissions = rsp.getProvider(); + return permissions.hasGroupSupport(); } private void setupEconomy() { diff --git a/src/main/java/sh/okx/rankup/RankupHelper.java b/src/main/java/sh/okx/rankup/RankupHelper.java index 0d1b425..5f627b0 100644 --- a/src/main/java/sh/okx/rankup/RankupHelper.java +++ b/src/main/java/sh/okx/rankup/RankupHelper.java @@ -1,6 +1,5 @@ package sh.okx.rankup; -import lombok.RequiredArgsConstructor; import net.milkbowl.vault.permission.Permission; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; diff --git a/src/main/java/sh/okx/rankup/commands/InfoCommand.java b/src/main/java/sh/okx/rankup/commands/InfoCommand.java index fa66e88..f901c3d 100644 --- a/src/main/java/sh/okx/rankup/commands/InfoCommand.java +++ b/src/main/java/sh/okx/rankup/commands/InfoCommand.java @@ -24,27 +24,36 @@ public class InfoCommand implements CommandExecutor { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (args.length > 0) { if (args[0].equalsIgnoreCase("reload") && sender.hasPermission("rankup.reload")) { - plugin.reload(); - sender.sendMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "Rankup " + ChatColor.YELLOW + "Reloaded configuration files."); + plugin.reload(false); + if (!plugin.error(sender)) { + sender.sendMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "Rankup " + ChatColor.YELLOW + "Reloaded configuration files."); + } return true; } } + PluginDescriptionFile description = plugin.getDescription(); + String version = description.getVersion(); sender.sendMessage( - ChatColor.GREEN + "" + ChatColor.BOLD + description.getName() + " " + description.getVersion() + + ChatColor.GREEN + "" + ChatColor.BOLD + description.getName() + " " + version + ChatColor.YELLOW + " by " + ChatColor.BLUE + ChatColor.BOLD + String.join(", ", description.getAuthors())); if (sender.hasPermission("rankup.reload")) { sender.sendMessage(ChatColor.GREEN + "/" + label + " reload " + ChatColor.YELLOW + "Reloads configuration files."); } if (sender.hasPermission("rankup.checkversion")) { if (versionMessage == null) { + if (version.contains("alpha") || version.contains("beta") || version.contains("rc")) { + versionMessage = ChatColor.YELLOW + "You are on a pre-release version."; + sender.sendMessage(versionMessage); + return true; + } sender.sendMessage(ChatColor.YELLOW + "Checking version..."); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { String message; try { String latest = getLatestVersion(); - if (description.getVersion().equals(latest)) { + if (version.equals(latest)) { message = ChatColor.GREEN + "You are on the latest version."; } else { message = ChatColor.YELLOW + "A new version is available: " + ChatColor.GOLD + latest diff --git a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java index 303b91a..5bbd9a6 100644 --- a/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java +++ b/src/main/java/sh/okx/rankup/commands/PrestigeCommand.java @@ -22,6 +22,10 @@ public class PrestigeCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + // check if player if (!(sender instanceof Player)) { return false; diff --git a/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java b/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java index df57c51..7bc12f4 100644 --- a/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java +++ b/src/main/java/sh/okx/rankup/commands/PrestigesCommand.java @@ -16,6 +16,10 @@ public class PrestigesCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + Prestiges prestiges = plugin.getPrestiges(); Prestige playerRank = null; if (sender instanceof Player) { diff --git a/src/main/java/sh/okx/rankup/commands/RanksCommand.java b/src/main/java/sh/okx/rankup/commands/RanksCommand.java index ca7c5ea..6104ff9 100644 --- a/src/main/java/sh/okx/rankup/commands/RanksCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RanksCommand.java @@ -16,6 +16,10 @@ public class RanksCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + Rankups rankups = plugin.getRankups(); Rank playerRank = null; if (sender instanceof Player) { diff --git a/src/main/java/sh/okx/rankup/commands/RankupCommand.java b/src/main/java/sh/okx/rankup/commands/RankupCommand.java index 1e4a3d7..16483c2 100644 --- a/src/main/java/sh/okx/rankup/commands/RankupCommand.java +++ b/src/main/java/sh/okx/rankup/commands/RankupCommand.java @@ -24,6 +24,10 @@ public class RankupCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (plugin.error(sender)) { + return true; + } + // check if player if (!(sender instanceof Player)) { return false; diff --git a/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java b/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java index 33d5eb1..5279289 100644 --- a/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java +++ b/src/main/java/sh/okx/rankup/requirements/RequirementRegistry.java @@ -31,7 +31,7 @@ public class RequirementRegistry { String name = parts[0]; String value = parts[1]; Requirement requirement = newRequirement(name, value); - Objects.requireNonNull(requirement, name.equalsIgnoreCase("money") ? "Money requirement disabled because no economy was found." : "Unknown requirement: " + name); + Objects.requireNonNull(requirement, name.equalsIgnoreCase("money") ? "The 'money' requirement is being used but no economy is found" : "Unknown requirement: " + name); requirements.add(requirement); } return requirements; diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/ItemRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/ItemRequirement.java index c28b17a..78450f4 100644 --- a/src/main/java/sh/okx/rankup/requirements/requirement/ItemRequirement.java +++ b/src/main/java/sh/okx/rankup/requirements/requirement/ItemRequirement.java @@ -9,6 +9,8 @@ import sh.okx.rankup.requirements.DeductibleRequirement; import sh.okx.rankup.requirements.ProgressiveRequirement; import sh.okx.rankup.requirements.Requirement; +import java.util.Arrays; + public class ItemRequirement extends DeductibleRequirement { public ItemRequirement(Rankup plugin) { super(plugin, "item", true); @@ -18,25 +20,25 @@ public class ItemRequirement extends DeductibleRequirement { super(clone); } - @Override - public double getProgress(Player player) { - Material material = Material.matchMaterial(getSub()); - int count = 0; - for (ItemStack item : player.getInventory().getStorageContents()) { - if (item != null && item.getType() == material) { - count += item.getAmount(); - } - } - return count; - } - @Override public void apply(Player player, double multiplier) { - player.getInventory().removeItem(new ItemStack(Material.matchMaterial(getSub()), (int) (getValueInt() * multiplier))); + Material type = Material.matchMaterial(getSub()); + if (type == null) { + throw new IllegalArgumentException("Invalid item " + getSub()); + } + player.getInventory().removeItem(new ItemStack(type, (int) (getValueInt() * multiplier))); } @Override public Requirement clone() { return new ItemRequirement(this); } + + @Override + public double getProgress(Player player) { + Material material = Material.matchMaterial(getSub()); + return Arrays.stream(player.getInventory().getStorageContents()) + .filter(item -> item != null && item.getType() == material) + .mapToInt(ItemStack::getAmount).sum(); + } } diff --git a/src/main/java/sh/okx/rankup/requirements/requirement/ItemhRequirement.java b/src/main/java/sh/okx/rankup/requirements/requirement/ItemhRequirement.java new file mode 100644 index 0000000..35ca8d3 --- /dev/null +++ b/src/main/java/sh/okx/rankup/requirements/requirement/ItemhRequirement.java @@ -0,0 +1,33 @@ +package sh.okx.rankup.requirements.requirement; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import sh.okx.rankup.Rankup; +import sh.okx.rankup.requirements.ProgressiveRequirement; +import sh.okx.rankup.requirements.Requirement; + +import java.util.Arrays; + +public class ItemhRequirement extends ProgressiveRequirement { + public ItemhRequirement(Rankup plugin) { + super(plugin, "itemh", true); + } + + protected ItemhRequirement(ItemRequirement clone) { + super(clone); + } + + @Override + public double getProgress(Player player) { + Material material = Material.matchMaterial(getSub()); + return Arrays.stream(player.getInventory().getStorageContents()) + .filter(item -> item != null && item.getType() == material) + .mapToInt(ItemStack::getAmount).sum(); + } + + @Override + public Requirement clone() { + return new ItemhRequirement(plugin); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2b01c13..7fc475b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Rankup -version: 3.5.6 +version: ${version} main: sh.okx.rankup.Rankup author: Okx depend: [Vault]